Repository navigation
Conversation
When a pane agent is first observed, its authoritative session ref (herdr detection or shepherd-pi registration) may not have landed yet, so history resolution falls back to cwd-based discovery. Discovery scans fixed roots (~/.pi/agent/sessions and peers) and ranks by cwd match and mtime, which can select an unrelated stale session that happens to share the cwd. That session's content is then persisted into status events and delivered to the orchestrator's wake messages, misattributing another run's output. A session file untouched since before the agent's first_seen_at cannot be that agent's live session, so discovery now drops candidates older than first_seen_at (10 min grace) and reports no history rather than a guessed one.
ryonakae
left a comment
There was a problem hiding this comment.
Thanks for investigating the stale-session attribution issue. The problem is real, and filtering candidates by recency is a useful direction.
The current implementation still has correctness gaps that should be addressed before merging:
-
A previous session from the same cwd remains eligible for ten minutes, so a recently completed run can still be attributed to a newly started agent. After stale cwd-matching candidates are removed, a newer candidate from a different cwd may also be selected.
-
firstSeenAtis Shepherd's first observation time, not necessarily the agent process start time. When Shepherd first observes an already-running agent, valid history that has not been updated for ten minutes can be rejected. Conversely,first_seen_atcan be retained when a stable terminal is reused, making the filter ineffective for a later run. -
OpenCode cwd discovery and previously persisted
discovered_filerefs bypass the new recency check.
Please define a discovery rule that fails closed when candidate ownership cannot be established, and add tests for recently completed same-cwd sessions, different-cwd candidates, adoption of an already-running agent, OpenCode, and persisted discovered refs.
I agree with the goal of the PR, but I don't think the current filter is strong enough to prevent the misattribution it is intended to fix. Happy to re-review after these cases are addressed.
… and enforce preferred ref cwd verification
|
Closing as stale — this work has moved to a separate repository. |
What & why
When a pane agent is first observed, its authoritative session ref (
agent_session) may not have landed yet, causing history resolution to fall back todiscoverAgentHistory. Discovery scans candidate session roots and ranks them by cwd and mtime.Previously, if an unrelated stale session shared the pane's cwd, discovery would pick it as the best candidate. That stale ref would then be persisted (
discovered_file) and used for status events and wake summaries, misattributing output from another run.Fix principle
Fail-closed: better to report no history than wrong or misattributed history.
candidate.cwd === cwdare considered. If cwd is missing or does not match, discovery fails closed and returnsnullwithout falling back to other directories.firstSeenAtMs(candidate.mtimeMs < firstSeenAtMs). The previous 10-minute grace window (DISCOVERY_RECENCY_GRACE_MS) has been removed in favor of strict cut-off.isAdoption):isAdoptionis only set totruewhen Shepherd initially discovers an already-running agent without prior tracking in Shepherd DB, exempting only that initial take-over run from recency cutoffs.done-> non-donestatus transition, pane revision decrement, agent change, or cwd change),first_seen_atis reset to the current timestamp,isAdoptiontransitions tofalse, andagent_session_hint_jsonis cleared tonull.AgentStore&AgentIndexService):AgentStore.updateStatusandreplaceForSessionclearagent_session_hint_jsonand resetis_adoption = 0ondone-> non-donetransitions.sameIdentityincludesfirstSeenAtandisAdoption, ensuring status-driven new runs triggeridentityChangedand force fresh discovery.isValidPreferredRef):readCandidateCwdor.project_root) and pass recency checks before reuse; unproven or mismatched refs fail closed and fall back to discovery.kind: "agent_session"refs (wheninput.agentSessionis null or does not match) are no longer unconditionally allowed and must pass cwd and recency validation.input.agentSessionremain trusted.Candidate[]in the same candidate filtering (cwd,firstSeenAtMs) and mtime ranking.Testing
firstSeenAtMs.firstSeenAtMs(isAdoption: true).firstSeenAtMs.opencode-sqlite).isAdoptionlifecycle states (initial adoption, live continuation, and subsequent new run).pane.agent_status_changeddone -> working) clearing session hint and forcing discovery.agent_sessionrefs wheninput.agentSessionis null.first_seen_atand session hint clearing on terminal reuse across new runs inAgentStore.discovered_filerefs viaisValidPreferredRefwith discovery fallback.agent_sessionrefs matchinginput.agentSession.pnpm typecheckandpnpm testclean).