Root cause: the 2026-09-28 controlled-projection hardening added the
ErrUnboundControlledProject guard, and the server path got session project
binding backfilled - but two paths missed:
- CLI chat mode never called session.SetProjectID (only -project name)
- coordinator handleAdvanceStage built StageRunRequest without
ProjectID/UserID, so every stage-advance squad task was rejected
Fixes:
- handleChatMode gains projectID param (wired from -project-id flag);
session binding follows the server convention
- handleAdvanceStage passes parseDecimalID(UserCtx.Project/User.ID)
- CLI chat tests get hermetic env (unreachable DB + ALLOW_IN_MEMORY) so
local runs stop accidentally hitting the real dev DB on :5433
- stale test TestBindSessionProjectContext_KeepsExistingProjectID asserted
the pre-fix 'switch does not propagate' bug; updated to assert switch
propagation + bind no-overwrite
Result: go test -short ./... = 75 packages, 0 failures (first time).
Short tests promoted from report-only back into the required CI gate.
Coordinator now takes a StageTaskRunner and injected context/KB ports.
Chatflow assembler reads maturity tokens instead of the orchestration root.
Co-authored-by: Cursor <cursoragent@cursor.com>
Move construction and document OnOutbox out of server, give HTTP/CLI a shared task use case, and block already-cleared import/event arch rules.
Co-authored-by: Cursor <cursoragent@cursor.com>
Unify auth middleware and remove X-User-ID trust, add project_members
authorization, sandbox workspaces via resolver, and admin-only reconcile
by run_id. Introduce goose migrations with startup schema gate, fail closed
when DB unavailable outside explicit ALLOW_IN_MEMORY, bundle web/dist in
app Dockerfile, and remove frontend pseudo-login fallback.