Unclassified

§E — Ecosystem Architecture & SDK Specification

Status: SUPERSEDED DEEP-DIVE. The old product name, layer model and
permanent Twin-panel examples are historical only. Current Capability,
Workbench and Silent Twin rules live in
ARCHITECTURE_LOCK.md and
TWIN_BEHAVIOR.md.

IntegrateWise Continuity Bridge v2.0 — Capability Fabric, Knowledge Protocol, A2A, SDK Variants, Composition Patterns

Status: DRAFT v2.0 — Stage 1/2 Deep-Dive
Domain Owner: Ecosystem Architecture & SDK
Supersedes: v1.0.1 §5 (MCP Pool), §9 (Discovery), §12.4 (A2A), §18 (Registry), §26 (Template) where conflicting.
Date: 2026-07-02


E.1 Doctrine — What the Ecosystem Layer Is

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.

The Ecosystem Layer sits conceptually across the Capability and Continuity layers of the 6-layer stack. It is the substrate that enables:

  1. Capability Fabric Model — How named business capabilities are discovered, composed, and executed across the mesh.
  2. Knowledge Sharing Protocol (KSP) — How memory, context, and evidence move between agents, tools, and humans without leaking tenant boundaries.
  3. Agent-to-Agent Communication (A2A) — How autonomous agents coordinate through the Spine (not peer-to-peer), governed by the Twin ambient reasoning layer.
  4. SDK Variants — Five consumer-facing SDK packages that expose the same contract at different fidelity levels.
  5. Ecosystem App Composition Patterns — How third-party developers build on the Bridge without importing internal topology.
  6. Template Starter — The canonical create-iw-app bootstrap for ecosystem participants.

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.


E.2 The Capability Fabric Model

E.2.1 Conceptual Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                         ECOSYSTEM CAPABILITY FABRIC                         │
│                                                                             │
│   ┌─────────────┐    ┌─────────────┐    ┌─────────────┐    ┌─────────────┐ │
│   │  Capability │◄──►│  Capability │◄──►│  Capability │◄──►│  Capability │ │
│   │   Registry  │    │   Router    │    │   Sandbox   │    │   Monitor   │ │
│   │(agent-registry)  │  (hermes)   │    │(iw-agent-  │    │ (telemetry) │ │
│   └──────┬──────┘    └──────┬──────┘    │  runtime)   │    └─────────────┘ │
│          │                  │            └─────────────┘                    │
│          ▼                  ▼                                               │
│   ┌─────────────────────────────────────────────────────────────────────┐  │
│   │                    SPINE — The Single Source of Truth               │  │
│   │         (entities, relationships, memory, audit, continuity)        │  │
│   └─────────────────────────────────────────────────────────────────────┘  │
│                              ▲                                              │
│   ┌─────────────┐    ┌───────┴───────┐    ┌─────────────┐    ┌──────────┐ │
│   │   Inbound   │    │    Twin       │    │   Outbound  │    │  Shared  │ │
│   │   MCP Pool  │◄──►│  (ambient)    │◄──►│   MCP Pool  │◄──►│  Memory  │ │
│   │(mcp-connector)    │(twin-orchestrator)  │  (act +    │    │(continuity│ │
│   └─────────────┘    └─────────────┘    │   adapters)   │    └──────────┘ │
│                                         └─────────────┘                   │
└─────────────────────────────────────────────────────────────────────────────┘
                              ▲
        Consumers ────────────┴───────────── SDKs, AI Assistants, Web Workbench

E.2.2 Capability Taxonomy

Every capability in the ecosystem is a named, versioned, discoverable action with a strict contract:

// packages/sdk/src/types/capability.ts

/**
 * Capability — the atomic unit of the Capability Fabric.
 * Every capability is: named, versioned, scoped, gated, and audited.
 */
export interface Capability {
  /** Canonical capability ID: `{domain}.{resource}.{action}` */
  id: string; // e.g., "salesforce.opportunity.create"

  /** Semantic version of the capability contract */
  version: string; // e.g., "2.1.0"

  /** Human-readable name */
  name: string;

  /** Markdown description for Discovery */
  description: string;

  /** The provider that owns this capability */
  provider: string; // e.g., "salesforce", "slack", "iw-native"

  /** Capability tier: L1=read, L2=insight, L3=execute, L4=autonomous */
  level: 1 | 2 | 3 | 4;

  /** Required scopes to invoke */
  scopes: string[]; // e.g., ["read:opportunities", "write:opportunities"]

  /** Input JSON Schema (for validation + UI generation) */
  inputSchema: JSONSchema7;

  /** Output JSON Schema */
  outputSchema: JSONSchema7;

  /** Governance gate required? */
  governanceGate: boolean; // true for L3/L4, false for L1/L2

  /** Minimum confidence threshold for auto-execution */
  autoExecuteThreshold: number; // 0.85 default for L3, 1.0 (never auto) for L4

  /** Whether this capability supports streaming (SSE) responses */
  streaming: boolean;

  /** Estimated cost in tokens / compute units */
  costEstimate: CostEstimate;

  /** Deprecation status */
  deprecation?: {
    deprecatedAt: string; // ISO date
    sunsetAt: string; // ISO date
    replacement?: string; // capability ID of replacement
  };
}

export interface CostEstimate {
  /** Token estimate for LLM-based capabilities */
  tokens?: { input: number; output: number };

  /** External API call cost estimate (USD) */
  apiCalls?: { count: number; estimatedCost: number };

  /** Compute time estimate (ms) */
  computeMs: number;
}

/** Capability invocation request — what consumers send */
export interface CapabilityInvokeRequest {
  /** The capability to invoke */
  capability: string;

  /** Tenant context (injected by Gateway, never from client) */
  tenantId: string;

  /** User context (injected by Gateway from JWT) */
  userId: string;

  /** Correlation ID for distributed tracing */
  correlationId: string;

  /** Invocation payload — validated against capability.inputSchema */
  payload: unknown;

  /** Execution preferences */
  options?: {
    /** Prefer streaming response? */
    streaming?: boolean;

    /** Maximum wait time (ms) before async handoff */
    timeoutMs?: number;

    /** Whether to compound result into memory */
    compoundMemory?: boolean;

    /** Required confidence threshold override */
    confidenceThreshold?: number;
  };
}

/** Capability invocation response */
export interface CapabilityInvokeResponse {
  correlationId: string;
  status: "success" | "pending" | "rejected" | "error" | "async";
  result?: unknown;
  proposalId?: string; // Present if governance-gated
  confidence?: number; // Governance confidence score
  auditLogId: string; // Reference to spine_audit_log entry
  executionTimeMs: number;
}

E.2.3 Capability Discovery & Routing

┌─────────────────────────────────────────────────────────────────────────────┐
│                     CAPABILITY DISCOVERY & ROUTING FLOW                     │
│                                                                             │
│  Consumer                          Gateway                        Discovery │
│     │                                │                              Cache   │
│     │  GET /api/v1/discovery         │                                 │   │
│     │ ─────────────────────────────► │                                 │   │
│     │                                │  1. Extract tenantId from JWT   │   │
│     │                                │  2. Query KV cache (5-min TTL)  │   │
│     │                                │                                 │   │
│     │                                │ ◄──── cached Discovery? ───────►│   │
│     │                                │                                 │   │
│     │                                │  [Cache MISS]                   │   │
│     │                                │     │                           │   │
│     │                                │     ▼                           │   │
│     │                                │  3. Fetch from agent-registry   │   │
│     │                                │     (service binding)           │   │
│     │                                │                                 │   │
│     │                                │  4. agent-registry queries:     │   │
│     │                                │     - capability_registry (D1)  │   │
│     │                                │     - endpoint_registry (D1)    │   │
│     │                                │     - connector status (KV)     │   │
│     │                                │                                 │   │
│     │                                │  5. Filter by tenant plan + RBAC │   │
│     │                                │                                 │   │
│     │                                │  6. Write to KV cache           │   │
│     │                                │                                 │   │
│     │  DiscoveryResponse             │                                 │   │
│     │ ◄───────────────────────────── │                                 │   │
│     │                                │                                 │   │
└─────────────────────────────────────────────────────────────────────────────┘

Discovery Response Contract:

// packages/sdk/src/types/discovery.ts

export interface DiscoveryResponse {
  /** Identity context */
  identity: {
    userId: string;
    tenantId: string;
    orgId: string;
    role: string;
    scopes: string[];
  };

  /** Workspace configuration */
  workspace: {
    name: string;
    plan: "free" | "pro" | "enterprise";
    connectedProviders: string[];
    limits: WorkspaceLimits;
  };

  /** Available projections (8 lenses) */
  projections: Projection[];

  /** Available capabilities — FILTERED by tenant plan + RBAC */
  capabilities: CapabilitySummary[];

  /** Available agents in the ecosystem */
  agents: AgentSummary[];

  /** Knowledge sources available */
  knowledgeSources: KnowledgeSource[];

  /** Navigation structure for the workbench */
  navigation: NavNode[];

  /** Personalization */
  personalization: {
    recentCapabilities: string[];
    pinnedProjections: string[];
    preferences: Record<string, unknown>;
  };

  /** SDK version compatibility */
  sdkVersion: string;

  /** Bridge version */
  bridgeVersion: string;
}

export interface CapabilitySummary {
  id: string;
  name: string;
  description: string;
  level: 1 | 2 | 3 | 4;
  provider: string;
  category: string;
  scopes: string[];
  streaming: boolean;
  /** Whether currently available (provider connected + healthy) */
  available: boolean;
}

export interface AgentSummary {
  id: string;
  name: string;
  description: string;
  capabilities: string[];
  status: "active" | "idle" | "maintenance";
}

export interface KnowledgeSource {
  id: string;
  name: string;
  type: "spine" | "memory" | "document" | "connector";
  entityTypes: string[];
}

E.2.4 Capability Execution Flow

Consumer → Gateway → hermes (queue) → twin-orchestrator (OODA) → govern (gate) → act (execute)
                                              │
                                              ▼
                                    ┌─────────────────┐
                                    │   SPINE READ    │
                                    │  Entity360 +    │
                                    │  Memory + RAG   │
                                    └─────────────────┘

Detailed Execution Flow:

StepServiceQueue/BindingActionSecurity Boundary
1gatewayN/AValidate JWT, extract tenant_id, assemble correlationIdIdentity Layer
2gatewayHERMES (service binding)Enqueue CapabilityInvokeRequest to HermesIngress → Capability
3hermesACT_QUEUEDO acquires message, checks idempotency keyCapability Layer
4hermesTWIN_ORCHESTRATOR (binding)If L2/L3/L4, route to Twin for OODACapability → Continuity
5twin-orchestratorD1 + KV + VectorizeOrient: assemble Entity360 + Memory + KnowledgeContinuity Layer
6twin-orchestratorTHINK (binding)Decide: LLM reasoning, proposal generationContinuity Layer
7twin-orchestratorGOVERN (binding)Confidence scoring, proposal emissionGovernance Layer
8governD1 action_proposalsGate: ≥0.85 auto, 0.70-0.85 HITL, <0.70 discardGovernance Layer
9governACT_QUEUEApproved → enqueue to actGovernance → Provider
10actD1 + outbound adaptersExecute: adapter selection, credential wall, Entity360 injectionProvider Fabric
11actPIPELINE_QUEUEWriteback: result → Pipeline → SpineProvider → Spine
12pipelineD1 entities + spine_audit_logCommit: ONLY writer to SpineSpine Integrity
13continuityD1 memory + KVRemember: compound into memory tiersMemory Layer

E.3 Knowledge Sharing Protocol (KSP)

E.3.1 Protocol Overview

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.

┌─────────────────────────────────────────────────────────────────────────────┐
│                    KNOWLEDGE SHARING PROTOCOL (KSP)                         │
│                                                                             │
│   ┌──────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐          │
│   │  Agent A │◄───►│  SPINE   │◄───►│  Agent B │◄───►│  Human   │          │
│   │ (twin-A) │     │ (shared) │     │ (twin-B) │     │ (desk)   │          │
│   └────┬─────┘     └────┬─────┘     └────┬─────┘     └────┬─────┘          │
│        │                │                │                │                │
│        │   KSP Packet   │   KSP Packet   │   KSP Packet   │                │
│        │   (scoped)     │   (scoped)     │   (scoped)     │                │
│        │                │                │                │                │
│   ┌────▼────────────────▼────────────────▼────────────────▼─────┐          │
│   │              KSP GOVERNANCE LAYER (govern)                  │          │
│   │  • tenant_id isolation (HARD)                               │          │
│   │  • scope validation (read/write/admin)                      │          │
│   │  • confidence scoring (0.70/0.85)                           │          │
│   │  • audit trail (spine_audit_log)                            │          │
│   │  • retention policy (D1 + R2)                               │          │
│   └─────────────────────────────────────────────────────────────┘          │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

E.3.2 KSP Packet Schema

// packages/sdk/src/types/ksp.ts

/**
 * Knowledge Sharing Protocol Packet — the unit of knowledge transfer.
 * Every packet is: typed, scoped, attributed, timed, and governed.
 */
export interface KSPPacket {
  /** Unique packet ID (UUID v7 for time-sortability) */
  id: string;

  /** Protocol version */
  version: "ksp/2.0";

  /** Tenant isolation boundary — HARD GATE */
  tenantId: string;

  /** Source of the knowledge */
  source: KSPSource;

  /** Destination of the knowledge */
  destination: KSPDestination;

  /** The knowledge payload */
  payload: KSPPayload;

  /** Temporal context */
  timing: KSPTiming;

  /** Governance metadata */
  governance: KSPGovernance;

  /** Audit reference */
  audit: {
    logId: string;
    spineAuditLogId: string;
  };
}

export interface KSPSource {
  /** Source type */
  type: "agent" | "tool" | "human" | "twin" | "system" | "connector";

  /** Source ID (agent ID, user ID, tool ID) */
  id: string;

  /** Source name (for display) */
  name: string;

  /** Capability that produced this knowledge (if applicable) */
  capabilityId?: string;

  /** Provider that produced this knowledge (if applicable) */
  providerId?: string;
}

export interface KSPDestination {
  /** Target type */
  type: "broadcast" | "agent" | "tool" | "human" | "twin" | "memory" | "spine";

  /** Target ID (for directed packets) */
  id?: string;

  /** Scope filter — who can see this packet */
  visibility: "personal" | "work" | "organization" | "ai";
}

export interface KSPPayload {
  /** Payload type discriminator */
  type:
    | "observation"
    | "orientation"
    | "decision"
    | "action_result"
    | "memory_fragment"
    | "signal"
    | "proposal"
    | "evidence";

  /** The actual content — shape depends on type */
  content: unknown;

  /** Semantic embedding (Vectorize) for similarity search */
  embedding?: number[];

  /** Confidence score (0.0–1.0) for memory triage */
  confidence: number;

  /** References to related Spine entities */
  entityRefs?: string[]; // SSOC UUIDs

  /** References to related packets (lineage) */
  parentPacketIds?: string[];
}

export interface KSPTiming {
  /** Packet creation time */
  createdAt: string; // ISO 8601

  /** Valid until (for time-bounded knowledge) */
  expiresAt?: string;

  /** Time-to-live in seconds (for cacheable knowledge) */
  ttlSeconds?: number;
}

export interface KSPGovernance {
  /** Minimum role required to access */
  minRole: string;

  /** Required scopes */
  requiredScopes: string[];

  /** Whether this packet requires governance approval before distribution */
  approvalRequired: boolean;

  /** Classification level */
  classification: "public" | "internal" | "confidential" | "restricted";

  /** Data residency requirements */
  residency?: string; // e.g., "us-east", "eu-west"
}

E.3.3 KSP Flow — Agent Shares Insight with Organization

┌─────────────────────────────────────────────────────────────────────────────┐
│           KSP FLOW: Agent A Shares Insight → Organization Memory             │
│                                                                             │
│  Agent A (twin-orchestrator-A)                                              │
│     │                                                                       │
│     │  1. Generates insight (OODA Decide phase)                             │
│     │     confidence: 0.92                                                  │
│     │                                                                       │
│     ▼                                                                       │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │  2. Assemble KSP Packet                                             │    │
│  │     source: { type: "twin", id: "twin-A", name: "Sales Twin" }      │    │
│  │     destination: { type: "memory", visibility: "organization" }     │    │
│  │     payload: { type: "memory_fragment", confidence: 0.92, ... }     │    │
│  │     governance: { minRole: "member", approvalRequired: false }      │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│     │                                                                       │
│     │  POST /api/v1/knowledge/share                                         │
│     ▼                                                                       │
│  Gateway — validates JWT, extracts tenant_id                                │
│     │                                                                       │
│     │  3. Route to knowledge service (service binding)                      │
│     ▼                                                                       │
│  knowledge — semantic analysis, embedding generation                        │
│     │                                                                       │
│     │  4. Route to continuity (service binding)                             │
│     ▼                                                                       │
│  continuity — Memory Triage                                                 │
│     │  confidence ≥ 0.85 → ACTIVE memory (D1 + KV + Vectorize)            │
│     │  0.70–0.85 → STAGING memory (D1 only)                               │
│     │  < 0.70 → DISCARD (R2 cold storage)                                 │
│     │                                                                       │
│     │  5. Write to spine_audit_log                                         │
│     ▼                                                                       │
│  pipeline — commit audit entry                                              │
│     │                                                                       │
│     │  6. Broadcast to subscribers                                         │
│     ▼                                                                       │
│  hermes — enqueue to notification queue                                     │
│     │                                                                       │
│     │  SSE push to connected workbench clients                             │
│     │  WebSocket update to Twin Workbench                                  │
│     ▼                                                                       │
│  Organization Memory Updated                                                │
└─────────────────────────────────────────────────────────────────────────────┘

E.3.4 KSP Security Boundaries

BoundaryEnforcementFailure Mode
Tenant IsolationWHERE tenant_id = ? on every KSP query403 fail-loud
Visibility Scopepersonal < work < organization < aiFilter silently
Role GateminRole checked against RBAC in tenants403 if insufficient
Scope GaterequiredScopes checked against JWT scope claim403 if missing
Classificationrestricted → requires admin role + approvalQuarantine to staging
ResidencyPacket rejected if target region mismatch422 with reason
Approval RequiredapprovalRequired: true → routed to governHITL queue

E.4 Agent-to-Agent Communication (A2A)

E.4.1 A2A Architecture — Spine as Shared Blackboard

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.

┌─────────────────────────────────────────────────────────────────────────────┐
│              A2A: SPINE-BASED COORDINATION (NOT PEER-TO-PEER)               │
│                                                                             │
│                                                                             │
│    Agent A ──────┐                                                          │
│   (Sales Twin)   │                                                          │
│                  │                                                          │
│                  │    ┌──────────────────────────────────────────┐          │
│                  │    │           SPINE BLACKBOARD               │          │
│                  ├───►│                                          │          │
│                  │    │  ┌─────────────┐   ┌─────────────┐       │          │
│    Agent B ──────┤    │  │  Intent A   │   │  Intent B   │       │          │
│   (CS Twin)      │    │  │  (proposal) │   │  (proposal) │       │          │
│                  │    │  └──────┬──────┘   └──────┬──────┘       │          │
│                  │    │         │                 │              │          │
│                  │    │         ▼                 ▼              │          │
│                  │    │  ┌─────────────────────────────────┐     │          │
│                  ├───►│  │     GOVERN (arbitration)        │     │          │
│                  │    │  │  • Detect conflicts             │     │          │
│    Agent C ──────┤    │  │  • Score joint confidence       │     │          │
│   (Finance Twin) │    │  │  • Enforce priority rules       │     │          │
│                  │    │  │  • Escalate to human if needed  │     │          │
│                  │    │  └─────────────────────────────────┘     │          │
│                  │    │         │                 │              │          │
│                  │    │         ▼                 ▼              │          │
│                  │    │  ┌─────────────┐   ┌─────────────┐       │          │
│                  └───►│  │  Action A   │   │  Action B   │       │          │
│                       │  │  (approved) │   │  (approved) │       │          │
│                       │  └─────────────┘   └─────────────┘       │          │
│                       │                                          │          │
│                       └──────────────────────────────────────────┘          │
│                                    ▲                                        │
│                                    │                                        │
│                            ┌───────┴───────┐                                │
│                            │   TWIN LAYER   │                                │
│                            │   (ambient)    │                                │
│                            │  • OODA cycle  │                                │
│                            │  • Context asm │                                │
│                            │  • Reasoning   │                                │
│                            └───────────────┘                                │
│                                                                             │
│  RULE: Agents never call each other directly. They read/write the Spine.    │
│        The Twin layer observes and reasons across agent outputs.            │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

E.4.2 A2A Intent Schema

// packages/sdk/src/types/a2a.ts

/**
 * A2A Intent — an agent's declared intention published to the Spine.
 * Other agents read intents and may respond with complementary or conflicting intents.
 */
export interface A2AIntent {
  /** Unique intent ID */
  id: string;

  /** The agent that published this intent */
  agentId: string;

  /** Agent type */
  agentType: "twin" | "autonomous" | "workflow" | "human";

  /** Tenant isolation */
  tenantId: string;

  /** Intent classification */
  intentType: A2AIntentType;

  /** The target capability or entity */
  target: {
    type: "capability" | "entity" | "memory" | "projection";
    id: string;
  };

  /** What the agent wants to do */
  action: {
    verb: "propose" | "request" | "inform" | "query" | "warn" | "block";
    description: string;
    payload: unknown;
  };

  /** Confidence in this intent (0.0–1.0) */
  confidence: number;

  /** Priority relative to other intents */
  priority: "critical" | "high" | "normal" | "low";

  /** Time bounds */
  timing: {
    publishedAt: string;
    validUntil?: string;
    executeAfter?: string; // Defer execution until this time
  };

  /** Dependencies — other intents that must resolve first */
  dependencies?: string[]; // Intent IDs

  /** Response to another intent (for threading) */
  inReplyTo?: string;

  /** Governance status */
  governance: {
    status: "pending" | "approved" | "rejected" | "escalated";
    proposalId?: string;
    approvedBy?: string;
    approvedAt?: string;
  };
}

export type A2AIntentType =
  | "cross-sell" // Sales agent → CS agent: opportunity signal
  | "churn-risk" // CS agent → Sales/Finance: retention alert
  | "data-request" // Any agent → Spine: needs context
  | "action-proposal" // Any agent → Govern: proposes action
  | "memory-share" // Any agent → Memory: shares insight
  | "conflict" // Agent → Agent: detects conflicting intent
  | "handoff" // Agent → Human: needs human intervention
  | "sync-request"; // Agent → Connector: trigger sync

/**
 * A2A Arbitration Result — produced by the Twin layer when conflicting intents detected.
 */
export interface A2AArbitration {
  id: string;
  tenantId: string;
  conflictType: "resource" | "priority" | "dependency" | "policy";
  conflictingIntents: string[];
  resolution: "merge" | "sequence" | "reject" | "escalate";
  mergedIntent?: A2AIntent;
  sequence?: string[]; // Ordered intent IDs
  reason: string;
  arbitratedBy: string; // Twin instance ID
  arbitratedAt: string;
}

E.4.3 A2A Flow — Cross-Sell Signal from Sales Twin to CS Twin

┌─────────────────────────────────────────────────────────────────────────────┐
│     A2A FLOW: Sales Twin Detects Upsell → CS Twin Takes Action              │
│                                                                             │
│  SALES TWIN (twin-orchestrator-sales)                                       │
│     │                                                                       │
│     │  1. OBSERVE: Account "Acme Corp" shows expansion signals              │
│     │     (new team members, API usage spike)                               │
│     │                                                                       │
│     │  2. ORIENT: Entity360 shows CS health score = 0.91                    │
│     │     Memory: recent positive NPS, no open tickets                      │
│     │                                                                       │
│     │  3. DECIDE: Publish "cross-sell" intent to Spine                      │
│     ▼                                                                       │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │  A2AIntent:                                                         │    │
│  │    agentId: "twin-sales"                                            │    │
│  │    intentType: "cross-sell"                                         │    │
│  │    target: { type: "entity", id: "account:acme-corp" }              │    │
│  │    action: { verb: "propose", description: "Upsell to Enterprise",  │    │
│  │              payload: { expansionSignals: [...] } }                 │    │
│  │    confidence: 0.89                                                 │    │
│  │    priority: "high"                                                 │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│     │                                                                       │
│     │  POST via mcp-connector → Gateway → pipeline                          │
│     ▼                                                                       │
│  SPINE — intent stored in `a2a_intents` table (D1)                          │
│     │                                                                       │
│     │  4. TWIN LAYER (ambient) observes new intent                          │
│     │     twin-orchestrator reads all unprocessed intents for tenant        │
│     ▼                                                                       │
│  CS TWIN (twin-orchestrator-cs)                                             │
│     │                                                                       │
│     │  5. Reads intent from Spine (WHERE tenant_id = ? AND agentId != self) │
│     │                                                                       │
│     │  6. ORIENT: Fetch Account context, recent tickets, NPS                │
│     │                                                                       │
│     │  7. DECIDE: Confidence = 0.87, agrees with upsell                     │
│     │     Publishes response intent: "action-proposal" to govern            │
│     ▼                                                                       │
│  GOVERN — joint confidence = 0.88 (0.89 × 0.87 weighted)                    │
│     │  ≥ 0.85 → AUTO-APPROVE                                              │
│     ▼                                                                       │
│  ACT — execute "salesforce.opportunity.create" + "slack.notify-cs-channel"  │
│     │                                                                       │
│     ▼                                                                       │
│  PIPELINE — writeback to Spine                                              │
│  CONTINUITY — compound into Organization Memory                             │
│                                                                             │
│  RESULT: CS team notified in Slack with full context. No manual routing.    │
│          Audit trail: spine_audit_log entries for every step.               │
└─────────────────────────────────────────────────────────────────────────────┘

E.4.4 A2A Security Model

ThreatMitigationEnforcement Point
Agent impersonationJWT signing + agent_id registrygateway + agent-registry
Cross-tenant intent leakageWHERE tenant_id = ? on ALL intent queriesAll services
Intent floodingRate-limit per agent: 100 intents/mingateway + hermes
Circular dependenciesDependency graph validation (DAG check)twin-orchestrator
Priority inversioncritical intents bypass normal queuehermes (queue priority)
Unauthorized arbitrationOnly twin-orchestrator instances may arbitrategovern + RBAC

E.5 SDK Variants

E.5.1 SDK Taxonomy

The Bridge exposes five SDK variants — same underlying contract, different fidelity and bundle size. Each variant is a separate npm package under the @iw scope.

┌─────────────────────────────────────────────────────────────────────────────┐
│                        SDK VARIANT SPECTRUM                                │
│                                                                             │
│   ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────┐  ┌──────┐ │
│   │ @iw/sdk-full│  │@iw/sdk-lite │  │@iw/sdk-content│ │@iw/sdk- │  │@iw/  │ │
│   │             │  │             │  │               │ │ minimal │  │sdk-  │ │
│   │  ~180 KB    │  │   ~85 KB    │  │    ~45 KB     │ │  ~12 KB │  │head- │ │
│   │  gzipped    │  │   gzipped   │  │   gzipped     │ │ gzipped │  │less  │ │
│   │             │  │             │  │               │ │         │  │~3 KB │ │
│   └──────┬──────┘  └──────┬──────┘  └──────┬──────┘  └────┬────┘  └──┬───┘ │
│          │                │                │              │          │     │
│          ▼                ▼                ▼              ▼          ▼     │
│    Full-stack      Browser/Node      Content-only    Telemetry   Server-  │
│    SDK with        SDK with         SDK (read-only   + Events   side only │
│    all features    streaming        Discovery +            (no UI)        │
│    + UI helpers    + caching        Projections)                          │
│                                                                             │
│    Use case:       Use case:        Use case:      Use case:   Use case:   │
│    Workbench       Web apps,        Mobile apps,   Analytics   Background  │
│    builders,       dashboards,      embeddable     pipelines,  workers,    │
│    extension       CLI tools        widgets        logging     edge        │
│    developers                                                       functions│
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

E.5.2 SDK Interface Contracts

// ============================================================
// @iw/sdk-full — The complete SDK (workbench + headless)
// ============================================================


export interface SDKFullConfig {
  /** Bridge endpoint */
  baseUrl: string; // default: "https://api.integratewise.ai"

  /** Authentication */
  jwt: string;

  /** Tenant context (optional — extracted from JWT if omitted) */
  tenantId?: string;

  /** MCP endpoint for AI assistant integration */
  mcpEndpoint?: string; // default: "https://mcp.integratewise.ai/v1/mcp"

  /** Enable React UI components */
  enableUI: boolean;

  /** UI theme config */
  theme?: UIThemeConfig;

  /** Real-time transport: 'sse' | 'ws' | 'polling' */
  realtimeTransport: "sse" | "ws" | "polling";

  /** Maximum reconnect attempts */
  maxReconnects: number;

  /** Debug mode */
  debug: boolean;
}

export class IWBridgeFull {
  constructor(config: SDKFullConfig);

  // ── Core Capabilities ──
  invoke<T = unknown>(capability: string, payload: unknown): Promise<CapabilityInvokeResponse<T>>;
  discover(): Promise<DiscoveryResponse>;
  stream(capability: string, payload: unknown): AsyncIterable<StreamChunk>;

  // ── Projections ──
  getProjection(name: string, params?: Record<string, unknown>): Promise<Projection>;
  listProjections(): Promise<ProjectionSummary[]>;

  // ── Memory ──
  queryMemory(query: MemoryQuery): Promise<MemoryResult[]>;
  shareKnowledge(packet: KSPPacketInput): Promise<KSPPacket>;

  // ── Agent ──
  getTwin(): TwinSession;
  listAgents(): Promise<AgentSummary[]>;
  publishIntent(intent: A2AIntentInput): Promise<A2AIntent>;

  // ── Governance ──
  getProposals(filter?: ProposalFilter): Promise<Proposal[]>;
  approveProposal(proposalId: string): Promise<void>;
  rejectProposal(proposalId: string, reason?: string): Promise<void>;

  // ── Real-time ──
  onEvent(event: string, handler: EventHandler): Unsubscribe;
  onIntent(handler: IntentHandler): Unsubscribe;

  // ── UI Components (React) ──
  Workbench: typeof WorkbenchUI;
  TwinPanel: typeof TwinPanel;
  MemoryExplorer: typeof MemoryExplorer;
  ProposalQueue: typeof ProposalQueue;
}

// ============================================================
// @iw/sdk-lite — Browser/Node SDK (no UI, with streaming)
// ============================================================


export interface SDKLiteConfig {
  baseUrl: string;
  jwt: string;
  tenantId?: string;
  realtimeTransport: "sse" | "polling";
  cacheEnabled: boolean;
  cacheTtlSeconds: number;
}

export class IWBridgeLite {
  constructor(config: SDKLiteConfig);

  invoke<T = unknown>(capability: string, payload: unknown): Promise<CapabilityInvokeResponse<T>>;
  stream(capability: string, payload: unknown): AsyncIterable<StreamChunk>;
  discover(): Promise<DiscoveryResponse>;
  queryMemory(query: MemoryQuery): Promise<MemoryResult[]>;
  onEvent(event: string, handler: EventHandler): Unsubscribe;

  // Lite has no UI components, no Twin session, no governance actions
}

// ============================================================
// @iw/sdk-content — Content/readonly SDK (smallest interactive)
// ============================================================


export interface SDKContentConfig {
  baseUrl: string;
  jwt: string;
  tenantId?: string;
}

export class IWContentSDK {
  constructor(config: SDKContentConfig);

  // Read-only operations only
  discover(): Promise<DiscoveryResponse>;
  getProjection(name: string): Promise<Projection>;
  queryMemory(query: MemoryQuery): Promise<MemoryResult[]>;

  // No invoke, no stream, no write operations
}

// ============================================================
// @iw/sdk-minimal — Telemetry + Events only
// ============================================================


export interface SDKMinimalConfig {
  baseUrl: string;
  jwt: string;
  tenantId?: string;
}

export class IWMinimalSDK {
  constructor(config: SDKMinimalConfig);

  // Events and telemetry only
  track(event: string, properties?: Record<string, unknown>): Promise<void>;
  onEvent(event: string, handler: EventHandler): Unsubscribe;
  health(): Promise<HealthStatus>;
}

// ============================================================
// @iw/sdk-headless — Server-side / edge functions
// ============================================================


export interface SDKHeadlessConfig {
  baseUrl: string;
  /** API Key (server-side only) OR JWT */
  apiKey?: string;
  jwt?: string;
  tenantId: string; // Required for headless
}

export class IWHeadlessSDK {
  constructor(config: SDKHeadlessConfig);

  // Full capability invocation (server-side has no governance gate —
  // assumes calling service has already gated)
  invoke<T = unknown>(capability: string, payload: unknown): Promise<CapabilityInvokeResponse<T>>;

  // Batch operations
  invokeBatch(requests: CapabilityInvokeRequest[]): Promise<CapabilityInvokeResponse[]>;

  // Admin operations (requires admin scope)
  getTenantConfig(): Promise<TenantConfig>;
  updateTenantConfig(config: Partial<TenantConfig>): Promise<void>;

  // No real-time, no UI, no streaming (server-side is request/response)
}

E.5.3 SDK Package Structure

packages/
├── sdk-full/
│   ├── src/
│   │   ├── index.ts              # Main export: IWBridgeFull
│   │   ├── client.ts             # HTTP client + retry logic
│   │   ├── streaming.ts          # SSE/WebSocket stream handler
│   │   ├── capabilities.ts       # Capability invocation wrappers
│   │   ├── projections.ts        # Projection fetch + cache
│   │   ├── memory.ts             # Memory query + KSP
│   │   ├── agent.ts              # Twin session + A2A intents
│   │   ├── governance.ts         # Proposal review actions
│   │   ├── realtime.ts           # Event bus (SSE/WS/polling)
│   │   ├── ui/                   # React components
│   │   │   ├── Workbench.tsx
│   │   │   ├── TwinPanel.tsx
│   │   │   ├── MemoryExplorer.tsx
│   │   │   └── ProposalQueue.tsx
│   │   └── types.ts              # Re-exports from @iw/sdk-types
│   ├── package.json
│   └── tsconfig.json
│
├── sdk-lite/
│   ├── src/
│   │   ├── index.ts
│   │   ├── client.ts             # Shared HTTP logic (same as sdk-full)
│   │   ├── streaming.ts          # SSE only
│   │   ├── capabilities.ts
│   │   ├── projections.ts
│   │   ├── memory.ts
│   │   └── realtime.ts
│   └── package.json
│
├── sdk-content/
│   ├── src/
│   │   ├── index.ts
│   │   ├── client.ts             # Simple fetch wrapper
│   │   ├── discovery.ts
│   │   ├── projections.ts
│   │   └── memory.ts             # Read-only queries
│   └── package.json
│
├── sdk-minimal/
│   ├── src/
│   │   ├── index.ts
│   │   ├── client.ts             # Tiny fetch wrapper (~2KB)
│   │   ├── events.ts
│   │   └── health.ts
│   └── package.json
│
├── sdk-headless/
│   ├── src/
│   │   ├── index.ts
│   │   ├── client.ts             # Node.js fetch / undici
│   │   ├── capabilities.ts       # Full invoke + batch
│   │   └── admin.ts              # Tenant management
│   └── package.json
│
└── sdk-types/                    # SHARED types package (all SDKs depend on this)
    ├── src/
    │   ├── capability.ts
    │   ├── discovery.ts
    │   ├── ksp.ts
    │   ├── a2a.ts
    │   ├── memory.ts
    │   ├── governance.ts
    │   └── events.ts
    └── package.json

E.5.4 SDK Authentication Patterns

// packages/sdk-types/src/auth.ts

/**
 * Authentication contract for all SDK variants.
 * The Gateway is the single source of truth for auth.
 */
export interface SDKAuth {
  /** JWT issued by Gateway (primary auth for browser clients) */
  jwt?: string;

  /** API Key for server-to-server calls */
  apiKey?: string;

  /** Tenant ID (extracted from JWT if omitted) */
  tenantId?: string;

  /** User ID (extracted from JWT if omitted) */
  userId?: string;
}

/**
 * Every SDK request carries these headers:
 *
 * Authorization: Bearer <jwt_or_apikey>
 * x-tenant-id: <tenant_id>        ← injected by Gateway, never trusted from client
 * x-correlation-id: <uuid>         ← for distributed tracing
 * x-sdk-variant: <full|lite|content|minimal|headless>
 * x-sdk-version: <semver>
 */

E.6 Ecosystem App Composition Patterns

E.6.1 The Composition Model

Third-party apps compose on the Bridge by consuming capabilities, not by importing internal services. The Bridge is a capability platform, not a PaaS.

┌─────────────────────────────────────────────────────────────────────────────┐
│                    ECOSYSTEM APP COMPOSITION PATTERNS                       │
│                                                                             │
│   ┌─────────────────────────────────────────────────────────────────────┐   │
│   │                    THIRD-PARTY APP (e.g., CS Widget)                │   │
│   │                                                                     │   │
│   │  ┌─────────────┐   ┌─────────────┐   ┌─────────────┐               │   │
│   │  │   @iw/sdk   │   │   @iw/sdk   │   │  @iw/sdk    │               │   │
│   │  │  -content   │   │   -lite     │   │   -full     │               │   │
│   │  │  (read-only)│   │  (streaming)│   │  (workbench)│               │   │
│   │  └──────┬──────┘   └──────┬──────┘   └──────┬──────┘               │   │
│   │         │                 │                 │                       │   │
│   │         └─────────────────┴─────────────────┘                       │   │
│   │                           │                                         │   │
│   │                    ┌──────┴──────┐                                  │   │
│   │                    │  Gateway    │                                  │   │
│   │                    │  (JWT gate) │                                  │   │
│   │                    └──────┬──────┘                                  │   │
│   │                           │                                         │   │
│   └───────────────────────────┼─────────────────────────────────────────┘   │
│                               │                                             │
│   ┌───────────────────────────┼─────────────────────────────────────────┐   │
│   │         CONTINUITY BRIDGE │                                         │   │
│   │                           ▼                                         │   │
│   │  ┌─────────────┐   ┌─────────────┐   ┌─────────────┐               │   │
│   │  │  Discovery  │   │  Capability │   │   Events    │               │   │
│   │  │  (GET /api/ │   │  (POST /api/│   │  (SSE /api/ │               │   │
│   │  │   v1/disco) │   │  v1/cap/...)│   │  v1/stream) │               │   │
│   │  └─────────────┘   └─────────────┘   └─────────────┘               │   │
│   │                                                                     │   │
│   │  The app NEVER imports: services/, packages/spine-schema/, D1       │   │
│   │  The app NEVER calls: act, pipeline, normalizer directly            │   │
│   │                                                                     │   │
│   └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│  COMPOSITION PATTERNS:                                                      │
│  1. Embed Pattern      — iframe/widget using @iw/sdk-content                │
│  2. Plugin Pattern     — browser extension using @iw/sdk-lite               │
│  3. Workbench Pattern  — full app using @iw/sdk-full                        │
│  4. Webhook Pattern    — server receives events, uses @iw/sdk-headless      │
│  5. MCP Pattern        — AI assistant connects via MCP, no SDK needed       │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

E.6.2 Composition Patterns Catalog

Pattern 1: Embed Pattern (iframe/widget)

// Third-party app embeds a Bridge-powered widget

const sdk = new IWContentSDK({
  baseUrl: "https://api.integratewise.ai",
  jwt: getTenantJWT(), // From host app auth
});

// Fetch discovery to learn what's available
const discovery = await sdk.discover();

// Render a read-only account health widget
const projection = await sdk.getProjection("cs-health", {
  accountId: props.accountId,
});

// Mount React component (if using @iw/sdk-full)
// Or render raw HTML from projection data

Security: Embed runs in sandboxed iframe. Host app provides JWT via postMessage. SDK validates JWT on every call.

Pattern 2: Plugin Pattern (browser extension)

// Browser extension content script

const bridge = new IWBridgeLite({
  baseUrl: "https://api.integratewise.ai",
  jwt: await chrome.storage.local.get("iw_jwt"),
  realtimeTransport: "sse",
  cacheEnabled: true,
});

// Listen for Twin proposals while user browses Salesforce
bridge.onEvent("twin.proposal", (proposal) => {
  showInPageNotification(proposal);
});

// Invoke capability from any page
bridge.invoke("salesforce.opportunity.update", {
  opportunityId: extractIdFromPage(),
  stage: "Closed Won",
});

Security: Extension manifest declares api.integratewise.ai as allowed host. CORS preflight validated by Gateway.

Pattern 3: Workbench Pattern (full app)

// Custom workbench built on Bridge

const bridge = new IWBridgeFull({
  baseUrl: 'https://api.integratewise.ai',
  jwt: auth.jwt,
  enableUI: true,
  theme: customTheme,
  realtimeTransport: 'ws',
});

// Render full workbench with Twin panel
function App() {
  return (
    <div className="workbench">
      <bridge.Workbench projection="sales" />
      <bridge.TwinPanel />
      <bridge.MemoryExplorer />
      <bridge.ProposalQueue />
    </div>
  );
}

Security: Full SDK requires scope: workbench in JWT. UI components are sandboxed React trees with CSP.

Pattern 4: Webhook Pattern (server-side integration)

// Third-party server receives Bridge webhooks

const bridge = new IWHeadlessSDK({
  baseUrl: "https://api.integratewise.ai",
  apiKey: process.env.IW_API_KEY,
  tenantId: process.env.IW_TENANT_ID,
});

// Webhook handler
app.post("/webhooks/iw", async (req, res) => {
  const event = req.body;

  // Verify webhook signature
  verifyWebhookSignature(req);

  switch (event.type) {
    case "proposal.approved":
      await bridge.invoke("slack.notify", {
        channel: "#ops",
        message: `Proposal approved: ${event.proposalId}`,
      });
      break;

    case "memory.promoted":
      await syncToExternalKB(event.memory);
      break;
  }

  res.sendStatus(200);
});

Security: Webhook signatures use HMAC-SHA256. API keys are server-side only. Never exposed to browser.

Pattern 5: MCP Pattern (AI assistant integration)

// No SDK needed — AI assistant connects via MCP directly
{
  "mcpServers": {
    "integratewise": {
      "type": "sse",
      "url": "https://mcp.integratewise.ai/v1/mcp",
      "headers": {
        "Authorization": "Bearer ${IW_JWT}"
      }
    }
  }
}

Security: MCP connection is read-only by default. Write capabilities require scope: write + governance approval.

E.6.3 App Manifest Contract

// packages/sdk-types/src/manifest.ts

/**
 * Ecosystem App Manifest — every third-party app registers with the Bridge.
 */
export interface EcosystemAppManifest {
  /** Unique app ID (reverse DNS) */
  id: string; // e.g., "com.acme.cswidget"

  /** Human name */
  name: string;

  /** Description for Discovery */
  description: string;

  /** App type */
  type: "embed" | "plugin" | "workbench" | "webhook" | "mcp-client";

  /** Required SDK variant */
  sdkVariant: "content" | "lite" | "full" | "headless";

  /** Minimum SDK version */
  minSdkVersion: string;

  /** Required scopes */
  requiredScopes: string[];

  /** Capabilities this app consumes */
  consumedCapabilities: string[];

  /** Capabilities this app provides (if any) */
  providedCapabilities?: Capability[];

  /** Webhook URL (for webhook-type apps) */
  webhookUrl?: string;

  /** Content Security Policy */
  csp: {
    allowedOrigins: string[];
    allowedConnectSrc: string[];
  };

  /** Data handling */
  dataHandling: {
    storesDataLocally: boolean;
    cachesInBrowser: boolean;
    piiAccess: boolean;
  };

  /** Registration */
  registeredBy: string; // User ID
  registeredAt: string;
  status: "pending" | "approved" | "rejected" | "revoked";
}

E.7 Template Starter (create-iw-app)

E.7.1 Template Architecture

create-iw-app/
├── templates/
│   ├── embed-widget/           # Pattern 1: iframe/widget
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── main.ts         # Widget entry point
│   │   │   ├── bridge.ts       # @iw/sdk-content init
│   │   │   └── widget.tsx      # React widget component
│   │   └── README.md
│   │
│   ├── browser-extension/      # Pattern 2: browser plugin
│   │   ├── manifest.json
│   │   ├── src/
│   │   │   ├── background.ts   # Service worker
│   │   │   ├── content.ts      # Content script
│   │   │   ├── bridge.ts       # @iw/sdk-lite init
│   │   │   └── popup.tsx       # Extension popup
│   │   └── README.md
│   │
│   ├── workbench-app/          # Pattern 3: full workbench
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── App.tsx
│   │   │   ├── bridge.ts       # @iw/sdk-full init
│   │   │   ├── pages/
│   │   │   │   ├── Dashboard.tsx
│   │   │   │   ├── TwinPage.tsx
│   │   │   │   └── Settings.tsx
│   │   │   └── components/
│   │   └── README.md
│   │
│   ├── webhook-server/         # Pattern 4: server-side webhook
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── server.ts       # Express/Fastify server
│   │   │   ├── bridge.ts       # @iw/sdk-headless init
│   │   │   ├── webhooks.ts     # Webhook handlers
│   │   │   └── verify.ts       # Signature verification
│   │   └── README.md
│   │
│   └── mcp-client/             # Pattern 5: AI assistant client
│       ├── package.json
│       ├── src/
│       │   ├── client.ts       # MCP client setup
│       │   └── prompts/        # System prompts for Bridge
│       └── README.md
│
├── src/
│   ├── index.ts                # CLI entry: create-iw-app <template>
│   ├── init.ts                 # Project scaffolding logic
│   └── validate.ts             # Manifest validation
│
├── package.json
└── README.md

E.7.2 Template Quick-Start

# Install the CLI
npm install -g @iw/create-app

# Create a new ecosystem app
create-iw-app my-cs-widget --template embed-widget --sdk content

# Templates: embed-widget | browser-extension | workbench-app | webhook-server | mcp-client
# SDKs:      content | lite | full | minimal | headless

cd my-cs-widget
npm install
npm run dev          # Local dev server with Bridge sandbox
npm run build        # Production build
npm run register     # Register app manifest with Bridge

E.7.3 Template Bootstrap Code

// templates/embed-widget/src/bridge.ts


/**
 * Bridge client initialization for embed widget pattern.
 * The host page injects the JWT via window.postMessage.
 */
  return new IWContentSDK({
    baseUrl: import.meta.env.VITE_BRIDGE_URL || "https://api.integratewise.ai",
    jwt: extractJWTFromParent(),
  });
}

