Skip to content

fix: harden runtime routing and ci#453

Merged
ScriptedAlchemy merged 11 commits into
masterfrom
codex/ci-runtime-hardening
Jul 12, 2026
Merged

fix: harden runtime routing and ci#453
ScriptedAlchemy merged 11 commits into
masterfrom
codex/ci-runtime-hardening

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary

This follow-up hardens the live TraceDecay/Hermes integration after the v0.0.58 rollout and addresses defects found by dogfooding real Hermes, Codex, Cursor, automation, analytics, and service logs. It keeps Windows coverage enabled while preventing superseded PR work and unsafe release cancellation.

Why this is needed

The live audit found four distinct correctness gaps:

  1. Modern registered project roots and worktree aliases were absent from the shared project-attribution guard. Historical Cursor and Hermes sessions could therefore remain in the user/projectless store even when transcript evidence referenced a registered repository or linked worktree.
  2. tracedecay analytics diagnostics read session counts from legacy global.db.session_messages. Session data is now project/user sharded, so diagnostics reported zero messages despite more than 900,000 healthy LCM raw messages.
  3. Memory-curator evidence was serialized more than once into the backend request. A real request reached 1,109,728 characters and exceeded Codex app-server's 1,048,576-character input limit. The permanent failure ledger then suppressed every future scheduled curator run, even after the request shape changed.
  4. Stock Hermes registers plugin skills as qualified, explicit-only skills and intentionally omits them from the flat skill index. TraceDecay registered the skill correctly but did not reveal tracedecay:tracedecay to the agent. In addition, the live Hermes profile's auto tool-search threshold did not activate for the large-context model, leaving 137 schemas/193 KB visible.

The CI/release audit also found that the Windows summary used always(), which can keep a superseded run alive, release PR integrity lacked PR-scoped cancellation, release-plz serialization began only at the second job, stable release publication was cancelable, and beta release publication was not serialized.

Changes

Session and project correlation

  • Extend the shared registered-project root set with modern code_projects canonical/display roots.
  • Include filesystem-backed project_aliases, including linked worktrees.
  • Exclude synthetic identity aliases such as git-common-dir: because transcript attribution requires real paths.
  • Reuse this same canonical/legacy/alias union for analytics shard enumeration so attribution and reporting cannot drift independently.
  • Add regression coverage proving canonical roots and worktree aliases are recognized.

This affects both Cursor and Hermes projectless catch-up because they share the same registered-root guard. Transport remains irrelevant: Telegram and non-Telegram Hermes sessions use the same session/workspace attribution path.

Sharded analytics diagnostics

  • Count active-project messages from the active project's sessions.db.
  • For --all, deduplicate and sum all registered project session shards plus user-sessions.db.
  • Keep global analytics event storage unchanged.
  • Add regressions for current-project and all-project message counts.

Autonomous memory curator

  • Stop embedding the full review evidence in both the prompt and context.
  • Keep one bounded context.llm_review.messages copy and retain only operational review metadata around it.
  • Add a regression showing a 600,000-character evidence payload remains below the Codex app-server limit.
  • Add a regression proving evidence appears exactly once.
  • Treat a recorded input_too_large failure as scheduler-retryable on a later rebuilt request, while keeping classification of the currently oversized request permanent so identical immediate retries are still prevented.
  • Preserve autonomous validate_then_apply; no dry-run gate was introduced.

Hermes discovery

  • Keep the plugin's bare-name registration required by stock Hermes.
  • Expose the qualified tracedecay:tracedecay skill through the first-turn code/project nudge so skill_view can load it.
  • Add generated-plugin regression coverage for qualified skill discovery.

Live profile validation additionally enabled Hermes progressive tool discovery (tools.tool_search.enabled=on). Offline stock-Hermes assembly then reduced the model-visible surface and successfully found TraceDecay callers/impact tools through the bridge; skill_view("tracedecay:tracedecay") loaded the generated skill.

CI and release safety

  • Replace the Windows aggregate job's cancellation-resistant always() predicate with !cancelled() while leaving the Windows build and all shards enabled.
  • Add PR-number concurrency with cancel-in-progress: true to release PR integrity.
  • Serialize the entire release-plz workflow at workflow scope and never cancel an in-progress crates.io/GitHub publication.
  • Make stable and beta release publication non-cancelable once started.
  • Extend release workflow contract tests to pin these invariants.
  • Windows remains enabled and visible, but is not configured as a required merge check.

Test isolation

  • Restore the production-default structured-backfill switch inside the process-safety test. This fixes a cargo-test-only order dependency: the test passed alone but failed after another test disabled the process-global switch, even with --test-threads=1.

Live rollout evidence

  • Published and installed v0.0.58 before this follow-up.
  • tracedecay doctor: database integrity OK; 32 watched projects, none degraded.
  • TraceDecay daemon and Hermes gateway restarted successfully against v0.0.58.
  • User-memory fact add/update/get/remove canary passed; removed fact returned fact not found.
  • Durable user fact records the Hermes/TraceDecay responsibility boundary and user-vs-project routing rule.
  • Hermes user-scope transcript search found real Telegram history with Hermes session provenance.
  • Cross-project Hermes search found repository-associated work across registered shards.
  • LCM status: 909,201 raw messages, 6,013 summaries, 5.4:1 compression, zero missing payloads and zero maintenance debt.
  • Hermes progressive tool discovery: 103 TraceDecay tools deferred; tool search returned tracedecay_callers, tracedecay_impact, and related tools.
  • Hermes plugin skill load: skill_view("tracedecay:tracedecay") succeeded.

