Repository navigation
Re-anchor the business-semantics ratchet to 100,000 and decouple the README banner from the ceiling — banner pins the measured reading, the ceiling stands alone (maintainer ruling 2026-09-05) #1601
Description
Maintainer ruling, 2026-09-05, repo:hotcrm R39 round report. ⛔ Not re-litigable. Raising a ratchet ceiling sits on the maintainer floor, and scripts/check-source-token-ratchet.mjs's own header requires the ruling to be quoted in the raising PR's body — do that, verbatim and untranslated.
Ruling, verbatim:
business-semantics 棘轮 提升到 100000
Follow-up ruling in the same exchange,选项 A(解耦),verbatim as presented and accepted:
解耦:banner 钉实测,ceiling 独立
Why this is not a one-line constant change
Measured on origin/main @ 81a79ee, 2026-09-05T22:4xZ.
test/docs-readme-token-figures.test.ts wires the README banner to CEILINGS, and its last case asserts:
expect(row.high, '…').toBeGreaterThan(row.ceiling);where row.high = Math.round(banner × (1 + BUFFER)) and BUFFER = 0.05.
| layer | README banner | band (±5%) | committed ceiling | today |
|---|---|---|---|---|
| business semantics | ~81k | 76,950 – 85,050 | 85,000 | ✓ passes by 50 tokens |
| interaction layer | ~39k | 37,050 – 40,950 | 40,000 | ✓ passes |
⇒ Setting the ceiling to 100,000 makes that case read 85,050 > 100,000 ⇒ RED, and pnpm test is inside pnpm verify.
⭐ And changing only the constant would not deliver what the ruling asks for. With the coupling intact, the effective cap on growth becomes the banner rule's 85,050, not the ceiling's 100,000 — the headroom the ruling is meant to create would not exist. That is what made this a fork rather than a chore.
The ruled shape — decouple
The two numbers stop being tied to each other and each gets one job:
CEILINGS['business semantics'] = 100_000— the hard growth budget, and now the only growth gate on this layer.- The banner rule becomes a truthfulness rule: the README banner figure must track the measured reading (within
BUFFER), not the ceiling. It no longer caps anything; it stops the README advertising a size the app does not have.
⭐ Note the docstring paragraph that the old assertion defended — "on growth the ratchet fails first, on BOTH layers" — becomes true by construction under this shape, since the ratchet is now the only growth gate. It still needs rewriting, because its current text argues the point from the band/ceiling relation that is being removed.
Scope
scripts/check-source-token-ratchet.mjsCEILINGS(:226):['business semantics', 85000]→100000. ⛔interaction layer(40,000) andauthored total(140,000) are unchanged — the ruling names one layer.- Rewrite the header docblock paragraph on re-anchoring / "ratchet fails first" to describe the decoupled shape. ⛔ Do not delete the maintainer-floor rule itself: "Lower them whenever the tree shrinks … Raising one requires a maintainer ruling quoted in the raising PR's body" — that rule is what made this card legitimate and it stays.
test/docs-readme-token-figures.test.ts- Replace the
row.high > row.ceilingcase with the truthfulness relation (banner tracks the measured reading withinBUFFER). ⛔ Re-express the rule, do not delete the file and do not weaken it to nothing — a gate deleted rather than re-aimed is exactly the failure this repo files cards about. - The case tying the row's restated ceiling to
CEILINGS.get(label)stays — it is what stops the README quoting a ceiling the gate no longer commits.
- Replace the
README.mdbanner + the BAND_ROW table- Under the new rule the banner must equal the measured reading, and both rows have drifted: business semantics states ~81k, measured 84,579 ⇒ ~85k; interaction layer states ~39k, measured 37,429 ⇒ ~37k. Seat ruling: apply the new rule uniformly to both rows — it is one rule, and leaving a row on the old basis would mean two rules with no way to tell which governs.
- A changeset. This is tooling + README, no
src/change.
⚠️ Numeral collision — ⛔ never do a repo-wide replace
100,000 / 100000 / $100K appear ~20 times across content/docs/** and test/deal-threshold-parity.test.ts as the opportunity approval threshold — an unrelated business number that is pinned by its own test (a deal at exactly $100,000.00 is on the approval side of the line). ⛔ Touch only CEILINGS and the token-figure surfaces named above.
Measured baseline to work from (⛔ re-measure at branch time; main moves)
node scripts/check-source-token-ratchet.mjs at 81a79ee — the script runs standalone, no node_modules needed:
business semantics ~84,579 (ceiling 85,000, headroom ~421)
interaction layer ~37,429 (ceiling 40,000, headroom ~2,571)
authored total ~136,349 (ceiling 140,000, headroom ~3,651)
Acceptance
pnpm verify green, with test/docs-readme-token-figures.test.ts and test/source-token-ratchet.test.ts both passing on their re-expressed relations — ⛔ not skipped, ⛔ not weakened to a tautology. The PR body quotes the maintainer ruling verbatim.
⚠️ Serial fence — ⛔ do not dispatch while #1533 is in flight
scripts/check-source-token-ratchet.mjs is currently held by #1533 (R39, branch claude/issue-1533-ratchet-importer-comment), which is editing the footer comment in the same file. fold-or-serial: SERIAL, fold refused at gate ① — a false-comment correction and a maintainer-ruled re-anchor are different defect shapes with different fixes, and #1533's dev is authorised to edit comment text, which overlaps this card's header-docblock rewrite. This card is dispatched the moment #1533's PR merges or closes.
src/** metadata to clear lint warnings against ~421 tokens of headroom, and hygiene:tokens is in pnpm verify.
Activity
os-steve commentedon Sep 5, 2026
Claim: PM loop round 39⚠️ This card necessarily touches two files inside epic #1579's declared census territory —
Session:
session_018xtjdpZFjgWh4Ad9Wcx68JBranch:
claude/issue-1601-ratchet-reanchor-100kWorktree:
hotcrm-issue-1601Domain:
repo:hotcrm(single-lane repo — nodomain:*prerequisite)File surface:
scripts/check-source-token-ratchet.mjs(CEILINGSat:226+ the re-anchoring docblock) ·test/docs-readme-token-figures.test.ts(the banner↔ceiling assertion + the BAND_ROW table) ·README.md(both banner figures) ·.changeset/. ⛔ Nothing undersrc/. (stop on breach; explain in the report)Container & model:
M,mode:subagent,model: opus(default judgement tier).dispatch-gates.mjs --tierreturns "no path-derived mandate … floor sonnet · default opus · ceiling fable" and warns its families are an objectstack property ⇒ this seat's judgement. Judgement tier because the card re-expresses a gate's assertion and edits the README's public positioning; ⛔ not the floor. Clause ② does not reach it: hotcrm isprivate: trueand the ratchet is an internal gate, ⛔ not a published contract surface — raising it sits on the maintainer floor, which is a question of who decides (already answered), not of which tier implements.Clause-②: no
Serial constraints cleared:
scripts/check-source-token-ratchet.mjs— free: #1533 / PR #1597 merged 2026-09-05T22:55:22Z (a0edefd3), which was this card's only fence.test/docs-readme-token-figures.test.tsand (read-only)test/source-token-ratchet.test.ts. They are not actively claimed: #1596's live claim declaressrc/**with an explicit ⛔ "notest/**deletions", and #1582–#1587 / #1595 are reserved but undispatched. The touch is unavoidable — the maintainer's ruling cannot be implemented without re-expressing the assertion in that file — and is being declared to the epic seat rather than taken silently. ⛔ Keep it to the one assertion plus the row table.Baseline re-measured on the CURRENT main, ⛔ not inherited
origin/main@a4e5ea3e(two PRs landed since the card was filed:a0edefd3#1597,a4e5ea3e#1599), 2026-09-05T23:0xZ:CEILINGSis still at:226. README banner still states ~81k / ~39k.CEILINGS. It is freshly correct and ⛔ must not be disturbed; this card's docblock work is the re-anchoring paragraph near the top, a different block.Generated by Claude Code
os-steve commentedon Sep 5, 2026
os-dev-report
{ "issue": 1601, "status": "blocked", "branch": "claude/issue-1601-ratchet-reanchor-100k", "pr": "https://github.com/objectstack-ai/hotcrm/pull/1606", "premise_still_valid": true, "summary": "Implemented the ruling: CEILINGS['business semantics'] 85,000 -> 100,000, interaction layer and authored total untouched; the banner rule re-aimed from the banner-vs-ceiling assertion to the ruled truthfulness relation (the band a row publishes must hold the measured reading), with the row-ceiling-to-CEILINGS case kept; both README banner figures moved to the measurement (~81k -> ~85k, ~39k -> ~37k); patch changeset. The header docblock now distinguishes an ANCHORED ceiling from a RULED one, because the raise makes that distinction unavoidable. BLOCKED on one assertion I am forbidden to touch: test/source-token-ratchet.test.ts models EVERY ceiling as anchor() of a measured reading (:536 one worked row per committed ceiling; :544 anchor(row.reading) equals the committed ceiling). A maintainer grant satisfies neither at any value that is not anchor() of a real reading — anchoring to 100,000 needs a reading of 94,286..95,238 and the tree measures 84,579 — so no honest header row exists and fabricating one would also require fabricating the anchoring run its date points at. I wrote the header to reduce the damage from three reds to one, and left that one standing rather than breach the declared surface.", "tests": "Full pnpm verify run stage by stage on the merged tree (exit codes captured by redirect-then-capture, never through a pipe): pnpm validate 0 · pnpm typecheck 0 · pnpm lint 0 (90 pre-existing warnings, none from this diff) · pnpm lint:i18n-gate 0 · pnpm hygiene 0 · pnpm hygiene:tokens 0 · pnpm build 0 · pnpm test EXIT=1 with 'Test Files 1 failed | 159 passed (160)' and 'Tests 1 failed | 3390 passed | 1 skipped (3392)'. The single red is test/source-token-ratchet.test.ts > 'carries exactly one worked row per committed ceiling, in the committed order': AssertionError expected [ 'interaction layer', ...(1) ] to deeply equal [ 'business semantics', ...(2) ] at :536. test/docs-readme-token-figures.test.ts is fully green on its re-expressed relations, all 10 cases. WHAT EACH RUN ESTABLISHES: docs-readme-token-figures proves the re-aimed banner rule holds against a live gate reading; source-token-ratchet proves the header table still derives from the constants for the two ANCHORED rows (its declined-raise and anchor-arithmetic cases pass) and that its model has no ruled ceiling in it. ABLATION of the re-aimed case, from the committed tree: moved the README banner and its worked row together to ~95k (keeps the banner-quote, band-edge and ceiling cases green so only the new relation is under test) -> '× is within the ruled 5% buffer of what the gate measures today' + '× works from a band that actually holds the measured reading', Tests 2 failed | 8 passed (10). On-disk mutation proof taken before the run, not from an editor exit code: injected text grep -c = 1, removed text grep -c = 0, blob hashes changed. Restore under an EXIT INT TERM trap via 'git checkout HEAD -- path', proved by blob hash not exit code: README.md back to 0ea084787109eb7f6ac6066ff0d33834b4cdd1e1 and the test file to 65f86a161e0d162377cb8ced9bbf25cf45b3d308, git diff HEAD empty. HONEST LIMIT: the new case cannot fire alone — rows are pinned to the README banner and to BUFFER, so 'measured in band' is entailed by the tolerance case. It can fail (proved above) so it is not a tautology, but it is a row-level restatement holding the published rounded band accountable, not an independent relation.", "gates": "validate=0 typecheck=0 lint=0 lint:i18n-gate=0 hygiene=0 hygiene:tokens=0 build=0 test=1 (one assertion, in the read-only suite). No narrowing was applied: the full pnpm test was run, not a targeted subset. changeset-check satisfied by a real patch changeset added by this PR — no skip-changeset label used. Re-measured twice: on base a4e5ea3e (84,579 / 37,429 / 136,349, identical to the dispatch) and again after merging current main 8223d0aa, where #1605 moved src/views: 84,579 / 37,447 / 136,366. The interaction layer moved 18 tokens and stays well inside the ~37k band, so no banner figure needed re-cutting — the 5% buffer absorbing routine churn is exactly its ruled purpose.", "line_budget": "4 files, +174/-49 against merge-base 8223d0aa. No skills/** touched, so no published-package line ratchet applies. Per file: .changeset (+52, new) · README.md (+2/-2) · scripts/check-source-token-ratchet.mjs (+59/-16) · test/docs-readme-token-figures.test.ts (+61/-31). Comment mass does not move the token ratchet (it measures src/** comment-stripped), and hygiene's file-size caps are green.", "deviations": "1. scripts/pm/os-verify-lock.sh does not exist in hotcrm (no scripts/pm/ at all), so the shared verify-lock entrypoint my standing clauses mandate was unavailable; heavy commands were run directly and serially in the foreground, and no flock/lockfile was hand-rolled. 2. pnpm verify was run stage by stage rather than as one command, to capture a per-stage exit code; all eight stages were run, so coverage is identical. 3. Merged current main (8223d0aa) into the branch mid-run after #1605 landed on src/views, then re-ran typecheck, hygiene, hygiene:tokens and the full test suite on the merged tree — the reported exit codes are all from that tree. 4. No second claim comment posted and the assignee not touched, per the inherited claim 5555357518, which names this branch and session. 5. Zone 3's suggested reading was tested and falsified — see open_questions.", "files_changed": [ "scripts/check-source-token-ratchet.mjs", "test/docs-readme-token-figures.test.ts", "README.md", ".changeset/ratchet-ruled-ceiling-banner-pins-the-measurement.md" ], "mcp_calls": "5", "open_questions": [ { "question": "test/source-token-ratchet.test.ts cannot express a maintainer-RULED ceiling, and it is outside my declared file surface ('read-only' in the claim; the dispatch says no other test/** file). Its model is that every ceiling is anchor() of a measured reading. How should this land?", "options": [ "A — extend the file surface to that suite and teach it the ruled kind: a RULED_ROW regex, amend the 'one worked row per committed ceiling' case to accept a ruled row for a ruled ceiling, and add a case pinning a ruled row's ceiling to CEILINGS.get(label) while asserting no reading anchors to it. Roughly one regex and one case; the two other pins that the constant broke are already retired honestly by the header rewrite.", "B — leave the model alone and keep the ceiling at 85,000. Not available: the raise is a maintainer ruling and not re-litigable.", "C — make the header row parse by writing a reading that anchors to 100,000. Refused: no such reading exists between the tree's 84,579 and the required 94,286..95,238, so the row and the anchoring run its date points at would both be fabricated measurements." ], "recommendation": "A. It is the only route that keeps the ruling and the gate's own anti-drift discipline. The remaining red is deliberately the one whose message already says 'teach TABLE_ROW the header's new shape — never to relax it, and never to drop the row', so the follow-up is small and self-describing. The work is on the branch and needs no redo." }, { "question": "The gate's opportunistic-tightening advisory now fires on business semantics every run: 'headroom is 15,421 tokens, over twice the 5% buffer — re-anchor this ceiling to ~89,000 in your PR'. Following it hands back the headroom the ruling was made to create. Should a ruled ceiling be exempt from that advisory?", "options": [ "A — leave the advisory as-is and rely on the header prose, which now says a ruled ceiling is not tightened on that line alone.", "B — file a follow-up card to make the advisory skip ruled ceilings, once the ruled kind exists in the model (question 1). This is gate behaviour, so it needs its own card and ruling rather than riding on this one.", "C — accept the tightening back to ~89,000, which would reverse the ruling." ], "recommendation": "B, after question 1 lands. I deliberately did NOT change when the advisory fires — Zone 1 rule 5 forbids building gate behaviour on this card, and the concept the exemption needs (a ruled ceiling) does not exist in the suite yet. C is not available. A alone leaves a standing invitation, in the gate's own output, for a future agent to undo a maintainer ruling." }, { "question": "Zone 3's mechanical assumption is falsified and I want it on the record rather than silently rewritten. The dispatch expected 'on growth the ratchet fails first, on BOTH layers' to become true by construction under decoupling. It becomes false: both bands now close BELOW their ceiling (89,250 vs 100,000; 38,850 vs 40,000), so the banner rule reddens first on both layers.", "options": [ "A — accept the falsification and let the paragraph stop reasoning from the band-vs-ceiling comparison altogether, which is what I implemented. The two reds are paid in different currencies: this one is cleared by restating the banner, which any PR may do; the ratchet's only by shrinking the layer or by another ruling.", "B — pin the inverted relation (row.high below row.ceiling) so the paragraph's new claim is checked the way its predecessor was." ], "recommendation": "A, and I rejected B deliberately. B would make the banner rule's verdict depend on the ceiling again, which is precisely the coupling 「解耦:banner 钉实测,ceiling 独立」 removed — a genuinely independent assertion bought by reinstating the thing the ruling deleted. The rewritten paragraph therefore states no unpinned numeric band-vs-ceiling claim at all." } ], "out_of_scope_findings": [ "NOT FILED as a separate issue, reported here and in the PR body and the gate header instead: the opportunistic-tightening advisory now permanently suggests undoing this ruling (open_questions #2). It is a direct consequence of this card rather than an unrelated defect, and the fix depends on the ruled-ceiling concept that question 1 decides, so filing it now would create a card that cannot be worked. Recommend the seat file it once question 1 lands — flagging it so it cannot vanish if this report is the last word.", "No unrelated defects encountered. The numeral-collision hazard was checked and held: the ~20 occurrences of 100,000 / $100K in content/docs/** and test/deal-threshold-parity.test.ts are the opportunity approval threshold and are untouched — no repo-wide replace was performed." ] }Generated by Claude Code
os-steve commentedon Sep 5, 2026
Seat ruling on the dev's three open questions — Q1 approved with an extended surface, Q3 falsifies the seat, Q2 filed as #1607.
repo:hotcrmseat R39,session_018xtjdpZFjgWh4Ad9Wcx68J, 2026-09-05T23:3xZ. Sent to the dev on the same claim (⛔ no re-dispatch, ⛔ no new branch). Recorded here because a ruling that lives only in a session does not exist.⭐ First: the dev refused to fabricate, and that was the right delivery
test/source-token-ratchet.test.tsmodels every ceiling asanchor()of a measured reading (:536one worked row per committed ceiling;:544anchor(row.reading)equals the committed ceiling). A maintainer-ruled 100,000 satisfies neither: anchoring there needs a reading of 94,286–95,238 and the tree measures 84,579. So no honest header row exists — and writing one would have fabricated both the row and the anchoring run its date points at.The dev shrank the damage from three reds to one, left that one standing, and reported rather than breaching its declared surface. ⛔ That is not a failed delivery; a blocked report with the blocker measured is worth more than a green bought by inventing a measurement.
Q1 — RULED: option A. File surface extended to
test/source-token-ratchet.test.ts.Teach the suite the ruled kind: a
RULED_ROWshape, amend the one-row-per-ceiling case to accept a ruled row for a ruled ceiling, add a case pinning a ruled row's ceiling toCEILINGS.get(label)while asserting no reading anchors to it.Authority, so it is citable rather than inferred:
⛔ Limits unchanged: those two
test/**files only, ⛔ no other test file, ⛔ no deletions there, ⛔ nothing undersrc/.test/**is epic #1579's declared territory; this exception is narrow and declared. ⛔ Option C stays refused.Q3 — the dev falsified the seat's Zone 3, and the seat was wrong
The dispatch predicted that under decoupling "on growth the ratchet fails first, on BOTH layers" would become true by construction. Measured: false. Both bands now close below their ceilings (89,250 vs 100,000; 38,850 vs 40,000), so the banner rule reddens first on both layers. That was this seat's error, recorded here as such — it was written into the order as a suggested reading and it did not survive contact with the tree.
Option A ruled. ⭐ And the dev's reason for rejecting B is better than the seat's original reasoning: pinning the inverted relation would make the banner rule's verdict depend on the ceiling again — reinstating exactly the coupling 「解耦」 deleted, and buying an "independent" assertion with the thing the ruling removed.
Q2 — ⛔ not in this PR. Filed as #1607, fenced behind PR #1606.
The opportunistic-tightening advisory now fires on
business semanticsevery run, asking for a re-anchor to ~89,000 — i.e. instructing the next agent to hand back the 15,421 tokens the ruling was made to create. Real hazard, and the dev was right that it needs the ruled-ceiling concept Q1 introduces before it can be fixed. ⛔ Changing when a gate speaks does not ride on the card that caused it.Interim mitigation stays in this PR as prose only — the header states that a ruled ceiling is not tightened on the advisory's word alone. ⛔ The advisory's firing condition is not touched here.
Also noted from the report
main(8223d0aa, PR Clear three platform lint rule families (31 of 90 warnings), and report the rest with named reasons #1605) mid-run and re-ran on the merged tree — correct.interaction layermoved 18 tokens (37,429 → 37,447) from Clear three platform lint rule families (31 of 90 warnings), and report the rest with named reasons #1605'ssrc/viewsedits and stays well inside its band ⇒ no banner re-cut needed. ⭐ That is the 5% buffer absorbing routine churn, which is its ruled purpose, observed working.100,000/$100Koccurrences are the opportunity approval threshold, untouched, ⛔ no repo-wide replace performed.scripts/pm/os-verify-lock.shdoes not exist in hotcrm (there is noscripts/pm/here at all) — that entry point is objectstack's. The dev correctly ran serially and ⛔ did not hand-roll a lock. Recorded as a lane fact.Generated by Claude Code
os-steve commentedon Sep 5, 2026
os-dev-report
Supersedes the earlier
blockedreport on this card — the seat ruled Q1 as option A and extended the file surface totest/source-token-ratchet.test.ts. Final state below.{ "issue": 1601, "status": "done", "branch": "claude/issue-1601-ratchet-reanchor-100k", "pr": "https://github.com/objectstack-ai/hotcrm/pull/1606", "premise_still_valid": true, "summary": "The ruling is implemented and pnpm verify is green on all eight stages. CEILINGS['business semantics'] 85,000 -> 100,000, with interaction layer and authored total untouched. The banner rule is re-aimed from the banner-vs-ceiling assertion to the ruled truthfulness relation (the band a row publishes must hold the measured reading); the case tying each row's restated ceiling to CEILINGS is kept. Both README figures move to the measurement, ~81k -> ~85k and ~39k -> ~37k, and the gate's own Headline line now prints exactly what the banner states. Under the seat's Q1 ruling, test/source-token-ratchet.test.ts learned the RULED ceiling kind: a RULED_ROW shape, a roster case that merges both kinds on document position and stays the vacuity guard for both parsers, and a NEW invariant that a ruled row restates the committed constant and that no reading recorded in the header anchors to it. Every anchored-row case is untouched, so the suite is strictly more expressive than before, not weaker.", "tests": "Full pnpm verify stage by stage, every run started after the last edit's mtime (last edit 23:31:17Z, final run started 23:31:31Z), exit codes captured by redirect-then-$?, never through a pipe: validate 0 · typecheck 0 · lint 0 (90 pre-existing warnings, none from this diff) · lint:i18n-gate 0 · hygiene 0 · hygiene:tokens 0 · build 0 · test 0 with 'Test Files 160 passed (160)' and 'Tests 3392 passed | 1 skipped (3393)'. WHAT EACH RUN ESTABLISHES: docs-readme-token-figures proves the re-aimed banner rule holds against a LIVE gate reading — it execs the gate in --json mode and hard-codes no figure; source-token-ratchet proves the header still derives from the constants for both ANCHORED rows (its anchor(reading), headroom/percentage, run-dating and declined-raise cases all pass unchanged) and that the ruled row is a grant no recorded reading could have produced. THREE ABLATIONS, each from the committed tree, each proving disk arrival by grep -c on both injected and removed text and each restored under an EXIT INT TERM trap with the restore proved by blob hash rather than an exit code. (1) Re-aimed banner case: README banner and its worked row moved together to ~95k, keeping the banner-quote, band-edge and ceiling cases green -> '× is within the ruled 5% buffer' + '× works from a band that actually holds the measured reading', Tests 2 failed | 8 passed (10). (2) NEW ruled invariant: the 2026-08-17 run's recorded business-semantics reading changed 80,356 -> 95,238, which does anchor to 100,000 -> exactly one red, '× states a ruled ceiling as ruled, and proves no recorded reading anchored it', Tests 1 failed | 21 passed (22). (3) Vacuity guard for the new parser: ruled row deleted outright -> exactly one red, '× carries exactly one row per committed ceiling, of either kind, in the committed order', Tests 1 failed | 21 passed (22). Restores verified by blob hash: gate back to 8bb0b4323a8cbedfdfa9da467cdd01be854201b5, README.md to 0ea084787109eb7f6ac6066ff0d33834b4cdd1e1, docs-readme test to 65f86a161e0d162377cb8ced9bbf25cf45b3d308; git diff HEAD empty after each. HONEST LIMIT, carried forward from the earlier report and unchanged: ablation 1's case cannot fire ALONE — rows are pinned to the README banner and to BUFFER, so 'measured in band' is entailed by the tolerance case. It can fail, so it is not a tautology, but it is a row-level restatement holding the published rounded band accountable, not an independent relation. Ablations 2 and 3 DO each fire alone, so the invariant added to the ratchet suite is independent in a way the banner one is not.", "gates": "validate=0 typecheck=0 lint=0 lint:i18n-gate=0 hygiene=0 hygiene:tokens=0 build=0 test=0. Full pnpm test was run, not a targeted subset — no narrowing applied and none declared. changeset-check satisfied by a real patch changeset added by this PR; no skip-changeset label used. PR #1606 mergeable_state clean, draft true, base still 8223d0aa. Re-measured three times: base a4e5ea3e (84,579 / 37,429 / 136,349, identical to the dispatch), after merging 8223d0aa where #1605 moved src/views (84,579 / 37,447 / 136,366), and again before the final push. main was re-checked immediately before the final run and had not moved past 8223d0aa. The interaction layer's 18-token drift stays well inside the ~37k band, so no banner figure needed re-cutting — the 5% buffer absorbing routine churn is exactly its ruled purpose.", "line_budget": "5 files, +299/-56 against merge-base 8223d0aa, across 4 commits. No skills/** touched, so no published-package line ratchet applies. Per file: .changeset (+62, new) · README.md (+2/-2) · scripts/check-source-token-ratchet.mjs (+59/-16) · test/docs-readme-token-figures.test.ts (+61/-31) · test/source-token-ratchet.test.ts (+115/-7). Comment mass does not move the token ratchet (it measures src/** comment-stripped) and hygiene's file-size caps are green.", "deviations": "1. scripts/pm/os-verify-lock.sh does not exist in hotcrm (no scripts/pm/ at all), so the shared verify-lock entrypoint my standing clauses mandate was unavailable; heavy commands were run directly and serially in the foreground, and no flock/lockfile was hand-rolled. 2. pnpm verify was run stage by stage rather than as one command, to capture a per-stage exit code; all eight stages were run, so coverage is identical. 3. Merged current main (8223d0aa) into the branch mid-run after #1605 landed on src/views; all reported exit codes are from the merged tree. 4. FILE SURFACE EXTENDED BY SEAT RULING mid-task: test/source-token-ratchet.test.ts was read-only in the original dispatch and I reported blocked rather than breach it; the seat ruled Q1 option A and extended the surface, so the work was completed on the same claim and the same branch, with no re-dispatch and no new branch. The two other test/** hard limits were observed — no third test file, no deletions. 5. The worktree was removed after the first (blocked) report per the cleanup clause, then recreated on the same branch to do the ruled work; nothing was lost, as everything was committed and pushed first. 6. No second claim comment posted and the assignee not touched, per inherited claim 5555357518. 7. Zone 3's mechanical assumption was tested and falsified; the seat has accepted the falsification.", "files_changed": [ "scripts/check-source-token-ratchet.mjs", "test/docs-readme-token-figures.test.ts", "test/source-token-ratchet.test.ts", "README.md", ".changeset/ratchet-ruled-ceiling-banner-pins-the-measurement.md" ], "mcp_calls": "11", "open_questions": [], "out_of_scope_findings": [ "Q2 remains with the seat, which said it is filing the card itself, fenced behind this PR: the gate's opportunistic-tightening advisory now permanently prints 're-anchor this ceiling to ~89,000' for business semantics, which is a standing invitation in the gate's own output for a future agent to undo a maintainer ruling. Per the seat's instruction I changed the PROSE only — the header now states plainly that a ruled ceiling is not tightened on that line alone — and left the advisory's firing condition untouched. Recording it here as well so it cannot vanish if this report is the last word on the card.", "No unrelated defects encountered. The numeral-collision hazard was checked and held: the ~20 occurrences of 100,000 / $100K in content/docs/** and test/deal-threshold-parity.test.ts are the opportunity approval threshold and are untouched — no repo-wide replace was performed." ] }Generated by Claude Code
os-steve commentedon Sep 5, 2026
✅ ACCEPT — PR #1606. The maintainer's ruling is implemented and green.
repo:hotcrmseat R39, 2026-09-05T23:5xZ.Reviewed against GitHub and against the branch tree, ⛔ not against the report's self-description.
Checklist
main,Fixes #1601,mergeable_state: clean— ✓['business semantics', 100000],['interaction layer', 40000],['authored total', 140000]. The other two are byte-identical — ✓ Ruling 2 held~81k→~85k,~39k→~37k— both figures moved to the measurement, ⛔ neither left on the old basis. Ruling 4 (apply the new rule uniformly) held — ✓CEILINGSkept. ⛔ Not deleted, ⛔ not weakened to a tautology — ✓ Ruling 3 heldscripts/check-source-token-ratchet.mjs,test/source-token-ratchet.test.ts,test/docs-readme-token-figures.test.ts,README.md, changeset. ⛔ Nothing undersrc/, ⛔ no thirdtest/**file, ⛔ no deletions there — ✓ the extended surface was used exactly as ruledcompleted: success— ✓pnpm verifystages exit 0;test160 files / 3392 passed / 1 skipped, run started 23:31:31Z against a last edit mtime of 23:31:17Z — ✓ a green whose freshness is proven, not assumed⭐ Three ablations, and two of them fire independently
The earlier round's honest limit was that the re-aimed banner case "cannot fire alone" — rows are pinned to the banner and to
BUFFER, so "measured in band" is entailed by the tolerance case. That limit is restated rather than quietly dropped, and the two new ablations answer it:Each proved arrival on disk by
grep -con both injected and removed text, and each restored under anEXIT INT TERMtrap with the restore proved by blob hash, ⛔ not by an exit code. ⇒ the invariant added to the ratchet suite is independent in the way the banner one is not, and the report says so plainly instead of blurring them together.The Q1 ruling was discharged as scoped
test/source-token-ratchet.test.tslearned the ruled kind: aRULED_ROWshape, a roster case merging both kinds on document position that stays the vacuity guard for both parsers, and a new invariant that a ruled row restates the committed constant and that no recorded reading anchors to it. Every anchored-row case is untouched —anchor(reading), headroom/percentage, run-dating and declined-raise all pass unchanged.⇒ strictly more expressive than before. ⛔ Not 门禁削弱, which is what made this the seat's call rather than the maintainer's.
Deviations, accepted
blockedrather than breach the declared surface, and resumed on the same claim and branch after the ruling. ⛔ No re-dispatch, ⛔ no new branch. That is the correct shape for a blocked-then-ruled card.scripts/pm/os-verify-lock.shabsent in hotcrm (there is noscripts/pm/here); ran serially, ⛔ did not hand-roll a lock. Standing lane fact.100,000/$100Koccurrences are the opportunity approval threshold, untouched, ⛔ no repo-wide replace.⇒ Path surface clean —
scripts/+test/+README.md+.changeset/, none of them governed (docs/adr/**,.claude/**,skills/**,AGENTS.md,CLAUDE.md). Clause-②no; hotcrm isprivate: trueand the ratchet is an internal gate, ⛔ not a published contract surface. ⇒ ready → merge queue.⭐ Note for whoever reads this later: the ceiling is now ruled, not anchored. Lowering it needs a maintainer ruling exactly as raising it did — that symmetry is what #1607 makes mechanical.
Generated by Claude Code
test(account): repair the gate pins and re-copy the figures they deri…