{"slug":"business/v2-ecosystem","title":"§E — Ecosystem Architecture & SDK Specification","section":"business","sectionLabel":"Business","status":"unclassified","type":"document","path":"business/v2-ecosystem.mdx","bytes":85106,"description":null,"updated":null,"source":"integratewise/Integratewise-docs-wiki","content":"\n> **Status: SUPERSEDED DEEP-DIVE.** The old product name, layer model and\n> permanent Twin-panel examples are historical only. Current Capability,\n> Workbench and Silent Twin rules live in\n> [`ARCHITECTURE_LOCK.md`](./ARCHITECTURE_LOCK.md) and\n> [`TWIN_BEHAVIOR.md`](./TWIN_BEHAVIOR.md).\n\n## IntegrateWise Continuity Bridge v2.0 — Capability Fabric, Knowledge Protocol, A2A, SDK Variants, Composition Patterns\n\n**Status:** DRAFT v2.0 — Stage 1/2 Deep-Dive  \n**Domain Owner:** Ecosystem Architecture & SDK  \n**Supersedes:** v1.0.1 §5 (MCP Pool), §9 (Discovery), §12.4 (A2A), §18 (Registry), §26 (Template) where conflicting.  \n**Date:** 2026-07-02\n\n---\n\n## E.1 Doctrine — What the Ecosystem Layer Is\n\n> **The Ecosystem is the capability fabric.** It is not a separate system. It is the emergent property of the Continuity Bridge when tools, agents, humans, and memory are allowed to communicate through the Spine — governed, audited, and scoped.\n\nThe Ecosystem Layer sits conceptually across the **Capability** and **Continuity** layers of the 6-layer stack. It is the substrate that enables:\n\n1. **Capability Fabric Model** — How named business capabilities are discovered, composed, and executed across the mesh.\n2. **Knowledge Sharing Protocol (KSP)** — How memory, context, and evidence move between agents, tools, and humans without leaking tenant boundaries.\n3. **Agent-to-Agent Communication (A2A)** — How autonomous agents coordinate through the Spine (not peer-to-peer), governed by the Twin ambient reasoning layer.\n4. **SDK Variants** — Five consumer-facing SDK packages that expose the same contract at different fidelity levels.\n5. **Ecosystem App Composition Patterns** — How third-party developers build on the Bridge without importing internal topology.\n6. **Template Starter** — The canonical `create-iw-app` bootstrap for ecosystem participants.\n\n**Key Invariant:** The Ecosystem never bypasses the Spine. All communication between ecosystem participants is mediated by the Spine, gated by `tenant_id`, and audited to `spine_audit_log`.\n\n---\n\n## E.2 The Capability Fabric Model\n\n### E.2.1 Conceptual Architecture\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                         ECOSYSTEM CAPABILITY FABRIC                         │\n│                                                                             │\n│   ┌─────────────┐    ┌─────────────┐    ┌─────────────┐    ┌─────────────┐ │\n│   │  Capability │◄──►│  Capability │◄──►│  Capability │◄──►│  Capability │ │\n│   │   Registry  │    │   Router    │    │   Sandbox   │    │   Monitor   │ │\n│   │(agent-registry)  │  (hermes)   │    │(iw-agent-  │    │ (telemetry) │ │\n│   └──────┬──────┘    └──────┬──────┘    │  runtime)   │    └─────────────┘ │\n│          │                  │            └─────────────┘                    │\n│          ▼                  ▼                                               │\n│   ┌─────────────────────────────────────────────────────────────────────┐  │\n│   │                    SPINE — The Single Source of Truth               │  │\n│   │         (entities, relationships, memory, audit, continuity)        │  │\n│   └─────────────────────────────────────────────────────────────────────┘  │\n│                              ▲                                              │\n│   ┌─────────────┐    ┌───────┴───────┐    ┌─────────────┐    ┌──────────┐ │\n│   │   Inbound   │    │    Twin       │    │   Outbound  │    │  Shared  │ │\n│   │   MCP Pool  │◄──►│  (ambient)    │◄──►│   MCP Pool  │◄──►│  Memory  │ │\n│   │(mcp-connector)    │(twin-orchestrator)  │  (act +    │    │(continuity│ │\n│   └─────────────┘    └─────────────┘    │   adapters)   │    └──────────┘ │\n│                                         └─────────────┘                   │\n└─────────────────────────────────────────────────────────────────────────────┘\n                              ▲\n        Consumers ────────────┴───────────── SDKs, AI Assistants, Web Workbench\n```\n\n### E.2.2 Capability Taxonomy\n\nEvery capability in the ecosystem is a **named, versioned, discoverable action** with a strict contract:\n\n```typescript\n// packages/sdk/src/types/capability.ts\n\n/**\n * Capability — the atomic unit of the Capability Fabric.\n * Every capability is: named, versioned, scoped, gated, and audited.\n */\nexport interface Capability {\n  /** Canonical capability ID: `{domain}.{resource}.{action}` */\n  id: string; // e.g., \"salesforce.opportunity.create\"\n\n  /** Semantic version of the capability contract */\n  version: string; // e.g., \"2.1.0\"\n\n  /** Human-readable name */\n  name: string;\n\n  /** Markdown description for Discovery */\n  description: string;\n\n  /** The provider that owns this capability */\n  provider: string; // e.g., \"salesforce\", \"slack\", \"iw-native\"\n\n  /** Capability tier: L1=read, L2=insight, L3=execute, L4=autonomous */\n  level: 1 | 2 | 3 | 4;\n\n  /** Required scopes to invoke */\n  scopes: string[]; // e.g., [\"read:opportunities\", \"write:opportunities\"]\n\n  /** Input JSON Schema (for validation + UI generation) */\n  inputSchema: JSONSchema7;\n\n  /** Output JSON Schema */\n  outputSchema: JSONSchema7;\n\n  /** Governance gate required? */\n  governanceGate: boolean; // true for L3/L4, false for L1/L2\n\n  /** Minimum confidence threshold for auto-execution */\n  autoExecuteThreshold: number; // 0.85 default for L3, 1.0 (never auto) for L4\n\n  /** Whether this capability supports streaming (SSE) responses */\n  streaming: boolean;\n\n  /** Estimated cost in tokens / compute units */\n  costEstimate: CostEstimate;\n\n  /** Deprecation status */\n  deprecation?: {\n    deprecatedAt: string; // ISO date\n    sunsetAt: string; // ISO date\n    replacement?: string; // capability ID of replacement\n  };\n}\n\nexport interface CostEstimate {\n  /** Token estimate for LLM-based capabilities */\n  tokens?: { input: number; output: number };\n\n  /** External API call cost estimate (USD) */\n  apiCalls?: { count: number; estimatedCost: number };\n\n  /** Compute time estimate (ms) */\n  computeMs: number;\n}\n\n/** Capability invocation request — what consumers send */\nexport interface CapabilityInvokeRequest {\n  /** The capability to invoke */\n  capability: string;\n\n  /** Tenant context (injected by Gateway, never from client) */\n  tenantId: string;\n\n  /** User context (injected by Gateway from JWT) */\n  userId: string;\n\n  /** Correlation ID for distributed tracing */\n  correlationId: string;\n\n  /** Invocation payload — validated against capability.inputSchema */\n  payload: unknown;\n\n  /** Execution preferences */\n  options?: {\n    /** Prefer streaming response? */\n    streaming?: boolean;\n\n    /** Maximum wait time (ms) before async handoff */\n    timeoutMs?: number;\n\n    /** Whether to compound result into memory */\n    compoundMemory?: boolean;\n\n    /** Required confidence threshold override */\n    confidenceThreshold?: number;\n  };\n}\n\n/** Capability invocation response */\nexport interface CapabilityInvokeResponse {\n  correlationId: string;\n  status: \"success\" | \"pending\" | \"rejected\" | \"error\" | \"async\";\n  result?: unknown;\n  proposalId?: string; // Present if governance-gated\n  confidence?: number; // Governance confidence score\n  auditLogId: string; // Reference to spine_audit_log entry\n  executionTimeMs: number;\n}\n```\n\n### E.2.3 Capability Discovery & Routing\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                     CAPABILITY DISCOVERY & ROUTING FLOW                     │\n│                                                                             │\n│  Consumer                          Gateway                        Discovery │\n│     │                                │                              Cache   │\n│     │  GET /api/v1/discovery         │                                 │   │\n│     │ ─────────────────────────────► │                                 │   │\n│     │                                │  1. Extract tenantId from JWT   │   │\n│     │                                │  2. Query KV cache (5-min TTL)  │   │\n│     │                                │                                 │   │\n│     │                                │ ◄──── cached Discovery? ───────►│   │\n│     │                                │                                 │   │\n│     │                                │  [Cache MISS]                   │   │\n│     │                                │     │                           │   │\n│     │                                │     ▼                           │   │\n│     │                                │  3. Fetch from agent-registry   │   │\n│     │                                │     (service binding)           │   │\n│     │                                │                                 │   │\n│     │                                │  4. agent-registry queries:     │   │\n│     │                                │     - capability_registry (D1)  │   │\n│     │                                │     - endpoint_registry (D1)    │   │\n│     │                                │     - connector status (KV)     │   │\n│     │                                │                                 │   │\n│     │                                │  5. Filter by tenant plan + RBAC │   │\n│     │                                │                                 │   │\n│     │                                │  6. Write to KV cache           │   │\n│     │                                │                                 │   │\n│     │  DiscoveryResponse             │                                 │   │\n│     │ ◄───────────────────────────── │                                 │   │\n│     │                                │                                 │   │\n└─────────────────────────────────────────────────────────────────────────────┘\n```\n\n**Discovery Response Contract:**\n\n```typescript\n// packages/sdk/src/types/discovery.ts\n\nexport interface DiscoveryResponse {\n  /** Identity context */\n  identity: {\n    userId: string;\n    tenantId: string;\n    orgId: string;\n    role: string;\n    scopes: string[];\n  };\n\n  /** Workspace configuration */\n  workspace: {\n    name: string;\n    plan: \"free\" | \"pro\" | \"enterprise\";\n    connectedProviders: string[];\n    limits: WorkspaceLimits;\n  };\n\n  /** Available projections (8 lenses) */\n  projections: Projection[];\n\n  /** Available capabilities — FILTERED by tenant plan + RBAC */\n  capabilities: CapabilitySummary[];\n\n  /** Available agents in the ecosystem */\n  agents: AgentSummary[];\n\n  /** Knowledge sources available */\n  knowledgeSources: KnowledgeSource[];\n\n  /** Navigation structure for the workbench */\n  navigation: NavNode[];\n\n  /** Personalization */\n  personalization: {\n    recentCapabilities: string[];\n    pinnedProjections: string[];\n    preferences: Record<string, unknown>;\n  };\n\n  /** SDK version compatibility */\n  sdkVersion: string;\n\n  /** Bridge version */\n  bridgeVersion: string;\n}\n\nexport interface CapabilitySummary {\n  id: string;\n  name: string;\n  description: string;\n  level: 1 | 2 | 3 | 4;\n  provider: string;\n  category: string;\n  scopes: string[];\n  streaming: boolean;\n  /** Whether currently available (provider connected + healthy) */\n  available: boolean;\n}\n\nexport interface AgentSummary {\n  id: string;\n  name: string;\n  description: string;\n  capabilities: string[];\n  status: \"active\" | \"idle\" | \"maintenance\";\n}\n\nexport interface KnowledgeSource {\n  id: string;\n  name: string;\n  type: \"spine\" | \"memory\" | \"document\" | \"connector\";\n  entityTypes: string[];\n}\n```\n\n### E.2.4 Capability Execution Flow\n\n```\nConsumer → Gateway → hermes (queue) → twin-orchestrator (OODA) → govern (gate) → act (execute)\n                                              │\n                                              ▼\n                                    ┌─────────────────┐\n                                    │   SPINE READ    │\n                                    │  Entity360 +    │\n                                    │  Memory + RAG   │\n                                    └─────────────────┘\n```\n\n**Detailed Execution Flow:**\n\n| Step | Service             | Queue/Binding                     | Action                                                           | Security Boundary       |\n| ---- | ------------------- | --------------------------------- | ---------------------------------------------------------------- | ----------------------- |\n| 1    | `gateway`           | N/A                               | Validate JWT, extract `tenant_id`, assemble `correlationId`      | Identity Layer          |\n| 2    | `gateway`           | `HERMES` (service binding)        | Enqueue `CapabilityInvokeRequest` to Hermes                      | Ingress → Capability    |\n| 3    | `hermes`            | `ACT_QUEUE`                       | DO acquires message, checks idempotency key                      | Capability Layer        |\n| 4    | `hermes`            | `TWIN_ORCHESTRATOR` (binding)     | If L2/L3/L4, route to Twin for OODA                              | Capability → Continuity |\n| 5    | `twin-orchestrator` | D1 + KV + Vectorize               | Orient: assemble Entity360 + Memory + Knowledge                  | Continuity Layer        |\n| 6    | `twin-orchestrator` | `THINK` (binding)                 | Decide: LLM reasoning, proposal generation                       | Continuity Layer        |\n| 7    | `twin-orchestrator` | `GOVERN` (binding)                | Confidence scoring, proposal emission                            | Governance Layer        |\n| 8    | `govern`            | D1 `action_proposals`             | Gate: ≥0.85 auto, 0.70-0.85 HITL, <0.70 discard                  | Governance Layer        |\n| 9    | `govern`            | `ACT_QUEUE`                       | Approved → enqueue to act                                        | Governance → Provider   |\n| 10   | `act`               | D1 + outbound adapters            | Execute: adapter selection, credential wall, Entity360 injection | Provider Fabric         |\n| 11   | `act`               | `PIPELINE_QUEUE`                  | Writeback: result → Pipeline → Spine                             | Provider → Spine        |\n| 12   | `pipeline`          | D1 `entities` + `spine_audit_log` | Commit: ONLY writer to Spine                                     | Spine Integrity         |\n| 13   | `continuity`        | D1 `memory` + KV                  | Remember: compound into memory tiers                             | Memory Layer            |\n\n---\n\n## E.3 Knowledge Sharing Protocol (KSP)\n\n### E.3.1 Protocol Overview\n\n> **KSP is the contract for how knowledge moves between ecosystem participants.** It is not a separate network protocol. It is a schema and governance contract over the Spine.\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                    KNOWLEDGE SHARING PROTOCOL (KSP)                         │\n│                                                                             │\n│   ┌──────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐          │\n│   │  Agent A │◄───►│  SPINE   │◄───►│  Agent B │◄───►│  Human   │          │\n│   │ (twin-A) │     │ (shared) │     │ (twin-B) │     │ (desk)   │          │\n│   └────┬─────┘     └────┬─────┘     └────┬─────┘     └────┬─────┘          │\n│        │                │                │                │                │\n│        │   KSP Packet   │   KSP Packet   │   KSP Packet   │                │\n│        │   (scoped)     │   (scoped)     │   (scoped)     │                │\n│        │                │                │                │                │\n│   ┌────▼────────────────▼────────────────▼────────────────▼─────┐          │\n│   │              KSP GOVERNANCE LAYER (govern)                  │          │\n│   │  • tenant_id isolation (HARD)                               │          │\n│   │  • scope validation (read/write/admin)                      │          │\n│   │  • confidence scoring (0.70/0.85)                           │          │\n│   │  • audit trail (spine_audit_log)                            │          │\n│   │  • retention policy (D1 + R2)                               │          │\n│   └─────────────────────────────────────────────────────────────┘          │\n│                                                                             │\n└─────────────────────────────────────────────────────────────────────────────┘\n```\n\n### E.3.2 KSP Packet Schema\n\n```typescript\n// packages/sdk/src/types/ksp.ts\n\n/**\n * Knowledge Sharing Protocol Packet — the unit of knowledge transfer.\n * Every packet is: typed, scoped, attributed, timed, and governed.\n */\nexport interface KSPPacket {\n  /** Unique packet ID (UUID v7 for time-sortability) */\n  id: string;\n\n  /** Protocol version */\n  version: \"ksp/2.0\";\n\n  /** Tenant isolation boundary — HARD GATE */\n  tenantId: string;\n\n  /** Source of the knowledge */\n  source: KSPSource;\n\n  /** Destination of the knowledge */\n  destination: KSPDestination;\n\n  /** The knowledge payload */\n  payload: KSPPayload;\n\n  /** Temporal context */\n  timing: KSPTiming;\n\n  /** Governance metadata */\n  governance: KSPGovernance;\n\n  /** Audit reference */\n  audit: {\n    logId: string;\n    spineAuditLogId: string;\n  };\n}\n\nexport interface KSPSource {\n  /** Source type */\n  type: \"agent\" | \"tool\" | \"human\" | \"twin\" | \"system\" | \"connector\";\n\n  /** Source ID (agent ID, user ID, tool ID) */\n  id: string;\n\n  /** Source name (for display) */\n  name: string;\n\n  /** Capability that produced this knowledge (if applicable) */\n  capabilityId?: string;\n\n  /** Provider that produced this knowledge (if applicable) */\n  providerId?: string;\n}\n\nexport interface KSPDestination {\n  /** Target type */\n  type: \"broadcast\" | \"agent\" | \"tool\" | \"human\" | \"twin\" | \"memory\" | \"spine\";\n\n  /** Target ID (for directed packets) */\n  id?: string;\n\n  /** Scope filter — who can see this packet */\n  visibility: \"personal\" | \"work\" | \"organization\" | \"ai\";\n}\n\nexport interface KSPPayload {\n  /** Payload type discriminator */\n  type:\n    | \"observation\"\n    | \"orientation\"\n    | \"decision\"\n    | \"action_result\"\n    | \"memory_fragment\"\n    | \"signal\"\n    | \"proposal\"\n    | \"evidence\";\n\n  /** The actual content — shape depends on type */\n  content: unknown;\n\n  /** Semantic embedding (Vectorize) for similarity search */\n  embedding?: number[];\n\n  /** Confidence score (0.0–1.0) for memory triage */\n  confidence: number;\n\n  /** References to related Spine entities */\n  entityRefs?: string[]; // SSOC UUIDs\n\n  /** References to related packets (lineage) */\n  parentPacketIds?: string[];\n}\n\nexport interface KSPTiming {\n  /** Packet creation time */\n  createdAt: string; // ISO 8601\n\n  /** Valid until (for time-bounded knowledge) */\n  expiresAt?: string;\n\n  /** Time-to-live in seconds (for cacheable knowledge) */\n  ttlSeconds?: number;\n}\n\nexport interface KSPGovernance {\n  /** Minimum role required to access */\n  minRole: string;\n\n  /** Required scopes */\n  requiredScopes: string[];\n\n  /** Whether this packet requires governance approval before distribution */\n  approvalRequired: boolean;\n\n  /** Classification level */\n  classification: \"public\" | \"internal\" | \"confidential\" | \"restricted\";\n\n  /** Data residency requirements */\n  residency?: string; // e.g., \"us-east\", \"eu-west\"\n}\n```\n\n### E.3.3 KSP Flow — Agent Shares Insight with Organization\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│           KSP FLOW: Agent A Shares Insight → Organization Memory             │\n│                                                                             │\n│  Agent A (twin-orchestrator-A)                                              │\n│     │                                                                       │\n│     │  1. Generates insight (OODA Decide phase)                             │\n│     │     confidence: 0.92                                                  │\n│     │                                                                       │\n│     ▼                                                                       │\n│  ┌─────────────────────────────────────────────────────────────────────┐    │\n│  │  2. Assemble KSP Packet                                             │    │\n│  │     source: { type: \"twin\", id: \"twin-A\", name: \"Sales Twin\" }      │    │\n│  │     destination: { type: \"memory\", visibility: \"organization\" }     │    │\n│  │     payload: { type: \"memory_fragment\", confidence: 0.92, ... }     │    │\n│  │     governance: { minRole: \"member\", approvalRequired: false }      │    │\n│  └─────────────────────────────────────────────────────────────────────┘    │\n│     │                                                                       │\n│     │  POST /api/v1/knowledge/share                                         │\n│     ▼                                                                       │\n│  Gateway — validates JWT, extracts tenant_id                                │\n│     │                                                                       │\n│     │  3. Route to knowledge service (service binding)                      │\n│     ▼                                                                       │\n│  knowledge — semantic analysis, embedding generation                        │\n│     │                                                                       │\n│     │  4. Route to continuity (service binding)                             │\n│     ▼                                                                       │\n│  continuity — Memory Triage                                                 │\n│     │  confidence ≥ 0.85 → ACTIVE memory (D1 + KV + Vectorize)            │\n│     │  0.70–0.85 → STAGING memory (D1 only)                               │\n│     │  < 0.70 → DISCARD (R2 cold storage)                                 │\n│     │                                                                       │\n│     │  5. Write to spine_audit_log                                         │\n│     ▼                                                                       │\n│  pipeline — commit audit entry                                              │\n│     │                                                                       │\n│     │  6. Broadcast to subscribers                                         │\n│     ▼                                                                       │\n│  hermes — enqueue to notification queue                                     │\n│     │                                                                       │\n│     │  SSE push to connected workbench clients                             │\n│     │  WebSocket update to Twin Workbench                                  │\n│     ▼                                                                       │\n│  Organization Memory Updated                                                │\n└─────────────────────────────────────────────────────────────────────────────┘\n```\n\n### E.3.4 KSP Security Boundaries\n\n| Boundary              | Enforcement                                        | Failure Mode          |\n| --------------------- | -------------------------------------------------- | --------------------- |\n| **Tenant Isolation**  | `WHERE tenant_id = ?` on every KSP query           | 403 fail-loud         |\n| **Visibility Scope**  | `personal` < `work` < `organization` < `ai`        | Filter silently       |\n| **Role Gate**         | `minRole` checked against RBAC in `tenants`        | 403 if insufficient   |\n| **Scope Gate**        | `requiredScopes` checked against JWT `scope` claim | 403 if missing        |\n| **Classification**    | `restricted` → requires `admin` role + approval    | Quarantine to staging |\n| **Residency**         | Packet rejected if target region mismatch          | 422 with reason       |\n| **Approval Required** | `approvalRequired: true` → routed to `govern`      | HITL queue            |\n\n---\n\n## E.4 Agent-to-Agent Communication (A2A)\n\n### E.4.1 A2A Architecture — Spine as Shared Blackboard\n\n> **A2A in v2.0 is NOT peer-to-peer.** Agents coordinate through the Spine as a shared blackboard, mediated by the ambient Twin layer. This prevents circular dependencies, ensures auditability, and maintains tenant isolation.\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│              A2A: SPINE-BASED COORDINATION (NOT PEER-TO-PEER)               │\n│                                                                             │\n│                                                                             │\n│    Agent A ──────┐                                                          │\n│   (Sales Twin)   │                                                          │\n│                  │                                                          │\n│                  │    ┌──────────────────────────────────────────┐          │\n│                  │    │           SPINE BLACKBOARD               │          │\n│                  ├───►│                                          │          │\n│                  │    │  ┌─────────────┐   ┌─────────────┐       │          │\n│    Agent B ──────┤    │  │  Intent A   │   │  Intent B   │       │          │\n│   (CS Twin)      │    │  │  (proposal) │   │  (proposal) │       │          │\n│                  │    │  └──────┬──────┘   └──────┬──────┘       │          │\n│                  │    │         │                 │              │          │\n│                  │    │         ▼                 ▼              │          │\n│                  │    │  ┌─────────────────────────────────┐     │          │\n│                  ├───►│  │     GOVERN (arbitration)        │     │          │\n│                  │    │  │  • Detect conflicts             │     │          │\n│    Agent C ──────┤    │  │  • Score joint confidence       │     │          │\n│   (Finance Twin) │    │  │  • Enforce priority rules       │     │          │\n│                  │    │  │  • Escalate to human if needed  │     │          │\n│                  │    │  └─────────────────────────────────┘     │          │\n│                  │    │         │                 │              │          │\n│                  │    │         ▼                 ▼              │          │\n│                  │    │  ┌─────────────┐   ┌─────────────┐       │          │\n│                  └───►│  │  Action A   │   │  Action B   │       │          │\n│                       │  │  (approved) │   │  (approved) │       │          │\n│                       │  └─────────────┘   └─────────────┘       │          │\n│                       │                                          │          │\n│                       └──────────────────────────────────────────┘          │\n│                                    ▲                                        │\n│                                    │                                        │\n│                            ┌───────┴───────┐                                │\n│                            │   TWIN LAYER   │                                │\n│                            │   (ambient)    │                                │\n│                            │  • OODA cycle  │                                │\n│                            │  • Context asm │                                │\n│                            │  • Reasoning   │                                │\n│                            └───────────────┘                                │\n│                                                                             │\n│  RULE: Agents never call each other directly. They read/write the Spine.    │\n│        The Twin layer observes and reasons across agent outputs.            │\n│                                                                             │\n└─────────────────────────────────────────────────────────────────────────────┘\n```\n\n### E.4.2 A2A Intent Schema\n\n```typescript\n// packages/sdk/src/types/a2a.ts\n\n/**\n * A2A Intent — an agent's declared intention published to the Spine.\n * Other agents read intents and may respond with complementary or conflicting intents.\n */\nexport interface A2AIntent {\n  /** Unique intent ID */\n  id: string;\n\n  /** The agent that published this intent */\n  agentId: string;\n\n  /** Agent type */\n  agentType: \"twin\" | \"autonomous\" | \"workflow\" | \"human\";\n\n  /** Tenant isolation */\n  tenantId: string;\n\n  /** Intent classification */\n  intentType: A2AIntentType;\n\n  /** The target capability or entity */\n  target: {\n    type: \"capability\" | \"entity\" | \"memory\" | \"projection\";\n    id: string;\n  };\n\n  /** What the agent wants to do */\n  action: {\n    verb: \"propose\" | \"request\" | \"inform\" | \"query\" | \"warn\" | \"block\";\n    description: string;\n    payload: unknown;\n  };\n\n  /** Confidence in this intent (0.0–1.0) */\n  confidence: number;\n\n  /** Priority relative to other intents */\n  priority: \"critical\" | \"high\" | \"normal\" | \"low\";\n\n  /** Time bounds */\n  timing: {\n    publishedAt: string;\n    validUntil?: string;\n    executeAfter?: string; // Defer execution until this time\n  };\n\n  /** Dependencies — other intents that must resolve first */\n  dependencies?: string[]; // Intent IDs\n\n  /** Response to another intent (for threading) */\n  inReplyTo?: string;\n\n  /** Governance status */\n  governance: {\n    status: \"pending\" | \"approved\" | \"rejected\" | \"escalated\";\n    proposalId?: string;\n    approvedBy?: string;\n    approvedAt?: string;\n  };\n}\n\nexport type A2AIntentType =\n  | \"cross-sell\" // Sales agent → CS agent: opportunity signal\n  | \"churn-risk\" // CS agent → Sales/Finance: retention alert\n  | \"data-request\" // Any agent → Spine: needs context\n  | \"action-proposal\" // Any agent → Govern: proposes action\n  | \"memory-share\" // Any agent → Memory: shares insight\n  | \"conflict\" // Agent → Agent: detects conflicting intent\n  | \"handoff\" // Agent → Human: needs human intervention\n  | \"sync-request\"; // Agent → Connector: trigger sync\n\n/**\n * A2A Arbitration Result — produced by the Twin layer when conflicting intents detected.\n */\nexport interface A2AArbitration {\n  id: string;\n  tenantId: string;\n  conflictType: \"resource\" | \"priority\" | \"dependency\" | \"policy\";\n  conflictingIntents: string[];\n  resolution: \"merge\" | \"sequence\" | \"reject\" | \"escalate\";\n  mergedIntent?: A2AIntent;\n  sequence?: string[]; // Ordered intent IDs\n  reason: string;\n  arbitratedBy: string; // Twin instance ID\n  arbitratedAt: string;\n}\n```\n\n### E.4.3 A2A Flow — Cross-Sell Signal from Sales Twin to CS Twin\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│     A2A FLOW: Sales Twin Detects Upsell → CS Twin Takes Action              │\n│                                                                             │\n│  SALES TWIN (twin-orchestrator-sales)                                       │\n│     │                                                                       │\n│     │  1. OBSERVE: Account \"Acme Corp\" shows expansion signals              │\n│     │     (new team members, API usage spike)                               │\n│     │                                                                       │\n│     │  2. ORIENT: Entity360 shows CS health score = 0.91                    │\n│     │     Memory: recent positive NPS, no open tickets                      │\n│     │                                                                       │\n│     │  3. DECIDE: Publish \"cross-sell\" intent to Spine                      │\n│     ▼                                                                       │\n│  ┌─────────────────────────────────────────────────────────────────────┐    │\n│  │  A2AIntent:                                                         │    │\n│  │    agentId: \"twin-sales\"                                            │    │\n│  │    intentType: \"cross-sell\"                                         │    │\n│  │    target: { type: \"entity\", id: \"account:acme-corp\" }              │    │\n│  │    action: { verb: \"propose\", description: \"Upsell to Enterprise\",  │    │\n│  │              payload: { expansionSignals: [...] } }                 │    │\n│  │    confidence: 0.89                                                 │    │\n│  │    priority: \"high\"                                                 │    │\n│  └─────────────────────────────────────────────────────────────────────┘    │\n│     │                                                                       │\n│     │  POST via mcp-connector → Gateway → pipeline                          │\n│     ▼                                                                       │\n│  SPINE — intent stored in `a2a_intents` table (D1)                          │\n│     │                                                                       │\n│     │  4. TWIN LAYER (ambient) observes new intent                          │\n│     │     twin-orchestrator reads all unprocessed intents for tenant        │\n│     ▼                                                                       │\n│  CS TWIN (twin-orchestrator-cs)                                             │\n│     │                                                                       │\n│     │  5. Reads intent from Spine (WHERE tenant_id = ? AND agentId != self) │\n│     │                                                                       │\n│     │  6. ORIENT: Fetch Account context, recent tickets, NPS                │\n│     │                                                                       │\n│     │  7. DECIDE: Confidence = 0.87, agrees with upsell                     │\n│     │     Publishes response intent: \"action-proposal\" to govern            │\n│     ▼                                                                       │\n│  GOVERN — joint confidence = 0.88 (0.89 × 0.87 weighted)                    │\n│     │  ≥ 0.85 → AUTO-APPROVE                                              │\n│     ▼                                                                       │\n│  ACT — execute \"salesforce.opportunity.create\" + \"slack.notify-cs-channel\"  │\n│     │                                                                       │\n│     ▼                                                                       │\n│  PIPELINE — writeback to Spine                                              │\n│  CONTINUITY — compound into Organization Memory                             │\n│                                                                             │\n│  RESULT: CS team notified in Slack with full context. No manual routing.    │\n│          Audit trail: spine_audit_log entries for every step.               │\n└─────────────────────────────────────────────────────────────────────────────┘\n```\n\n### E.4.4 A2A Security Model\n\n| Threat                      | Mitigation                                       | Enforcement Point            |\n| --------------------------- | ------------------------------------------------ | ---------------------------- |\n| Agent impersonation         | JWT signing + `agent_id` registry                | `gateway` + `agent-registry` |\n| Cross-tenant intent leakage | `WHERE tenant_id = ?` on ALL intent queries      | All services                 |\n| Intent flooding             | Rate-limit per agent: 100 intents/min            | `gateway` + `hermes`         |\n| Circular dependencies       | Dependency graph validation (DAG check)          | `twin-orchestrator`          |\n| Priority inversion          | `critical` intents bypass normal queue           | `hermes` (queue priority)    |\n| Unauthorized arbitration    | Only `twin-orchestrator` instances may arbitrate | `govern` + RBAC              |\n\n---\n\n## E.5 SDK Variants\n\n### E.5.1 SDK Taxonomy\n\nThe Bridge exposes **five SDK variants** — same underlying contract, different fidelity and bundle size. Each variant is a separate npm package under the `@iw` scope.\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                        SDK VARIANT SPECTRUM                                │\n│                                                                             │\n│   ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────┐  ┌──────┐ │\n│   │ @iw/sdk-full│  │@iw/sdk-lite │  │@iw/sdk-content│ │@iw/sdk- │  │@iw/  │ │\n│   │             │  │             │  │               │ │ minimal │  │sdk-  │ │\n│   │  ~180 KB    │  │   ~85 KB    │  │    ~45 KB     │ │  ~12 KB │  │head- │ │\n│   │  gzipped    │  │   gzipped   │  │   gzipped     │ │ gzipped │  │less  │ │\n│   │             │  │             │  │               │ │         │  │~3 KB │ │\n│   └──────┬──────┘  └──────┬──────┘  └──────┬──────┘  └────┬────┘  └──┬───┘ │\n│          │                │                │              │          │     │\n│          ▼                ▼                ▼              ▼          ▼     │\n│    Full-stack      Browser/Node      Content-only    Telemetry   Server-  │\n│    SDK with        SDK with         SDK (read-only   + Events   side only │\n│    all features    streaming        Discovery +            (no UI)        │\n│    + UI helpers    + caching        Projections)                          │\n│                                                                             │\n│    Use case:       Use case:        Use case:      Use case:   Use case:   │\n│    Workbench       Web apps,        Mobile apps,   Analytics   Background  │\n│    builders,       dashboards,      embeddable     pipelines,  workers,    │\n│    extension       CLI tools        widgets        logging     edge        │\n│    developers                                                       functions│\n│                                                                             │\n└─────────────────────────────────────────────────────────────────────────────┘\n```\n\n### E.5.2 SDK Interface Contracts\n\n```typescript\n// ============================================================\n// @iw/sdk-full — The complete SDK (workbench + headless)\n// ============================================================\n\n\nexport interface SDKFullConfig {\n  /** Bridge endpoint */\n  baseUrl: string; // default: \"https://api.integratewise.ai\"\n\n  /** Authentication */\n  jwt: string;\n\n  /** Tenant context (optional — extracted from JWT if omitted) */\n  tenantId?: string;\n\n  /** MCP endpoint for AI assistant integration */\n  mcpEndpoint?: string; // default: \"https://mcp.integratewise.ai/v1/mcp\"\n\n  /** Enable React UI components */\n  enableUI: boolean;\n\n  /** UI theme config */\n  theme?: UIThemeConfig;\n\n  /** Real-time transport: 'sse' | 'ws' | 'polling' */\n  realtimeTransport: \"sse\" | \"ws\" | \"polling\";\n\n  /** Maximum reconnect attempts */\n  maxReconnects: number;\n\n  /** Debug mode */\n  debug: boolean;\n}\n\nexport class IWBridgeFull {\n  constructor(config: SDKFullConfig);\n\n  // ── Core Capabilities ──\n  invoke<T = unknown>(capability: string, payload: unknown): Promise<CapabilityInvokeResponse<T>>;\n  discover(): Promise<DiscoveryResponse>;\n  stream(capability: string, payload: unknown): AsyncIterable<StreamChunk>;\n\n  // ── Projections ──\n  getProjection(name: string, params?: Record<string, unknown>): Promise<Projection>;\n  listProjections(): Promise<ProjectionSummary[]>;\n\n  // ── Memory ──\n  queryMemory(query: MemoryQuery): Promise<MemoryResult[]>;\n  shareKnowledge(packet: KSPPacketInput): Promise<KSPPacket>;\n\n  // ── Agent ──\n  getTwin(): TwinSession;\n  listAgents(): Promise<AgentSummary[]>;\n  publishIntent(intent: A2AIntentInput): Promise<A2AIntent>;\n\n  // ── Governance ──\n  getProposals(filter?: ProposalFilter): Promise<Proposal[]>;\n  approveProposal(proposalId: string): Promise<void>;\n  rejectProposal(proposalId: string, reason?: string): Promise<void>;\n\n  // ── Real-time ──\n  onEvent(event: string, handler: EventHandler): Unsubscribe;\n  onIntent(handler: IntentHandler): Unsubscribe;\n\n  // ── UI Components (React) ──\n  Workbench: typeof WorkbenchUI;\n  TwinPanel: typeof TwinPanel;\n  MemoryExplorer: typeof MemoryExplorer;\n  ProposalQueue: typeof ProposalQueue;\n}\n\n// ============================================================\n// @iw/sdk-lite — Browser/Node SDK (no UI, with streaming)\n// ============================================================\n\n\nexport interface SDKLiteConfig {\n  baseUrl: string;\n  jwt: string;\n  tenantId?: string;\n  realtimeTransport: \"sse\" | \"polling\";\n  cacheEnabled: boolean;\n  cacheTtlSeconds: number;\n}\n\nexport class IWBridgeLite {\n  constructor(config: SDKLiteConfig);\n\n  invoke<T = unknown>(capability: string, payload: unknown): Promise<CapabilityInvokeResponse<T>>;\n  stream(capability: string, payload: unknown): AsyncIterable<StreamChunk>;\n  discover(): Promise<DiscoveryResponse>;\n  queryMemory(query: MemoryQuery): Promise<MemoryResult[]>;\n  onEvent(event: string, handler: EventHandler): Unsubscribe;\n\n  // Lite has no UI components, no Twin session, no governance actions\n}\n\n// ============================================================\n// @iw/sdk-content — Content/readonly SDK (smallest interactive)\n// ============================================================\n\n\nexport interface SDKContentConfig {\n  baseUrl: string;\n  jwt: string;\n  tenantId?: string;\n}\n\nexport class IWContentSDK {\n  constructor(config: SDKContentConfig);\n\n  // Read-only operations only\n  discover(): Promise<DiscoveryResponse>;\n  getProjection(name: string): Promise<Projection>;\n  queryMemory(query: MemoryQuery): Promise<MemoryResult[]>;\n\n  // No invoke, no stream, no write operations\n}\n\n// ============================================================\n// @iw/sdk-minimal — Telemetry + Events only\n// ============================================================\n\n\nexport interface SDKMinimalConfig {\n  baseUrl: string;\n  jwt: string;\n  tenantId?: string;\n}\n\nexport class IWMinimalSDK {\n  constructor(config: SDKMinimalConfig);\n\n  // Events and telemetry only\n  track(event: string, properties?: Record<string, unknown>): Promise<void>;\n  onEvent(event: string, handler: EventHandler): Unsubscribe;\n  health(): Promise<HealthStatus>;\n}\n\n// ============================================================\n// @iw/sdk-headless — Server-side / edge functions\n// ============================================================\n\n\nexport interface SDKHeadlessConfig {\n  baseUrl: string;\n  /** API Key (server-side only) OR JWT */\n  apiKey?: string;\n  jwt?: string;\n  tenantId: string; // Required for headless\n}\n\nexport class IWHeadlessSDK {\n  constructor(config: SDKHeadlessConfig);\n\n  // Full capability invocation (server-side has no governance gate —\n  // assumes calling service has already gated)\n  invoke<T = unknown>(capability: string, payload: unknown): Promise<CapabilityInvokeResponse<T>>;\n\n  // Batch operations\n  invokeBatch(requests: CapabilityInvokeRequest[]): Promise<CapabilityInvokeResponse[]>;\n\n  // Admin operations (requires admin scope)\n  getTenantConfig(): Promise<TenantConfig>;\n  updateTenantConfig(config: Partial<TenantConfig>): Promise<void>;\n\n  // No real-time, no UI, no streaming (server-side is request/response)\n}\n```\n\n### E.5.3 SDK Package Structure\n\n```\npackages/\n├── sdk-full/\n│   ├── src/\n│   │   ├── index.ts              # Main export: IWBridgeFull\n│   │   ├── client.ts             # HTTP client + retry logic\n│   │   ├── streaming.ts          # SSE/WebSocket stream handler\n│   │   ├── capabilities.ts       # Capability invocation wrappers\n│   │   ├── projections.ts        # Projection fetch + cache\n│   │   ├── memory.ts             # Memory query + KSP\n│   │   ├── agent.ts              # Twin session + A2A intents\n│   │   ├── governance.ts         # Proposal review actions\n│   │   ├── realtime.ts           # Event bus (SSE/WS/polling)\n│   │   ├── ui/                   # React components\n│   │   │   ├── Workbench.tsx\n│   │   │   ├── TwinPanel.tsx\n│   │   │   ├── MemoryExplorer.tsx\n│   │   │   └── ProposalQueue.tsx\n│   │   └── types.ts              # Re-exports from @iw/sdk-types\n│   ├── package.json\n│   └── tsconfig.json\n│\n├── sdk-lite/\n│   ├── src/\n│   │   ├── index.ts\n│   │   ├── client.ts             # Shared HTTP logic (same as sdk-full)\n│   │   ├── streaming.ts          # SSE only\n│   │   ├── capabilities.ts\n│   │   ├── projections.ts\n│   │   ├── memory.ts\n│   │   └── realtime.ts\n│   └── package.json\n│\n├── sdk-content/\n│   ├── src/\n│   │   ├── index.ts\n│   │   ├── client.ts             # Simple fetch wrapper\n│   │   ├── discovery.ts\n│   │   ├── projections.ts\n│   │   └── memory.ts             # Read-only queries\n│   └── package.json\n│\n├── sdk-minimal/\n│   ├── src/\n│   │   ├── index.ts\n│   │   ├── client.ts             # Tiny fetch wrapper (~2KB)\n│   │   ├── events.ts\n│   │   └── health.ts\n│   └── package.json\n│\n├── sdk-headless/\n│   ├── src/\n│   │   ├── index.ts\n│   │   ├── client.ts             # Node.js fetch / undici\n│   │   ├── capabilities.ts       # Full invoke + batch\n│   │   └── admin.ts              # Tenant management\n│   └── package.json\n│\n└── sdk-types/                    # SHARED types package (all SDKs depend on this)\n    ├── src/\n    │   ├── capability.ts\n    │   ├── discovery.ts\n    │   ├── ksp.ts\n    │   ├── a2a.ts\n    │   ├── memory.ts\n    │   ├── governance.ts\n    │   └── events.ts\n    └── package.json\n```\n\n### E.5.4 SDK Authentication Patterns\n\n```typescript\n// packages/sdk-types/src/auth.ts\n\n/**\n * Authentication contract for all SDK variants.\n * The Gateway is the single source of truth for auth.\n */\nexport interface SDKAuth {\n  /** JWT issued by Gateway (primary auth for browser clients) */\n  jwt?: string;\n\n  /** API Key for server-to-server calls */\n  apiKey?: string;\n\n  /** Tenant ID (extracted from JWT if omitted) */\n  tenantId?: string;\n\n  /** User ID (extracted from JWT if omitted) */\n  userId?: string;\n}\n\n/**\n * Every SDK request carries these headers:\n *\n * Authorization: Bearer <jwt_or_apikey>\n * x-tenant-id: <tenant_id>        ← injected by Gateway, never trusted from client\n * x-correlation-id: <uuid>         ← for distributed tracing\n * x-sdk-variant: <full|lite|content|minimal|headless>\n * x-sdk-version: <semver>\n */\n```\n\n---\n\n## E.6 Ecosystem App Composition Patterns\n\n### E.6.1 The Composition Model\n\n> **Third-party apps compose on the Bridge by consuming capabilities, not by importing internal services.** The Bridge is a capability platform, not a PaaS.\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                    ECOSYSTEM APP COMPOSITION PATTERNS                       │\n│                                                                             │\n│   ┌─────────────────────────────────────────────────────────────────────┐   │\n│   │                    THIRD-PARTY APP (e.g., CS Widget)                │   │\n│   │                                                                     │   │\n│   │  ┌─────────────┐   ┌─────────────┐   ┌─────────────┐               │   │\n│   │  │   @iw/sdk   │   │   @iw/sdk   │   │  @iw/sdk    │               │   │\n│   │  │  -content   │   │   -lite     │   │   -full     │               │   │\n│   │  │  (read-only)│   │  (streaming)│   │  (workbench)│               │   │\n│   │  └──────┬──────┘   └──────┬──────┘   └──────┬──────┘               │   │\n│   │         │                 │                 │                       │   │\n│   │         └─────────────────┴─────────────────┘                       │   │\n│   │                           │                                         │   │\n│   │                    ┌──────┴──────┐                                  │   │\n│   │                    │  Gateway    │                                  │   │\n│   │                    │  (JWT gate) │                                  │   │\n│   │                    └──────┬──────┘                                  │   │\n│   │                           │                                         │   │\n│   └───────────────────────────┼─────────────────────────────────────────┘   │\n│                               │                                             │\n│   ┌───────────────────────────┼─────────────────────────────────────────┐   │\n│   │         CONTINUITY BRIDGE │                                         │   │\n│   │                           ▼                                         │   │\n│   │  ┌─────────────┐   ┌─────────────┐   ┌─────────────┐               │   │\n│   │  │  Discovery  │   │  Capability │   │   Events    │               │   │\n│   │  │  (GET /api/ │   │  (POST /api/│   │  (SSE /api/ │               │   │\n│   │  │   v1/disco) │   │  v1/cap/...)│   │  v1/stream) │               │   │\n│   │  └─────────────┘   └─────────────┘   └─────────────┘               │   │\n│   │                                                                     │   │\n│   │  The app NEVER imports: services/, packages/spine-schema/, D1       │   │\n│   │  The app NEVER calls: act, pipeline, normalizer directly            │   │\n│   │                                                                     │   │\n│   └─────────────────────────────────────────────────────────────────────┘   │\n│                                                                             │\n│  COMPOSITION PATTERNS:                                                      │\n│  1. Embed Pattern      — iframe/widget using @iw/sdk-content                │\n│  2. Plugin Pattern     — browser extension using @iw/sdk-lite               │\n│  3. Workbench Pattern  — full app using @iw/sdk-full                        │\n│  4. Webhook Pattern    — server receives events, uses @iw/sdk-headless      │\n│  5. MCP Pattern        — AI assistant connects via MCP, no SDK needed       │\n│                                                                             │\n└─────────────────────────────────────────────────────────────────────────────┘\n```\n\n### E.6.2 Composition Patterns Catalog\n\n#### Pattern 1: Embed Pattern (iframe/widget)\n\n```typescript\n// Third-party app embeds a Bridge-powered widget\n\nconst sdk = new IWContentSDK({\n  baseUrl: \"https://api.integratewise.ai\",\n  jwt: getTenantJWT(), // From host app auth\n});\n\n// Fetch discovery to learn what's available\nconst discovery = await sdk.discover();\n\n// Render a read-only account health widget\nconst projection = await sdk.getProjection(\"cs-health\", {\n  accountId: props.accountId,\n});\n\n// Mount React component (if using @iw/sdk-full)\n// Or render raw HTML from projection data\n```\n\n**Security:** Embed runs in sandboxed iframe. Host app provides JWT via `postMessage`. SDK validates JWT on every call.\n\n#### Pattern 2: Plugin Pattern (browser extension)\n\n```typescript\n// Browser extension content script\n\nconst bridge = new IWBridgeLite({\n  baseUrl: \"https://api.integratewise.ai\",\n  jwt: await chrome.storage.local.get(\"iw_jwt\"),\n  realtimeTransport: \"sse\",\n  cacheEnabled: true,\n});\n\n// Listen for Twin proposals while user browses Salesforce\nbridge.onEvent(\"twin.proposal\", (proposal) => {\n  showInPageNotification(proposal);\n});\n\n// Invoke capability from any page\nbridge.invoke(\"salesforce.opportunity.update\", {\n  opportunityId: extractIdFromPage(),\n  stage: \"Closed Won\",\n});\n```\n\n**Security:** Extension manifest declares `api.integratewise.ai` as allowed host. CORS preflight validated by Gateway.\n\n#### Pattern 3: Workbench Pattern (full app)\n\n```typescript\n// Custom workbench built on Bridge\n\nconst bridge = new IWBridgeFull({\n  baseUrl: 'https://api.integratewise.ai',\n  jwt: auth.jwt,\n  enableUI: true,\n  theme: customTheme,\n  realtimeTransport: 'ws',\n});\n\n// Render full workbench with Twin panel\nfunction App() {\n  return (\n    <div className=\"workbench\">\n      <bridge.Workbench projection=\"sales\" />\n      <bridge.TwinPanel />\n      <bridge.MemoryExplorer />\n      <bridge.ProposalQueue />\n    </div>\n  );\n}\n```\n\n**Security:** Full SDK requires `scope: workbench` in JWT. UI components are sandboxed React trees with CSP.\n\n#### Pattern 4: Webhook Pattern (server-side integration)\n\n```typescript\n// Third-party server receives Bridge webhooks\n\nconst bridge = new IWHeadlessSDK({\n  baseUrl: \"https://api.integratewise.ai\",\n  apiKey: process.env.IW_API_KEY,\n  tenantId: process.env.IW_TENANT_ID,\n});\n\n// Webhook handler\napp.post(\"/webhooks/iw\", async (req, res) => {\n  const event = req.body;\n\n  // Verify webhook signature\n  verifyWebhookSignature(req);\n\n  switch (event.type) {\n    case \"proposal.approved\":\n      await bridge.invoke(\"slack.notify\", {\n        channel: \"#ops\",\n        message: `Proposal approved: ${event.proposalId}`,\n      });\n      break;\n\n    case \"memory.promoted\":\n      await syncToExternalKB(event.memory);\n      break;\n  }\n\n  res.sendStatus(200);\n});\n```\n\n**Security:** Webhook signatures use HMAC-SHA256. API keys are server-side only. Never exposed to browser.\n\n#### Pattern 5: MCP Pattern (AI assistant integration)\n\n```json\n// No SDK needed — AI assistant connects via MCP directly\n{\n  \"mcpServers\": {\n    \"integratewise\": {\n      \"type\": \"sse\",\n      \"url\": \"https://mcp.integratewise.ai/v1/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer ${IW_JWT}\"\n      }\n    }\n  }\n}\n```\n\n**Security:** MCP connection is read-only by default. Write capabilities require `scope: write` + governance approval.\n\n### E.6.3 App Manifest Contract\n\n```typescript\n// packages/sdk-types/src/manifest.ts\n\n/**\n * Ecosystem App Manifest — every third-party app registers with the Bridge.\n */\nexport interface EcosystemAppManifest {\n  /** Unique app ID (reverse DNS) */\n  id: string; // e.g., \"com.acme.cswidget\"\n\n  /** Human name */\n  name: string;\n\n  /** Description for Discovery */\n  description: string;\n\n  /** App type */\n  type: \"embed\" | \"plugin\" | \"workbench\" | \"webhook\" | \"mcp-client\";\n\n  /** Required SDK variant */\n  sdkVariant: \"content\" | \"lite\" | \"full\" | \"headless\";\n\n  /** Minimum SDK version */\n  minSdkVersion: string;\n\n  /** Required scopes */\n  requiredScopes: string[];\n\n  /** Capabilities this app consumes */\n  consumedCapabilities: string[];\n\n  /** Capabilities this app provides (if any) */\n  providedCapabilities?: Capability[];\n\n  /** Webhook URL (for webhook-type apps) */\n  webhookUrl?: string;\n\n  /** Content Security Policy */\n  csp: {\n    allowedOrigins: string[];\n    allowedConnectSrc: string[];\n  };\n\n  /** Data handling */\n  dataHandling: {\n    storesDataLocally: boolean;\n    cachesInBrowser: boolean;\n    piiAccess: boolean;\n  };\n\n  /** Registration */\n  registeredBy: string; // User ID\n  registeredAt: string;\n  status: \"pending\" | \"approved\" | \"rejected\" | \"revoked\";\n}\n```\n\n---\n\n## E.7 Template Starter (`create-iw-app`)\n\n### E.7.1 Template Architecture\n\n```\ncreate-iw-app/\n├── templates/\n│   ├── embed-widget/           # Pattern 1: iframe/widget\n│   │   ├── package.json\n│   │   ├── src/\n│   │   │   ├── main.ts         # Widget entry point\n│   │   │   ├── bridge.ts       # @iw/sdk-content init\n│   │   │   └── widget.tsx      # React widget component\n│   │   └── README.md\n│   │\n│   ├── browser-extension/      # Pattern 2: browser plugin\n│   │   ├── manifest.json\n│   │   ├── src/\n│   │   │   ├── background.ts   # Service worker\n│   │   │   ├── content.ts      # Content script\n│   │   │   ├── bridge.ts       # @iw/sdk-lite init\n│   │   │   └── popup.tsx       # Extension popup\n│   │   └── README.md\n│   │\n│   ├── workbench-app/          # Pattern 3: full workbench\n│   │   ├── package.json\n│   │   ├── src/\n│   │   │   ├── App.tsx\n│   │   │   ├── bridge.ts       # @iw/sdk-full init\n│   │   │   ├── pages/\n│   │   │   │   ├── Dashboard.tsx\n│   │   │   │   ├── TwinPage.tsx\n│   │   │   │   └── Settings.tsx\n│   │   │   └── components/\n│   │   └── README.md\n│   │\n│   ├── webhook-server/         # Pattern 4: server-side webhook\n│   │   ├── package.json\n│   │   ├── src/\n│   │   │   ├── server.ts       # Express/Fastify server\n│   │   │   ├── bridge.ts       # @iw/sdk-headless init\n│   │   │   ├── webhooks.ts     # Webhook handlers\n│   │   │   └── verify.ts       # Signature verification\n│   │   └── README.md\n│   │\n│   └── mcp-client/             # Pattern 5: AI assistant client\n│       ├── package.json\n│       ├── src/\n│       │   ├── client.ts       # MCP client setup\n│       │   └── prompts/        # System prompts for Bridge\n│       └── README.md\n│\n├── src/\n│   ├── index.ts                # CLI entry: create-iw-app <template>\n│   ├── init.ts                 # Project scaffolding logic\n│   └── validate.ts             # Manifest validation\n│\n├── package.json\n└── README.md\n```\n\n### E.7.2 Template Quick-Start\n\n```bash\n# Install the CLI\nnpm install -g @iw/create-app\n\n# Create a new ecosystem app\ncreate-iw-app my-cs-widget --template embed-widget --sdk content\n\n# Templates: embed-widget | browser-extension | workbench-app | webhook-server | mcp-client\n# SDKs:      content | lite | full | minimal | headless\n\ncd my-cs-widget\nnpm install\nnpm run dev          # Local dev server with Bridge sandbox\nnpm run build        # Production build\nnpm run register     # Register app manifest with Bridge\n```\n\n### E.7.3 Template Bootstrap Code\n\n```typescript\n// templates/embed-widget/src/bridge.ts\n\n\n/**\n * Bridge client initialization for embed widget pattern.\n * The host page injects the JWT via window.postMessage.\n */\n  return new IWContentSDK({\n    baseUrl: import.meta.env.VITE_BRIDGE_URL || \"https://api.integratewise.ai\",\n    jwt: extractJWTFromParent(),\n  });\n}\n\nfunction extractJWTFromParent(): string {\n  // Host app sends JWT via postMessage\n  return new Promise((resolve) => {\n    window.addEventListener(\"message\", (e) => {\n      if (e.origin !== \"https://app.integratewise.ai\") return;\n      if (e.data.type === \"IW_JWT\") resolve(e.data.jwt);\n    });\n  });\n}\n\n// ───────────────────────────────────────────────────────────────────────────\n// templates/workbench-app/src/bridge.ts\n// ───────────────────────────────────────────────────────────────────────────\n\n\n  baseUrl: import.meta.env.VITE_BRIDGE_URL,\n  jwt: localStorage.getItem(\"iw_jwt\")!,\n  enableUI: true,\n  theme: {\n    primary: \"#0F172A\",\n    accent: \"#3B82F6\",\n    surface: \"#F8FAFC\",\n  },\n  realtimeTransport: \"ws\",\n  maxReconnects: 5,\n  debug: import.meta.env.DEV,\n});\n\n// Auto-refresh JWT before expiry\nbridge.onEvent(\"auth.token_expiring\", async () => {\n  const newToken = await refreshToken();\n  bridge.setJWT(newToken);\n});\n\n// ───────────────────────────────────────────────────────────────────────────\n// templates/webhook-server/src/bridge.ts\n// ───────────────────────────────────────────────────────────────────────────\n\n\n  baseUrl: process.env.BRIDGE_URL!,\n  apiKey: process.env.IW_API_KEY!,\n  tenantId: process.env.IW_TENANT_ID!,\n});\n\n// Health check on startup\nbridge.health().then((status) => {\n  if (status.status !== \"healthy\") {\n    console.error(\"Bridge unhealthy:\", status);\n    process.exit(1);\n  }\n});\n```\n\n---\n\n## E.8 Integration Points with Adjacent Layers\n\n### E.8.1 North-South Integration Matrix\n\n| Ecosystem Component     | North Bound (Ingress)                   | South Bound (Egress)                        | Adjacent Layer          |\n| ----------------------- | --------------------------------------- | ------------------------------------------- | ----------------------- |\n| **Capability Registry** | Discovery API (`GET /api/v1/discovery`) | `agent-registry` service binding            | Identity + Capability   |\n| **Capability Router**   | `HERMES` queue consumer                 | `ACT_QUEUE` producer                        | Capability + Governance |\n| **KSP Packet Bus**      | `mcp-connector` inbound                 | `knowledge` + `continuity` service bindings | Continuity + Knowledge  |\n| **A2A Intent Bus**      | `twin-orchestrator` read                | `pipeline` write + `spine_audit_log`        | Continuity + Governance |\n| **SDK Client**          | `gateway` HTTP/SSE                      | Consumer app runtime                        | Identity (JWT)          |\n| **Template Starter**    | `gateway` registration API              | `agent-registry` manifest storage           | Registry                |\n\n### E.8.2 Service Binding Map (Ecosystem-Relevant)\n\n```typescript\n// apps/gateway/src/bindings.ts — Ecosystem-relevant bindings\n\nexport interface ServiceBindings {\n  // Tier 0 — Ingress\n  GATEWAY: Fetcher; // Self\n  WEBHOOK_INGRESS: Fetcher;\n\n  // Tier 1 — Tenant & Sync\n  TENANTS: Fetcher;\n  CONNECTOR: Fetcher;\n  CONNECTOR_SYNC: Fetcher;\n  NORMALIZER: Fetcher;\n  LOADER: Fetcher;\n\n  // Tier 2 — Projection (Ecosystem reads these)\n  PIPELINE: Fetcher; // Spine writer — ecosystem NEVER calls directly\n  TWIN_ORCHESTRATOR: Fetcher; // OODA engine — ecosystem routes through Gateway\n  L2: Fetcher;\n  INTELLIGENCE: Fetcher; // Context assembly\n  KNOWLEDGE: Fetcher; // KSP semantic layer\n  GOVERN: Fetcher; // Governance gate\n  STORE: Fetcher;\n  ACT: Fetcher; // Outbound execution — ecosystem NEVER calls directly\n  SPINE_V2: Fetcher;\n\n  // Tier 3 — Runtime (Ecosystem orchestrates through these)\n  HERMES: Fetcher; // Message queue — primary ecosystem router\n  TRIAGE: Fetcher; // Confidence routing (runs inside Hermes)\n  WORKFLOW: Fetcher;\n  IW_AGENT_RUNTIME: Fetcher; // Agent sandbox\n  MCP_CONNECTOR: Fetcher; // Inbound MCP pool\n\n  // Tier 4 — Supporting (Ecosystem metadata)\n  AGENT_REGISTRY: Fetcher; // Capability catalog\n  BILLING: Fetcher;\n  ADMIN: Fetcher;\n  FOLDER_WATCHER: Fetcher;\n  CONTINUITY: Fetcher; // Memory substrate\n  TELEMETRY: Fetcher;\n  THINK: Fetcher; // LLM orchestration\n}\n```\n\n### E.8.3 Queue Topology (Ecosystem-Relevant)\n\n| Queue                        | Publisher                     | Consumer            | Purpose                                | Ecosystem Role                 |\n| ---------------------------- | ----------------------------- | ------------------- | -------------------------------------- | ------------------------------ |\n| `DISCOVERY_CACHE_INVALIDATE` | `agent-registry`, `connector` | `gateway`           | Cache bust on capability changes       | Keeps Discovery fresh          |\n| `ACT_QUEUE`                  | `hermes`, `govern`            | `act`               | Approved action execution              | Ecosystem actions execute here |\n| `PIPELINE_QUEUE`             | `act`, `normalizer`           | `pipeline`          | Spine write requests                   | Ecosystem results written here |\n| `KSP_BROADCAST`              | `knowledge`, `continuity`     | `hermes`            | Knowledge packet distribution          | KSP fan-out                    |\n| `A2A_INTENT`                 | `twin-orchestrator`           | `twin-orchestrator` | Intent publication (self-consuming DO) | A2A blackboard                 |\n| `NOTIFICATION_SSE`           | `hermes`                      | `gateway`           | SSE push to connected clients          | Real-time ecosystem updates    |\n| `CONNECTOR_SYNC_QUEUE`       | `loader`, `connector-sync`    | `connector-sync`    | Provider sync jobs                     | Ecosystem data freshness       |\n\n---\n\n## E.9 Security Boundaries\n\n### E.9.1 Ecosystem Security Model\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                    ECOSYSTEM SECURITY BOUNDARIES                            │\n│                                                                             │\n│   ┌─────────────────────────────────────────────────────────────────────┐   │\n│   │  LAYER 1: Identity Gate (Gateway)                                   │   │\n│   │  • JWT validation (RS256)                                           │   │\n│   │  • tenant_id extraction from JWT claim ONLY                         │   │\n│   │  • Rate-limit per tenant: 1000 req/min (pro), 100 req/min (free)    │   │\n│   │  • API Key rotation (90 days)                                       │   │\n│   └─────────────────────────────────────────────────────────────────────┘   │\n│                              │                                              │\n│   ┌──────────────────────────┼──────────────────────────────────────────┐   │\n│   │  LAYER 2: Capability Gate (agent-registry + Gateway)                │   │\n│   │  • Discovery filtered by tenant plan + RBAC                         │   │\n│   │  • Capability schema validation on invoke                           │   │\n│   │  • Scope enforcement: `scope: read` default, `scope: write` opt-in  │   │\n│   │  • Deprecated capabilities hidden after sunset date                 │   │\n│   └─────────────────────────────────────────────────────────────────────┘   │\n│                              │                                              │\n│   ┌──────────────────────────┼──────────────────────────────────────────┐   │\n│   │  LAYER 3: Governance Gate (govern)                                  │   │\n│   │  • Confidence scoring: ≥0.85 auto, 0.70–0.85 HITL, <0.70 discard    │   │\n│   │  • Proposal expiry: 48 hours default                                │   │\n│   │  • Audit: every decision → spine_audit_log                          │   │\n│   │  • Escalation: L4 capabilities NEVER auto-execute                   │   │\n│   └─────────────────────────────────────────────────────────────────────┘   │\n│                              │                                              │\n│   ┌──────────────────────────┼──────────────────────────────────────────┐   │\n│   │  LAYER 4: Memory Gate (continuity + triage)                         │   │\n│   │  • KSP packet validation: tenant_id, scope, classification          │   │\n│   │  • Memory triage: ≥0.85 active, 0.70–0.85 staging, <0.70 discard    │   │\n│   │  • Retention: active 30 days, staging 90 days, archived 7 years     │   │\n│   │  • Cross-scope leakage: personal < work < org < ai (HARD filter)    │   │\n│   └─────────────────────────────────────────────────────────────────────┘   │\n│                              │                                              │\n│   ┌──────────────────────────┼──────────────────────────────────────────┐   │\n│   │  LAYER 5: Execution Gate (act + adapters)                           │   │\n│   │  • Credential wall: per-tenant, never shared                        │   │\n│   │  • Adapter sandbox: provider errors don't crash Bridge              │   │\n│   │  • Circuit breaker: 5 errors → 30s cooldown                         │   │\n│   │  • Entity360 injection: context enriched before outbound call       │   │\n│   └─────────────────────────────────────────────────────────────────────┘   │\n│                                                                             │\n└─────────────────────────────────────────────────────────────────────────────┘\n```\n\n### E.9.2 SDK Security Invariants\n\n| Invariant                                                    | Enforcement                       | Violation                               |\n| ------------------------------------------------------------ | --------------------------------- | --------------------------------------- |\n| **JWT never stored in localStorage for SDK-headless**        | Server-side API keys only         | SDK-headless throws if jwt provided     |\n| **SDK-content never invokes write capabilities**             | Runtime schema check              | 403 from Gateway                        |\n| **SDK-lite streaming requires `scope: stream`**              | JWT scope validation              | SSE connection rejected                 |\n| **Cross-origin SDK calls require app manifest registration** | Gateway CORS + manifest check     | 403 with `X-IW-App-Not-Registered`      |\n| **SDK version compatibility checked on every call**          | `x-sdk-version` header validation | 426 Upgrade Required                    |\n| **KSP packets without tenant_id are quarantined**            | `continuity` validation           | Packet logged to `ksp_quarantine` table |\n\n---\n\n## E.10 Metrics & Observability\n\n### E.10.1 Ecosystem Metrics\n\n```typescript\n// packages/sdk-types/src/telemetry.ts\n\nexport interface EcosystemMetrics {\n  // Capability Fabric\n  \"capability.invocations.total\": Counter;\n  \"capability.invocations.success\": Counter;\n  \"capability.invocations.error\": Counter;\n  \"capability.invocations.latency\": Histogram; // ms\n  \"capability.discovery.cache_hit_rate\": Gauge; // 0–1\n\n  // KSP\n  \"ksp.packets.sent\": Counter;\n  \"ksp.packets.received\": Counter;\n  \"ksp.packets.quarantined\": Counter;\n  \"ksp.memory.promoted\": Counter;\n  \"ksp.memory.staged\": Counter;\n  \"ksp.memory.discarded\": Counter;\n\n  // A2A\n  \"a2a.intents.published\": Counter;\n  \"a2a.intents.resolved\": Counter;\n  \"a2a.conflicts.detected\": Counter;\n  \"a2a.arbitrations.completed\": Counter;\n\n  // SDK\n  \"sdk.connections.active\": Gauge; // Per variant\n  \"sdk.streaming.bytes\": Counter;\n  \"sdk.errors.timeout\": Counter;\n  \"sdk.errors.auth\": Counter;\n\n  // Ecosystem Apps\n  \"ecosystem.apps.registered\": Gauge;\n  \"ecosystem.apps.invocations\": Counter; // Per app ID\n}\n```\n\n---\n\n## E.11 Glossary\n\n| Term                  | Definition                                                                                                                          |\n| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |\n| **Capability**        | A named, versioned, discoverable business action with a strict input/output schema.                                                 |\n| **Capability Fabric** | The mesh of registries, routers, and execution engines that makes capabilities composable.                                          |\n| **KSP**               | Knowledge Sharing Protocol — the schema and governance contract for moving knowledge between ecosystem participants.                |\n| **A2A**               | Agent-to-Agent communication — Spine-based coordination (not peer-to-peer).                                                         |\n| **Discovery**         | The canonical API (`GET /api/v1/discovery`) that tells consumers what exists and what they can do.                                  |\n| **Twin**              | The ambient reasoning layer — not a separate entity, but the emergent property of OODA across the Capability and Continuity layers. |\n| **Spine**             | The single source of truth for context — entities, relationships, memory, audit.                                                    |\n| **OODA**              | Observe → Orient → Decide → Act — the decision cycle running across Capability and Continuity.                                      |\n| **Governance Gate**   | The 0.70/0.85 confidence threshold system that governs execution and memory promotion.                                              |\n\n---\n\n## E.12 Version History\n\n| Version | Date       | Changes                                                                                                                                                                                                       |\n| ------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| v1.0.0  | 2026-06-15 | Initial ecosystem specification (part of FINAL_E2E_SYSTEM)                                                                                                                                                    |\n| v2.0.0  | 2026-07-02 | **This document.** Separate Capability Fabric, KSP, A2A, SDK variants, composition patterns, template starter. SDK split into 5 variants. A2A formalized as Spine-based (not P2P). KSP packet schema defined. |\n\n---\n\n**END OF DOCUMENT**\n\n_IntegrateWise Continuity Bridge v2.0 — Ecosystem Architecture & SDK Specification. This is the definitive reference for the Capability Fabric Model, Knowledge Sharing Protocol, Agent-to-Agent Communication, SDK Variants, Ecosystem App Composition Patterns, and Template Starter domains._\n"}