Repository navigation
fix(lint)!: os build and the page save door refuse a page component props CEL slot over the platform parse bounds (#25002) - #25088
Conversation
…ntry gating Claude-Session: https://claude.ai/code/session_01D6F9axfoPzR7t8G1J7Ytzz Co-authored-by: Claude <noreply@anthropic.com>
…lot over the parse bounds; changeset Claude-Session: https://claude.ai/code/session_01D6F9axfoPzR7t8G1J7Ytzz Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
What this run could not see
Coarse fallback — 4 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 8ab9e9729b6f442d716e56336e4fb338b907d14a && git checkout 8ab9e9729b6f442d716e56336e4fb338b907d14a
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin a39389eb51738cc91fa450a1f3035d221ec65642 53ae2b07d2f2be712aff6188db39f23a1e46081e && git checkout -B drift-repro a39389eb51738cc91fa450a1f3035d221ec65642 && git merge --no-ff 53ae2b07d2f2be712aff6188db39f23a1e46081e
node scripts/docs-audit/affected-docs.mjs --json a39389eb51738cc91fa450a1f3035d221ec65642
|
Seat review — PASS ·
|
Closes #25002
Clause-②: no (narrowing: a page component props CEL slot over the platform parse bounds is refused at
os buildand the page door; it ships now under the amended 「甲」, #60156303865025)What changes
page-predicate-over-budget(validatePagePredicateBounds,packages/lint/src/validate-page-predicate-bounds.ts) reports aterrorinstead ofwarning. In the same edit, its entry inpackages/lint/src/authoring-rules.tsmoves from theadvisorytier to thegatingtier. A page carrying a CEL slot inside a component'spropertiesbag whose source overrunsDEFAULT_LIMITS(maxAstNodes256,maxDepth,maxListElements) now failsos validate,os buildandos lint. An active write of that page, or the promotion of its draft, is refused at the page save door. This is the refusal half of #24953, re-timed to 18.x by triage (6305866852) under the amended 「甲」 (#60156303865025).gating.PagePredicateBoundsFinding.severityis typed'error'.errorto the refusal and the rest toadvisories.The door's code, measured
The card says
422 VALIDATION_ERROR. The page save door actually answers422 INVALID_METADATA, the author-time refusal envelope every runtime-gate refusal uses. The new pin asserts{ code: 'INVALID_METADATA', status: 422 }, the same as the #23388 and #24491 page blocks next to it. The changeset saysINVALID_METADATA.Tests
packages/lint/src/validate-page-predicate-bounds.test.ts: the warning assertions are now error assertions. The finding isseverity: 'error', and each ofos validate/os build/os lintreports it as the page's only error. The page door'serrorschannel carries the build's finding verbatim, with nothing onadvisories. The tier isgating. The message no longer contains "future major". The within-bounds CONTROL is unchanged and green.packages/metadata-protocol/src/protocol.runtime-authoring-gate.test.ts: a new block, "runtime authoring gate on PAGE writes — a props-bag CEL slot over the parse bounds (lint 18.x:page-predicate-over-budgetbecomes an error, refusing a page component props CEL slot over the platform parse bounds (the refusal half of #24953) #25002)", runs through the REALsaveMetaItem/publishMetaItem. It is inserted after the lint: the visibility-predicate rules run at the runtime save door for a view but not for a page, so a page visibleWhen calling an unknown function is saved through Studio, REST or MCP and refused only by os validate (ruling B on #23388's principle) #24491 page block, not at the end of the file, which keeps it textually apart from open PR fix(lint)!: os build and the object save door refuse a validations[] rule whose predicate reads parent #25052's append. It pins:page:tabsitemvisibleWhenanswers{ code: 'INVALID_METADATA', status: 422 }, with onepage-predicate-over-budgetissue atpages[0].regions[0].components[0].properties.items[1].visibleWhennaming "maxAstNodesbudget (platform limit 256)", and no active row is stored;os build's, key by key;runtime-gate.page-visibility-predicate-writes.test.ts: one comment now says "refusal" instead of "warning". The dispatch-order pin is unchanged.Evidence (run on head
53ae2b07d2, afterpnpm --filter '@objectstack/lint...' buildandpnpm --filter '@objectstack/metadata-protocol^...' build):pnpm --filter @objectstack/lint exec vitest run --maxWorkers=2 src/validate-page-predicate-bounds.test.ts src/runtime-gate.page-visibility-predicate-writes.test.ts src/authoring-rule-wiring.test.ts→Test Files 3 passed (3),Tests 59 passed (59).pnpm --filter @objectstack/metadata-protocol exec vitest run --maxWorkers=2 src/protocol.runtime-authoring-gate.test.ts→Test Files 1 passed (1),Tests 180 passed (180).pnpm --filter @objectstack/lint typecheck(tsc pluscheck:test-typecheck) → exit 0.pnpm --filter @objectstack/lint exec vitest run --maxWorkers=2(the whole package) →Test Files 153 passed (153),Tests 7056 passed (7056).pnpm --filter @objectstack/metadata-protocol typecheck→ exit 0 (in the same&&chain, lockVERDICT command-exit 0).Ablation (one-shot, nothing left in the tree)
Committed first, then mutated through
scripts/ablation-replace.mjs(anchorseverity: 'error',aboverule: PAGE_PREDICATE_OVER_BUDGET,, hit x1 -> x0, blobe4a15923c57d->51d908070c3a) to the pre-change severity, spelled['warning', 'ablation25002'][0] as 'error'so the marker survives the bundle.pnpm --filter @objectstack/lint build, thenscripts/ablation-dist-preflight.mjs @objectstack/lint ablation25002→ marker present in 4 built files.validate-page-predicate-bounds.test.ts→Tests 5 failed | 13 passed (18)(the error finding,os validate/os build/os lint, the door's errors channel).protocol.runtime-authoring-gate.test.ts -t '#25002'→Tests 3 failed | 1 passed | 176 skipped((a) refusal, (a) draft promotion, (b) parity fail; (c) the within-bounds control stays green, as it must).git checkout HEAD -- PATH,git diff HEADempty, hashe4a15923c57dequals the HEAD blob; rebuilt;ablation-dist-preflight --absent→ marker absent from all 20 built files, tree clean. Restored run: lint file18 passed (18), door file180 passed (180).Producers, measured before crossing
0 in-repo producers carry such a slot, so this PR fixes none:
*.page.tsandpages/*.tsmodule underexamples/andpackages/(30 files, 65 page values), loaded with tsx and judged by the builtvalidatePagePredicateBounds, gives 0 findings.app-crm,app-multi-packageandapp-todostacks also give 0. Theapp-showcaseconfig did not load here, because an unbuilt@objectstack/connector-mcpwas missing; its pages are covered by the page-module pass..ts/.tsx/.mts/.js/.mjs/.json/.yamlfile underexamples/,packages/(dogfood and the package pages included),skills/,apps/andcontent/docs/was scanned (9,919 files). Each string literal or+-chain of 120 or more characters (13,840) was judged byvalidateExpression's bounds verdict, and 0 arecel-too-large.objectstack-ai/hotcrmatc8a7a70(611 files) finds 0..join) is outside the literal scan. The page-module pass covers it for the in-repo pages.Gates
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 66 commands at53ae2b07d2, and all 66 were run. 63 exit 0, includingcheck-adr-0087-registration --base origin/main(it reads thenot-required (no-migration-prescription)marker),check-changeset-no-major,check-empty-changeset,check:changeset-gate-self-tests,check:nul-bytes,check:cross-package-test-inputsandcheck:test-source-alias. Three are NOT MEASURED, each exiting 3 on its own prerequisite and not on a finding:check:dual-build-cjs-loads: needs a whole-workspacedist/.check:lean-entry-closure: needs a built@objectstack/objectql.check:type-check-debt: its closure build hit the shared verify lock's queue budget.CI runs all three.
dispatch-gates --ranwith every exit code recorded:66 derived, 63 run, 3 NOT-MEASURED, 0 UNRUN.Acceptance notes
.changeset/24953-page-predicate-bounds-warning.md(from feat(lint): a page component props CEL slot over the platform parse bounds warns at validate, build and the page door #24999, not yet released) still says "A future major release refuses it." If both ship in one release, the two CHANGELOG entries for@objectstack/lintdisagree. This PR's changeset says it supersedes the warning-only behaviour. The other file is outside this claim's file surface, so it is not edited here. The seat can amend that one sentence in a follow-up if wanted.VALIDATION_ERRORis not what the door answers. See "The door's code, measured" above.Running author-time rules (50)) does not move. Nothing was regenerated.Release
@objectstack/lintminor, BREAKING (FROM a warning with the page saved, TO an error with the page refused). The one-line fix: shrink the predicate, or precompute it into a formula or roll-up field. ADR-0087:not-required (no-migration-prescription), following the shape of bb4f5cc.content/docs/releases/is untouched.Generated by Claude Code