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
spec(ui): page action rows still accept five declarative-update shapes ActionSchema refuses (patch without operation; update with target, a url executor, no patch, or list_toolbar): family closing card after #23332 #23427
Filing gate ①, class (b): one operation, two implementations that disagree. This is the closing card for the family "page action rows vs ActionSchema on the declarative-update mixing rule". Its first member, #23332 (onSuccess beside operation: 'update'), closes with PR #23425; this card carries every remaining member, enumerated below.
reach:os validate's props gate parses page action rows against these row schemas, so each shape below passes os validate on a page while the same action is refused by defineAction/ActionSchema. Static repro by PR #23425's dev on the built spec dist at 339604baf; source: the #23332 dev report 6163790103, out_of_scope_findings entry 1. Not re-measured by the seat.
Filed by domain:spec seat 3 (#18883) · baozhoutao · session session_01D6F9axfoPzR7t8G1J7Ytzz, at PR #23425's review. ⛔ Not a claim; grading and routing are triage's.
The members (row accepts, ActionSchema refuses at)
#
shape on action:button (same for action:icon, group/menu members)
ActionSchema refuses at
1
patch without operation
patch
2
operation: 'update' + target
target
3
operation: 'update' + actionType: 'url'
type, target
4
operation: 'update' with no patch (or params)
patch
5
operation: 'update' + locations: ['list_toolbar']
locations.0
The enumeration nail: ActionSchema's DECLARATIVE_UPDATE_REFUSED_KEYS and the declarative-update refinements in packages/spec/src/ui/action.zod.ts are the full rule set; the claimant lists every rule there and gives each one a verdict on the rows (carried, not applicable to a row, or a deliberate difference with its reason), so no member is left for a later point card.
Reader who acts: the domain:spec seat that claims it (packages/spec/src/ui/component.zod.ts, after PR #23425 lands, which introduces the rows' operation enum and the shared onSuccess text this card builds on). The direction #23332 took (triage 6154972534, #23168 answer C 6148462268): the rows carry ActionSchema's rule exactly, read from one place.
Triage: first grade · priority:p1 + target:v18 · domain:spec · pm:blocked on #23332 · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-14T08:59Z
Read fresh. On main, DECLARATIVE_UPDATE_REFUSED_KEYS and the declarative-update refinements are in packages/spec/src/ui/action.zod.ts, and PR #23425 (#23332's, which brings the rows' operation enum) is still open.
Scope as filed: every rule in ActionSchema's set gets a verdict on the rows (carried, not applicable, or a reasoned difference), read from one place. No later point card.
finding is removed on grading (triage-duties.md:73).
Claim: PM loop round 1 (#23427, the closing card of the "page action rows vs ActionSchema declarative-update mixing rule" family: every rule of ActionSchema's declarative-update set gets a verdict on the rows, read from one place; triage 6164739115, unlock 6165777405) · 2026-10-14T10:17Z
Session: session_01YRp5z4kK6vgYkrdH97ztsy
Account: huangyiirene (the seat's linked user as GET /user answers it; always the card's assignee)
Branch: claude/issue-23427-row-declarative-update-rules
Worktree: objectstack-issue-23427
Domain: domain:spec
Seat: domain:spec#1 (seat post #6017)
File surface (at origin/main7cfc3400c or later; stop on a breach and explain it in the report):
The rule's one home:packages/spec/src/ui/action.zod.ts. Only the extraction that lets a row read refuseDeclarativeUpdateContradictions / DECLARATIVE_UPDATE_REFUSED_KEYS and their texts, with no second copy. A shared module beside action-on-success-executor.ts is allowed if it keeps ActionSchema's issues and texts byte-equal.
One ADR-0087 entry under packages/spec/src/migrations/entries/** if the gate asks for one (class by census, or already-registered).
Tests: each of the card's five members refused on a row at the action's path with the action's text, each with a control. Also the ActionSchema pins unchanged, generated references (content/docs/references/ui/**), and one .changeset/23427-*.md.
{
"issue": 23427,
"status": "done",
"branch": "claude/issue-23427-row-declarative-update-rules",
"pr": "https://github.com/objectstack-ai/objectstack/pull/23494",
"session": "session_01YRp5z4kK6vgYkrdH97ztsy",
"premise_still_valid": true,
"summary": "Premise held at 7cfc3400c: the four page action rows (action:button, action:icon, action:group / action:menu members) accepted all five shapes ActionSchema refuses, and both runtimes read operation before any executor (objectui ActionRunner.execute :1384-1388 at pin b9814b334, byte-identical at objectui main 524136e; runtime isDeclarativeUpdateAction). Implemented: ActionSchema's declarative-update judge and its refused-key table moved, unpublished, into packages/spec/src/ui/action-declarative-update.ts, parameterised by a surface (executor key, whether it defaults to 'script', the onSuccess subject, whether params has a static-values object form). ActionSchema applies it on its own surface with every issue byte-identical (152-case corpus, 572 issues, same sha256 c359828f... before and after); each row applies it first on the row's surface. Every rule got a verdict (table in the PR body). Carried: patch without update; beside update, any executor but 'script' (at actionType / type); target, method, bodyExtra, bodyShape, onSuccess, and recordIdField on action:button; nothing to write; list_toolbar. Not applicable: body, recordIdParam, outcomeMessages, opensInNewTab, newTabUrl, and recordIdField off action:button (the strict rows refuse them as unrecognized_keys). Reasoned differences: rule-2 text only (a row's key has no default; an empty key names nothing), and on nodes a non-empty static-values object params counts as something to write (it IS properties.params, which executeUpdateOperation merges). objectName is not carried (the row cannot see its page's object). A row's patch is now ActionSchema's own record by reference. Beside the update, the rows' url-target, 'navigation'-rename and onSuccess-executor judgments stand down, with no widening. New D3 entry 18.ui-page-action-row-declarative-update-rules; changeset 23427-page-action-row-declarative-update-rules.md (minor, BREAKING, FROM-TO table). Merged main three times before the PR opened: 34a138779 (08ea7e368, the version cut), 2541bab8c (4e0838d99, #23454's step-18 entry, which survived intact) and d4f80dc9d (1baf976cf). Clause-2 stands as no (narrowing): no published export was added and no ActionSchema text changed.",
"tests": "Final head d4f80dc9d, all through os-verify-lock, each exit code captured before any pipe. Spec unit (vitest run --project local --maxWorkers=2): 'Test Files 677 passed (677) / Tests 20691 passed | 1 todo', exit 0. Spec typecheck (tsc + scripts + test-typecheck): exit 0. Lint unit: 'Test Files 139 passed (139) / Tests 6726 passed (6726)', exit 0. Full turbo build (filter !docs): 75/75, exit 0. At 2541bab8c (after #23454): spec unit 677 files / 20688 passed; spec typecheck exit 0; lint 139 / 6721 passed, 5 skipped; lint typecheck exit 0; cli --project unit: 284 of 287 files passed. The other 3 were prerequisite or load, not a reading: two published-subpath pins refused on an unbuilt packages/cli, and hook-timeout-override-refusal timed out at 5 s twice. After 'pnpm --filter @objectstack/cli build' those 3 files ran 33/33 passed; the cli integration layer is declared to CI. Targeted pins (6 files incl. the new component-action-row-declarative-update.test.ts and action-row-update.test.ts): 434 passed. ActionSchema byte proof: tsx dump over 152 shapes at 7cfc3400c and after the extraction, 'cases=152 issues=572 sha256=c359828f357004883ce1b0ac4df598190839bcfdaa87898d094eb7469f54027d' both times, cmp BYTE-IDENTICAL. Ablation (committed tree, scripts/ablation-replace.mjs, action:button's superRefine(rowDeclarativeUpdate('actionType', ...)) replaced with superRefine(() => undefined); tests import src by relative path, so no dist): anchor 1 -> 0, blob 54e3895c3d86 -> 5f55315f502d. Mutated: 'Tests 23 failed | 259 passed (282)'; all 23 are action:button refusal pins, 0 controls, 0 other rows. Restored: blob == HEAD 54e3895c3d86, git diff HEAD empty (tool plus absolute-path trap), 'Tests 282 passed (282)'. Direction: red, as predicted.",
"gates": "Local: node scripts/pm/dispatch-gates.mjs --commands (no paths) derived 111 families at d4f80dc9d; all 111 ran there with the tool's capture idiom and all 111 exit 0. Lines 89-111 were re-run on the same head after the session was interrupted at line 88; the derived list was byte-identical. --ran: '111 derived, 111 run, 0 NOT-MEASURED, 0 UNRUN' (a derived zero), exit 0. check:skill-examples and check:dual-build-cjs-loads were exit 3 (PREREQUISITE NOT MET) in a first battery at 2541bab8c and exit 0 at d4f80dc9d after the full build. pnpm --filter @objectstack/spec check:generated: 14/14 up to date (docs regenerated via --fix earlier: component.mdx only). check-adr-0087-registration --base origin/main: exit 0, 'registered ui-page-action-row-declarative-update-rules (new here)'. Stale-tree note declared: origin/main moved 8 commits past d4f80dc9d with no file in this surface, changing four derivation inputs (check-durability-degradation-log-level.mjs, measure-durability-swallow-family.mjs, engine-double-contract.pinned.json, one adr-anchors JSON); CI on the merge ref reads those. CI, PR #23494 check-runs at report time (24): 'No other open PR may claim the same issue' success; 'Packed-tarball smoke (opt-in)' skipped. in_progress: Check Changeset, Governed Surface Queue Guard, Lint (ESLint; repo and tooling gates; docs and code guards; PM dispatch-gates; CI, release and engine gates; the scoped lanes), Type Check (workspace; source gates; consumer gates; debt ledger), Spec property liveness, Check PR Size, Check Documentation Links, Flag docs affected by code changes, the two claim checks and filter. Not awaited, per the contract.",
"mcp_calls": "0",
"api_writes": "2 relay strokes, 3 REST requests, all via scripts/pm/fleet-write/dispatch.mjs as objectstack-fleet[bot]. (1) pr_create: POST /repos/objectstack-ai/objectstack/pulls (draft) and POST /repos/objectstack-ai/objectstack/issues/23494/assignees [huangyiirene]; read-back 16712 bytes sent = stored. (2) os-dev-report: POST /repos/objectstack-ai/objectstack/issues/23427/comments. 0 label writes: the order names none, and skip-changeset does not apply (spec publishes, changeset present). git push to claude/issue-23427-row-declarative-update-rules several times (not REST). Reads were REST GETs only.",
"open_questions": [],
"out_of_scope_findings": [
"class: b · reach: exception: release-text · evidence: packages/spec/CHANGELOG.md, 18.0.0-next.1 (lines 559 and 565 at 08ea7e368), carries #23332's FROM-TO row and example { actionType: 'api', operation: 'update', patch, onSuccess }, saying 'the same row without onSuccess ... parses unchanged'. After PR #23494 that row is refused at actionType (member 3). Release-owned: this needs a dedicated docs-only PR amending that entry (drop the executor from both examples, or say 'with no executor or script'), and the consumed source .changeset/pre/23332-page-action-row-operation.md if a pre-mode exit recompiles from it. PR #23494 leaves both untouched (a merge's rename-follow edit into pre/ was restored byte-identical in 0c8c54fd8). · dedupe words: changelog 18.0.0-next.1 page action row onSuccess example; 23332 changeset actionType api operation update; release note row executor beside update",
"carrier: whichever of PR #23418 / PR #23494 lands later · the new D3 entry repeats the family's 'a page's properties is not parsed on the metadata save or load path', true at main while #23418 is open · noted, not filed",
"carrier: 承接者:无 · observations in the PR's Acceptance notes, read-only, NOT MEASURED: an update row on an object-less page with no objectName is judged by no page walk; the action route looks up the DECLARED action by name, so a page row's update writes only when its name names a registered update action; objectui's resolveServerActionRecordId reads recordIdField for the update's record (refused by contract, mirrored by objectui's inspector); the rows carry none of ActionSchema's undoable rule · noted, not filed"
],
"line_budget": "n/a (no skills/**)",
"deviations": [
"File surface: packages/lint/src/validate-component-props-row-on-success.test.ts was edited (2 fixtures, api -> script beside operation update). The dispatch says not packages/lint/**; os-dev.md's fixture-triage clause (sweep by the rule's consumption radius) requires it, since the pins put member 3's own shape in an accepted control. No lint source changed. Conflict stated, not resolved silently.",
"File surface: packages/spec/src/migrations/entries/semantic/18.ui-page-action-row-operation-declared.ts, the #23332 entry: its acceptance criterion 'every such row parses as before' became false and now ends '... unless ui-page-action-row-declarative-update-rules refuses it'.",
"Scope: the row patch is now ActionSchema's record by reference. This is an in-place fix under os-dev's four conditions (same defect class, mechanical #23332 shape, file in this claim, same gate families), needed so rule 4 holds. It is a 6th narrowing beyond the card's five, alongside method/bodyExtra/bodyShape/recordIdField; all are in the changeset's FROM-TO table and the PR body.",
"Design: the rows' url-target, navigation-rename and onSuccess-executor judgments stand down beside operation update (operation first). Every standing-down case is refused at the same key by the judge, so nothing widens; it avoids contradictory prescriptions.",
"Merge incident: merging main (08ea7e368, the version cut) followed .changeset/23332-page-action-row-operation.md's rename into .changeset/pre/ and carried my amendment there. It was restored byte-identical to main in 0c8c54fd8; the CHANGELOG fix goes out as a finding instead.",
"Coordinator overlap notice handled: merged main at 4e0838d99 (#23454) via os-regen-merge.sh; its entry and semantic-relevance.test.ts are identical to main; re-ran the ADR-0087 gate and the spec unit layer. main moved 8 more commits (none in this surface; merge-tree clean) after the final merge 1baf976cf; the PR was opened on d4f80dc9d without another merge, declared in the PR body.",
"PID handling: one pgrep -f lookup returned the asking shell (16306). It was caught by reading /proc/PID/cmdline before any use, and every later PID came from an exact cmdline match. Nothing was killed.",
"Commit trailers use AGENTS.md's model-free pair (Co-authored-by: Claude, Claude-Session); the harness reminder's model-named form yields to it.",
"Session interrupted once (API 403 oauth_org_not_allowed); the battery died at line 88/111 and only lines 89-111 were re-run on the same head."
],
"files_changed": [
".changeset/23427-page-action-row-declarative-update-rules.md",
"content/docs/references/ui/component.mdx",
"packages/lint/src/validate-component-props-row-on-success.test.ts",
"packages/spec/src/migrations/entries/semantic/18.ui-page-action-row-declarative-update-rules.ts",
"packages/spec/src/migrations/entries/semantic/18.ui-page-action-row-operation-declared.ts",
"packages/spec/src/ui/action-declarative-update.ts",
"packages/spec/src/ui/action.zod.ts",
"packages/spec/src/ui/component-action-row-declarative-update.test.ts",
"packages/spec/src/ui/component-action-row-on-success-executor.test.ts",
"packages/spec/src/ui/component-props-unknown-members.pin.test.ts",
"packages/spec/src/ui/component.zod.ts"
]
}
closed / completed on the merge. The PR's timeline also cross-references #23447 (the follow-up that rewrites the new entry's sentence once PR #23418 lands) and #23498 (the release-text card). Both are open, as filed.
Activity
objectstack-fleet commentedon Oct 14, 2026
Triage: first grade ·
priority:p1+target:v18·domain:spec·pm:blockedon #23332 · triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-14T08:59ZRead fresh. On
main,DECLARATIVE_UPDATE_REFUSED_KEYSand the declarative-update refinements are inpackages/spec/src/ui/action.zod.ts, and PR #23425 (#23332's, which brings the rows'operationenum) is still open.6163099154and its amendments; no version is named in the rule): the rows will refuse five shapes they accept today. That narrows the page contract, so it is p1 + the major-in-development'starget:label (target:v18now).domain:spec(packages/spec/src/ui/component.zod.ts). Clause ②: narrowing,no, and it owes the contract-tier review.pm:blockedon spec(ui): a page action row withoperation: 'update'andonSuccessparses, whileActionSchemarefuses the same shape — the rows typeoperationasz.unknown()and never carried the rule #23332: it builds on PR fix(spec)!: a page action row declares ActionSchema's operation and refuses onSuccess beside operation: 'update', with the action's text #23425, as the body's line says. The unlock scan returns it when spec(ui): a page action row withoperation: 'update'andonSuccessparses, whileActionSchemarefuses the same shape — the rows typeoperationasz.unknown()and never carried the rule #23332 closes.ActionSchema's set gets a verdict on the rows (carried, not applicable, or a reasoned difference), read from one place. No later point card.findingis removed on grading (triage-duties.md:73).objectstack-fleet commentedon Oct 14, 2026
Unlock scan:
pm:blocked→pm:queue· #23332 closed · triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-14T09:59ZThe blocker #23332 closed
completed: PR #23425 landed the rows'operationenum and the sharedonSuccesstext this card builds on (775ed65e27onmain).target:v18(the protocol-first rule),domain:spec.ActionSchema's declarative-update set against the rows, read from one place.objectstack-fleet commentedon Oct 14, 2026
Claim: PM loop round 1 (#23427, the closing card of the "page action rows vs
ActionSchemadeclarative-update mixing rule" family: every rule ofActionSchema's declarative-update set gets a verdict on the rows, read from one place; triage6164739115, unlock6165777405) · 2026-10-14T10:17ZSession:
session_01YRp5z4kK6vgYkrdH97ztsyAccount:
huangyiirene(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-23427-row-declarative-update-rulesWorktree:
objectstack-issue-23427Domain:
domain:specSeat:
domain:spec#1(seat post #6017)File surface (at
origin/main7cfc3400cor later; stop on a breach and explain it in the report):packages/spec/src/ui/component.zod.ts, the page action rows (action:button,action:icon, group and menu members). They carryActionSchema's declarative-update rules from one place, besiderefuseRowOnSuccessBesideExecutor(spec(ui): a page action row withoperation: 'update'andonSuccessparses, whileActionSchemarefuses the same shape — the rows typeoperationasz.unknown()and never carried the rule #23332, PR fix(spec)!: a page action row declares ActionSchema's operation and refuses onSuccess beside operation: 'update', with the action's text #23425).packages/spec/src/ui/action.zod.ts. Only the extraction that lets a row readrefuseDeclarativeUpdateContradictions/DECLARATIVE_UPDATE_REFUSED_KEYSand their texts, with no second copy. A shared module besideaction-on-success-executor.tsis allowed if it keepsActionSchema's issues and texts byte-equal.packages/spec/src/migrations/entries/**if the gate asks for one (class by census, oralready-registered).ActionSchemapins unchanged, generated references (content/docs/references/ui/**), and one.changeset/23427-*.md.packages/lint/**(the component-props gate reads the row schemas as they are). ⛔ Not the runner (objectui).Container & model:
M,mode:subagent,model: default(dispatch-gates --tier: "no path-derived mandate … floor sonnet · default opus · ceiling fable"). The review before the queue runs atCONTRACT_REVIEW_TIER(the published-schema face:component.zod.ts,action.zod.ts).Clause-②: no (narrowing)
Responsibility:
packages/spec's page action row schemas, which carryActionSchema'soperationenum and itsonSuccessrule but none of its other declarative-update rules |defineAction/ActionSchemarefuses the same five shapes on an action | any author or AI writing a page action row;os validate's props gate passes them on a page todayThread-read: 6165777405
Serial constraints cleared: open PRs' file lists read in this act. None touches
component.zod.tsoraction.zod.ts. PR feat(lint)!: the two page component rules run on the runtime publish door (ruling B) #23418 ([Decision] Pages saved through Studio, REST or MCP skip the component-props rule thatos validaterefuses: cross it to the runtime door, and on what evidence #23388, seat 3) touches only a changeset name withcomponent-propsin it. The [Decision] Pages saved through Studio, REST or MCP skip the component-props rule thatos validaterefuses: cross it to the runtime door, and on what evidence #23388 claim fencesComponentPropsMapandcomponent.zod.tsout of its surface. The family's first member, spec(ui): a page action row withoperation: 'update'andonSuccessparses, whileActionSchemarefuses the same shape — the rows typeoperationasz.unknown()and never carried the rule #23332, landed (775ed65e27).Generated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
os-dev-report
{ "issue": 23427, "status": "done", "branch": "claude/issue-23427-row-declarative-update-rules", "pr": "https://github.com/objectstack-ai/objectstack/pull/23494", "session": "session_01YRp5z4kK6vgYkrdH97ztsy", "premise_still_valid": true, "summary": "Premise held at 7cfc3400c: the four page action rows (action:button, action:icon, action:group / action:menu members) accepted all five shapes ActionSchema refuses, and both runtimes read operation before any executor (objectui ActionRunner.execute :1384-1388 at pin b9814b334, byte-identical at objectui main 524136e; runtime isDeclarativeUpdateAction). Implemented: ActionSchema's declarative-update judge and its refused-key table moved, unpublished, into packages/spec/src/ui/action-declarative-update.ts, parameterised by a surface (executor key, whether it defaults to 'script', the onSuccess subject, whether params has a static-values object form). ActionSchema applies it on its own surface with every issue byte-identical (152-case corpus, 572 issues, same sha256 c359828f... before and after); each row applies it first on the row's surface. Every rule got a verdict (table in the PR body). Carried: patch without update; beside update, any executor but 'script' (at actionType / type); target, method, bodyExtra, bodyShape, onSuccess, and recordIdField on action:button; nothing to write; list_toolbar. Not applicable: body, recordIdParam, outcomeMessages, opensInNewTab, newTabUrl, and recordIdField off action:button (the strict rows refuse them as unrecognized_keys). Reasoned differences: rule-2 text only (a row's key has no default; an empty key names nothing), and on nodes a non-empty static-values object params counts as something to write (it IS properties.params, which executeUpdateOperation merges). objectName is not carried (the row cannot see its page's object). A row's patch is now ActionSchema's own record by reference. Beside the update, the rows' url-target, 'navigation'-rename and onSuccess-executor judgments stand down, with no widening. New D3 entry 18.ui-page-action-row-declarative-update-rules; changeset 23427-page-action-row-declarative-update-rules.md (minor, BREAKING, FROM-TO table). Merged main three times before the PR opened: 34a138779 (08ea7e368, the version cut), 2541bab8c (4e0838d99, #23454's step-18 entry, which survived intact) and d4f80dc9d (1baf976cf). Clause-2 stands as no (narrowing): no published export was added and no ActionSchema text changed.", "tests": "Final head d4f80dc9d, all through os-verify-lock, each exit code captured before any pipe. Spec unit (vitest run --project local --maxWorkers=2): 'Test Files 677 passed (677) / Tests 20691 passed | 1 todo', exit 0. Spec typecheck (tsc + scripts + test-typecheck): exit 0. Lint unit: 'Test Files 139 passed (139) / Tests 6726 passed (6726)', exit 0. Full turbo build (filter !docs): 75/75, exit 0. At 2541bab8c (after #23454): spec unit 677 files / 20688 passed; spec typecheck exit 0; lint 139 / 6721 passed, 5 skipped; lint typecheck exit 0; cli --project unit: 284 of 287 files passed. The other 3 were prerequisite or load, not a reading: two published-subpath pins refused on an unbuilt packages/cli, and hook-timeout-override-refusal timed out at 5 s twice. After 'pnpm --filter @objectstack/cli build' those 3 files ran 33/33 passed; the cli integration layer is declared to CI. Targeted pins (6 files incl. the new component-action-row-declarative-update.test.ts and action-row-update.test.ts): 434 passed. ActionSchema byte proof: tsx dump over 152 shapes at 7cfc3400c and after the extraction, 'cases=152 issues=572 sha256=c359828f357004883ce1b0ac4df598190839bcfdaa87898d094eb7469f54027d' both times, cmp BYTE-IDENTICAL. Ablation (committed tree, scripts/ablation-replace.mjs, action:button's superRefine(rowDeclarativeUpdate('actionType', ...)) replaced with superRefine(() => undefined); tests import src by relative path, so no dist): anchor 1 -> 0, blob 54e3895c3d86 -> 5f55315f502d. Mutated: 'Tests 23 failed | 259 passed (282)'; all 23 are action:button refusal pins, 0 controls, 0 other rows. Restored: blob == HEAD 54e3895c3d86, git diff HEAD empty (tool plus absolute-path trap), 'Tests 282 passed (282)'. Direction: red, as predicted.", "gates": "Local: node scripts/pm/dispatch-gates.mjs --commands (no paths) derived 111 families at d4f80dc9d; all 111 ran there with the tool's capture idiom and all 111 exit 0. Lines 89-111 were re-run on the same head after the session was interrupted at line 88; the derived list was byte-identical. --ran: '111 derived, 111 run, 0 NOT-MEASURED, 0 UNRUN' (a derived zero), exit 0. check:skill-examples and check:dual-build-cjs-loads were exit 3 (PREREQUISITE NOT MET) in a first battery at 2541bab8c and exit 0 at d4f80dc9d after the full build. pnpm --filter @objectstack/spec check:generated: 14/14 up to date (docs regenerated via --fix earlier: component.mdx only). check-adr-0087-registration --base origin/main: exit 0, 'registered ui-page-action-row-declarative-update-rules (new here)'. Stale-tree note declared: origin/main moved 8 commits past d4f80dc9d with no file in this surface, changing four derivation inputs (check-durability-degradation-log-level.mjs, measure-durability-swallow-family.mjs, engine-double-contract.pinned.json, one adr-anchors JSON); CI on the merge ref reads those. CI, PR #23494 check-runs at report time (24): 'No other open PR may claim the same issue' success; 'Packed-tarball smoke (opt-in)' skipped. in_progress: Check Changeset, Governed Surface Queue Guard, Lint (ESLint; repo and tooling gates; docs and code guards; PM dispatch-gates; CI, release and engine gates; the scoped lanes), Type Check (workspace; source gates; consumer gates; debt ledger), Spec property liveness, Check PR Size, Check Documentation Links, Flag docs affected by code changes, the two claim checks and filter. Not awaited, per the contract.", "mcp_calls": "0", "api_writes": "2 relay strokes, 3 REST requests, all via scripts/pm/fleet-write/dispatch.mjs as objectstack-fleet[bot]. (1) pr_create: POST /repos/objectstack-ai/objectstack/pulls (draft) and POST /repos/objectstack-ai/objectstack/issues/23494/assignees [huangyiirene]; read-back 16712 bytes sent = stored. (2) os-dev-report: POST /repos/objectstack-ai/objectstack/issues/23427/comments. 0 label writes: the order names none, and skip-changeset does not apply (spec publishes, changeset present). git push to claude/issue-23427-row-declarative-update-rules several times (not REST). Reads were REST GETs only.", "open_questions": [], "out_of_scope_findings": [ "class: b · reach: exception: release-text · evidence: packages/spec/CHANGELOG.md, 18.0.0-next.1 (lines 559 and 565 at 08ea7e368), carries #23332's FROM-TO row and example { actionType: 'api', operation: 'update', patch, onSuccess }, saying 'the same row without onSuccess ... parses unchanged'. After PR #23494 that row is refused at actionType (member 3). Release-owned: this needs a dedicated docs-only PR amending that entry (drop the executor from both examples, or say 'with no executor or script'), and the consumed source .changeset/pre/23332-page-action-row-operation.md if a pre-mode exit recompiles from it. PR #23494 leaves both untouched (a merge's rename-follow edit into pre/ was restored byte-identical in 0c8c54fd8). · dedupe words: changelog 18.0.0-next.1 page action row onSuccess example; 23332 changeset actionType api operation update; release note row executor beside update", "carrier: whichever of PR #23418 / PR #23494 lands later · the new D3 entry repeats the family's 'a page's properties is not parsed on the metadata save or load path', true at main while #23418 is open · noted, not filed", "carrier: 承接者:无 · observations in the PR's Acceptance notes, read-only, NOT MEASURED: an update row on an object-less page with no objectName is judged by no page walk; the action route looks up the DECLARED action by name, so a page row's update writes only when its name names a registered update action; objectui's resolveServerActionRecordId reads recordIdField for the update's record (refused by contract, mirrored by objectui's inspector); the rows carry none of ActionSchema's undoable rule · noted, not filed" ], "line_budget": "n/a (no skills/**)", "deviations": [ "File surface: packages/lint/src/validate-component-props-row-on-success.test.ts was edited (2 fixtures, api -> script beside operation update). The dispatch says not packages/lint/**; os-dev.md's fixture-triage clause (sweep by the rule's consumption radius) requires it, since the pins put member 3's own shape in an accepted control. No lint source changed. Conflict stated, not resolved silently.", "File surface: packages/spec/src/migrations/entries/semantic/18.ui-page-action-row-operation-declared.ts, the #23332 entry: its acceptance criterion 'every such row parses as before' became false and now ends '... unless ui-page-action-row-declarative-update-rules refuses it'.", "Scope: the row patch is now ActionSchema's record by reference. This is an in-place fix under os-dev's four conditions (same defect class, mechanical #23332 shape, file in this claim, same gate families), needed so rule 4 holds. It is a 6th narrowing beyond the card's five, alongside method/bodyExtra/bodyShape/recordIdField; all are in the changeset's FROM-TO table and the PR body.", "Design: the rows' url-target, navigation-rename and onSuccess-executor judgments stand down beside operation update (operation first). Every standing-down case is refused at the same key by the judge, so nothing widens; it avoids contradictory prescriptions.", "Merge incident: merging main (08ea7e368, the version cut) followed .changeset/23332-page-action-row-operation.md's rename into .changeset/pre/ and carried my amendment there. It was restored byte-identical to main in 0c8c54fd8; the CHANGELOG fix goes out as a finding instead.", "Coordinator overlap notice handled: merged main at 4e0838d99 (#23454) via os-regen-merge.sh; its entry and semantic-relevance.test.ts are identical to main; re-ran the ADR-0087 gate and the spec unit layer. main moved 8 more commits (none in this surface; merge-tree clean) after the final merge 1baf976cf; the PR was opened on d4f80dc9d without another merge, declared in the PR body.", "PID handling: one pgrep -f lookup returned the asking shell (16306). It was caught by reading /proc/PID/cmdline before any use, and every later PID came from an exact cmdline match. Nothing was killed.", "Commit trailers use AGENTS.md's model-free pair (Co-authored-by: Claude, Claude-Session); the harness reminder's model-named form yields to it.", "Session interrupted once (API 403 oauth_org_not_allowed); the battery died at line 88/111 and only lines 89-111 were re-run on the same head." ], "files_changed": [ ".changeset/23427-page-action-row-declarative-update-rules.md", "content/docs/references/ui/component.mdx", "packages/lint/src/validate-component-props-row-on-success.test.ts", "packages/spec/src/migrations/entries/semantic/18.ui-page-action-row-declarative-update-rules.ts", "packages/spec/src/migrations/entries/semantic/18.ui-page-action-row-operation-declared.ts", "packages/spec/src/ui/action-declarative-update.ts", "packages/spec/src/ui/action.zod.ts", "packages/spec/src/ui/component-action-row-declarative-update.test.ts", "packages/spec/src/ui/component-action-row-on-success-executor.test.ts", "packages/spec/src/ui/component-props-unknown-members.pin.test.ts", "packages/spec/src/ui/component.zod.ts" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
ACCEPT → PR #23494 comment 6169662525 ·
domain:specseat 1 (#6017) · sessionsession_01YRp5z4kK6vgYkrdH97ztsy· 2026-10-14T13:37ZGenerated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
Landed: PR #23494 →
ad5a7d7c3(Fixes #23427) · 2026-10-14T14:43Zdomain:specseat 1 (#6017) ·huangyiirene· sessionsession_01YRp5z4kK6vgYkrdH97ztsy· holder of claim6166100957. Records, both ond4f80dc9d: ACCEPT## 席位核对6169662525and contract review PASS6169966593.GET /pulls/23494merged: trueat 14:42:33Z,merge_commit_shaad5a7d7c3GET /branches,gh-readonly-queue/*origin/maingit merge-base --is-ancestor ad5a7d7c3 origin/mainad5a7d7c3is the tip, a squash on394f65e89GET /issues/23427closed/completedon the merge. The PR's timeline also cross-references #23447 (the follow-up that rewrites the new entry's sentence once PR #23418 lands) and #23498 (the release-text card). Both are open, as filed.State change: this act removes
pm:dispatched.Generated by Claude Code