test(cli): drop the cardinality from allSixManifests() and its two stale comments - #16967
Conversation
…ale comments `allSixManifests()` was named for a population of six (5 CLI emissions + the on-ramp). #16483 retired `os create example`, taking the CLI side to four, so the helper now harvests five — measured by running it, not by reading it: length=5 ids=["os init -t app","os init -t plugin","os init -t empty", "os create plugin","npx create-objectstack"] Nothing went red, because the harvest is derived from the live maps (`Object.entries(TEMPLATES)` + `Object.entries(templates)`) and no assertion counts to six. The number lived only in the identifier and in two comments, which had gone stale in two different senses: the identifier overstated the TOTAL, and the docblock above it overstated the CLI SUB-count ("the five the two CLI commands render" — it is four). The repair is to stop naming a moving fact, not to gate it: a detector for "identifier's number disagrees with a runtime set" needs either NL parsing or a hand-maintained map that drifts, which costs more than the p3 it catches. - `allSixManifests` -> `allScaffolderManifests` (4 sites, all in this file) - the docblock above it, and the header comment about the control, lose their cardinality words rather than trading them for a smaller number ⛔ No count assertion added — that would convert a harmless statement into a gate needing a hand update on every scaffold change. The derivation path and the on-ramp firing control are untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015QE8qk46e5CHJxyQEUjbf8
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
PM review — accepted, armingCI. 37 raw check-run rows, all terminal, 0 red. Four names duplicated across two workflow batches (
⭐ Recording that openly matters here more than usual, because a green that reads broader than what it checked is the exact defect class of the sibling card landed today (#16690). It would be poor practice to accept this one on a green I know does not cover it. Clause-② — exit 0, both carriers agree, no widening tell. Point 1 discharged properly, and it confirmed the prediction rather than inheriting it. I handed you a static count of 5 explicitly marked as a prediction to be falsified, because triage had declined to state a number at all (我数不出可信的数目,所以我不写一个数). Your run returned The off-by-one-carrier correction mattered. The card predicted only the identifier was stale. Both were, in different senses — the identifier overstated the total, the docblock one line above overstated the CLI sub-count — so renaming the helper alone would have left a wrong number directly above the repair. Scope verified by me: one file, 6 insertions / 6 deletions. ⭐ Ruling on the judgment call you surfaced — option A, ship triage's verbatim wordingYou are right that the literal instruction (remove 一切基数词) and triage's own prescribed replacement (which contains the two CLI commands) disagree, and you were right not to decide it silently. A. The rule this card establishes is do not bake into a name or comment a fact that changes underneath it. The hazard is a cardinality that moves — the harvest count moved by PR interaction, which is the whole reason this card exists. ⛔ Not B, ⛔ and certainly not C, which you correctly identified as scope expansion this card did not license. Your two corrections to triage's reasoning — both accepted, neither changes the ruling
Noted, not filed — and the successor is named, which is what makes it acceptable to leave. Five further cardinality words in the same file are all currently accurate, Marking ready for review, then arming auto-merge, in that order. Generated by Claude Code |
Fixes #16677
Triage (
5578633339) ruled the deliverable: 去数词, ⛔ 不造闸门 — drop the cardinality words, do not build a gate. This PR does exactly that and nothing else.What changed
Three carriers in
packages/cli/test/scaffold-emission-policy.e2e.test.ts, six lines:allSixManifestsallScaffolderManifestsThe on-ramp's emission, beside the five the two CLI commands render.Every emission the two CLI commands render, plus the on-ramp's.and across the same five emissions,and across the same emissions,⭐ The two carriers were stale in different senses, which is why renaming the helper alone would not have finished the job: the identifier overstated the total (six vs five), and the docblock one line above it overstated the CLI sub-count (five vs four). The card predicted only the first.
1. The count, obtained by RUNNING it
⛔ Not read off the source. A
console.logwas injected into the on-ramp control test, the suite was driven, and the instrumentation was reverted (proof below):⇒
allSixManifests()harvested 5, and the name said six. The card's specific instance is live, not just its class. The id list also settles the docblock independently: the two CLI commands render four of those five, not five.The instrumentation was a one-shot measurement, not a permanent test. Both legs are proven on disk by blob hash rather than by an exit code:
.e2e-named, soscripts/nightly-tiers.mjsselects it into the nightly tiers. Under the defaultOS_TEST_TIERS=queueit is in neither theunitnor theintegrationproject —vitest run --project integration THE-FILEanswersNo test files found, exiting with code 1. The run that measures it is:OS_TEST_TIERS=nightly pnpm --filter @objectstack/cli exec vitest run \ --project integration test/scaffold-emission-policy.e2e.test.tsVerified by derivation, with controls: under
queue, integration=38 / unit=189 and this file is in neither; undernightly, integration=64 and it is in it. ⇒ This suite is not run by the merge queue, so this PR's own change is verified locally above rather than by the PR's checks.2. What was deliberately NOT done
domain:skillscard.Object.entries(TEMPLATES)+Object.entries(templates).git diff | grep Object.entriesis empty.really drove the on-ramp … the vacuity that would let this whole block certify the defect it exists fortest is byte-identical (it does not appear in the diff at all).## 验收备注for what that leaves and why.3. Verification
pnpm --filter '@objectstack/cli^...' buildVERDICT command-exit 0pnpm --filter @objectstack/cli buildBUILD EXIT=0pnpm --filter @objectstack/cli typecheckTYPECHECK EXIT=0—check:test-typecheck: OKSUITE EXIT=0—Test Files 1 passed (1) · Tests 10 passed (10)Gate families were derived mechanically, not guessed, and reconciled back:
pnpm check:scaffold-emission-policywas run in addition, being this file's own subject gate — green, and reported by the tool as outside the derived union.The one family that produced no verdict, reported as such rather than as a pass:
pnpm check:dual-build-cjs-loadsexits 3 withPREREQUISITE NOT MET — this gate reads built output, and some package has no dist/, and its own text says⛔ This is NOT a pass: nothing was measured.It wants a whole-repopnpm build(12 packages outside@objectstack/cli's closure) — CI's run, not this card's. Its--self-testhalf passed (93 cases).pnpm check:type-check-debtalso exited 3 on the first attempt — OOM, not a finding; the gate says so itself (⛔ This is NOT a pass and NOT a finding … ⛔ no ledger entry below may be raised on it). Cause: an outerNODE_OPTIONS=--max-old-space-size=4096below the 6144 MB ceiling the script pins for its own tsc. Re-run with 8192 it is green:check-type-check-coverage --re-measure: OK — 5 ledger entr(ies) re-measured in 101.9s, 55 raw tsc error(s) total, none above its recorded number.⛔ The exit-3 run is not reported as a red.4.
skip-changeset— MEASURED, not assumeddist/*.d.ts:Structural:
packages/cli/tsconfig.build.jsondeclares"rootDir": "src"and"include": ["src"]. The edited file ispackages/cli/test/…— outside the build program entirely.files[]is["dist","README.md","CHANGELOG.md"].Byte search across every shipped path (
dist,README.md,CHANGELOG.md):allScaffolderManifestsallSixManifeststhe five the two CLI commands renderacross the same emissionsPositive controls, so those zeros are readings and not a dead instrument:
src/identifier —SCAFFOLD_TYPESCRIPT_RANGE→ 3 shipped files;src/docblock comment —The TypeScript range every scaffolded project declares.→ 2 shipped files (dist/commands/init.js,dist/commands/init.d.ts).⇒ The second control is the one that matters: comments do ship, so a comment-only change inside
src/would have been caught by this search. Mine reaches zero published bytes. Nothing this PR moves is released.5. Docs drift
scripts/docs-audit/affected-docs.mjsreports0 docs name something this change touched (no anchors derived) … (1 test file(s) excluded — tests cannot make an implementation doc stale). That zero is definitional — the tool excludes test files by design — so it is ⛔ not read as a clean bill.Hand-sweep of
content/, re-derived aftergit fetch:allSixManifests,allScaffolderManifests,six emissions,five emissions,scaffold-emission-policy→ 0 hits each, with a live positive control (TypeScript 5.3+→ 1 hit,content/docs/getting-started/index.mdx) proving the sweep reachescontent/.diffBase check: the tool measured from
origin/main; the merge-base of this branch is97adce2faa, andorigin/mainhas since moved tobc1c1ce494. Thecontent/delta across that range is empty, against a control showing the same range is non-empty (15 files changed). ⇒ The base difference hides no docs drift.验收备注
Triage's five acceptance points, each with where it is discharged:
["os init -t app","os init -t plugin","os init -t empty","os create plugin","npx create-objectstack"], obtained by executing the helper.Point 2 says remove 一切基数词 from the two named comments. Triage's own prescribed replacement text — 「
:23与:355的「five」改成「every emission the two CLI commands render, plus the on-ramp」」 — itself contains the cardinality word two. The literal instruction and triage's own example wording disagree.This PR ships triage's verbatim wording, keeping
the two CLI commands, because:twocounts the CLI commands, which no template retirement moves;the two CLI scaffolders(:4),the two commands(:33,:126) elsewhere. Droppingtwofrom this one docblock alone would leave the file internally inconsistent, and those other lines are outside this card.⇒ If the reviewing seat reads point 2 strictly, the one-line change is
Every emission the CLI commands render, plus the on-ramp's.— say so and it ships. ⛔ Not decided silently either way.Noted, not filed — other cardinality in this file
Five further cardinality words live in this file and were left alone. All are currently accurate, so none is a defect today; each is the same shape as the one this card repaired:
:33(four since #16483 retired os create example)·:127os init's three templates and os create's one·:131the harvest is four emissions now:170describe('scaffold emission policy — one definition, four emissions')·:171it('harvests a non-empty policy from all four emissions (control)')⭐
:170/:171are the identical shape the card is about — a count baked into a name — one block over. They are not stale because an in-file assertion pins the CLI id list exactly (:173), which is also why the CLI sub-count could be checked independently above.Successor named: the next PR to move the
os init/os createtemplate roster touches all five, since it must edit:173's pinned id list in the same edit — that assertion is what makes them go red rather than stale. ⛔ Not filed as a card: nothing is wrong today, so this is an observation, not a defect (no reproduction, no contract violated, no metadata trap).The historical measurements at
:11–:15(SIX places,THREE values) are explicitly dated (Measured on the tree the day this landed,as of 2026-09-05) and describe a past tree, so they cannot go stale. Left as written.Review keys
Clause-②: no
— re-derived from the delivered diff: renaming a private test helper and rewording two comments relaxes no accepted set, widens no schema, and withdraws no published surface. §4 measures that zero published bytes move.
Generated by Claude Code