function extractJWTFromParent(): string {
  // Host app sends JWT via postMessage
  return new Promise((resolve) => {
    window.addEventListener("message", (e) => {
      if (e.origin !== "https://app.integratewise.ai") return;
      if (e.data.type === "IW_JWT") resolve(e.data.jwt);
    });
  });
}

// ───────────────────────────────────────────────────────────────────────────
// templates/workbench-app/src/bridge.ts
// ───────────────────────────────────────────────────────────────────────────


  baseUrl: import.meta.env.VITE_BRIDGE_URL,
  jwt: localStorage.getItem("iw_jwt")!,
  enableUI: true,
  theme: {
    primary: "#0F172A",
    accent: "#3B82F6",
    surface: "#F8FAFC",
  },
  realtimeTransport: "ws",
  maxReconnects: 5,
  debug: import.meta.env.DEV,
});

// Auto-refresh JWT before expiry
bridge.onEvent("auth.token_expiring", async () => {
  const newToken = await refreshToken();
  bridge.setJWT(newToken);
});

// ───────────────────────────────────────────────────────────────────────────
// templates/webhook-server/src/bridge.ts
// ───────────────────────────────────────────────────────────────────────────


  baseUrl: process.env.BRIDGE_URL!,
  apiKey: process.env.IW_API_KEY!,
  tenantId: process.env.IW_TENANT_ID!,
});

