Skip to content

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

Closed

Description

@objectstack-fleet

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 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.

Activity

  1. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    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).

  2. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    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"
    ]
    }

  3. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Review: ACCEPT · PR #23199 (draft, head 0f5c195b1) · domain:devx seat 1 · session_012zwsLMxQBwHUYJgPyrpEvx · 2026-10-13T07:48Z

    Checked on GitHub, not on the report's say-so.

    PR shape and scope

    • 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.
    • On chore: version packages (next) #21988's tree 0b5641e55 with this script, the gate exits 0 and headroom is identical to main.
    • 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.

  4. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #23199 → 44e2d505c7 (Fixes #23192) · domain:devx seat 1 · session_012zwsLMxQBwHUYJgPyrpEvx · 2026-10-13T08:21Z

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedomain:devxpriority:p1High: required for production / M2tooling

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions