Skip to content

docs(readme): state the positioning claim as the two measured layer figures (#1187) - #1197

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-1187-readme-headline-figures
Aug 17, 2026
Merged

os-steve merged 1 commit into
mainfrom
claude/issue-1187-readme-headline-figures

Conversation

@os-steve

@os-steve os-steve commented Aug 17, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #1187

The README banner sold the app as "~170k tokens of typed ObjectStack metadata
(~18,000 lines)". Both figures were a hand measurement of a tree that had since
moved — the one number in the repo with no source, on the first line a reader
sees. It now states the two layers the maintainer asked customers to be shown,
each read from the gate that landed in #1183.

The figures are the gate's, taken on this branch

$ node scripts/check-source-token-ratchet.mjs          # at f5373112
  business semantics          76   8,460   323,068    80,767
  interaction layer           33   4,689   155,392    38,848
  authored total             152  14,236   533,861   133,465

  Headline: business semantics ~81k · interaction layer ~39k · authored total ~133k
  ✓ source token ratchet clean

The banner says ~81k, where the ruling said 「写实测值 ~80k / ~39k」 — please
sanity-check this one.
That is not a departure from the ruling, it is the
ruling applied to today's tree: the instruction was to publish the measured
values, and the digits quoted alongside it were the measurement as it stood at
that moment. main has moved since. ~81k is what the gate's own headline()
prints, so the README and the command it tells readers to run agree character
for character. Nothing was hand-rounded.

Translations and seed data stay out of the accounting per
「translations + seed 肯定是不需要算 token 的」, and the banner says so in one
small-print clause — without it a reader who compares ~81k against the size of
src/ is being told a number for a surface they cannot see.

The phrasing: accurate today vs accurate in six months

The card asked me to argue this choice rather than just pick digits. The
measurement moved 80,411 → 80,356 → 81,233 → 80,767 in one working day as four
ordinary PRs landed, crossing the ~80k/~81k rounding boundary twice. A banner
pinned to today's rounded reading would need a PR at every one of those steps —
which is the same maintenance defect this card is closing, one decimal place
down, and the first person to pay that tax twice deletes the guard.

I did not solve that by weakening the claim into a bound ("under 85k"). A
ceiling is a bigger, vaguer number, and it works against the message: the
selling point here is that the app is small, so inflating the published figure
to buy durability trades away the thing being sold.

Instead the durability lives in the tolerance, and the tolerance is one the
maintainer has already ruled: 「给 5% 缓冲」, the same 5% working buffer the
ratchet's ceilings carry through its anchor(). Reusing it rather than inventing
a README-specific number is what makes this stick — the banner and the ratchet
ceiling now go stale at almost the same reading, so re-stating the claim is a
maintainer-ruling moment rather than merge overhead:

layer banner 5% band ratchet ceiling
business semantics ~81k 76,950 – 85,050 85,000
interaction layer ~39k 37,050 – 40,950 42,000

On business semantics the band's upper edge sits just past the ceiling, so the
ratchet goes red first — the banner cannot be lying while CI is green. On the
interaction layer the ceiling's round-up-to-1k left it 7.5% of headroom instead
of 5%, so the doc guard is the tighter of the two and fires about 1k early.
Early is the safe direction for a doc guard; late is the direction that cost us
this card.

So: accurate today and accurate in six months, without buying the second
with a vaguer claim.

The claim now defends itself

test/docs-readme-token-figures.test.ts parses both figures out of the banner
and compares them against a live --json run of the gate. Expected values are
never written down in the test — they are read by running the same command CI
runs, for the reason the #729 count rule gives: a hard-coded expectation is just
the hand-maintained number moved into a test file, stale on the next merge. Five
assertions: a vacuity guard (one figure per layer, so a reflow cannot silently
disarm the rule), the layer names matching the gate's own, the accounting-basis
clause, the 5% tolerance, and a check that the banner never claims a figure the
ratchet would already reject.

It is a sibling file rather than a block inside test/docs-drift.test.ts,
which is where the card pointed it. docs-drift.test.ts is 100,190 bytes against
the 102,400-byte ceiling in scripts/check-source-hygiene.mjs — appending this
block took it to 107KB and turned the hygiene gate red. Most of that rule family
already lives in sibling test/docs-*.test.ts files, so this follows the
convention instead of inventing one. Filed the near-cap condition separately, see
below.

Reverse verification

Predicted red-before / green-after and measured both ways, from the committed
state each time.

Restoring the pre-fix banner — the drift that opened this card — reddens three of
the five assertions:

FAIL > states exactly one figure for each layer the gate reports
  business semantics: 0 match(es) for business semantics \([^)]*\) in \*\*~([\d.]+)k tokens\*\*
  interaction layer: 0 match(es) for interaction layer \([^)]*\) in another \*\*~([\d.]+)k\*\*
FAIL > names layers the gate actually measures, and cites the gate
FAIL > states the accounting basis the ruling set
  Tests  3 failed | 78 passed

Hand-corrupting the interaction figure to ~41k — deliberately chosen as inside
the ratchet ceiling (42,000) but outside the 5% band — isolates the tolerance
assertion, which is the one that could have been vacuous:

FAIL > is within the ruled 5% buffer of what the gate measures today
  interaction layer: banner says ~41k, the gate measures 38,848 (band 38,950–43,050)
  Tests  1 failed | 80 passed

The ceiling assertion correctly stayed green there, since 41,000 is under 42,000.

#1191 — the repository description

Update, mid-task: the description is no longer the drifted string, and it is
being edited live.
When I started it read the ~170k tokens sentence #1191
quotes. It then changed twice while this branch was in verification — both
observations inside four minutes:

05:20:19Z  … in typed ObjectStack metadata — business logic under 100k tokens,
           the whole authored app under 150k. Small enough to hand an agent in
           one context window.

05:23Z     … in typed ObjectStack metadata — business logic under 100k tokens.
           Small enough to hand an agent in one context window.

I did not set either and cannot — the GitHub MCP surface here has no
update_repository and there is no gh CLI — so another actor on our shared
identity is applying them. Flagging rather than touching or chasing: read the
live value, not my transcription above, which may already be stale again.

Where that leaves the card, for your call:

  • The drifted ~170k claim is gone from the live surface, which was The GitHub repository description still quotes the drifted "~170k tokens" claim — it is not in the tree, so #1187's grep cannot find it #1191's
    actual defect. Every value I saw it hold is true against today's gate: business
    semantics 80,767 is under 100k, and the authored total 133,465 was under the
    150k the earlier version also carried.
  • The description states bounds; the README states the ruled measured pair. I
    think that split is right rather than an inconsistency to iron out — the
    description has no CI guard and cannot get one, so it should not carry digits
    that drift, while the README can carry them precisely because the test above
    holds them honest.
  • The one point worth a deliberate decision: the ruling asked that customers be
    shown two layers, and the current description states a single bound, on
    business logic only. The interaction layer is no longer represented there.

If you would rather the description mirror the README's pair, this matches it
(297 chars, GitHub's limit is 350):

The reference app for AI-written enterprise software: a complete CRM whose whole business semantics (objects, flows, actions, hooks) is ~81k tokens of typed ObjectStack metadata, and whose whole interaction layer is another ~39k. Every business rule fits in a fraction of one agent context window.

Otherwise the current string needs no edit from me. Either way #1191 is not
closed by this PR
— merging it does not touch repo metadata — and it is now
best assessed against the live description rather than the one quoted in its body.

Two corrections to the card's scope

The archived report never carried this claim, so there was nothing to leave
alone.
The card records docs/archive/2026-02/CRM_INDUSTRY_AI_TRANSFORMATION_REPORT.md
as the second tracked file stating it. That is a false positive from grepping
bare 18,000: the only hit in that file is
120 hours/month × $150/hour = $18,000/month, a labor-cost calculation with no
relation to tokens. Searching the whole tracked tree for 170k, 170,000,
18,000 lines and context window finds the claim in README.md and nowhere
else. I did not touch the archive — and I agree with the card's reasoning that
rewriting a dated historical record to match today's measurement would be worse
than leaving it, had there been anything there to rewrite.

No other surface carries it. objectstack.manifest.json's description is a
feature list with no token claim; content/docs/, apps/docs/,
README.legacy.md and the marketplace publisher are all clean. Re-checked after
the change:

$ git grep -nI "170k\|170,000\|18,000 lines"
(no matches)

Gates

Full pnpm verify green on the pushed tree, f5373112 — the real exit code, not
a piped one:

validate ✓ (1190ms) · typecheck ✓ · lint ✓ · lint:i18n-gate ✓
hygiene ✓ source hygiene clean · hygiene:tokens ✓ source token ratchet clean
build ✓ · test  Test Files 111 passed (111)   Tests 2685 passed | 1 skipped (2686)

Also ran, since they are ci.yml steps verify does not cover:
node scripts/check-stackblitz-lock.mjs (in sync) and
pnpm changeset status --since=origin/main (hotcrm → patch).

Left to CI, per #1149: test:coverage (same suite, instrumented), e2e.yml
(Playwright, needs a running app — this change touches no runtime metadata),
link-check.yml (the only URL in the added lines is the pre-existing ObjectStack
link, target unchanged), and CodeQL.

Out-of-scope finding

test/docs-drift.test.ts sits at 100,190 of the 102,400-byte hygiene ceiling —
97.8% full, so the next rule added to it turns the gate red, as this card's first
attempt did. Filed unassigned as #1196 rather than fixed here — two closed
precedents (#814, #635) show the same condition being found only when it bites.

Generated by Claude Code

…igures (#1187)

The banner sold the app as "~170k tokens of typed ObjectStack metadata
(~18,000 lines)" — a hand measurement of a tree that had since moved, and
the one number in the repo with no source. It now states the two layers the
maintainer asked customers to be shown, each read from the gate landed in
#1183: business semantics ~81k tokens, interaction layer ~39k, with
translations and seed data outside the count by ruling.

test/docs-readme-token-figures.test.ts holds the banner to a live --json run
of scripts/check-source-token-ratchet.mjs, within the maintainer's already-
ruled 5% working buffer, so the next drift fails CI instead of surviving to
the next audit.
@vercel

vercel Bot commented Aug 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
hotcrm Ignored Ignored Aug 17, 2026 5:20am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation ci/cd CI plumbing and the verification pipeline labels Aug 17, 2026
@os-steve
os-steve marked this pull request as ready for review August 17, 2026 05:27
@os-steve
os-steve added this pull request to the merge queue Aug 17, 2026
Merged via the queue into main with commit f1f075c Aug 17, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd CI plumbing and the verification pipeline documentation Improvements or additions to documentation

Projects

None yet

2 participants