Found in the adversarial review of #120.
Pipeline order runs refresh_manifest last, but the pin list and mech_stats both depend on manifest.json
Where: .claude/skills/update-xmech-page/SKILL.md:65
Step 1 pins 'each Mech in _fleet/data/manifest.json', which is the committed snapshot and not the CLAW pin. Step 4 runs mech_stats.py, which reads MEMBERS from manifest.json when it is imported (mech_stats.py:61-62), before refresh_manifest.py. If the membership at the pinned CLAW differs from the committed snapshot, the run pins and counts the wrong set of Mechs. assemble_page then stops with 'Mech stats must cover canonical fleet membership exactly' only after the scans and the whole step 5 audit are done.
Failure scenario. CLAW admits an eleventh Mech between refreshes. The skill snapshots and counts ten, refresh_manifest writes eleven, and assemble_page raises ValueError at step 8. Recovering means cloning and pinning the new Mech and rerunning mech_stats, whose merged-PR counts are then taken at a different moment from the others.
Evidence. SKILL.md:65 reads 'For each Mech in _fleet/data/manifest.json plus culturebotai-claw'. SKILL.md:110-114: refresh_manifest.py comes after mech_stats.py. mech_stats.py:61-62 has MANIFEST = json.load(open(... 'manifest.json')) and MEMBERS = list(MANIFEST["mechs"]). assemble_page.py:112-114 has if counted != names: raise ValueError("Mech stats must cover canonical fleet membership exactly").
Verifier (confirmed, low). SKILL.md step 1 (line 65) and step 2 take the Mech list from the committed manifest.json. mech_stats.py (lines 61-62) reads MEMBERS from that same file at import and runs before refresh_manifest.py (SKILL.md lines 113-114). If CLAW's membership at the pin differs from the committed snapshot, the run pins, clones and counts the old set, and refresh_manifest then writes the new one. assemble_page.py stops only at step 8. It raises "Mech cards must match canonical fleet membership exactly" if step 5 added no card, or "Mech stats must cover canonical fleet membership exactly" if it did. The run fails closed, so no wrong data is published, but the scans and audit are wasted and a partial rerun is needed.
Suggested fix. Pin and clone CLAW first, run refresh_manifest.py next, and take the Mech list for steps 1-2 from the refreshed manifest. Then run the scans and mech_stats.
Found in the adversarial review of #120.
Pipeline order runs refresh_manifest last, but the pin list and mech_stats both depend on manifest.json
Where:
.claude/skills/update-xmech-page/SKILL.md:65Step 1 pins 'each Mech in
_fleet/data/manifest.json', which is the committed snapshot and not the CLAW pin. Step 4 runs mech_stats.py, which reads MEMBERS from manifest.json when it is imported (mech_stats.py:61-62), before refresh_manifest.py. If the membership at the pinned CLAW differs from the committed snapshot, the run pins and counts the wrong set of Mechs. assemble_page then stops with 'Mech stats must cover canonical fleet membership exactly' only after the scans and the whole step 5 audit are done.Failure scenario. CLAW admits an eleventh Mech between refreshes. The skill snapshots and counts ten, refresh_manifest writes eleven, and assemble_page raises ValueError at step 8. Recovering means cloning and pinning the new Mech and rerunning mech_stats, whose merged-PR counts are then taken at a different moment from the others.
Evidence. SKILL.md:65 reads 'For each Mech in
_fleet/data/manifest.jsonplusculturebotai-claw'. SKILL.md:110-114: refresh_manifest.py comes after mech_stats.py. mech_stats.py:61-62 hasMANIFEST = json.load(open(... 'manifest.json'))andMEMBERS = list(MANIFEST["mechs"]). assemble_page.py:112-114 hasif counted != names: raise ValueError("Mech stats must cover canonical fleet membership exactly").Verifier (confirmed, low). SKILL.md step 1 (line 65) and step 2 take the Mech list from the committed manifest.json. mech_stats.py (lines 61-62) reads MEMBERS from that same file at import and runs before refresh_manifest.py (SKILL.md lines 113-114). If CLAW's membership at the pin differs from the committed snapshot, the run pins, clones and counts the old set, and refresh_manifest then writes the new one. assemble_page.py stops only at step 8. It raises "Mech cards must match canonical fleet membership exactly" if step 5 added no card, or "Mech stats must cover canonical fleet membership exactly" if it did. The run fails closed, so no wrong data is published, but the scans and audit are wasted and a partial rerun is needed.
Suggested fix. Pin and clone CLAW first, run refresh_manifest.py next, and take the Mech list for steps 1-2 from the refreshed manifest. Then run the scans and mech_stats.