Superseded

IntegrateWise — Cloudflare Zero Trust → Twin/OpenWebUI Provisioning

⚠️ SUPERSEDED (v3.7, June 12 2026) — see AGENTS.md DECISION 22.
The product Twin is NOT OpenWebUI/Agent Zero on a VPS. The Twin runs entirely in Cloudflare
(services/iw-agent-runtime — Cloudflare Agents SDK: TwinAgent + TenantBrainDO + TwinSessionDO).
No OpenWebUI, no Hostinger/VPS, no Supabase in the product. This doc is retained for historical
context on the Zero Trust identity flow only; ignore the OpenWebUI/Agent-Zero/Hostinger runtime parts.
Canonical: docs/architecture/USER_SYSTEM_JOURNEY_BLUEPRINT.md + AGENTS.md (DECISION 22) + CLAUDE.md.

Date: 2026-06-09
Status: SUPERSEDED (was "Canonical")
Scope: User provisioning, session handoff, and trusted identity flow for L3 Twin / OpenWebUI
Architecture: Cloudflare Zero Trust already implemented
Auth Authority: Cloudflare Access + Gateway D1 JWT
Runtime Authority: IW Continuity Bridge
Twin Surface: Open WebUI + Agent Zero → Cloudflare-native (iw-agent-runtime)
Rule: OpenWebUI is not the identity authority. It is a trusted downstream runtime.


1. Executive Decision

Because Cloudflare Zero Trust is already implemented, IntegrateWise does not need OpenWebUI-native signup, password auth, or SCIM as the primary path.

The correct provisioning model is:

Cloudflare Access proves who the user is.
Gateway + D1 prove what the user can access.
Continuity Bridge provides what the Twin should know.
OpenWebUI provides where the user thinks.

Therefore, OpenWebUI provisioning should be treated as:

edge-authenticated runtime session injection

not:

standalone user registration

2. Canonical Flow

User
  │
  ▼
Cloudflare Access
  - Google / GitHub SSO
  - Zero Trust policy
  - Access JWT
  │
  ▼
Gateway
  - validates CF Access identity
  - resolves D1 user
  - resolves tenant
  - resolves role / department / plan
  - resolves awareness profile
  - issues Gateway JWT
  - creates Twin launch session
  │
  ▼
IW Continuity Bridge
  - stores context key
  - hydrates Entity 360
  - controls Spine / Memory / Signals access
  │
  ▼
OpenWebUI / Agent Zero
  - receives trusted user identity
  - receives continuity session pointer
  - loads context through Bridge
  - proposes, reasons, briefs
  - never becomes source of truth

3. Identity Ownership

ConcernOwner
Human authenticationCloudflare Access
Application authorizationGateway + D1
Tenant membershipD1 tenant_users
Department / roleD1
Awareness profileD1 / KV
Twin continuity sessionGateway + Continuity Bridge
Runtime chat UIOpenWebUI
Operational truthD1 spine_vault
MemoryD1 + R2 + AI Search
External agent accessMCP, separately gated

4. Provisioning Is Just-in-Time

A user is provisioned when Cloudflare proves identity and the Gateway sees them.

Provisioning states:

identity_seen
  → d1_user_created
  → tenant_bound
  → awareness_profile_assigned
  → twin_entitlement_checked
  → continuity_session_created
  → openwebui_runtime_user_ready

OpenWebUI user records are only runtime convenience records. They are not the product identity layer.


5. Primary Pattern: Trusted Header + Signed Launch Session

Why this is the right model

Since Twin is behind Cloudflare Zero Trust, IntegrateWise can safely pass identity downstream only after the request crosses the Cloudflare/Gateway boundary.

OpenWebUI should receive a trusted identity envelope such as:

X-User-Email
X-User-Name
X-IW-User-ID
X-IW-Tenant-ID
X-IW-Role
X-IW-Department
X-IW-Groups
X-IW-Continuity-Session
X-IW-Context-Key
X-IW-Launch-JWT

Only the Gateway or trusted reverse proxy may inject these headers.
Browsers must never be allowed to provide these headers directly.


6. Cloudflare Access Input Headers

Gateway should consume Cloudflare Access identity from:

Cf-Access-Authenticated-User-Email
Cf-Access-Jwt-Assertion

The Gateway must validate:

Access JWT signature
Access JWT audience
Access JWT issuer expiration
email claim

Then Gateway maps the identity into IntegrateWise's internal model.


7. Gateway → Internal Identity Model

Canonical internal identity object:

export interface IWResolvedUser {
  userId: string;
  email: string;
  displayName: string;

  tenantId: string;
  tenantSlug?: string;

  role: "founder" | "admin" | "manager" | "member" | "viewer";
  department:
    | "founder"
    | "bizops"
    | "account-success"
    | "sales"
    | "marketing"
    | "finance"
    | "engineering"
    | "hr"
    | "legal"
    | "security"
    | "partnerships"
    | "personal";

  plan: "free" | "starter" | "pro" | "enterprise";

  awarenessProfileId: string;
  signalThreshold: number;

  groups: string[];

  status: "active" | "invited" | "disabled";
}

8. Twin Launch Contract

L2 should never send trusted user or tenant data from the browser.

The browser may request Twin like this:

export interface TwinLaunchRequest {
  source: "l2" | "l1" | "l4";
  domain: string;

  entityId?: string;
  entityType?: string;
  entityName?: string;

  insightId?: string;
  insightTitle?: string;

  returnUrl?: string;
}

The Gateway enriches it server-side into:

export interface TwinLaunchSession {
  sessionId: string;
  contextKey: string;

  userId: string;
  email: string;
  tenantId: string;

  role: string;
  department: string;
  groups: string[];

  source: "l1" | "l2" | "l3" | "l4";
  domain: string;

  entityId?: string;
  entityType?: string;
  entityName?: string;

  insightId?: string;
  insightTitle?: string;

  createdAt: string;
  expiresAt: string;

  status: "created" | "opened" | "expired" | "revoked";
}

The launch session should be short-lived.

Recommended TTL:

Launch JWT: 60–180 seconds
Continuity session: 4–8 hours
Context key: 1 hour

9. Launch JWT Claims

Gateway should create a signed one-time Twin launch JWT.

export interface TwinLaunchJwtClaims {
  iss: "gateway.dev.integratewise.ai";
  aud: "twin.integratewise.ai";

  sub: string; // IW user id
  email: string;

  tenant_id: string;
  role: string;
  department: string;

  context_key: string;
  continuity_session_id: string;

  jti: string;
  iat: number;
  exp: number;
}

Rules:

jti must be one-time-use
token must be short-lived
context data must not be embedded directly if large/sensitive
tenant_id must be server-derived
role must be server-derived
department must be server-derived

10. D1 Tables

Minimum D1 tables required for canonical provisioning:

CREATE TABLE IF NOT EXISTS tenant_users (
  id TEXT PRIMARY KEY,
  tenant_id TEXT NOT NULL,
  email TEXT NOT NULL,
  display_name TEXT,
  role TEXT NOT NULL,
  department TEXT NOT NULL,
  plan TEXT NOT NULL DEFAULT 'free',
  status TEXT NOT NULL DEFAULT 'active',
  awareness_profile_id TEXT,
  created_at TEXT NOT NULL,
  updated_at TEXT NOT NULL,
  UNIQUE (tenant_id, email)
);

CREATE TABLE IF NOT EXISTS awareness_profiles (
  id TEXT PRIMARY KEY,
  tenant_id TEXT NOT NULL,
  role TEXT NOT NULL,
  department TEXT NOT NULL,
  signal_threshold REAL NOT NULL,
  signal_entitlements TEXT NOT NULL,
  panel_entitlements TEXT NOT NULL,
  created_at TEXT NOT NULL,
  updated_at TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS twin_sessions (
  id TEXT PRIMARY KEY,
  tenant_id TEXT NOT NULL,
  user_id TEXT NOT NULL,
  email TEXT NOT NULL,
  context_key TEXT NOT NULL,
  source TEXT NOT NULL,
  domain TEXT NOT NULL,
  entity_id TEXT,
  entity_type TEXT,
  entity_name TEXT,
  insight_id TEXT,
  insight_title TEXT,
  status TEXT NOT NULL DEFAULT 'created',
  created_at TEXT NOT NULL,
  expires_at TEXT NOT NULL,
  opened_at TEXT,
  revoked_at TEXT
);

CREATE TABLE IF NOT EXISTS twin_audit_events (
  id TEXT PRIMARY KEY,
  tenant_id TEXT NOT NULL,
  user_id TEXT NOT NULL,
  session_id TEXT,
  event_type TEXT NOT NULL,
  payload TEXT,
  created_at TEXT NOT NULL
);

11. KV Keys

Use KV for hot session/context lookup.

twin:session:{sessionId}
twin:context:{contextKey}
twin:jti:{launchJwtId}
user:profile:{tenantId}:{email}
awareness:{tenantId}:{profileId}

Recommended TTLs:

twin:context:*   1 hour
twin:session:*   4–8 hours
twin:jti:*       same as launch JWT expiry
awareness:*      5–15 minutes

12. OpenWebUI Runtime Mode

OpenWebUI should run as a trusted downstream app.

Recommended settings conceptually:

disable public signup
disable password-first product flow
enable trusted email/name header mode if supported
default runtime role = user
admin managed separately

Canonical headers to OpenWebUI:

X-User-Email: nirmal@integratewise.ai
X-User-Name: Nirmal
X-IW-User-ID: usr_xxx
X-IW-Tenant-ID: iw-customer-zero
X-IW-Role: founder
X-IW-Department: bizops
X-IW-Groups: founder,bizops,all-employees
X-IW-Continuity-Session: tws_xxx
X-IW-Context-Key: ctx_xxx
X-IW-Launch-JWT: eyJ...

If stock OpenWebUI only consumes email/name headers, that is fine.
Role, tenant, department, and context should be consumed by the IW Continuity Bridge, not by OpenWebUI's native RBAC.


13. Origin Protection Requirement

Because OpenWebUI runs on Hostinger, the origin must not be directly reachable without Cloudflare.

Acceptable origin protection:

Preferred:
  Cloudflare Tunnel from Hostinger to Cloudflare

Also acceptable:
  Cloudflare proxy + Access policy
  origin firewall allows only Cloudflare IP ranges
  authenticated origin pull
  no direct public bypass

Critical rule:

Trusted headers are safe only if users cannot bypass Cloudflare and hit the origin directly.

14. Twin Handoff Endpoint

Canonical endpoint:

POST /v1/twin/handoff

Responsibilities:

1. Validate Cloudflare Access identity
2. Resolve Gateway/D1 user
3. Validate tenant membership
4. Validate Twin entitlement by plan
5. Resolve department and awareness profile
6. Create context key
7. Create Twin session row
8. Create one-time launch JWT
9. Store context/session in KV
10. Return Twin launch URL
11. Write audit event

Response:

{
  "success": true,
  "twinUrl": "https://twin.integratewise.ai/launch?token=...",
  "sessionId": "tws_123",
  "contextKey": "ctx_123",
  "expiresAt": "2026-06-09T12:00:00.000Z"
}

15. Continuity Context Resolution

OpenWebUI / Agent Zero should not directly query D1.

The Twin should call the Continuity Bridge:

POST /v1/continuity/session/resolve

With:

{
  "contextKey": "ctx_123",
  "sessionId": "tws_123"
}

The Continuity Bridge returns:

{
  "entity360": {},
  "signals": [],
  "memory": [],
  "permissions": {},
  "availableTools": ["spine.entity.get", "spine.entity.search", "memory.search", "proposal.create"]
}

16. Approval Boundary

The Twin may reason and propose.
The Twin must not be the final approval authority.

Canonical rule:

U3 Reason happens in Twin.
U4 Decide happens in Governance / L2 approval surface.
U5 Act happens only after policy or human approval.

Therefore:

OpenWebUI chat is not the audit trail.
OpenWebUI approval buttons are not canonical unless they write through Governance.
All decisions must write to D1 governance/audit tables.

17. L2 → L3 Behavior

When L2 awareness drawer shows a signal:

User clicks: Open Twin ↗

The frontend sends only contextual hints:

{
  "source": "l2",
  "domain": "sales",
  "entityId": "ent_acme",
  "entityType": "opportunity",
  "entityName": "Acme Corp",
  "insightTitle": "Deal stalled 21 days"
}

The Gateway derives:

user
tenant
role
department
plan
awareness profile
permissions

Never trust these from browser input.


18. User Provisioning Rules

Existing active user

CF Access identity found
D1 tenant_user active
Twin entitlement valid
Create session
Open Twin

New user

CF Access identity found
No tenant_user found
Create edge user
Create or attach tenant
Set onboarding_required = true
Assign default awareness profile
Route to L0 onboarding
Do not open Twin until entitlement allows it

Disabled user

CF Access may prove identity
D1 status = disabled
Gateway denies
No Twin session created
Audit event written

Free-plan user

Can access L0/L1
No Twin unless plan allows
Return upgrade/entitlement response

19. Awareness Profile Mapping

Default profile thresholds:

Founder  → 0.65
Manager  → 0.75
Member   → 0.85
Viewer   → 0.95

Example profile:

{
  "role": "manager",
  "department": "account-success",
  "signalThreshold": 0.75,
  "signalEntitlements": ["renewal_risk", "health_drop", "escalation", "engagement_drop"],
  "panelEntitlements": ["spine", "context"]
}

20. Security Controls

Required controls:

Strip all inbound X-User-* and X-IW-* headers from public requests.
Inject trusted headers only after CF Access validation.
Validate Access JWT at Gateway.
Use one-time launch JWT.
Store jti to prevent replay.
Keep tenant_id server-derived.
Keep role server-derived.
Keep raw context out of query strings.
Use contextKey instead of full payload in URL.
Require service auth between Twin and Continuity Bridge.
Audit every handoff.
Audit every proposal.
Audit every approval.
Audit every act.

Forbidden:

OpenWebUI as primary auth
Supabase auth
browser-provided tenant_id
browser-provided role
OpenWebUI direct D1 access
OpenWebUI direct source-tool access
Nango token exposure to Twin
approval only in chat
public Hostinger origin bypassing Cloudflare

21. SCIM Position

SCIM is not required for the current architecture.

Use SCIM later only for enterprise lifecycle automation:

Okta
Azure AD
Google Workspace
enterprise provisioning
automatic deprovisioning
group sync

Primary path remains:

Cloudflare Access → Gateway D1 identity → Continuity session → OpenWebUI runtime

22. MCP Position

The Twin should use:

continuity-tool-server → pipeline → Spine

External agents should use:

mcp.integratewise.ai

MCP is the external door.
The Bridge is the product runtime.

Therefore:

OpenWebUI / Agent Zero should not be treated as an external MCP client by default.
It is inside the Bridge experience.

23. Rollout Plan

P0 — Required

1. Lock OpenWebUI behind Cloudflare Access.
2. Prevent direct Hostinger origin bypass.
3. Add /v1/twin/handoff to Gateway.
4. Add twin_sessions table.
5. Add twin_audit_events table.
6. Add KV context/session keys.
7. Generate one-time launch JWT.
8. Inject trusted user headers to OpenWebUI.
9. Make Twin resolve context through Continuity Bridge.
10. Disable OpenWebUI public signup/password path.

P1 — Operational

1. Add awareness profile resolution.
2. Add plan/tier Twin entitlement checks.
3. Add proposal.create from Twin.
4. Route approval to Governance Workbench.
5. Add audit trail UI.
6. Add session revocation.
7. Add disabled-user denial test.

P2 — Enterprise

1. Add SCIM only for enterprise tenants.
2. Add custom domain Twin routing.
3. Add per-tenant encryption keys.
4. Add enterprise group sync.
5. Add admin lifecycle dashboard.

24. Definition of Done

Provisioning is complete when:

A Cloudflare-authenticated active user can open Twin with no OpenWebUI login.
A disabled D1 user cannot open Twin even if Cloudflare authenticates them.
A free-plan user cannot open Twin unless entitled.
A replayed launch token fails.
A browser-spoofed X-IW-Tenant-ID is ignored or stripped.
OpenWebUI cannot be reached directly outside Cloudflare.
Twin loads Entity 360 only through Continuity Bridge.
Twin can propose but not approve.
Governance approval writes to D1 audit trail.
No source tool credentials are exposed to OpenWebUI.
No Supabase auth is involved.

25. Final Canonical Statement

Cloudflare Zero Trust is the identity membrane.
Gateway is the authorization brain.
D1 is the edge identity and Spine substrate.
Continuity Bridge is the runtime access path.
OpenWebUI is the Twin surface.

Provisioning is not account creation inside OpenWebUI.
Provisioning is continuity session creation after Cloudflare and Gateway trust are established.

The user does not log into Twin.
The user is carried into Twin by the Bridge.

Final System Architecture

Status: Canonical
Date: 2026-06-09
Architecture Principle: One Twin. One Spine. One Memory. One Bridge.
Auth: Cloudflare Zero Trust + Gateway D1 JWT
Product: IW Continuity Bridge
Runtime Surface: OpenWebUI + Agent Zero
Operational Truth: Cloudflare D1 spine_vault
External Agent Door: MCP
Tool Token Vault: Nango
Supabase: No auth. Usage-allocated fortress storage only for promoted tenants.

Final One-Line Architecture

Tools → Nango → Connector Sync/Webhooks → Loader → Normalizer → Cloudflare Spine
→ Signals + Memory + Intelligence → IW Continuity Bridge → L1/L2/L3/L4 Surfaces
→ Human Approves → Act → Tools → Spine Updates Again

The system never starts cold because every session, signal, decision, and memory loops back into the Spine and Memory substrate.

System Map

┌─────────────────────────────────────────────────────────────────────────────┐
│                              USER SURFACES                                  │
│                                                                             │
│  L0 Onboarding                                                              │
│  L1 Workspace: BI Hub / Account Success / Ops Board / Personal / Work       │
│  L2 Awareness Drawer: signals, context, HITL approval surface               │
│  L3 Twin: OpenWebUI + Agent Zero + Grok + Voice                             │
│  L4 Library: Coda / Knowledge / Memory / Playbooks                          │
│                                                                             │
└───────────────────────────────┬─────────────────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                      IW CONTINUITY BRIDGE                                   │
│                                                                             │
│  Runtime path for Twin                                                       │
│                                                                             │
│  OpenWebUI / Agent Zero                                                      │
│      → continuity-tool-server                                                │
│      → Gateway                                                               │
│      → Pipeline / Intelligence / Knowledge                                   │
│      → Spine + Memory + Signals                                              │
│                                                                             │
│  The Bridge is the product experience.                                       │
│  MCP is only the external agent door.                                        │
│                                                                             │
└───────────────────────────────┬─────────────────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                         CLOUDFLARE EDGE                                     │
│                                                                             │
│  Cloudflare Zero Trust                                                       │
│  Gateway                                                                     │
│  D1 JWT                                                                      │
│  Workers                                                                     │
│  Queues                                                                      │
│  KV                                                                          │
│  R2                                                                          │
│  Vectorize / AI Search                                                       │
│  D1 spine_vault                                                              │
│                                                                             │
│  Cloudflare is the edge substrate.                                           │
│  D1 spine_vault is the operational Spine.                                    │
│                                                                             │
└───────────────────────────────┬─────────────────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                         EXTERNAL TOOLS                                      │
│                                                                             │
│  HubSpot / Salesforce / Jira / Stripe / Slack / Gmail / Drive / GitHub      │
│  Intercom / Linear / Notion / ERP / Calendar / Documents                    │
│                                                                             │
│  Tool identity dies at the Normalizer.                                      │
│  Spine stores canonical truth, not source labels.                           │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Hard Rules

1. Cloudflare Zero Trust is the identity membrane.
2. Gateway is the authorization brain.
3. D1 spine_vault is operational truth.
4. Pipeline is the only Spine writer.
5. Normalizer erases source identity.
6. Nango owns tool credentials.
7. Twin reads through Continuity Bridge.
8. MCP is for external agents.
9. L2 is an awareness service, not a page.
10. Twin proposes; Governance decides; Act executes.
11. Chat is not the audit trail.
12. Coda is projection, not truth.
13. Supabase is not auth.
14. Supabase is not default.
15. Every query is tenant-scoped.
16. No surface reads source tools directly.
17. No agent gets raw source credentials.
18. Every action loops back through Spine.
19. Every useful learning can become Memory.
20. The system never starts cold.

Final Architecture Statement

IntegrateWise is an edge-native continuity system.

Cloudflare provides the identity membrane, routing layer, compute substrate,
queues, cache, encrypted operational store, and semantic memory infrastructure.

The Spine is the canonical D1 operational truth.
The Pipeline is the only writer to that truth.
The Normalizer turns every tool into one source-agnostic model.
Nango protects all external credentials.
The Intelligence layer turns state changes into signals and proposals.
L2 manifests only entitled awareness.
L3 Twin reasons through the IW Continuity Bridge.
L4 projects governed organizational memory.
MCP lets external agents reach the same Spine without becoming the runtime path.

The user buys the IW Continuity Bridge: the guarantee that their AI, dashboards,
agents, memory, and tools all share one continuous context.

Connect once. Normalize once. Render anywhere.
Reason continuously. Approve deliberately. Act safely. Remember forever.

26. Implementation Status (2026-06-09)

This section maps the canonical target (sections 1–25) to what is live in code and ops today.

26.1 Identity & Auth

ComponentTargetLive todayGap
Cloudflare Access SSOPrimary identity membrane✅ Implemented (Google + GitHub)—
Gateway CF JWT verificationValidates Cf-Access-Jwt-Assertion✅ services/gateway/src/index.ts—
Gateway D1 JWT + x-tenant-idApp session for L0–L2✅ Live—
OpenWebUI trusted headersWEBUI_AUTH_TRUSTED_* from gateway/proxy❌ Not in VPS composeAdd when Twin is CF-fronted
OpenWebUI public signup disabledNo standalone Twin login⚠️ Partial — OWUI has local auth todayLock when trusted-header path is live
SCIM 2.0Enterprise lifecycle only❌ Not configuredP2 — optional

26.2 L2 → L3 Handoff (Continuity, not account creation)

ComponentTargetLive todayGap
POST /v1/twin/handoff (Gateway)Server-side session + launch JWT❌ Not implementedP0 — see §14
twin_sessions / twin_audit_events (D1)Session + audit trail❌ Tables not migratedP0
KV twin:context:* / twin:session:*Hot context lookup❌ Not wired for Twin launchP0
Client handoff (twin-owui-handoff.ts)Browser opens Twin with context✅ LiveInterim path — query params + sessionStorage
IW_HANDOFF: envelope in promptL1/L2 context in first message✅ iw-l1-handoff-inlet.py filter on VPS
TwinInsightsSurface → openTwinWorkbench()L2 "Open Twin ↗"✅ apps/web/src/components/l2/insights/twin-insights-surface.tsx
Server-derived tenant/role in handoffNever trust browser❌ Client passes entity hints only todayGateway handoff closes this

Interim handoff (live):

L1/L2 click "Open Twin"
  → writeTwinHandoffContext() (sessionStorage)
  → buildTwinOwuiUrl() with iw_context, iw_prompt, iw_domain, iw_source
  → window.open("https://twin.integratewise.ai?...")
  → OWUI inlet filter parses IW_HANDOFF: from first user message
  → continuity-tool-server reads Spine/Memory via pipeline

Target handoff (canonical):

L1/L2 POST /v1/twin/handoff { entityId, domain, source }  (hints only)
  → Gateway validates CF Access + D1 user + plan entitlement
  → Creates twin_sessions row + KV context key + one-time launch JWT
  → Returns twinUrl with token (60–180s TTL)
  → User lands on CF-protected Twin; proxy injects X-IW-* headers
  → Continuity Bridge resolves contextKey → Entity 360

26.3 L3 Runtime (Hostinger VPS)

ComponentTargetLive todayGap
twin.integratewise.aiPrimary L3 surface✅ Traefik + OWUI (integratewise-ops/vps-operations-stack)—
twin.operations.integratewise.aiOps-branded first-win Twin❌ DNS/route not provisionedSee CONTINUITY_BRIDGE_DEPLOYMENT_STATUS §8
continuity-tool-serverBridge read path to pipeline✅ Container in openwebui composeExtend for session/resolve
agentzero-tool-serverMulti-step execution✅ Container live—
LiteLLM + Ollama fallbackLocal models when cloud fails✅ iw-ollama + LiteLLM—
CF Tunnel / origin lockNo direct Hostinger bypass⚠️ Traefik on host :443Prefer CF Tunnel or origin firewall
Infisical secrets wireRuntime env from vault⚠️ Deployed, not wired to stackinfisical-wire-stack.sh

26.4 L2 Cognitive Layer (from l2.zip contract)

L2 surfaceMaps to S-seriesOWUI / Bridge roleStatus
Spine panelS2 Awareness / evidencespine.entity.get via continuity✅ Partial in drawer
Context panelS2 / think substrateEntity 360 assembly✅ Live
LiveSignalsStripS2 / U2 NoticeSignal cards in L1 shell✅ Live
HITL / PendingApprovalsS2 / U4 DecideGovernance workbench — not OWUI chat✅ Live in L2
TwinInsightsSurfaceS2 digest → S3 handoffopenTwinWorkbench()✅ Live
Domain happy path (Today/Queue/Decisions)S2 per-domainRoutes in workbench✅ Live
SlidingPanel / cognitive triggersS2 overlaycognitive-triggers.tsx⚠️ Partial triggers

26.5 Code References

ArtifactPath
Client handoff libraryintegratewise-live/apps/web/src/lib/twin-owui-handoff.ts
L2 Twin insights + Open Twin buttonintegratewise-live/apps/web/src/components/l2/insights/twin-insights-surface.tsx
OWUI handoff inlet filterintegratewise-ops/vps-operations-stack/openwebui/filters/iw-l1-handoff-inlet.py
VPS Twin composeintegratewise-ops/vps-operations-stack/openwebui/docker-compose.yml
Continuity tool serverintegratewise-ops/vps-operations-stack/tool-servers/tool_server.py
Gateway CF Access verificationintegratewise-live/services/gateway/src/index.ts
L2 surface contractintegratewise-docs/docs/internal/architecture/l2-twin-surface-contract.md
MCP / Bridge canonintegratewise-docs/docs/internal/architecture/mcp-continuity-bridge.md

26.6 Next implementation sequence

P0 (closes provisioning gap)
  1. Add POST /v1/twin/handoff to Gateway (§14 request/response)
  2. Migrate twin_sessions + twin_audit_events (§10)
  3. Wire KV context keys (§11)
  4. Put Twin origin behind Cloudflare Access (§13)
  5. Add WEBUI_AUTH_TRUSTED_* to openwebui/docker-compose.yml when CF proxy injects headers

P1 (continuity hardening)
  6. POST /v1/continuity/session/resolve from continuity worker (§15)
  7. Plan-tier Twin entitlement check in handoff (§18)
  8. Switch openTwinWorkbench() to call Gateway handoff instead of direct URL

P2 (enterprise)
  9. SCIM for Okta/Azure AD lifecycle (§21)
  10. twin.operations.integratewise.ai branded route