Verification

  • cargo test --test hermes_suite: 66 passed.
  • cargo test --test automation_runner_test: 160 passed.
  • cargo test --test session_suite -- --test-threads=1: 222 passed.
  • Focused analytics regressions: 6 passed.
  • Focused project-root/worktree attribution regression: passed.
  • Focused curator request-size/dedup regressions: 2 passed.
  • cargo check --all-targets: passed.
  • cargo clippy --all-targets -- -D warnings: passed.
  • cargo fmt --all -- --check: passed.
  • bash tests/release_workflow_contract_test.sh: passed.
  • actionlint on all changed workflows: passed.
  • git diff --check: passed.
  • TraceDecay simplify scan reviewed; reported warnings are existing large-file/hub findings, not new helper regressions.

Release note

Includes a patch changeset for the next release. No user memory, project databases, blocked manifests, or Hermes-owned skill directories are deleted or rewritten by this PR.

Follow-up hardening and platform verification

The curator change does not add a blunt byte truncation layer. It serializes the review evidence once instead of duplicating the same corpus in two prompt sections; the existing cluster bounds then keep the rebuilt production request below the backend ceiling while preserving the full bounded evidence set.

The v0.0.58 rollout already supplied Hermes runtime-cwd routing, stable Hermes session IDs, and explicit user-versus-project memory scope. This PR extends transport-agnostic historical catch-up through modern registered roots and worktree aliases. Telegram is only one Hermes transport and is never used as a memory-scope key.

Portable fixtures now create independent Git roots, write matching project identity only where eligibility is intended, canonicalize temporary paths for macOS /var to /private/var behavior, refresh the reviewed generated-Hermes asset hash, and restore both structured-backfill process switches after daemon-gate assertions. The final local workspace run passed 4,655 tests with 2 intentional skips.

The CI design follows GitHub concurrency semantics: pull-request work shares a PR-number group and newer commits cancel superseded runs. Aggregate jobs use !cancelled() rather than always() so cancellation can drain. Publication workflows serialize mutations with cancel-in-progress false. Stable and beta manual rebuilds now require an explicit tag and share the same concurrency identity as automatic publication; beta dispatch validates that the target is an existing prerelease and checks out that tag. Windows remains enabled and exercised, but is not made a merge prerequisite.

After merge, release-plz will publish the patch. The rollout is not considered complete until tracedecay update installs it, stale TraceDecay/Hermes runtimes are restarted, and live diagnostics, project/user routing, Hermes discovery, autonomous curation, and log canaries are repeated against the installed binary.

Telegram transcript and live-log follow-up

The live Telegram DM session 20260711_131044_4e9b777f supplied a decisive mixed-scope case. Hermes keeps that long-lived DM row unpinned (cwd, git_repo_root, and git_branch are null), but the TraceDecay turn correlator inspects the current turn’s terminal calls. The user message “Find tracedecay ptoject. List open PRs on it find local repo” produced terminal calls with workdir=/fast/projects/tracedecay; project-scoped TraceDecay transcript search returns that exact message from the TraceDecay shard. Thus a general Telegram conversation can remain user-scoped overall while repository turns are attributed to the correct project. Transport is not the scope key.

That same transcript exposed two additional defects. First, projectless context compression forgot to attach storage_scope=user to tracedecay_lcm_compress, so a 371,447-token general chat attempted project discovery and returned an unchanged replay instead of compacting the user LCM store. Second, project discovery used tracedecay_active_project against speculative process paths such as /home/zack, /, and /home/zack/.hermes/hermes-agent, creating daemon errors and allowing a nested Hermes-owned path past the exact-home guard.

The fix routes projectless compression explicitly to the profile-level user session store. Project correlation now resolves candidates through the global project registry, understands canonical roots and worktree aliases, and does not open a project shard merely to test an unregistered path. Both generated transport and plugin routing reject the Hermes home and every descendant. Bare transport calls no longer infer a project from the plugin process cwd; routed host wrappers supply real session or tool workspace evidence. Regression coverage reproduces projectless compression, registry alias resolution, Hermes-descendant rejection, and legacy-pin isolation. The generated Hermes suite now passes 68/68, with Clippy and formatting clean.

Canonical user history and multi-project turn correlation

The final correlation model deliberately separates host-session identity from per-turn repository attribution. Every completed Hermes turn is written once to the profile-level user session store as the canonical conversation. TraceDecay then scans only that turn—from its last user message through the assistant tool calls/results—collects every explicit project selector, cwd, workdir, and terminal cd, resolves those candidates through the registry and worktree aliases, and projects the same user/assistant pair into every distinct project shard touched by the turn.