// Health check on startup
bridge.health().then((status) => {
  if (status.status !== "healthy") {
    console.error("Bridge unhealthy:", status);
    process.exit(1);
  }
});

E.8 Integration Points with Adjacent Layers

E.8.1 North-South Integration Matrix

Ecosystem ComponentNorth Bound (Ingress)South Bound (Egress)Adjacent Layer
Capability RegistryDiscovery API (GET /api/v1/discovery)agent-registry service bindingIdentity + Capability
Capability RouterHERMES queue consumerACT_QUEUE producerCapability + Governance
KSP Packet Busmcp-connector inboundknowledge + continuity service bindingsContinuity + Knowledge
A2A Intent Bustwin-orchestrator readpipeline write + spine_audit_logContinuity + Governance
SDK Clientgateway HTTP/SSEConsumer app runtimeIdentity (JWT)
Template Startergateway registration APIagent-registry manifest storageRegistry

E.8.2 Service Binding Map (Ecosystem-Relevant)

// apps/gateway/src/bindings.ts — Ecosystem-relevant bindings

export interface ServiceBindings {
  // Tier 0 — Ingress
  GATEWAY: Fetcher; // Self
  WEBHOOK_INGRESS: Fetcher;

  // Tier 1 — Tenant & Sync
  TENANTS: Fetcher;
  CONNECTOR: Fetcher;
  CONNECTOR_SYNC: Fetcher;
  NORMALIZER: Fetcher;
  LOADER: Fetcher;

