Context
Filed 2026-05-09 from a daemon-coordination brainstorm with @tobiu. Empirical gap: the session-sunset skill correctly differentiates between Shared Checkout and Isolated Worktree harness classes, but the Isolated Worktree branch leaves the operator's primary checkout silently stale — the bridge daemon and other daemons running from the primary checkout (/path/to/neo/ rather than .claude/worktrees/<name>/) read pre-merge code until the operator manually runs git pull origin dev.
Substrate citation from .agents/skills/session-sunset/references/<...>:
Shared Checkout (Antigravity/Gemini): Execute git checkout dev && git pull origin dev.
Isolated Worktree (Claude Code): Do NOT checkout dev (which would conflict with the main checkout). Instead, ensure your current PR branch is fully committed and pushed. The next agent session will either resume this worktree or bootstrap a new one from the main checkout's updated dev.
The phrase "main checkout's updated dev" assumes the operator has pulled origin/dev into the primary checkout, but the skill doesn't define the trigger. In practice the operator's primary dev can fall arbitrarily behind origin/dev between sunset events, so daemons running from primary read stale code.
The Problem
Bridge-daemon and other daemons running from primary checkout depend on primary's dev being current:
- bridge-daemon (reads source for delivery logic + skill payloads)
- DreamService (reads source for ingestion patterns)
- Future orchestrator-daemon (post-#11009) (reads source for task definitions)
- KB sync pipeline (reads source for indexing)
When primary's dev is stale, these run pre-merge code. The shared-checkout discipline (sunset auto-pulls) closes the gap on the Antigravity/Gemini side; the isolated-worktree branch leaves the gap open.
This is friction-to-gold: the substrate already differentiates harness classes at sunset, but doesn't surface the staleness signal to the operator. Adding a one-line check + conditional reminder to the Isolated Worktree branch closes the discipline loop.
The Architectural Reality
.agents/skills/session-sunset/references/<...>.md — Step 1 / Codebase Sync section already has the harness-class discrimination. The Isolated Worktree branch is the natural place to extend.
bridge-daemon.mjs's scope is "wake delivery only" per its JSDoc; adding pull logic crosses its scope boundary. Not the substrate for the daemon-driven solution (see Out of Scope).
- The cleaner long-term solution is a daemon-driven auto-pull task in
Orchestrator.mjs post-#11009 (Shape A in the brainstorm). This ticket implements the interim discipline-only path (Shape B).
The Fix
Extend the Isolated Worktree branch in the session-sunset skill payload with a primary-checkout staleness check:
- Detect staleness: during sunset Step 1 (Codebase Sync), the agent runs
git -C <primary-checkout-path> rev-list --count HEAD..origin/dev to detect commit-count delta.
- Conditional reminder: if
behind > 0, append a ⚠️ Primary-checkout reminder block to the sunset handover comment template, instructing the operator to run git -C <primary> pull origin dev for fresh bridge-daemon + downstream-daemon state.
- No-op when fresh: if
behind == 0, skip the reminder (no handover-comment noise).
The primary-checkout path detection: from a worktree, the primary checkout is one level up from .claude/worktrees/<name>/ — the agent can either resolve via git rev-parse --git-common-dir (returns the shared .git/ location, which is inside primary's .git/) or use a known repo-root convention.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
| Session-sunset Isolated Worktree branch |
This ticket + brainstorm with @tobiu |
Conditional ⚠️ reminder when primary dev lags origin/dev |
If staleness check fails (e.g., primary path unresolvable), emit a soft warning rather than skip silently |
.agents/skills/session-sunset/references/<...>.md |
grep confirms the reminder section exists; manual sunset rehearsal verifies the conditional fires when N>0 |
| Operator-visible signal |
This ticket |
Operator sees the warning in the sunset handover comment when applicable |
None — discipline-only path |
Sunset handover comment template |
Empirical sunset event on a stale-primary worktree surfaces the warning |
Acceptance Criteria
Out of Scope
- Daemon-driven auto-pull (Shape A from brainstorm): add a
primary-dev-sync task to Orchestrator.mjs post-#11009 that runs git pull --ff-only origin dev automatically. Separate follow-up ticket; depends on #11009 landing first. This ticket is Shape B (interim discipline-only).
- Bridge-daemon scope expansion: bridge-daemon stays focused on wake delivery only per its JSDoc + #11006. Pull discipline lives in orchestrator-daemon, not bridge-daemon.
- Pre-merge primary-pull (proactive sync): this ticket only addresses sunset-time discipline. Mid-session staleness is unaddressed (Shape A handles that).
- Symlink-based shared-state alternatives: #10224 ("Unify .neo-ai-data across worktrees via bootstrap symlink") is closed and orthogonal to this concern.
Avoided Traps
- Bundle Shape A + Shape B in one ticket: Shape A depends on #11009 landing; bundling would block the immediate Shape B fix on multi-step substrate work. Sub-tickets keep the scope reviewable.
- Make the warning unconditional: noise when
behind == 0 adds clutter to every sunset handover; conditional fire is cleaner.
- Move pull logic into bridge-daemon: crosses bridge-daemon's scope boundary per its JSDoc. Orchestrator-daemon is the v13-path.md M3 home for scheduled-maintenance tasks.
- Skip the path-detection mechanism in AC4: without explicit detection, agents may emit the warning against their own worktree path (which is always fresh because they just pulled their feature branch) rather than the operator's primary checkout.
Related
- Daemon-driven follow-up (Shape A): to be filed post-#11009 merge; will register
primary-dev-sync task in Orchestrator.mjs.
- Orchestrator class extraction: #11009 — Shape A's prerequisite.
- Session-sunset skill substrate:
.agents/skills/session-sunset/
- Bridge-daemon scope boundary: #11006, #11008 (orchestrator MVP that established daemon scope split).
- Closed adjacent ticket: #10224 (symlink-based shared-state across worktrees) — closed, orthogonal scope.
Origin Session ID: c2912891-b459-4a03-b2af-154d5e264df1
Retrieval Hint: query_raw_memories(query="session-sunset primary-checkout dev staleness isolated worktree bridge-daemon Shape B interim discipline-only orchestrator post-#11009")
Context
Filed 2026-05-09 from a daemon-coordination brainstorm with @tobiu. Empirical gap: the session-sunset skill correctly differentiates between Shared Checkout and Isolated Worktree harness classes, but the Isolated Worktree branch leaves the operator's primary checkout silently stale — the bridge daemon and other daemons running from the primary checkout (
/path/to/neo/rather than.claude/worktrees/<name>/) read pre-merge code until the operator manually runsgit pull origin dev.Substrate citation from
.agents/skills/session-sunset/references/<...>:The phrase "main checkout's updated
dev" assumes the operator has pulled origin/dev into the primary checkout, but the skill doesn't define the trigger. In practice the operator's primarydevcan fall arbitrarily behind origin/dev between sunset events, so daemons running from primary read stale code.The Problem
Bridge-daemon and other daemons running from primary checkout depend on primary's
devbeing current:When primary's
devis stale, these run pre-merge code. The shared-checkout discipline (sunset auto-pulls) closes the gap on the Antigravity/Gemini side; the isolated-worktree branch leaves the gap open.This is friction-to-gold: the substrate already differentiates harness classes at sunset, but doesn't surface the staleness signal to the operator. Adding a one-line check + conditional reminder to the Isolated Worktree branch closes the discipline loop.
The Architectural Reality
.agents/skills/session-sunset/references/<...>.md— Step 1 / Codebase Sync section already has the harness-class discrimination. The Isolated Worktree branch is the natural place to extend.bridge-daemon.mjs's scope is "wake delivery only" per its JSDoc; adding pull logic crosses its scope boundary. Not the substrate for the daemon-driven solution (see Out of Scope).Orchestrator.mjspost-#11009 (Shape A in the brainstorm). This ticket implements the interim discipline-only path (Shape B).The Fix
Extend the Isolated Worktree branch in the session-sunset skill payload with a primary-checkout staleness check:
git -C <primary-checkout-path> rev-list --count HEAD..origin/devto detect commit-count delta.behind > 0, append a⚠️ Primary-checkout reminderblock to the sunset handover comment template, instructing the operator to rungit -C <primary> pull origin devfor fresh bridge-daemon + downstream-daemon state.behind == 0, skip the reminder (no handover-comment noise).The primary-checkout path detection: from a worktree, the primary checkout is one level up from
.claude/worktrees/<name>/— the agent can either resolve viagit rev-parse --git-common-dir(returns the shared.git/location, which is inside primary's.git/) or use a known repo-root convention.Contract Ledger Matrix
⚠️reminder when primarydevlags origin/dev.agents/skills/session-sunset/references/<...>.mdgrepconfirms the reminder section exists; manual sunset rehearsal verifies the conditional fires when N>0Acceptance Criteria
HEAD..origin/dev).⚠️ Primary-checkout reminderblock in handover-comment template fires whenbehind > 0; suppressed whenbehind == 0.git -C <primary> pull origin devwith explicit rationale (refresh bridge-daemon + downstream-daemon state).git rev-parse --git-common-diror repo-root convention) so agents can reliably resolve the primary checkout path from a worktree.create-skillguide §"Byte Budget").Out of Scope
primary-dev-synctask toOrchestrator.mjspost-#11009 that runsgit pull --ff-only origin devautomatically. Separate follow-up ticket; depends on #11009 landing first. This ticket is Shape B (interim discipline-only).Avoided Traps
behind == 0adds clutter to every sunset handover; conditional fire is cleaner.Related
primary-dev-synctask inOrchestrator.mjs..agents/skills/session-sunset/Origin Session ID:
c2912891-b459-4a03-b2af-154d5e264df1Retrieval Hint:
query_raw_memories(query="session-sunset primary-checkout dev staleness isolated worktree bridge-daemon Shape B interim discipline-only orchestrator post-#11009")