Repository navigation
Keep saved transcripts with their bus or external harness owner - #2771
Conversation
|
WIP handoff: the first checkpoint is pushed. src/agent_comms/session_file.py:17-92 now declares RegistrySessionLocation, BusSessionLocation and ExternalSessionLocation. from_path selects ownership once; Bus stores a relative path and resolves beneath the supplied root; External stores an absolute path and writable refuses a root other than the published live route. No other source file has been migrated. This checkpoint is incomplete: old SavedSessionFile imports and constructors still exist, so it is not runnable and must stay draft. Left: migrate RuntimeLocation (src/agent_comms/agent_backend.py:48) and its PiSessionFile/DurableDatabase implementations to carry RegistrySessionLocation and resolve using the supplied root. Migrate all writers, beginning registry_store.py:151 and thread_management.py:249, to RegistrySessionLocation.from_path. Migrate raw-path consumers, launches, compaction, fork, recovery and storage operations; external writes from copied roots must refuse through the location owner. Remove old SavedSessionFile imports throughout Core/tests and the paired Toad consumers. Add the one-shot installer carry under tools/cutover through Carry/step_worker; prove dry/apply/idempotence on a scratch registry, never live. Then update #2756 to cite the resolving readers; its earlier green replay leaked native session reads and does not prove isolation. Exact next edit: change RuntimeLocation.arguments/read_key/read_keys/storage_files/imported_sources to accept the bus root and delegate path resolution/write permission to the declared RegistrySessionLocation, then migrate PiSessionFile.history_source/imported_sources and DurableDatabase.history_source/session to that shared behavior. Keep the absence behavior on UnstartedRuntime. Resolve the current session_file -> unstarted_runtime -> agent_backend import relationship without adding local-import shims. Evidence already collected: live registry.json was opened rb only: 194 threads, 111 saved paths, 104 under /home/ts/.agent-comms and 7 outside under the Pi harness directory, 83 unsaved, zero relative paths. No live data changed. NRA ModuleSyntaxIndex covered 952 Core/tools/tests/Toad modules with zero parse omissions and 455 lexical sites; dynamic receiver binding is not proved. No tests were run for this branch. Existing #2756 snapshot remains retained for its review. New branch is based on origin/main 791e5a2. Review the location declarations before relying on them: this is the first checkpoint, not completed consumer migration. |
The registry stored every saved transcript as one absolute string, so a copied root read and wrote the live root's transcripts. RegistryStore now binds each decoded thread's location to its own root, as it already binds turn records; a bus location resolves under that root and an external harness transcript refuses writes from any root but the published one. Writers publish through RegistrySessionLocation.from_path, and launches and compaction take the writable runtime. The duplicate SavedSessionFile pattern declaration is now BusTranscriptFile. A one-shot carry turns the old strings into bus and external locations before any step decodes the registry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A location's identity is its path: a bus path is relative and an external one absolute, so the bound root says where it is read, not which one it is. Archived history sources bind their provenance to the original root, and a decoded transcript read witness binds its thread to the root that published it. The carry rewrites the history catalogue against each source's original root before the registries. Tests build locations against the root of the registry that reads them instead of the test directory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
|
debt-tools at 46e9e63, every finding: |
|
debt-src at 46e9e63, every finding: |
The carry walked raw JSON by hand: string subscripts on the catalogue, provenance and thread rows, restating the shape RegistryDocument and HistorySource already declare. FieldCodec now walks both documents and hands each ThreadProvenance record to one Relocation change; an archived source names its original root before its threads, so each path is classified against the root that published it. A bound location is a member of the registry location family, so it inherits the resolve and writable it calls, and every writer's result is a SessionFile. The carry test isolates HOME so it never reads this machine's published route. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The registry stored every saved transcript as one absolute string (IDEN-3,
registry_store.py, written bynative_session_files.py). A copied root could not tell its own transcripts from the live root's, so it read and wrote the live root's files.What changed
session_file.py:RegistrySessionLocationfamily.BusSessionLocationholds a root-relative path, rejects absolute paths and.., andresolve(root)joins it under the root.ExternalSessionLocationholds an absolute path. FieldCodec encodes each member as its declared class; there is no kind field.RegistrySessionLocation.from_path(path, root): a path under the root becomes Bus, anything else External. It is used byregistry_store.prepare_native_source,thread_management(new, fork, import, attach),work_dispatchandcheck_root.RegistryStore._bind_threadbinds each decoded location to the store's root (Bound*Session; the root isWireTransient).thread.runtimetherefore resolves under the root that read it, so resume, compaction and everyRuntimeLocationconsumer read the copy's own files. An unbound location refuses.Thread.writable_runtimeis used by pi native launch, pi durable open and manual compaction. An external location written from any root other than the published route raisesRelationViolationError.original_root; a decoded transcript read witness binds to the root that published its thread.SavedSessionFileinnative_session_files.pyis nowBusTranscriptFile.tools/cutover/carry_session_locations.py: a one-shotSessionLocationscarry. FieldCodec walksRegistryDocumentand the catalogue'stuple[HistorySource, ...], and hands eachThreadProvenancerecord to oneRelocationchange. Wire keys come fromFieldCodec.record_key; there are no string subscripts. An archived source names its original root before its threads, so each path is classified against the root that published it. The catalogue is resealed likeClaimFields.Proof
The carry ran through the real step worker (
agent_comms.installer.step_worker) on a scratch copy of the live root, under a held maintenance barrier. The live root was read only.Tests ran on the touched test files and the tests of the touched src, compared with origin/main at the same files:
test_bus_files,test_ircremoveprefix,test_historical_viewsDeclaredFile,carry_bus_history(BusSchema differs from its declaration, red on main since Type Command by its owners' context and result; drop remaining dead Any #2762),optional_awareness,todos, and Give DM peers one typed encoding, fix stale tests, repin native build #2763's set.tests/test_carry_session_locations.py: the carry splits once and a rerun changes nothing; a copied root resolves Bus under the copy and refuses to write External; an unbound location refuses; the catalogue is carried.Paired change: OpenHCSDev/toad#1152, which must land right after this.
Assumed:
RegistryStore, not by aresolve(root)call at each reader. One owner binds, and everythread.runtimeconsumer derives from it.session_filecolumn, transcript checkpoints, native identitysession_file).original_root, because the snapshot copies no sessions.🤖 Generated with Claude Code