  // Tier 2 — Projection (Ecosystem reads these)
  PIPELINE: Fetcher; // Spine writer — ecosystem NEVER calls directly
  TWIN_ORCHESTRATOR: Fetcher; // OODA engine — ecosystem routes through Gateway
  L2: Fetcher;
  INTELLIGENCE: Fetcher; // Context assembly
  KNOWLEDGE: Fetcher; // KSP semantic layer
  GOVERN: Fetcher; // Governance gate
  STORE: Fetcher;
  ACT: Fetcher; // Outbound execution — ecosystem NEVER calls directly
  SPINE_V2: Fetcher;

  // Tier 3 — Runtime (Ecosystem orchestrates through these)
  HERMES: Fetcher; // Message queue — primary ecosystem router
  TRIAGE: Fetcher; // Confidence routing (runs inside Hermes)
  WORKFLOW: Fetcher;
  IW_AGENT_RUNTIME: Fetcher; // Agent sandbox
  MCP_CONNECTOR: Fetcher; // Inbound MCP pool

  // Tier 4 — Supporting (Ecosystem metadata)
  AGENT_REGISTRY: Fetcher; // Capability catalog
  BILLING: Fetcher;
  ADMIN: Fetcher;
  FOLDER_WATCHER: Fetcher;
  CONTINUITY: Fetcher; // Memory substrate
  TELEMETRY: Fetcher;
  THINK: Fetcher; // LLM orchestration
}

