feat(sdui): wire the ADR-0080 manifest into the production JSX gate — artefact, freshness gate, witness tests, ratchet-to-zero ledger - #13446
Draft
claude[bot] wants to merge 8 commits into
Conversation
…nerator and provenance record
…ity ratchet; declare the witness test's cross-package inputs
…g filter (check:ci-filter-parity)
…ui-manifest-wiring-r31
… module import adds a frozen TEST_DEBT tsc error
Contributor
📓 Docs Drift Check
What this run could not see
Coarse fallback — 5 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
…ui-manifest-wiring-r31
…y rollback pin — count, prose, and by-name assertion
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 #12924
Implements the 2026-08-29T14:57Z superseding ruling (comment 5463102691): adopt the wiring. All five execution points land here; the three dispatch fences are respected —
examples/app-showcasepages andskills/objectstack-ui/SKILL.mduntouched, no lint.yml step precedes the artefact (the artefact is checked in by this same PR and the gate hard-fails on absence), no new diagnostics ported into validateTree, andpackages/cliuntouched. #12858 stays an independent card and is not ridden along. This PR is held for contract review (clause 2: activating validateTree changes what the save gate refuses) — it stays draft and must not be enqueued until that review clears.Ruling point 1 — manifest source, checked in, freshness gate
sdui.manifest.json(repo root): objectui's public-tier component manifest — 57 components, 66,910 bytes, sha25649211fee7792...c19e69d. Generated from the PUBLISHED@object-ui/*packages at 17.6.0, the version the committed pin.objectui-sha(9602dc820450) ships — verified by reading the pin's ownpackages/core/package.json(17.6.0) via the GitHub contents API. Component set is set-identical toPUBLIC_BLOCKSat the pin (57 == 57, zero symmetric difference; no intrinsic HTML tags; thehtmltier-C escape hatch present).scripts/gen-sdui-manifest-node.mjs: the Node-route producer. Same enumeration as objectui'sapps/console/dev/manifest-dump.tsx(eager-import the 16 registry modules in its order,ComponentRegistry.getPublicConfigs(),manifestFromConfigsfrom the lockstep-pinned@objectstack/sdui-parser), plus the one loader accommodation plain Node needs:.cssside-effect imports resolve to an empty module. Measured this round: 16/16 modules import, 57 configs, 0 lazy stubs, ~4.3 s, no browser, no Playwright, no objectui build. Reproducibility: two generator runs from the same install produce byte-identical output (sha256 match against the checked-in artefact).scripts/sdui-manifest.record.json: provenance (pin sha, package version, sha256, component count).scripts/check-sdui-manifest.mjs(+ self-test, wired in lint.yml): offline freshness gate. Red on absence (the resolver degrades to parse-only SILENTLY — this gate is the thing that notices), on tamper (sha256 vs record), on shape damage, and on a moved.objectui-shawhose record was not regenerated — the anti-rot half the ruling asked for. Reverse-verified on the real tree: a one-token hand edit reds (key/type + hash), a simulated pin bump reds with the regeneration remedy, both restored to a committed state and re-verified green.check:react-declaration-parityEXTERNAL_INPUT_REQUIRED standing: the parity ratchet now runs per-PR in lint.yml against the checked-in manifest (--strict; measured green — "no new DECLARATION divergence vs accepted baseline"; only NEW divergence can red). The ledger prose inpackages/spec/scripts/check-generated.ts("nothing in this repo can hand it one") and the parity script header are now stale but live outside this card's file surface — reported to the PM rather than edited here.Ruling point 2 — the resolver finds it; measured end-to-end, zero cli changes
resolveSduiManifest()path 1 isjoin(process.cwd(), 'sdui.manifest.json'); the CI verify leg and every repo-root CLI run have cwd = repo root. Measured on this branch through the real CLI, both directions:node packages/cli/bin/run.js validate examples/app-showcase/objectstack.config.ts --jsonexits 0, 0 errors, 0 jsx findings (parse-only, the pre-wiring status quo).That red is the gate WORKING (full validation live for
os validate/os build/os lintfrom the project root); its noise is governed by point 4 below. No current CI leg runs those commands from the repo root (the dogfood leg runsverify, which does CRUD/RLS proofs, not authoring lint — measured by reading every CLI invocation in the workflows), so no required context inherits the baseline red.Ruling point 3 — production-path witness tests
packages/lint/src/validate-jsx-pages.production-witness.test.ts(runs in Test Core): reads the checked-in artefact from DISK (findUp to the workspace root — the declared-spelling the cross-package gate recognizes), asserts manifest-only diagnostics fire throughvalidateJsxPagesAND through the production registry entry (runAuthoringRuleswithsduiManifest), pins the arming delta (same stack, parse-only, emits neither), and hard-fails loudly if the artefact goes missing (reverse-verified: removing the file reds the suite at collection). The blind spot the card named — every prior guard fed validateTree an in-memory manifest — is closed by construction: no test in this file constructs one.Ruling point 4 — first-run noise, itemized and ratcheted (ui#6779 shape)
packages/lint/src/sdui-jsx-baseline.json: the ratchet-to-zero ledger — 13 rows itemizing ALL 232 first-run findings (200 errors: div 79+79, a 21+21 across the three shipped pages; 32 warnings: not-a-container on flex, which is objectui#6740). The witness suite holds the live census EQUAL to the ledger in both directions: a finding beyond the ledger is a NEW violation (red, fix the page or regenerate the manifest — never grow the ledger); a row the live run no longer produces is STALE (red, delete the row in the same PR). Both directions reverse-verified red with their exact messages. The corpus itself is deliberately NOT rewritten — that is the dispatch's fence 1 (option A2-1 by the back door), and the ledger keeps the pressure visible until the vocabulary question is settled at the producer.Ruling point 5
#12858 remains independent; nothing here touches the manifest-generation guard.
Mechanically-required accompaniments (declared in a claim amendment on #12924)
turbo.json: 4 inputs appended to the existing@objectstack/lint#testblock (3 page files + the artefact) — demanded by check:cross-package-test-inputs.scripts/cross-package-test-inputs.mjs: the same four paths in the declaration home..github/workflows/ci.yml: one crosspkg filter entry (sdui.manifest.json), verbatim as check:ci-filter-parity's failure text prescribes.Verification (union re-run at final head
c821db62)scripts/pm/dispatch-gates.mjsatc821db62(47 path-matched + convention families; set unchanged vs the pre-merge derivation). All run green at that head, including: check:cross-package-test-inputs (117 self-test cases + "OK: 24 packages... turbo.json hashes every declared glob"), check:examples-live-imports ("0 invisible, 8 inputs-declared, 73 graph-visible"), check:ci-filter-parity ("all 127 declared cross-package globs covered"), check:type-check-debt ("29 ledger entries re-measured... none above its recorded number" — an earlier draft of the test added one tsc error via a NodeNext JSON module import; caught by the ratchet, fixed by switching to readFileSync), check:sdui-lockstep, check:self-test-wired (152 scripts), the new check:sdui-manifest (self-test: 6 cases), and the full battery from the derivation output.@objectstack/lint: vitest 85 files / 2360 tests pass;tsc --noEmitgreen (NOTE: the package tsconfig excludes test files from its own typecheck program — pre-existing package debt; the new test file is verified by vitest execution, eslint, and the TEST_DEBT re-measure, which is the program that actually reads it).@objectstack/sdui-parser: 6 files / 130 tests pass.--format json, and the config declares noparserOptions.projecttype-aware linting, so this diff cannot move untouched files' verdicts).skills/**: untouched (0 lines), so the published-skill line-budget readings do not apply.Changeset
None: this PR releases nothing from any package (published outputs unchanged — check:published-files green; the artefact lives at the repo root, outside every package's files set; the ledger and test are test-layer). Applying the
skip-changesetlabel per the changeset workflow's own prescription for CI-internal changes; noting for the record that the os-dev contract's closed path list is narrower than that prescription — the conflict is #13432, already on file.Out-of-scope finding filed as sub-issue #13445: the runtime save gate's only production caller still passes no sduiManifest (the third independent inertness cause, measured again at
c821db62) — deliberately not fixed here.Generated by Claude Code
Generated by Claude Code