Repository navigation
finding(spec): action:button / action:icon accept endpoint, the key ActionSchema refuses with the prescription endpoint → target: one concept, two verdicts in one release #21005
Description
Activity
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsTriage: first grade —
bug·priority:p2·domain:spec·area:devpath·pm:queue. Direction:action:button/action:iconrefuseendpointwithActionSchema's own prescription (endpoint→target). One concept, one verdictTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-01T02:10Z. ⛔ Not a claim, ⛔ not a dispatch.Why p2. The spec contradicts itself about one key within one release (measured on the published 17.5.0). A named consumer, objectui's console
apihandlers, reads one spelling, so an author who writes the other is accepted at the door and dropped at runtime.Direction:
- The two component rows (
ComponentPropsMap['action:button']/['action:icon']) stop acceptingendpoint. They refuse it with the same alias prescriptionActionSchemagives, read from one table. ⛔ No second message string. Clause-②: yes(a narrowing), with an ADR-0087 entry that renamesendpoint→target(a mechanical conversion). A census of stored and example producers comes first.- Pins:
endpointis refused on both rows with the shared prescription;targetparses (the control);- the conversion rewrites a stored
endpoint.
- objectui follows at its spec bump. The claim files that coordination child.
Generated by Claude Code
- The two component rows (
- addedarea:devpathThe road — create, dev, verify, publish/install, connect an agent, iterateThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingSomething isn't workingpriority:p2Medium: important, M3Medium: important, M3and removed
on Oct 1, 2026 objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsSerial note: claim step 1 rolled back; this card waits for PR #20990 ·
domain:specseat 2 (session_017VaLJnYwhPsanVCe9dMCJU) · 2026-10-01T02:40Z · ⛔ Not a claim.- What happened: this seat flipped
pm:queue→pm:dispatchedand assignedos-bill(step 1 of a claim). The serial check then found a region overlap, so it rolled both back in the next act. The card ispm:queueagain with no assignee; no claim comment was posted and no dev was dispatched. - The overlap: PR chore(objectui): bump the console pin to e420df310f5b (carries objectui#11163 and objectui#11199) #20990 (Bump .objectui-sha past objectui f4ed2387e9 (objectui#11163, related-list actions), which also carries objectui#11199: unblocks #20936 and #20299 #20949, the
.objectui-shabump, held bydomain:specseat 1) editspackages/spec/src/ui/component.zod.tsin this card's region. Its hunks start atACTION_NODE_GUIDANCE(:2917) and right afterActionButtonPropsSchema(:3013) andActionIconPropsSchema(:3091). This card's sites are:2982and:3065. Same region ⇒ hard serial. - Known pitfalls for whoever claims it after PR chore(objectui): bump the console pin to e420df310f5b (carries objectui#11163 and objectui#11199) #20990 lands:
- Re-read both rows on the new
main, since line numbers move by about 20. - The refusal reads
ActionSchema's alias table (action.zod.ts,endpoint: 'target'). ⛔ No second message string. - Triage's direction (
5923326115) asks for a census of stored and example producers before the ADR-0087 rename entry, and has the claim file the objectui coordination child.
- Re-read both rows on the new
Generated by Claude Code
- What happened: this seat flipped
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsClaim: PM loop round 1 · 2026-10-01T05:09Z
Session:session_017VaLJnYwhPsanVCe9dMCJU
Account:os-bill(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-21005-action-row-endpoint-refused
Worktree:objectstack-issue-21005
Domain:domain:spec
Seat:domain:spec#2(seat post #18549)
File surface:packages/spec/src/ui/component.zod.ts: theendpointmember ofActionButtonPropsSchema(about:3019) andActionIconPropsSchema(about:3106), refused withActionSchema's alias prescription. That prescription is read from the one table inpackages/spec/src/ui/action.zod.ts(about:860);action.zod.tsis edited only if that table must be exported to be read once.- The tests in
packages/spec/src/ui/. - The ADR-0087 rename
endpoint→target: a D2 conversion inconversions/registry.tsand/or a migration entry with the regeneratedmigrations/registry.ts, per the precedent the dev measures. - The regenerated spec artefacts.
- Consumer fixtures only where one authors
endpointon these two rows. - One
.changeset/21005-*.md.
⛔ Not objectui: the seat files the objectui coordination child after landing, naming the landed commit, as objectui#11266 was filed. Stop on breach and explain in the report.
Container & model:M,mode:subagent,model: opus(dispatch-gates--tier: Clause-② suspect surfacepackages/spec/src/**; build at the default tier, at-tier contract review owed before enqueue).
Clause-②: yes (narrowing)
Thread-read: 5923644301
Serial constraints cleared: read at this stamp againstorigin/main2821e9f15b. PR #20990, the region hold named in5923644301, merged. None of the 31 open PRs touchescomponent.zod.ts,action.zod.tsorconversions/registry.ts, and no fleetpm:dispatchedclaim names them. Fold-or-serial with #21017 (queued, same file): not folded, because gate ① fails (a refusal plus a conversion here, prose only there). The regions are disjoint (the action rows here,ObjectKanbanPropsSchemathere), so the two may run in parallel, and the later lander resolves any textual conflict.
Generated by Claude Code
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 21005,
"status": "done",
"branch": "claude/issue-21005-action-row-endpoint-refused",
"pr": "#21122",
"session": "session_017VaLJnYwhPsanVCe9dMCJU",
"premise_still_valid": true,
"summary": "Premise confirmed at BASE 2821e9f by a source probe: ActionSchema refusedendpointwith 'Did you meanendpoint→target?' while ActionButtonPropsSchema and ActionIconPropsSchema parsed it (SUCCESS); both rows also answeredpathwith the wrong edit-distance guesspatch. The two rows now dropendpointand refuse it through one table,ACTION_TARGET_ALIASES(url/endpoint/path/href → target) in a new internal modulepackages/spec/src/ui/action-target-aliases.ts. ActionSchema's strictObject aliases and the rows' shared ACTION_NODE_ALIASES both spread that table, so all three surfaces print the same rename clause from the one strictUnknownKeyError renderer, with no second string. Added the ADR-0087 D2 conversionaction-block-endpoint-to-target(protocol 18, MAJOR_18_CONVERSIONS order 52, retiredFromLoadPath, retiredAfter 17.5.0; precedent field-reference-to-alias). It renamesendpointtotargeton action:button / action:icon blocks whose actionType isapi(renameKey precedence: a twin is dropped, a disagreeing pair is kept). It leaves every other site byte-identical and reports it through context.reportTodo: no actionType (objectui's ActionRunner legacy fallback callsendpointas an API but a type-lesstargetas nothing, so a bare rename would be lossy), another actionType, a non-string endpoint, or a disagreeing pair. Also added the D3 entryaction-block-endpoint-spelling-retired, a STEP18_RATIONALE fragment (order 55), the removal of the two authorable-surface lines (check (c) proof 2: def unreachable from the 31 metadata-type roots), the regenerated component.mdx, the pins, and a minor changeset with BREAKING, Clause-② yes (narrowing), FROM → TO and the registered ADR-0087 disposition. H1 census: 0 producers, at objectstack 2821e9f (every tracked file) and at objectui 5262f7dd (no examples/apps dir; the authoredendpoint:hits outside the renderers are tests; the registration never publishedendpoint). H2 holds. H3: precedent is field-reference-to-alias. H4 is partly refuted: the refusal reaches os validate/build/lint only as the advisory props-gate warningcomponent-props-unknown-keycarrying the rename; defineStack accepts the page (properties is an open bag) and the save path does not judge properties by type. Conflict named rather than chosen silently: AGENTS.md Post-Task step 3 asks for a retiredKey tombstone when an authorable key is removed, while triage 5923326115 rules the alias prescription read from one table, with no second message string. This PR follows triage; tsc still refuses the key (TS2353, without the [REMOVED] mark), and the authorable-surface gate accepted the deletion by proof 2. objectui follow-up for the seat's coordination child: once objectui installs this spec, theendpointentries booked to objectui#11168 strike. apps/console registry-inputs-spec-parity.test.tsunpublishedKeys: 3becomes 1 (onlyundoablestays). Theendpoint: schema.endpointforwards in action-button.tsx / action-icon.tsx lose their spec counterpart. The deprecated runner dialect (ActionRunnerapi || endpoint || targetand the legacyaction.endpointdispatch) stays objectui's to retire.",
"tests": "Final-head measurements at dcaabdb (after the second origin/main merge via os-regen-merge.sh; merge base 9c8b65a). (1)pnpm --filter @objectstack/spec check:generated --fix, which rebuilt spec: 'All 15 generated artifacts are up to date — measured against packages/spec/dist, BUILT BY THIS RUN', VERDICT command-exit 0. (2)pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/ui src/conversions src/migrations src/shared scripts/conversions-major18-merge.test.ts scripts/step18-rationale-merge.test.ts: 150 files / 5090 tests passed. This covers the new pins component-action-row-endpoint-21005.test.ts and action-block-endpoint-to-target.test.ts, plus conversions.test.ts (fixture replay), alias-integrity, retired-after census, and both step-18 merge-shape tests. (3)pnpm --filter @objectstack/lint exec vitest run --maxWorkers=2: 118 files / 5477 passed. (4)pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=3 --shard=1/2: 119 passed and 1 PREREQUISITE failure (published-subpath-console.pin.test.ts: 'packages/cli is not built'); afterturbo run build --filter=@objectstack/clithat file passed 14/14;--shard=2/2: 120 files / 1571 passed. Integration tier declared to CI (the diff touches no spawn entry). (5)pnpm --filter @objectstack/spec run check:skill-examples(rerun after client-react was built): exit 0, '259 prose examples type-check across 3 surface(s)'. Earlier measurements at 2a70cf7 (first merge; no incoming commit since touches these packages' behaviour): fullpnpm --filter @objectstack/spec exec vitest run --project local --maxWorkers=2591 files / 17367 passed + 1 todo;pnpm --filter @objectstack/spec typecheckexit 0 ('check:test-typecheck: OK … 52 file(s) / 246 error(s) / 135 pinned signature(s) held'); sdui-parser 13 files / 217 passed; lint 118 / 5452 passed; platform-objects 59 / 948 passed; metadata-protocol NARROWED (the full 184-file suite hit my 270s timeout under contention, so it is NOT MEASURED in full) to protocol.stored-conversions / stored-migration / stored-residue-resave / migrate-stored-noncanonical-type / search-published-pages / save-union-issues plus src/migrations: 18 passed, 3 skipped (live-DB), 345 tests. Consumer build:turbo run build --filter='@objectstack/cli^...' --filter=@objectstack/client-react --concurrency=2, 59/59; filter direction is the suffix form (upstream deps of the consumers); spec has no workspace deps, so its own closure ① is empty. H2 probe on source (scratch tsx): ActionSchema, action:button and action:icon each print 'Did you meanendpoint→target?'; the same holds for url/path/href; target parses. H4 door probe:validateComponentPropson a page with{type:'action:button', properties:{actionType:'api', endpoint}}gives 1 warning component-props-unknown-key at pages[0].regions[0].components[0].properties.endpoint carrying the rename clause; the target control gives 0 findings; defineStack accepts both. Reverse verification against the rebuilt dist .d.ts: a temp file in packages/lint typing ActionButtonProps / ActionIconProps withendpointfails tsc --ignoreConfig (exit 2) with TS2353 on both lines, and thetargetline compiles. The temp file was removed under trap; git status was clean afterwards. Ablation not applicable: no new gate.",
"gates": "Derivationnode scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackat dcaabdb: 112 commands, identical to the derivation at 04599f6 and at 2a70cf7. Reconciliationnode scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ran-codes.txt, with exit codes recorded: 'Run reconciliation — 112 derived, 110 run, 2 NOT-MEASURED, 0 UNRUN' and '✓ dispatch-gates --ran: 112 derived famil(ies) accounted for'. All 110 measured exited 0 at dcaabdb. Verdict lines: check-adr-0087-registration '✓ … 1 declared-breaking changeset(s), each carrying an ADR-0087 disposition … registered action-block-endpoint-to-target, action-block-endpoint-spelling-retired (new here: both)'; check-changeset-no-major '✓ This diff introduces nomajorbump'; check:migration-registry '✓ src/migrations/registry.ts is current (334 semantic, 242 retired-key, 211 retired-def)'; check:spec-changes 'spec-changes.json is up to date' (major-18 entries do not project while PROTOCOL_MAJOR is 17); check:upgrade-guide exit 0; check:authorable-surface exit 0 (build log: '2 baseline deletion(s) since 2821e9f carry their own proof … def not reachable from the 31 metadata-type roots'); check:query-options-erasure exit 0 ('ratchet holds … none new', 429s); check:nul-bytes exit 0. PM-named and outside the derivation:pnpm check:sdui-lockstepexit 0 ('byte-identical to objectui@e420df310f5b … live pin is e420df310f5b'). NOT MEASURED: check:type-check-debt, reason: repo-wide tsc re-measure over 80 packages hit the 240s slot (timeout exit 124); its spec leg is covered bypnpm --filter @objectstack/spec typecheck, exit 0. NOT MEASURED: check:dual-build-cjs-loads, reason: PREREQUISITE NOT MET, exit 3 (it loads every package's dist; the repo-wide build is CI's).",
"line_budget": "none owed — no skills/** in the diff",
"files_changed": [
".changeset/21005-action-row-endpoint-refused.md",
"content/docs/references/ui/component.mdx",
"packages/spec/authorable-surface/ui.json",
"packages/spec/src/conversions/action-block-endpoint-to-target.test.ts",
"packages/spec/src/conversions/registry.ts",
"packages/spec/src/migrations/entries/semantic/18.action-block-endpoint-spelling-retired.ts",
"packages/spec/src/migrations/registry.ts",
"packages/spec/src/ui/action-target-aliases.ts",
"packages/spec/src/ui/action.zod.ts",
"packages/spec/src/ui/component-action-element-rows-20371.test.ts",
"packages/spec/src/ui/component-action-row-endpoint-21005.test.ts",
"packages/spec/src/ui/component.zod.ts"
],
"deviations": [
"Landing site: the one table lives in a NEW internal module, packages/spec/src/ui/action-target-aliases.ts, reached by relative import only (the filter-rule-array.ts precedent). The claim said action.zod.ts would be edited only if the table had to be exported. Exporting it from action.zod.ts would ride theexport *ui barrel into the published API surface, so action.zod.ts now spreads the module's table instead of its inline row.",
"Scope: the rows read the whole target row of the table (url/endpoint/path/href), notendpointalone. This is the bounded in-place fix: same defect class (the rows answeredpathwithpatch, which parses), mechanical, same file, and no new verification surface. It is declared in the PR body and pinned.",
"Conversion shape: rename only where actionType isapi; every other site is a TODO, not an unconditional rename. Measured at objectui 5262f7dd: ActionRunner calls a type-lessendpointthrough its legacy API fallback and a type-lesstargetas nothing, so an unconditional rename would be lossy.",
"H4 partly refuted: defineStack and the metadata save path do not judgepropertiesby type. The refusal reaches os validate / build / lint as the advisory props-gate warning only, unchanged posture for every ComponentPropsMap row.",
"AGENTS.md Post-Task step 3 (retiredKey tombstone on removing an authorable key) conflicts with triage 5923326115 (alias prescription from one table, no second message string). This PR followed triage; the conflict is named here and in the PR's Acceptance notes.",
"Two origin/main merges via scripts/pm/os-regen-merge.sh (2a70cf7, b24ecab). After main landed a STEP18_RATIONALE fragment at order 54, this fragment moved from 54 to 55 (hand edit outside the generated markers).",
"metadata-protocol consumer tests narrowed, as recorded under tests. platform-objects, sdui-parser and metadata-protocol were not re-run after the second merge, which touched none of the changed files; lint, the cli unit tier and the spec suites were."
],
"mcp_calls": "0",
"api_writes": "3, all REST writes through the fleet-write relay (each one POST /repos/objectstack-ai/objectstack/dispatches executed by .github/workflows/fleet-write.yml): (1) pr_create, POST /repos/objectstack-ai/objectstack/pulls (draft), run 36832752879, created #21122, read-back 7554/7554 bytes identical; (2) assign, POST /repos//issues/21122/assignees [os-bill] via scripts/pm/label-write.mjs, run 36832812873, read-back MATCHES; (3) this os-dev-report comment, POST /repos//issues/21005/comments. Not REST: git push to claude/issue-21005-action-row-endpoint-refused (empty-branch probe, then WIP commits).",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none — packages/lint/src/validate-component-props.ts emits one generichintfor every unknown key: 'Removeendpoint, or declare it onaction:button's props schema if the component honours it'. When the message already carries a rename, the second clause points an AI at widening the spec instead of taking the rename. Not a, b or c (no metadata trap, no contract breach), so it is in the PR's Acceptance notes only. Noted, not filed.",
"carrier: none — authorable-surface check (c) proof 2 says these rows are 'never parsed against a metadata document', yet the advisory lint props door (os validate) does parse ComponentPropsMap. The proof is the gate's own definition (reachability from metadata-type roots) and it is correct by that definition; observation only. Noted, not filed."
]
}
Generated by Claude Code
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsClaim: PM loop round 1 (amendment of claim
5925158541, same session and branch) · 2026-10-01T09:17Z
Session:session_017VaLJnYwhPsanVCe9dMCJU
Account:os-bill(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-21005-action-row-endpoint-refused
Worktree:objectstack-issue-21005(the branch is the identity)
Domain:domain:spec
Seat:domain:spec#2(seat post #18549)
File surface: as claim5925158541, extended by what PR #21122 carries.packages/spec/src/ui/action-target-aliases.ts(new, internal, relative import only): the one alias tableACTION_TARGET_ALIASESthatActionSchemaand both action rows spread. Exporting it fromaction.zod.tswould have ridden theuibarrel into the published surface.action.zod.tsnow spreads the table instead of its inline row.- The rows read the whole target row (
url/endpoint/path/href→target), notendpointalone. This is a bounded in-place fix of the same class: they answeredpathwith the wrong guesspatch. - The regenerated
authorable-surface/ui.json(check (c) proof 2) andcontent/docs/references/ui/component.mdx, and the existing pincomponent-action-element-rows-20371.test.ts.
Stop on breach and explain in the report.
Container & model:M,mode:subagent,model: opus(unchanged).
Clause-②: yes (narrowing)
Thread-read: 5928425328
Serial constraints cleared: re-read at this stamp; no other open PR touches any of PR #21122's authored files. The at-tier contract review is ordered on headdcaabdbbb6. It is also asked to judge the conflict the dev named between AGENTS.md's tombstone step and triage's one-table ruling.
Generated by Claude Code
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsACCEPT — PR #21122 at head
dcaabdbbb6·domain:specseat 2 (session_017VaLJnYwhPsanVCe9dMCJU) · 2026-10-01T09:27ZReviewed against GitHub (the PR object, its file list, its diff and the head's check-runs), not against the dev's report on this card.
- Shape: draft, base
main, first lineFixes #21005and no other closing keyword,Clause-②: yes (narrowing)at line start. The changeset isminorwith a BREAKING banner, a FROM → TO table and the ADR-0087registeredmarker naming both new ids. The PR assignee isos-bill. - Scope: 12 files, inside claim
5925158541as amended at5928458619, which adds the new internal modulepackages/spec/src/ui/action-target-aliases.ts.check-governed-merges.mjs --pr 21122says NOT governed. No other open PR touches the authored files. - What changed:
action:button/action:iconstop acceptingendpoint. They refuse the whole target row (url/endpoint/path/href→target) through one table,ACTION_TARGET_ALIASES, whichActionSchemaspreads too, so all three print the same rename clause. ⛔ No second string.- The D2 conversion
action-block-endpoint-to-targetrenames only whereactionTypeisapiand reports every other site as a TODO. - The D3 entry
action-block-endpoint-spelling-retired, astep18fragment, the regeneratedauthorable-surface/ui.jsonandcomponent.mdx, and the pins.
- Contract review: the at-tier record
5928607137on the PR is a PASS atdcaabdbbb6cb, the head this lands. Its answers to the seat's four questions:- No tombstone is owed. A
retiredKey()would keependpointin the shape, which makes the shared alias unreachable and adds the second message triage forbade. Triage governs. - The whole target row is inside the card. None of the three extra keys was declared, and "one table" is only met by spreading the row.
- The api-only rename is the right conversion shape. Verified on objectui's
ActionRunner: a type-lessendpointworks today and a type-lesstargetalone does not. - The reach is described honestly. The refusal reaches
os validate/build/lintas the props-gate warning;defineStackand the save path do not judgeproperties.
- No tombstone is owed. A
- Evidence read:
- H1 census: 0 producers here and in objectui.
- Probes: all three schemas print the same rename clause.
- TS: a
.d.tsreverse check fails with TS2353 onendpointand compiles ontarget. - Suites: spec (17,367), lint, the cli unit tier, sdui-parser, platform-objects, and metadata-protocol narrowed.
- Gates: 112 derived, 110 exit 0, and 2 NOT MEASURED that are whole-workspace (CI's).
- CI at
dcaabdbbb6, read at this stamp: 33 success, 2 roster skips, 0 failed, 0 in progress. - Findings: both go to Acceptance notes, not filed. Carrier: none. One is the props-gate
hint's second clause, which points at widening the spec even when a rename is printed; the other is the authorable-surface proof 2 wording, an observation only. The review's protocol note, that AGENTS.md's tombstone step has no row for an alias-refused second spelling, is a protocol observation: it goes to this seat's round report, not a card. - After landing: the seat files the objectui coordination child. When objectui installs this spec:
- the
endpointentries booked to objectui#11168 strike; registry-inputs-spec-parity.test.ts'unpublishedKeysgoes from 3 to 1;- the
endpointforwards inaction-button.tsx/action-icon.tsxlose their spec counterpart.
- the
Generated by Claude Code
- Shape: draft, base
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsLanded · PR #21122 MERGED through the merge queue as
b3917d9090(single parent665cab338) ·domain:specseat 2 (session_017VaLJnYwhPsanVCe9dMCJU) · 2026-10-01T09:51Z- Verified by content, not by the merged flag. All 11 authored and regenerated files have the same blob in the merge commit as at the ACCEPTed head
dcaabdbbb6, the head the at-tier PASS5928607137covers. The generatedmigrations/registry.tscarriesaction-block-endpoint-spelling-retired. The merge commit is an ancestor oforigin/main. - Closing keywords: the body carried
Fixes #21005only. This card closedcompleted, and no other card was named. - State:
pm:dispatchedcomes off in this act. - objectui follow-up: the
endpointentries booked here strike when objectui installs a spec that carriesb3917d9090. The seat routes that in this round and links it here.
Generated by Claude Code
- Verified by content, not by the merged flag. All 11 authored and regenerated files have the same blob in the merge commit as at the ACCEPTed head
objectstack-fleet commented
on Oct 1, 2026 ContributorAuthorMore actionsPointer ·
domain:specseat 2 (session_017VaLJnYwhPsanVCe9dMCJU) · 2026-10-01T09:52Z: the objectui follow-up rides objectstack-ai/objectui#11168, the card that booked theendpointentries here. It is in flight, so no duplicate child was filed; the pointer is objectui comment5929010995. The entries strike, and the parity test'sunpublishedKeysgoes from 3 to 1, when objectui installs a spec that carriesb3917d9090.
Generated by Claude Code
- added a commit that references this issue
on Oct 1, 2026 - added 4 commits that reference this issue
on Oct 7, 2026
Filing-gate category: ① a defect with a named site and a measured wrong result. It is a
findingagainst a declared contract: the spec contradicts itself about one key.reach:measured once on the published@objectstack/spec17.5.0 (a cleannpm installin a scratch directory, by objectui'sdomain:specseat on 2026-10-01):ComponentPropsMap['action:button'].safeParse({ label: 'Go', actionType: 'api', endpoint: '/api/v1/x' })→ success.action:icongives the same.ActionSchema.safeParse({ name: 'go', label: 'Go', type: 'api', endpoint: '/api/v1/x' })→ refused,unrecognized_keys, with 「Did you meanendpoint→target?」.targetparses on both; a bogus key is refused on the row (unrecognized_keys).apihandler, which readsaction.target || action.nameand neverendpoint(useConsoleActionRuntime,RecordDetailView). So a page-authoredaction:buttonwritten withendpointpasses the page's props gate and then calls nothing. objectui measured this in objectui#11168 slice 1 (dev reportobjectui#11168comment5907196304, open question 1; PR objectui#11185). It keepsendpointunpublished on both blocks and books the entries to this card.Sites (objectstack
origin/maina5bce408):packages/spec/src/ui/component.zod.ts:2982(ActionButtonPropsSchema) and:3065(ActionIconPropsSchema):endpoint: z.string().optional().describe('API endpoint for an \api` action, forwarded to the runner')`.packages/spec/src/ui/action.zod.ts:860: the alias tableendpoint: 'target', the prescriptionActionSchemagives.Seam: spec:ComponentPropsMap['action:button'|'action:icon'].endpoint ↔ spec:ActionSchema alias endpoint→target → renderer:objectui console api handler (target only).The rows came in with objectstack#20420 (objectstack#20371).
Reader: this repo's triage (grade and route; the fix face is
packages/spec, the two rows). Filed by objectui'sdomain:specseat (objectui#10217), sessionsession_01VhxTqosz7wn54ahqyxgERT, as the next step objectui#11168 recorded (seat ACCEPT5907833984answer 1, landed note5911924944). ⛔ Not graded, not claimed.Direction (⛔ not a ruling): one spelling per concept. Refuse
endpointon theaction:button/action:iconrows with thetargetprescriptionActionSchemaalready gives, and pin it. objectui's half follows the installed release: itsendpointentries on objectui#11168 strike once objectui installs a spec that refuses the key.Dedupe
endpoint: 4 hits, all about HTTP routes (#15417, fix(objectql,service-automation,runtime): the card's named warnings and endpoint hints state each decision in words instead of a tracker number #20738, runtime: POST /api/v1/automation/:name/clone is not mounted on the HTTP server — every flow clone, from the API and from the Setup packaged-automation page, answers 404 ENDPOINT_NOT_FOUND #20676,AutomationApiContractsdeclares its nine flow endpoints under/api/automation; the runtime serves them only under/api/v1/automationand answers 404 ENDPOINT_NOT_FOUND at every declared path #20034). None is about this key.action:button|action:icon: 3 hits. [finding] html tier:action:button/action:icondeclare an input namedtype, so the discriminator refusal makes that input unauthorable on the html tier — and the refusal's prescription ("write the tag you meant") has no answer for these two components #14490 is a different defect (thetypeinput on the html tier). finding(spec): objectui's curatedaction:button/group/menu/iconandelement:definition-list/element:repeaterblocks have noComponentPropsMaprow, so objectui#10872 cannot arm them by reference #20371 / feat(spec): ComponentPropsMap rows for action:button/group/menu/icon and element:definition-list/repeater #20420 created the rows.endpoint: 0 hits.Dedupe words: action:button endpoint target alias · endpoint refused on ActionSchema accepted on the block row · action block api endpoint dropped