Conversation
A store's folding flavor is exactly one state slot —
`${ns}/kvunified:presentation-receipt`; everything else the adaptive path
persists is shared between solvers. This adds the utility that handles
the two things a bare foldingStrategy config flip does not:
- validate: dry-runs the strict CanonicalSummaryForest (via
previewContext, committing nothing) under each treeification policy
(strict / treeify / preserve-gaps) and recommends the first that
builds. kv-stable's SummaryTree tolerates scarred chronicles the
forest rejects, so this is the go/no-go check before any migration.
- to-unified: synthesizes the initial receipt chain from the carried
`autobio:resolutions` frontier — the same (repHash, level) pairs the
kv-unified draft builder records — so the first solve has a
continuity baseline instead of a one-shot presentation jump. No cache
reference (the provider cache is genuinely cold after a solver
switch). Resolutions pointing at unreachable levels degrade
deterministically with warnings. Refuses to overwrite an existing
chain unless --overwrite. acceptedAt is an explicit required input —
no clock reads, migrations are reproducible.
- to-stable: clears the receipt slot, closing the flip-back landmine
where a stale chain would be resurrected as the continuity anchor
(nothing else reads or clears it). Never opens a ContextManager, so
no on-load repairs run.
Shipped as bin `context-manager-migrate` (validate / to-unified /
to-stable, dry-run by default, --apply to write, --json for tooling),
mirroring the agent-framework-recover pattern.
The integration tests are the first coverage of the cross-strategy
switch path at all: a store compiled under kv-stable is migrated and
then loaded + compiled under kv-unified.
Also: buildPicker's [picker-config-drift] alarm no longer fires while a
previewContext override is in flight — a mid-preview foldingStrategy
swap is the caller's requested what-if, not drift.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ej5yriRtwnzjYWNy3YeXeE
Field-tested against a production resident store (137MB, 6k messages, 2.5 weeks of life). Two fixes: - A solver capacity limit (SparseLabelCeilingError / ExactEnumerationLimitError) hit AFTER forest construction now counts as a pass with a reported note, not a validate failure: the forest is built at solve start, and the forest is what validate is for. The real deployment tunes its own solver config. - The canned validation solver config is sized for real stores instead of the unit-test toys it started as (the production store blew the 10k label ceiling at 10,471): coarse 2k buckets, 500k ceiling. Field results, for the record: the store's strict forest carries two non-contiguous-ownership scars (validate correctly recommends a tolerance policy — matching the Sep 9 production incident where kv-unified went hard-down on exactly this forest), and to-unified correctly refused the existing receipt chain left behind by the Sep 10 revert to kv-stable — the flip-back landmine to-stable exists to clear. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ej5yriRtwnzjYWNy3YeXeE
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.
What
Adds
context-manager-migrate— a CLI (bin, mirroring theagent-framework-recoverpattern) plussrc/migration/library exports for switching an existing store between folding strategies. Three subcommands, all dry-run by default (--applyto write,--jsonfor tooling):validate— dry-runs the strict kv-unifiedCanonicalSummaryForestagainst the store (viapreviewContext, which commits nothing) under each treeification policy (strict/treeify/preserve-gaps) and recommends the first that builds. kv-stable'sSummaryTreetolerates scarred chronicles that the strict forest rejects (Phase-0 found 11 non-contiguous summary nodes on a real export), so this is the go/no-go check — and it's useful standalone as a fleet-wide forest health inventory.to-unified— synthesizes the initial presentation-receipt chain from the carriedautobio:resolutionsfrontier, recording the sameraw:{id}/summary:{summaryId}(repHash, level) pairs the kv-unified draft builder would. This gives the first kv-unified solve a continuity baseline instead of a one-shot presentation jump. No cache reference — the provider cache is genuinely cold after a solver switch. Resolutions pointing at unreachable levels degrade deterministically to the deepest reachable level, with warnings. Refuses to overwrite an existing chain unless--overwrite(exit 4).to-stable— clears${ns}/kvunified:presentation-receipt, closing the flip-back landmine: nothing reads or clears the slot after a switch away from kv-unified, so a later flip back would resurrect a stale chain as its continuity anchor. Never opens a ContextManager (no on-load repairs); the chronicle is append-only, so the cleared chain stays recoverable from state history.Design notes
acceptedAt— is a required parameter, never a clock read; dry-run and apply produce byte-identical receipt hashes (asserted in tests).validate/to-unifiedopen the store through the strategy and therefore run its standard on-load canonicalization (identical to any agent restart) — the CLI help says loudly to run against a copy.buildPicker's[picker-config-drift]alarm no longer fires while_previewInFlight— a preview'sfoldingStrategyoverride is the caller's requested what-if, not drift (previously any preview overriding the solver, e.g. from the conhost panel, produced the scary stack trace).Testing
10 new tests in
test/folding-migration.test.ts— pure-function coverage (presentation synthesis, L1-ledger + sourceIds fallback, unreachable-level degradation, chain determinism) plus integration tests that are, as far as I can tell, the first coverage of the cross-strategy switch path at all: a store compiled under kv-stable is migrated, then loaded and compiled under kv-unified with the synthesized chain as its continuity baseline; refusal/overwrite and to-stable idempotence are covered. Full suite: 768/769 pass — the 1 failure (snapshot cadence retune) is pre-existing drift against the installed chronicle build (missinggetStateItemJson-family API), unrelated to this change.Draft until we've exercised all three subcommands against a copy of a real deployed instance's datastore.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Ej5yriRtwnzjYWNy3YeXeE