Summary
When req.tenantId is undefined (auth disabled / no master-tenant header), ACP-routed prompt delivery fails with:
ACP session not found in the requested tenant and owner scope: <id>
acpBackend.createSession(...) stores the session under tenantId: req.tenantId ?? SYSTEM_TENANT (= '_system'), but four downstream acpBackend.sendPrompt(...) call sites fall back to the literal 'system'. The lookup misses every time the request doesn't carry an authenticated tenant.
Affected call sites
src/routes/sessions.ts:401 — existing-idle-session prompt
src/routes/sessions.ts:472 — new-session initial prompt
src/routes/session-actions.ts:57 — POST /v1/sessions/:id/send
src/routes/session-actions.ts:275 — POST /v1/sessions/:id/command
Reproduction
- Build:
npm run build
- Start with auth disabled:
AEGIS_DISABLE_AUTH=true node dist/cli.js
POST /v1/sessions with a prompt field → response includes promptDelivery.delivered=false, error: "ACP session not found in the requested tenant and owner scope".
- ACP child process and Claude CLI spawn correctly — only the prompt delivery JSON-RPC fails because the lookup scope doesn't match the create scope.
Fix
Replace the four literal 'system' fallbacks with the existing SYSTEM_TENANT constant so the unauth scope matches the create-time scope.
Verification
Reproduced and validated locally on develop (HEAD 536ff01) with Claude Code 2.1.139. After the fix, both initial prompt and /send follow-up are delivered (delivered: true) and assistant text appears in the JSONL transcript.
Phase / scope
Phase 3.5 — ACP backend migration. Tenant scoping is part of the multi-tenancy primitives. The fix is surgical: 4 swaps + 1 missing import.
Summary
When
req.tenantIdis undefined (auth disabled / no master-tenant header), ACP-routed prompt delivery fails with:acpBackend.createSession(...)stores the session undertenantId: req.tenantId ?? SYSTEM_TENANT(='_system'), but four downstreamacpBackend.sendPrompt(...)call sites fall back to the literal'system'. The lookup misses every time the request doesn't carry an authenticated tenant.Affected call sites
src/routes/sessions.ts:401— existing-idle-session promptsrc/routes/sessions.ts:472— new-session initial promptsrc/routes/session-actions.ts:57—POST /v1/sessions/:id/sendsrc/routes/session-actions.ts:275—POST /v1/sessions/:id/commandReproduction
npm run buildAEGIS_DISABLE_AUTH=true node dist/cli.jsPOST /v1/sessionswith apromptfield → response includespromptDelivery.delivered=false, error: "ACP session not found in the requested tenant and owner scope".Fix
Replace the four literal
'system'fallbacks with the existingSYSTEM_TENANTconstant so the unauth scope matches the create-time scope.Verification
Reproduced and validated locally on
develop(HEAD536ff01) with Claude Code2.1.139. After the fix, both initial prompt and/sendfollow-up are delivered (delivered: true) and assistant text appears in the JSONL transcript.Phase / scope
Phase 3.5 — ACP backend migration. Tenant scoping is part of the multi-tenancy primitives. The fix is surgical: 4 swaps + 1 missing import.