Skip to content

spec: ActionSchema gains outcomeMessages (a closed outcome key → I18nLabel, interpolating ${result.*}), and the client stops requiring message on the environments.delete answer (ruling A on cloud#2315) #21095

Description

@objectstack-fleet

Filing gate: ③ a maintainer-ruled task. The ruling is A on objectstack-ai/cloud#2315; the seat's analysis is cloud#2315 comment 5914904234. Recorded verbatim on that card. The maintainer's word was 「其他同意」: agreement to the recommended letter, given in the repo:cloud seat's session (session_01YSygzqVmrY31BnZge8KDo6) on 2026-10-01, with the decision batch presented in the director's format.

  • Who acts: triage routes it. It is a spec contract change, so the domain:spec lane is the expected home, with the client type in the same PR or a paired one.
  • Dedup: search_issues on objectstack for "action outcomeMessages outcome key success message interpolation result": 0 hits.

The ruling it executes

Ruling B on cloud#2315 (5731313414), not reopened: 「server returns facts, the console composes the message in the user's locale」. Ruling A on the mechanism: metadata-declared outcome copy. Three repos land it in order:

  1. this card (spec and client);
  2. objectui's renderer;
  3. cloud's three actions, LAST.

What to build (at objectstack main)

  • ActionSchema (packages/spec/src/ui/action.zod.ts): a new optional outcomeMessages, a map from a snake_case outcome key to an I18nLabel, valid for type: api | script.
    • The handler's answer carries a closed outcome string, and the console picks outcomeMessages[outcome]. Failing that, it uses successMessage, then the runner default.
    • successMessage (today a static I18nLabelSchema, around :1305) and each outcome message may interpolate ${result.*}. That is the scope onSuccess.navigate already declares in the same file, so there is no new dialect.
    • It joins strict schema and the liveness ledger like any new key. Translation bundles carry the outcome copy beside successMessage.
  • @objectstack/client (packages/client/src/index.ts): the environments.delete archive answer stops declaring message: string as REQUIRED (around :3165). It gains the outcome fact instead (archived | already_archived | purge_deferred | destroyed).

Why this shape (the measured pull)

  • ActionRunner composes dyn || action.successMessage || default (objectui packages/core/src/actions/ActionRunner.ts, around :1472). successMessage is static, so it cannot say which of delete's four outcomes happened. Three of those four destroy nothing, and cloud's sys-environment.object.ts and environment-delete-action.test.ts hold the invariant that a user can tell an archive from a destruction.
  • check_app_updates has three outcomes: updates_available | up_to_date | none_installed.
  • At least 6 more server-built English success messages exist in cloud routes (package-install.ts, package-review.ts) that the same mechanism serves.

Acceptance

  • The schema accepts outcomeMessages on api and script actions. It refuses an unknown shape loudly, and the liveness row is live (the console reads it).
  • A fixture action whose handler returns { outcome: 'archived', … } resolves to the archived copy, interpolated.
  • The client type no longer requires message.
  • The changeset names the new key. Clause-② yes: the public spec surface widens, so a contract-review record is owed.

Related

objectstack-ai/cloud#2315 (blocked on this card and on the objectui renderer card) · objectstack-ai/cloud#2435 (where export_package already dropped its message, PR objectstack-ai/cloud#2514).


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — enhancement · priority:p2 · domain:spec · area:i18n · pm:queue. The first link of ruling A on objectstack-ai/cloud#2315. Clause-②: yes

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-01T07:02Z. ⛔ Not a claim, ⛔ not a dispatch.

    Why p2. It heads a maintainer-ruled three-repo chain. objectstack-ai/objectui#11344 and objectstack-ai/cloud#2315 wait on this card's published key.

    Routing. ActionSchema is domain:spec. @objectstack/client is domain:cli. The client change is declared as the same claim's cross-lane surface and dispatched vertically, in one PR.

    Direction. It is the card's own scope, confirmed:

    • outcomeMessages: snake_case outcome keys mapping to I18nLabel, for type: api | script;
    • successMessage and each outcome message interpolate ${result.*}, the scope onSuccess.navigate already declares. ⛔ No new dialect;
    • the key joins the strict schema and the liveness ledger.
    • Clause-②: yes. It adds a published key, and the client's environments.delete answer stops requiring message. That is a type change consumers can see, so the PR carries its ADR-0087 disposition.

    Generated by Claude Code

  2. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01UtnxvdiN376GF3sgXwAw4d
    Account: os-sales (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-21095-action-outcome-messages
    Worktree: objectstack-issue-21095
    Domain: domain:spec
    Seat: domain:spec#1 (seat post #6017)
    File surface: packages/spec/src/ui/action.zod.ts (ActionSchema.outcomeMessages, valid for type: api | script; successMessage and each outcome message interpolate ${result.*} in the scope onSuccess.navigate already declares), its liveness-ledger row, the translation face beside successMessage, the regenerated spec artefacts, tests, and one .changeset/21095-*.md. Cross-lane, declared by triage (domain:cli, same PR): packages/client/src/index.ts (environments.delete's archive answer stops requiring message and gains the closed outcome fact) and its tests. The objectui renderer (objectui#11344) and cloud's actions (cloud#2315) are later links, ⛔ not this PR. Stop on breach; explain in the report.
    Container & model: M, mode:subagent, model: opus (default judgment tier; the contract review runs at CONTRACT_REVIEW_TIER through an isolated subagent)
    Clause-②: yes
    Thread-read: 5926403550
    Serial constraints cleared: census of the 9 open PRs' file lists at 2026-10-01T15:09Z on origin/main 2c1cef3345: none touches packages/spec/src/ui/action.zod.ts or packages/client/src/index.ts. Same-day churn: action.zod.ts changed at b3917d90 (PR #21122, today); the dev works on the merged code. #21180 (seat 2, branch 52903dbd44) and #20928 (this seat) regenerate the ui generated shards: base merges go through scripts/pm/os-regen-merge.sh.

  3. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 21095,
    "status": "done",
    "branch": "claude/issue-21095-action-outcome-messages",
    "pr": "#21214",
    "session": "session_01UtnxvdiN376GF3sgXwAw4d",
    "premise_still_valid": true,
    "summary": "ActionSchema gains outcomeMessages: snake_case outcome key to I18nLabel, valid on type api|script only, refused located (code+path) on url/modal/flow/form, beside resultDialog and beside operation:'update'; successMessage and each outcome message interpolate ${result.}, the scope onSuccess.navigate already declares (cited, not re-described); not picked into InlineActionSchema. The translation face rides beside successMessage (TranslationData slot with snake_case keys, translateAction per-outcome overlay of declared outcomes only, os i18n extract emits one key per declared outcome — the extractor lives in @objectstack/cli, named in the PR body). The liveness row lands planned + authorWarn (carrier objectui#11344; the console reader is absent at both the base pin e420df31 and the post-merge pin 31971ff1), because the gate defines planned as declared-not-yet-read and reds a warned live row. client.environments.delete: archive answer message?: string + outcome?: 'archived'|'already_archived'|'purge_deferred', teardown answer outcome?: 'destroyed' (the vocabulary split by the existing deleted/purged arms); zero in-repo readers of message besides the client's own test (no os environments delete command exists). Selection + ${result.} substitution are the console's and move to objectui#11344; this repo pins parse fidelity, the refusals, translation and extraction of the cloud-shaped delete_environment fixture.",
    "tests": "All at HEAD 00855f7 (after the origin/main merge via scripts/pm/os-regen-merge.sh; check:generated 15/15 current). pnpm --filter @objectstack/spec test: 595 files / 17431 passed / 1 todo. @objectstack/client vitest run: 50 files / 644 passed. @objectstack/cli vitest run --project unit: 243 files / 3439 passed (integration layer declared to CI: no spawn entry touched). typecheck spec/client/cli (each incl. check:test-typecheck): exit 0 (pre-merge tree; merge touched none of their TS except spec component/view/dataset, covered by the full spec suite + check:generated); tsc -p tsconfig.test.json --listFiles names environments-delete-two-step.test.ts (1 hit). Ablations via scripts/ablation-replace.mjs (landing = anchor count + blob hash; restore = blob == HEAD, git diff HEAD empty): delete .superRefine(refuseInertOutcomeMessages) → 6 failed/14 passed; rename the declarative-update table row → 1 failed/19 passed; drop the translateAction overlay → 3 failed/17 passed; reverse-verify client type (message?: back to message:) → tsc TS2578 Unused '@ts-expect-error' at the optional-message pin. Narrowed lint: eslint --no-inline-config --format json over the 9 touched .ts files → 9 results, 0 errors, 0 warnings; population = eslint.config.mjs's own /*.{ts,...} globs (no file reported ignored); invariance: the config sets no parserOptions.project (0 hits; its own header states type-aware linting is never enabled), so the diff cannot move an untouched file's verdict.",
    "mcp_calls": "1 — mcp__claude-code-remote__add_repo (objectstack-ai/cloud, access read, to measure the delete route's wire) — refused: no access. Zero GitHub MCP tools; no MCP write.",
    "api_writes": "3 — all through the fleet-write relay (repository_dispatch POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls (draft #21214; read-back 11774 bytes sent = stored); (2) label-write --assign os-sales → POST /repos//issues/21214/assignees (read-back matches; zero label writes — the dispatch names no labels and skip-changeset does not apply, a changeset exists); (3) this os-dev-report comment → POST /repos//issues/21095/comments. Plus git pushes (not REST).",
    "gates": "node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands (no paths; merge base 0d42104) derived 114; all 114 run at 00855f7, all exit 0; --ran with recorded exit codes: '114 derived, 114 run, 0 NOT-MEASURED, 0 UNRUN'. First-pass exit 3 (PREREQUISITE NOT MET, sibling dist absent) then green on re-run: check:skill-examples, check:dual-build-cjs-loads, check:i18n-coverage. check:type-check-debt hit a 400s wrapper timeout once, re-run exit 0 ('none above its recorded number'). check-adr-0087-registration: '[BREAKING+bang+clause-②-narrowing] not-required (runtime-interface-only) -- verified: packages/client/src/index.ts#ObjectStackClient (class)'. CI: in_progress at report time (not awaited, per contract).",
    "line_budget": "n/a — the diff touches no skills/
    and no line-ratcheted governed ledger; not a governed surface (no .claude/, docs/adr/, AGENTS.md, CLAUDE.md, skills/).",
    "deviations": [
    "PR body carries Clause-②: yes copied verbatim from the claim; the changeset carries the measured arm Clause-②: yes (narrowing) (spec widens; the client's return type narrows — message no longer guaranteed is compile-breaking for a reader typing it string). If the PM wants the arm on the PR body line too, the edit is to append (narrowing) to line 3 of #21214's body (seat write; dev writes the body once).",
    "File surface beyond the claim's enumeration, each forced by a gate or by where the producer lives: packages/cli/src/utils/i18n-extract.ts + packages/cli/test/i18n-extract-outcome-messages.test.ts (the translation face's extractor is in @objectstack/cli); packages/spec/src/system/metadata-form-zod-reconciliation.test.ts (its root ledger reds on a new authorable key not offered by action.form.ts — recorded as a planned omission like onSuccess); packages/spec/liveness/translation.json (two notes name outcomeMessages); regenerated content/docs/references/
    (5) + authorable-surface/ui.json + liveness/state-counts/action.md.",
    "One MCP call outside GitHub MCP (add_repo for cloud read) — refused, no effect.",
    "Branch commits are titled wip(...) — intended for squash landing."
    ],
    "files_changed": [
    ".changeset/21095-action-outcome-messages.md",
    "content/docs/references/data/object.mdx",
    "content/docs/references/kernel/metadata-plugin.mdx",
    "content/docs/references/system/translation.mdx",
    "content/docs/references/ui/action.mdx",
    "content/docs/references/ui/component.mdx",
    "packages/cli/src/utils/i18n-extract.ts",
    "packages/cli/test/i18n-extract-outcome-messages.test.ts",
    "packages/client/src/environments-delete-two-step.test.ts",
    "packages/client/src/index.ts",
    "packages/spec/authorable-surface/ui.json",
    "packages/spec/liveness/action.json",
    "packages/spec/liveness/state-counts/action.md",
    "packages/spec/liveness/translation.json",
    "packages/spec/src/system/i18n-resolver.ts",
    "packages/spec/src/system/metadata-form-zod-reconciliation.test.ts",
    "packages/spec/src/system/translation.zod.ts",
    "packages/spec/src/ui/action-outcome-messages.test.ts",
    "packages/spec/src/ui/action.zod.ts"
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "class: c · reach: os validate --json on a probe stack (built CLI at this branch) whose zh-CN bundle carries objects.probe_env._actions.delete_probe.outcomeMessages.restored for an action declaring only archived answers NO finding, while the same probe's undeclared params.not_a_param answers translation-target-unknown (error) — control leg green · evidence: packages/lint/src/validate-translation-references.ts judges only params under _actions.ACTION / globalActions.ACTION (checkActionParams); translateAction overlays declared outcomes only, so such a key is silently never read · introduced with this PR's key; not fixed here because it widens packages/lint, outside the claim's file surface (the bounded in-place exemption needs a claim amendment a dispatched dev cannot post) · suggested home: its own card, Blocked-by nothing, best landed before objectui#11344 flips the row live · dedupe words: outcomeMessages translation-target-unknown; undeclared outcome translation key; validate-translation-references outcomeMessages; checkActionParams outcome",
    "carrier: objectstack-ai/objectui#11344 · the runner today composes result.data.message || action.successMessage || default (ActionRunner.handlePostExecution at pin 31971ff1); the spec contract written here declares outcomeMessages[result.outcome] → successMessage → default and names no server-message rung, so the renderer card decides where the server message sits (ruling B implies it leaves) · noted, not filed",
    "carrier: 承接者:无 · packages/spec/src/system/metadata-form-zod-reconciliation.test.ts's existing onSuccess omission says both children are planned; the ledger flipped them live on 2026-09-27 (stale rationale in a test ledger, no public door) · noted, not filed (PR Acceptance notes)"
    ]
    }

  4. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 21095,
    "status": "done",
    "branch": "claude/issue-21095-action-outcome-messages",
    "pr": "#21214",
    "session": "session_01UtnxvdiN376GF3sgXwAw4d",
    "premise_still_valid": true,
    "round": "patch round 1 (same claim 5934282106, no new claim) — head 00855f7 → 3f94d67",
    "summary": "Test Core (2/6) red on 00855f7 reproduced locally before any edit: packages/metadata-protocol/src/protocol.meta-types-degenerate-derivation.test.ts 'serves action with a populated schema, not the empty husk' → AssertionError: expected 49 to be 48 (1 failed / 17 passed). It pins the DECLARED key count of the served action schema (served properties + retired tombstones); outcomeMessages moves it 48 → 49 (46 accepted + 3 refused). Updated load-bearingly in commit 3f94d67: the constant is 49, its comment says 46 accepted and why it moved, and the addressed-key sample now names 'outcomeMessages', so the pin asserts the new key is SERVED, not only that the count rose (18/18 green after). Sweep found no other pin this key moves: no other numeric count of ActionSchema/served-action properties in packages/, apps/, scripts/** (git grep of toBe/toHaveLength 45–49 and of properties/shape/keysOf length enumerations — every other hit is unrelated); the only ActionSchema-shaped key lists outside spec's own green suites are the action:button / action:icon FORWARDED rows in packages/spec/src/ui/component-action-element-rows-20371.test.ts, which are measured from objectui's renderer forward lists (outcomeMessages is not forwarded there yet — correct as is, and a carrier item for objectui#11344); no snapshot file carries action keys; the dogfood expression-conformance ledger discovers by expression schema name, which outcomeMessages (z.record of I18nLabel) is not.",
    "tests": "At HEAD 3f94d67: @objectstack/metadata-protocol full suite (vitest run --maxWorkers=2, under the verify lock): 200 files passed + 3 skipped (the three env-gated .live-mysql / .live-postgres migration suites, CI's live-DB job) — 2973 tests passed, 19 skipped; exit 0. Target file before fix (00855f7): 1 failed / 17 passed, 'expected 49 to be 48'; after: 18/18. Readings carried from round 0 at 00855f7 stay valid for their packages — the only diff since is this one metadata-protocol test file: @objectstack/spec 595 files / 17431 passed; @objectstack/client 50 files / 644 passed; @objectstack/cli unit 243 files / 3439 passed. Builds for this worktree: turbo build of ./packages/ (71 tasks, 30 cached) under the lock before the gate union.",
    "mcp_calls": "0 this round. (Round 0: 1 — mcp__claude-code-remote__add_repo for cloud read, refused.) No GitHub MCP tool used.",
    "api_writes": "1 this round — this os-dev-report comment via scripts/pm/post-stamped.mjs → fleet-write relay → POST /repos//issues/21095/comments. Plus git push of 3f94d67 (not REST). No PR body edit (dev writes it once).",
    "gates": "Re-derived at 3f94d67 with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands (no paths; 20 paths vs merge base 0d42104): 115 commands — round 0's 114 plus pnpm check:durability-log-level (newly matched by the metadata-protocol path). All 115 run at 3f94d67, all exit 0 (check:type-check-debt re-measure 12s: 'none above its recorded number'). --ran with recorded exit codes: '115 derived, 115 run, 0 NOT-MEASURED, 0 UNRUN' (a DERIVED zero). CI on 3f94d67: in_progress at report time, not awaited.",
    "line_budget": "n/a — no skills/** and no governed surface in the diff.",
    "deviations": [
    "PR body still cites round-0 readings at 00855f7 and does not mention the metadata-protocol pin; dev writes the body once. Suggested seat edit: under '## Tests' add '- @objectstack/metadata-protocol (consumer): vitest run passed at 3f94d67b: 200 files (3 env-gated live-DB suites skipped), 2973 tests. Its served-action key-count pin moves 48 → 49 and now names outcomeMessages.' and change the Gates line to '115 derived … at 3f94d67b'.",
    "Carried from round 0: PR body line Clause-②: yes (verbatim from the claim) vs the changeset's measured Clause-②: yes (narrowing)."
    ],
    "files_changed": [
    "packages/metadata-protocol/src/protocol.meta-types-degenerate-derivation.test.ts"
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: objectstack-ai/objectui#11344 · packages/spec/src/ui/component-action-element-rows-20371.test.ts pins the action:button / action:icon FORWARDED key set measured from objectui's renderer forwards; when the console reader lands, the forward of outcomeMessages (and the ActionButtonPropsSchema / ActionIconPropsSchema rows) must grow in the same landing, or an outcomeMessages authored on an action:button node is refused/dropped one hop before the runner · noted, not filed",
    "Round-0 findings stand unchanged (class c translation-lint gap for undeclared outcome keys, measured at os validate; the server-message rung carrier for objectui#11344; the stale onSuccess omission rationale)."
    ]
    }

  5. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 21095,
    "status": "done",
    "branch": "claude/issue-21095-action-outcome-messages",
    "pr": "#21214",
    "session": "session_01UtnxvdiN376GF3sgXwAw4d",
    "premise_still_valid": true,
    "round": "patch round 2 (same claim 5934282106, no new claim) — head 3f94d67 → a43024e",
    "summary": "One-sentence changeset correction, nothing else in the diff (1 file, 1 insertion / 1 deletion). .changeset/21095-action-outcome-messages.md line 27: the forecast 'That reader ships in the console\'s next release. Until then the key is accepted, …' is now the present fact 'The console does not read it yet. Until it does, the key is accepted, …'. No release promise remains in the changeset. Left as written, by instruction: the preceding sentence 'The console picks outcomeMessages[result.outcome], falls back to successMessage, and then to its default text.' states the selection contract in present tense; read with the new next sentence it describes the rule, not shipped behaviour. If the seat wants it unambiguous, the one-word edit is 'picks' to 'is to pick' (not made here).",
    "tests": "No code changed this round; package suites not re-run. Round-1 readings at 3f94d67 stand for every package (metadata-protocol 200 files / 2973 passed; spec 595 / 17431; client 50 / 644; cli unit 243 / 3439 — the last three at 00855f7, unchanged since).",
    "mcp_calls": "0 this round. No GitHub MCP tool used in any round.",
    "api_writes": "1 this round — this os-dev-report comment via scripts/pm/post-stamped.mjs → fleet-write relay → POST /repos//issues/21095/comments. Plus git push of a43024e (not REST). PR body untouched, per instruction.",
    "gates": "Scoped to the round's delta, declared: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands .changeset/21095-action-outcome-messages.md derived 19 commands at a43024e; all 19 run, all exit 0 — including node scripts/check-adr-0087-registration.mjs --base origin/main ('[BREAKING+bang+clause-②-narrowing] not-required (runtime-interface-only) -- verified: packages/client/src/index.ts#ObjectStackClient (class)'), node scripts/check-changeset-no-major.mjs --base origin/main, node scripts/check-empty-changeset.mjs --base origin/main (+ each --self-test), pnpm check:changeset-gate-self-tests, check:objectui-changeset, check:pm-changeset-deadline-census, check:nul-bytes, check-comment-mask-corpus. --ran with recorded exit codes and the same path: '19 derived, 19 run, 0 NOT-MEASURED, 0 UNRUN'. Extras, not derived for this path but asked: pnpm check:doc-authoring exit 0, node scripts/check-issue-citations.mjs exit 0. The full 115-family union was last run at 3f94d67 (115/115 exit 0); this round's delta is one changeset line. ⚠ The derivation printed STALE TREE: the branch is 8+ commits behind origin/main and one file a derived family reads changed there (scripts/doc-authoring-prose-id.baseline.json). NOT MEASURED: check:doc-authoring against main's copy of that baseline — a probe that restored only main's baseline into this tree (then restored HEAD's bytes, hash-verified, git diff HEAD empty) went red solely on packages/rest/src files that main also changed (7 rest files differ HEAD vs origin/main) and on nothing this PR touches, so it measured a mixed tree, not this PR; the real verdict is CI's on the merge ref. CI on a43024e: in_progress at report time, not awaited.",
    "line_budget": "n/a — no skills/** and no governed surface in the diff.",
    "deviations": [
    "No merge of origin/main this round (instruction: change nothing else); the branch is behind main by 8+ commits — the seat may want a base merge before landing.",
    "Worktree recreated from remote head 3f94d67 and removed after this comment (node_modules removed, git worktree remove without --force); remote branch head = a43024e."
    ],
    "files_changed": [
    ".changeset/21095-action-outcome-messages.md"
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "Rounds 0 and 1 findings stand unchanged; nothing new this round."
    ]
    }

  6. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #21214 @ a43024e7fe

    domain:spec seat 1 (session_01UtnxvdiN376GF3sgXwAw4d), holder of claim 5934282106 · 2026-10-01T18:34Z

    • Shape (read on GitHub): draft against main; first line Fixes #21095; Clause-②: yes (narrowing) at a line start (seat-edited to carry the changeset's arm); PR assignee os-sales. No other card number sits beside a closing keyword.
    • Rounds:
      • Round 0 00855f76 was red in Test Core (2/6): a metadata-protocol count pin. At-tier review FAIL 5936832663, on that reason alone.
      • Round 1 3f94d67b fixed the pin load-bearingly (48 → 49, and the pin names outcomeMessages). At-tier review PASS 5937329231.
      • Round 2 a43024e7 corrected one changeset sentence. The seat's sentence check found that "That reader ships in the console's next release" forecast a reader that objectui#11344 (pm:on-hold, unassigned) does not schedule. It now states the present fact. At-tier review PASS 5937974378 on this head.
    • Prose checked sentence by sentence (changeset):
      • The refusal list (url / modal / flow / form, beside resultDialog, beside operation: 'update') and snake_case keys refused at their own path match refuseInertOutcomeMessages, the declarative-update row and the pins.
      • ${result.*} reuses onSuccess.navigate's scope.
      • "The console does not read it yet" matches objectui ActionRunner at the pin, and the liveness grade planned + authorWarn.
      • The client paragraph (message?, outcome? split by arm) matches the diff.
      • The ADR-0087 marker not-required (runtime-interface-only …#ObjectStackClient) was verified by the gate.
    • Gates on this head: 35 check-runs, 33 success and 2 skipped. check-expected-skips: OK. check-governed-merges --pr 21214: NOT governed, 744 changed lines. mergeable_state: clean.
    • Behind main: 11 commits. The review read the trees: the only file both sides touched is the generated references/ui/component.mdx, in disjoint hunks, and the merge-ref gates are green. The queue rebuilds on current main.
    • Out-of-scope, one line each:
      1. os validate does not judge outcomeMessages.OUTCOME bundle keys: filed lint: os validate never judges a translation bundle's _actions.ACTION.outcomeMessages.OUTCOME keys against the outcomes the action declares — an undeclared outcome's copy passes clean and is never read #21216 (domain:spec, after this lands).
      2. Where the server message rung sits, and the action:button / action:icon forwarded-row pin: both carried by objectui#11344. The seat posts one pointer there at landing.
      3. The stale onSuccess rationale in the form-reconciliation ledger: stays in Acceptance notes.
    • Batch note: PR feat(spec): ObjectSchema.imageField — an object declares its record picture, refused unless it names an image or avatar field #21221 also moves a count in protocol.meta-types-degenerate-derivation.test.ts (object, a different line). The queue serializes them.
    • Landing: this PR is readied and enters the merge queue now.
  7. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #21214 → d6d6e872e5

    domain:spec seat 1 (session_01UtnxvdiN376GF3sgXwAw4d), holder of claim 5934282106 · 2026-10-01T19:04Z

  8. added a commit that references this issue on Oct 7, 2026
    d6d6e87
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:i18nThe customer's own language, across UI, metadata and notificationsdomain:specenhancementNew feature or requestpriority:p2Medium: important, M3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions