LearnNewsExamplesServices
Frontmatter
id12853
titleSunset codebase-sync mis-routes on harness label, not checkout state
stateClosed
labels
enhancementaimodel-experience
assigneesneo-opus-grace
createdAtJun 10, 2026, 8:44 PM
updatedAtJun 10, 2026, 8:54 PM
githubUrlhttps://github.com/neomjs/neo/issues/12853
authorneo-opus-grace
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 10, 2026, 8:54 PM

Sunset codebase-sync mis-routes on harness label, not checkout state

Closed v13.0.0/archive-v13-0-0-chunk-17 enhancementaimodel-experience
neo-opus-grace
neo-opus-grace commented on Jun 10, 2026, 8:44 PM

Context

Operator @tobiu (2026-06-10) observed agents finishing sessions on a stale repo — stale dev and a stale generated ai/config.mjs — and asked us to refresh (switch to dev in the main checkout, git pull, regenerate config via ai/scripts/setup/initServerConfigs.mjs). Verify-Before-Assert while filing surfaced that the Sunset Protocol already prescribes exactly this (session-sunset-workflow.md Step 1 + the #11013 Primary-Checkout Staleness Probe). So the friction is not a missing step — it is that the existing step routes on the wrong signal and offloads the work to the operator.

The Problem

session-sunset-workflow.md Step 1 ("Codebase Synchronization — The Pre-Sunset Pull") branches on harness identity, not on the agent's actual checkout state:

  • "Shared Checkout (Antigravity/Gemini)"git checkout dev && git pull origin dev
  • "Isolated Worktree (Claude Code)" → do NOT checkout dev; push your branch; run the staleness probe; if primary is behind, emit a handover-comment asking the operator to run git pull + initServerConfigs.mjs --migrate-config.

Two empirically-confirmed failures fall out of this:

  1. Harness label ≠ checkout reality. This session is @neo-opus-grace (Claude Code) running in the main checkout on dev — verified: git rev-parse --git-dir.git; git worktree list → single entry. The workflow hardcodes "Claude Code → Isolated Worktree," so a literal reading routes a main-checkout agent down the worktree branch → it does NOT pull dev and instead nags the operator. That is precisely the "none of you updated your repo" friction.
  2. The Shared-Checkout path never regenerates config. It runs git checkout dev && git pull origin dev and stops — it never runs initServerConfigs.mjs, so the gitignored ai/config.mjs overlay keeps stale leaves after config.template.mjs changes → AiConfig.X.Y resolves undefined at runtime (the documented config.template-vs-config.mjs drift). Only the worktree handover-comment branch mentions --migrate-config, and that branch hands it to the operator.

Net effect: an agent that could self-refresh (main checkout) is told to offload to the operator, and an agent that does pull (shared checkout) skips the config regen. The operator ends up running the refresh by hand — the observed friction.

The Architectural Reality

  • File: .agents/skills/session-sunset/references/session-sunset-workflow.md, Step 1 (~lines 52–86).
  • The correct discriminator is runtime checkout detection, available cheaply from git and already used in the same file by the #11013 probe: git rev-parse --git-dir (main → .git; linked worktree → an absolute …/.git/worktrees/<name>), or --git-common-dir vs --git-dir. This is harness-agnostic and therefore more fork-safe than hardcoded harness names (forks / npx neo-app inherit .agents/skills/**).
  • ai/scripts/setup/initServerConfigs.mjs already exists and supports --migrate-config (operator-overlay reconcile). No new .mjs → structural-pre-flight not triggered.
  • The thin session-sunset/SKILL.md router stays untouched; the change lands entirely in the references/ workflow doc — Progressive Disclosure preserved (confirmed against create-skill / ADR 0008).

The Fix

Rewrite Step 1 to branch on detected checkout state, not harness label:

  • Main checkout (any harness), clean tree: git switch dev && git pull --ff-only origin dev && node ai/scripts/setup/initServerConfigs.mjs --migrate-config. The agent self-serves; no operator handover-comment.
  • Linked worktree: keep current behavior (do NOT checkout dev; commit+push the PR branch; run the #11013 primary-staleness probe; emit the operator handover-comment only when BEHIND > 0) — an agent legitimately cannot safely mutate primary's branch from a worktree.
  • Make the initServerConfigs.mjs --migrate-config regen explicit on both the main-checkout self-serve path and the worktree handover-comment (the latter already has it).

Decision Record impact: none — refines existing protocol, no ADR conflict; aligned-with the #11013 staleness-probe intent.

Acceptance Criteria

  • Step 1 routing discriminator is runtime checkout detection (git-dir / common-dir), not harness-identity strings.
  • Main-checkout path runs git switch dev + git pull --ff-only origin dev + initServerConfigs.mjs --migrate-config, executed by the agent (no operator offload).
  • Worktree path unchanged in spirit (no dev checkout; push branch; probe; conditional handover-comment) and explicitly retains the --migrate-config regen instruction.
  • No new harness-name hardcoding; language is harness-agnostic (fork-safe).
  • session-sunset/SKILL.md router unchanged (Progressive Disclosure preserved).

Out of Scope

  • Automating the primary-checkout pull via a daemon (orchestrator-daemon primary-dev-sync periodic task) — the #11013 follow-up (Shape A), tracked separately.
  • Mid-session staleness (this is sunset-scoped).
  • Changes to initServerConfigs.mjs itself.

Avoided Traps

  • "Just add a repo-refresh step" — rejected: the step already exists; the defect is mis-routing + missing regen, not absence. (V-B-A caught this before filing — the exact value of the §0 intent gate.)
  • Keying on harness identity (the current approach) — brittle: the harness↔checkout mapping is deployment-specific and was already false this session.

Related

  • #11013 — origin of the Primary-Checkout Staleness Probe this ticket refines.
  • #12696 — [Epic] v13 release (board attachment).

Handoff Retrieval Hints

  • query_raw_memories: "sunset codebase sync harness label vs checkout state"
  • Grep anchor: session-sunset-workflow.md Step 1 — "Shared Checkout" / "Isolated Worktree".

Filed by @neo-opus-grace (Claude Code) per operator @tobiu friction report, 2026-06-10.