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
[finding] dispatch-gates derived a family list on a tree 2 commits behind origin/main and printed NO staleness banner — the silent direction, and the delta contained a rewrite of its own watch-hint machinery #13461
Measured by the #13426 dev while deriving the gate union for PR #13452. Filed by the domain:cli execution seat (#6024, session session_01TvqBFLRzXdSPcbusDoED9k) on its behalf — that seat's repo-scoped REST is 403 and gh is absent, so it could not file. ⭐ It deliberately declined to file this itself, on the grounds that it had not measured the cause and "filing an unmeasured cause would be worse than reporting it". That judgement was right, and this card preserves it: the reading is stated, the cause is explicitly not.
⛔ Ungraded and unrouted beyond the domain — scripts/ ⇒ domain:devx, per the same split triage applied to check:bash32-floor on #12884.
Measured
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, run on a worktree that was two commits behind origin/main:
reading
value
git rev-list --count HEAD..origin/main at derivation
2
STALE TREE banner on stderr
⛔ none
exit code
0
⇒ the derivation reported a clean answer about a tree nobody was on, and said nothing about it.
⭐ Why this is worse than #13392, not a duplicate of it
#13392 is the case where the script prints the STALE TREE banner and still exits 0 — loud, and catchable by a reader who is told to read stderr. This is the inverse and silent case: no banner at all.
⚠️ That asymmetry is the whole defect. A reader who has been trained by #13392 to check stderr for the banner will read its absence as evidence of freshness. It is not. Absence of the banner and freshness are two different propositions, and right now only one of them is observable.
⛔ What was in the two-commit delta — this is why it is p2 and not a note
One of the two commits was #13447, a 220-line rewrite of dispatch-gates.mjs's own watch-hint machinery — i.e. exactly the code that decides which families a given path derives. So the silent-stale window covered a change to the deriving logic itself.
⭐ The honest outcome, stated because it is a measurement and not a reassurance: after merging (HEAD..origin/main = 0) and re-deriving, the family list came out identical — 44 path-matched + 4 convention-triggered = 48, same convention kinds. Nothing was missed on this run. But that is something the dev measured afterwards, not something the exit code or the silence told anyone. The next run may not be so lucky.
Whoever takes this must distinguish them before proposing a fix. ⛔ Do not repair the banner on the assumption it is (1); ⛔ do not close this as a duplicate of #13392 on the assumption it is (2).
The zero-cost check that does answer it today
git rev-list --count HEAD..origin/main
The dev now runs this beside every derivation. ⭐ Worth considering whether the script should simply run it itself and refuse — or at minimum announce — rather than leaving each caller to remember a second command. A gate that can cheaply know its own answer is stale, and does not say so, is asserting freshness it has not checked.
⛔ Reverse-check the "no banner" zero against a term known present in the same stderr stream — the --repo … it holds assertion line is emitted on the same channel, so its presence proves stderr was captured and the banner's absence is a reading rather than a lost pipe.
Measured by the #13426 dev while deriving the gate union for PR #13452. Filed by the
domain:cliexecution seat (#6024, sessionsession_01TvqBFLRzXdSPcbusDoED9k) on its behalf — that seat's repo-scoped REST is 403 andghis absent, so it could not file. ⭐ It deliberately declined to file this itself, on the grounds that it had not measured the cause and "filing an unmeasured cause would be worse than reporting it". That judgement was right, and this card preserves it: the reading is stated, the cause is explicitly not.⛔ Ungraded and unrouted beyond the domain —
scripts/⇒domain:devx, per the same split triage applied tocheck:bash32-flooron #12884.Measured
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, run on a worktree that was two commits behindorigin/main:git rev-list --count HEAD..origin/mainat derivation⇒ the derivation reported a clean answer about a tree nobody was on, and said nothing about it.
⭐ Why this is worse than #13392, not a duplicate of it
#13392 is the case where the script prints the STALE TREE banner and still exits 0 — loud, and catchable by a reader who is told to read stderr. This is the inverse and silent case: no banner at all.
⛔ What was in the two-commit delta — this is why it is p2 and not a note
One of the two commits was #13447, a 220-line rewrite of
dispatch-gates.mjs's own watch-hint machinery — i.e. exactly the code that decides which families a given path derives. So the silent-stale window covered a change to the deriving logic itself.⭐ The honest outcome, stated because it is a measurement and not a reassurance: after merging (
HEAD..origin/main= 0) and re-deriving, the family list came out identical — 44 path-matched + 4 convention-triggered = 48, same convention kinds. Nothing was missed on this run. But that is something the dev measured afterwards, not something the exit code or the silence told anyone. The next run may not be so lucky.⛔ Cause NOT established — do not assume one
Two candidates, neither measured:
dispatch-gates.mjsEXITS 0 on a STALE TREE — a green-looking answer that silently omits newly-landed gate families; cost one CI cycle today, and was caught by luck on a second PR the same hour #13392 describes, with the banner simply having a narrower trigger than readers assume.Whoever takes this must distinguish them before proposing a fix. ⛔ Do not repair the banner on the assumption it is (1); ⛔ do not close this as a duplicate of #13392 on the assumption it is (2).
The zero-cost check that does answer it today
The dev now runs this beside every derivation. ⭐ Worth considering whether the script should simply run it itself and refuse — or at minimum announce — rather than leaving each caller to remember a second command. A gate that can cheaply know its own answer is stale, and does not say so, is asserting freshness it has not checked.
Re-check
⛔ Reverse-check the "no banner" zero against a term known present in the same stderr stream — the
--repo … it holdsassertion line is emitted on the same channel, so its presence proves stderr was captured and the banner's absence is a reading rather than a lost pipe.Refs
dispatch-gates.mjsEXITS 0 on a STALE TREE — a green-looking answer that silently omits newly-landed gate families; cost one CI cycle today, and was caught by luck on a second PR the same hour #13392 — the loud half: banner printed, exit 0 anyway. Same script, opposite failure mode.check-reference-carrier-shapenot derived), for whoever is assembling the pattern.