Skip to main content

What does success look like — in terms anyone can explain without reading the spec?

OUTCOME MAP: IDENTITY & ACCESS
════════════════════════════════════════════════════════════

DESIRED OUTCOME
Every user lands in the right org with the right
permissions — no lockouts, no data leakage, no
manual DB intervention to onboard a customer.

├── Contributing Factors
│ ├── Authentication solid — Clerk middleware + ClerkAuthAdapter 3-layer validation working
│ ├── Multi-tenancy schema complete — all business tables FK to org_organisation
│ ├── Identity resolution working — ExternalAuthId → SystemUserId → OrganisationId
│ ├── Auto-provisioning exists — user + "Personal Workspace" org created on first login
│ ├── PolicyEngine built — canI() method, governance tables, role-permission join all exist
│ └── 80% of infrastructure already built — gap is wiring, not architecture

├── Obstacles
│ ├── PostgreSQL 22P02 — User-Role query passes Clerk userId (string) where UUID expected
│ │ → Fix the query to use systemUserId, not Clerk userId
│ ├── Infinite redirect loop — /dashboard → /sign-in → /dashboard every 400ms (789 errors/30min)
│ │ → Show error page on access denied, not redirect to sign-in
│ ├── No role seed data — governance_user_roles table empty, roles can't be assigned
│ │ → Seed Admin/Member/Viewer roles on deploy
│ ├── defaultAllow: true — PolicyEngine bypasses all permission checks
│ │ → Switch to defaultAllow: false after roles seeded and assigned
│ └── No invite flow — users can only self-provision, no way to join existing org
│ → Build invite-by-email after RBAC working

├── Investigations (answer before committing)
│ ├── Is auto-provision transactional? If it fails mid-create, is there a half-provisioned user? [Owner: Engineering]
│ ├── Will Clerk organization sync create duplicate orgs? [Owner: Engineering]
│ └── Can base repository class enforce org scoping without breaking existing queries? [Owner: Engineering]

├── Success Measures (binary)
│ ├── Owner logs in → dashboard loads, no redirect loop → YES / NO
│ ├── First user in new org auto-gets Admin role → YES / NO
│ ├── defaultAllow: false in production, no permission = no access → YES / NO
│ └── User in org1 cannot access org2 data (negative security test) → YES / NO

├── Roles (RACI)
│ ├── Accountable: Wik (commissioning decisions, go/no-go on each tier)
│ ├── Responsible: Engineering team (fix bugs, build tiers, ship features)
│ ├── Consulted: Clerk documentation (auth provider patterns, org sync)
│ └── Informed: All venture PRDs blocked by this (Sales CRM, Sales Dev Agent, Content Amplifier)

└── Next Actions (momentum within 48 hours)
├── Fix User-Role query: use systemUserId not Clerk userId (Tier 0, task 1)
├── Break redirect loop: show error page on admin_access_required (Tier 0, task 2)
└── Set ADMIN_EMAILS env var in Vercel production (Tier 0, task 3)

════════════════════════════════════════════════════════════

Gate

Before moving to Value Stream Map:

  • Desired outcome is crisp: "Every user lands in the right org with the right permissions" — YES
  • Contributing factors have evidence: each references existing built infrastructure verified in codebase audit
  • Obstacles have mitigations assigned: each has a fix strategy with tier reference
  • Investigation questions have owners: all Engineering team
  • Success measures are binary: all four are YES/NO with clear verification method
  • RACI is complete: one Accountable (Wik), one Responsible (Engineering)
  • Next actions are assigned: three Tier 0 tasks with immediate start

Context