E.8.3 Queue Topology (Ecosystem-Relevant)

QueuePublisherConsumerPurposeEcosystem Role
DISCOVERY_CACHE_INVALIDATEagent-registry, connectorgatewayCache bust on capability changesKeeps Discovery fresh
ACT_QUEUEhermes, governactApproved action executionEcosystem actions execute here
PIPELINE_QUEUEact, normalizerpipelineSpine write requestsEcosystem results written here
KSP_BROADCASTknowledge, continuityhermesKnowledge packet distributionKSP fan-out
A2A_INTENTtwin-orchestratortwin-orchestratorIntent publication (self-consuming DO)A2A blackboard
NOTIFICATION_SSEhermesgatewaySSE push to connected clientsReal-time ecosystem updates
CONNECTOR_SYNC_QUEUEloader, connector-syncconnector-syncProvider sync jobsEcosystem data freshness

E.9 Security Boundaries

E.9.1 Ecosystem Security Model

┌─────────────────────────────────────────────────────────────────────────────┐
│                    ECOSYSTEM SECURITY BOUNDARIES                            │
│                                                                             │
│   ┌─────────────────────────────────────────────────────────────────────┐   │
│   │  LAYER 1: Identity Gate (Gateway)                                   │   │
│   │  • JWT validation (RS256)                                           │   │
│   │  • tenant_id extraction from JWT claim ONLY                         │   │
│   │  • Rate-limit per tenant: 1000 req/min (pro), 100 req/min (free)    │   │
│   │  • API Key rotation (90 days)                                       │   │
│   └─────────────────────────────────────────────────────────────────────┘   │
│                              │                                              │
│   ┌──────────────────────────┼──────────────────────────────────────────┐   │
│   │  LAYER 2: Capability Gate (agent-registry + Gateway)                │   │
│   │  • Discovery filtered by tenant plan + RBAC                         │   │
│   │  • Capability schema validation on invoke                           │   │
│   │  • Scope enforcement: `scope: read` default, `scope: write` opt-in  │   │
│   │  • Deprecated capabilities hidden after sunset date                 │   │
│   └─────────────────────────────────────────────────────────────────────┘   │
│                              │                                              │
│   ┌──────────────────────────┼──────────────────────────────────────────┐   │
│   │  LAYER 3: Governance Gate (govern)                                  │   │
│   │  • Confidence scoring: ≥0.85 auto, 0.70–0.85 HITL, <0.70 discard    │   │
│   │  • Proposal expiry: 48 hours default                                │   │
│   │  • Audit: every decision → spine_audit_log                          │   │
│   │  • Escalation: L4 capabilities NEVER auto-execute                   │   │
│   └─────────────────────────────────────────────────────────────────────┘   │
│                              │                                              │
│   ┌──────────────────────────┼──────────────────────────────────────────┐   │
│   │  LAYER 4: Memory Gate (continuity + triage)                         │   │
│   │  • KSP packet validation: tenant_id, scope, classification          │   │
│   │  • Memory triage: ≥0.85 active, 0.70–0.85 staging, <0.70 discard    │   │
│   │  • Retention: active 30 days, staging 90 days, archived 7 years     │   │
│   │  • Cross-scope leakage: personal < work < org < ai (HARD filter)    │   │
│   └─────────────────────────────────────────────────────────────────────┘   │
│                              │                                              │
│   ┌──────────────────────────┼──────────────────────────────────────────┐   │
│   │  LAYER 5: Execution Gate (act + adapters)                           │   │
│   │  • Credential wall: per-tenant, never shared                        │   │
│   │  • Adapter sandbox: provider errors don't crash Bridge              │   │
│   │  • Circuit breaker: 5 errors → 30s cooldown                         │   │
│   │  • Entity360 injection: context enriched before outbound call       │   │
│   └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

E.9.2 SDK Security Invariants

InvariantEnforcementViolation
JWT never stored in localStorage for SDK-headlessServer-side API keys onlySDK-headless throws if jwt provided
SDK-content never invokes write capabilitiesRuntime schema check403 from Gateway
SDK-lite streaming requires scope: streamJWT scope validationSSE connection rejected
Cross-origin SDK calls require app manifest registrationGateway CORS + manifest check403 with X-IW-App-Not-Registered
SDK version compatibility checked on every callx-sdk-version header validation426 Upgrade Required
KSP packets without tenant_id are quarantinedcontinuity validationPacket logged to ksp_quarantine table

E.10 Metrics & Observability

E.10.1 Ecosystem Metrics

// packages/sdk-types/src/telemetry.ts

export interface EcosystemMetrics {
  // Capability Fabric
  "capability.invocations.total": Counter;
  "capability.invocations.success": Counter;
  "capability.invocations.error": Counter;
  "capability.invocations.latency": Histogram; // ms
  "capability.discovery.cache_hit_rate": Gauge; // 0–1

  // KSP
  "ksp.packets.sent": Counter;
  "ksp.packets.received": Counter;
  "ksp.packets.quarantined": Counter;
  "ksp.memory.promoted": Counter;
  "ksp.memory.staged": Counter;
  "ksp.memory.discarded": Counter;

