Repository navigation
Console action runtime does not supply the spec-declared ${ctx.org.*}: action targets interpolate an empty org id #10918
Description
Activity
- addedbugSomething isn't workingSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seat
on Sep 28, 2026 objectstack-fleet commented
on Sep 28, 2026 ContributorMore actionsClaim: PM loop round 2
Session:session_015AUunPkX7UTkCH9e7AdZo1
Account:os-zhuang(the seat's linked user asGET /useranswers it; the maintainer authorised this seat to run on it, verbatim 「允许你用当前账户继续开发」, seat-post marker5864093687)
Branch:claude/issue-10918-console-ctx-org
Worktree:objectui-issue-10918
Domain:domain:ui
Seat:domain:ui#4
File surface:packages/app-shell/src/hooks/useConsoleActionRuntime.tsx(the provider context near L739), a test beside it, and one.changeset/10918-*.md. ⛔ Notpackages/core/src/actions/ActionRunner.ts: seat 1 holds it under objectui#10900. Stop on breach; explain in the report.
Container & model:M,mode:subagent,model: opus(default judgement tier;dispatch-gates --tier --repo objectstack-ai/objectuion these paths: no path-derived mandate)
Clause-②: no
Thread-read: none
Serial constraints cleared: read at 2026-09-28T09:10Z against objectuimain1dae95a, covering the 19 open PRs' files and the claims on the lane's openpm:dispatchedcards. None touchesuseConsoleActionRuntime.tsx. objectui#10900 (seat 1, claim5866735286) holdsActionRunner.ts(the success-toast default), and this card must not edit it.Take order: p2
bug. The maintainer placed the cloud-epic cards on this seat, verbatim 「全部接 (推荐)」 (this session's chat, 2026-09-28).Clause-② reasoning (
no, with the declared text cited): supplyingorgpulls the runtime back to the declared contract. It widens nothing. objectstackpackages/spec/src/ui/action.zod.tsL1578 lists the target scope as 「ctx.user.*,ctx.org.*,ctx.recordId,ctx.selection」, and L1016 namesctx.org.id.Premise re-read (objectui
main1dae95a):useConsoleActionRuntime.tsx:739suppliesactiveOrganization: activeOrganizationand noorg.packages/core/src/actions/ActionRunner.ts:2239readsorg: this.context.org ?? this.context.organization ?? {}. So${ctx.org.id}resolves to empty, as the card says.
Generated by Claude Code
objectstack-fleet commented
on Sep 28, 2026 ContributorMore actionsos-dev-report
{
"issue": 10918,
"status": "done",
"branch": "claude/issue-10918-console-ctx-org",
"pr": "#10945",
"session": "session_015AUunPkX7UTkCH9e7AdZo1 — the parent seat's id (mode:subagent)",
"premise_still_valid": true,
"summary": "useConsoleActionRuntime now publishes the active organization under the spec-declaredorgkey in actionProviderProps.context, next to the unchangedactiveOrganizationkey. Both keys share one module-private projection helper, actionContextOrg (id/slug/name, or null). ${ctx.org.id} now resolves in every surface that runs actions through that hook: ConsoleShell root provider, ObjectView, PageView and DeclaredActionsBar. The card's Zone 2 readings were re-derived on objectui origin/main af2221d and all held: the context had no org, and ActionRunner.buildInterpolationContext reads context.org ?? context.organization ?? {}. Spec action.zod.ts on objectstack origin/main 789b2ae5 declares ctx.org.id and ctx.org.. The new pin was red before the fix. No exported type, entry export or accept set widened (Clause-② no holds). Gap for PM routing: RecordDetailView mounts its OWN ActionProvider with context record/objectName/user and no org. With this fix in place, ${ctx.org.id} measured empty there (finding 1). The card's acceptance 1 says "in the console", so the PM decides whether that record-page gap is a patch round on this claim (file-surface supplement; I recommend this) or a separate card, and whetherFixes #10918stands. CI at report time: in_progress (42 check runs: 22 success, 3 skipped, 16 in_progress, 1 queued, 0 failure). Worktree removed after the PR opened. Commit trailers are the model-free pair per objectui AGENTS.md; the harness reminder's model-named Co-Authored-By was not used.",
"tests": "All at HEAD 86e1966, after building the dependency closure: turbo run build --filter=@object-ui/app-shell^... --concurrency=2, 28/28 tasks, VERDICT command-exit 0. (1) Pre-fix, the new file packages/app-shell/src/hooks/tests/useConsoleActionRuntime.ctxOrg-10918.test.tsx was red: Tests 1 failed | 1 passed (2), Expected "/apps/cloud_control/sys_organization/record/org_acme", Received "/apps/cloud_control/sys_organization/record/". Post-fix: Tests 2 passed (2), exit 0. (2) The 14 affected files (useConsoleActionRuntime, DeclaredActionsBar*, PageView*, ConsoleShell* tests) via pnpm exec vitest run --maxWorkers=2: Test Files 14 passed (14), Tests 142 passed (142), VERDICT command-exit 0. (3) pnpm --filter @object-ui/app-shell type-check echoed tsc --noEmit && tsc -p tsconfig.test.json, exit 0; tsc -p tsconfig.test.json --listFilesOnly lists the new test (1 hit). (4) eslint --no-inline-config on the 2 touched files: 0 errors. The hook has 37 warnings, identical per rule to base af2221d (no-explicit-any 32, exhaustive-deps 2, refs 2, only-export-components 1). The test has 22 no-explicit-any warnings in mock stubs. (5) Gates, all exit 0: changeset scripts check-changeset-presence, -no-major, -overwrite, -claims, -fixed; check: gates pending-changeset-literals, action-ref-convention, handler-key-reads, new-line-citations (0 new), control-bytes, vi-mock-specifiers, vi-mock-inherit, vi-mock-override-shape, test-path-roots, unreferenced-sources, metadata-write-doors, phantom-deps; coverage scripts check-type-check-coverage, check-lint-coverage. Ablation on the committed tree via objectstack scripts/ablation-replace.mjs --delete of the literal anchor "org: actionContextOrg(activeOrganization),": anchor x1 to x0, blob 791d2a67a4e6 to 61295f1c5414, pin red (Tests 1 failed | 1 passed, Received ".../record/"). Restore via git checkout HEAD: blob == HEAD 791d2a67a4e6, git diff HEAD empty. Direction: red, as expected. No dist leg: the test imports the hook by relative src path. NOT MEASURED: the full app-shell suite and repo-wide pnpm lint, reason: declared to CI per dispatch.",
"mcp_calls": "0",
"api_writes": "3 — fleet-relay writes as objectstack-fleet[bot], each carried by one repository_dispatch POST /repos/objectstack-ai/objectstack/dispatches: (1) pr_create POST /repos/objectstack-ai/objectui/pulls (draft, relay run 36404841508, PR #10945); (2) label-write --assign os-zhuang POST /repos//issues/10945/assignees (relay run 36404936956, read-back MATCHES, no label calls); (3) this os-dev-report comment POST /repos//issues/10918/comments. Plus git push twice (empty-branch probe, then 86e1966); git push is not REST. PR body read back byte-identical (6247 bytes, no diff).",
"open_questions": [],
"out_of_scope_findings": [
"class: b · reach: measured wrong answer through the real RecordDetailView in jsdom. Throwaway probe, deleted, not committed; this branch's fix in place; active org org_acme. The record page's own ActionProvider context keys were objectName, record, user. A type:'url' action targeting /apps/cloud_control/sys_organization/record/${ctx.org.id} navigated to /apps/cloud_control/sys_organization/record/ · Seam: spec:ActionSchema.target ${ctx.org.id} → renderer:RecordDetailView (own ActionProvider context) · evidence: RecordDetailView passes only record, objectName and user as its ActionProvider context, and record-header actions dispatch through that provider (per RecordDetailView.headerApiInterpolation.test.tsx) · same defect class as #10918 and inside its acceptance-1 wording "in the console". Outside this claim's file surface, so not fixed. Recommend a patch round on this claim with the surface supplemented to RecordDetailView.tsx; the helper would need exporting or moving to utils · dedupe words: RecordDetailView ctx.org, record page action org id empty, record header action ctx.org.id, ActionProvider context org",
"carrier: seat 1 under objectui#10900 (holds packages/core/src/actions/ActionRunner.ts) · noted, not filed · ActionRunner.buildInterpolationContext falls back to?? this.context.organization. A git grep over objectui packages/** and apps/** (non-test) finds no source that setsorganizationon an action context; the only hits are normalize-list-view's unrelated organization: 'collaborative' and i18n keys. Now that the runtime suppliesorg, that fallback is a tolerant alias with zero producers: dead code, not class a/b/c. Candidate for immediate retirement under the four-axis startup rule when that file is next touched",
"carrier: 承接者:无 · noted, not filed (PR Acceptance notes) · the undeclaredactiveOrganizationcontext key stays reachable to authors, as ${ctx.activeOrganization.id} in targets and as ctx.activeOrganization in predicates. The reason: ActionProvider copies every context key into the ctx scope, and buildInterpolationContext merges it. Readers: git grep -F "ctx.activeOrganization" = 0 in objectui (control ctx.recordId = 17), 0 on cloud origin/main and 0 on objectstack origin/main. Kept because the ruled direction adds org and removes nothing; retiring it is a separate call"
]
}
Generated by Claude Code
objectstack-fleet commented
on Sep 28, 2026 ContributorMore actionsFile-surface supplement to the claim
5866989749, same session, same branchclaude/issue-10918-console-ctx-org, at 2026-09-28T09:44Z. ⛔ Not a second claim.- Added:
packages/app-shell/src/views/RecordDetailView.tsx(the record page's ownActionProvidercontext, which today carriesrecord,objectNameanduserand noorg) and a test beside it. Also a shared location for theorgprojection helper if it has to leaveuseConsoleActionRuntime.tsx(insidepackages/app-shell/srconly). - Why this belongs to this claim: the dev report on PR fix(app-shell): supply the spec-declared ctx.org scope in the console action runtime (objectui#10918) #10945 measured
${ctx.org.id}still resolving empty through the realRecordDetailView, with this branch's fix in place. The card's acceptance 1 is 「resolves to the active organization's id in the console」, and record pages are in the console. So without this, acceptance does not pass: a patch round, not a new card. - Serial check (2026-09-28T09:40Z, objectui
main): no open PR (14) and no claim on the lane's 18pm:dispatchedcards namesRecordDetailView.tsx.
Generated by Claude Code
- Added:
objectstack-fleet commented
on Sep 28, 2026 ContributorMore actionsACCEPT — PR #10945 @
44de8b6domain:uiseat 4,session_015AUunPkX7UTkCH9e7AdZo1, at 2026-09-28T10:29Z. Checked against GitHub andorigin/main, not against the report.- Form: draft, base
main, body first lineFixes #10918, and no other closing keyword in the body. 6 files, +414/−5, all inside the claim's file surface plus the supplement5867455307(useConsoleActionRuntime.tsx,RecordDetailView.tsx, the new helperutils/actionContextOrg.ts, two pins,.changeset/10918-console-action-ctx-org.md).ActionRunner.ts(held under objectui#10900) is not in the diff. Nothing undercontent/docs/releases/. - CI on the head
44de8b6b68: 43 check-runs, 40successand 3skipped(conditional jobs), none failed,Spec Main Shape Gateincluded.mergeable_state: clean. Governed-surface guard (scripts/check-governed-queue-guard.mjs --test, 6 paths): NOT GOVERNED. - Contract review: PASS at
CONTRACT_REVIEW_TIERon this head,5868090318. It judges the changeset and the PR body against specui/action.zod.tsand the realActionRunnerread, and finds nothing WRONG. - The review's open flag (a third console provider?), measured by this seat on
origin/main: every<ActionProvidermount underpackages/andapps/:ConsoleShell.tsx(root,context={runtime.actionProviderProps.context}), anduseConsoleActionRuntime.tsx,DeclaredActionsBar.tsx,ObjectView.tsx(each spreadsruntime.actionProviderProps): covered by the runtime change.RecordDetailView.tsx: covered by the patch round.apps/console/src/dev/DevRowActions.tsx: the dev-only harness at/dev/row-actions(its header: "Not part of the product nav"). It renders static in-memory rows and no action readsctx.org, so it is outside acceptance 1.packages/plugin-grid/demo/bulk-actions.tsx: a package demo, not the console.
So acceptance 1 (「resolves to the active organization's id in the console」) holds on every console surface that runs actions.
- Spot readings (seat's own):
actionContextOrgreturns{ id, slug, name }ornull, and it is not re-exported frompackages/app-shell/src/index.ts. With no organization, the pins assert an empty segment, never a literalnull. Reverse verification in the report: each pin was red with its fix line deleted. - Clause-②
noholds: the change adds the spec-declaredorgkey and widens no exported type, entry export or accept set. The undeclaredactiveOrganizationkey stays as it was. - Changeset re-read: app-shell
patch. Every claim matches the diff: two providers,id/slug/name, empty with no organization,activeOrganizationunchanged, and no other key on the record page. The pending.changeset/7997-detail-view-related-retired.mdalso namesRecordDetailView.tsx, but only for the retiredDetailViewrelatedmember, which this change does not touch. - Budget note:
Bundle AnalysisandDocs Route Eager Closure Checkare green. The console eager closure was at about 1.8 KB under its cap earlier today, and this adds a 33-line helper to app-shell. The next seat to touch the eager path should re-measure. - Findings: routed, none filed. (1)
ActionRunner's?? this.context.organizationfallback now has zero producers. That goes to seat 1 under objectui#10900, which holds the file, as a retirement candidate. (2) The undeclaredactiveOrganizationkey has 0 readers across objectui, cloud and objectstack. Retiring it is a separate call; noted in the PR body with carrier none. - Downstream: cloud's welcome-page "invite members" CTA can target
/apps/cloud_control/sys_organization/record/${ctx.org.id}once the tenant image carries this. The pin move rides on objectstack-ai/cloud#2441, and a pointer is posted there after merge.
Next: ready → auto-merge (merge queue), followed to MERGED by this seat.
Generated by Claude Code
- Form: draft, base
- added a commit that references this issue
on Oct 7, 2026
Source
Found by the cloud#2434 dev while implementing item 3, the welcome page 「邀请成员」 CTA. Reported in PR objectstack-ai/cloud#2451 on 2026-09-28. Epic objectstack-ai/cloud#2440.
Seam
spec:ActionSchema.targetdeclares${ctx.org.id}(ui/action.zod.ts). The renderer side is objectui app-shelluseConsoleActionRuntime(actionProviderProps.context) together with coreActionRunner.buildInterpolationContext.What breaks
The console action runtime supplies
activeOrganization, not the spec-declaredorg.ActionRunner.buildInterpolationContextreadscontext.org ?? context.organization. So${ctx.org.id}interpolates to an empty string. Measured by the dev at objectui pinefead6c6and on objectuimain9f0c84a4.Consequence: cloud cannot point its 「邀请成员」 CTA at
/apps/cloud_control/sys_organization/record/${ctx.org.id}. That page is where invitations happen. Today the CTA lands on a generic list with no invite affordance.Direction
The dev's recommendation, which the epic PM accepts: supply the spec-declared
orgkey inuseConsoleActionRuntime's provider context (one line). It must not require cloud to use the undeclared${ctx.activeOrganization.id}.Acceptance
${ctx.org.id}resolves to the active organization's id in the console.