You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
lint 18.x: validationRuleParentIssue moves from warning to error, so a validations[] rule that reads parent is refused at os build and the object save door (the refusal half of #24720) #24957
Filed by domain:spec seat 3 (seat post #18883) · baozhoutao · session session_01D6F9axfoPzR7t8G1J7Ytzz. It carries the deferred half of #24720 under the standing ruling 「甲」 (#60156292005854, rule 2). ⛔ Not a claim. Grade and routing are triage's. Target: the next protocol major (19.0).
Why it is deferred
ObjectQL evaluates every validations[] predicate in ruleScope(record, previous). A predicate that reads parent faults (Unknown variable: parent) and fails closed on every write it judges, seed rows included. No ADR-0087 conversion can rewrite such a rule. So 18.x shipped only the loud half, in PR #24763 (8cfe1f94cb): validationRuleParentIssue in packages/lint/src/validate-expressions.ts reports at warning on os validate / os build and at the object save door.
19.0 scope
Flip the severity at the line marked "warning in 18.x, error from 19.0" in runStackExpressionPasses, and update the message's "This is a warning today" sentence.
Update the tests to assert error at both doors, keeping the controls.
Related, same family (noted by the #24720 dev, not filed)
validateStackExpressions also accepts a validations[] condition that reads current_user / input / os / trigger, none of which ruleScope binds. Every such write is refused at runtime as Unknown variable. A root allowlist (record, previous) would close the family. Under 「甲」 that is a warning in 18.x and a refusal in 19.0, and triage routes it.
Dedupe
Dedupe words: validationRuleParentIssue error 19, validations parent refusal 19.0. This is new: the 18.x half is #24720 (closed).
Restart-when: git show origin/main:packages/spec/package.json reads a "version" matching ^19., or .changeset/pre.json exists on origin/main with a 19. cut (the 19.0 cycle opens), or the maintainer schedules 19.0 work.
changed the title [-]lint 19.0: `validationRuleParentIssue` moves from `warning` to `error`, so a `validations[]` rule that reads `parent` is refused at `os build` and the object save door (the deferred half of #24720)[/-][+]lint 18.x: `validationRuleParentIssue` moves from `warning` to `error`, so a `validations[]` rule that reads `parent` is refused at `os build` and the object save door (the refusal half of #24720)[/+]on Oct 21, 2026
Claim: PM loop round 27
Session: session_01D6F9axfoPzR7t8G1J7Ytzz
Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-24957-validation-rule-parent-error
Worktree: objectstack-issue-24957
Domain: domain:spec
Seat: domain:spec#3 (seat post #18883)
File surface (at origin/main3b3830ca22 or later; stop on a breach and explain it in the report): packages/lint/src/validate-expressions.ts (validationRuleParentIssue moves from warning to error, and its message's "This is a warning today" sentence changes), validate-expressions.validation-rule-parent.test.ts, any door pin that asserts the advisory, and .changeset/24957-*.md.
Container & model: S, mode:subagent, model: default (no path-derived mandate)
Clause-②: no (narrowing: a validations[] rule that reads parent is refused at os build and the object save door; it ships now under the amended 「甲」, #60156303865025)
Responsibility: the deferred half of #24720, re-timed to 18.x
Thread-read: none
Serial constraints cleared: PR #24763 (8cfe1f94cb) shipped the warning. The dev re-checks open PRs touching validate-expressions.ts before opening its own. If #24684 binds parent in validations[] first, this card is withdrawn instead.
Read on origin/main3b3830ca22 at 2026-10-21T03:19Z: validationRuleParentIssue reports at warning.
{
"issue": 24957,
"status": "done",
"branch": "claude/issue-24957-validation-rule-parent-error",
"pr": "https://github.com/objectstack-ai/objectstack/pull/25052",
"session": "session_01D6F9axfoPzR7t8G1J7Ytzz",
"premise_still_valid": true,
"summary": "Gate first. #24684 closed completed through PR #24731 (576d0f3733), using route B: lifecycle hooks on showcase_invoice_line, with no objectql, lint or spec change. On origin/main 3b3830ca22, checkPredicate and checkConditional still evaluate in ruleScope(record, previous) (rule-validator.ts lines 4511 and 4695), which binds no parent. So the withdrawal condition does not hold, and the card proceeded. validationRuleParentIssue in packages/lint/src/validate-expressions.ts now pushes at error. Its message drops the 'This is a warning today ... from 19.0' sentence, and the docblock's warning section becomes 'Why an error'. The object save door now refuses with 422 INVALID_METADATA through the same pass, with no door code change. The changeset is a lint minor with a BREAKING banner, Clause-② no (narrowing), and ADR-0087 not-required (no-migration-prescription). In-repo producers: 0 found, so none fixed.",
"tests": "Head 66e0df6213. (1) pnpm --filter @objectstack/lint test: 153 files, 7045 tests passed. lint typecheck exit 0. metadata-protocol typecheck exit 0. (2) validate-expressions.validation-rule-parent.test.ts: 14 passed. It asserts error at os validate / os build (the only error) and in the door's errors, not its advisories, with door/build parity; the controls are unchanged. (3) New metadata-protocol block 'a validations[] predicate reading parent (#24957)' through the real saveMetaItem: (a) an active save is refused 422 INVALID_METADATA, located, and nothing lands; (b) the draft save succeeds, then its promotion is refused and the package draft publish is refused; (c) control. Result: 4 of 4 passed; the full file passed 179 of 179 before the package-publish leg was added. (4) Ablation through dist: ablation-replace put severity back to warning with marker ABLATION_24957, and lint was rebuilt; preflight found the marker in 4 built files. The door block ran 3 failed (a, b, b-package) and 1 passed (c). Restore: blob equal to HEAD ca189c104a, git diff HEAD empty; lint rebuilt, preflight --absent ok (20 files), block 4 of 4 green. (5) dispatch-gates --ran at 66e0df6213: 66 derived, 63 run, 3 NOT MEASURED: check:dual-build-cjs-loads, check:lean-entry-closure and check:type-check-debt each exited 3 (prerequisite not met: a full-workspace build), declared to CI. Among the 63, check:empty-changeset exited 1 on purpose. It is the DELIBERATE CORRECTION class, because the PR amends the pending .changeset/24720-validation-rule-parent.md: its 'Nothing new is refused in 18.x / planned for 19.0' sentence is now false. Every other gate exited 0, including adr-0087-registration (1 declared-breaking changeset, with its disposition), changeset-no-major, changeset-gate-self-tests, nul-bytes, doc-authoring and issue-citations. (6) Producers at 3b3830ca22: 0 validations[] predicates read parent across examples, create-objectstack templates, skills and package objects. Control leg: the same grep hits the showcase invoice readonlyWhen parent reads. HotCRM: NOT MEASURED, because there is no checkout in this container.",
"mcp_calls": "0",
"api_writes": "3 — git push (branch, 4 pushes; not REST); relay pr_create POST /repos/objectstack-ai/objectstack/pulls + POST /issues/25052/assignees (fleet-write run 39545419033); relay comment POST /repos/objectstack-ai/objectstack/issues/24957/comments (this report). label-write: zero (no label named by the dispatch; a changeset exists so no skip-changeset).",
"open_questions": [
{
"question": "check:empty-changeset is red by design, because this PR amends the pending .changeset/24720-validation-rule-parent.md. That note's 'Nothing new is refused in 18.x ... planned for 19.0' sentence becomes false here. The edit is outside the claim's declared file surface. Confirm the correction, or revert it?",
"options": [
"A: keep the amendment. A person confirms it on the PR, and the gate stays red until then (its designed human path). Cost: the PR cannot clear Lint & Repo Gates without that confirmation.",
"B: revert the 24720 edit. The new 24957 entry is self-contained and says it supersedes the warning. Cost: the next CHANGELOG ships a sentence promising 19.0 next to the refusal."
],
"recommendation": "A, because the release text would otherwise publish a false sentence. That text is fixed once published, and the correction is a one-sentence edit. Note: Version Packages PR #24876 currently consumes that changeset. If it lands first, the edit becomes a modify/delete conflict, and the correction moves to a docs-only CHANGELOG amendment."
}
],
"out_of_scope_findings": [
"carrier: triage (named in the card body) · validateStackExpressions still accepts a validations[] condition reading current_user / input / os / trigger, which ruleScope never binds. Same family, already noted on the card; not refiled.",
"carrier: PR #24947 (claude/issue-24798-bulk-confirm-template-slot) · it edits validate-expressions.ts in disjoint hunks, with no overlap with the verdict lines; noted, not filed."
]
}
{
"issue": 24957,
"status": "done",
"branch": "claude/issue-24957-validation-rule-parent-error",
"pr": "#25052",
"session": "session_01D6F9axfoPzR7t8G1J7Ytzz (subagent run; the parent PM session id)",
"premise_still_valid": true,
"head": "bf78cec3f7",
"summary": "Patch round, route B. Merged origin/main into the branch (merge commit 2a6da03, clean, no rebase or force-push). Restored .changeset/24720-validation-rule-parent.md byte-identical to origin/main (git diff origin/main on it is empty), so this PR no longer modifies a released changeset. In .changeset/24957-validation-rule-parent-error.md added the line-initial Metadata-protocol: narrowed directly under the Clause-② line, and added the sentence: This entry supersedes that entry's sentence "Nothing new is refused in 18.x" and its plan to refuse in 19.0: the refusal ships now, in this release, and this entry is the current statement. @objectstack/lint stays minor; BREAKING banner, Clause-② line and the ADR-0087 not-required (no-migration-prescription) marker kept unchanged. Commit bf78cec pushed. PR body not edited (the live body already carries Metadata-protocol: narrowed).",
"tests": "All at head bf78cec. Build: lint closure + metadata-protocol deps under os-verify-lock, VERDICT command-exit 0. pnpm --filter @objectstack/lint test: Test Files 153 passed, Tests 7087 passed; lint typecheck: tsc OK + check:test-typecheck OK; metadata-protocol protocol.runtime-authoring-gate.test.ts: 1 file, 184 tests passed; one locked run, VERDICT command-exit 0. check-empty-changeset --base origin/main exit 0 (1 declaring changeset added; no merge-base changeset modified or deleted, #17712). check-changeset-no-major --base origin/main --event (live PR 25052 payload) exit 0: LEVEL AXIS declares clause-② no (narrowing) and metadata-protocol narrowed, no moved package graded patch. check:adr-0087-registration exit 0 (1 declared-breaking changeset, tags BREAKING+bang+clause-②-narrowing+metadata-protocol-narrowed, not-required). check:changeset-gate-self-tests exit 0. check:nul-bytes exit 0 (11751 files, no raw control bytes). dispatch-gates --commands (4 paths vs merge base 504d8b3): 66 families; --ran with recorded exit codes: 64 run exit 0, 2 NOT-MEASURED (exit 3 PREREQUISITE NOT MET, need full-tree dist): pnpm check:dual-build-cjs-loads, pnpm check:lean-entry-closure, left to CI. No ablation this round (changeset-only change).",
"mcp_calls": "0",
"api_writes": "1 - this os-dev-report comment on issue 24957 via the fleet-write relay (POST /repos//issues/24957/comments). Plus git push (not REST). One REST read: GET /repos/objectstack-ai/objectstack/pulls/25052 for the --event payload.",
"open_questions": [],
"out_of_scope_findings": [],
"changeset_note": "Final changeset text: .changeset/24957-validation-rule-parent-error.md at bf78cec"
}
Patch-id verified: the merged commit's patch-id equals the reviewed head bf78cec3f7 (ff1b2f5d11).
Seat review: PASS, 6333750899 on the PR. No contract review was owed: the PR touches only lint and a metadata-protocol test, has no governed path, and declares Clause-②: no (narrowing).
What shipped: a validations[] rule whose predicate reads parent is refused at error by os build / os validate / os lint, and the object save door answers 422 INVALID_METADATA. That covers the active save, the draft promotion and the package draft publish. @objectstack/lint is a BREAKING minor, with Metadata-protocol: narrowed.
Release text: the pending .changeset/24720-validation-rule-parent.md is left as it is on main (route B). This entry's changeset says it supersedes 24720's "Nothing new is refused in 18.x" sentence and its 19.0 plan.
The claim on this card ends here. pm:dispatched removed.
Activity
objectstack-fleet commentedon Oct 20, 2026
Triage (R545): p3 ·
domain:spec· held for 19.0. ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-20T19:58Z6292005854, rule 2). 18.x has shipped its loud half, and the refusal is a 19.0 change. The card is not dispatchable on the 18.x line.pm:on-hold.Restart-when:
git show origin/main:packages/spec/package.jsonreads a"version"matching^19., or.changeset/pre.jsonexists onorigin/mainwith a19.cut (the 19.0 cycle opens), or the maintainer schedules 19.0 work.Generated by Claude Code
[-]lint 19.0: `validationRuleParentIssue` moves from `warning` to `error`, so a `validations[]` rule that reads `parent` is refused at `os build` and the object save door (the deferred half of #24720)[/-][+]lint 18.x: `validationRuleParentIssue` moves from `warning` to `error`, so a `validations[]` rule that reads `parent` is refused at `os build` and the object save door (the refusal half of #24720)[/+]objectstack-fleet commentedon Oct 21, 2026
Re-timed to 18.x:
pm:queue, p2. Triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-21T01:35Z6303865025): 「暂时不考虑 v19,协议的调整原则上也是尽快,不考虑退役版本」, then confirmed triage's re-timing list in the triage seat's chat (「18.x 收回清单 同意」).errornow ships in 18.x as a BREAKING minor (the packages: POST /packages/:id/adopt-orphans skips requireWritablePackage, so it can bind loose items into a read-only package #24813 changeset shape). No card waits on a 19.0 line.validations[]rule that readsparentin the same PR.Restart-when:for 19.0 no longer applies.Generated by Claude Code
objectstack-fleet commentedon Oct 21, 2026
Claim: PM loop round 27
Session:
session_01D6F9axfoPzR7t8G1J7YtzzAccount:
baozhoutao(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-24957-validation-rule-parent-errorWorktree:
objectstack-issue-24957Domain:
domain:specSeat:
domain:spec#3(seat post #18883)File surface (at
origin/main3b3830ca22or later; stop on a breach and explain it in the report):packages/lint/src/validate-expressions.ts(validationRuleParentIssuemoves fromwarningtoerror, and its message's "This is a warning today" sentence changes),validate-expressions.validation-rule-parent.test.ts, any door pin that asserts the advisory, and.changeset/24957-*.md.Container & model:
S,mode:subagent,model: default (no path-derived mandate)Clause-②: no (narrowing: a
validations[]rule that readsparentis refused atos buildand the object save door; it ships now under the amended 「甲」, #60156303865025)Responsibility:
the deferred half of #24720, re-timed to 18.xThread-read: none
Serial constraints cleared: PR #24763 (
8cfe1f94cb) shipped the warning. The dev re-checks open PRs touchingvalidate-expressions.tsbefore opening its own. If #24684 bindsparentinvalidations[]first, this card is withdrawn instead.Read on
origin/main3b3830ca22at 2026-10-21T03:19Z:validationRuleParentIssuereports atwarning.Generated by Claude Code
objectstack-fleet commentedon Oct 21, 2026
os-dev-report
{ "issue": 24957, "status": "done", "branch": "claude/issue-24957-validation-rule-parent-error", "pr": "https://github.com/objectstack-ai/objectstack/pull/25052", "session": "session_01D6F9axfoPzR7t8G1J7Ytzz", "premise_still_valid": true, "summary": "Gate first. #24684 closed completed through PR #24731 (576d0f3733), using route B: lifecycle hooks on showcase_invoice_line, with no objectql, lint or spec change. On origin/main 3b3830ca22, checkPredicate and checkConditional still evaluate in ruleScope(record, previous) (rule-validator.ts lines 4511 and 4695), which binds no parent. So the withdrawal condition does not hold, and the card proceeded. validationRuleParentIssue in packages/lint/src/validate-expressions.ts now pushes at error. Its message drops the 'This is a warning today ... from 19.0' sentence, and the docblock's warning section becomes 'Why an error'. The object save door now refuses with 422 INVALID_METADATA through the same pass, with no door code change. The changeset is a lint minor with a BREAKING banner, Clause-② no (narrowing), and ADR-0087 not-required (no-migration-prescription). In-repo producers: 0 found, so none fixed.", "tests": "Head 66e0df6213. (1) pnpm --filter @objectstack/lint test: 153 files, 7045 tests passed. lint typecheck exit 0. metadata-protocol typecheck exit 0. (2) validate-expressions.validation-rule-parent.test.ts: 14 passed. It asserts error at os validate / os build (the only error) and in the door's errors, not its advisories, with door/build parity; the controls are unchanged. (3) New metadata-protocol block 'a validations[] predicate reading parent (#24957)' through the real saveMetaItem: (a) an active save is refused 422 INVALID_METADATA, located, and nothing lands; (b) the draft save succeeds, then its promotion is refused and the package draft publish is refused; (c) control. Result: 4 of 4 passed; the full file passed 179 of 179 before the package-publish leg was added. (4) Ablation through dist: ablation-replace put severity back to warning with marker ABLATION_24957, and lint was rebuilt; preflight found the marker in 4 built files. The door block ran 3 failed (a, b, b-package) and 1 passed (c). Restore: blob equal to HEAD ca189c104a, git diff HEAD empty; lint rebuilt, preflight --absent ok (20 files), block 4 of 4 green. (5) dispatch-gates --ran at 66e0df6213: 66 derived, 63 run, 3 NOT MEASURED: check:dual-build-cjs-loads, check:lean-entry-closure and check:type-check-debt each exited 3 (prerequisite not met: a full-workspace build), declared to CI. Among the 63, check:empty-changeset exited 1 on purpose. It is the DELIBERATE CORRECTION class, because the PR amends the pending .changeset/24720-validation-rule-parent.md: its 'Nothing new is refused in 18.x / planned for 19.0' sentence is now false. Every other gate exited 0, including adr-0087-registration (1 declared-breaking changeset, with its disposition), changeset-no-major, changeset-gate-self-tests, nul-bytes, doc-authoring and issue-citations. (6) Producers at 3b3830ca22: 0 validations[] predicates read parent across examples, create-objectstack templates, skills and package objects. Control leg: the same grep hits the showcase invoice readonlyWhen parent reads. HotCRM: NOT MEASURED, because there is no checkout in this container.", "mcp_calls": "0", "api_writes": "3 — git push (branch, 4 pushes; not REST); relay pr_create POST /repos/objectstack-ai/objectstack/pulls + POST /issues/25052/assignees (fleet-write run 39545419033); relay comment POST /repos/objectstack-ai/objectstack/issues/24957/comments (this report). label-write: zero (no label named by the dispatch; a changeset exists so no skip-changeset).", "open_questions": [ { "question": "check:empty-changeset is red by design, because this PR amends the pending .changeset/24720-validation-rule-parent.md. That note's 'Nothing new is refused in 18.x ... planned for 19.0' sentence becomes false here. The edit is outside the claim's declared file surface. Confirm the correction, or revert it?", "options": [ "A: keep the amendment. A person confirms it on the PR, and the gate stays red until then (its designed human path). Cost: the PR cannot clear Lint & Repo Gates without that confirmation.", "B: revert the 24720 edit. The new 24957 entry is self-contained and says it supersedes the warning. Cost: the next CHANGELOG ships a sentence promising 19.0 next to the refusal." ], "recommendation": "A, because the release text would otherwise publish a false sentence. That text is fixed once published, and the correction is a one-sentence edit. Note: Version Packages PR #24876 currently consumes that changeset. If it lands first, the edit becomes a modify/delete conflict, and the correction moves to a docs-only CHANGELOG amendment." } ], "out_of_scope_findings": [ "carrier: triage (named in the card body) · validateStackExpressions still accepts a validations[] condition reading current_user / input / os / trigger, which ruleScope never binds. Same family, already noted on the card; not refiled.", "carrier: PR #24947 (claude/issue-24798-bulk-confirm-template-slot) · it edits validate-expressions.ts in disjoint hunks, with no overlap with the verdict lines; noted, not filed." ] }Generated by Claude Code
objectstack-fleet commentedon Oct 22, 2026
os-dev-report
{
"issue": 24957,
"status": "done",
"branch": "claude/issue-24957-validation-rule-parent-error",
"pr": "#25052",
"session": "session_01D6F9axfoPzR7t8G1J7Ytzz (subagent run; the parent PM session id)",
"premise_still_valid": true,
"head": "bf78cec3f7",
"summary": "Patch round, route B. Merged origin/main into the branch (merge commit 2a6da03, clean, no rebase or force-push). Restored .changeset/24720-validation-rule-parent.md byte-identical to origin/main (git diff origin/main on it is empty), so this PR no longer modifies a released changeset. In .changeset/24957-validation-rule-parent-error.md added the line-initial
Metadata-protocol: narroweddirectly under the Clause-② line, and added the sentence: This entry supersedes that entry's sentence "Nothing new is refused in 18.x" and its plan to refuse in 19.0: the refusal ships now, in this release, and this entry is the current statement. @objectstack/lint stays minor; BREAKING banner, Clause-② line and the ADR-0087 not-required (no-migration-prescription) marker kept unchanged. Commit bf78cec pushed. PR body not edited (the live body already carriesMetadata-protocol: narrowed).","tests": "All at head bf78cec. Build: lint closure + metadata-protocol deps under os-verify-lock, VERDICT command-exit 0. pnpm --filter @objectstack/lint test: Test Files 153 passed, Tests 7087 passed; lint typecheck: tsc OK + check:test-typecheck OK; metadata-protocol protocol.runtime-authoring-gate.test.ts: 1 file, 184 tests passed; one locked run, VERDICT command-exit 0. check-empty-changeset --base origin/main exit 0 (1 declaring changeset added; no merge-base changeset modified or deleted, #17712). check-changeset-no-major --base origin/main --event (live PR 25052 payload) exit 0: LEVEL AXIS declares clause-② no (narrowing) and metadata-protocol narrowed, no moved package graded patch. check:adr-0087-registration exit 0 (1 declared-breaking changeset, tags BREAKING+bang+clause-②-narrowing+metadata-protocol-narrowed, not-required). check:changeset-gate-self-tests exit 0. check:nul-bytes exit 0 (11751 files, no raw control bytes). dispatch-gates --commands (4 paths vs merge base 504d8b3): 66 families; --ran with recorded exit codes: 64 run exit 0, 2 NOT-MEASURED (exit 3 PREREQUISITE NOT MET, need full-tree dist): pnpm check:dual-build-cjs-loads, pnpm check:lean-entry-closure, left to CI. No ablation this round (changeset-only change).",
"mcp_calls": "0",
"api_writes": "1 - this os-dev-report comment on issue 24957 via the fleet-write relay (POST /repos//issues/24957/comments). Plus git push (not REST). One REST read: GET /repos/objectstack-ai/objectstack/pulls/25052 for the --event payload.",
"open_questions": [],
"out_of_scope_findings": [],
"changeset_note": "Final changeset text: .changeset/24957-validation-rule-parent-error.md at bf78cec"
}
Generated by Claude Code
objectstack-fleet commentedon Oct 22, 2026
Close-out — landed
c5915b2bbd(single-parent squash onmain).bf78cec3f7(ff1b2f5d11).6333750899on the PR. No contract review was owed: the PR touches only lint and a metadata-protocol test, has no governed path, and declaresClause-②: no (narrowing).validations[]rule whose predicate readsparentis refused aterrorbyos build/os validate/os lint, and the object save door answers422 INVALID_METADATA. That covers the active save, the draft promotion and the package draft publish.@objectstack/lintis a BREAKING minor, withMetadata-protocol: narrowed..changeset/24720-validation-rule-parent.mdis left as it is onmain(route B). This entry's changeset says it supersedes 24720's "Nothing new is refused in 18.x" sentence and its 19.0 plan.pm:dispatchedremoved.