Uh oh!
There was an error while loading. Please reload this page.
feat(spec): declare cloud-connection:panel / marketplace:installed-list in ComponentPropsMap — undeclared keys refused (#11575) - #11743
Conversation
…st in ComponentPropsMap — undeclared keys refused (#11575) - ui/component.zod.ts: two emptyProps rows — key sets measured from the renderers' ACTUAL read points at the .objectui-sha pin (app-shell CloudConnectionPanel.tsx / InstalledListWidget.tsx): both registrations discard the schema node ('() => <Widget />') and neither component takes a prop, so the accepted key set is EMPTY (strict). The registrations' declared 'inputs: []' agree here; the row is the measurement, not the claim. - cloud-connection canonical-expression-envelopes.test.ts: the two exemptUnmappedTypes entries and the emptiness pins deleted — door 3 now reads both bags; the exact-set assert (still in place) demands exactly this. - pins: spec-side (component.test.ts — rows defined, {} accepted, any key refused naming the surface) + lint-side dispatch pins (validate-component-props.test.ts #11575 suite). - semantic migration entry under protocol-18 + regenerated registry (111). - changeset: minor + BREAKING + ADR-0087 disposition (#8744 precedent). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rxnd8cyFnoU8V5y21PaTsy
…oud-connection-props-rows
📓 Docs Drift CheckThis PR changes 1 package(s): ⛔ 1 release-owned page(s) name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 126 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 3d5495d506abd3b4a096a8d76e2b28bbd3a5e81c && git checkout 3d5495d506abd3b4a096a8d76e2b28bbd3a5e81c
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 945ffbea814c07ec93e81a3444af1790d9692cc3 b60e520deaa63de63ab1b0e17baa7cead349153d && git checkout -B drift-repro 945ffbea814c07ec93e81a3444af1790d9692cc3 && git merge --no-ff b60e520deaa63de63ab1b0e17baa7cead349153d
node scripts/docs-audit/affected-docs.mjs --json 945ffbea814c07ec93e81a3444af1790d9692cc3
|
Fixes#11575
Two console-registered widget types on
@objectstack/cloud-connection's published Setup pages —cloud-connection:panelandmarketplace:installed-list— had noComponentPropsMaprow: the #8691/#8744 silent no-op class (any authored key in theirpropertiesbag rode through every validator in silence, because the #5068 gate's dispatch skips unmapped types).What landed
packages/spec/src/ui/component.zod.ts— oneComponentPropsMaprow per type, via the existingemptyPropsfactory (strict, empty accept set). Key sets measured from the renderers' ACTUAL read points at the pinned.objectui-sha(190fbd01d0), never from the registrations' declared-input claims:packages/app-shell/src/console/cloud-connection/CloudConnectionPanel.tsx— the registration lambda renders the component bare and discards the schema node; the component function takes no parameters. Accepted key set: EMPTY.packages/app-shell/src/console/marketplace/InstalledListWidget.tsx— same shape: registration lambda discards the schema node, component takes no parameters. Accepted key set: EMPTY.inputs: []happen to agree with the measurement here (unlike spec:record:reference_railhas no ComponentPropsMap row — an entryfilterparses, typechecks, validates, ships, and silently does nothing #8691/spec:record:alert/record:quick_actions/record:historyhave no ComponentPropsMap row — same silent no-op mechanism #8691 closed for the rail #8744, where they diverged); the rows record the measurement, not the claim. Per the card, no keys were invented to fill a row — an empty strict row is the measured outcome.packages/cloud-connection/src/canonical-expression-envelopes.test.ts— the twoexemptUnmappedTypesentries and the emptiness pins deleted, exactly as the gate's exact-set assert demands in the same PR; the exemption machinery stays for future unmapped types.component.test.ts: rows defined, empty bag accepted, any key refused naming the surface) and lint-side dispatch pins (validate-component-props.test.ts, spec:cloud-connection:panelandmarketplace:installed-listhave no ComponentPropsMap row — two more instances of the #8691/#8744 silent no-op class #11575 suite).ui-cloud-connection-widgets-unknown-keys-refusedunder protocol major 18 + regenerated registry; changeset@objectstack/spec: minorwith BREAKING prose and the registered disposition marker (spec:record:alert/record:quick_actions/record:historyhave no ComponentPropsMap row — same silent no-op mechanism #8691 closed for the rail #8744 precedent).Verification (all at merged head
b60e520de, aftergit merge origin/main)pnpm --filter @objectstack/spec test— 420 files / 11225 tests passed;typecheckOK (test layer held at 55 files / 263 errors in the shrink-only debt ledger, unchanged).pnpm --filter @objectstack/lint test— 81 files / 2274 tests passed;typecheckOK.pnpm --filter @objectstack/cloud-connection test— 26 files / 281 tests passed (includes the edited envelope gate: door 3 now reads both bags; the exact-set assert holds with zero exemptions — which also proves the suite consumed the rebuilt spec dist, since against the old dist it reds).pnpm --filter @objectstack/spec check:generated— "All 14 generated artifacts are up to date" (only the migration registry needed regenerating; no new exports, so api-surface / docs / authorable-surface are unchanged — the map rows are BFS-unreachable from metadata roots by design, per the file's own header measurement).node scripts/pm/dispatch-gates.mjs(no hand-built path list; the derivation's stderr named this repo and my HEAD, change set 7 paths vs merge base). All path-derived and convention-triggered families green, with two declared deviations:check:dev-prereqs— red on "workspace is not built" (37/67 package dists absent in this fresh worktree): a build-state precondition, not a diff finding; every package my diff touches is built; CI builds fresh.check:type-check-debt— NARROWED (declared): the re-measure population is the DEBT ledger inscripts/check-type-check-coverage.mjs; the only DEBT entry among my touched packages is@objectstack/cloud-connection, re-measured with the gate's own measurement (tsc --noEmitin the package): 13 errors = the recorded 13, and none of them are in the file this PR edits. spec and lint are typecheck-covered (not DEBT) and their full typechecks ran green. The full-farm re-measure is CI's.check:type-check-coverage,check:query-options-erasure,check:engine-double-contract,check:where-matcher,check:cross-package-test-inputs— all green.Reverse verification (ablation — both legs rebuilt, both proven on disk)
Fix committed first. RED leg: the two map rows deleted (anchored greps on the exact row text 1/1 to 0/0 = mutation proof on disk), spec rebuilt,
scripts/ablation-dist-preflight.mjsproved the compiled row markers ABSENT from all 209 built files — then the three suites went red in exactly the new pins: spec 3 (the whole #11575 describe), lint 2 (the loud dispatch pins), cloud-connection 2 (the exact-set asserts). GREEN leg: restore from HEAD (greps 0/0 to 1/1, porcelain clean), rebuilt, preflight proved the markers PRESENT indist/ui/index.jsand.mjs, all three suites exit 0. Both leg scripts carried trap-based restores. Note: the lint suite's third pin (empty bag stays silent) is green in both states by design — its value is guarding the accept face, not the row's existence.Clause-②: this PR changes accept behaviour on a published face (silently-accepted authored keys become validated refusals) — draft; the contract-review chain runs before enqueue.
Generated by Claude Code