Found immediately after running merge-and-release end to end on #1397, by re-checking the machine
state the skill had just declared current.
Failure scenario, reproduced on this host
merge-and-release step 7 checks out main, fast-forwards it to the promoted tip, installs,
and instructs: "confirm --report now reads current". It did, stale: false at f8e7491d.
- Step 7 is followed by step 8, which is mandatory ("Run cleanup regardless of how steps 5
through 7 ended") and fast-forwards the base clone back to develop.
--report now reads stale: true, on a machine whose install is correct and current:
"stamp": { "source": { "commit": "f8e7491d..." } },
"currentCommit": "aaaae368...",
"stale": true
So step 8 falsifies step 7's own confirmation, every time, by design rather than by accident.
Why the report is wrong here, not merely surprising
stale is a plain inequality between the stamp's commit and the checkout's HEAD. It is a
statement about commit identity, presented as a statement about whether this machine's
skills are current. On this host those two disagree completely:
aaaae368 (the develop tip) is an ancestor of f8e7491d (the main tip), verified with
git merge-base --is-ancestor. The installed commit is strictly newer.
git diff aaaae368 f8e7491d -- .agents/skills/ .claude-plugin/ is empty. The skill content
is byte-identical on both branches.
The machine has the newest skill content that exists, installed from the newest commit that exists,
and the report calls it stale.
Consequence
fleet-conformance-check exists to answer "is this machine current" and reads this report to do
it. Its answer here is a false stale, and the remedy it prescribes makes things worse rather than
better: reinstalling from develop stamps aaaae368, an older commit than the one already
installed, to silence a warning about content that never differed. The stamp moves backwards and
the report goes green, which is the exact inversion of what the stamp is for.
Every session working on develop after any promotion sees this, so it is the normal state rather
than an edge case.
Proposed dispositions, needing a decision rather than a fix
- Compare content, not commit identity. The stamp could carry a digest of the two installed
trees. .claude-plugin/fleet-skills/.source-digests/ already computes per-skill digests, so the
input exists.
- Compare reachability. Read as current when the stamped commit is a descendant of, or equal
to, HEAD. Cheaper, and it would answer this case correctly, but it says nothing about a
checkout that has moved sideways onto an unrelated branch.
- Leave the engine alone and fix the two skills that read it.
merge-and-release step 7 would
stop instructing a confirmation that step 8 is about to invalidate, and
fleet-conformance-check would stop treating a bare stale: true as actionable.
Option 1 is the one that makes the report mean what its field name says. Options 2 and 3 keep a
report that is only correct when read with a caveat that is nowhere written down.
Found immediately after running
merge-and-releaseend to end on #1397, by re-checking the machinestate the skill had just declared current.
Failure scenario, reproduced on this host
merge-and-releasestep 7 checks outmain, fast-forwards it to the promoted tip, installs,and instructs: "confirm
--reportnow reads current". It did,stale: falseatf8e7491d.through 7 ended") and fast-forwards the base clone back to
develop.--reportnow readsstale: true, on a machine whose install is correct and current:So step 8 falsifies step 7's own confirmation, every time, by design rather than by accident.
Why the report is wrong here, not merely surprising
staleis a plain inequality between the stamp's commit and the checkout'sHEAD. It is astatement about commit identity, presented as a statement about whether this machine's
skills are current. On this host those two disagree completely:
aaaae368(thedeveloptip) is an ancestor off8e7491d(themaintip), verified withgit merge-base --is-ancestor. The installed commit is strictly newer.git diff aaaae368 f8e7491d -- .agents/skills/ .claude-plugin/is empty. The skill contentis byte-identical on both branches.
The machine has the newest skill content that exists, installed from the newest commit that exists,
and the report calls it stale.
Consequence
fleet-conformance-checkexists to answer "is this machine current" and reads this report to doit. Its answer here is a false stale, and the remedy it prescribes makes things worse rather than
better: reinstalling from
developstampsaaaae368, an older commit than the one alreadyinstalled, to silence a warning about content that never differed. The stamp moves backwards and
the report goes green, which is the exact inversion of what the stamp is for.
Every session working on
developafter any promotion sees this, so it is the normal state ratherthan an edge case.
Proposed dispositions, needing a decision rather than a fix
trees.
.claude-plugin/fleet-skills/.source-digests/already computes per-skill digests, so theinput exists.
to,
HEAD. Cheaper, and it would answer this case correctly, but it says nothing about acheckout that has moved sideways onto an unrelated branch.
merge-and-releasestep 7 wouldstop instructing a confirmation that step 8 is about to invalidate, and
fleet-conformance-checkwould stop treating a barestale: trueas actionable.Option 1 is the one that makes the report mean what its field name says. Options 2 and 3 keep a
report that is only correct when read with a caveat that is nowhere written down.