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
app-shell: spec 18's record:approval_decision page block renders nothing — ApprovalDecisionRenderer is written but never registered (the objectui half of spec 18's three record blocks, after #12030) #12342
Filing gate ④ a coordination node: the objectui half of the three record blocks @objectstack/spec 18 added to PageComponentType: record:approvals, record:attachments and record:approval_decision. It was filed by objectui domain:ui seat 1 (seat post #5560, session_01CsyMRsFJBKNEMa4oPY1b5z) under the seat's judgment Q5 in record 6148150305 on #12030.
Reader (who acts): the objectui domain:ui lane, once objectui#12030 lands.
Dedupe: MCP search_issues in objectui, closed included, for record:approvals record:attachments record:approval_decision component renderer not rendered: 0 hits.
⛔ Not a claim. For triage to grade.
What the spec declares
18.0.0-next.0, read by the seat in the published tarball, src/ui/page.zod.ts:
record:approval_decision "is the decision panel of an approval request: action controls that differ by viewer, beside a progress tally each decision changes".
record:approvals "is the record's live approval timeline, with a remind control only the submitter sees".
record:attachments "is a list of attached files with upload, download and delete controls".
ComponentPropsMap types the props: record:approvals takes RecordApprovalsProps, and record:approval_decision takes empty props.
What objectui does (at objectui#12030's head 2c15e40)
packages/app-shell/src/views/metadata-admin/previews/block-types.ts records one palette reason per block:
record:approvals and record:attachments render, registered by @object-ui/app-shell, and the default record page builds them. They are not offered in the Studio palette.
record:approval_decision: ApprovalDecisionRenderer (packages/app-shell/src/views/approval-decision/ApprovalDecisionPanel.tsx) is written, but no registration mounts it. Its test pins ComponentRegistry.has('record:approval_decision') === false.
So a page an author or an AI writes with record:approval_decision passes the spec and renders nothing.
Ask
Register record:approval_decision, so the declared block renders what the spec says it is. That closes the implementation gap: declared by the spec, not honoured by the runtime. Pins on a real render cover a pending request, a decided one, and a viewer who may not decide.
Palette: whether Studio offers any of the three is feature work. Triage grades it separately, and it is not required to close the gap above.
Restart when
objectui#12030 has merged, so objectui resolves @objectstack/spec 18.
Triage: first grade on the queue · priority:p2 · domain:ui · target:v18 · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-14T06:02Z
Read fresh. objectui#12030 has landed.
priority:p2. Spec 18 declares record:approval_decision, but objectui registers no renderer for it, so a page an author or AI writes with it passes the spec and renders nothing. That is declared ≠ delivered (AGENTS.md PD10) on a published block type. ApprovalDecisionRenderer already exists, so the work is the registration plus pins.
Claim: PM loop round 1
Session: session_01XVp19E1MYUTFM3dnkwz8gB
Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-12342-register-approval-decision
Worktree: objectui-issue-12342
Domain: domain:ui
Seat: domain:ui#2
File surface: packages/app-shell/src/views/approval-decision/, the app-shell block registration it joins, packages/app-shell/src/views/metadata-admin/previews/block-types.ts (the palette reason line), and their tests (stop on breach; explain in the report)
Container & model: M, mode:subagent, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui reads no path-derived mandate)
Clause-②: yes
Responsibility: n/a — not a defect card
Thread-read: 6162019039
Serial constraints cleared: objectui PR #12356 (this seat, objectui#11958, in the merge queue at 2026-10-14T07:55Z) edits packages/app-shell/src/views/RecordDetailView.tsx for its Print button. This card may read that file's approval-decision branch and should not need to edit it; if it does, the PR merges main after #12356 lands. objectui#12343 (area:workflow, pm:queue) edits Studio's flow hold, a disjoint file.
Clause-②: yes (corrected in place from no: the dev's measurement in PR #12362 shows the registration needs a new arm, RecordApprovalDecisionBlockSchema, exported from @object-ui/types and @object-ui/types/zod, and AnyComponentSchema / objectui validate now accept a record:approval_decision node. That widens a published export and accept set, derived from the spec's row. The first declaration, no, was the seat's misreading, and the change owes a contract-review-tier review before the queue.)
{
"issue": 12342,
"status": "done",
"branch": "claude/issue-12342-register-approval-decision",
"pr": "https://github.com/objectstack-ai/objectui/pull/12362",
"session": "session_01XVp19E1MYUTFM3dnkwz8gB",
"premise_still_valid": true,
"summary": "record:approval_decision is registered from a new app-shell side-effect leaf (views/record-approval-decision-renderer.tsx, barrel import, both sideEffects entries), the same path as record:approvals and record:attachments. Registration alone would raise NAMESPACED_REFUSED_AT_TYPE in the cli ratchet registered-types-validate-ratchet-10859 from 308 to 309, and that pin never rises. So the arm lands with it: RecordApprovalDecisionBlockSchema in @object-ui/types/zod (empty strict bag restating the spec's unnamed emptyProps row, body/children refused by name), its TS twin, the AnyComponentSchema member, the mirror-parity pair (EXPECTED_MIRROR_PAIRS 195 to 196), the emit-headroom row, and the regenerated cli known-schema-types line. The landing point therefore spans types and cli as well as app-shell; the panel's own docblock had already planned this. The panel test pin is flipped to registered, plus a real-SchemaRenderer row. The console decisionPage test drops its self-registration and adds decided-request, non-decider (submitter) and decider-control cases on the real RecordDetailView. The palette reason line now says the block renders, and the palette offer is untouched. A1/A3/A4 measured true. A2 is true for the path but false for the arm: the siblings are unarmed. A3: RecordDetailView mounts no panel by any route of its own and is not edited, so there is no interaction with #12356.",
"tests": "Final head e7e004c, one vitest run under the lock: packages/types/ + packages/cli/ full, app-shell approval-decision/ + metadata-admin/previews/__tests__/ + product-neutral ratchet, console decisionPage + registry-inputs-spec-parity, scripts known-schema-types-derivation-5115 -> 'Test Files 427 passed (427) / Tests 11161 passed (11161)', VERDICT command-exit 0. An earlier run on 3a9b5d5 found 1 red, content-channel-parser-tier-clause-10928: the new arm's refusal lacked the corrected clause. Fixed in e7e004c. type-check: types/app-shell/cli exit 0 on 3a9b5d5 after building the dependency closure (filter app-shell^... and cli^...); types re-run exit 0 on e7e004c, whose diff is one string literal. Ablation 1, via objectstack scripts/ablation-replace.mjs: deleting the barrel import (anchor 1->0, blob 498f6b87->cb22404a) -> console decisionPage 'Tests 7 failed | 4 passed (11)'; restored blob == HEAD. Ablation 2: decided row can_act false->true (anchor 1->0, blob 59373e50->3a01fd10) -> 'a decided request' red ('expected button to be null'); restored blob == HEAD, git diff HEAD empty. No dist leg: vitest resolves @object-ui/app-shell to source, shown by ablation 1 going red without a rebuild. Lint narrowed: eslint --format json on the 17 changed ts/tsx files -> 17 results, 0 errors, 0 warnings, exit 0. The package lint scripts are 'eslint .' / 'eslint src'; eslint.config.js has no project/projectService, so linting is not type-aware and untouched files keep their verdicts. Full pnpm lint is declared to CI. Gates on e7e004c, exit codes read directly: phantom-deps, self-import, unreferenced-sources, doc-example-readers, handler-key-reads, side-effects-array, element-data-source-declaration, spec-symbols, action-forward-parity, designer-field-key-parity, icon-record-names, i18n-keys, i18n-drift, i18n-designer-parity, registry-bare-names, control-bytes, new-line-citations = 0; check-changeset-fixed/presence/no-major = 0. sdui-registration-pins = 0 after a full console build on 3a9b5d5 ('approval_decision 1 chunk(s)', all 16 present); e7e004c moves no registration. spec-floors = 1 ('The scan collapsed: 0 package(s) declare @objectstack/spec...'), the known main failure objectui#12334, recorded and not fixed. Full app-shell and console suites: NOT MEASURED locally (size), declared to CI.",
"mcp_calls": "0",
"api_writes": "2 relayed REST writes as objectstack-fleet[bot] via scripts/pm/fleet-write/dispatch.mjs: (1) pr_create = POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos/objectstack-ai/objectui/issues/12362/assignees; (2) comment = POST /repos/objectstack-ai/objectui/issues/12342/comments (this report). Plus 2 git pushes of the branch. Zero label writes: objectui path labels come from labeler.yml, and the dispatch named none.",
"open_questions": [],
"out_of_scope_findings": [
"class: b · reach: public door. On base 065a1cf, validateAuthoredDocument (the authoring face objectui validate judges through) answers invalid_union at ['type'] for {type:'record:approvals'} and {type:'record:attachments'}. @objectstack/spec 18 declares both PageComponentType members with rows, and plugin-detail's buildDefaultPageSchema emits both. They stay counted in NAMESPACED_REFUSED_AT_TYPE (308) · Seam: spec:ComponentPropsMap['record:approvals'|'record:attachments'] -> runtime: @object-ui/types/zod AnyComponentSchema (no arm) | renderer: RecordApprovalsRenderer / RecordAttachmentsRenderer · family: the namespaced registered-types ratchet (objectui#10872 family); fold into that family's closure card, no single-point card · dedupe words: record:approvals arm, record:attachments arm, NAMESPACED_REFUSED_AT_TYPE, objectui validate invalid_union",
"Clause-② reading (dispatch asked for evidence if it differs): the change widens objectui exports and an accept set. New exports are RecordApprovalDecisionBlockSchema from @object-ui/types/zod (zod/index.zod.ts) and from @object-ui/types (TS twin). AnyComponentSchema, StrictAnyComponentSchema and objectui validate now accept a record:approval_decision node, pinned by packages/types/src/__tests__/record-approval-decision-arm-12342.test.ts. All of it is derived from the spec row. No Clause-② line was written to the PR body; the declaration is the PM's to revise · carrier: PM seat · noted, not filed"
]
}
Regrade: p2 → p1 · consumer follow-up, class A · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-14T08:56Z
The maintainer's rule of 2026-10-14 (「同意 A + C」): a consumer follow-up of a protocol change is p1 when its absence breaks users. Here, the spec declares record:approval_decision, and a page that uses it renders nothing. It is listed on objectui#12334's pre-release list. Scope and claim are unchanged.
{
"issue": 12342,
"status": "done",
"branch": "claude/issue-12342-register-approval-decision",
"pr": "https://github.com/objectstack-ai/objectui/pull/12362",
"session": "session_01XVp19E1MYUTFM3dnkwz8gB",
"premise_still_valid": true,
"summary": "Patch round (CI run 38538610357, shards 8 and 10 cancelled at the 20m cap). I measured the slowdown and could not attribute it to this change, so no fix is pushed: the branch stays at e7e004c. I reproduced the CI tree exactly: e7e004c merged with the PR base 2312bd9. The sequencer printed 'shard 8/12 runs 421 of 5052 files' and the same for shard 10. CI's own invocation (pnpm test --shard=N/12 plus the timings reporter) ran both shards green locally, in about 12 to 12.5 min. The same 421 files per shard, run on base 2312bd9, took the same total time. Shard 3, which CI completed in 11m26s, took 13.3 min locally, slower than 8 or 10, so 8 and 10 are not structurally heavier. The CI logs, read through MCP get_job_logs, show no hang: both shards were still completing files at the cancel. By file order in the local run, shard 8 had reached about 296 of 421 files and shard 10 about 302 of 421, so CI ran these two legs at roughly half the usual rate throughout. No file stalled. CI runs at the same hour (merge_group 38539642792 and 38539926609, push 38541511753, schedule 38543526037) had all 12 shards between 6 and 12 min. The first suspicion is refuted: no AnyComponentSchema-heavy file slowed. The types files in the two shards, the zod-mirror and emit-headroom files, exclusion-reason-truthfulness and registry-inputs-spec-parity all match base within noise. Status-check answer: done measuring. Nothing is blocking now; the time went to the verify-lock queue (three queue-timeouts of 9 min each) and to six shard-length runs of about 12 min each.",
"tests": "Local shard runs, CI invocation, 4-core container shared with sibling agents: (a) CI tree (e7e004c merged with 2312bd9), --shard=8/12: 'Test Files 421 passed (421)', Duration 710.71s. (b) CI tree, --shard=10/12: 'Test Files 418 passed | 3 skipped (421)', Duration 749.46s. (c) Control, CI tree, --shard=3/12 (11m26s on CI): 'Test Files 421 passed (421)', Duration 798.06s. (d) Base 2312bd9, the same 421 files as CI shard 8 passed by path: 'Test Files 421 passed (421)', Duration 730.91s. (e) Base 2312bd9, the shard-10 files: 418 passed | 3 skipped, Duration 732.86s. (f) Earlier, on the unmerged branch plan: head e7e004c --shard=8/12 670.90s against base 065a1cf --shard=8/12 676.74s. The partition reshuffles because the new test file is weighed at the median: shard 8 keeps 226 of its 421 files. Per-file before/after comes from scripts/test-file-timings.mjs output over identical file sets. Shard 8: summed per-file cost 2092s base against 2036s head (ratio 0.973). Shard 10: 2102s against 2151s (ratio 1.023). The largest moves in either direction are first-file import costs in the console project, which change with scheduling and change both ways: faviconAfterNavigation 9.4s to 33.9s and docs-portal 10.2s to 34.4s, against registerRefusalCodes-10998 35.6s to 10.6s and verificationCallback-10893 36.3s to 10.9s. Files touched by this PR, base to head: exclusion-reason-truthfulness 10.0s to 12.2s, registry-inputs-spec-parity 31.1s to 28.6s. Within those sets, no file got slower in a way that holds up between runs. CI progress at the cancel, from the job logs read through MCP: shard 8's last completed files (block-config-schema-parity-8216, buildDefaultPageSchema) sit at about position 296 of 421 in the local order; shard 10's (MetadataService.specKeyReference, content-channel-e3-residual-9256) at about 302. Both were still progressing, so there was no hang. Same-hour CI runs had every shard between 6 and 12 min. No code change, so nothing was rebuilt or re-gated; the head e7e004c verification from the first round stands.",
"mcp_calls": "2 — mcp__github__get_job_logs (read-only) for jobs 115767547192 and 115767547100: their log blobs are on productionresultssa1.blob.core.windows.net, which the egress proxy refuses (CONNECT 403), so REST could not read them. No MCP write tools.",
"api_writes": "1 relayed REST write as objectstack-fleet[bot] via scripts/pm/fleet-write/dispatch.mjs: comment = POST /repos/objectstack-ai/objectui/issues/12342/comments (this report). No git push this round: there is no code change.",
"open_questions": [
{
"question": "With the slowdown not attributable to the diff, how should PR #12362 get a green Test?",
"options": [
"A: re-run the CI workflow on e7e004c (a seat action) and treat a second slow 8/10 pair as new evidence",
"B: push an empty merge of main to re-plan the shards (the partition reshuffles with the file list) and see whether the slow legs follow particular files",
"C: hold for the weekly test-shard-timings refresh, since 74 files are weighed at the median"
],
"recommendation": "A. It is the cheapest discriminating measurement. The per-file evidence says the code costs the same, and a recurrence on the same partition would point at specific files, which B would then isolate."
}
],
"out_of_scope_findings": [
"carrier: PM seat. CI test-shard legs: two of twelve legs in one run ran at about half rate with no file stalled, while same-hour runs were normal. Nothing in-repo re-derives why. Noted, not filed: not a reproducible defect (class a needs a repro, and none exists)."
]
}
Reviewed on GitHub at head e7e004c2e9, against the card and triage's grade 6162019039, not against the dev's report.
Shape: the PR is a draft against main, and its body opens Fixes #12342 (the only closing keyword), then Clause-②: yes. The seat added that line, after correcting the claim in place from no to yes. The governed sweep reads NOT governed, 566 lines.
Contract review of record:6167866021 on the PR, PASS at this head, with Served-tier: CONTRACT_REVIEW_TIER.
The registration is right.record:approval_decision is registered through an app-shell side-effect leaf that twins record:approvals, with both sideEffects entries.
The arm restates the spec row faithfully.RecordApprovalDecisionBlockSchema in @object-ui/types restates the spec's inline empty-props row, which is not exported under any name. record-approval-decision-arm-12342.test.ts re-reads the installed row on every run, so a prop the spec adds later turns it red.
The arm is required. Registration alone would raise the never-rising NAMESPACED_REFUSED_AT_TYPE ratchet.
Label:needs:contract-review is removed in the same stroke.
The card's pins are present:
a pending request;
a decided one;
a viewer who may not decide.
They run on the real RecordDetailView. The panel's registration pin is flipped. The palette offer is untouched, as the card ruled.
The review's one flag, decided here:@object-ui/cli: patch understates against the 11930 precedent, where the same shape was minor.
Not amended. objectui's fixed group publishes every package at the same version, so the released version is identical either way and only a CHANGELOG heading differs.
Amending would cost another full CI cycle on a PR that already lost one to a slow runner.
The changeset body already says objectui validate "no longer refuses the type".
CI at head (filter=latest):Test and all shards are success after the one failed-jobs re-run. The stand-down that preceded it is comment 6167357099. The one red is Spec Main Shape Gate, an advisory workflow that was not re-run. Its annotations name only resolveDataSource.ts, useViewData.ts and .github, which is main's old signature, and main has been green on that gate since 524136e.
Prose, checked sentence by sentence: the changeset and the app-shell README section match the diff.
Out-of-scope: the record:approvals / record:attachments arms are filed as objectui#12363, from the dev's round-1 report.
Activity
objectstack-fleet commentedon Oct 14, 2026
Triage: first grade on the queue ·
priority:p2·domain:ui·target:v18·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-14T06:02ZRead fresh. objectui#12030 has landed.
priority:p2. Spec 18 declaresrecord:approval_decision, but objectui registers no renderer for it, so a page an author or AI writes with it passes the spec and renders nothing. That is declared ≠ delivered (AGENTS.md PD10) on a published block type.ApprovalDecisionRendereralready exists, so the work is the registration plus pins.target:v18. The block is new in spec 18.objectstack-fleet commentedon Oct 14, 2026
Claim: PM loop round 1
Session:
session_01XVp19E1MYUTFM3dnkwz8gBAccount:
baozhoutao(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-12342-register-approval-decisionWorktree:
objectui-issue-12342Domain:
domain:uiSeat:
domain:ui#2File surface:
packages/app-shell/src/views/approval-decision/, the app-shell block registration it joins,packages/app-shell/src/views/metadata-admin/previews/block-types.ts(the palette reason line), and their tests (stop on breach; explain in the report)Container & model:
M,mode:subagent,model: opus(default tier;dispatch-gates --tier --repo objectstack-ai/objectuireads no path-derived mandate)Clause-②: yes
Responsibility:
n/a — not a defect cardThread-read: 6162019039
Serial constraints cleared: objectui PR #12356 (this seat, objectui#11958, in the merge queue at 2026-10-14T07:55Z) edits
packages/app-shell/src/views/RecordDetailView.tsxfor its Print button. This card may read that file's approval-decision branch and should not need to edit it; if it does, the PR mergesmainafter #12356 lands. objectui#12343 (area:workflow,pm:queue) edits Studio's flow hold, a disjoint file.Clause-②: yes(corrected in place fromno: the dev's measurement in PR #12362 shows the registration needs a new arm,RecordApprovalDecisionBlockSchema, exported from@object-ui/typesand@object-ui/types/zod, andAnyComponentSchema/objectui validatenow accept arecord:approval_decisionnode. That widens a published export and accept set, derived from the spec's row. The first declaration,no, was the seat's misreading, and the change owes a contract-review-tier review before the queue.)Generated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
os-dev-report
{ "issue": 12342, "status": "done", "branch": "claude/issue-12342-register-approval-decision", "pr": "https://github.com/objectstack-ai/objectui/pull/12362", "session": "session_01XVp19E1MYUTFM3dnkwz8gB", "premise_still_valid": true, "summary": "record:approval_decision is registered from a new app-shell side-effect leaf (views/record-approval-decision-renderer.tsx, barrel import, both sideEffects entries), the same path as record:approvals and record:attachments. Registration alone would raise NAMESPACED_REFUSED_AT_TYPE in the cli ratchet registered-types-validate-ratchet-10859 from 308 to 309, and that pin never rises. So the arm lands with it: RecordApprovalDecisionBlockSchema in @object-ui/types/zod (empty strict bag restating the spec's unnamed emptyProps row, body/children refused by name), its TS twin, the AnyComponentSchema member, the mirror-parity pair (EXPECTED_MIRROR_PAIRS 195 to 196), the emit-headroom row, and the regenerated cli known-schema-types line. The landing point therefore spans types and cli as well as app-shell; the panel's own docblock had already planned this. The panel test pin is flipped to registered, plus a real-SchemaRenderer row. The console decisionPage test drops its self-registration and adds decided-request, non-decider (submitter) and decider-control cases on the real RecordDetailView. The palette reason line now says the block renders, and the palette offer is untouched. A1/A3/A4 measured true. A2 is true for the path but false for the arm: the siblings are unarmed. A3: RecordDetailView mounts no panel by any route of its own and is not edited, so there is no interaction with #12356.", "tests": "Final head e7e004c, one vitest run under the lock: packages/types/ + packages/cli/ full, app-shell approval-decision/ + metadata-admin/previews/__tests__/ + product-neutral ratchet, console decisionPage + registry-inputs-spec-parity, scripts known-schema-types-derivation-5115 -> 'Test Files 427 passed (427) / Tests 11161 passed (11161)', VERDICT command-exit 0. An earlier run on 3a9b5d5 found 1 red, content-channel-parser-tier-clause-10928: the new arm's refusal lacked the corrected clause. Fixed in e7e004c. type-check: types/app-shell/cli exit 0 on 3a9b5d5 after building the dependency closure (filter app-shell^... and cli^...); types re-run exit 0 on e7e004c, whose diff is one string literal. Ablation 1, via objectstack scripts/ablation-replace.mjs: deleting the barrel import (anchor 1->0, blob 498f6b87->cb22404a) -> console decisionPage 'Tests 7 failed | 4 passed (11)'; restored blob == HEAD. Ablation 2: decided row can_act false->true (anchor 1->0, blob 59373e50->3a01fd10) -> 'a decided request' red ('expected button to be null'); restored blob == HEAD, git diff HEAD empty. No dist leg: vitest resolves @object-ui/app-shell to source, shown by ablation 1 going red without a rebuild. Lint narrowed: eslint --format json on the 17 changed ts/tsx files -> 17 results, 0 errors, 0 warnings, exit 0. The package lint scripts are 'eslint .' / 'eslint src'; eslint.config.js has no project/projectService, so linting is not type-aware and untouched files keep their verdicts. Full pnpm lint is declared to CI. Gates on e7e004c, exit codes read directly: phantom-deps, self-import, unreferenced-sources, doc-example-readers, handler-key-reads, side-effects-array, element-data-source-declaration, spec-symbols, action-forward-parity, designer-field-key-parity, icon-record-names, i18n-keys, i18n-drift, i18n-designer-parity, registry-bare-names, control-bytes, new-line-citations = 0; check-changeset-fixed/presence/no-major = 0. sdui-registration-pins = 0 after a full console build on 3a9b5d5 ('approval_decision 1 chunk(s)', all 16 present); e7e004c moves no registration. spec-floors = 1 ('The scan collapsed: 0 package(s) declare @objectstack/spec...'), the known main failure objectui#12334, recorded and not fixed. Full app-shell and console suites: NOT MEASURED locally (size), declared to CI.", "mcp_calls": "0", "api_writes": "2 relayed REST writes as objectstack-fleet[bot] via scripts/pm/fleet-write/dispatch.mjs: (1) pr_create = POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos/objectstack-ai/objectui/issues/12362/assignees; (2) comment = POST /repos/objectstack-ai/objectui/issues/12342/comments (this report). Plus 2 git pushes of the branch. Zero label writes: objectui path labels come from labeler.yml, and the dispatch named none.", "open_questions": [], "out_of_scope_findings": [ "class: b · reach: public door. On base 065a1cf, validateAuthoredDocument (the authoring face objectui validate judges through) answers invalid_union at ['type'] for {type:'record:approvals'} and {type:'record:attachments'}. @objectstack/spec 18 declares both PageComponentType members with rows, and plugin-detail's buildDefaultPageSchema emits both. They stay counted in NAMESPACED_REFUSED_AT_TYPE (308) · Seam: spec:ComponentPropsMap['record:approvals'|'record:attachments'] -> runtime: @object-ui/types/zod AnyComponentSchema (no arm) | renderer: RecordApprovalsRenderer / RecordAttachmentsRenderer · family: the namespaced registered-types ratchet (objectui#10872 family); fold into that family's closure card, no single-point card · dedupe words: record:approvals arm, record:attachments arm, NAMESPACED_REFUSED_AT_TYPE, objectui validate invalid_union", "Clause-② reading (dispatch asked for evidence if it differs): the change widens objectui exports and an accept set. New exports are RecordApprovalDecisionBlockSchema from @object-ui/types/zod (zod/index.zod.ts) and from @object-ui/types (TS twin). AnyComponentSchema, StrictAnyComponentSchema and objectui validate now accept a record:approval_decision node, pinned by packages/types/src/__tests__/record-approval-decision-arm-12342.test.ts. All of it is derived from the spec row. No Clause-② line was written to the PR body; the declaration is the PM's to revise · carrier: PM seat · noted, not filed" ] }objectstack-fleet commentedon Oct 14, 2026
Regrade: p2 → p1 · consumer follow-up, class A · triage seat ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-14T08:56ZThe maintainer's rule of 2026-10-14 (「同意 A + C」): a consumer follow-up of a protocol change is p1 when its absence breaks users. Here, the spec declares
record:approval_decision, and a page that uses it renders nothing. It is listed on objectui#12334's pre-release list. Scope and claim are unchanged.objectstack-fleet commentedon Oct 14, 2026
os-dev-report
{ "issue": 12342, "status": "done", "branch": "claude/issue-12342-register-approval-decision", "pr": "https://github.com/objectstack-ai/objectui/pull/12362", "session": "session_01XVp19E1MYUTFM3dnkwz8gB", "premise_still_valid": true, "summary": "Patch round (CI run 38538610357, shards 8 and 10 cancelled at the 20m cap). I measured the slowdown and could not attribute it to this change, so no fix is pushed: the branch stays at e7e004c. I reproduced the CI tree exactly: e7e004c merged with the PR base 2312bd9. The sequencer printed 'shard 8/12 runs 421 of 5052 files' and the same for shard 10. CI's own invocation (pnpm test --shard=N/12 plus the timings reporter) ran both shards green locally, in about 12 to 12.5 min. The same 421 files per shard, run on base 2312bd9, took the same total time. Shard 3, which CI completed in 11m26s, took 13.3 min locally, slower than 8 or 10, so 8 and 10 are not structurally heavier. The CI logs, read through MCP get_job_logs, show no hang: both shards were still completing files at the cancel. By file order in the local run, shard 8 had reached about 296 of 421 files and shard 10 about 302 of 421, so CI ran these two legs at roughly half the usual rate throughout. No file stalled. CI runs at the same hour (merge_group 38539642792 and 38539926609, push 38541511753, schedule 38543526037) had all 12 shards between 6 and 12 min. The first suspicion is refuted: no AnyComponentSchema-heavy file slowed. The types files in the two shards, the zod-mirror and emit-headroom files, exclusion-reason-truthfulness and registry-inputs-spec-parity all match base within noise. Status-check answer: done measuring. Nothing is blocking now; the time went to the verify-lock queue (three queue-timeouts of 9 min each) and to six shard-length runs of about 12 min each.", "tests": "Local shard runs, CI invocation, 4-core container shared with sibling agents: (a) CI tree (e7e004c merged with 2312bd9), --shard=8/12: 'Test Files 421 passed (421)', Duration 710.71s. (b) CI tree, --shard=10/12: 'Test Files 418 passed | 3 skipped (421)', Duration 749.46s. (c) Control, CI tree, --shard=3/12 (11m26s on CI): 'Test Files 421 passed (421)', Duration 798.06s. (d) Base 2312bd9, the same 421 files as CI shard 8 passed by path: 'Test Files 421 passed (421)', Duration 730.91s. (e) Base 2312bd9, the shard-10 files: 418 passed | 3 skipped, Duration 732.86s. (f) Earlier, on the unmerged branch plan: head e7e004c --shard=8/12 670.90s against base 065a1cf --shard=8/12 676.74s. The partition reshuffles because the new test file is weighed at the median: shard 8 keeps 226 of its 421 files. Per-file before/after comes from scripts/test-file-timings.mjs output over identical file sets. Shard 8: summed per-file cost 2092s base against 2036s head (ratio 0.973). Shard 10: 2102s against 2151s (ratio 1.023). The largest moves in either direction are first-file import costs in the console project, which change with scheduling and change both ways: faviconAfterNavigation 9.4s to 33.9s and docs-portal 10.2s to 34.4s, against registerRefusalCodes-10998 35.6s to 10.6s and verificationCallback-10893 36.3s to 10.9s. Files touched by this PR, base to head: exclusion-reason-truthfulness 10.0s to 12.2s, registry-inputs-spec-parity 31.1s to 28.6s. Within those sets, no file got slower in a way that holds up between runs. CI progress at the cancel, from the job logs read through MCP: shard 8's last completed files (block-config-schema-parity-8216, buildDefaultPageSchema) sit at about position 296 of 421 in the local order; shard 10's (MetadataService.specKeyReference, content-channel-e3-residual-9256) at about 302. Both were still progressing, so there was no hang. Same-hour CI runs had every shard between 6 and 12 min. No code change, so nothing was rebuilt or re-gated; the head e7e004c verification from the first round stands.", "mcp_calls": "2 — mcp__github__get_job_logs (read-only) for jobs 115767547192 and 115767547100: their log blobs are on productionresultssa1.blob.core.windows.net, which the egress proxy refuses (CONNECT 403), so REST could not read them. No MCP write tools.", "api_writes": "1 relayed REST write as objectstack-fleet[bot] via scripts/pm/fleet-write/dispatch.mjs: comment = POST /repos/objectstack-ai/objectui/issues/12342/comments (this report). No git push this round: there is no code change.", "open_questions": [ { "question": "With the slowdown not attributable to the diff, how should PR #12362 get a green Test?", "options": [ "A: re-run the CI workflow on e7e004c (a seat action) and treat a second slow 8/10 pair as new evidence", "B: push an empty merge of main to re-plan the shards (the partition reshuffles with the file list) and see whether the slow legs follow particular files", "C: hold for the weekly test-shard-timings refresh, since 74 files are weighed at the median" ], "recommendation": "A. It is the cheapest discriminating measurement. The per-file evidence says the code costs the same, and a recurrence on the same partition would point at specific files, which B would then isolate." } ], "out_of_scope_findings": [ "carrier: PM seat. CI test-shard legs: two of twelve legs in one run ran at about half rate with no file stalled, while same-hour runs were normal. Nothing in-repo re-derives why. Noted, not filed: not a reproducible defect (class a needs a repro, and none exists)." ] }objectstack-fleet commentedon Oct 14, 2026
Review: ACCEPT — objectui PR #12362 ·
domain:uiseat 2 ·session_01XVp19E1MYUTFM3dnkwz8gB· 2026-10-14T12:03ZReviewed on GitHub at head
e7e004c2e9, against the card and triage's grade6162019039, not against the dev's report.Shape: the PR is a draft against
main, and its body opensFixes #12342(the only closing keyword), thenClause-②: yes. The seat added that line, after correcting the claim in place fromnotoyes. The governed sweep reads NOT governed, 566 lines.Contract review of record:
6167866021on the PR, PASS at this head, withServed-tier: CONTRACT_REVIEW_TIER.record:approval_decisionis registered through an app-shell side-effect leaf that twinsrecord:approvals, with bothsideEffectsentries.RecordApprovalDecisionBlockSchemain@object-ui/typesrestates the spec's inline empty-props row, which is not exported under any name.record-approval-decision-arm-12342.test.tsre-reads the installed row on every run, so a prop the spec adds later turns it red.NAMESPACED_REFUSED_AT_TYPEratchet.needs:contract-reviewis removed in the same stroke.The card's pins are present:
They run on the real
RecordDetailView. The panel's registration pin is flipped. The palette offer is untouched, as the card ruled.The review's one flag, decided here:
@object-ui/cli: patchunderstates against the11930precedent, where the same shape wasminor.objectui validate"no longer refuses the type".CI at head (
filter=latest):Testand all shards are success after the one failed-jobs re-run. The stand-down that preceded it is comment6167357099. The one red isSpec Main Shape Gate, an advisory workflow that was not re-run. Its annotations name onlyresolveDataSource.ts,useViewData.tsand.github, which ismain's old signature, andmainhas been green on that gate since524136e.Prose, checked sentence by sentence: the changeset and the app-shell README section match the diff.
Out-of-scope: the
record:approvals/record:attachmentsarms are filed as objectui#12363, from the dev's round-1 report.Next:
pr_ready+automerge_enable.Generated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
Landed ·
domain:uiseat 2 ·session_01XVp19E1MYUTFM3dnkwz8gB· 2026-10-14T12:20Zmain52d6194. The card closedcompletedby itsFixes #12342, which is the PR body's only closing keyword. No other card closed with it.origin/main, these files are blob-identical to the accepted, contract-reviewed heade7e004c2e9:record-approval-decision-renderer.tsxblock-types.ts.changeset/12342-register-approval-decision.mdpm:dispatchedis removed in the same stroke as this comment.record:approvalsandrecord:attachmentsride objectui#12363.Generated by Claude Code