feat(spec): publish the dimensionless marker on the reference page - #18684
Merged
Merged
Conversation
The `dimensionless` schema marker landed with its gate reader and no docs half. Ruling B on #14478 put both halves in the mechanism: a marker "declared ON THE SCHEMA, never in a gate ledger … the gate honours and the docs generator publishes". Its sibling `externalVocabulary` has had its renderer since #15626; this one had none, so a key marked `dimensionless` would carry an in-schema declaration the published reference page says nothing about. Adds `dimensionlessNote()` beside `externalVocabularyNote()` in `scripts/lib/schema-section.ts`, appended to the same description cell, and reading the same declaration the gate reads: a non-empty string literal, so an empty or non-string marker publishes nothing. No key is marked by this change — the live population stays 0 — so no reference page moves and no published payload changes. Claude-Session: https://claude.ai/code/session_01JbZnqu8bt6YqfJsr9vaFb3 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JbZnqu8bt6YqfJsr9vaFb3 Co-authored-by: Claude <noreply@anthropic.com>
Contributor
📓 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): |
This was referenced Sep 17, 2026
os-bill
marked this pull request as ready for review
September 17, 2026 15:02
os-bill
enabled auto-merge
September 17, 2026 15:02
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #18500
Clause-②: no
PR #18486 landed the
dimensionlessschema marker with its gate reader and no docs half. Ruling B on #14478 put both halves in the mechanism, verbatim:The sibling marker
externalVocabularyhas had its renderer inpackages/spec/scripts/lib/schema-section.tssince #15626.dimensionlesshad none, so a key markeddimensionlesswould carry an in-schema declaration that the published reference page says nothing about.The gate's own header already asserts the half that did not exist.
check-duration-unit-keys.ts, exemption class 4: "Same mechanism as class 2, same literal-only validation, same visibility." Class 2 isexternalVocabulary, and its visibility is that renderer. This PR is what makes that sentence true.What landed
dimensionlessNote(prop)inpackages/spec/scripts/lib/schema-section.ts, besideexternalVocabularyNote(prop), appended to the same description cell rather than given a column.packages/spec/scripts/schema-section.test.ts, mirroring the sibling's block one-for-one.A key described
Failures seen in the last 5 minutesand carrying.meta({ dimensionless: 'failed attempts' })now publishes:Why that wording
The card suggested "counts
what" and wrote "⛔ no ruling implied", so the shape was read off the declaration instead of taken from the suggestion. The marker's declared value is a non-empty string literal naming what the number counts —check-duration-unit-keys.tsrefuses an empty string and a computed value, because an unverifiable claim exempts nothing — so the declared value is printed verbatim, and the same non-empty-string-literal test decides whether anything is printed at all. The worddimensionlessis kept in front of it for the one thing the value alone does not state: the exemption's claim is that the number has no unit, which is exactly the ambiguity a reader has when the prose beside a naked number names a time unit. It also keeps one vocabulary across the marker name, the census line the gate prints, and the ruling.The three questions the dispatch asked
1. Which gate can actually go red on this change?
packages/spec/scripts/schema-section.test.ts, run bypnpm --filter @objectstack/spec test(vitest projectlocal; the file is not listed invitest.repo-tests.json) — in CI,Test Core.check:docsandcheck:generatedstructurally cannot move: the live population is 0 keys marked, so no reference page changes andcheck:docsis green both before and after. Established by ablation, not assumed — below.2. Does the marker ride into the published JSON Schema via
z.toJSONSchema? — Yes.z.number().meta({ dimensionless: 'failed attempts' })emits"dimensionless": "failed attempts"on the node, unchanged. A fabricated marker name rides identically, so the channel is generic rather than per-key.pnpm --filter @objectstack/spec gen:schema: 18 files underpackages/spec/json-schema/carry"externalVocabulary"(LIT control), 0 carry"dimensionless", 0 carry the fabricated name (DARK controls).packages/spec/json-schema/has 0 tracked files, so this cannot be read from git — it was built and read.⇒ the docs generator is not the only publisher.
json-schemais inpackages/spec/package.jsonfiles[], so a marked key would also ship inside the npm tarball. Nothing is marked by this PR, so nothing moves today — but the second publisher is a fact the first card to mark a key inherits.3. What should it print? — answered from the declared value shape, above.
Clause-② and the changeset
Declared
no, unchanged — the dispatch reserved that line, and question 2's answer does not move it for this diff: no key is marked, so no published byte changes.skip-changeset, measured rather than assumed:packages/spec/package.jsonfiles[]=dist,json-schema,liveness,prompts,llms.txt,README.md,src/**/*.zod.ts,CHANGELOG.md,api-surface,spec-changes.json.scripts/**is not among them.dimensionlessNoteafter the build: 0 hits in every one of those paths. Positive control on the same greps,ObjectSchema:api-surface2,llms.txt1,README.md1,src/**/*.zod.ts14.distcannot carry it either way: everytsupentry inpackages/spec/tsup.config.tsis undersrc/, soscripts/**is not an entry.check:docsgreen ⇒ 0 reference pages move.json-schema/is published — so that card's declaration and changeset are a different question from this one's.Testing
Union run at
d6f2148892(the final commit; gate logs carry no sha, so this is the tree every number below was taken on).pnpm --filter @objectstack/spec test(projectlocal)pnpm --filter @objectstack/spec typecheck(incl.check:scripts-typecheck,check:test-typecheck)pnpm --filter @objectstack/spec check:docs·check:variant-docs·check:liveness·check:empty-state·check:strictness-ledgerpnpm lint(eslint . --no-inline-config, whole repo — not narrowed)node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ...The 5 NOT MEASURED are
check:dts-closure,check:dual-build-cjs-loads,check:lean-entry-closure,check:sourcemap-no-sources-content,check:type-check-debt— each exited 3,PREREQUISITE NOT MET, which those gates spell out as "not a pass and not a finding". All five read built output of the whole monorepo, which this worktree does not have; CI'sBuild Coreis where they are measured. This diff adds no export, no entry point and no emitted file, so it has no channel to reach any of them.Red before green — ablation with an on-disk proof and a hash-verified restore
Run from the committed state, under a
trap ... EXIT INT TERM, against absolute paths:HEAD:packages/spec/scripts/lib/schema-section.tsblob =a92ba895b1f51e8eaf8945e45f8bf8c12ea77e90.dimensionlessNote(prop)term from the description cell.4f00017eab...differs from the HEAD blob.Tests 4 failed | 39 passed (43)— the four cases that assert the note is printed. The two that assert its absence stayed green, which is the predicted direction and what keeps the note from decorating every row in the reference.git checkout HEAD -- path(never a baregit checkout --), then hash re-read =a92ba895b1..., matching, andgit diff HEADempty. Green re-run at the final head: 43 passed.Predicted direction was stated before the run and matched: turn red, not "more diagnostics" and not "inverted".
skills/**derivativeNone. Reading, not expectation: the diff is exactly 2 files (
git diff --name-onlyagainst the merge base), 0 of them underskills/.packages/spec/scripts/build-skill-docs.tsdoes not importschema-section, andcheck:skill-docs/check:skill-refswere not derived for these paths. So no net-line-count reading is owed.Acceptance notes
Out of scope, noted and deliberately not filed:
.meta()channel is generic, not a marker allowlist. A fabricated key name ridesz.toJSONSchemaintojson-schema/exactly asexternalVocabularyanddimensionlessdo, andjson-schema/is published. This is the documented mechanism (xRef/xExpression/xEnumDeprecateduse the same channel by design), not a defect, and none of the three filing classes fits: no repro, no contract violated, and the hazard is metadata being published rather than silently dropped or refused. Who will meet this file next: spec: the genuine duration rows adopt a declaration —DurationMs/DurationSecondsor a unit-suffixed name (census #18078 classes A-true ×6, B ×2, D ×≥2) — step ③ of ruling A on #18115 #18124 step 4, the card that will first mark keys.schema-section.ts". The next marker added tocheck-duration-unit-keys.tscan repeat exactly this half-build. Not filed: it is undemonstrated drift today, ruling B is honoured on the tree as of this PR, and both markers that exist now carry both halves.Dispatch fences observed
packages/spec/src/migrations/**andscripts/check-cross-package-test-inputs.mjsuntouched (the latter moved onmainunder #18667 and arrived through a plain merge oforigin/main, with no conflict and no edit by this branch).packages/spec/scripts/check-duration-unit-keys.tsread only. No live key was markeddimensionless— population stays 0, by measurement above.Generated by Claude Code