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
{{ message }}
Repository navigation
ci(skills-ratchet): exclude the whole release-bot version: stamp line from the token count and re-pin the ceilings so headroom stays 0 and 1 (#23177 ruling B, item A2′) #23192
Filing-gate category ③, a maintainer-ruled duty: #23177, ruling B (6139629628, the maintainer's 「同意」), item 2 (A2′, which replaces A2).
Reader who acts: the domain:devx execution seat. It lands in scripts/check-skills-token-ratchet.mjs, which is not a governed path, so it goes through the ordinary queue.
What the ruling binds (quoted from 6139629628, item 2)
A2′ (replaces A2): no tolerance band.scripts/check-skills-token-ratchet.mjs counts authored content only: the frontmatter version: line that the release bot rewrites is excluded from the count (or normalized to a fixed-width placeholder before counting); ceilings stay shrink-only and the current headroom (0 and 1 tokens) stays as it is. This is also #23176's structural fix; whatever one-token trim is in flight there is the stop-gap, not the route.
Where main stands (so the dev starts from the landed state)
What A2′ adds beyond that: the stable part of the stamp still counts today. For example, 18.10.0 is one byte longer than 18.9.0, so a zero-headroom file can still go red on a version number no author wrote.
What done looks like
For the files the version script stamps (stampedSkillPaths()), the whole frontmatter metadata.version line is excluded from the count, or normalized to one fixed-width placeholder. The count no longer moves with any version value.
Every CEILINGS row for a stamped file is re-pinned by exactly the bytes taken out, so each file's headroom on main is unchanged (objectstack-data 0, objectstack-automation 1, and the others as they are). It is shrink-only: no ceiling minus its count grows.
The header's counting-convention section and the hand-audit sentence say what now holds. The route-A prerelease-only code is replaced, not kept alongside.
The self-test pins: a stamp change of any width (17.7.0 → 18.10.0-next.12) moves no count; one authored byte over a zero-headroom ceiling is red; a version-shaped string outside the stamp is priced; and the per-file headroom before equals after on the real bundle.
Claim: PM loop round 7 · domain:devx seat 1 · 2026-10-13T07:02Z · maintainer-ruled: #23177 ruling B, item A2′ (6139629628, 「同意」)
Session: session_012zwsLMxQBwHUYJgPyrpEvx
Account: zhuangjianguo (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-23192-ratchet-exclude-stamp-line
Worktree: objectstack-issue-23192
Domain: domain:devx
Seat: domain:devx#1
File surface: scripts/check-skills-token-ratchet.mjs only (its count, its CEILINGS rows for stamped files re-pinned downward by exactly the excluded bytes, its header and its self-test). ⛔ No edit to skills/**, scripts/check-skill-compatibility-version.mjs or any governed surface. ⛔ No ceiling's headroom grows
Container & model: M, mode:subagent, model: opus (the default judgment tier; dispatch-gates --tier on this surface: "no path-derived mandate")
Clause-②: no (an internal repo gate)
Responsibility: the ratchet still prices the stable part of the release bot's version stamp, so a zero-headroom file can go red on a version number no author wrote (18.9.0 → 18.10.0) | no platform path covers it: route A (PR #23187) excluded only the prerelease segment | the next stable-width change of the stamp reds the gate for no authored reason
Thread-read: 6139629628
Serial constraints cleared: no open PR touches scripts/check-skills-token-ratchet.mjs or scripts/check-skill-compatibility-version.mjs (all open PRs' file lists read at this act).
os-dev-report
{
"issue": 23192,
"status": "done",
"branch": "claude/issue-23192-ratchet-exclude-stamp-line",
"pr": "#23199",
"session": "session_012zwsLMxQBwHUYJgPyrpEvx",
"premise_still_valid": true,
"summary": "scripts/check-skills-token-ratchet.mjs now leaves the whole release-stamp line (frontmatter metadata.version, plus its newline) out of every stamped SKILL.md count at every stamp width; route A (stampPrerelease / STAMP_PRERELEASE_RE) is deleted, not kept alongside. The line is located by the stamp WRITER itself: stampLine() runs deriveFrontmatter with a non-numeric probe and takes the one line it rewrote (a second rewritten line throws), so no second parser and no edit to check-skill-compatibility-version.mjs. Exclusion was chosen over a fixed-width placeholder because on the basis tree d4aaeaf every stamp line is 20 bytes = exactly 5 units, so ceil((B-20)/4) = ceil(B/4)-5 for every file: all ten stamped CEILINGS rows dropped by exactly 5 (ai 6806->6801, api 6319->6314, automation 5785->5780, data 6128->6123, formula 6002->5997, i18n 6338->6333, platform 5833->5828, query 5552->5547, ui 3856->3851, upgrade 6193->6188) and per-file headroom is identical on all 54 priced files (data 0, automation 1; 0 diffs, 44 rows untouched). The hand audit gains one grep term. Judgment call to review: a width-6 placeholder would have needed zero re-pins, which is simpler in a literal sense; I rejected it because it builds today's stamp width into the convention as a constant and keeps pricing bytes no author wrote. The reasons are in the PR body. Premise check: main at d4aaeaf carried route A exactly as the card says, and ablation 2 below shows the stable part still moved the count (18.9.0 -> 18.10.0: 32 -> 33). Self-test roster 76 -> 79 (11 route-A batteries replaced by 14), SELF_TEST_BATTERY_FLOOR 75 -> 79. Commits use the AGENTS.md model-free trailer pair and the PR body the AGENTS.md session-URL footer, per that file's precedence over the harness attribution reminder. The worktree is removed (node_modules deleted first, then git worktree remove, refused nothing), and the scratch clone of changeset-release/main is deleted.",
"tests": "All on final head 0f5c195. Gate self-test: node scripts/check-skills-token-ratchet.mjs --self-test -> "✓ check-skills-token-ratchet self-test: 79 cases pass." (exit 0). Gate: node scripts/check-skills-token-ratchet.mjs -> "✓ check-skills-token-ratchet: 54 authored bundle file(s) within their ceilings; 10 generator-owned file(s) measured, not ratcheted." (exit 0). pnpm check:ratchet-remedy-authority -> "OK check-ratchet-remedy-authority: 275 scripts swept ...; 14 mark the expanding remedy ⛔ MAINTAINER-ONLY" (exit 0). dispatch-gates --repo objectstack-ai/objectstack derived 31 families for the 1-path change set: the 30 direct commands each exited 0 (incl. check:nul-bytes OK over 11195 files, check:entry-guard, check:scripts-symbol-anchors, check:self-test-wired, bare-root-worklist --self-test, check:cross-package-test-inputs), and pnpm check:pm-dispatch-gates exit 0 with "✓ dispatch-gates self-test (fast tier): 1833 cases pass". --ran reconciliation at 0f5c195: 31 derived, 31 run, 0 NOT-MEASURED, 0 UNRUN. Script-suite duty: no .test. names this script (git grep), so its --self-test is its suite. eslint narrowed (CI owns pnpm lint): npx eslint --no-inline-config --format json on the one file -> 1 file, 0 errors, 0 warnings; population = eslint.config.mjs glob **/*.{...,mjs,...}, resolved by --print-config; invariance = resolved parserOptions {ecmaVersion, sourceType} with no project, so no type-aware rule exists and untouched files cannot change. Before/after on main: per-file table in the PR body; 0 headroom diffs over 54 files. Ablations (one-time, scripts/ablation-replace.mjs; each mutation proven on disk, anchor 1->0 and blob changed; each restore proven, blob == HEAD 5c98de59e and git diff HEAD empty; no build/dist involved, since the gate runs from source): (1) unpriced=0 -> self-test 4 red (width invariance got [32,34,33,35]; zero-headroom green; hand audit; real-bundle re-pin), gate red automation over by 4 and data over by 5; (2) route A restored -> same 4 red, width invariance [32,33]; (3) every indented version: line excluded -> 3 red ("a version-shaped string outside the stamp is priced" 13 vs 18; hand audit and re-pin name objectstack-platform/SKILL.md, which has a second indented version: line); (4) numeric probe 1.0.0 -> self-test and gate both throw "the stamp writer rewrote 2 lines for one probe stamp". changeset-release/main at 0b5641e (stamp 18.0.0-next.0, a one-time shallow sparse clone, deleted afterwards): its route-A gate exit 0; this script copied in: gate exit 0, self-test 79 pass, all 54 headroom values identical to main. With the clone restamped to 18.0.0-next.0, 18.10.0, 18.10.10-next.12, 18.100.10 and 100.100.100, objectstack-data read 6123/6123 at every width, while route A went red at 100.100.100 (6129 over 6128).",
"mcp_calls": "0 — no MCP GitHub tool called",
"api_writes": "3 — each one relay stroke sent as POST /repos/objectstack-ai/objectstack/dispatches (scripts/pm/fleet-write/dispatch.mjs) and executed by fleet-write.yml as objectstack-fleet[bot]: (1) pr_create -> POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/23199/assignees [zhuangjianguo], body read back 11658/11658 bytes identical; (2) labels_add via scripts/pm/label-write.mjs -> POST /repos//issues/23199/labels [skip-changeset], read back size/m + skip-changeset; (3) this report via scripts/pm/post-stamped.mjs -> POST /repos//issues/23192/comments. Plus 3 git pushes (empty-branch probe, 5b7df2d, 0f5c195), which are not REST writes.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: 承接者:无 · noted, not filed (only in the PR Acceptance notes): deriveFrontmatter also rewrites the compatibility: major pins (@objectstack/spec 17.x), and those stay priced because A2′ names only the version: line. Their width changes only when a major gains a digit (next case 99 -> 100), so this is dormant. Dedupe words: skills ratchet, compatibility pin, major width, release stamp"
]
}
Open, draft, base main. Body line 1 is Fixes #23192, line 2 is Clause-②: no.
Assignee zhuangjianguo. Labels size/m and skip-changeset, which is right for a root gate script.
One file: scripts/check-skills-token-ratchet.mjs (+208 / −95).
Not governed (check-governed-merges --pr 23199), 303 lines.
No skills/**, no change to check-skill-compatibility-version.mjs, no workflow.
None of the three contract faces is touched.
The ruling 6139629628 item 2 (A2′) is quoted verbatim in the body.
The change, read on the diff
Ceilings only move down. The ten stamped CEILINGS rows each drop by exactly 5: ai 6806→6801, api 6319→6314, automation 5785→5780, data 6128→6123, formula 6002→5997, i18n 6338→6333, platform 5833→5828, query 5552→5547, ui 3856→3851, upgrade 6193→6188. Each row's comment carries the A2′ step.
Why exactly 5: the stamp line version: "17.7.0" plus its newline is 20 bytes on every file. So ceil((B−20)/4) = ceil(B/4) − 5, and every file's headroom is unchanged. The report reads 0 diffs over 54 priced files (data 0, automation 1). No ceiling minus its count grows.
Locating the line:stampLine() asks the stamp writer itself. It runs deriveFrontmatter with a non-numeric probe, takes the single line that changed, and throws if more than one line changes (ablation 4: a numeric probe rewrites the compat pin too, and the gate refuses rather than guesses). There is no second parser.
Route A replaced:stampPrerelease() and STAMP_PRERELEASE_RE are deleted, not kept alongside. They had no consumers outside this file (git grep).
Self-test: 79 cases (floor 75→79). They pin that the count does not move at any stamp width, that zero headroom plus one authored byte is red, and that a version-shaped string outside the stamp is priced.
Ablations prove each pin:
route A restored: width invariance fails;
every indented version: line excluded: the outside-stamp row fails, naming objectstack-platform/SKILL.md's second version: line.
The chosen form, exclusion over a fixed-width placeholder, is within the ruling's "excluded … (or normalized …)". The reason, that a placeholder hard-codes today's width into the convention, is in the body.
Evidence (report)
On main: the gate exits 0 over 54 files; check:ratchet-remedy-authority is OK; 31 derived gates were run, all exit 0, with 0 NOT-MEASURED.
Restamped to 18.0.0-next.0, 18.10.0, 18.10.10-next.12, 18.100.10 and 100.100.100, data reads 6123/6123 at every width. Route A went red at 100.100.100.
CI on 0f5c195b1 at this review: 24 green, 11 skipped, 6 running, none red.
Landing held, deliberately:#21988 (18.0.0-next.0) is in the merge queue now. The queue groups entries ALLGREEN, so this seat arms this PR only after #21988 has merged. The release candidate never shares a group with an unrelated change.
Out-of-scope finding (not filed): the compatibility: major pins stay priced. A2′ names only the version: line, and they change width only when a major gains a digit. They are noted in the PR's Acceptance notes.
The card closed completed on the merge, and pm:dispatched is removed with this record.
A2′ is on main. The ratchet leaves the whole release-stamp line out of every stamped SKILL.md count. The ten stamped ceilings each moved down by 5, so per-file headroom is unchanged.
Landing was held until chore: version packages (next) #21988 (18.0.0-next.0) merged at 2026-10-13T08:04Z, so the release candidate never shared a merge-queue group with this change.
Activity
objectstack-fleet commentedon Oct 13, 2026
Claim: PM loop round 7 ·
domain:devxseat 1 · 2026-10-13T07:02Z · maintainer-ruled: #23177 ruling B, item A2′ (6139629628, 「同意」)Session:
session_012zwsLMxQBwHUYJgPyrpEvxAccount:
zhuangjianguo(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-23192-ratchet-exclude-stamp-lineWorktree:
objectstack-issue-23192Domain:
domain:devxSeat:
domain:devx#1File surface:
scripts/check-skills-token-ratchet.mjsonly (its count, itsCEILINGSrows for stamped files re-pinned downward by exactly the excluded bytes, its header and its self-test). ⛔ No edit toskills/**,scripts/check-skill-compatibility-version.mjsor any governed surface. ⛔ No ceiling's headroom growsContainer & model:
M,mode:subagent,model: opus(the default judgment tier;dispatch-gates --tieron this surface: "no path-derived mandate")Clause-②: no (an internal repo gate)
Responsibility: the ratchet still prices the stable part of the release bot's version stamp, so a zero-headroom file can go red on a version number no author wrote (
18.9.0→18.10.0) | no platform path covers it: route A (PR #23187) excluded only the prerelease segment | the next stable-width change of the stamp reds the gate for no authored reasonThread-read: 6139629628
Serial constraints cleared: no open PR touches
scripts/check-skills-token-ratchet.mjsorscripts/check-skill-compatibility-version.mjs(all open PRs' file lists read at this act).objectstack-fleet commentedon Oct 13, 2026
os-dev-report
{
"issue": 23192,
"status": "done",
"branch": "claude/issue-23192-ratchet-exclude-stamp-line",
"pr": "#23199",
"session": "session_012zwsLMxQBwHUYJgPyrpEvx",
"premise_still_valid": true,
"summary": "scripts/check-skills-token-ratchet.mjs now leaves the whole release-stamp line (frontmatter metadata.version, plus its newline) out of every stamped SKILL.md count at every stamp width; route A (stampPrerelease / STAMP_PRERELEASE_RE) is deleted, not kept alongside. The line is located by the stamp WRITER itself: stampLine() runs deriveFrontmatter with a non-numeric probe and takes the one line it rewrote (a second rewritten line throws), so no second parser and no edit to check-skill-compatibility-version.mjs. Exclusion was chosen over a fixed-width placeholder because on the basis tree d4aaeaf every stamp line is 20 bytes = exactly 5 units, so ceil((B-20)/4) = ceil(B/4)-5 for every file: all ten stamped CEILINGS rows dropped by exactly 5 (ai 6806->6801, api 6319->6314, automation 5785->5780, data 6128->6123, formula 6002->5997, i18n 6338->6333, platform 5833->5828, query 5552->5547, ui 3856->3851, upgrade 6193->6188) and per-file headroom is identical on all 54 priced files (data 0, automation 1; 0 diffs, 44 rows untouched). The hand audit gains one grep term. Judgment call to review: a width-6 placeholder would have needed zero re-pins, which is simpler in a literal sense; I rejected it because it builds today's stamp width into the convention as a constant and keeps pricing bytes no author wrote. The reasons are in the PR body. Premise check: main at d4aaeaf carried route A exactly as the card says, and ablation 2 below shows the stable part still moved the count (18.9.0 -> 18.10.0: 32 -> 33). Self-test roster 76 -> 79 (11 route-A batteries replaced by 14), SELF_TEST_BATTERY_FLOOR 75 -> 79. Commits use the AGENTS.md model-free trailer pair and the PR body the AGENTS.md session-URL footer, per that file's precedence over the harness attribution reminder. The worktree is removed (node_modules deleted first, then git worktree remove, refused nothing), and the scratch clone of changeset-release/main is deleted.",
"tests": "All on final head 0f5c195. Gate self-test: node scripts/check-skills-token-ratchet.mjs --self-test -> "✓ check-skills-token-ratchet self-test: 79 cases pass." (exit 0). Gate: node scripts/check-skills-token-ratchet.mjs -> "✓ check-skills-token-ratchet: 54 authored bundle file(s) within their ceilings; 10 generator-owned file(s) measured, not ratcheted." (exit 0). pnpm check:ratchet-remedy-authority -> "OK check-ratchet-remedy-authority: 275 scripts swept ...; 14 mark the expanding remedy ⛔ MAINTAINER-ONLY" (exit 0). dispatch-gates --repo objectstack-ai/objectstack derived 31 families for the 1-path change set: the 30 direct commands each exited 0 (incl. check:nul-bytes OK over 11195 files, check:entry-guard, check:scripts-symbol-anchors, check:self-test-wired, bare-root-worklist --self-test, check:cross-package-test-inputs), and pnpm check:pm-dispatch-gates exit 0 with "✓ dispatch-gates self-test (fast tier): 1833 cases pass". --ran reconciliation at 0f5c195: 31 derived, 31 run, 0 NOT-MEASURED, 0 UNRUN. Script-suite duty: no .test. names this script (git grep), so its --self-test is its suite. eslint narrowed (CI owns pnpm lint): npx eslint --no-inline-config --format json on the one file -> 1 file, 0 errors, 0 warnings; population = eslint.config.mjs glob **/*.{...,mjs,...}, resolved by --print-config; invariance = resolved parserOptions {ecmaVersion, sourceType} with no project, so no type-aware rule exists and untouched files cannot change. Before/after on main: per-file table in the PR body; 0 headroom diffs over 54 files. Ablations (one-time, scripts/ablation-replace.mjs; each mutation proven on disk, anchor 1->0 and blob changed; each restore proven, blob == HEAD 5c98de59e and git diff HEAD empty; no build/dist involved, since the gate runs from source): (1) unpriced=0 -> self-test 4 red (width invariance got [32,34,33,35]; zero-headroom green; hand audit; real-bundle re-pin), gate red automation over by 4 and data over by 5; (2) route A restored -> same 4 red, width invariance [32,33]; (3) every indented version: line excluded -> 3 red ("a version-shaped string outside the stamp is priced" 13 vs 18; hand audit and re-pin name objectstack-platform/SKILL.md, which has a second indented version: line); (4) numeric probe 1.0.0 -> self-test and gate both throw "the stamp writer rewrote 2 lines for one probe stamp". changeset-release/main at 0b5641e (stamp 18.0.0-next.0, a one-time shallow sparse clone, deleted afterwards): its route-A gate exit 0; this script copied in: gate exit 0, self-test 79 pass, all 54 headroom values identical to main. With the clone restamped to 18.0.0-next.0, 18.10.0, 18.10.10-next.12, 18.100.10 and 100.100.100, objectstack-data read 6123/6123 at every width, while route A went red at 100.100.100 (6129 over 6128).",
"mcp_calls": "0 — no MCP GitHub tool called",
"api_writes": "3 — each one relay stroke sent as POST /repos/objectstack-ai/objectstack/dispatches (scripts/pm/fleet-write/dispatch.mjs) and executed by fleet-write.yml as objectstack-fleet[bot]: (1) pr_create -> POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/23199/assignees [zhuangjianguo], body read back 11658/11658 bytes identical; (2) labels_add via scripts/pm/label-write.mjs -> POST /repos//issues/23199/labels [skip-changeset], read back size/m + skip-changeset; (3) this report via scripts/pm/post-stamped.mjs -> POST /repos//issues/23192/comments. Plus 3 git pushes (empty-branch probe, 5b7df2d, 0f5c195), which are not REST writes.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: 承接者:无 · noted, not filed (only in the PR Acceptance notes): deriveFrontmatter also rewrites the compatibility: major pins (@objectstack/spec 17.x), and those stay priced because A2′ names only the version: line. Their width changes only when a major gains a digit (next case 99 -> 100), so this is dormant. Dedupe words: skills ratchet, compatibility pin, major width, release stamp"
]
}
objectstack-fleet commentedon Oct 13, 2026
Review: ACCEPT · PR #23199 (draft, head
0f5c195b1) ·domain:devxseat 1 ·session_012zwsLMxQBwHUYJgPyrpEvx· 2026-10-13T07:48ZChecked on GitHub, not on the report's say-so.
PR shape and scope
main. Body line 1 isFixes #23192, line 2 isClause-②: no.zhuangjianguo. Labelssize/mandskip-changeset, which is right for a root gate script.scripts/check-skills-token-ratchet.mjs(+208 / −95).check-governed-merges --pr 23199), 303 lines.skills/**, no change tocheck-skill-compatibility-version.mjs, no workflow.6139629628item 2 (A2′) is quoted verbatim in the body.The change, read on the diff
CEILINGSrows each drop by exactly 5: ai 6806→6801, api 6319→6314, automation 5785→5780, data 6128→6123, formula 6002→5997, i18n 6338→6333, platform 5833→5828, query 5552→5547, ui 3856→3851, upgrade 6193→6188. Each row's comment carries the A2′ step.version: "17.7.0"plus its newline is 20 bytes on every file. Soceil((B−20)/4) = ceil(B/4) − 5, and every file's headroom is unchanged. The report reads 0 diffs over 54 priced files (data 0, automation 1). No ceiling minus its count grows.stampLine()asks the stamp writer itself. It runsderiveFrontmatterwith a non-numeric probe, takes the single line that changed, and throws if more than one line changes (ablation 4: a numeric probe rewrites the compat pin too, and the gate refuses rather than guesses). There is no second parser.stampPrerelease()andSTAMP_PRERELEASE_REare deleted, not kept alongside. They had no consumers outside this file (git grep).version:line excluded: the outside-stamp row fails, namingobjectstack-platform/SKILL.md's secondversion:line.Evidence (report)
main: the gate exits 0 over 54 files;check:ratchet-remedy-authorityis OK; 31 derived gates were run, all exit 0, with 0 NOT-MEASURED.0b5641e55with this script, the gate exits 0 and headroom is identical tomain.18.0.0-next.0,18.10.0,18.10.10-next.12,18.100.10and100.100.100, data reads 6123/6123 at every width. Route A went red at100.100.100.CI on
0f5c195b1at this review: 24 green, 11 skipped, 6 running, none red.Landing held, deliberately: #21988 (
18.0.0-next.0) is in the merge queue now. The queue groups entriesALLGREEN, so this seat arms this PR only after #21988 has merged. The release candidate never shares a group with an unrelated change.Out-of-scope finding (not filed): the
compatibility:major pins stay priced. A2′ names only theversion:line, and they change width only when a major gains a digit. They are noted in the PR's Acceptance notes.objectstack-fleet commentedon Oct 13, 2026
Landed: PR #23199 →
44e2d505c7(Fixes #23192) ·domain:devxseat 1 ·session_012zwsLMxQBwHUYJgPyrpEvx· 2026-10-13T08:21Zmain,scripts/check-skills-token-ratchet.mjsis blobf386e08a56, equal to the PR head0f5c195b1.completedon the merge, andpm:dispatchedis removed with this record.main. The ratchet leaves the whole release-stamp line out of every stamped SKILL.md count. The ten stamped ceilings each moved down by 5, so per-file headroom is unchanged.18.0.0-next.0) merged at 2026-10-13T08:04Z, so the release candidate never shared a merge-queue group with this change.