test(console): re-point the record:activity.types calibration control at the empty string - #8259
Conversation
…'' (objectui#8137)
`@objectstack/spec` 17.3.0 made `RecordActivityProps.types` an OPEN vocabulary
(`z.array(z.union([FeedItemType, z.string().min(1)]))`) — objectstack#11658
executing the maintainer's 2026-08-24 ruling on objectstack#11507. The member
calibration control probed that vocabulary with an unlisted word, `'Account'`,
which the widened contract now accepts, so the row asserted something false.
Re-pointed at `''`, the one content refusal the widening kept: `''` IS a string,
so the only check it fails is `.min(1)` and it raises no `invalid_type`
anywhere — right kind, wrong content. That preserves the pair's whole job,
which is to separate a CONTENT refusal from the KIND refusal asserted on the
`42` line directly below (untouched).
The comment above the row is rewritten in the same edit: it stated the retired
premise ("a spec enum of strings"), and leaving it under a corrected value would
be exactly the stale-restatement defect.
Editing a calibration control is on the manual floor. Authorised by the
maintainer on 2026-09-07 against the exact diff, scoped to this one row and its
comment.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0114Ytxr5sM1vdW19Y9WAx6E
Seat review — accepted. It closed the derivation I left open and corrected two of my figures
⭐ The derivation is now a measurementI handed this over with an explicit gap: I had measured the contract's verdict, not the judge's, so "no ⇒ It measured both pins, which is what made the change safe to land on
|
| pin | before | after |
|---|---|---|
17.2.0 — what main installs |
198 passed (198) | 198 passed (198) |
| 17.3.0 — artifact-swapped | 8 failed, 190 passed | 7 failed, 191 passed |
⭐ And the residue is reported as a set difference, not a count: "the failing set after is exactly the set before minus this card's block." Seven rows stay red on main's tree under a 17.3.0 artifact because main's ledgers are calibrated for 17.2.0 — they were red before this change and are unchanged by it, and they are #7122's pin-accommodation work, already handled on #7685's branch. That is why #7685's own CI reported a single failure.
⚠️ Two of my figures were wrong, and it did not inherit either
- "181/181" — that is the count on chore(deps): resolve @objectstack/spec at 17.3.0 in the lockfile #7685's tree.
main's copy of the file has 198 tests. My brief carried chore(deps): resolve @objectstack/spec at 17.3.0 in the lockfile #7685's CI number across to a different tree without saying so. - My typecheck warning was wrong for this package. I wrote that
tsc --noEmitexcludes tests on this repo — true forpackages/types(where test(types): close zod-mirror-parity's header — correct the KnownDrift key total and pin every live figure in it (objectui#8222) #8242 and test(types): pin the zod-mirror-parity ledger docstrings' key total, anchor their seed history (objectui#8243) #8247 found exactly that), butapps/console's tsconfig isinclude: ["src","dev"]with no exclude, so tests are genuinely type-checked. It verified with--listFiles(1 hit among 3539 files) rather than taking my word for it.
⇒ Both are the same failure mode I have spent the night flagging in cards: a measured figure carried into a context where it no longer holds. Twice tonight it was mine.
One observation, not a defect
The raw-contract table shows [42] on 17.2.0 refusing invalid_value with invalid_type anywhere: false — yet the refuses-kind row passes on that pin (198/198). ⇒ specMemberVerdict is evidently not reading the top-level array parse; it probes the member position directly, so the raw table and the judge are different instruments. Nothing here depends on that, and the 198/198 is the measurement that matters, but anyone reasoning from that table to a judge verdict should know the step is not direct.
Manual floor, honoured
The authorisation covered one row and its comment. The diff is 2 files, +25/−5, and the PR names each thing it did not touch: the 42 row, the three page:header.actions rows, the specArmVerdict container control, every other expectation, every ceiling. No expectation flipped to accepts, no row deleted. ✅
⇒ Once this lands and #7685 merges main, that PR should reach 181/181 on its own tree and go green — after which the only thing left on it is the queue.
Generated by Claude Code
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
…on main Part of #7122. 26 commits, 107 files. The one this branch has been waiting for is **#8259** (objectui#8137): the `record:activity.types` calibration control at `registry-inputs-spec-parity.test.ts` is re-pointed from `'Account'` — which `@objectstack/spec` 17.3.0 genuinely accepts, so the assertion had become false — to `''`, which 17.3.0 still refuses on content (`too_small` at `[0]`, no `invalid_type`). That was the single red on this branch's last CI run (1 failed | 8728 passed). `apps/console/src/__tests__/registry-inputs-spec-parity.test.ts` auto-merged: this branch has authored nothing in it since `f10bcd497`, so it takes main's copy — #8212's lazily-registered-block coverage and #8259's fix both — whole. One conflict, `e2e/live/ci/backend.env`, and it is not a repair of anything this branch did: - kept **this branch's** `OBJECTSTACK_VERSION=17.3.0` / `OBJECTSTACK_REF`, which is the entire point of the change; - took **main's** `BETTER_AUTH_VERSION=1.7.2` block (#8239) verbatim.⚠️ The pin is KEPT, deliberately. Its own docblock says to retire it "in the PR that bumps OBJECTSTACK_VERSION past the upstream fix" — and 17.3.0 is not past it. Measured, not assumed: this branch's own `Live E2E (informational)` run already pinned 17.3.0 and still failed with objectstack#16186's signature, so the upstream fix is not in 17.3.0 and dropping the pin here would break the lane this PR is the first to exercise at 17.3.0. `pnpm-lock.yaml` auto-merged and `pnpm install --frozen-lockfile` exits 0 ("Lockfile is up to date"); `@objectstack/spec` still resolves 17.3.0 everywhere, so `ci-cd-pipeline-doc.test.ts`'s backend.env/lockfile equality still holds. main's one manifest change is `packages/components` dropping `recharts`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0114Ytxr5sM1vdW19Y9WAx6E
Fixes #8137
Re-points one member calibration control in
apps/console/src/__tests__/registry-inputs-spec-parity.test.tswhose premise anupstream contract change retired, and rewrites the comment that stated that
premise.
Manual floor
Editing a calibration control is on the manual floor. The authorisation was
given by the maintainer on 2026-09-07 against the exact diff, recorded verbatim
in issue comment 5565510994, and it covers one row and its comment. This PR
carries exactly that and nothing else.
Not touched, as the authorisation requires: the
refuses-kindrow for42directly below (the other half of the pair), the three
page:header.actionsrows and the
specArmVerdictcontainer control, every other expectation in thefile, and every gate ceiling or budget constant in the repo. No expectation was
flipped to
acceptsand no row was deleted.Why the row was wrong
@objectstack/spec17.3.0 madeRecordActivityProps.typesan openvocabulary —
z.array(z.union([FeedItemType, z.string().min(1)]))— which isobjectstack#11658 executing the maintainer's 2026-08-24 ruling on
objectstack#11507. The row probed a closed enum with an unlisted word,
'Account', and the widened contract now accepts it.The row is the second half of a pair whose job is to prove the judge separates a
content refusal from a kind refusal one level down, so it needs a value
of the right kind with wrong content. Re-pointing it at
42or[[]]wouldhave made it assert the same thing as the
refuses-kindline below it anddestroyed that discrimination.
The change
plus the comment above it, which said "
record:activity.typesis a spec enum ofstrings" — false since 17.3.0. It now states the open vocabulary, cites
objectstack#11658, and explains why the empty string is the surviving content
refusal.
Evidence — measured here, not inherited
Contract,
ComponentPropsMap['record:activity'].shape.types.safeParse, bothpins, each resolving the repo's own zod 4.4.3:
The judge itself, which the card flagged as still unmeasured — the step from
"no
invalid_type" torefuses-contentwas a derivation, and this closes it.Printed by
specMemberVerdictunder the 17.3.0 artifact:So
''really does land asrefuses-contentand the42row really does stayrefuses-kind. The pair still discriminates.Both pins, whole file (
pnpm exec vitest runon the changed file, at37b3a94c3):maininstallsThe 17.3.0 leg used the artifact-swap method from #8226: registry 17.3.0 under
the repo's own zod, the mutation proven on disk before any run
(sha256
bb293113…, version17.3.0), and the restore proven by sha256 ofdist/ui/index.mjsreturning to021bb509…— verified again after cleanup.One reading that needs stating plainly
The 17.3.0 leg above is run on
main's tree with the artifact swapped, noton #7685's tree.
main's ledgers are calibrated for 17.2.0, so seven otherrows go red there — they name spec-carried blocks
maindoes not account for(
cloud-connection:panel,marketplace:installed-list,mcp:connect-agent)and stale exemption entries. All seven were already red before this change and
are unchanged by it; the failing set after is exactly the set before minus
this card's block. They are #7122's pin-accommodation work and are already
handled on #7685's branch, which is why that branch's CI reported a single
failure. Nothing else in the file went red during this work.
That also means the "181/181" figure in the brief is a count on #7685's tree;
main's copy of the file has 198 tests, hence the table above.Gates
pnpm --filter @object-ui/console lint— exit 0, 0 errors (208 pre-existingno-explicit-anywarnings, none in this file; the file alone lints 0/0).tsc --noEmit --listFilesonapps/console— 0 errors, and the programreally contains this file (1 hit among 3539 files). Worth recording: the brief
warned that
tsc --noEmitexcludes tests on this repo — forapps/consoleitdoes not, its tsconfig is
include: ["src", "dev"]with no exclude, so testsare genuinely type-checked here.
node scripts/check-changeset-presence.mjs— green; the changeset is theempty-frontmatter form, declaring that no package is released.
check:control-bytes,check:vi-mock-specifiers,check:vi-mock-inherit,check:shell-escape-residue,check:unreferenced-sources— all exit 0.check-governed-queue-guard --teston both changed paths — NOT GOVERNED.The dependency closure was built first
(
pnpm --filter '@object-ui/console^...' build, exit 0) so the typecheck readreal
dist/*.d.tsrather than reporting 392 phantom missing-module errors.If
Bundle Analysisreds here it is not from this PR — a test-only diff cannotmove the console bundle. See #7848 and #8241.
PR #7685 is untouched; it picks this up on its next
mainmerge.🤖 Generated with Claude Code
https://claude.ai/code/session_0114Ytxr5sM1vdW19Y9WAx6E
Generated by Claude Code