Repository navigation
Replies: 3 comments 2 replies
|
I verified the load-bearing claim in source, and the rule holds up. Do this: Confirm the gap first ( Take the general-proof branch, not the restore-path re-read. Your four guards (own launch, resume-sourced, same process, one hop) map onto machinery that already exists: the occupant-tenure generation ledger already distinguishes 'same launch' from 'new tenure', so the T2-acceptance can ride the same comparison instead of adding restore-path special-casing that every future rotation path would need to duplicate. On your open questions: source-absent must fail closed (your rule already does — old Claude versions just keep today's behavior); T2 should stay 'hook-accepted for this launch' rather than becoming argv-equivalent, because a later restore replays argv and would then bless the rotated id without a fresh hook. One test to demand of whichever PR implements it: the B-case (same process, |
|
Thanks, @haralez, for a precise report from a real host: one of eleven Claude seats was restored with You offered a PR, and a focused one with regression tests would be welcome. On your three questions, we'd rather the PR take a position on each, with its reasons, than settle them in this thread; the review will decide. The tests should keep today's distinctions between resume, clear, startup and compact. In particular, a |
|
PR: #1080. It follows the rule proposed here, takes a position with reasons on each of the three open questions (rely on |
Uh oh!
There was an error while loading. Please reload this page.
What I'm trying to do, and what stops me
After
rig up <rig> --existingrestores a Claude Code seat with--resume <id>, Claude Code sometimes continues the conversation under a new session id. OpenRig's SessionStart hook then records the new id, and from that point the seat can never pass the strict identity proof:selectNativeProcess(native-process-lineage.ts) requires the--resumetoken in the process argv to equal the stored token. Argv still says the old id; the stored token is the new one.rig seat clear-attentioncan't verify the seat, and it staysattention_requiredfor the life of that process. Everyrig sendto it warns: "Claude launch identity differs from the stored conversation; current conversation is unverified".The seat is healthy, and nothing an operator can do short of restarting it clears the state.
set-resume-tokenback to the argv id would be wrong, because the new id is the conversation that is actually being written.Evidence (OpenRig 0.6.6 and 0.6.7, Linux, Claude Code 2.1.x)
One of eleven Claude seats on one host after a reboot restore:
claude --resume T1.T2: theT2.jsonltranscript is the one being appended, andT1.jsonlstopped at the restore time.T1(provenance scrape/operator) toT2(provenancehook).rig psshows the seatattention_required,clear-attentioncan't prove it, and every send to it carries the warning above.The other ten seats kept their id on resume and prove fine. Any resumed seat whose id rotates will hit this.
Why this is not just "trust the hook"
The refusal is deliberate, and the comment in
observeClaudeDeliverygives the reason:That's right as far as it goes. Today the daemon can't tell these two cases apart:
T1T2T1and Claude Code continued asT2(this report)T1T2/clearin the same process, starting a new conversationT2T1T2The missing fact: Claude already says which case it is
Claude Code's SessionStart hook input carries
source:startup,resume,clearorcompact. OpenRig's relay (activity-relay.cjs,buildSessionIdentityPayload) runs on every SessionStart (no matcher) but forwards onlysession_id, so the daemon receives A and B as the same event.Proposed rule
Accept a stored Claude token
T2that differs from the argv tokenT1only when all of these hold. Otherwise keep today's behaviour (unknown).T1is the token OpenRig itself launched this occupant with: the restore or launch recorded it on this session row (or its launch receipt) for the same seat and launch generation.T2was recorded by the hook withsource: "resume"(newly relayed), for this same session row, after that launch and before any other SessionStart for it. Asource: "clear"or"startup"record never qualifies.T1 → T2once per launch. A laterclearmakes the seat unverified again, which is today's behaviour.Why it stays safe
/clear) reportssource: "clear", so rule 2 refuses it. The current refusal is kept exactly where it matters.source: "resume"hook record tied to this launch, so rules 1 and 2 refuse it.Cost to everyone else
source) to the session-identity post, and the daemon stores it with the token's provenance.Open questions for maintainers
sourcestable enough across Claude Code versions to rely on? If it is absent, the rule simply doesn't apply (fail closed).T2also become the argv-equivalent for later restores, or stay "hook-accepted for this launch" only?I'm happy to send a PR for whichever shape you prefer.
All reactions