diff --git a/docs/superpowers/specs/2026-05-28-l1-workspace-phase-1-acceptance.md b/docs/superpowers/specs/2026-05-28-l1-workspace-phase-1-acceptance.md index 2a2baeb3..462ea60c 100644 --- a/docs/superpowers/specs/2026-05-28-l1-workspace-phase-1-acceptance.md +++ b/docs/superpowers/specs/2026-05-28-l1-workspace-phase-1-acceptance.md @@ -280,3 +280,92 @@ See spec §13 "Out of scope (v1 non-goals)" for the full non-goals list and spec --- *Report generated by T26 acceptance validation pass, 2026-05-28.* + +--- + +## Post-Final-Review Fixes Addendum + +All 5 issues surfaced by the final code review were addressed in individual commits on +`2026-05-28`. Details below. + +--- + +### Fix 1 — `audit_logs.acting_as` at L1 terminal events (Important) + +**Issue:** Per spec §5.6.1, audit rows must be written at session terminal events +(resolve, escalate). No rows were being written for L1 actions at all. + +**Changes:** +- `/backend/app/core/audit.py` — `log_audit` gains optional `acting_as: str | None` + parameter, passed through to the `AuditLog` row. +- `/backend/app/services/l1_session_service.py` — `resolve()`, `escalate()`, and + `escalate_without_walk()` each call `log_audit` before/after their `db.flush()`, + writing rows with `action=l1.session.resolve|escalate|escalate_no_walk` and + `acting_as` from the session. +- `/backend/tests/test_l1_session_service.py` — 4 new integration tests: + `test_resolve_writes_audit_log_with_acting_as`, + `test_resolve_writes_audit_log_native_l1_acting_as_null`, + `test_escalate_writes_audit_log`, + `test_escalate_without_walk_writes_audit_log`. + +**Commit:** `a5f4c16` + +--- + +### Fix 2 — Session-ownership policy documented in `_get_session_or_404` (Important) + +**Issue:** Policy that sessions are account-scoped (not user-scoped) was implicit. + +**Change:** Docstring added to `_get_session_or_404` in +`/backend/app/api/endpoints/l1.py` explaining the Phase 1 account-scoped policy per +spec §7.9, and noting where to tighten to creator-only if needed. + +**Commit:** `939b827` + +--- + +### Fix 3 — Router placement comment (Minor) + +**Issue:** L1 router mounted under `_tenant_deps` without explanation. + +**Change:** Two-line comment added in `/backend/app/api/router.py` above the +`l1.router` include, explaining that L1 uses seat-based gating rather than +`require_active_subscription`. + +**Commit:** `01ab52d` + +--- + +### Fix 4 — Toast on intake failure in L1Dashboard (Minor) + +**Issue:** `handleStart` in `L1Dashboard.tsx` swallowed errors silently. + +**Change:** `catch (err)` block added that surfaces a toast with the backend +`detail` string, falling back to a generic message. Import of `toast` from +`@/lib/toast` added. + +**Commit:** `c803fcc` + +--- + +### Fix 5 — 402 seat-limit handler on invite (Minor) + +**Issue:** `accountsApi.createInvite` 402 response was handled by the generic +`toast.error('Failed to send invitation')` branch — no seat count info surfaced. + +**Change:** `/frontend/src/pages/AccountSettingsPage.tsx` `handleInvite` catches +HTTP 402 with `detail.code === 'seat_limit_exceeded'` and shows a warning toast +with the role label and `current/limit` counts. Generic error path retained for +all other failures. + +**Commit:** `a762a5c` + +--- + +## Validation results (post-fix) + +| Check | Result | +|---|---| +| `pytest --override-ini="addopts=" -n auto` | 1329 passed (was 1325; +4 audit tests) | +| `npx tsc -b` | clean (no output) | +| `npm run build` | clean, built in ~74s |