Canonical and project projections use identical stable (provider, message_id) identities. No global fact table or session-wide project pin is introduced, and no schema migration is required. The canonical projection records associated_project_roots; project searches find the same user message in each relevant shard, while user-scope search retains the complete Telegram/CLI/Desktop conversation. A later general-chat turn does not inherit earlier project attribution because candidate collection is bounded to the current turn, and self.project_root is not mutated by fan-out.

Historical Hermes catch-up now follows the same rule. The existing project sweeper already fans one historical turn into every matching destination; user catch-up now retains all turns rather than excluding project-attributed turns. Its cursor version advances from user-turn-v1 to user-turn-v2, forcing one idempotent backfill so already-advanced installations recover previously omitted canonical user messages.

Each successful canonical/project write emits its matching turnCompleted and turnIngested receipt in that scope. This closes the earlier gap where a terminal receipt could exist in an earlier project touched by a multi-project turn but only the last project received ingestion readiness. Tests cover canonical metadata preservation, identical IDs across user and project stores, two-project fan-out, no session rebinding, historical canonical recovery, worktree alias resolution, and Hermes-home descendant rejection. Final bounded aggregate verification passed 4,659/4,659 tests with 2 intentional skips using eight local test threads; all affected Hermes, transcript, agent, MCP, formatting, Clippy, workflow-contract, and actionlint checks pass.

Local development dogfood installation

This PR also adds the missing first-class local-development deployment path requested during live verification. cargo dogfood builds the current checkout as a locked release binary, copies it out of Cargo’s mutable target/ tree to ~/.local/lib/tracedecay/dogfood/tracedecay, and atomically replaces ~/.local/bin/tracedecay. This prevents later rebuilds, cleans, worktree removal, or Cargo file locks from invalidating the executable used by active agents.

After staging, the command explicitly removes Cargo’s hermetic TRACEDECAY_DATA_DIR=target/test-profile/.tracedecay and TRACEDECAY_DISABLE_GLOBAL_DB=1 environment before invoking the installed binary. It then runs the canonical hidden post-update lifecycle, which quiesces and refreshes the managed daemon, regenerates plugin assets, refreshes every tracked host integration, performs the health pass, updates install markers, and restarts the prior daemon state. It finally verifies daemon status, doctor output, and binary version. It never invokes published-release upgrade, so an unmerged checkout cannot be silently replaced by the latest GitHub release.

The command is exposed as the Cargo alias cargo dogfood and implemented by scripts/dogfood.sh. Its isolated contract test uses a fake Cargo executable, fake built binary, temporary HOME, custom target directory, and action log to prove the build arguments, stable stage copy, global executable copy, post-update call, daemon status, doctor, and version verification without touching the real user profile. CI runs this shell contract in the Release Version Drift job.

A repo-local dogfooding-tracedecay skill is installed for both Codex and Claude. The two SKILL.md files are byte-identical and teach agents to use cargo dogfood rather than cargo run or tracedecay upgrade, verify the live global runtime, inspect host/service logs, preserve in-flight worktrees, and rerun deployment after source changes. Contract tests validate the Codex skill frontmatter, host mirror parity, required stable paths, isolation warning, verification commands, and release-upgrade prohibition.

Dogfood implementation correction and live result

The first attempted Cargo alias used Git-style !scripts/dogfood.sh; live execution correctly rejected it because Cargo aliases do not support shell escapes. A second launcher prototype exposed that starting a nested Cargo build from cargo run can wait on the outer Cargo build lock. Both defects were caught before merge and replaced by the final lock-safe design: .cargo/config.toml maps cargo dogfood to cargo run --quiet --release --bin tracedecay -- dogfood; the hidden developer subcommand receives the already-built release executable through current_exe, invokes the staging script with TRACEDECAY_DOGFOOD_SOURCE_BINARY, and therefore performs no nested Cargo invocation. Direct script use still performs its own locked release build.

The final command was exercised against the real user profile. It built PR head code, staged and atomically installed it, completed the normal post-update lifecycle, refreshed Claude/Codex/Cursor/Hermes and all other tracked integrations, restarted the systemd user daemon, verified a connectable daemon socket, ran doctor, and printed the installed version. target/release/tracedecay, ~/.local/lib/tracedecay/dogfood/tracedecay, and ~/.local/bin/tracedecay were byte-identical after deployment. Focused verification after the launcher correction passed 2,095/2,095 tests plus cargo check --all-targets, formatting, shell syntax, isolated dogfood contract, skill validation, mirror parity, and diff checks.

The health pass found no actionable installation failures. It preserved three pre-existing blocked store manifests lacking repository identity/enrollment and reported one historical Cursor MCP connection failure whose host requires a Cursor reload/toggle; neither warning was introduced by the dogfood deployment.

@changeset-bot

changeset-bot Bot commented Jul 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a85f505

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d50588d76e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/session_suite/structured_backfill.rs
@ScriptedAlchemy ScriptedAlchemy merged commit 8001a1f into master Jul 12, 2026
13 checks passed
@ScriptedAlchemy ScriptedAlchemy deleted the codex/ci-runtime-hardening branch July 12, 2026 00:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant