refactor(provider): adapter-owned state composition — ReadChat replaces ReadTranscript; PendingDialog/BlockedState become adapter-private (ADR-0038) #94
No reviewers
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/coding-lab!94
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "afk/92"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #92
What
The seam method
ReadTranscript(path)becomesReadChat(runID, runtimeDir, transcriptPath), and conversational-state composition moves wholly into the adapters. Core owns run lifecycle only — theStateEndedoverride and transcript identity. Behavior-neutral: identical state semantics, identical HTTP payload (pending_dialog,transcript_id, state vocabulary byte-for-byte).How
internal/provider/provider.go):ReadChatwith pinned""semantics — an emptytranscriptPath(active run, transcript not yet located) must still consult live signals and yields an idle empty chat, never an error; an emptyruntimeDiris a transcript-only read, which is exactly how core reads ended runs, so terminal spool-residue leaks are impossible by construction.provider.Chatgains thePendingDialogside-channel field — never a synthetic message, so the #89/#90 reparse-stable-seq invariant transfers verbatim.Setup,SpoolSig,SweepSpools.PendingDialog/BlockedStateare now claudecode-private functions, applied inside itsReadChatwith core's exact old precedence (live spool dialog → question + side channel; transcript-flushed dialog stands — the dormant fallback; blocked marker → needs_input; else transcript state).internal/chat):applyLiveSignalsand theliveSignals()resolver deleted;Readand the tailer callReadChat;ViewforwardsChat.PendingDialogvia embedding and keepsTranscriptID+ theStateEndedoverride. The tailer stages stat results and commits them only after a successful read, so a failed read retries next tick.runID/runtimeDirignored; both adapters' exportedParseTranscriptcompat entry points untouched.read-chatobligation (empty-path idle contract,ErrTranscriptGonesentinel) — both adapters pass through the existing registration table; broken-adapter coverage for all three failure shapes.ReadChatargs, so core tests pin the forwarding (seam args per run outcome), while composition itself is pinned in the adapters' own tests.Regression guards (issue checklist)
Chat.PendingDialogand in claudecode's composition tests.StateQuestionwith nil side channel (claudecode + core forwarding tests).StateEndedregardless of spool residue — asserted by construction (ReadCallsshowsruntimeDir ""for the ended read).Verification
gofmtclean,CGO_ENABLED=0 go build ./...,go vet ./...,golangci-lint run(0 issues),go test ./...— all green exceptinternal/tmuxxintegration tests, which fail identically on the base commit in this sandbox (tmux sessions cannot spawn here; pre-existing, unrelated). Live compat recipe tests compile (vet) and stay env-gated.🤖 Generated with Claude Code
https://claude.ai/code/session_01Erjjo4AEr16vSAxM9AFqou