You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Session identity is minted fresh on every open, so a restarted or peer instance cannot resume a session #675
SessionManager._open_session() mints a new id on every open
(session/manager.py:150, session_id = str(uuid4())), and SessionManager.create_session() (:100) takes no parameters, so a caller
has no way to supply an existing one. Two other sites also rotate the id:
the operator session reset (session/state.py:356) and the
attestation-staleness refresh (:380).
The store added in #629 is keyed by session id, session_id TEXT PRIMARY KEY on both session_state and closed_sessions
(session/store.py:52-62). docs/configuration.md describes session_state_path as making the ratchet "hold per session across
instances and survive a restart". Wiring the store (#653, #661) is
necessary for that but not sufficient while the identity is regenerated on
every open, since a restarted or peer instance looks up a row key it can
never produce again.
Worth noting for whoever picks this up: SessionState is a dataclass that
already accepts session_id=, so the gap is at the manager entry point
rather than in the data model.
Confirmed all the specifics here manager.py:150, the reset/upgrade_attestation rotation sites, and the schema. Diagnosis is right.
One thing worth flagging before implementing resume: session_id isn't just the session_state_store key, it's also the audit_store key, and AuditChain has no resume awareness, init unconditionally calls _append_session_start() and sequence_number is just len(self._entries), starting at 0 every process. There's also no DB-level guard against this (entry_id, not session_id, is the actual primary key), so it would insert silently rather than failing loudly.
Reusing a session_id across a restart would write a second session_start and colliding (session_id, sequence_number) rows under one id. A live process's own chain verification stays internally sound (it only checks its own in-memory entries), but the persisted, session_id-keyed audit trail becomes ambiguous concretely, find_orphaned_sessions() (called at every startup) would stop flagging the old incarnation as orphaned once the new one closes cleanly, silently hiding a real unclean shutdown. That's a worse problem than the one being fixed.
Also worth keeping reset()/upgrade_attestation() out of scope as those rotate the id on purpose, to invalidate trust in the old one. A resume mechanism should only apply to the very first open of a new process, not those.
Given that, would lean toward not resuming the actual session_id at all keep it process-local and audit-chain-fresh like today, and give session_state_store its own resume key, decoupled from session_id. ctx.agent_manifest is already a stable, process-level (config-bound, not per-call) identity used for kill-switch tracking might be a natural fit, though someone who knows the trust model here should weigh in on whether it's appropriate, and on what happens for anonymous/no-manifest deployments where there'd be no such key. Flagging as a design question rather than proposing a patch, since this touches the audit chain's integrity guarantees and deserves a real decision.
@rajnisht7, keep audit session IDs fresh. Policy-state continuity needs a separate key; it must not resume or overwrite an earlier audit chain.
A configured manifest identity alone does not authorize resumption. The design must define the authenticated principal, logical session scope and authority to resume, so unrelated sessions cannot share state accidentally. Anonymous deployments need an explicit trusted mechanism or must refuse resumption.
Please propose that contract before implementation. Cover restart and concurrent-instance continuity, unauthorized resume attempts, missing stored state, reset invalidation and attestation refresh. Preserve the sensitivity ratchet and orphaned-session evidence, with positive controls for legitimate continuity.
@rajnisht7@imran-siddique I can provide independent verification support for the continuity contract before implementation. Keeping Rajnish's design ownership and the ruling above intact, the bounded review matrix I propose is:
Boundary
Legitimate control
Refusal / evidence control
Resume authority
Authenticated principal resumes its authorized logical scope
Same identifier under a different principal or scope cannot load that state
Audit incarnation
Restart uses a fresh audit session and separate continuity key
Earlier chain is not overwritten; unclean incarnation remains observable as orphaned
Concurrent instances
Authorized shared continuity preserves the maximum sensitivity
Racing lower-state writes cannot roll back the ratchet or create ambiguous authority
Missing state
Contract explicitly distinguishes new authorized scope from resumed scope
Missing/deleted store cannot silently reset a purportedly resumed session to public
Reset
Explicit reset produces its declared invalidation and a fresh audit incarnation
Legitimate refresh preserves/changes continuity only as the contract declares
Old credentials and weaker assurance cannot regain authority through a reused key
Anonymous operation
Explicit trusted resumption mechanism, if supported
No configured authenticated mechanism means resumption is refused
Storage failure
Protected store available and namespace correctly selected
Unavailable/substituted/stale state is visible; rollback resistance is not inferred from SQLite
For each selected refusal, retain a valid twin and a weakening that catches the intended authority/ratchet/evidence guard. Separate process-restart persistence from a claim of rollback resistance or hardware protection. These are proposed acceptance obligations, not executed results or permission to implement a new resumption API. I can review a pinned contract/patch against them once you post it.
Activity
rajnisht7 commentedon Sep 20, 2026
Confirmed all the specifics here manager.py:150, the reset/upgrade_attestation rotation sites, and the schema. Diagnosis is right.
One thing worth flagging before implementing resume: session_id isn't just the session_state_store key, it's also the audit_store key, and AuditChain has no resume awareness, init unconditionally calls _append_session_start() and sequence_number is just len(self._entries), starting at 0 every process. There's also no DB-level guard against this (entry_id, not session_id, is the actual primary key), so it would insert silently rather than failing loudly.
Reusing a session_id across a restart would write a second session_start and colliding (session_id, sequence_number) rows under one id. A live process's own chain verification stays internally sound (it only checks its own in-memory entries), but the persisted, session_id-keyed audit trail becomes ambiguous concretely, find_orphaned_sessions() (called at every startup) would stop flagging the old incarnation as orphaned once the new one closes cleanly, silently hiding a real unclean shutdown. That's a worse problem than the one being fixed.
Also worth keeping reset()/upgrade_attestation() out of scope as those rotate the id on purpose, to invalidate trust in the old one. A resume mechanism should only apply to the very first open of a new process, not those.
Given that, would lean toward not resuming the actual session_id at all keep it process-local and audit-chain-fresh like today, and give session_state_store its own resume key, decoupled from session_id. ctx.agent_manifest is already a stable, process-level (config-bound, not per-call) identity used for kill-switch tracking might be a natural fit, though someone who knows the trust model here should weigh in on whether it's appropriate, and on what happens for anonymous/no-manifest deployments where there'd be no such key. Flagging as a design question rather than proposing a patch, since this touches the audit chain's integrity guarantees and deserves a real decision.
imran-siddique commentedon Sep 24, 2026
@rajnisht7, keep audit session IDs fresh. Policy-state continuity needs a separate key; it must not resume or overwrite an earlier audit chain.
A configured manifest identity alone does not authorize resumption. The design must define the authenticated principal, logical session scope and authority to resume, so unrelated sessions cannot share state accidentally. Anonymous deployments need an explicit trusted mechanism or must refuse resumption.
Please propose that contract before implementation. Cover restart and concurrent-instance continuity, unauthorized resume attempts, missing stored state, reset invalidation and attestation refresh. Preserve the sensitivity ratchet and orphaned-session evidence, with positive controls for legitimate continuity.
dinakarjs commentedon Oct 15, 2026
@rajnisht7 @imran-siddique I can provide independent verification support for the continuity contract before implementation. Keeping Rajnish's design ownership and the ruling above intact, the bounded review matrix I propose is:
For each selected refusal, retain a valid twin and a weakening that catches the intended authority/ratchet/evidence guard. Separate process-restart persistence from a claim of rollback resistance or hardware protection. These are proposed acceptance obligations, not executed results or permission to implement a new resumption API. I can review a pinned contract/patch against them once you post it.