Filed unassigned by the domain:devx PM seat (session session_015ahemw8RcTgqtxrj15PEZx). Recording only — ⛔ no domain:* label applied; routing and grading are triage's.
Measured while deriving model tiers for a dispatch batch, on the shared checkout at /home/user/objectstack.
The recipe names a ref, and nothing refreshes it
Three places prescribe the same incantation, base ref included:
| where | text |
|---|
CLAUDE.md:33 (objectstack) | git worktree add ../<repo>-<task> -b <branch> main && cd ../<repo>-<task> && pnpm install |
CLAUDE.md:16 (objectui) | identical |
AGENTS.md:173 — Prime Directive #11 itself | git worktree add ../objectstack-<task> -b <branch> main && cd ../objectstack-<task> && pnpm install |
main here is the local branch ref, not origin/main. Nothing in the recipe, and nothing in the surrounding prose, fetches. So the base a dev inherits is only as fresh as whenever someone last happened to update that ref on the shared checkout — and on a long-lived container nobody has a reason to.
Measured on the live shared checkout
local main : 76876ac3 2026-08-16T14:39:32+00:00
origin/main : cd932772 2026-08-24T02:34:46+00:00
behind : 120 commits
age gap : 179 hours (7.5 days)
git merge-base main origin/main is main itself, so this is not a divergence to reconcile — a branch created by the documented recipe today starts 120 commits back, by construction. No judgement call, no race, no unlucky timing.
⚠️ Honest scope: this is latent, not a live incident
I checked the one dev worktree in flight at the time (objectstack-issue-10611). Its merge-base with origin/main is daacc107 — 2 commits back, i.e. that dev fetched and branched off origin/main rather than following the recipe literally. So:
- live instances of a dev bitten by this: zero, as measured.
- The agents currently working this repo are, in practice, doing the right thing despite the recipe rather than because of it.
That makes this the same shape as #11494 — a counting/authoring contract that is violated the moment something lands on it, with no live instance today. It is filed on that basis and should be graded on that basis, not as an incident.
⭐ The related half that DID cause a live wrong reading, and is a different mechanism
The stale ref above is latent. The stale working tree of the same checkout is not — it produced a wrong instrument reading this shift:
The PM seat derives model tiers by running node scripts/pm/dispatch-gates.mjs --tier <paths> from /home/user/objectstack. That checkout sits at b863f012, and its on-disk copy of that script hashes 00a51862…, while origin/main's copy hashes edfe4ab1…. The two differ because PR #11512 changed that exact file. The stale copy runs and exits 0 and prints a well-formed tier verdict — it just answers about a tree nobody is on.
This was caught only because #11512 had landed minutes earlier in that specific file, so the check was top of mind. Nothing in the tool, the output, or the workflow would have said so otherwise: dispatch-gates prints the commit it derived from (derived from the tree of … at commit <sha>), which is exactly the line that would have exposed it — but that line names the checkout's own HEAD, so a stale checkout reports its staleness in a form that reads as ordinary provenance.
Both halves share one root: the shared checkout is never refreshed, and everything that reads it — the documented base ref, and every tool invoked from it — silently inherits whatever staleness has accumulated.
Workaround in use by this seat, offered as a shape rather than a prescription: a detached worktree pinned at origin/main for tool runs (git worktree add --detach ../objectstack-pm-main origin/main), so derivations are provably against the tree being dispatched for.
Direction (not a decision)
- Change the base in all three texts to
origin/main, and prepend an explicit git fetch origin main. Cheapest, and it makes the recipe self-sufficient rather than dependent on checkout hygiene nobody owns. - Leave the recipe and make the staleness visible instead — e.g. have the tooling that reads the shared checkout assert its HEAD against
origin/main and say so loudly. Attacks the second half, which is the one with a measured wrong reading. - Both. They are independent: (1) fixes what a dev branches off, (2) fixes what a tool reports about.
⚠️All three target files are governed surface (AGENTS.md, CLAUDE.md in both repos). Whatever route is chosen, the PR stays draft and is merged by the maintainer by hand — no AI seat merges, queues, or arms auto-merge on it. Note also AGENTS.md:203 carries the recipe a second time as git worktree add ../objectstack-<task> -b <branch> with no base ref at all, which silently bases off whatever the shared checkout's HEAD happens to be — a related but distinct hazard, and arguably the worse of the two since it has no stated base to be wrong about.
Searched before filing
worktree main stale (0 hits) · origin/main base branch recipe (0) · dispatch-gates stale checkout (0). ⚠️ The zero-hit readings are reported as live because a control query in the same window (platform-checklist) returned known-present results — #11421 and #11524 — so the search surface was responding.
Refs: #11512 (the PR whose landing exposed the stale tool copy) · #11190 · #11494 (same latent-contract shape)
Filed unassigned by the
domain:devxPM seat (sessionsession_015ahemw8RcTgqtxrj15PEZx). Recording only — ⛔ nodomain:*label applied; routing and grading are triage's.Measured while deriving model tiers for a dispatch batch, on the shared checkout at
/home/user/objectstack.The recipe names a ref, and nothing refreshes it
Three places prescribe the same incantation, base ref included:
CLAUDE.md:33(objectstack)git worktree add ../<repo>-<task> -b <branch> main && cd ../<repo>-<task> && pnpm installCLAUDE.md:16(objectui)AGENTS.md:173— Prime Directive #11 itselfgit worktree add ../objectstack-<task> -b <branch> main && cd ../objectstack-<task> && pnpm installmainhere is the local branch ref, notorigin/main. Nothing in the recipe, and nothing in the surrounding prose, fetches. So the base a dev inherits is only as fresh as whenever someone last happened to update that ref on the shared checkout — and on a long-lived container nobody has a reason to.Measured on the live shared checkout
git merge-base main origin/mainismainitself, so this is not a divergence to reconcile — a branch created by the documented recipe today starts 120 commits back, by construction. No judgement call, no race, no unlucky timing.I checked the one dev worktree in flight at the time (
objectstack-issue-10611). Its merge-base withorigin/mainisdaacc107— 2 commits back, i.e. that dev fetched and branched offorigin/mainrather than following the recipe literally. So:That makes this the same shape as #11494 — a counting/authoring contract that is violated the moment something lands on it, with no live instance today. It is filed on that basis and should be graded on that basis, not as an incident.
⭐ The related half that DID cause a live wrong reading, and is a different mechanism
The stale ref above is latent. The stale working tree of the same checkout is not — it produced a wrong instrument reading this shift:
The PM seat derives model tiers by running
node scripts/pm/dispatch-gates.mjs --tier <paths>from/home/user/objectstack. That checkout sits atb863f012, and its on-disk copy of that script hashes00a51862…, whileorigin/main's copy hashesedfe4ab1…. The two differ because PR #11512 changed that exact file. The stale copy runs and exits 0 and prints a well-formed tier verdict — it just answers about a tree nobody is on.This was caught only because #11512 had landed minutes earlier in that specific file, so the check was top of mind. Nothing in the tool, the output, or the workflow would have said so otherwise: dispatch-gates prints the commit it derived from (
derived from the tree of … at commit <sha>), which is exactly the line that would have exposed it — but that line names the checkout's own HEAD, so a stale checkout reports its staleness in a form that reads as ordinary provenance.Both halves share one root: the shared checkout is never refreshed, and everything that reads it — the documented base ref, and every tool invoked from it — silently inherits whatever staleness has accumulated.
Workaround in use by this seat, offered as a shape rather than a prescription: a detached worktree pinned at
origin/mainfor tool runs (git worktree add --detach ../objectstack-pm-main origin/main), so derivations are provably against the tree being dispatched for.Direction (not a decision)
origin/main, and prepend an explicitgit fetch origin main. Cheapest, and it makes the recipe self-sufficient rather than dependent on checkout hygiene nobody owns.origin/mainand say so loudly. Attacks the second half, which is the one with a measured wrong reading.AGENTS.md,CLAUDE.mdin both repos). Whatever route is chosen, the PR stays draft and is merged by the maintainer by hand — no AI seat merges, queues, or arms auto-merge on it. Note alsoAGENTS.md:203carries the recipe a second time asgit worktree add ../objectstack-<task> -b <branch>with no base ref at all, which silently bases off whatever the shared checkout's HEAD happens to be — a related but distinct hazard, and arguably the worse of the two since it has no stated base to be wrong about.Searched before filing
worktree main stale(0 hits) ·origin/main base branch recipe(0) ·dispatch-gates stale checkout(0).platform-checklist) returned known-present results — #11421 and #11524 — so the search surface was responding.Refs: #11512 (the PR whose landing exposed the stale tool copy) · #11190 · #11494 (same latent-contract shape)