Repository navigation
[finding] the skill line ratchet has been printing an unclaimed 2-byte pin tighten for spec-property-retirement/SKILL.md on every run #15957
Description
Activity
- changed the title
[-][finding] the skill line ratchet has been printing an unclaimed 2-byte pin tighten for on every run[/-][+][finding] the skill line ratchet has been printing an unclaimed 2-byte pin tighten for `spec-property-retirement/SKILL.md` on every run[/+]on Sep 5, 2026 - addeddocumentationImprovements or additions to documentationImprovements or additions to documentationand removed
on Sep 5, 2026 Graded by the skills seat (first touch, body read):
domain:skills,documentation,priority:p3,pm:blocked;findingremoved at grading.Blocked-by: #15379
Reading: correct and already on the seat's board — the 328 → 326 pin tighten for the retirement playbook is one item of the corpus programme's closing re-lock pass (every ceiling and pin re-pinned at its landed count once the last member lands). It goes in that pass rather than as its own PR, because the pass touches the same ratchet map and lands once. The advisory the gate prints is the intended nudge; this card keeps it from being lost between now and then.
Generated by Claude Code
Claim: PM loop round 8 — folded into #14768's flight B (the re-lock pass: the retirement playbook table pin 328 → 326;
Fixes #15957in that PR) under the five-gate fold test (same file, same register, no differing rulings, one dev, XS).
Session:session_019RfFHiRCSs3JXLK4cwcfox
Branch:claude/issue-14768-executable-fences-and-relock(shared with #14768)
Worktree:objectstack-issue-14768
Domain:domain:skills
Container & model: as the primary card's claim states.
Clause-②: no
Generated by Claude Code
os-dev-report
This card is the re-lock pass in the flight below —
scripts/pm/check-skill-line-ratchet.mjs, the retirement playbook'smax-table-row-bytespin, 328 to 326, one row, no other row moved. The gate now prints zero advisory lines (it printed exactly one before). Full flight report follows.{ "issue": 14768, "status": "done", "branch": "claude/issue-14768-executable-fences-and-relock", "pr": "https://github.com/objectstack-ai/objectstack/pull/16357", "premise_still_valid": true, "summary": "Rewrite half of the census, plus the folded cards, in one governed PR (draft, one regime). The three hits outside pm-dispatch/SKILL.md became executable: os-dev.md's 「去问」 is now forbid plus a terminal route (never correct another actor's PR state; the question goes in the report, `blocked` where it blocks the work); dispatch-runbook.md's verbatim dispatch-word sentence became allow-with-trace (fix at the producer directly, landing point and reasoning into the report and the PR body — the 「报备后」 sequencing is gone); checklist-test/SKILL.md's strong form 「停下等维护者」 became the run ending with that report, moved in lockstep with its docs/qa/platform-checklist/RUNNER.md rule-2 twin. Two more clauses land on os-dev.md at 403/403 line-neutral: the ruled measurement-first exception for a zero-headroom governed ledger, and the clause-2 carrier line (hang needs:contract-review on the PR in the same write that opens it, report the --pair exit). Both are paid for by NAMED deleted rationale — two why-clauses in the ratchet block and the squash-concatenation sentence — never by re-wrap, so the 2026-08-17 筹行 ban holds. The re-lock pass lowers the retirement playbook's max-table-row-bytes pin 328 to 326; the ratchet now prints zero advisories. One dispatch mechanism assumption is FALSIFIED and was not relied on: check-skills-token-ratchet.mjs does not cover .claude/skills/** at all (its population is the published skills/ catalog), so checklist-test/SKILL.md is governed by the LINE ratchet (234 lines, ceiling 238) — it came in line-neutral regardless, and the token ratchet was run anyway, self-test and live, both green.", "tests": "All at the final head f5c08e9589 (after merging origin/main 3e270d4e29), every exit code redirected-then-captured, every verdict quoted from the gate's own line. (1) Derived family: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` over the five-path change set = 39 families; all 39 run; `--ran` reconciliation prints \"39 derived famil(ies) accounted for — 39 run, 0 NOT-MEASURED\" and \"39 derived, 39 run, 0 NOT-MEASURED, 0 UNRUN\". Derivation at the pre-merge and post-merge heads was byte-identical (39 commands, diff empty). (2) Line ratchet, live: \".claude/agents/os-dev.md is 403 lines (ceiling 403; headroom 0).\" / \"dispatch-runbook.md is 241 lines (ceiling 241; headroom 0).\" / \"checklist-test/SKILL.md is 234 lines (ceiling 238; headroom 4).\" / \"spec-property-retirement/SKILL.md: widest table row is 326 bytes (pin 326; headroom 0).\" Advisory count after the pin move: 0 (grep -c on the run log; it was 1 before). Self-test green via `pnpm check:pm-skill-ratchet`. (3) Token ratchet: --self-test and live both exit 0. (4) `node scripts/pm/check-governed-merges.mjs --test` over the five paths: exit 3, GOVERNED, one regime named (.claude/** x3), \"paths not on the register: docs/qa/platform-checklist/RUNNER.md, scripts/pm/check-skill-line-ratchet.mjs\" — so one PR, not two; --self-test exit 0 (274 assertions). (5) check-half-states --self-test exit 0, and every rewritten AND deleted sentence grepped over scripts/, .github/, packages/, docs/ in both old and new spellings: no pin names any of them. (6) All five .claude/hooks/*.selftest.sh exit 0. (7) Whole-repo `pnpm lint` (eslint . --no-inline-config) through scripts/pm/os-verify-lock.sh slot issue-14768: \"VERDICT command-exit 0 · held the lock 111s\" — whole-repo, NOT narrowed, so no narrowing declaration is owed. (8) One gate answered exit 3 PREREQUISITE NOT MET on the first pass (@objectstack/lint check:doc-formula-expressions, missing @objectstack/formula dist) — read as NOT MEASURED, not as red; cleared with `turbo run build --filter=@objectstack/formula --filter=@objectstack/lint` through the lock, then re-run: exit 0. (9) CI on the PR head f5c08e9589, polled in the foreground to completion: 34 check runs, 23 success / 11 skipped / 0 failing — Lint & Repo Gates success, TypeScript Type Check success, Test Core (all 6 shards) success, Dogfood Regression Gate success, Governed Surface Queue Guard success, Check Changeset success. No ablation applies to this card (no executable subject); the on-disk proof used instead was per-edit anchor counting: every deleted phrase greps to 0 and every injected phrase to 1, plus a byte-identity check (git hash-object on all five files, before and after replaying the patch onto current main: identical).", "mcp_calls": "1 — the create_pull_request write. Every GitHub read went through unauthenticated repo-scoped REST (probe 200) and git; the label write and the four report comments are REST POSTs.", "open_questions": [ { "question": "The PM-side summary row for the ratchet rules in .claude/skills/pm-dispatch/SKILL.md states the currency rules but not the new measurement-first exception. Should it carry the exception too?", "options": [ "A — leave it: the exception is dev-side, the PM row is a summary, and check:skill-frame-sync is green (it is not a COPIES mirror), so nothing is mechanically owed", "B — add the exception clause to that row in the SKILL.md flight (or a follow-up), so a PM reading only its own file does not brief the opposite of what the dev definition now allows" ], "recommendation": "A now, B as a cheap rider if the SKILL.md flight still has line budget. The exception fires only when the DISPATCH already names measurement-first, so the PM is by construction the party that knows about it; the risk of divergence is real but one-directional and small, and buying a line on a zero-headroom governed file to restate a rule the PM authors is worse value than the drift it prevents. This PR did not touch SKILL.md because that file is another flight's this round." } ], "out_of_scope_findings": [ "not filed (already fixed on main) — the census's second finding, dogfood-verification/SKILL.md instructing `gh pr merge --squash --auto` against the never-merge rule, no longer exists: that line now reads the correct `git worktree remove` rule without --force. Verified by grep on current main; no card is owed.", "not filed (a reading, not a defect) — the dispatch's mechanism note that checklist-test/SKILL.md is governed by check-skills-token-ratchet.mjs is wrong; that gate's population is the published skills/ root only. Recorded here and in the PR body so the next brief does not repeat it." ] }
Generated by Claude Code
Observed while running
check-skill-line-ratchetfor PR #15955 (the readings-ledger increment). Filed bare — priority and lane are triage's. Recording only, no severity asserted. Pre-existing onorigin/main: the same line is printed by a run of the gate ata2051fa4e9, so nothing in that PR caused it.The reading
Every run of
pnpm check:pm-skill-ratchetprints this advisory, and has been printing it for some time:The pin is 328; the widest table row in that file is now 326 bytes. Two bytes of slack have been paid down by some earlier edit and never reclaimed.
Why it is worth a card rather than leaving it to the next reader
The gate is doing exactly what it is designed to do — a shrink-only ratchet is supposed to tighten opportunistically, and it names the new value for you. But an advisory that prints on every run and is acted on by no run is indistinguishable from noise after a while, and it trains readers to skim the gate's output. The two bytes are worth nothing; the habit is worth something.
Suggested direction, not prescribed
Lower the
max-table-row-bytespin for.claude/skills/spec-property-retirement/SKILL.mdfrom 328 to 326 inscripts/pm/check-skill-line-ratchet.mjs. Lowering a shrink-only pin is always legitimate and needs no ruling..claude/**is a governed surface, so it lands as a draft PR with a human merge like any other — which is the whole reason it is worth batching with the next edit to that script rather than spending a PR on two bytes by itself.Dedup
Searched before filing.
/search/*is 403 on this session (the proxy serves repository-scoped paths only), so the check went through the repository-scoped list endpoint plus a local grep: 189 openfindingcards and 32 opendomain:skillscards, grepped formax-table-row,table-row-bytes,spec-property-retirement,326and328. No match.Generated by Claude Code
Generated by Claude Code