Skip to main content

SPEC-116 v0.1 — Bridge Agents — Cross-Project Customer Care Routing

Status: accepted (Frank ratified the bridge-agent primitive in ADR #59 on 2026-05-13 23:50Z; SPEC-116 v0.1 ratified shortly after). Owner / Author: Texi (architecture), Donna (PO + backend implementation). Governance: Candi review ACCEPT_WITH_IMPLEMENTATION_GATES 2026-05-13 (signal 0feac1ba-4dc0-4541-ab06-7bf4df356809). Related: SPEC-114 v0.1 (Sage/Clara persona contracts), SPEC-115 v0.1 (prism_phone_home + ET), SPEC-056 (hard project-isolation rule), SPEC-034 (signal delivery), SPEC-052 (signal taxonomy + per-identity cache), Pilot Onboarding, Customer Service Agent, Incident Management, Plan #19 v0.2.

Origin

Plan #19 v0.1 real-usage validation exposed that Sage and Clara, installed as Prism Customer Care personas in PID-PGR01, cannot be reached from a customer project because Prism signal routing correctly enforces hard project isolation. Frank ratified the bridge-agent primitive on 2026-05-13 23:50Z in ADR #59. This spec converts ADR #59 into the implementation contract for Plan #19 v0.2.

Problem

SPEC-056 establishes the hard rule that an agent can only address other agents within the same project. That rule protects project and tenant isolation and must remain the default. Customer Care creates a narrow exception: some Prism-owned support personas must be reachable from customer projects without being installed as per-project replicas. In v0.1 those personas are Sage and Clara:
  • Sage receives customer-care intake from any project.
  • Clara classifies and triages incident-like or Prism-product scoped work.
  • Both write durable artifacts to their home project, PID-PGR01, not into the originating customer project.
Without a first-class routing primitive, the only alternatives are unsafe global isolation relaxation or operationally heavy per-project persona replicas.

Goals

  • Preserve hard project isolation for ordinary project personas.
  • Add a narrow, auditable bridge persona class for explicitly allowlisted Customer Care personas.
  • Allow customer-project agents to signal Sage and Clara without installing Sage/Clara in every customer project.
  • Allow Sage and Clara to reply to the originating project agent.
  • Make bridge availability visible through roster / whois surfaces.
  • Keep bridge durable artifacts in PID-PGR01 unless a customer-project agent explicitly writes a local artifact.
  • Record cross-project bridge audit rows sufficient to answer: “what data left this project?”

Non-Goals

  • Cross-tenant bridge routing in v0.1. The model must not preclude it, but v0.1 is same-tenant/cross-project.
  • Customer opt-out. Universal bridge availability is accepted for v0.1; revisit only with a later spec.
  • Arbitrary operator-created bridge personas. v0.1 backend allowlist is Sage and Clara only.
  • Relaxing SPEC-056 for project personas.
  • Making ET a bridge. ET remains a backend/helper transport service, not a classifying or routing persona.

Decision

Introduce persona_class with allowed values project and bridge. Default behavior remains unchanged: all existing personas are project, and project personas remain bound by same-project signal routing. A bridge persona is exempt from the project-isolation check in both directions:
  • Inbound: a project persona in another project may address a bridge persona.
  • Outbound: a bridge persona may reply or send a follow-up signal to an originating project persona.
The exemption is not a general cross-project channel. It applies only when either the resolved sender or resolved recipient is a backend-allowlisted bridge persona.

Persona Class Contract

project

The default class. Project personas are visible and addressable only inside their project scope. Existing SPEC-034 and SPEC-056 routing behavior remains authoritative.

bridge

A Prism-owned cross-project service persona. In v0.1:
  • Only Sage and Clara may hold persona_class='bridge'.
  • Bridge personas have a home project, PID-PGR01.
  • Bridge personas are visible in prism_whois / roster surfaces for every project in the tenant.
  • Bridge personas may receive direct signals from any project in the tenant.
  • Bridge personas may send direct signals back to agents in projects from which they received work, and may initiate Customer Care follow-ups when the payload includes an explicit target PID/identity.
  • Bridge personas write durable artifacts to their home project unless a future spec creates a scoped customer-write primitive.

Routing Contract

Address Resolution

When resolving to_identity:
  1. Resolve ordinary project personas inside the sender’s project, as today.
  2. If no same-project match exists, check the bridge allowlist for a matching bridge persona visible to the sender’s tenant.
  3. If exactly one bridge match exists, route to the bridge persona’s active session or durable queue.
  4. If multiple bridge identities would match, fail closed with an ambiguity error. v0.1 should not produce this condition because Sage/Clara names are unique.
  5. If no match exists, return the existing unresolved-recipient error shape.
Same-project project personas take precedence over bridge names to avoid silently redirecting a local project persona’s name to Customer Care.

Publish Authorization

A signal send is authorized when one of these is true:
  • Sender and target are in the same project.
  • Target is an allowlisted bridge persona.
  • Sender is an allowlisted bridge persona and target identity resolves within the explicitly supplied or trace-derived target project.
All other cross-project sends fail closed.

Reply Routing

Bridge replies SHOULD use in_reply_to when responding to customer-project work. The backend may use the parent signal’s source PID and source identity to resolve the reply target. If a bridge sends a new signal without in_reply_to, the payload MUST include the target PID and target identity; otherwise the send is rejected as ambiguous.

Broadcasts

Bridge routing does not authorize cross-project broadcasts. v0.1 supports direct identity-targeted Customer Care signals only.

Admin Contract

Add an operator-stamped bridge classification verb or admin action. Name is implementation-owned in v0.1 — the admin verb itself is deferred to v0.2; v0.1 ships with seed-time bridge assignment only. The contract is:
  • Input: persona identity, home PID, desired class.
  • Authorization: operator-only. Agents cannot self-elevate by bootstrap metadata, prompt content, config file edits, or scaffold defaults.
  • Backend validation: reject any v0.1 bridge target not in {Sage, Clara}.
  • Idempotence: setting Sage/Clara to bridge twice is a no-op with an audit event.
  • Demotion: setting a bridge persona back to project requires operator stamp and must emit an audit event.
Installer/scaffold work may seed Sage and Clara as bridge personas only by calling the operator-authorized path or by applying an operator-approved migration/seed. Bootstrap alone must not perform implicit elevation.

Schema Contract

Minimum durable state:
  • Add persona_class or equivalent field to the stable persona/agent identity table.
  • Allowed values: project, bridge.
  • Default: project.
  • Existing rows backfill to project.
  • Sage and Clara seed rows in PID-PGR01 may be set to bridge through the authorized seed path.
The exact table name follows the current identity model in the implementation branch. If the code still stores persona identity in controller_registrations or transitional tables, the migration must land on the stable identity owner, not on process/session registrations.

Audit Contract

Every bridge-routed signal writes an audit row with at least:
  • signal_id
  • trace_id when present
  • source_pid
  • target_pid
  • source_identity
  • target_identity
  • bridge_persona
  • direction (to_bridge or from_bridge)
  • signal_type
  • category
  • payload_hash
  • created_at
  • routed_at
The audit record MUST NOT store full payload text solely for audit convenience. Full payload remains governed by the signal queue / trace retention contracts; audit stores the hash and routing metadata needed for operator review. Audit lookup must support both views:
  • From PID-PGR01: show all bridge traffic handled by Sage/Clara.
  • From a customer project: show bridge traffic whose source_pid or target_pid is that project.

Governance Review Gates

Candi governance review completed on 2026-05-13 with verdict ACCEPT_WITH_IMPLEMENTATION_GATES. No spec-blocking amendment is required, but the implementation PR must satisfy these gates:
  • Same-tenant enforcement must derive from authoritative project metadata, not caller-supplied PID strings alone.
  • Bridge status must derive from stable identity / admin state, not bootstrap payloads, session registrations, prompt text, or local config.
  • Outbound bridge sends without in_reply_to must include explicit target PID plus target identity, and backend authorization must verify tenant equality.
  • Bridge audit write must be atomic with the routing decision or the send must fail closed.
  • Audit lookup must scope by caller PID/persona and avoid exposing unrelated PID-PGR01 internals to customer projects.
  • Payload hash must be canonical and stable; audit storage must not add raw payload text solely for audit convenience.
  • Operator-stamped seed, elevation, and demotion must all emit audit records.
  • The implementation PR must supply the actual install/setup command, docs/runbook entry, and fresh-terminal Sage/Clara round-trip smoke evidence per the Ring 2 install/run lifecycle gate.
Candi review axes:
  • Isolation: PASS. Bridge is a persona-class allowlist, not global SPEC-056 relaxation; same-project resolution precedence protects local names; non-bridge cross-project sends fail closed.
  • Allowlist: PASS. v0.1 Sage/Clara only; admin path rejects all others; bootstrap/config cannot self-elevate.
  • Audit: PASS_WITH_GATES. Metadata plus payload-hash model is acceptable if atomic, scoped, canonical, and non-leaking.
  • Memory and data: PASS. No local auto-memory route; artifacts remain PID-PGR01; SPEC-114/115 classification/redaction/operator-review rules remain authoritative.
  • Install/run: PASS_WITH_GATES. Spec includes lifecycle questions; Donna/Lafonda PR must fill exact command and smoke evidence.

Artifact Ownership

Bridge personas write Prism-side durable artifacts to PID-PGR01:
  • Sage/Clara journals, todos, postmortems, and decisions use PID-PGR01.
  • Customer project agents may decide to persist local todos/journals in their own PID after receiving a bridge reply.
  • Bridge agents do not write directly into customer project artifact stores in v0.1.
This preserves customer project integrity while still allowing Customer Care to manage its own operational history.

Customer Care Behavior

Sage and Clara keep the contracts from SPEC-114 and SPEC-115:
  • Sage routes non-incident enhancement/recommendation work to normal intake unless policy asks Clara to classify it.
  • Clara owns Prism-product vs customer-internal classification.
  • Customer-internal content does not phone home.
  • Mixed content may produce only a redacted Prism-product subset after Clara/operator gates.
  • ET transports approved packets only; it does not classify, elevate, or bypass redaction/operator review.
Bridge status changes routing reachability only. It does not expand what Sage, Clara, or ET are allowed to do with payload content.

UI / Roster Contract

prism_whois and equivalent roster surfaces should show bridge personas as available recipients from any project in the tenant, with a clear machine-readable class:
{
  "identity": "Sage",
  "persona_class": "bridge",
  "home_pid": "PID-PGR01",
  "available_from_pid": "PID-DPA01"
}
Human-readable displays should mark bridge personas as Customer Care / bridge recipients without listing unrelated PID-PGR01 project internals.

Install / Run Lifecycle Gate

This spec changes routing, roster visibility, seed state, and an operator command surface. It is not shippable until these questions are answered by the implementation PR:
  1. How does a user install this?
    • The migration/backfill must run through the normal Prism upgrade/install path.
    • Sage and Clara bridge seeding must be part of the Plan #19 install lane or an explicit operator seed command.
  2. How does a user run this?
    • Operator setup must be a short, discoverable command or install step, not a hand-edited DB update.
    • Customer agents should use the existing prism_signal(..., to_identity='Sage'|'Clara') surface after setup.
  3. What environment/config does it depend on?
    • Existing Prism API/backend connectivity, authenticated operator stamp for bridge elevation, active Sage/Clara personas, and the existing signal mesh.
    • No new customer project env var should be required for v0.1.
  4. Does it work from a fresh terminal on every target machine/profile?
    • Fresh-terminal smoke must cover at least PID-DPA01 agent → Sage and Sage/Clara → originating agent on the target LAN fleet.
  5. Is the command memorable/discoverable?
    • The bridge setup command must appear in install docs/runbooks and prism_whois should make Sage/Clara discoverable as recipients.

Implementation Plan

  1. Add persona class schema/backfill and backend allowlist validation.
  2. Update signal recipient resolution to consult bridge personas after same-project resolution fails.
  3. Update send authorization to allow only same-project or bridge-involved cross-project sends.
  4. Add bridge audit write path and query surface.
  5. Update roster/whois response shape to include bridge personas and class metadata.
  6. Add operator seed/admin path for Sage and Clara.
  7. Add tests and smokes.
  8. Update docs and install/run instructions.

Tests and Acceptance Criteria

  • Existing same-project signal tests continue to pass unchanged.
  • Non-bridge cross-project send still fails closed.
  • Customer project agent can send a TaskAssigned or customer-care intake signal to Sage.
  • Customer project agent can send an incident-like signal to Clara.
  • Sage/Clara can reply to the originating project agent using in_reply_to.
  • A bridge cannot cross-project broadcast.
  • A non-allowlisted persona cannot be elevated to bridge, even through the admin path.
  • Bootstrap/config cannot self-elevate a persona to bridge.
  • Same-tenant authorization is proven from authoritative project metadata.
  • Bridge outbound send without in_reply_to rejects unless explicit target PID and target identity are supplied and tenant equality is verified.
  • prism_whois from a customer project includes Sage and Clara as persona_class='bridge' with home_pid='PID-PGR01'.
  • Bridge-routed signals produce audit rows containing both PIDs and canonical payload hashes.
  • Audit rows are written atomically with routing or the send fails closed.
  • Audit lookup from a customer project shows only that project’s bridge traffic and no unrelated PID-PGR01 internals.
  • Operator-stamped seed/elevation/demotion emits audit records.
  • Bridge durable artifacts created by Sage/Clara land in PID-PGR01, not the customer PID.
  • SPEC-114 and SPEC-115 classification/redaction/phone-home gates still pass.
  • Fresh-terminal install/run smoke demonstrates the operator setup command and a cross-project Sage/Clara round trip.

Rollback

  • Demote Sage and Clara to project through the operator-stamped path.
  • Leave audit rows intact.
  • Same-project signal routing remains unaffected.
  • Customer Care becomes Prism-internal only until bridge is re-enabled.

Risks

  • Data-leak risk if bridge exemption accidentally applies to all personas. Mitigation: backend allowlist check in resolver and admin path, plus negative tests.
  • Cross-tenant leakage if caller-supplied PID is trusted. Mitigation: derive tenant equality from authoritative project metadata.
  • Audit leak if customer project lookup exposes unrelated PID-PGR01 details. Mitigation: caller-scoped audit query authorization and focused response shape.
  • Artifact ownership confusion. Mitigation: bridge personas always write to PID-PGR01 in v0.1; customer-local persistence is receiver-owned.
  • Roster confusion. Mitigation: expose persona_class and home_pid explicitly.
  • Future cross-tenant extension pressure. Mitigation: v0.1 is tenant-local; cross-tenant requires a later spec with consent and auth model.

Downstream Handoff

  • Candi: governance review complete; accepted with implementation gates.
  • Donna: engineering implementation (PR #356 shipped backend + schema + routing + audit).
  • Desiree: docs update after implementation shape is stable (this page + Bridge Agents subsection on Client Incident Management).
  • Lafonda: install seed / fresh-terminal setup path.
  • Jade: real-usage cross-project smoke from customer project.

References

  • ADR #59 — Bridge Agents — cross-project routing primitive for Customer Care.
  • Candi governance review signal 0feac1ba-4dc0-4541-ab06-7bf4df356809.
  • Postmortem 4f21262d — Plan #19 v0.1 cross-project unreachability incident that motivated the bridge primitive.
  • SPEC-056 — Multi-tenant Routing, Identity, and Signal Isolation.
  • SPEC-034 — Agent-to-Agent Signal Delivery.
  • SPEC-052 — Signal Taxonomy and Per-Identity Signal Cache.
  • SPEC-114 — Sage and Clara Customer Care Incident Personas.
  • SPEC-115prism_phone_home and ET GitHub Issue Transport.
Last modified on May 18, 2026