fix(agents): recover post-update integration state#443
Merged
Conversation
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This is the rollout follow-up to #441. The Hermes/TraceDecay architecture in #441 is intact: Hermes sessions resolve memory and LCM storage from the session workspace, project-backed sessions remain project-sharded, untethered sessions use profile-level user memory/session stores, autonomous post-turn review applies validated mutations, and TraceDecay-managed skills are exposed through Hermes's native plugin discovery and progressive tool discovery.
The v0.0.54 rollout exposed two pre-existing-state problems that could not be reproduced from a clean install:
sessions.dbcontained sessions whose original project path no longer exists. Explicit Hermes migration correctly refused to guess, but the same unresolved source also gated automatic post-update reinstall forever.This PR makes those states recoverable without claiming user-authored text, guessing project identity, copying unscoped memory into user memory, or hiding real database failures.
Generated prompt block recovery
Managed-skill indexes and memory-digest blocks now recognize a narrowly defined orphaned generated block:
When all of those ownership signals are present, reinstall replaces or removes only the generated range beginning at the exact preamble. Text before and after that range is preserved. This repairs the real rollout state while avoiding a broad heading-based deletion heuristic.
Ambiguous states remain fail-closed:
Shared prompt files receive a two-pass uninstall: all target-slugged blocks are removed first, then the one legacy unslugged block is evaluated. This removes ordering dependence when an orphaned legacy block and a newer target-slugged block coexist.
The memory digest uses the same ownership and ambiguity rules. The generated heading/body preamble is now a single constant shared by rendering and recovery, preventing recovery logic from drifting from emitted content.
Hermes legacy session migration
The legacy migrator now has two explicit destination layouts:
sessions.dbandtracedecay.db;user-sessions.db, with no project memory target.Only sessions with provably neutral scope may enter
user-sessions.db. Neutral evidence is limited to an empty selector, the explicituserselector, the exact user home, or the exact Hermes home. An arbitrary existing directory is not considered projectless. A vanished directory is not considered projectless. A Hermes plugin subdirectory is not considered projectless.Project evidence is correlated per source session before the source store is assigned a destination. This prevents unrelated parallel or historical sessions from being flattened into one inferred project. Migration refuses:
Deleted symlink metadata is now preserved when the removed alias can no longer be proven. A remaining registered path is not enough to silently assume that an unresolvable sibling field was merely an alias; privacy and project isolation take priority over opportunistic migration.
For genuinely projectless legacy sessions, copied session rows are normalized to project key/path
userand written idempotently touser-sessions.db. The source is opened read-only and retained. Re-running migration recognizes the same logical source fingerprint and does not duplicate rows.Legacy memory is deliberately stricter than session history. If a projectless legacy source also has a memory database, those facts are not copied to profile user memory because there is no durable proof that they are user-global. The session migration may complete, but the report now explicitly records the memory database as preserved/unresolved. Automatic reinstall prints that warning; explicit Hermes install remains strict. This prevents a successful-session message from silently implying that unscoped memory was migrated.
Automatic reinstall versus explicit migration
Automatic post-update reinstall now distinguishes migration outcomes:
This prevents an unresolved historical source from wedging every future TraceDecay command while retaining the important retry behavior for actual corruption or incomplete copying. Explicit
tracedecay install --agent hermesremains strict and reports unresolved sources as an error so an operator cannot mistake preservation for completed cutover.Autonomous curation boundary
This follow-up does not introduce a scheduler dry-run mode. Autonomous memory curation remains a two-phase validated mutation: proposed operations are evaluated read-only, accepted operations are then applied, and rejected operations remain audited. The read-only phase is validation, not the terminal behavior of an autonomous run.
An explicit operator preview remains useful and read-only. Destructive offline database repair, migration, garbage collection, and source-tree edits also retain their existing safety confirmations. That distinction lets TraceDecay self-improve and update/delete stale memories autonomously while preserving an audit boundary for operator-invoked destructive maintenance.
Concurrency and isolation
No process-global "active project" is introduced. Hermes runtime routing remains session-specific, so parallel Hermes sessions may use separate projects or separate worktrees without overwriting one another's routing context. Sessions in the same project intentionally converge on the same project shard, where database transactions and idempotent receipts provide coordination. Generated prompt updates remain ownership-scoped and ambiguity-safe.
Tests
Local verification on the final diff:
9dd9ef0ec99a87f078f7272b4323df5440b4b3f9.cargo clippy --all-targets -- -D warnings: passed.cargo fmt --all -- --check: passed.git diff --check: passed.The Hermes harness verifies plugin loading, memory provider discovery, context-engine activation, project isolation, untethered user scope, exact-session LCM ingestion, structured tool correlation, managed-skill discovery, progressive tool discovery, graph dispatch, and clean Hermes doctor output.
Rollout
After merge, release-plz should publish the follow-up release. The released artifact must then be installed, integrations reinstalled noninteractively, and both TraceDecay and Hermes restarted. Live verification should confirm that the preserved ambiguous legacy source produces a warning without a reinstall loop, project sessions remain in their project shards, untethered sessions use profile user scope, and the generated prompt markers remain balanced and idempotent.