diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md
index eef963f..5a2f236 100644
--- a/.planning/ROADMAP.md
+++ b/.planning/ROADMAP.md
@@ -103,12 +103,13 @@ Plans:
3. A template-deployed agent is immediately functional — responds in connected channels with the template's persona, tools, and escalation rules
4. The wizard and templates are accessible to both platform admins and customer admins (respecting RBAC)
5. Created agents appear in the Agent Designer for further customization after initial setup
-**Plans**: 3 plans
+**Plans**: 4 plans
Plans:
- [ ] 05-01-PLAN.md — Backend: AgentTemplate model, migration 007 with 7 seed templates, template list/deploy API, system prompt builder, unit + integration tests
- [ ] 05-02-PLAN.md — Frontend: three-option entry screen, template gallery with one-click deploy, 5-step wizard (Role/Persona/Tools/Channels/Escalation), Advanced mode relocation
- [ ] 05-03-PLAN.md — Human verification: test all three creation paths, RBAC enforcement, system prompt auto-generation
+- [ ] 05-04-PLAN.md — Gap closure: add /agents/new to proxy RBAC restrictions, hide New Employee button for operators, fix wizard deploy error handling
## Progress
@@ -121,7 +122,7 @@ Phases execute in numeric order: 1 -> 2 -> 3 -> 4 -> 5
| 2. Agent Features | 6/6 | Complete | 2026-03-24 |
| 3. Operator Experience | 5/5 | Complete | 2026-03-24 |
| 4. RBAC | 3/3 | Complete | 2026-03-24 |
-| 5. Employee Design | 3/3 | Complete | 2026-03-25 |
+| 5. Employee Design | 3/4 | Gap Closure | 2026-03-25 |
---
diff --git a/.planning/phases/05-employee-design/05-04-PLAN.md b/.planning/phases/05-employee-design/05-04-PLAN.md
new file mode 100644
index 0000000..df6fb12
--- /dev/null
+++ b/.planning/phases/05-employee-design/05-04-PLAN.md
@@ -0,0 +1,182 @@
+---
+phase: 05-employee-design
+plan: 04
+type: execute
+wave: 1
+depends_on: []
+files_modified:
+ - packages/portal/proxy.ts
+ - packages/portal/app/(dashboard)/agents/page.tsx
+ - packages/portal/components/wizard-steps/step-review.tsx
+autonomous: true
+gap_closure: true
+requirements: [EMPL-04]
+
+must_haves:
+ truths:
+ - "customer_operator is redirected away from /agents/new (and all sub-paths) by proxy.ts before reaching creation UI"
+ - "customer_operator does not see the New Employee button on the agents list page"
+ - "Wizard deploy failure displays a visible error message to the user"
+ artifacts:
+ - path: "packages/portal/proxy.ts"
+ provides: "RBAC redirect for /agents/new paths"
+ contains: "/agents/new"
+ - path: "packages/portal/app/(dashboard)/agents/page.tsx"
+ provides: "Role-gated New Employee button"
+ contains: "useSession"
+ - path: "packages/portal/components/wizard-steps/step-review.tsx"
+ provides: "Visible error handling on deploy failure"
+ key_links:
+ - from: "packages/portal/proxy.ts"
+ to: "CUSTOMER_OPERATOR_RESTRICTED"
+ via: "/agents/new added to restricted array"
+ pattern: '"/agents/new"'
+ - from: "packages/portal/components/wizard-steps/step-review.tsx"
+ to: "error UI div"
+ via: "re-thrown error sets createAgent.isError"
+ pattern: "throw"
+---
+
+
+Close two verification gaps from Phase 5 Employee Design:
+
+1. Frontend RBAC gap: customer_operator can navigate to /agents/new and sub-paths (proxy.ts missing restriction) and sees the New Employee button (no role guard)
+2. Wizard deploy error handling: catch block swallows errors so the error UI never renders
+
+Purpose: Complete EMPL-04 compliance (RBAC-enforced access) and fix silent deploy failure UX
+Output: Three patched files — proxy.ts, agents/page.tsx, step-review.tsx
+
+
+
+@/home/adelorenzo/.claude/get-shit-done/workflows/execute-plan.md
+@/home/adelorenzo/.claude/get-shit-done/templates/summary.md
+
+
+
+@.planning/PROJECT.md
+@.planning/ROADMAP.md
+@.planning/STATE.md
+@.planning/phases/05-employee-design/05-VERIFICATION.md
+
+
+
+
+From packages/portal/proxy.ts (line 23):
+```typescript
+const CUSTOMER_OPERATOR_RESTRICTED = ["/billing", "/settings/api-keys", "/users", "/admin"];
+```
+
+From packages/portal/app/(dashboard)/agents/page.tsx (line 74):
+```typescript
+
+```
+
+From packages/portal/components/wizard-steps/step-review.tsx (lines 28-53):
+```typescript
+const handleDeploy = async () => {
+ try {
+ const agent = await createAgent.mutateAsync({
+ tenantId,
+ data: { /* ... */ },
+ });
+ router.push(`/agents/${agent.id}?tenant=${tenantId}`);
+ } catch (err) {
+ console.error("Failed to deploy agent:", err);
+ }
+};
+```
+
+Error display div (lines 141-145):
+```typescript
+{createAgent.error && (
+
+
{createAgent.error.message}
+
+)}
+```
+
+Session pattern used in portal:
+```typescript
+import { useSession } from "next-auth/react";
+const { data: session } = useSession();
+const role = (session?.user as { role?: string })?.role;
+```
+
+
+
+
+
+
+ Task 1: Add /agents/new to proxy RBAC restrictions and hide New Employee button for operators
+ packages/portal/proxy.ts, packages/portal/app/(dashboard)/agents/page.tsx
+
+1. In proxy.ts, add "/agents/new" to the CUSTOMER_OPERATOR_RESTRICTED array (line 23). The existing startsWith check on line 59 already handles sub-paths, so adding "/agents/new" will automatically block /agents/new/templates, /agents/new/wizard, and /agents/new/advanced.
+
+2. In agents/page.tsx, add role-based visibility to the New Employee button:
+ - Import useSession from "next-auth/react"
+ - Get session via useSession() hook
+ - Extract role: `const role = (session?.user as { role?: string })?.role`
+ - Wrap the New Employee Button in a conditional: only render when role is "platform_admin" or "customer_admin" (i.e., hide when role is "customer_operator" or undefined)
+ - Use: `{role && role !== "customer_operator" && (
+
+ cd /home/adelorenzo/repos/konstruct/packages/portal && grep -q '"/agents/new"' proxy.ts && grep -q 'useSession' app/\(dashboard\)/agents/page.tsx && echo "PASS"
+
+ customer_operator is redirected by proxy.ts when navigating to /agents/new or any sub-path; New Employee button is hidden for customer_operator role
+
+
+
+ Task 2: Fix wizard deploy error handling to surface errors to user
+ packages/portal/components/wizard-steps/step-review.tsx
+
+In step-review.tsx, fix the handleDeploy catch block (lines 50-52) to re-throw the error so TanStack Query's mutateAsync sets the mutation's isError/error state. This allows the existing error display div at lines 141-145 to render.
+
+Change the catch block from:
+```typescript
+} catch (err) {
+ console.error("Failed to deploy agent:", err);
+}
+```
+
+To:
+```typescript
+} catch (err) {
+ console.error("Failed to deploy agent:", err);
+ throw err;
+}
+```
+
+This is the minimal fix. The mutateAsync call throws on error; catching without re-throwing prevents TanStack Query from updating mutation state. Re-throwing lets createAgent.error get set, which triggers the existing error div to display.
+
+Do NOT add useState for local error handling — the existing createAgent.error UI is correctly wired, it just never receives the error.
+
+
+ cd /home/adelorenzo/repos/konstruct/packages/portal && grep -A2 'catch (err)' components/wizard-steps/step-review.tsx | grep -q 'throw err' && echo "PASS"
+
+ Deploy failures in wizard now surface error message to user via the existing error display div; createAgent.isError becomes true on failure
+
+
+
+
+
+1. grep for "/agents/new" in CUSTOMER_OPERATOR_RESTRICTED array in proxy.ts
+2. grep for useSession import in agents/page.tsx
+3. grep for "throw err" in step-review.tsx catch block
+4. Confirm no other files were modified
+
+
+
+- proxy.ts CUSTOMER_OPERATOR_RESTRICTED includes "/agents/new"
+- agents/page.tsx New Employee button conditionally rendered based on session role
+- step-review.tsx catch block re-throws error so mutation error state is set
+- All three changes are minimal, surgical fixes to close the two verification gaps
+
+
+