  // A2A
  "a2a.intents.published": Counter;
  "a2a.intents.resolved": Counter;
  "a2a.conflicts.detected": Counter;
  "a2a.arbitrations.completed": Counter;

  // SDK
  "sdk.connections.active": Gauge; // Per variant
  "sdk.streaming.bytes": Counter;
  "sdk.errors.timeout": Counter;
  "sdk.errors.auth": Counter;

  // Ecosystem Apps
  "ecosystem.apps.registered": Gauge;
  "ecosystem.apps.invocations": Counter; // Per app ID
}

E.11 Glossary

TermDefinition
CapabilityA named, versioned, discoverable business action with a strict input/output schema.
Capability FabricThe mesh of registries, routers, and execution engines that makes capabilities composable.
KSPKnowledge Sharing Protocol — the schema and governance contract for moving knowledge between ecosystem participants.
A2AAgent-to-Agent communication — Spine-based coordination (not peer-to-peer).
DiscoveryThe canonical API (GET /api/v1/discovery) that tells consumers what exists and what they can do.
TwinThe ambient reasoning layer — not a separate entity, but the emergent property of OODA across the Capability and Continuity layers.
SpineThe single source of truth for context — entities, relationships, memory, audit.
OODAObserve → Orient → Decide → Act — the decision cycle running across Capability and Continuity.
Governance GateThe 0.70/0.85 confidence threshold system that governs execution and memory promotion.

E.12 Version History

VersionDateChanges
v1.0.02026-06-15Initial ecosystem specification (part of FINAL_E2E_SYSTEM)
v2.0.02026-07-02This 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.

END OF DOCUMENT

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.