fix(workspace): nest new workspaces under sole root when no platform-agent (core#2697) #2783
Reference in New Issue
Block a user
Delete Branch "fix/new-workspace-parent-fallback"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Bug (CTO-reported)
New workspaces are created at bare org root instead of under the org's root agent. Confirmed on JRS: its only workspace is the SEO Agent (
kind=workspace,parent_id=NULL) — there is nokind='platform'concierge.Root cause
Createdefaultsparent_idviaplatformRootWorkspaceID, which resolves only when exactly onekind='platform'workspace exists. JRS has zero → it returns""→ new workspaces land atparent_id NULLas bare-root siblings of the SEO Agent.approval_gate/discoverywalk theparent_idchain treating each NULL-parent row as its own org root → broken hierarchy + delegation routing (exactly the issue flagged).Fix
defaultCreateParentID: (1) platform-agent root if exactly one (unchanged intent, core#2609); (2) fallback — the SOLE non-removed root workspace when no platform-agent exists; (3)""otherwise (preserves multi-root bootstrap/self-host). New workspaces now nest under the org's de-facto root agent. Tests cover all three branches.Durable follow-up (NOT in this PR — needs operator action / your call)
InstallPlatformAgentalready does this transactionally; it mutates live tenant data so it's left for explicit operator action.🤖 Generated with Claude Code
REQUEST_CHANGES on head
63eaadb5.Correctness blocker: the implementation falls back after
platformRootWorkspaceID(ctx)returns empty, but that helper returns empty for two different cases: no platform workspace, and ambiguous multiple platform workspaces. The PR states the fallback is only for the no-platform-agent case. Today, if the DB has multiple non-removedkind='platform'rows but exactly one non-removed root row,defaultCreateParentIDwill silently choose that sole root instead of preserving the existing ambiguous-platform fail-soft behavior.That matters because the old helper intentionally treated multiple platform agents as ambiguous and left
parent_idunset rather than guessing. The new code should distinguish zero platform agents from >1 platform agents before applying the sole-root fallback. A small helper/query that returns platform count plus id, or a dedicatednoPlatformAgentbranch, would keep the JRS fix while preserving multi-platform ambiguity. Please add a regression for “multiple platform agents, one root” returning empty.The sole-root fallback itself is the right shape for the JRS zero-platform case, and the existing tests cover platform precedence / zero-platform sole-root / multi-root ambiguity. But they do not cover the >1-platform ambiguity that this change can now mask.
CI note:
E2E API Smoke Testis also red on this head at review time, so this cannot be approved under the requested CI gate even without the correctness issue. Security/performance/readability otherwise look acceptable for the narrow fallback.REQUEST_CHANGES on head
c28e4004.The ambiguity blocker from #11497 is fixed:
defaultCreateParentIDnow directly queries up to two platform agents, returns the sole platform root when exactly one exists, returns empty for >1 platform rows, and only runs the sole-root fallback in the zero-platform case. The added multi-platform regression covers the case I flagged.Current blocker is required CI/code hygiene:
CI / Platform (Go)is red because golangci-lint reportsinternal/handlers/platform_agent.go:213:6: func platformRootWorkspaceID is unused. That is directly caused by replacing the Create call site withdefaultCreateParentID. Please either remove the now-unused helper or keep it used in a way that preserves the intended semantics, then rerun CI.I also saw
E2E API Smoke Testred on this head, but the immediate actionable code issue is the unused helper that makes the required Go lane fail. I can approve once the current head is code-clean and CI/all-required is green.REQUEST_CHANGES on head
c28e4004a1d5bf53f95ce16339f1437bc3fb7b52.The 0/1/>1 platform-root split itself is the right shape:
defaultCreateParentIDreturns the single platform root, returns empty for multiple platform agents without falling through to root lookup, and only uses the sole-root fallback in the zero-platform case (workspace-server/internal/handlers/platform_agent.go:253). The regression test covers the multi-platform no-root-fallback path (workspace-server/internal/handlers/platform_agent_test.go:687).Blocking findings:
CI / Platform (Go)is failing on this head because the old helper is now unused afterCreateswitched todefaultCreateParentID:workspace-server/internal/handlers/platform_agent.go:213:6: func platformRootWorkspaceID is unused. This is a code-gate failure, not a review-gate artifact, andCI / all-requiredis skipped as a result.E2E API Smoke Testis also failing in the channels prune lane:FAIL: purge over-reached: sibling data did not survive. The test creates no-parent workspaces and then expects the second workspace to remain a sibling when the first is purged (tests/e2e/test_channels_e2e.sh:442). With the new sole-root fallback, the second no-parent create can be nested under the first sole root, so the test's sibling assumption is no longer stable. Either the e2e fixture needs explicit hierarchy for its sibling invariant, or the fallback needs narrowing if this nesting is not intended for that path.Please fix the unused helper and resolve the E2E API Smoke failure, then rerun required CI including Platform Go, E2E API Smoke, staging Platform Boot, and
CI / all-required.APPROVED on head
77febde919d34558b9e8207518b3890468090b08.Re-verified my prior blockers on the current head:
platformRootWorkspaceIDis gone,defaultCreateParentID+queryUpToTwoIDsare the active path, andCI / Platform (Go)is green.test_channels_e2e.shnow creates an explicit common parent (e2e-chan-parent-$$) and nests target+sibling under it, so the target purge no longer depends on the no-parent sibling invariant that core#2697 intentionally changed.CI checked on this head:
CI / all-required, Platform Go, Shellcheck, E2E API Smoke, local-provision stub, and local-provision real-image advisory are green. Remaining review/ceremony reds are stale/missing-review gates that this approval should clear, not code failures.SOP ACK: reviewed correctness, regression coverage, CI, security/no data exposure, and operational risk.