Changelog

What's shipped, week by week

Pause-Health.AI is built in the open. The git log at github.com/hucmaggie/pause-health.ai is the source of truth — this page is a hand-curated narrative view of the marquee weeks. Roadmap items (what's coming) live at /roadmap.

244 marquee entries across 15 weeks189 total commits since May 24, 2026See all commits on GitHub →

Where we are right now

Provider-graph Phase 2 + Data 360 Phase 2 are both shipped.

The provider directory carries 2,015 NPPES-derived rows behind the frozen Experience API contract. Distance ranking from Census 2020 ZCTA centroids, six NPPES board-cert + multi-specialty signals, three state license-sanction filters dropping 1,720 sanctioned candidates at build (CA Medi-Cal + NY OPMC + TX TMB), real-shaped synthetic insurance, and a /provider browseable UI all ship today. Data Cloud Calculated Insights grounding is live in production on the trailsignup org (HRV / vasomotor burden / sleep disruption). The Care Router consumes both, so an MSCP-pathway routing decision now attaches a distance-ranked, plan-narrowed, modality-aware recommended-provider list to its output. Closed-loop outcomes scoring (Phase 3) activates with referral volume.

Read the provider-graph brief →Browse the directory →Curl the contract →

Week of September 13, 2026

The fabric meets Salesforce — five Pause agents go live in Agentforce, and all 110 land in Anypoint Exchange

This week the Agent Fabric stopped being a pure in-repo A2A construct and became discoverable across the MuleSoft + Salesforce stack. All 110 fabric agents were published to Anypoint Exchange as native type=agent assets (A2A v0.3 cards) via the Exchange Experience API — the fabric is now a browsable Agents & Tools catalog in the org. And five patient-facing agents were rebuilt as real, native Salesforce Agentforce agents: Benefits & Coverage Verification, Member Service (billing & claims), Appointment Scheduling, Care Router (symptom triage), and SDOH Screening (social needs). Each speaks to its fabric endpoint through a thin flat REST alias that reuses the same deterministic lib + the same Agent Fabric governance gate, registered as a Salesforce External Service and wired into an Agentforce subagent + action — so the Agentforce agent and the A2A agent can never diverge. Every one was tested GROUNDED in Agent Builder, including the load-bearing clinical-safety flows (Care Router's mandatory red-flag screen → urgent escalation; SDOH's positive interpersonal-safety screen → 988/911 human-social-worker escalation and consent-before-referral gate). A unified 'concierge' super-agent was attempted and honestly set aside — the Service Agent template's platform safety classifier intercepts benign coverage/billing questions at the router and isn't editable, so the five narrow standalone agents remain the reliable surface. Also this week: the site rebranded to Pause-Health.AI to match the new LinkedIn company page, and 143 pre-existing TypeScript errors were cleared so the frontend typechecks clean.

Agentforce: brought five Pause fabric agents into Salesforce Agentforce as native agents — Benefits & Coverage Verification, Member Service (billing & claims), Appointment Scheduling, Care Router (symptom triage with a mandatory red-flag screen), and SDOH Screening (social needs with 988/911 safety escalation + consent-before-referral) — each backed by a flat REST alias over its A2A fabric endpoint that reuses the same deterministic lib and governance gate, registered as a Salesforce External Service and wired into an Agentforce subagent + action, all five tested GROUNDED in Agent Builder and captured to the repo as deployable Bot + GenAiPlannerBundle metadata

Shipped
Details

The five patient-facing fabric agents (EBV, Member Service, Appointment Scheduling, Care Router, SDOH Screening) now run as real native Agentforce agents in the trailsignup org, not just mocked A2A endpoints. The pattern per agent: a thin flat REST alias (frontend/app/api/agentforce/<agent>/route.ts) wraps the A2A tasks/send endpoint — Agentforce External Services can't map an A2A JSON-RPC envelope, so the alias exposes a plain GET that reuses the SAME deterministic lib function (verifyCoverage / answerBillingQuestion / bookAppointment / scriptedRoute / screenSocialNeeds) and the SAME Agent Fabric governance gate, returning the flat result or a {blocked, violations} shape. Each alias ships to prod on Vercel, is registered in Salesforce as an External Service (PauseBenefitsVerification / PauseMemberService / PauseAppointmentScheduling / PauseCareRouter / PauseSdohScreening) against the existing Pause_Provider_API no-auth Named Credential, and is wired into one Agentforce subagent + action authored in Agent Builder. All five were tested GROUNDED in Preview: EBV returns in/out-of-network coverage + patient-responsibility and blocks on missing consent; Member Service answers claim/balance questions and routes out-of-scope requests to a human; Appointment Scheduling books against a synthetic provider calendar and blocks a double-book / out-of-availability slot; Care Router enforces a MANDATORY red-flag screen before routing (a missing screen hard-blocks on policy.intake.red-flag-mandatory) and escalates a positive red flag to urgent care + 911/ER; SDOH runs the CMS AHC-HRSN screen, surfaces a positive interpersonal-safety screen as a mandatory 988/911 human-social-worker escalation, and gates a community-resource referral behind explicit patient consent (blocked → asks → consents → proceeds). Two clinical agents required a routing workaround: the Service Agent template's Inappropriate Content guardrail intercepts sensitive symptom language, so the classification descriptions name those symptoms as legitimate clinical content and the reasoning asks single yes/no safety questions the patient answers without restating trigger terms. Each agent was retrieved from the org and committed as deploy-clean source (Bot + BotVersion + GenAiPlannerBundle with its localActions), and salesforce/manifest/package.xml now registers all five External Services + Bots + GenAiPlannerBundles — deployable to a fresh org via ./deploy.sh. Per-agent runbooks (salesforce/AGENTFORCE_*_RUNBOOK.md) capture the exact wiring + paste-ready reasoning copy. The backing fabric agents remain deterministic (no Claude) and synthetic/clearly-labeled — not real EDI / FHIR / booking / screening systems.

81cb213 EBV Agentforce agent: alias + OAS + runbook (16); fixes 143 pre-existing tsc errors7313189 EBV Agentforce agent: captured metadata + subagent-terminology runbook (18)0b5da57 Member Service (Billing & Coverage) Agentforce agent: alias + OAS + runbook (21)d414eb6 Capture the live Member Service Agentforce agent as source-of-truth (24)9e7c96b Appointment Scheduling (MSCP) Agentforce agent: alias + OAS + runbook (25)ce9273b Capture the live Appointment Scheduling Agentforce agent as source-of-truth (27)a279dbd Care Router Agentforce agent: alias + OAS + runbook (26)ca0c706 Capture the live Care Router Agentforce agent as source-of-truth (28)f27e869 SDOH Screening Agentforce agent: alias + OAS + runbook (29)9b74bb7 Capture the live SDOH Screening Agentforce agent — completes the 5-agent set (30)

Anypoint Exchange: published all 110 fabric agents as native type=agent assets (A2A v0.3 cards) via the Exchange Experience API, with dry-run-first tooling — the fabric is now a browsable Agents & Tools catalog in the org

Shipped
Details

All 110 fabric agents are registered in Anypoint Exchange as native type=agent assets (classifier a2a-card), published via the Exchange Experience API (POST .../assets with type=agent + files.json=the A2A card) — verified against the live org, which is the path that yields a real Agent-typed asset (the Maven jar PUT used for the spec assets yields type=unknown and is deliberately not used). The tooling under mulesoft/agents/ is dry-run by default: a deterministic offline snapshot of listAgents() drives a generator that writes one A2A card per agent, and a publisher that validates every asset and prints the exact publish plan with zero network calls unless run with --live CONFIRM=yes (plus a --probe read-only creds check and a --limit=N staged batch). Registration makes the agents discoverable in Exchange's Agents & Tools view; a scoping doc (VISUALIZER_RUNTIME_SCOPE.md) records the honest finding that Anypoint Agent Visualizer needs live Omni-Gateway runtime traffic — not just Exchange registration — to render a graph, so the Visualizer stays empty until a real runtime is stood up. Synthetic prototype cards; no real PHI.

bf4c9f8 Exchange agent-asset tooling (110 fabric agents published as type=agent) (31)

Agentforce: attempted a unified 'Pause Health Concierge' super-agent (one router across all five subagents) — fully built and its happy path worked, but honestly set aside because the Service Agent template's platform Inappropriate Content classifier intercepts benign coverage/billing questions at the router and isn't editable; the five narrow standalone agents remain the reliable surface

Shipped
Details

A unified concierge was built on the Agentforce Service Agent template — one host agent (Pause_Health_Concierge) whose router hands off across all five subagents (Care Routing, Appointment Scheduling, Benefits & Coverage, Billing & Coverage, Social Needs Screening) in a single conversation. The happy path worked GROUNDED in Preview (triage → offer to book → book → screen). But the template carries a platform-level Inappropriate Content safety classifier that evaluates at the Agent Router BEFORE routing reasoning runs, and with all five subagents under one router it fired inconsistently on benign questions — 'Will my Aetna plan cover a visit?', 'what do I owe' — returning a refusal. It is not an editable subagent (the router has no transition to it, there's no node to open), and neither strengthened per-subagent classification descriptions nor Agent-Level (System) Instructions overrode it. Decision: keep the five standalone agents (each narrow-scoped, so the classifier rarely mis-fires) as the deliverable; the concierge draft was left unactivated. The attempt + the paste-ready build copy + the reasons are documented in salesforce/AGENTFORCE_CONCIERGE_BUILD_SHEET.md for a possible future retry on a different template.

c67303e Concierge build sheet + outcome (attempted, kept 5 standalone) (32)

Brand + site: rebranded to Pause-Health.AI to match the new LinkedIn company page (new logo assets + wordmark casing across the site), added the company LinkedIn reference to the Organization JSON-LD and press page, fixed the press About-card layout, and cleared 143 pre-existing TypeScript errors so the frontend typechecks clean

Shipped
Details

Housekeeping alongside the integration work: the site rebranded from Pause-Health.ai to Pause-Health.AI to match the new LinkedIn company page (linkedin.com/company/pause-health.ai) — new optimized brand PNGs + wordmark casing across ~40 files, the company LinkedIn added to the Organization JSON-LD sameAs and a visible Follow link on the press page, and a press About-card width fix so it no longer reads as half-empty. Separately, 143 pre-existing TypeScript errors (chiefly test fixtures missing a required A2AMessage timestamp field, plus a handful of real type mismatches) were fixed so tsc --noEmit is clean and the frontend suite (4,616 tests) stays green — clearing the way for the Agentforce alias routes to ship on a green typecheck.

b393978 Update brand to match LinkedIn: new logo assets + Pause-Health.AI wordmark (22)34e2f3e Add the company LinkedIn page reference (19)

Week of September 6, 2026

The Agent Fabric crosses 100 — a run of deterministic classical-algorithm agents, each a genuinely new computation pattern

The fabric grew from the 68th to the 101st agent this week — a deliberate march through the classical-algorithms canon, each agent a DIFFERENT computation pattern with three governance-enforced honesty gates (sourced + self-consistent, a recomputing optimum, and never an autonomous action): Dijkstra shortest path, Boyer–Moore majority vote, trie longest-prefix match, weighted-interval-scheduling DP, Kadane's maximum-subarray, earliest-deadline-first scheduling, longest-common-subsequence diff, Huffman optimal prefix coding, linear partition by binary-search-on-the-answer (the 100th), and Kruskal's minimum spanning tree (the 101st) — alongside the patient-rights and payer-integrity agents (Right of Access, OIG exclusion screening, amendment/correction, information blocking, DDI safety, MLR rebate, 834 reconciliation, care-pathway sequencing, access-anomaly detection, caseload balancing, LASA medication-name safety, claim-lifecycle guard, NPI validation, household composition, provider benchmarking, network adequacy, PCP matching, reportable-condition classification, timeline merge, and SPC quality-shift detection). Every agent is deterministic (no Claude), PHI-audited where it touches clinical data, and demonstrable on /demo/intake with a parented Agent Fabric trace.

Agent Fabric: added the Status Timeline Compression / Run-Length Encoding (RLE) agent — deterministic run-length encoding that compresses a per-slot status stream into canonical (value, length) runs, with every encoding a sourced self-consistent lossless run list (it decodes back exactly), a re-deriving canonical RLE, and never an autonomous write-back (the 110th agent)

Shipped
Details

Added the one-hundred-and-tenth agent on the fabric — status-timeline-rle-agent, a DETERMINISTIC (no-Claude) platform / data-substrate stream-compression agent on the PHI-adjacent platform & data-substrate plane, reusing the existing data-plane tier as a SIBLING to the Huffman Coding and Timeline Merge agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric, and CRUCIALLY the heart of the service is RUN-LENGTH ENCODING: a single left-to-right pass that coalesces each maximal block of identical consecutive values into one (value, length) run — the canonical, provably-unique RLE of the stream, losslessly REVERSIBLE (decoding the runs reproduces the exact original). It is NOT the Huffman agent's OPTIMAL PREFIX CODING (a FREQUENCY-based variable-length code over the alphabet — this is CONSECUTIVE-RUN coalescing, order-dependent, no frequency model), NOT the Coverage Heatmap agent's DIFFERENCE-ARRAY RANGE ACCUMULATION, NOT the Rolling Census Peak agent's SLIDING-WINDOW MAXIMUM, NOT the Timeline Merge agent's K-WAY MERGE (which interleaves multiple sorted streams — this compresses ONE stream), and NOT the List Reconciliation agent's LONGEST COMMON SUBSEQUENCE. In a new pure lib/status-timeline-rle.ts, evaluateStatusTimeline(request) takes a per-slot STATUS stream (device state / bed-occupancy / monitoring status) and DETERMINISTICALLY run-length-encodes it into (value, length) runs, reading off the run count, the compression ratio (originalLength / runCount), the longest run, and the dominant status — with disposition compressible (fewer runs than slots) or incompressible (one run per slot — no consecutive repeats, RLE gains nothing). The exact, reversible run list is the invariant this service reports and defends. It COMPLEMENTS, not duplicates, the Huffman agent (frequency-based prefix coding) and the Timeline Merge agent (multi-source interleave): this run-length-compresses one status stream. TIME IS DATA: the statuses are plain values and the encoding is a pure function of them (no clock, no randomness), so the same request always yields the same determination. An encoding — compressible / incompressible — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresStewardReview:true, autoWritten:false); an incompressible disposition is a LEGITIMATE FINDING (no consecutive repeats to coalesce), NOT a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.statusrle.encoding-sourced (signal statusEncodingSourced, violating value false) blocks an encoding that isn't a real, lossless accounting — DECODING the runs (each value repeated `length` times, in order) must reproduce EXACTLY the submitted stream (same values, order, and length), every run length ≥ 1, honest counts/ratio/longest-run/dominant-status — a fabricated run, a wrong length, or a reordered decode is a corrupted encoding — the sourced + self-consistency gate (mirroring the Huffman Agent's code-sourced and the Rolling Census Peak Agent's windows-sourced) — backed by the pure guard encodingSourced; policy.statusrle.runs-canonical (signal statusRunsCanonical, violating value false) blocks a non-canonical run list — re-running RLE over the submitted statuses must reproduce the EXACT run list; RLE has a UNIQUE canonical form (maximal runs — adjacent runs never share a value), so an OVER-SPLIT run (a single run reported as two adjacent same-value runs) is non-canonical EVEN THOUGH IT STILL DECODES CORRECTLY — this is the load-bearing correctness gate, and it re-derives the canonical runs INDEPENDENT of the reported runs (so an over-split-but-decodable encoding fails canonical ONLY while a fabricated run that doesn't decode fails sourced only — the two gates are isolable) (mirroring the Rolling Census Peak Agent's deque-exact and the Huffman Agent's code-optimal) — backed by the guard runsCanonical; and policy.statusrle.no-autonomous-write (signal statusNoAutonomousWrite, violating value false) blocks a determination that autonomously wrote the compressed timeline back to a source of record, replaced the raw stream, or persisted the encoding (autoWritten:true — each is a data-write that must be authorized) or did not require steward review (requiresStewardReview:false) — the agent COMPRESSES on paper, and every encoding is a RECOMMENDATION requiring a data steward to confirm — backed by the guard noAutonomousWrite (mirroring the Timeline Merge Agent's no-autonomous-merge and the Rolling Census Peak Agent's no-autonomous-divert; the harmful action is enforced-off). It IS PHI-adjacent — the statuses reference a device / bed monitoring timeline — so it is on the HIPAA-audit policy (phiAccessed:true throughout) and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/status-timeline-rle/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — statusrle.receive-stream → statusrle.encode → statusrle.classify-disposition → statusrle.log-audit — with phiAccessed:true, returning the StatusTimelineDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Status Timeline panel (a compressible preset over a 16-slot RPM device stream → 5 runs (3.2× compression), longest run 5, dominant 'normal'; an incompressible preset where statuses alternate every slot → one run per slot; a stable preset that collapses to a single run; plus doesn't-decode / over-split / auto-written governance-block presets), a seeded statusrle.receive-stream→encode→classify-disposition→log-audit trace showing the compressible case (runCount 5, compressionRatio 3.2, requiresStewardReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'one hundred ten agents', with the Status Timeline Compression agent on the data-plane tier alongside the Huffman Coding agent) all reflect it. Menopause-relevant: a remote-monitoring device that streams a menopause patient's status once a minute across a long stable stretch — normal, normal, …, a brief high, back to normal — is exactly the run-heavy timeline this RLE compacts to a handful of runs for efficient storage and transmission, without ever overwriting the raw stream on its own. Frontend tests green (+ status-timeline-rle runLengthEncode / decode-round-trip / one-run-per-slot / empty, evaluate compressible / incompressible / stable / determinism, and three-guards-on-produced with over-split-decodes-but-non-canonical + doesn't-decode + zero-length-run + encoding-sourced-vs-runs-canonical-isolation + mis-merged + auto-written + skipped-review guard cases, the route's envelope / three governance blocks / compressible + incompressible + stable happy paths with a PHI-adjacent trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to one hundred ten agents); the stream is a clearly-labeled illustrative synthetic — NOT a certified time-series / telemetry compression system (real telemetry compression uses delta / delta-of-delta encoding, dictionary methods, Gorilla-style float compression, and lossy downsampling — not a bare RLE over illustrative status labels). Lint + build clean.

c8802b7 agent fabric: add the Status Timeline Compression / Run-Length Encoding (RLE) agent (110th) — deterministic run-length encoding that compresses a per-slot status stream into canonical (value, length) runs, with every encoding a sourced self-consistent lossless run list, a re-deriving canonical RLE, and never an autonomous write-back

Agent Fabric: added the Rolling Census Peak / Sliding-Window Maximum (Monotonic Deque) agent — deterministic monotonic deque that computes the peak census in every trailing window of a unit's occupancy readings and flags over-capacity windows, with every report a sourced self-consistent per-window peak (cross-checked by direct scanning), a re-deriving exact deque, and never an autonomous diversion (the 109th agent)

Shipped
Details

Added the one-hundred-and-ninth agent on the fabric — rolling-census-peak-agent, a DETERMINISTIC (no-Claude) care-coordination capacity-monitoring agent on the PHI-adjacent patient/clinical plane, reusing the existing care-coordination tier as a SIBLING to the Coverage Heatmap and Access Anomaly agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric, and CRUCIALLY the heart of the service is the MONOTONIC DEQUE sliding-window maximum: maintain a double-ended queue of candidate indices whose readings are decreasing, pop from the back every index whose reading is ≤ the incoming reading, push the new index, and drop the front once it falls out of the window — the front is always the window's maximum, O(1) amortized per window and O(n) overall. It is NOT the Access Anomaly agent's SLIDING-WINDOW COUNTING (a fixed-window EVENT COUNT — this is the sliding-window EXTREMUM via a monotonic deque), NOT the Coverage Heatmap agent's DIFFERENCE-ARRAY RANGE ACCUMULATION (per-slot occupancy from range-adds — this is the rolling MAX over a window of an existing series), NOT the Peak-Window agent's KADANE MAXIMUM-SUBARRAY (a max contiguous SUM — this is a max VALUE per fixed-width window), NOT the Fenwick / Benefit Accumulator agent's PREFIX SUMS, and NOT the SLA Worklist agent's EARLIEST-DEADLINE-FIRST SCHEDULING. In a new pure lib/rolling-census-peak.ts, evaluateRollingCensus(request) takes per-slot CENSUS readings, a trailing WINDOW width k, and a CAPACITY threshold, and DETERMINISTICALLY computes the peak census in every trailing window via the monotonic deque, flags the over-capacity windows, reads off the overall peak, and derives the disposition: within-capacity (no window breaches capacity) or over-capacity (some window peaks above it). The per-window peak is the invariant this service reports and defends. It COMPLEMENTS, not duplicates, the Coverage Heatmap agent (per-slot concurrent coverage) and the Access Anomaly agent (windowed event counts): this reports the rolling peak occupancy. TIME IS DATA: the readings + window size are plain numbers and the report is a pure function of them (no clock, no randomness), so the same request always yields the same determination. A report — within-capacity / over-capacity — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresSupervisorReview:true, autoDiverted:false); an over-capacity disposition is a LEGITIMATE FINDING (a capacity breach), NOT a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.rollingcensus.windows-sourced (signal censusWindowsSourced, violating value false) blocks a report whose per-window maxima aren't the true peaks — each windowMaxes[i] must equal max(readings[i .. i+k-1]), checked by DIRECT per-window scanning (INDEPENDENT of the monotonic-deque method), exactly readingCount - k + 1 windows, the overCapacityWindows exactly the breaching windows, peakCensus / windowCount / readingCount honest, and the disposition following — a fabricated window max, a mis-listed over-capacity window, or a dishonest peak is a corrupted report — the sourced + self-consistency gate (mirroring the Coverage Heatmap Agent's coverage-sourced and the Benefit Accumulator Agent's ledger-sourced) — backed by the pure guard windowsSourced; policy.rollingcensus.deque-exact (signal censusDequeExact, violating value false) blocks a mis-derived maxima array — re-running the MONOTONIC DEQUE sliding-window maximum over the submitted readings + window size must reproduce the reported windowMaxes array exactly, window for window — this is the load-bearing correctness gate, and it re-runs the monotonic deque INDEPENDENT of the reported maxima (and of the sourced gate's direct scanning), so the two gates CROSS-CHECK the same per-window truth by TWO DIFFERENT METHODS: a fabricated maxima array that still reports the right over-capacity windows fails deque only, and a genuine-but-mislabeled disposition fails sourced only — the two are isolable (mirroring the Coverage Heatmap Agent's accumulation-exact and the Benefit Accumulator Agent's accumulator-exact) — backed by the guard dequeExact; and policy.rollingcensus.no-autonomous-divert (signal censusNoAutonomousDivert, violating value false) blocks a determination that autonomously diverted admissions, triggered surge staffing, or acted on a peak (autoDiverted:true — each is an operational action that must be authorized) or did not require supervisor review (requiresSupervisorReview:false) — the agent MONITORS on paper, and every report is a RECOMMENDATION requiring a nursing supervisor to confirm — backed by the guard noAutonomousDivert (mirroring the Coverage Heatmap Agent's no-autonomous-staff and the Interpreter Assignment Agent's no-autonomous-dispatch; the harmful action is enforced-off). It IS PHI-adjacent — the census references a care unit's occupancy — so it is on the HIPAA-audit policy (phiAccessed:true throughout) and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/rolling-census-peak/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — rollingcensus.receive-readings → rollingcensus.peak → rollingcensus.classify-disposition → rollingcensus.log-audit — with phiAccessed:true, returning the RollingCensusDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Rolling Census Peak panel (an over-capacity preset over 10 hourly readings with a 3-hour window and capacity 18 → window maxes [15,20,20,20,19,16,17,18], four windows over capacity, peak 20; a within-capacity preset that never breaches; a spike preset exercising the deque's back-eviction with a decreasing run then a spike; plus fabricated-max / mis-derived / auto-diverted governance-block presets), a seeded rollingcensus.receive-readings→peak→classify-disposition→log-audit trace showing the over-capacity case (peakCensus 20, overCapacityCount 4, requiresSupervisorReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'one hundred nine agents', with the Rolling Census Peak agent on the care-coordination tier alongside the Coverage Heatmap agent) all reflect it. Menopause-relevant: watching a menopause-clinic's rolling occupancy across a busy day — seeing which 3-hour windows peak above the safe capacity as walk-ins and scheduled visits stack up — so a supervisor can flex capacity before wait times or safety suffer, is exactly the rolling peak this monotonic-deque sliding-window maximum computes, without ever diverting a patient on its own. Frontend tests green (+ rolling-census-peak slidingWindowMax / deque-vs-direct-agreement / back-eviction / window-too-large, evaluate over-capacity / within-capacity / spike / determinism, and three-guards-on-produced with fabricated-max + mis-listed-windows + dishonest-peak + windows-sourced-vs-deque-exact-isolation + mis-derived + auto-diverted + skipped-review guard cases, the route's envelope / three governance blocks / over-capacity + within-capacity + spike happy paths with a PHI-adjacent trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to one hundred nine agents); the readings are a clearly-labeled illustrative synthetic — NOT a certified capacity-management / patient-flow system (real census management weighs acuity, staffed vs licensed beds, isolation & telemetry needs, anticipated discharges, and boarding — not a bare rolling max over illustrative counts). Lint + build clean.

bd51443 agent fabric: add the Rolling Census Peak / Sliding-Window Maximum (Monotonic Deque) agent (109th) — deterministic monotonic deque that computes the peak census in every trailing window and flags over-capacity windows, with every report a sourced self-consistent per-window peak, a re-deriving exact deque, and never an autonomous diversion

Agent Fabric: added the Coverage Heatmap / Difference-Array Range Accumulation agent — deterministic difference array that computes per-slot concurrent staffing coverage from overlapping shift intervals and flags under-staffed slots, with every heatmap a sourced self-consistent count (cross-checked by direct counting), a re-materializing exact accumulation, and never an autonomous staffing action (the 108th agent)

Shipped
Details

Added the one-hundred-and-eighth agent on the fabric — coverage-heatmap-agent, a DETERMINISTIC (no-Claude) care-coordination capacity-visibility agent on the PHI-adjacent patient/clinical plane, reusing the existing care-coordination tier as a SIBLING to the Schedule Conflict and Caseload Balancing agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric, and CRUCIALLY the heart of the service is the DIFFERENCE ARRAY (the imos / range-update technique): to add `staff` to every slot in [start, end), increment diff[start] and decrement diff[end] — an O(1) range update — then a single PREFIX-SUM pass materializes the concurrent coverage at every slot in O(T), so applying m overlapping intervals costs O(m + T), not O(m·T). It is NOT the Fenwick / Benefit Accumulator agent's POINT-UPDATE + PREFIX-QUERY tree (the dual problem — this is RANGE-UPDATE + full MATERIALIZE), NOT the Schedule Conflict agent's GREEDY INTERVAL SELECTION (which picks a max non-overlapping subset — this COUNTS overlaps per slot), NOT the Peak-Window agent's KADANE MAXIMUM-SUBARRAY (a max contiguous sum — this is per-slot occupancy), NOT the Caseload Balancing agent's BIN-PACKING, and NOT the Batch Partition agent's LINEAR PARTITION. In a new pure lib/coverage-heatmap.ts, evaluateCoverageHeatmap(request) takes a set of staffing COVERAGE INTERVALS (each { label, start, end, staff }) over a slot count and a REQUIRED MINIMUM, and DETERMINISTICALLY materializes the concurrent coverage at every slot via the difference array, finds the UNDER-STAFFED slots (below the minimum), reads off min/max, and derives the disposition: fully-covered (every slot meets the minimum) or understaffed (some slot below). The per-slot concurrent coverage is the invariant this service reports and defends. It COMPLEMENTS, not duplicates, the Schedule Conflict agent (double-booking guard) and the Caseload Balancing agent (panel capacity fill): this visualizes concurrent coverage across a schedule. TIME IS DATA: the intervals + slot indices are plain numbers and the heatmap is a pure function of them (no clock, no randomness), so the same request always yields the same determination. A heatmap — fully-covered / understaffed — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresManagerReview:true, autoStaffed:false); an understaffed disposition is a LEGITIMATE FINDING (a coverage gap), NOT a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.coverageheat.coverage-sourced (signal coverageSourcedSignal, violating value false) blocks a heatmap whose per-slot coverage isn't the true count — each coverage[t] must equal the sum of `staff` over every submitted interval whose [start, end) contains t, checked by DIRECT interval counting (INDEPENDENT of the difference-array method), the understaffedSlots exactly the below-min slots, minCoverage / maxCoverage / slotCount / intervalCount honest, and the disposition following — a fabricated coverage value, a mis-listed under-staffed slot, or a dishonest min/max is a corrupted heatmap — the sourced + self-consistency gate (mirroring the Benefit Accumulator Agent's ledger-sourced and the Interpreter Assignment Agent's assignment-sourced) — backed by the pure guard coverageSourced; policy.coverageheat.accumulation-exact (signal coverageAccumulationExact, violating value false) blocks a mis-materialized heatmap — re-applying the intervals to a fresh DIFFERENCE ARRAY and prefix-summing must reproduce the reported coverage array exactly, slot for slot — this is the load-bearing correctness gate, and it re-runs the difference-array range accumulation INDEPENDENT of the reported coverage (and of the sourced gate's direct counting), so the two gates CROSS-CHECK the same per-slot truth by TWO DIFFERENT METHODS: a fabricated coverage that still reports the right under-staffed slots fails accumulation only, and a genuine-but-mislabeled disposition fails sourced only — the two are isolable (mirroring the Benefit Accumulator Agent's accumulator-exact and the Interpreter Assignment Agent's cost-optimal) — backed by the guard accumulationExact; and policy.coverageheat.no-autonomous-staff (signal coverageNoAutonomousStaff, violating value false) blocks a determination that autonomously scheduled, adjusted, or dispatched staff (autoStaffed:true — each is a staffing action that must be authorized) or did not require manager review (requiresManagerReview:false) — the agent VISUALIZES on paper, and every heatmap is a RECOMMENDATION requiring a staffing manager to confirm before any coverage changes — backed by the guard noAutonomousStaff (mirroring the Interpreter Assignment Agent's no-autonomous-dispatch and the Benefit Accumulator Agent's no-autonomous-adjust; the harmful action is enforced-off). It IS PHI-adjacent — the intervals reference care-unit staffing — so it is on the HIPAA-audit policy (phiAccessed:true throughout) and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/coverage-heatmap/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — coverageheat.receive-schedule → coverageheat.accumulate → coverageheat.classify-disposition → coverageheat.log-audit — with phiAccessed:true, returning the CoverageHeatmapDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Coverage Heatmap panel (an understaffed preset over a 12-slot care-unit day with four overlapping shifts against a required min of 2 → coverage [2,2,3,3,3,3,1,1,3,3,2,2], slots 6–7 below the minimum; a fully-covered preset where the intervals blanket every slot; a spike preset with many overlapping short intervals → a midday spike to 5 and understaffed edges; plus fabricated-coverage / mis-materialized / auto-staffed governance-block presets), a seeded coverageheat.receive-schedule→accumulate→classify-disposition→log-audit trace showing the understaffed case (minCoverage 1, understaffedCount 2, requiresManagerReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'one hundred eight agents', with the Coverage Heatmap agent on the care-coordination tier alongside the Schedule Conflict agent) all reflect it. Menopause-relevant: seeing which hours of a menopause-clinic day dip below the required nurse / MA coverage as morning and afternoon shifts overlap and hand off — so a manager can plug the gap before it becomes a wait-time or safety problem — is exactly the per-slot concurrency this difference-array heatmap computes, without ever moving a staff member on its own. Frontend tests green (+ coverage-heatmap accumulateCoverage / coverageByDirectCount-agreement / zero-width-and-zero-staff / empty, evaluate understaffed / fully-covered / spike / determinism, and three-guards-on-produced with fabricated-coverage + mis-listed-slots + dishonest-min-max + coverage-sourced-vs-accumulation-exact-isolation + mis-materialized + auto-staffed + skipped-review guard cases, the route's envelope / three governance blocks / understaffed + fully-covered + spike happy paths with a PHI-adjacent trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to one hundred eight agents); the intervals are a clearly-labeled illustrative synthetic — NOT a certified workforce-management / staffing system (real staffing weighs skill mix, acuity-adjusted ratios, licensure, breaks & meal relief, union rules, and float pools — not a bare count of overlapping intervals). Lint + build clean.

6c38a33 agent fabric: add the Coverage Heatmap / Difference-Array Range Accumulation agent (108th) — deterministic difference array that computes per-slot concurrent staffing coverage from overlapping shift intervals and flags under-staffed slots, with every heatmap a sourced self-consistent count, a re-materializing exact accumulation, and never an autonomous staffing action

Agent Fabric: added the Interpreter Assignment / Optimal Assignment (Hungarian Algorithm) agent — deterministic Hungarian algorithm that matches interpreters to concurrent appointments at minimum total cost, with every assignment a sourced self-consistent one-to-one matching, a re-optimizing cost, and never an autonomous dispatch (the 107th agent)

Shipped
Details

Added the one-hundred-and-seventh agent on the fabric — interpreter-assignment-agent, a DETERMINISTIC (no-Claude) care-coordination assignment agent on the PHI-adjacent patient/clinical plane, reusing the existing care-coordination tier as the operational SIBLING of the Language Access & Health Equity agent (which decides WHETHER a qualified interpreter is required; this decides WHICH interpreter covers WHICH appointment at least total cost) — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric, and CRUCIALLY the heart of the service is the HUNGARIAN ALGORITHM (Kuhn–Munkres): the O(n³) combinatorial method that finds a minimum-cost perfect matching in a bipartite graph by maintaining dual potentials and augmenting along tight-edge alternating paths until every row is matched. It is EMPHATICALLY DISTINCT from the two matching agents it sits near: NOT the PCP Matching agent's GALE–SHAPLEY STABLE MATCHING (which produces a STABLE matching from two-sided PREFERENCE lists — no costs, no global optimum, and stability, not minimum total cost, is its property) and NOT the Caseload Balancing agent's WORST-FIT-DECREASING BIN-PACKING (an unordered greedy capacity fill, not a one-to-one optimal matching). It is also NOT the Referral Throughput agent's MAX-FLOW, NOT the Network Build-Out agent's MINIMUM SPANNING TREE, NOT the Batch Partition agent's LINEAR PARTITION, NOT the Outreach agent's 0/1 KNAPSACK, and NOT the Care Routing agent's DIJKSTRA'S SHORTEST PATH. In a new pure lib/interpreter-assignment.ts, evaluateInterpreterAssignment(request) takes a set of qualified INTERPRETERS, a set of concurrent APPOINTMENTS, and a COST matrix (travel + wait + skill-mismatch, or an UNAVAILABLE sentinel when an interpreter can't cover an appointment), and DETERMINISTICALLY computes the MINIMUM-TOTAL-COST one-to-one ASSIGNMENT via the Hungarian algorithm on a padded square matrix (unavailable / padded cells given a large finite stand-in so the solver never prefers them; a match landing on such a cell is reported unmatched) — reporting the pairings, the total cost, any uncoverable appointments, and the disposition: assignable (every appointment covered with a finite-cost interpreter) or infeasible (some appointment has no qualified interpreter). The minimum total assignment cost is the invariant this service reports and defends. It COMPLEMENTS, not duplicates, the PCP Matching agent (stable member↔PCP matching) and the Caseload Balancing agent (panel capacity fill): this is the optimal one-to-one assignment. TIME IS DATA: the costs are plain numbers and the assignment is a pure function of them (no clock, no randomness — ties broken by a stable row/column order), so the same request always yields the same determination. An assignment — assignable / infeasible — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresCoordinatorReview:true, autoDispatched:false); an infeasible disposition is a LEGITIMATE FINDING (a coverage gap), NOT a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.interpasg.assignment-sourced (signal interpAssignmentSourced, violating value false) blocks an assignment that isn't a real one-to-one matching — each pairing using a SUBMITTED interpreter + appointment, no interpreter or appointment used twice, each cost equal to the SUBMITTED matrix cell and finite (not the UNAVAILABLE sentinel), the totalCost equal to the sum of the chosen cells, the unmatched list exactly the uncovered appointments, and the disposition following — a fabricated pairing, a reused interpreter, or an overstated cost is a corrupted assignment — the sourced + self-consistency gate (mirroring the Benefit Accumulator Agent's ledger-sourced and the Network Build-Out Agent's tree-sourced) — backed by the pure guard assignmentSourced; policy.interpasg.cost-optimal (signal interpAssignmentOptimal, violating value false) blocks a sub-optimal assignment — re-running the HUNGARIAN ALGORITHM over the submitted cost matrix must reproduce the reported totalCost (and disposition) — this is the load-bearing correctness gate, and it recomputes the minimum total cost INDEPENDENT of the reported pairings (it compares the scalar optimum, since different optimal assignments can tie on total cost — so a fabricated assignment that still reports the optimal cost fails sourced only, and a real-but-sub-optimal assignment fails optimal only — the two gates are isolable) (mirroring the Benefit Accumulator Agent's accumulator-exact and the Network Build-Out Agent's cost-optimal) — backed by the guard assignmentOptimal; and policy.interpasg.no-autonomous-dispatch (signal interpNoAutonomousDispatch, violating value false) blocks a determination that autonomously booked, dispatched, or notified an interpreter (autoDispatched:true — each is a scheduling action that must be authorized) or did not require coordinator review (requiresCoordinatorReview:false) — the agent ASSIGNS on paper, and every assignment is a RECOMMENDATION requiring a language-access coordinator to confirm — backed by the guard noAutonomousDispatch (mirroring the Benefit Accumulator Agent's no-autonomous-adjust and the Referral Throughput Agent's no-autonomous-route; the harmful action is enforced-off). It IS PHI-adjacent — the appointments reference member encounters — so it is on the HIPAA-audit policy (phiAccessed:true throughout) and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/interpreter-assignment/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — interpasg.receive-roster → interpasg.assign → interpasg.classify-disposition → interpasg.log-audit — with phiAccessed:true, returning the InterpreterAssignmentDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Interpreter Assignment panel (an assignable preset over three interpreters + three appointments → the min-total-cost matching of 12, NOT the greedy per-appointment pick; a greedy-trap preset where the naive cheapest-per-appointment pick would double-book but the Hungarian optimum spreads them for a lower total; an infeasible preset where one appointment has no qualified interpreter; plus reused-interpreter / sub-optimal / auto-dispatched governance-block presets), a seeded interpasg.receive-roster→assign→classify-disposition→log-audit trace showing the assignable case (totalCost 12, requiresCoordinatorReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'one hundred seven agents', with the Interpreter Assignment agent on the care-coordination tier alongside the Language Access agent) all reflect it. Menopause-relevant: staffing a morning of concurrent menopause-clinic visits — a Spanish telehealth consult, a Mandarin in-person visit, an Arabic follow-up — with the on-call interpreters at the least total travel + wait cost, and surfacing the appointment that has no qualified interpreter, is exactly the optimal assignment this Hungarian solver computes, without ever booking an interpreter on its own. Frontend tests green (+ interpreter-assignment solveAssignment optimal-matching / uncoverable / greedy-trap, evaluate assignable / infeasible / determinism, and three-guards-on-produced with reused-interpreter + unavailable-cell + overstated-cost + assignment-sourced-vs-cost-optimal-isolation + sub-optimal + auto-dispatched + skipped-review guard cases, the route's envelope / three governance blocks / assignable + infeasible + greedy-trap happy paths with a PHI-adjacent trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to one hundred seven agents); the costs are a clearly-labeled illustrative synthetic — NOT a certified interpreter-scheduling / workforce system (real interpreter scheduling weighs certification & specialty, modality, union & labor rules, travel logistics, and member language preference — not a bare cost matrix). Lint + build clean.

01a3835 agent fabric: add the Interpreter Assignment / Optimal Assignment (Hungarian Algorithm) agent (107th) — deterministic Hungarian algorithm that matches interpreters to concurrent appointments at minimum total cost, with every assignment a sourced self-consistent one-to-one matching, a re-optimizing cost, and never an autonomous dispatch

Agent Fabric: added the Benefit Accumulator Ledger / Fenwick-Tree Prefix Sums agent — deterministic Fenwick tree that tallies a member's running benefit accumulator and locates the OOP-max crossover claim, with every ledger a sourced self-consistent accounting, a re-deriving exact accumulator, and never an autonomous adjustment (the 106th agent)

Shipped
Details

Added the one-hundred-and-sixth agent on the fabric — benefit-accumulator-agent, a DETERMINISTIC (no-Claude) payer-operations accumulator-ledger agent on the PHI-bearing payer & plan operations plane, reusing the existing payer-operations tier as a SIBLING to the Member Cost-Share, Claims Adjudication, and Audit Sample agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric, and CRUCIALLY the heart of the service is the FENWICK TREE (Binary Indexed Tree): a cumulative-frequency data structure supporting point updates and prefix-sum queries in O(log n), plus a binary lower-bound descent that finds the first index whose prefix sum reaches a threshold in O(log n). It is NOT the Member Cost-Share agent's COST-SHARING WATERFALL (which splits a SINGLE claim across deductible / coinsurance / OOP for one date of service — this is a CUMULATIVE data structure over a SEQUENCE of claims with prefix-sum + find-by-threshold queries), NOT the Audit Sample agent's RESERVOIR SAMPLING, NOT the Duplicate-Claim Screen agent's BLOOM FILTER, NOT the MLR Rebate agent's LARGEST-REMAINDER APPORTIONMENT, NOT the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS, and NOT the Peak-Window agent's KADANE MAXIMUM-SUBARRAY. In a new pure lib/benefit-accumulator.ts, evaluateBenefitAccumulator(request) takes an ORDERED sequence of applied claim amounts and an OUT-OF-POCKET MAXIMUM, and DETERMINISTICALLY computes the running cumulative totals and locates the CROSSOVER claim — the first at which the running total reaches/exceeds the OOP max — via a Fenwick-tree lower-bound descent (amounts scaled to integer cents so the compares are exact) — reporting the per-claim running totals, the total applied, the crossover index (or -1), the remaining-before-OOP-max, and the disposition: under-oop-max (never crosses) or oop-max-met (crosses at some claim, after which the plan pays 100%). The running prefix sums and the crossover index are the invariants this service reports and defends. It COMPLEMENTS, not duplicates, the Member Cost-Share agent (which splits a single claim across the cost-sharing waterfall): this tallies the running accumulator across many claims. TIME IS DATA: the amounts + OOP max are plain numbers and the ledger is a pure function of them (no clock, no randomness), so the same request always yields the same determination. A ledger — under-oop-max / oop-max-met — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresAnalystReview:true, autoAdjusted:false); an oop-max-met disposition is a LEGITIMATE FINDING (the member reached their OOP maximum), NOT a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.benefitacc.ledger-sourced (signal benefitLedgerSourced, violating value false) blocks a ledger that isn't a real, self-consistent accounting — each runningTotals[k] must equal the sum of appliedAmounts[0..k], the reported totalApplied equal to the final running total, the crossoverIndex either -1 or a valid submitted-claim index, remainingBeforeOopMax equal to max(0, oopMax - totalApplied), and the disposition following — a fabricated running total, a mis-summed ledger, or an out-of-range crossover is a corrupted accounting — the sourced + self-consistency gate (mirroring the Audit Sample Agent's sample-sourced and the Duplicate-Claim Screen Agent's filter-sourced) — backed by the pure guard ledgerSourced; policy.benefitacc.accumulator-exact (signal benefitAccumulatorExact, violating value false) blocks a mislocated crossover — re-building the FENWICK TREE from the submitted amounts and re-querying must reproduce every prefix sum, and the CROSSOVER index located by the tree's binary lower-bound descent must equal the reported crossoverIndex — this is the load-bearing correctness gate, and it re-derives the prefix sums AND the crossover INDEPENDENT of the reported running totals (it descends the tree, not the reported array; a mislocated crossover mis-states when the plan starts paying 100% — the member's liability — so a fabricated ledger that still reports the right crossover fails sourced only, and a real-but-mislocated crossover fails exact only — the two gates are isolable) (mirroring the Audit Sample Agent's selection-reproducible and the Duplicate-Claim Screen Agent's membership-exact) — backed by the guard accumulatorExact; and policy.benefitacc.no-autonomous-adjust (signal benefitNoAutonomousAdjust, violating value false) blocks a determination that autonomously posted, adjusted, or paid against a member's real accumulator (autoAdjusted:true — each is a benefit-adjustment action that must be authorized) or did not require analyst review (requiresAnalystReview:false) — the agent COMPUTES on paper, and every ledger is a RECOMMENDATION requiring a benefits analyst to confirm before anything touches the member's real accumulator — backed by the guard noAutonomousAdjust (mirroring the Audit Sample Agent's no-autonomous-audit and the Duplicate-Claim Screen Agent's no-autonomous-reject; the harmful action is enforced-off). It IS PHI-adjacent — the ledger references a member's claims — so it is on the HIPAA-audit policy (phiAccessed:true throughout) and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/benefit-accumulator/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — benefitacc.receive-ledger → benefitacc.accumulate → benefitacc.classify-disposition → benefitacc.log-audit — with phiAccessed:true, returning the BenefitAccumulatorDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Benefit Accumulator panel (an oop-max-met preset over six claims against a $3,000 OOP max → the running total crosses at the fifth claim; an under-oop-max preset where the total stays below the max with a remaining balance reported; an immediate-crossover preset where one large first claim meets the max; plus fabricated-total / mislocated-crossover / auto-adjusted governance-block presets), a seeded benefitacc.receive-ledger→accumulate→classify-disposition→log-audit trace showing the oop-max-met case (totalApplied 3550, crossoverIndex 4, requiresAnalystReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'one hundred six agents', with the Benefit Accumulator agent on the payer & plan operations plane alongside the Member Cost-Share agent) all reflect it. Menopause-relevant: tracking a member's running out-of-pocket accumulation across a year of menopause-care claims — HRT, labs, specialist visits — and pinpointing the claim at which they hit their OOP maximum (so the plan pays 100% thereafter) is exactly what this Fenwick accumulator computes, without ever adjusting the member's real accumulator on its own. Frontend tests green (+ benefit-accumulator FenwickTree point-add / prefix-sum / lower-bound, runningTotalsOf / crossoverViaFenwick, evaluate oop-max-met / under / immediate / determinism, and three-guards-on-produced with fabricated-total + dishonest-total + out-of-range-crossover + ledger-sourced-vs-accumulator-exact-isolation + mislocated-crossover + disagreeing-prefix + auto-adjusted + skipped-review guard cases, the route's envelope / three governance blocks / oop-max-met + under + immediate happy paths with a PHI-adjacent trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to one hundred six agents); the amounts are a clearly-labeled illustrative synthetic — NOT a certified benefits-accumulator / claims-payment system (real accumulator processing weighs the full benefit design — embedded vs aggregate family deductibles, network tiers, carve-outs, EOB reversals — plan-year resets, and an authoritative accumulator store — not a bare prefix-sum over illustrative amounts). Lint + build clean.

ccf78bd agent fabric: add the Benefit Accumulator Ledger / Fenwick-Tree Prefix Sums agent (106th) — deterministic Fenwick tree that tallies a member's running benefit accumulator and locates the OOP-max crossover claim, with every ledger a sourced self-consistent accounting, a re-deriving exact accumulator, and never an autonomous adjustment

Agent Fabric: added the Audit Sample Selection / Reservoir Sampling (Algorithm R, Seeded) agent — deterministic single-pass reservoir sampling that draws a reproducible, uniform k-record audit sample from a stream, with every sample a sourced self-consistent subset, a re-runnable seeded draw, and never an autonomous audit (the 105th agent)

Shipped
Details

Added the one-hundred-and-fifth agent on the fabric — audit-sample-agent, a DETERMINISTIC (no-Claude) payer-operations compliance-sampling agent on the PHI-bearing payer & plan operations plane, reusing the existing payer-operations tier as a SIBLING to the Claims Adjudication, Fraud-Waste-Abuse, and Duplicate-Claim Screen agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric, and CRUCIALLY the heart of the service is RESERVOIR SAMPLING (Vitter's Algorithm R): fill a reservoir with the first k items, then for each subsequent item at 0-indexed position i draw j in [0, i] and replace reservoir[j] if j < k; after one pass over a stream of unknown / unbounded length, every item has been retained with uniform probability k/n, without ever holding the whole population in memory. It is NOT the Duplicate-Claim Screen agent's BLOOM FILTER (a membership test, not a uniform draw), NOT the Outreach Prioritization agent's 0/1 KNAPSACK (a value-maximizing subset, not an equal-probability sample), NOT the SLA Worklist agent's EARLIEST-DEADLINE-FIRST SCHEDULING, NOT the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS, NOT the Contact Rate Limit agent's TOKEN BUCKET, and NOT the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE. In a new pure lib/audit-sample.ts, evaluateAuditSample(request) takes a STREAM of record ids (claims / charts flagged for a compliance audit), a target sample size k, and an explicit SEED, and DETERMINISTICALLY draws a k-record sample via Algorithm R with a SEEDED PRNG (mulberry32 — no OS randomness) — reporting the selected ids, the population size, the effective sample size (min(k, n)), the uniform inclusion probability (k/n), the seed, and the disposition: sampled (n > k) or full-population (n ≤ k → the whole population is selected). The randomness being seeded is the whole point: the sample is fully REPRODUCIBLE — the same stream + k + seed always yields the same records, which is what makes an audit sample DEFENSIBLE (an auditor, or a regulator, can re-run it and get the identical set). The uniform inclusion probability and the reproducibility of the seeded draw are the invariants this service reports and defends. It COMPLEMENTS, not duplicates, the Fraud-Waste-Abuse and Duplicate-Claim Screen agents (which flag records): this selects a defensible SAMPLE of records to audit. TIME IS DATA: the ids + k + seed are plain data and the draw is a pure function of them (a seeded PRNG, no clock), so the same request always yields the same sample. A sample — sampled / full-population — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresAuditorReview:true, autoAudited:false); a full-population disposition is a LEGITIMATE FINDING (the population is at most k), NOT a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.auditsample.sample-sourced (signal auditSampleSourced, violating value false) blocks a sample that isn't a real subset of the submitted stream — every selected id appearing in the submitted recordIds (no fabricated id), no id selected more times than it appears, the sample size equal to min(sampleSize, populationSize), the reported populationSize equal to the stream length, the inclusionProbability equal to effectiveSampleSize / populationSize, and the disposition following — a fabricated id, a duplicate pick, or a mis-sized sample is a corrupted draw — the sourced + self-consistency gate (mirroring the Duplicate-Claim Screen Agent's filter-sourced and the Contact Rate Limit Agent's replay-sourced) — backed by the pure guard sampleSourced; policy.auditsample.selection-reproducible (signal auditSelectionReproducible, violating value false) blocks a cherry-picked or otherwise unreproducible draw — re-running the seeded RESERVOIR SAMPLING over the submitted stream + (sampleSize, seed) must reproduce the EXACT sample (same ids, same order) — this is the load-bearing correctness gate, and it re-runs Algorithm R INDEPENDENT of the reported sample (so a fabricated-but-in-population sample fails reproducibility only, and a real seeded draw with a fabricated id fails sourced only — the two gates are isolable) (mirroring the Duplicate-Claim Screen Agent's membership-exact and the Contact Rate Limit Agent's throttle-exact) — backed by the guard selectionReproducible; and policy.auditsample.no-autonomous-audit (signal auditNoAutonomousAudit, violating value false) blocks a determination that autonomously opened, adjudicated, flagged, or acted on a sampled record (autoAudited:true — each is an audit action that must be authorized) or did not require auditor review (requiresAuditorReview:false) — the agent SELECTS on paper, and every sample is a RECOMMENDATION of WHICH records to pull, requiring a compliance auditor to run the actual audit — backed by the guard noAutonomousAudit (mirroring the Duplicate-Claim Screen Agent's no-autonomous-reject and the Contact Rate Limit Agent's no-autonomous-send; the harmful action is enforced-off). It IS PHI-adjacent — record ids are PHI-adjacent — so it is on the HIPAA-audit policy (phiAccessed:true throughout) and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/audit-sample/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — auditsample.receive-population → auditsample.select → auditsample.classify-disposition → auditsample.log-audit — with phiAccessed:true, returning the AuditSampleDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Audit Sample panel (a sampled preset drawing 5 of 20 claim ids with a fixed seed → each with a 0.25 inclusion probability; a reseed preset over the same population with a different seed → a different reproducible sample, showing the seed (not chance) determines the draw; a full-population preset where the population (4) is smaller than the requested sample (10); plus fabricated-id / cherry-picked / auto-audited governance-block presets), a seeded auditsample.receive-population→select→classify-disposition→log-audit trace showing the sampled case (effectiveSampleSize 5, requiresAuditorReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'one hundred five agents', with the Audit Sample agent on the payer & plan operations plane alongside the Claims Adjudication and Duplicate-Claim Screen agents) all reflect it. Menopause-relevant: pulling a defensible, reproducible sample of HRT-titration or menopause-visit claims for an SIU or quality audit — one a regulator can re-run and get the identical records — is exactly what this seeded reservoir sampler produces, without ever opening a chart on its own. Frontend tests green (+ audit-sample mulberry32 determinism, reservoirSample subset / whole-population / k=0 / different-seed, evaluate sampled / full-population / determinism, and three-guards-on-produced with fabricated-id + mis-sized + duplicate-pick + sample-sourced-vs-selection-reproducible-isolation + cherry-picked + wrong-seed + auto-audited + skipped-review guard cases, the route's envelope / three governance blocks / sampled + full-population + reseed happy paths with a PHI-adjacent trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to one hundred five agents); the ids are a clearly-labeled illustrative synthetic — NOT a certified statistical-sampling / audit system (real audit sampling weighs stratification, RAT-STATS / OIG methodology, confidence intervals, and dollar-unit / probability-proportional-to-size designs — not a bare uniform reservoir over illustrative ids). Lint + build clean.

19609ac agent fabric: add the Audit Sample Selection / Reservoir Sampling (Algorithm R, Seeded) agent (105th) — deterministic single-pass reservoir sampling that draws a reproducible, uniform k-record audit sample from a stream, with every sample a sourced self-consistent subset, a re-runnable seeded draw, and never an autonomous audit

Agent Fabric: added the Duplicate-Claim Pre-Screen / Bloom-Filter Membership Test agent — deterministic Bloom filter that pre-screens incoming claim ids against processed ids (definitely-new vs possibly-duplicate), with every screen a sourced self-consistent filter, a re-deriving membership with no false negatives, and never an autonomous rejection (the 104th agent)

Shipped
Details

Added the one-hundred-and-fourth agent on the fabric — duplicate-claim-screen-agent, a DETERMINISTIC (no-Claude) payer-operations claims pre-screen agent on the PHI-bearing payer & plan operations plane, reusing the existing payer-operations tier as a SIBLING to the Claims Adjudication agent — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric, and CRUCIALLY the heart of the service is the BLOOM FILTER: a space-efficient PROBABILISTIC set-membership structure. It is NOT the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE (an EXACT two-roster diff — this is a probabilistic one-sided membership pre-screen with a tunable false-positive rate and NO per-key storage), NOT the Source Consensus agent's BOYER–MOORE MAJORITY VOTE, NOT the Timeline Merge agent's K-WAY MERGE, NOT the Audit Log Integrity agent's HASH CHAIN, NOT the Identifier Validation agent's MODULAR-ARITHMETIC CHECKSUM, and NOT the Code Taxonomy agent's TRIE LONGEST-PREFIX MATCH. In a new pure lib/duplicate-claim-screen.ts, evaluateDuplicateScreen(request) takes a set of already-PROCESSED claim ids and a batch of INCOMING claim ids plus a Bloom config (bit size m + hash count k), and DETERMINISTICALLY builds a Bloom filter over the processed ids (setting the k double-hashed bits per id, via a fixed seeded FNV-1a — no randomness) and screens each incoming id: all k bits set ⇒ POSSIBLY-DUPLICATE (route to the authoritative exact check), any bit clear ⇒ DEFINITELY-NEW (provably never processed — a Bloom filter has NO false negatives) — reporting the per-id verdicts, the possible-duplicate / definitely-new tallies, the bit array + set-bit count, and the estimated false-positive rate ((1 − e^(−k·n/m))^k), with disposition all-clear (none flagged) or possible-duplicates (some flagged). The one-sided guarantee (no false negatives) and the honest false-positive rate are the invariants this service reports and defends. It COMPLEMENTS, not duplicates, the Enrollment Reconciliation agent (an exact keyed set-difference): this is a fast probabilistic pre-filter run BEFORE the exact check. TIME IS DATA: the ids + config are plain data and the filter is a pure function of them (a fixed seeded hash, no clock), so the same request always yields the same determination. A screen — all-clear / possible-duplicates — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresAdjudicatorReview:true, autoRejected:false); a possible-duplicates disposition is a LEGITIMATE FINDING (some ids need the exact check) that ALWAYS defers to it, NOT a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.dupscreen.filter-sourced (signal dupScreenFilterSourced, violating value false) blocks a plan that isn't a real, self-consistent Bloom filter — the reported bit array must be the EXACT insert of the submitted processed ids with the submitted (m, k), the setBitCount honest, each result's id one of the submitted incoming ids (all covered, in order, none fabricated), each verdict consistent with the array (possibly-duplicate iff all k bits set), the tallies matching, and the disposition following — a fabricated bit, a mis-tallied count, or a contradicting verdict is a corrupted screen — the sourced + self-consistency gate (mirroring the Contact Rate Limit Agent's replay-sourced and the Referral Throughput Agent's flow-sourced) — backed by the pure guard filterSourced; policy.dupscreen.membership-exact (signal dupScreenMembershipExact, violating value false) blocks a mislabeled verdict — re-building the Bloom filter from the submitted processed ids + config and re-querying every incoming id must reproduce the reported verdict for each, and LOAD-BEARINGLY there must be NO FALSE NEGATIVE (any incoming id that IS one of the processed ids must be reported possibly-duplicate, never definitely-new — reporting a known duplicate as new would let a duplicate claim through, the one failure a Bloom filter must never make), and the false-positive-rate estimate must equal the standard formula — this is the load-bearing correctness gate, and it re-derives the membership INDEPENDENT of the reported bit array (so a fabricated array that still reports the right verdicts fails filter-sourced only, and a false negative fails membership-exact only — the two gates are isolable) (mirroring the Contact Rate Limit Agent's throttle-exact and the Referral Throughput Agent's throughput-optimal) — backed by the guard membershipExact; and policy.dupscreen.no-autonomous-reject (signal dupScreenNoAutonomousReject, violating value false) blocks a determination that autonomously rejected, denied, or paid a claim (autoRejected:true — each is an adjudication action that must be authorized) or did not require adjudicator review (requiresAdjudicatorReview:false) — the agent PRE-SCREENS on paper, a possibly-duplicate is a ROUTING SIGNAL to the exact check (never a denial), and every screen is a RECOMMENDATION requiring a claims adjudicator to confirm — backed by the guard noAutonomousReject (mirroring the Contact Rate Limit Agent's no-autonomous-send and the Referral Throughput Agent's no-autonomous-route; the harmful action is enforced-off). It IS PHI-adjacent — claim ids are PHI-adjacent — so it is on the HIPAA-audit policy (phiAccessed:true throughout) and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/duplicate-claim-screen/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — dupscreen.receive-batch → dupscreen.screen → dupscreen.classify-disposition → dupscreen.log-audit — with phiAccessed:true, returning the DuplicateScreenDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Duplicate-Claim Pre-Screen panel (a possible-duplicates preset over 6 processed + 5 incoming ids on a 64-bit / 3-hash filter → 3 possible-duplicate (all re-submissions caught, no false negatives) / 2 definitely-new; an all-clear preset where every incoming id is new; a deliberately-undersized (16-bit) filter preset illustrating the space/accuracy trade-off with a false positive routed safely to the exact check; plus fabricated-array / false-negative / auto-rejected governance-block presets), a seeded dupscreen.receive-batch→screen→classify-disposition→log-audit trace showing the possible-duplicates case (possibleDuplicateCount 3, requiresAdjudicatorReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'one hundred four agents', with the Duplicate-Claim Pre-Screen agent on the payer & plan operations plane alongside the Claims Adjudication agent) all reflect it. Menopause-relevant: a re-submitted HRT-titration or lab claim arriving in the same cycle as the original is exactly the duplicate this Bloom pre-screen flags for the exact check — fast, at scale, with no false negatives — without ever denying a claim on its own. Frontend tests green (+ duplicate-claim-screen buildBloomBits no-false-negative / determinism, estimateFalsePositiveRate formula, evaluate possible-duplicates / all-clear / saturated-false-positive / determinism, and three-guards-on-produced with fabricated-array + contradicting-verdict + false-negative + wrong-FP-rate + filter-sourced-vs-membership-exact-isolation + auto-rejected + skipped-review guard cases, the route's envelope / three governance blocks / possible-duplicates + all-clear + saturated happy paths with a PHI-adjacent trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to one hundred four agents); the ids are a clearly-labeled illustrative synthetic — NOT a certified claims-dedup / payment-integrity system (real duplicate-claim detection weighs the full claim key — member, provider, DOS, procedure, units — adjustment / void logic, and an authoritative claims store — not a bare Bloom pre-screen over illustrative ids). Lint + build clean.

9bc0e21 agent fabric: add the Duplicate-Claim Pre-Screen / Bloom-Filter Membership Test agent (104th) — deterministic Bloom filter that pre-screens incoming claim ids against processed ids, with every screen a sourced self-consistent filter, a re-deriving membership with no false negatives, and never an autonomous rejection

Agent Fabric: added the Member Contact Rate Limiting / Token-Bucket Throttle agent — deterministic token-bucket that replays a member's outbound contact attempts to permit or throttle each under a frequency cap, with every plan a sourced order-preserving replay, a re-simulating exact throttle, and never an autonomous send (the 103rd agent)

Shipped
Details

Added the one-hundred-and-third agent on the fabric — contact-rate-limit-agent, a DETERMINISTIC (no-Claude) care-coordination contact-governance agent on the PHI-adjacent patient/clinical plane, reusing the existing care-coordination tier as a SIBLING to the Outreach Prioritization, Referral Throughput, and Scheduling agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric, and CRUCIALLY the heart of the service is the TOKEN-BUCKET RATE-LIMITING algorithm: a bucket holds up to `capacity` tokens and refills continuously at `refillPerHour` tokens/hour (never above capacity); each attempt, processed in time order, first accrues the refill earned since the previous attempt, then — if at least one whole token is available — consumes one token and is PERMITTED, otherwise is THROTTLED. It is NOT the Outreach Prioritization agent's 0/1 KNAPSACK (which selects WHICH members to contact under a capacity budget — this governs HOW OFTEN one member may be contacted over time), NOT the Access Anomaly agent's SLIDING-WINDOW COUNTING (a fixed-window event count with no continuous refill or token reservoir), and NOT the SLA Worklist agent's EARLIEST-DEADLINE-FIRST SCHEDULING, the Referral Throughput agent's MAX-FLOW, the Network Build-Out agent's MINIMUM SPANNING TREE, the Care Routing agent's DIJKSTRA'S SHORTEST PATH, or the Schedule Conflict agent's GREEDY INTERVAL SELECTION. In a new pure lib/contact-rate-limit.ts, evaluateContactRateLimit(request) takes a chronologically-ordered sequence of outbound contact ATTEMPTS to a member (calls / texts / emails) and a token-bucket CONFIG (burst capacity + refill per hour), and DETERMINISTICALLY replays the attempts through the bucket to permit or throttle each — reporting the per-attempt decisions (with the token level seen just before each), the permitted / throttled tallies, the final token level, and the disposition: within-limits (none throttled) or throttled (some attempts exceeded the cap). The per-attempt decision is provably determined by the bucket state, and the exact throttle decision is the invariant this service reports and defends. It COMPLEMENTS, not duplicates, the Outreach Prioritization agent (which selects whom to reach): this caps how often one member may be reached. TIME IS DATA: the timestamps + config are plain numbers and the replay is a pure function of them (no real clock, no randomness), so the same request always yields the same determination. A throttle plan — within-limits / throttled — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresCoordinatorReview:true, autoSent:false); a throttled disposition is a LEGITIMATE FINDING (some attempts really exceed the cap), NOT a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.contactrate.replay-sourced (signal contactReplaySourced, violating value false) blocks a plan that isn't a real, self-consistent replay — the decisions must cover EXACTLY the submitted attempts (same ids, same timestamps, in non-decreasing time order — none dropped, added, reordered, or with a fabricated timestamp), the permitted / throttled tallies must match, attemptCount honest, and the disposition following — a fabricated attempt, a reordered replay, or a miscounted tally is a corrupted plan — the sourced + self-consistency gate (mirroring the Referral Throughput Agent's flow-sourced and the Batch Partition Agent's partition-sourced) — backed by the pure guard replaySourced; policy.contactrate.throttle-exact (signal contactThrottleExact, violating value false) blocks an over- or under-throttled decision — re-running the TOKEN-BUCKET simulation over the submitted attempts + config must reproduce the EXACT permit / throttle decision for every attempt and the final token level — this is the load-bearing correctness gate, and it re-simulates the bucket INDEPENDENT of the reported decisions (over-throttling denies a contact the bucket would allow; under-throttling permits a contact past the cap — over-contacting the member — so a fabricated replay that still reports the right tally fails sourced only, and a real-but-mis-simulated throttle fails exact only — the two gates are isolable) (mirroring the Referral Throughput Agent's throughput-optimal and the Care Routing Agent's route-optimal) — backed by the guard throttleExact; and policy.contactrate.no-autonomous-send (signal contactNoAutonomousSend, violating value false) blocks a determination that autonomously sent a permitted contact or suppressed a throttled one (autoSent:true — each is a member-communication action that must be authorized) or did not require coordinator review (requiresCoordinatorReview:false) — the agent PLANS on paper, and every plan is a RECOMMENDATION requiring an outreach coordinator to confirm — backed by the guard noAutonomousSend (mirroring the Referral Throughput Agent's no-autonomous-route and the Batch Partition Agent's no-autonomous-assign; the harmful action is enforced-off). It IS PHI-adjacent — the attempts reference member contacts — so it is on the HIPAA-audit policy (phiAccessed:true throughout) and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/contact-rate-limit/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — contactrate.receive-attempts → contactrate.throttle → contactrate.classify-disposition → contactrate.log-audit — with phiAccessed:true, returning the ContactRateLimitDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Contact Rate Limiting panel (a throttled preset over five attempts in 90 minutes against a capacity-3 bucket → 4 permitted / 1 throttled; a within-limits preset where hourly attempts match the refill; a dense capacity-1 burst → only the first permitted; plus reordered-replay / under-throttled / auto-sent governance-block presets), a seeded contactrate.receive-attempts→throttle→classify-disposition→log-audit trace showing the throttled case (permittedCount 4, requiresCoordinatorReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'one hundred three agents', with the Contact Rate Limiting agent on the care-coordination tier alongside the Outreach Prioritization agent) all reflect it. Menopause-relevant: a newly-enrolled member getting simultaneous nudges from the intake, care-gap, adherence, and education agents in the same afternoon is exactly the over-contact risk this token bucket caps — permitting a healthy cadence and throttling the rest — without ever sending a message on its own. Frontend tests green (+ contact-rate-limit simulateTokenBucket burst-refill / within / dense-burst / empty, evaluate throttled-within / sort-into-time-order / determinism, and three-guards-on-produced with reordered-replay + miscounted-tally + dropped-attempt + replay-sourced-vs-throttle-exact-isolation + under-throttled + mismatched-final-tokens + auto-sent + skipped-review guard cases, the route's envelope / three governance blocks / throttled + within + burst happy paths with a PHI-adjacent trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to one hundred three agents); the attempts are a clearly-labeled illustrative synthetic — NOT a certified communications-compliance system (real member-contact governance weighs TCPA / CAN-SPAM consent, quiet hours, channel-specific caps, member preferences, and campaign suppression lists — not a bare token bucket over illustrative timestamps). Lint + build clean.

b5c8751 agent fabric: add the Member Contact Rate Limiting / Token-Bucket Throttle agent (103rd) — deterministic token-bucket that replays a member's outbound contact attempts to permit or throttle each under a frequency cap, with every plan a sourced order-preserving replay, a re-simulating exact throttle, and never an autonomous send

Agent Fabric: added the Referral Throughput / Maximum-Flow Network Capacity (Edmonds–Karp) agent — deterministic max-flow / min-cut that computes the most referrals routable through a capacity network and names the bottleneck, with every plan a sourced conservation-consistent feasible flow, a recomputing maximum (max-flow = min-cut), and never an autonomous routing (the 102nd agent)

Shipped
Details

Added the one-hundred-and-second agent on the fabric — referral-throughput-agent, a DETERMINISTIC (no-Claude) care-coordination network-capacity agent on the PHI-adjacent patient/clinical plane, reusing the existing care-coordination tier as a SIBLING to the Network Build-Out, Care Routing, and Batch Partition agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric, and CRUCIALLY the heart of the service is MAXIMUM-FLOW / MINIMUM-CUT via EDMONDS–KARP (the BFS-augmenting-path refinement of FORD–FULKERSON): repeatedly find a shortest augmenting path from source to sink in the residual graph, push its bottleneck residual capacity, and update residual capacities (including back-edges) until no augmenting path remains; the total pushed is the maximum flow, and the source-reachable side of the final residual graph induces the minimum cut. It is NOT the Network Build-Out agent's MINIMUM SPANNING TREE (Kruskal's — connect all nodes at least cost; this pushes maximum flow through capacities), NOT the Care Routing agent's DIJKSTRA'S SHORTEST PATH (one cheapest path between two nodes; this saturates the whole network), and NOT the PCP Matching agent's GALE–SHAPLEY STABLE MATCHING, the Batch Partition agent's LINEAR PARTITION, the Outreach agent's 0/1 KNAPSACK, the Caseload Balancing agent's BIN-PACKING, the Household Composition agent's UNION-FIND, the SLA Worklist agent's EARLIEST-DEADLINE-FIRST SCHEDULING, or the Timeline Merge agent's K-WAY MERGE. In a new pure lib/referral-throughput.ts, evaluateReferralThroughput(request) takes a referral-routing NETWORK (a source feeding intake pools through capacity-limited specialty CHANNELS to a sink of appointment slots, each edge carrying a CAPACITY) and DETERMINISTICALLY computes the maximum flow (referrals routable end-to-end), reconstructs a feasible per-edge flow, and reads the min-cut off the final residual graph — reporting the flows, the max-flow value, the total demand (capacity leaving the source), the min-cut edges + capacity, and the disposition: unconstrained (throughput meets demand) or bottlenecked (a min-cut caps it below demand). By the max-flow min-cut theorem the maximum flow EQUALS the minimum cut capacity — the invariant this service reports and defends. It COMPLEMENTS, not duplicates, the sibling care-coordination agents: distinct from the Care Routing agent (cheapest single path) and the Network Build-Out agent (connect sites at least cost) — this pushes as much flow as possible through the capacities. TIME IS DATA: the capacities are plain numbers and the flow is a pure function of them (no real clock, no randomness — augmenting paths chosen by a deterministic BFS), so the same request always yields the same determination. A throughput plan — unconstrained / bottlenecked — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresCoordinatorReview:true, autoRouted:false); a bottlenecked disposition is a LEGITIMATE FINDING (a min-cut really caps throughput below demand), NOT a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.referralflow.flow-sourced (signal referralFlowSourced, violating value false) blocks a plan that isn't a real, feasible flow — every edge's flow must be between 0 and its SUBMITTED capacity (no fabricated edge, no over-capacity flow), flow CONSERVED at every non-source/sink node (in === out), the reported maxFlow the net out of source AND net into sink, nodeCount and edgeCount honest — a fabricated edge, an over-capacity flow, or a conservation violation is a corrupted plan — the sourced + self-consistency gate (mirroring the Network Build-Out Agent's tree-sourced and the Batch Partition Agent's partition-sourced) — backed by the pure guard flowSourced; policy.referralflow.throughput-optimal (signal referralThroughputOptimal, violating value false) blocks a sub-maximal or overstated throughput — re-running EDMONDS–KARP over the submitted network must reproduce the reported maxFlow, with the min-cut capacity equal to it — this is the load-bearing correctness gate, and it recomputes the maximum flow + min-cut INDEPENDENT of the reported per-edge flows (it compares the scalar optimum, not the assignment — different maximum flows achieve the same value — so a fabricated flow that still reports the optimal value fails sourced only, and a real-but-sub-maximal flow fails optimal only — the two gates are isolable) (mirroring the Network Build-Out Agent's cost-optimal and the Care Routing Agent's route-optimal) — backed by the guard throughputOptimal; and policy.referralflow.no-autonomous-route (signal referralNoAutonomousRoute, violating value false) blocks a determination that autonomously booked, dispatched, or routed a referral (autoRouted:true — each is a scheduling action that must be authorized) or did not require coordinator review (requiresCoordinatorReview:false) — the agent PLANS on paper, and every plan is a RECOMMENDATION requiring a referral coordinator to confirm — backed by the guard noAutonomousRoute (mirroring the Network Build-Out Agent's no-autonomous-provision and the Batch Partition Agent's no-autonomous-assign; the harmful action is enforced-off). It IS PHI-adjacent — the node labels reference intake pools / specialties / slots — so it is on the HIPAA-audit policy (phiAccessed:true throughout) and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/referral-throughput/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — referralflow.receive-network → referralflow.solve-maxflow → referralflow.classify-disposition → referralflow.log-audit — with phiAccessed:true, returning the ReferralThroughputDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Referral Throughput panel (a bottlenecked preset over a six-node menopause-clinic network → throughput 8 of 12 demanded, min-cut on the two specialty→slot edges; an unconstrained preset where throughput 3 meets demand 3; a diamond preset exercising residual back-edge cancellation → 3 of 4; plus over-capacity / sub-maximal / auto-routed governance-block presets), a seeded referralflow.receive-network→solve-maxflow→classify-disposition→log-audit trace showing the bottlenecked case (maxFlow 8, requiresCoordinatorReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'one hundred two agents', with the Referral Throughput agent on the care-coordination tier alongside the Care Routing and Network Build-Out agents) all reflect it. Menopause-relevant: sizing a menopause-clinic referral network — how many intake referrals can actually reach a gyn or endo appointment slot given each channel's weekly capacity, and which saturated edge to add capacity to — is exactly the max-flow / min-cut question this agent answers, without ever booking a referral on its own. Frontend tests green (+ referral-throughput maxFlowValue / minCut / reconstructFlows / evaluate bottlenecked-unconstrained-diamond / determinism / source-equals-sink, and three-guards-on-produced with over-capacity + conservation-violation + flow-sourced-vs-throughput-optimal-isolation + sub-maximal + overstated + auto-routed + skipped-review guard cases, the route's envelope / three governance blocks / bottlenecked + unconstrained + diamond happy paths with a PHI-adjacent trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to one hundred two agents); the capacities are a clearly-labeled illustrative synthetic — NOT a certified capacity-planning / scheduling system (real referral capacity planning weighs clinical urgency, specialty match, geography, payer networks, and provider preference — not a bare max-flow over illustrative capacities). Lint + build clean.

45a78dd agent fabric: add the Referral Throughput / Maximum-Flow Network Capacity (Edmonds–Karp) agent (102nd) — deterministic max-flow / min-cut that computes the most referrals routable through a capacity network and names the bottleneck, with every plan a sourced conservation-consistent feasible flow, a recomputing maximum, and never an autonomous routing

Agent Fabric: added the Provider Network Build-Out / Minimum Spanning Tree (Kruskal's Algorithm) agent — deterministic minimum spanning tree that connects a set of care sites into one network at minimum total build cost, with every plan sourced + self-consistent (a real acyclic subset of the candidate links), a recomputing minimal-cost optimum, and never an autonomous provisioning (the 101st agent)

Shipped
Details

Added the one-hundred-and-first agent on the fabric — network-buildout-agent, a DETERMINISTIC (no-Claude) care-coordination network-planning agent on the PHI-adjacent patient/clinical plane, reusing the existing care-coordination tier as a SIBLING to the Caseload Balancing, Batch Partition, SLA Worklist, and List Reconciliation agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric, and CRUCIALLY the heart of the service is MINIMUM SPANNING TREE construction via KRUSKAL'S ALGORITHM: sort the candidate links by ascending cost, then walk them cheapest-first, adding a link IFF it JOINS TWO DISTINCT COMPONENTS (a union-find cycle check rejects a link whose endpoints are already connected). Union-find here is a SUBROUTINE — the cycle test inside the greedy edge selection — NOT the computation itself: this is emphatically NOT the Household Composition agent's UNION-FIND CONNECTED-COMPONENT LABELING (which groups records into families by transitively merging match edges — NO edge weights, chooses NO minimum-cost subset, reports components not a tree). It is also DIFFERENT from the Care Routing agent's DIJKSTRA'S SHORTEST PATH (which minimizes the cost of ONE path between TWO nodes; MST minimizes the total cost to connect ALL nodes), the Batch Partition agent's LINEAR PARTITION, the Care Pathway agent's TOPOLOGICAL ORDERING, the Outreach agent's 0/1 KNAPSACK, the PCP Matching agent's GALE–SHAPLEY STABLE MATCHING, the SLA Worklist agent's EARLIEST-DEADLINE-FIRST SCHEDULING, the Huffman agent's OPTIMAL PREFIX CODING, the List Reconciliation agent's LONGEST COMMON SUBSEQUENCE, the Timeline Merge agent's K-WAY MERGE, and the Peak-Window agent's KADANE MAXIMUM-SUBARRAY. In a new pure lib/network-buildout.ts, evaluateNetworkBuildout(request) takes a set of care SITES (clinics / facilities / exchange endpoints) and candidate LINKS between them — each carrying a build COST — and DETERMINISTICALLY selects the MINIMUM-TOTAL-COST set of links that connects every site into ONE network, or reports a spanning FOREST when the candidate links cannot connect everything — reporting the chosen links, the minimum total build cost, the connected-component count, and the disposition: connected (componentCount === 1) or partitioned (more than one component remains). Kruskal's tree is provably optimal — no spanning tree of the candidate links has a smaller total cost — and the minimum total build cost is the invariant this service reports and defends. It COMPLEMENTS, not duplicates, the sibling care-coordination agents: distinct from the Care Routing agent (which finds the cheapest single path between two nodes) — this finds the cheapest way to connect ALL the sites. TIME IS DATA: the costs are plain numbers and the tree is a pure function of them (no real clock, no randomness — ties broken by a stable link ordering), so the same request always yields the same determination. A build plan — connected / partitioned — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresArchitectReview:true, autoProvisioned:false); a partitioned disposition is a LEGITIMATE FINDING (the candidate links really can't connect every site), NOT a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.netbuildout.tree-sourced (signal networkTreeSourced, violating value false) blocks a plan that isn't a real, self-consistent accounting of the submitted candidates — each chosen link must be a SUBMITTED candidate (same endpoints, same cost — no fabricated link, no altered cost), the chosen links must form a FOREST (no cycle, verified by a union-find pass over the chosen links), the reported totalCost equal to the sum of the chosen links' costs, the reported componentCount equal to the components the chosen links induce over the sites, siteCount and linkCount honest, and the disposition following — a fabricated link, an altered cost, or a cycle is a corrupted plan — the sourced + self-consistency gate (mirroring the Batch Partition Agent's partition-sourced and the Huffman Agent's code-sourced) — backed by the pure guard treeSourced; policy.netbuildout.cost-optimal (signal networkTreeCostOptimal, violating value false) blocks a sub-optimal tree that wastes build budget — re-running the KRUSKAL solver over the submitted sites + links must reproduce the reported totalCost (and disposition) — this is the load-bearing correctness gate, and it recomputes the minimum total cost from the sites + links INDEPENDENT of the reported tree (it compares the scalar optimum, not the tree — different minimum spanning trees can tie on cost — so a fabricated tree that still reports the optimal total cost fails sourced only, and a real-but-sub-optimal tree fails optimal only — the two gates are isolable) (mirroring the Batch Partition Agent's load-optimal and the Care Routing Agent's route-optimal) — backed by the guard treeOptimal; and policy.netbuildout.no-autonomous-provision (signal networkNoAutonomousProvision, violating value false) blocks a determination that autonomously provisioned, activated, or ordered a link (autoProvisioned:true — each is an infrastructure change that must be authorized) or did not require architect review (requiresArchitectReview:false) — the agent PLANS on paper, and every build plan is a RECOMMENDATION requiring a network architect to confirm — backed by the guard noAutonomousProvision (mirroring the Batch Partition Agent's no-autonomous-assign and the Huffman Agent's no-autonomous-deploy; the harmful action is enforced-off). It IS PHI-adjacent — the site labels reference clinics / facilities — so it is on the HIPAA-audit policy (phiAccessed:true throughout) and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/network-buildout/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — netbuildout.receive-network → netbuildout.build → netbuildout.classify-disposition → netbuildout.log-audit — with phiAccessed:true, returning the NetworkBuildoutDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Network Build-Out panel (a connected preset over five care sites + seven candidate links → minimum total build cost 18 across four links; a partitioned preset where a detached annex leaves two components; a triangle preset where the priciest link closes a cycle and is dropped → cost 3 not 10; plus fabricated-link / sub-optimal / auto-provisioned governance-block presets), a seeded netbuildout.receive-network→build→classify-disposition→log-audit trace showing the connected case (totalCost 18, requiresArchitectReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'one hundred one agents', with the Network Build-Out agent on the care-coordination tier alongside the Care Routing agent) all reflect it. Menopause-relevant: standing up a connected menopause-care network — linking a hub clinic, satellite offices, a lab, and a telehealth endpoint at the least total integration cost so records and referrals flow across all of them — is exactly the connect-everything-cheaply problem this minimum spanning tree solves, without ever provisioning a link on its own. Frontend tests green (+ network-buildout kruskalMST / cycle-drop / spanning-forest / unknown-site-and-self-loop / empty, connected / partitioned / triangle / determinism, and three-guards-on-produced with fabricated-link + dishonest-cost + cycle + tree-sourced-vs-cost-optimal-isolation + sub-optimal + auto-provisioned + skipped-review guard cases, the route's envelope / three governance blocks / connected + partitioned + triangle happy paths with a PHI-adjacent trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to one hundred one agents); the costs are a clearly-labeled illustrative synthetic — NOT a certified network-design system (real provider-network design weighs adequacy standards, contracted rates, capacity, redundancy, and regulatory requirements — not a bare minimum spanning tree over illustrative costs). Lint + build clean.

b6b9336 agent fabric: add the Provider Network Build-Out / Minimum Spanning Tree (Kruskal's Algorithm) agent (101st) — deterministic minimum spanning tree that connects a set of care sites into one network at minimum total build cost, with every plan sourced + self-consistent, a recomputing minimal-cost optimum, and never an autonomous provisioning

Agent Fabric: added the Chart Review Batch Partitioning / Linear Partition (Binary-Search-on-Answer) agent — deterministic linear partition that splits a priority-ordered clinical review worklist into k contiguous batches minimizing the busiest reviewer's load, with every partition sourced + self-consistent (a real order-preserving cover), a recomputing minimal-peak-load optimum, and never an autonomous reviewer assignment (the 100th agent)

Shipped
Details

Added the one-hundredth agent on the fabric — batch-partition-agent, a DETERMINISTIC (no-Claude) care-coordination workload-partitioning agent on the PHI-adjacent patient/clinical plane, reusing the existing care-coordination tier as a SIBLING to the Caseload Balancing, SLA Worklist, List Reconciliation, and Peak-Window agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric, and CRUCIALLY it is NOT the Caseload Balancing agent's WORST-FIT-DECREASING BIN-PACKING (which reorders members by descending acuity and greedily drops each into the emptiest bin — an UNORDERED heuristic assignment) and NOT the Peak-Window agent's KADANE MAXIMUM-SUBARRAY (which finds one best contiguous window, not a k-way split); it is also NOT the Huffman agent's OPTIMAL PREFIX CODING, the List Reconciliation agent's LONGEST COMMON SUBSEQUENCE, the SLA Worklist agent's EARLIEST-DEADLINE-FIRST SCHEDULING, the Care Routing agent's DIJKSTRA'S SHORTEST PATH, the Outreach agent's 0/1 KNAPSACK, the PCP Matching agent's GALE–SHAPLEY STABLE MATCHING, the Scheduling agent's INTERVAL SELECTION, or the Household Composition agent's UNION-FIND: the heart of the service is the LINEAR PARTITION PROBLEM solved by BINARY SEARCH ON THE ANSWER. In a new pure lib/batch-partition.ts, evaluateBatchPartition(request) takes a CHRONOLOGICALLY / PRIORITY-ORDERED clinical review worklist — each item carrying an effort WEIGHT (estimated review minutes / complexity points) — and a reviewer count k, and DETERMINISTICALLY splits it into k CONTIGUOUS batches (order preserved: no item jumps its neighbours) that MINIMIZE the busiest reviewer's load (the maximum batch weight): the minimal feasible peak load lies between the single heaviest item and the total weight; a greedy feasibility test (how many contiguous batches does a candidate cap require?) is monotonic in the cap, so binary search converges on the exact minimal maximum, and an order-preserving DP reconstructs the split — reporting the batch boundaries, each batch load, the minimal achievable peak load (maxBatchLoad), the heaviest single item, the total weight, and the disposition: divisible (the peak exceeds every single item) or item-bound (one dominant item sets the peak — more reviewers cannot lower it). The linear partition minimum is provably optimal — no contiguous k-way split achieves a smaller maximum — and the minimal peak load is the invariant this service reports and defends. Order matters — the split is CONTIGUOUS — which is exactly what unordered bin-packing throws away. It COMPLEMENTS, not duplicates, the sibling care-coordination agents: distinct from the Caseload Balancing agent (which greedily bin-packs unordered members into capacity-bounded panels) — this splits an ORDERED worklist into contiguous batches, provably minimizing the peak. TIME IS DATA: the weights are plain numbers and the partition is a pure function of them (no real clock, no randomness), so the same request always yields the same determination. A partition — divisible / item-bound — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresSupervisorReview:true, autoAssigned:false), which is how a legitimate partition is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.batchpartition.partition-sourced (signal batchPartitionSourced, violating value false) blocks a partition that isn't a real, self-consistent accounting of the submitted worklist — the batches, concatenated IN ORDER, must reproduce EXACTLY the submitted items (same labels, same weights, same sequence — no item dropped, added, reordered, or split across batches), there must be exactly batchCount NON-EMPTY contiguous batches, each batch's load equal to the sum of its items' weights, the reported maxBatchLoad the largest batch load, maxItemWeight and totalWeight honest, and the disposition following — a fabricated batch, a reordered cover, or an overstated load is a corrupted partition — the sourced + self-consistency gate (mirroring the Huffman Agent's code-sourced and the List Reconciliation Agent's diff-sourced) — backed by the pure guard partitionSourced; policy.batchpartition.load-optimal (signal batchPartitionLoadOptimal, violating value false) blocks a sub-optimal split that overloads one reviewer — re-running the LINEAR-PARTITION solver (binary search on the answer) over the submitted weights + batchCount must reproduce the reported maxBatchLoad (and disposition) — this is the load-bearing correctness gate, and it recomputes the minimal peak load from the weights INDEPENDENT of the reported batches (it compares the scalar optimum, not the cover — different optimal splits achieve the same minimal maximum — so a fabricated cover that still reports the optimal peak load fails sourced only, and a real-but-sub-optimal split fails optimal only — the two gates are isolable) (mirroring the Huffman Agent's code-optimal and the Care Routing Agent's route-optimal) — backed by the guard partitionOptimal; and policy.batchpartition.no-autonomous-assign (signal batchPartitionNoAutonomousAssign, violating value false) blocks a determination that autonomously assigned a named reviewer to a batch or dispatched the worklist (autoAssigned:true — each is a staffing action that must be authorized) or did not require supervisor review (requiresSupervisorReview:false) — the agent PARTITIONS on paper, and every partition is a RECOMMENDATION requiring a supervisor to confirm — backed by the guard noAutonomousAssign (mirroring the Huffman Agent's no-autonomous-deploy and the SLA Worklist Agent's no-autonomous-dispatch; the harmful action is enforced-off). It IS PHI-adjacent — the item labels reference charts / encounters — so it is on the HIPAA-audit policy (phiAccessed:true throughout) and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/batch-partition/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — batchpartition.receive-worklist → batchpartition.partition → batchpartition.classify-disposition → batchpartition.log-audit — with phiAccessed:true, returning the BatchPartitionDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Batch Partition panel (a divisible preset over a six-chart backlog split across three reviewers → minimal peak load 10, total 24; an item-bound preset where one 20-point chart sets the floor; an even preset with four equal-weight encounters split into two perfectly-balanced batches of 8; plus reordered-cover / sub-optimal / auto-assigned governance-block presets), a seeded batchpartition.receive-worklist→partition→classify-disposition→log-audit trace showing the divisible case (maxBatchLoad 10, requiresSupervisorReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'one hundred agents', with the Batch Partition agent on the care-coordination tier alongside the Caseload Balancing agent) all reflect it. Menopause-relevant: a menopause-clinic chart-review backlog — annual visit notes, HRT titration reviews, lab-result reconciliations — priority-ordered and split evenly across the reviewing clinicians so no one reviewer is overloaded, is exactly the ordered worklist this linear partition balances, without ever assigning a named reviewer on its own. Frontend tests green (+ batch-partition optimalMaxLoad / partitionItems / evaluate divisible-item-bound-even / determinism, and three-guards-on-produced with reordered-cover + dishonest-load + dropped-item + partition-sourced-vs-load-optimal-isolation + sub-optimal + auto-assigned + skipped-review guard cases, the route's envelope / three governance blocks / divisible + item-bound + even happy paths with a PHI-adjacent trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to one hundred agents); the weights are a clearly-labeled illustrative synthetic — NOT a certified staffing / workforce-management system (real reviewer scheduling weighs skills, certifications, shift rules, breaks, and fatigue — not a bare contiguous split by an effort number). Lint + build clean.

e7152f7 agent fabric: add the Chart Review Batch Partitioning / Linear Partition (Binary-Search-on-Answer) agent (100th) — deterministic linear partition that splits an ordered clinical review worklist into k contiguous batches minimizing the busiest reviewer's load, with every partition sourced + self-consistent, a recomputing minimal-peak-load optimum, and never an autonomous reviewer assignment

Agent Fabric: added the Event-Stream Code Assignment / Huffman Optimal Prefix Coding agent — deterministic Huffman coding that assigns an optimal prefix-free binary code to a stream of event types by frequency (minimizing the total encoded length), with every code sourced + self-consistent (a real, uniquely-decodable prefix code), a recomputing Huffman optimum, and never an autonomous codec deploy (the 99th agent)

Shipped
Details

Added the ninety-ninth agent on the fabric — huffman-coding-agent, a DETERMINISTIC (no-Claude) platform / data-plane code-assignment agent on the NON-PHI platform & data-substrate plane, reusing the existing data-plane tier as a SIBLING to the Code Taxonomy, Identifier Validation, Source Consensus, and Timeline Merge agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric, and CRUCIALLY it is NOT the Code Taxonomy agent's TRIE LONGEST-PREFIX MATCH (which walks a code down a prefix tree of taxonomy categories to bucket it — a lookup, not a code construction) and NOT the Identifier Validation agent's MODULAR-ARITHMETIC CHECKSUM; it is also NOT the Source Consensus agent's BOYER–MOORE MAJORITY VOTE, the Timeline Merge agent's K-WAY MERGE, the List Reconciliation agent's LONGEST COMMON SUBSEQUENCE, the SLA Worklist agent's EARLIEST-DEADLINE-FIRST SCHEDULING, the Peak-Window agent's KADANE MAXIMUM-SUBARRAY, the Care Routing agent's DIJKSTRA'S SHORTEST PATH, the Outreach agent's 0/1 KNAPSACK, the PCP Matching agent's GALE–SHAPLEY STABLE MATCHING, the Household Composition agent's UNION-FIND, the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS, or the MLR Rebate agent's LARGEST-REMAINDER APPORTIONMENT: the heart of the service is HUFFMAN CODING. In a new pure lib/huffman-coding.ts, evaluateHuffman(request) takes a set of event / message TYPES flowing across the integration bus — each type with an observed FREQUENCY (its share of the stream volume) — and DETERMINISTICALLY builds the optimal prefix-free code by repeatedly merging the two lowest-frequency nodes into a subtree (a greedy priority-queue construction, tie-broken by a stable creation-order counter), then reads each symbol's code off the root-to-leaf path — reporting one code per type, the weighted total encoded length (the sum over types of frequency × code length), the fixed-width baseline (ceil(log2(n)) bits per symbol × total frequency), and the disposition: compressible (the Huffman total beats the fixed-width baseline) or already-uniform (equal — a uniform distribution gains nothing). Huffman is provably optimal — no prefix-free code assigns a smaller total encoded length — and the total encoded length is the invariant this service reports and defends. It COMPLEMENTS, not duplicates, the sibling data-plane agents: distinct from the Code Taxonomy agent (which walks a code down a prefix tree of taxonomy categories to bucket it) and the Identifier Validation agent (which validates an identifier's check digit) — this CONSTRUCTS an optimal prefix-free code from frequencies. TIME IS DATA: the frequencies are plain numbers and the coding is a pure function of them (no real clock, no randomness), so the same request always yields the same determination. A code assignment — compressible / already-uniform — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresEngineerReview:true, autoDeployed:false), which is how a legitimate code is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.huffcode.code-sourced (signal huffCodeSourced, violating value false) blocks a code that isn't a real, self-consistent accounting of the submitted symbols — the reported codes must cover EXACTLY the submitted symbols (each once — no fabricated symbol, none dropped or double-coded), each code a non-empty binary string whose reported length matches, each frequency echoed, the code PREFIX-FREE (no code a prefix of another — the property that makes it uniquely decodable), the reported weightedTotal equal to Σ frequency × length, the fixed-width baseline computed honestly, and the disposition following — a fabricated symbol, a non-prefix-free code, or an overstated total is a corrupted assignment — the sourced + self-consistency gate (mirroring the List Reconciliation Agent's diff-sourced and the SLA Worklist Agent's schedule-sourced) — backed by the pure guard codeSourced; policy.huffcode.code-optimal (signal huffCodeOptimal, violating value false) blocks a sub-optimal prefix code that wastes bandwidth — re-running the HUFFMAN construction over the submitted frequencies must reproduce the reported weightedTotal (and disposition) — this is the load-bearing correctness gate, and it recomputes the minimal total encoded length from the frequencies INDEPENDENT of the reported codes (it compares the scalar optimum, not the code strings — different optimal trees achieve the same optimal length — so a fabricated non-prefix-free code that still reports the optimal length fails sourced only, and a real-but-sub-optimal code, e.g. a fixed-width code, fails optimal only — the two gates are isolable) (mirroring the List Reconciliation Agent's lcs-optimal and the Care Routing Agent's route-optimal) — backed by the guard codeOptimal; and policy.huffcode.no-autonomous-deploy (signal huffCodeNoAutonomousDeploy, violating value false) blocks a determination that autonomously deployed the codec to the live integration bus or re-encoded the production stream (autoDeployed:true — each is an infrastructure change that must be authorized) or did not require engineer review (requiresEngineerReview:false) — the agent ASSIGNS on paper, and every assignment is a RECOMMENDATION requiring an integration engineer to confirm — backed by the guard noAutonomousDeploy (mirroring the List Reconciliation Agent's no-autonomous-update and the SLA Worklist Agent's no-autonomous-dispatch; the harmful action is enforced-off). It operates ONLY on the platform / data-substrate plane — DELIBERATELY NOT PHI-bearing (phiAccessed:false throughout — an event-type frequency is aggregate integration telemetry, not patient health information), NOT on the HIPAA-audit policy, and NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/huffman-coding/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — huffcode.receive-symbols → huffcode.build-code → huffcode.classify-disposition → huffcode.log-audit — with phiAccessed:false, returning the HuffmanDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Huffman Coding panel (a compressible preset over five RPM device event types → 178 bits vs 300 fixed-width, 122 saved, the frequent 'heartbeat' getting a one-bit code; an already-uniform preset where four equally-frequent types match the 2-bit fixed-width code; a heavily-skewed ack/nack preset → 130 bits vs 200; plus non-prefix-free / sub-optimal / auto-deployed governance-block presets), a seeded huffcode.receive-symbols→build-code→classify-disposition→log-audit trace showing the compressible case (weightedTotal 178, requiresEngineerReview:true, phiAccessed:false), the console subtitle, and the investor brief (now 'ninety-nine agents', with the Huffman Coding agent on the data-plane tier alongside the Code Taxonomy agent) all reflect it. Menopause-relevant: a Pause remote-patient-monitoring device stream — heartbeat, normal readings, high readings, battery-low, sync-error — is exactly the skewed event stream this Huffman coder assigns compact codes to for efficient transmission across the integration bus, without ever deploying the codec on its own. Frontend tests green (4,188 tests — + huffman-coding Huffman-tree / single-symbol-one-bit / empty / fixed-width-baseline / optimal-length, compressible / already-uniform / heavily-skewed / determinism, and three-guards-on-produced with non-prefix-free + fabricated-symbol + overstated-total + code-sourced-vs-code-optimal-isolation + sub-optimal-fixed-width + auto-deployed + skipped-review guard cases, the route's envelope / three governance blocks / compressible + uniform + skewed happy paths with a non-PHI trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to ninety-nine agents); the frequencies are a clearly-labeled illustrative synthetic — NOT a certified codec / compression system (real stream compression uses context modeling, arithmetic / range coding, dictionary methods (LZ77 / LZMA), and adaptive codebooks). Lint + build clean.

8aaf52f agent fabric: add the Event-Stream Code Assignment / Huffman Optimal Prefix Coding agent (99th) — deterministic Huffman coding that assigns an optimal prefix-free code to an event stream by frequency, with every code sourced + self-consistent, a recomputing Huffman optimum, and never an autonomous codec deploy

Agent Fabric: added the Clinical List Reconciliation / Longest-Common-Subsequence (LCS) Diff agent — deterministic LCS reconciliation that diffs two ordered clinical lists (a prior list vs the current list), finds the items preserved in both (retained), and derives the added + removed items (lists-match / changes-present), with every diff sourced + self-consistent, a recomputing LCS optimum, and never an autonomous chart write (the 98th agent)

Shipped
Details

Added the ninety-eighth agent on the fabric — list-reconciliation-agent, a DETERMINISTIC (no-Claude) care-coordination reconciliation agent on the PHI-bearing patient/clinical plane, reusing the existing care-coordination tier as a SIBLING to the Medication Name Safety, Care Pathway, Transitions of Care, Care Routing, and Timeline Merge agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric, and CRUCIALLY it is NOT the Medication Name Safety agent's LEVENSHTEIN EDIT DISTANCE (which measures CHARACTER-level edit distance between two drug-name STRINGS to catch look-alike/sound-alike confusability) and NOT the Enrollment Reconciliation agent's KEYED SET RECONCILIATION (which joins two record sets on a key to find adds/drops/mismatches, order-independent); it is also NOT the Timeline Merge agent's K-WAY MERGE, the SLA Worklist agent's EARLIEST-DEADLINE-FIRST SCHEDULING, the Peak-Window agent's KADANE MAXIMUM-SUBARRAY, the Care Routing agent's DIJKSTRA'S SHORTEST PATH, the Outreach agent's 0/1 KNAPSACK, the Source Consensus agent's BOYER–MOORE MAJORITY VOTE, the Code Taxonomy agent's TRIE LONGEST-PREFIX MATCH, the Household Composition agent's UNION-FIND, the Care Pathway agent's TOPOLOGICAL ORDERING, or the Identifier Validation agent's MODULAR-ARITHMETIC CHECKSUM: the heart of the service is the LONGEST COMMON SUBSEQUENCE. In a new pure lib/list-reconciliation.ts, evaluateListReconciliation(request) takes TWO ordered clinical lists for one record — a PRIOR list (the medication list at admission, the problem list at last visit, the care-plan steps as last agreed) and a CURRENT list (the same list now) — and DETERMINISTICALLY runs a dynamic-programming table over the two ORDERED lists to find the longest subsequence common to both (the items kept, in their shared order — the RETAINED items), then complements it in each list to derive what was REMOVED (prior only) and ADDED (current only), reporting the retained / added / removed items, the LCS length, and the disposition: lists-match or changes-present. Order matters — LCS respects the sequence — which is exactly what set reconciliation throws away. It COMPLEMENTS, not duplicates, the sibling agents: distinct from the Medication Name Safety agent (which measures character-level edit distance between two drug-name strings) and the Enrollment Reconciliation agent (which joins two record sets on a key, order-independent) — this DIFFS two ORDERED lists respecting sequence. TIME IS DATA: the two lists are plain ordered tokens and the diff is a pure function of them (no real clock, no randomness), so the same request always yields the same determination. A reconciliation — lists-match / changes-present — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresClinicianReview:true, autoApplied:false), which is how a legitimate diff is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.listdiff.diff-sourced (signal listDiffSourced, violating value false) blocks a diff that isn't a real, self-consistent accounting of the two submitted lists — the reported RETAINED list must be a genuine COMMON SUBSEQUENCE of both lists (it appears in order within prior AND within current — nothing fabricated, nothing reordered), the REMOVED list must equal exactly the prior items left unmatched (in order), the ADDED list must equal exactly the current items left unmatched (in order), the reported lcsLength must match the retained length, and the disposition must follow — a fabricated / reordered retained item or a mis-stated add/remove is a corrupted diff — the sourced + self-consistency gate (mirroring the SLA Worklist Agent's schedule-sourced and the Peak-Window Agent's window-sourced) — backed by the pure guard diffSourced; policy.listdiff.lcs-optimal (signal listDiffLcsOptimal, violating value false) blocks a shorter-than-optimal common subsequence that over-reports change — re-running the LCS dynamic program over the two submitted lists must reproduce the reported lcsLength (and disposition) — this is the load-bearing correctness gate, and it recomputes the LCS length from the two lists INDEPENDENT of the reported retained subsequence (it compares the scalar optimum, not the reported items, so a fabricated retained list that still reports the optimal length fails sourced only, and a real-but-sub-optimal subsequence fails optimal only — the two gates are isolable) (mirroring the SLA Worklist Agent's edf-ordered and the Care Routing Agent's route-optimal) — backed by the guard diffOptimal; and policy.listdiff.no-autonomous-update (signal listDiffNoAutonomousUpdate, violating value false) blocks a determination that autonomously wrote the reconciled list back, updated the chart, or started/stopped a medication (autoApplied:true — each is a clinical write that must be authorized) or did not require clinician review (requiresClinicianReview:false) — the agent RECONCILES on paper, and every reconciliation is a RECOMMENDATION requiring a clinician to confirm — backed by the guard noAutonomousUpdate (mirroring the SLA Worklist Agent's no-autonomous-dispatch and the Resource Scheduling Agent's no-autonomous-booking; the harmful action is enforced-off). It IS PHI-bearing — the lists are one patient's clinical record — so it is on the HIPAA-audit policy (phiAccessed:true throughout) and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/list-reconciliation/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — listdiff.receive-lists → listdiff.diff-lcs → listdiff.classify-disposition → listdiff.log-audit — with phiAccessed:true, returning the ListReconciliationDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new List Reconciliation panel (a medication-list preset where admission→discharge retains metformin → atorvastatin → aspirin, removes lisinopril, and adds estradiol; a lists-match preset; a problem-list preset with several changes; plus fabricated-retained / sub-optimal / auto-applied governance-block presets), a seeded listdiff.receive-lists→diff-lcs→classify-disposition→log-audit trace showing the changes-present case (LCS length 3, requiresClinicianReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'ninety-eight agents', with the List Reconciliation agent on the care-coordination tier alongside the Medication Name Safety and Timeline Merge agents) all reflect it. Menopause-relevant: reconciling a menopause patient's medication list between admission and discharge — surfacing that lisinopril was stopped and estradiol started while metformin, atorvastatin, and aspirin were preserved — is exactly the retained/added/removed diff this LCS reconciler produces for a clinician to confirm, without ever writing the chart on its own. Frontend tests green (4,149 tests — + list-reconciliation LCS / lcsLength / identical-lists / no-common-item / empty, changed-medication-list / lists-match / problem-list / determinism, and three-guards-on-produced with fabricated-reordered-retained + mis-stated-add-remove + lcsLength-mismatch + diff-sourced-vs-lcs-optimal-isolation + sub-optimal + auto-applied + skipped-review guard cases, the route's envelope / three governance blocks / changed + lists-match + problem-list happy paths with a PHI trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to ninety-eight agents); the lists are a clearly-labeled illustrative synthetic — NOT a certified medication-reconciliation system (real medication / problem-list reconciliation normalizes to RxNorm / SNOMED and accounts for dose, route, frequency, therapeutic equivalence, and clinical intent). Lint + build clean.

96eecd8 agent fabric: add the Clinical List Reconciliation / Longest-Common-Subsequence (LCS) Diff agent (98th) — deterministic LCS reconciliation that diffs two ordered clinical lists into retained / added / removed, with every diff sourced + self-consistent, a recomputing LCS optimum, and never an autonomous chart write

Agent Fabric: added the SLA Worklist Sequencing / Earliest-Deadline-First (EDF) Scheduling agent — deterministic EDF scheduling that orders a worklist of pending cases by SLA deadline, computes each case's cumulative completion time, and flags the SLA breaches (all-on-time / breaches-present), with every schedule sourced + self-consistent, a recomputing EDF order, and never an autonomous dispatch (the 97th agent)

Shipped
Details

Added the ninety-seventh agent on the fabric — sla-worklist-agent, a DETERMINISTIC (no-Claude) payer-operations work-sequencing agent on the PHI-bearing payer & plan-operations plane, reusing the existing payer-operations tier as a SIBLING to the Claims Adjudication, Utilization Review, Coordination of Benefits, FWA Detection, and Formulary agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric, and CRUCIALLY it is NOT the Resource Scheduling agent's WEIGHTED INTERVAL SCHEDULING (which SELECTS a max-weight non-overlapping SUBSET of time-windowed requests for one resource — a subset, with dropped requests) and NOT the Scheduling Conflict agent's GREEDY INTERVAL SELECTION (which admits the max COUNT of non-overlapping appointments); it is also NOT the Peak-Window agent's KADANE MAXIMUM-SUBARRAY, the Care Routing agent's DIJKSTRA'S SHORTEST PATH, the Outreach agent's 0/1 KNAPSACK, the Source Consensus agent's BOYER–MOORE MAJORITY VOTE, the Code Taxonomy agent's TRIE LONGEST-PREFIX MATCH, the Timeline Merge agent's K-WAY MERGE, the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS, the Household Composition agent's UNION-FIND, the MLR Rebate agent's LARGEST-REMAINDER APPORTIONMENT, or the Identifier Validation agent's MODULAR-ARITHMETIC CHECKSUM: the heart of the service is EARLIEST-DEADLINE-FIRST (EDF) SCHEDULING. In a new pure lib/sla-worklist.ts, evaluateWorklist(request) takes a single WORKLIST of pending cases for one processor (a UM nurse's queue, an appeals analyst's desk, a claims-review bench) — each case a unit of work with a processing DURATION and an SLA DEADLINE — and DETERMINISTICALLY orders the entire worklist by deadline ascending (documented tie-break: earlier deadline first, then lexical case id), then processes the cases sequentially from time zero — each case starts when the previous finishes, its completion time is the running cumulative duration, and it BREACHES when its completion time exceeds its deadline — reporting the ordered worklist, the per-case completion times + lateness, the breach count, and the disposition: all-on-time or breaches-present. EDF is the classic optimal single-processor discipline: if ANY ordering can meet every deadline, EDF does (it minimizes the maximum lateness). It COMPLEMENTS, not duplicates, the sibling scheduling agents: distinct from the Resource Scheduling agent (which selects a max-value non-overlapping subset for one resource) and the Caseload Balancing agent (which bin-packs patients across care managers) — this ORDERS a whole worklist for one processor by SLA deadline and flags the breaches. TIME IS DATA: durations + deadlines are plain numbers (minutes from the top of the shift) and the sequencing is a pure function of the tasks (no real clock, no randomness), so the same worklist always yields the same schedule. A worklist — all-on-time / breaches-present — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresReviewerReview:true, autoDispatched:false), which is how a legitimate schedule is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.worklist.schedule-sourced (signal worklistScheduleSourced, violating value false) blocks a schedule that isn't a real, self-consistent accounting of the submitted cases — the scheduled list must be a PERMUTATION of the submitted tasks (each submitted case once — no fabricated case, none dropped or double-worked), each entry must echo its case's duration + deadline, the completion times must chain (the first starts at zero, each starts when the previous finishes, each completion = start + duration), each late flag must equal completion > deadline, the counts must add up, and the disposition must follow — the sourced + self-consistency gate (mirroring the Resource Scheduling Agent's selection-sourced and the Scheduling Conflict Agent's intervals-sourced) — backed by the pure guard scheduleSourced; policy.worklist.edf-ordered (signal worklistEdfOrdered, violating value false) blocks a non-EDF order that needlessly breaches deadlines — re-running the EARLIEST-DEADLINE-FIRST discipline over the submitted cases must reproduce the reported ORDER (cases sequenced by deadline ascending, tie-break by case id) — this is the load-bearing correctness gate, and it compares the ORDERING of the real submitted cases INDEPENDENT of the reported completion times (it extracts the subsequence of reported cases that are real submitted cases and verifies that subsequence is in EDF order, so a fabricated-case schedule that still orders the real cases correctly fails sourced only — the phantom is filtered out here — and a real-but-mis-ordered schedule fails ordered only — the two gates are isolable) (mirroring the Resource Scheduling Agent's schedule-optimal and the Care Routing Agent's route-optimal) — backed by the guard scheduleOrdered; and policy.worklist.no-autonomous-dispatch (signal worklistNoAutonomousDispatch, violating value false) blocks a determination that autonomously dispatched, started, or reassigned a case (autoDispatched:true — each is a work-assignment action that must be authorized) or did not require reviewer review (requiresReviewerReview:false) — the agent SEQUENCES on paper, and every worklist is a RECOMMENDATION requiring a supervisor to confirm — backed by the guard noAutonomousDispatch (mirroring the Resource Scheduling Agent's no-autonomous-booking and the Caseload Balancing Agent's no-autonomous-assignment; the harmful action is enforced-off). It IS PHI-bearing — each case references the member / claim being worked — so it is on the HIPAA-audit policy (phiAccessed:true throughout) and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/sla-worklist/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — worklist.receive-cases → worklist.sequence-edf → worklist.classify-disposition → worklist.log-audit — with phiAccessed:true, returning the WorklistDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new SLA Worklist panel (a with-breach preset over four UM authorization cases → EDF orders auth-502 → auth-501 → auth-504 → auth-503 with auth-504 breaching its 70-minute SLA; an all-on-time preset; an over-committed preset where even the optimal EDF order breaches two SLAs; plus fabricated-case / non-EDF-order / auto-dispatched governance-block presets), a seeded worklist.receive-cases→sequence-edf→classify-disposition→log-audit trace showing the breaches-present case (1 of 4 breaching, requiresReviewerReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'ninety-seven agents', with the SLA Worklist agent on the payer-operations tier alongside the Utilization Review and Coordination of Benefits agents) all reflect it. Menopause-relevant: a UM / appeals queue of menopause-care prior-auths and appeals racing regulatory SLA clocks is exactly the worklist this EDF sequencer orders to minimize breaches — surfacing an over-committed queue to a supervisor rather than silently missing deadlines, and never dispatching the work on its own. Frontend tests green (4,110 tests — + sla-worklist EDF order-and-chain / deadline-tie-break / empty, breaches / all-on-time / over-committed / determinism, and three-guards-on-produced with fabricated-case + mis-chained-completion + count-mismatch + schedule-sourced-vs-edf-ordered-isolation + non-EDF-order + auto-dispatched + skipped-review guard cases, the route's envelope / three governance blocks / breaches + all-on-time + over-committed happy paths with a PHI trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to ninety-seven agents); the worklist is a clearly-labeled illustrative synthetic — NOT a certified workforce / queueing system (real worklist management uses staffing levels, skills-based routing, case arrival times, preemption, priority tiers, and shift schedules). Lint + build clean.

db9b731 agent fabric: add the SLA Worklist Sequencing / Earliest-Deadline-First (EDF) Scheduling agent (97th) — deterministic EDF scheduling that orders a worklist by SLA deadline and flags the breaches, with every schedule sourced + self-consistent, a recomputing EDF order, and never an autonomous dispatch

Agent Fabric: added the Commercial Peak-Window / Maximum Contiguous Net-Gain Detection agent — deterministic Kadane's maximum-subarray that finds the single maximum-sum contiguous window (the peak net-gain stretch) in a signed metric series (positive-window / no-positive-window), with every window sourced + self-honest, a recomputing Kadane optimum, and never an autonomous action (the 96th agent)

Shipped
Details

Added the ninety-sixth agent on the fabric — peak-window-agent, a DETERMINISTIC (no-Claude) commercial-analytics agent on the strictly PHI-separated commercial CRM plane, reusing the existing commercial-operations tier as a SIBLING to the KPI Trend, Pipeline Management, Account Management, Provider Contracting, Provider Benchmarking, and Deal Desk agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric, and CRUCIALLY it is NOT the sibling KPI Trend agent's ORDINARY LEAST-SQUARES LINEAR REGRESSION (which fits a best-fit line and PROJECTS it to a horizon — a fitted model + extrapolation), NOT the Quality Shift agent's CUSUM CHANGE-POINT DETECTION (a running deviation from a target to catch a SUSTAINED shift), NOT the Access Anomaly agent's SLIDING-WINDOW COUNTING (a FIXED-width window sliding over events), and NOT the Remote Patient Monitoring agent's WINDOW-VS-BASELINE trend classification; it is also NOT the Resource Scheduling agent's WEIGHTED INTERVAL SCHEDULING, the Care Routing agent's DIJKSTRA'S SHORTEST PATH, the Outreach agent's 0/1 KNAPSACK, the Source Consensus agent's BOYER–MOORE MAJORITY VOTE, the Code Taxonomy agent's TRIE LONGEST-PREFIX MATCH, the Timeline Merge agent's K-WAY MERGE, the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS, the Household Composition agent's UNION-FIND, or the Identifier Validation agent's MODULAR-ARITHMETIC CHECKSUM: the heart of the service is KADANE'S MAXIMUM-SUBARRAY. In a new pure lib/peak-window.ts, evaluatePeakWindow(request) takes a time-ordered series of a business metric's SIGNED per-period NET CHANGE (net-new ARR = bookings − churn, net enrolled patients = adds − drops, net revenue delta) and DETERMINISTICALLY runs a single linear scan carrying a running sum that RESETS whenever extending the previous stretch would do worse than starting fresh at the current period (curSum = max(x_i, curSum + x_i)), tracking the best window seen — the maximum-sum contiguous subarray in O(n) — to find the single MAXIMUM-SUM CONTIGUOUS WINDOW (the strongest sustained net-gain STRETCH), reporting its start / end period, summed net gain, and length, or honestly reporting NO POSITIVE WINDOW when every contiguous stretch nets a loss (returning the least-negative single period), and deriving the disposition: positive-window or no-positive-window. A fixed-width or whole-series average hides the true peak run; Kadane finds the exact contiguous window that maximizes net gain. It COMPLEMENTS, not duplicates, the sibling commercial agents: distinct from the KPI Trend agent (which fits a least-squares trend line and projects it) and the Pipeline Management agent (which rolls up CRM opportunity records) — this finds the peak contiguous net-gain window. TIME IS DATA: the series is plain labeled numbers and the detection is a pure function of the series (no real clock, no randomness), so the same request always yields the same determination. A window — positive-window / no-positive-window — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresAnalystReview:true, autoActioned:false), which is how a legitimate window is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.peak-window.window-sourced (signal peakWindowSourced, violating value false) blocks a window that isn't a real, self-honest sub-range of the submitted series — the reported window must be a REAL contiguous sub-range (0 <= startIndex <= endIndex < n), its reported windowLength must match (end − start + 1), its reported windowSum must equal the ACTUAL sum of the series over that range, and hasPositiveWindow / disposition must follow the sum's sign — a window that runs off the series or overstates its own sum is a fabricated finding — the sourced + self-honesty gate (mirroring the Care Routing Agent's path-sourced and the Resource Scheduling Agent's selection-sourced) — backed by the pure guard windowSourced; policy.peak-window.window-optimal (signal peakWindowOptimal, violating value false) blocks a sub-optimal window that under-reports the true peak run — re-running Kadane's maximum-subarray over the submitted series must reproduce the reported windowSum and the same positive-window / no-positive-window disposition — this is the load-bearing correctness gate, and it recomputes the optimum from the series INDEPENDENT of the reported window bounds (it recomputes the max sum, not the reported window, so a fabricated out-of-range window that still reports the optimal sum fails sourced only, and a real-but-sub-optimal window fails optimal only — the two gates are isolable) (mirroring the Care Routing Agent's route-optimal and the Resource Scheduling Agent's schedule-optimal) — backed by the guard windowOptimal; and policy.peak-window.no-autonomous-action (signal peakWindowNoAutonomousAction, violating value false) blocks a determination that autonomously committed the finding as an official metric, adjusted a quota / target, or notified finance (autoActioned:true — each is a consequential commercial action that must be authorized) or did not require analyst review (requiresAnalystReview:false) — the agent DETECTS on paper, and every window is a RECOMMENDATION requiring a revenue analyst to confirm — backed by the guard noAutonomousAction (mirroring the KPI Trend Agent's no-autonomous-commit and the Provider Benchmarking Agent's no-autonomous-tiering; the harmful action is enforced-off). It operates ONLY on the commercial CRM plane — DELIBERATELY NOT PHI-bearing (phiAccessed:false throughout), NOT on the HIPAA-audit policy, and NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/peak-window/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — peak.receive-series → peak.scan-max-subarray → peak.classify-disposition → peak.log-audit — with phiAccessed:false, returning the PeakWindowDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Peak Window panel (a positive-window preset over twelve months of net-new ARR → the Apr→Aug peak run netting +58; a no-positive-window preset; a whole-series-is-the-window preset; plus fabricated-window / sub-optimal / auto-actioned governance-block presets), a seeded peak.receive-series→scan-max-subarray→classify-disposition→log-audit trace showing the positive-window case (window sum 58 over 5 periods, requiresAnalystReview:true, phiAccessed:false), the console subtitle, and the investor brief (now 'ninety-six agents', with the Peak Window agent on the commercial-operations tier alongside the KPI Trend agent) all reflect it. Menopause-relevant: the strongest contiguous growth stretch in Pause's net-new enrolled-patient or net-new-ARR series is exactly the momentum window this agent surfaces for a GTM review — without ever committing the figure or moving a quota on its own. Frontend tests green (4,073 tests — + peak-window Kadane max-subarray / all-negative-least-negative / all-positive-whole-series / earliest-window-on-tie / empty, positive-window / no-positive-window / whole-series / determinism, and three-guards-on-produced with out-of-range-fabricated + overstated-sum + length-mismatch + window-sourced-vs-window-optimal-isolation + sub-optimal + auto-actioned + skipped-review guard cases, the route's envelope / three governance blocks / positive + no-positive + whole-series happy paths with a non-PHI trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to ninety-six agents); the series are clearly-labeled illustrative aggregate business figures — NOT a certified analytics / FP&A system (real commercial analytics weighs seasonality, cohort dynamics, pipeline mix, macro conditions, and human judgment). Lint + build clean.

e5b416f agent fabric: add the Commercial Peak-Window / Maximum Contiguous Net-Gain Detection agent (96th) — deterministic Kadane's maximum-subarray that finds the single maximum-sum contiguous window in a signed metric series, with every window sourced + self-honest, a recomputing Kadane optimum, and never an autonomous action

Agent Fabric: added the Resource-Block Scheduling / Max-Value Non-Overlapping Selection agent — deterministic weighted interval scheduling (dynamic programming) that selects the max-total-weight non-overlapping set of competing requests for one contended resource (all-scheduled / contended), with every selection sourced + feasible, a recomputing DP optimum, and never an autonomous booking (the 95th agent)

Shipped
Details

Added the ninety-fifth agent on the fabric — resource-scheduling-agent, a DETERMINISTIC (no-Claude) care-coordination capacity-optimization service on the patient & clinical-operations plane, reusing the existing care-coordination tier as a SIBLING to the Scheduling Conflict, Caseload Balancing, and Appointment Scheduling agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric, and CRUCIALLY it is NOT the sibling Scheduling Conflict agent's GREEDY INTERVAL SELECTION (which maximizes the COUNT of double-booking-free appointments, WEIGHTLESS) and NOT the Caseload Balancing agent's GREEDY BIN-PACKING under a capacity constraint or the Outreach Prioritization agent's 0/1 KNAPSACK DYNAMIC PROGRAMMING (items with a value + a cost packed under a single capacity budget, no time / overlap structure); it is also NOT the Care Routing agent's DIJKSTRA'S WEIGHTED SHORTEST PATH, the Source Consensus agent's BOYER–MOORE MAJORITY VOTE, the Code Taxonomy agent's TRIE LONGEST-PREFIX MATCH, the KPI Trend agent's LEAST-SQUARES REGRESSION, the Quality Shift agent's CUSUM CHANGE-POINT DETECTION, the Timeline Merge agent's K-WAY MERGE, the PCP Matching agent's STABLE MATCHING, the Network Adequacy agent's GREAT-CIRCLE DISTANCE, the Household Composition agent's UNION-FIND, the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS, or the Identifier Validation agent's MODULAR-ARITHMETIC CHECKSUM: the heart of the service is WEIGHTED INTERVAL SCHEDULING via DYNAMIC PROGRAMMING. In a new pure lib/resource-scheduling.ts, evaluateBlockSchedule(request) takes a single SHARED SCARCE RESOURCE (an infusion chair, an OR block, a specialist's slot ladder, an imaging machine) and a batch of competing REQUESTS for it — each a half-open [start, end) time WINDOW with a priority WEIGHT (clinical value / acuity) — and DETERMINISTICALLY sorts the requests by end time, computes for each request i the latest earlier request p(i) that does NOT overlap it, fills dp[i] = max(dp[i-1], weight_i + dp[p(i)]), and backtracks to recover the MAX-WEIGHT compatible subset — selecting the maximum-total-weight set of non-overlapping requests the resource can honor, reporting the rest as CONTENDED, and deriving the disposition: all-scheduled or contended. A greedy earliest-finish rule maximizes the COUNT of appointments but can leave clinical VALUE on the table (two short low-acuity blocks beat one long high-acuity block by count, but not by weight); the DP maximizes the total weight the resource actually delivers. It COMPLEMENTS, not duplicates, the sibling scheduling agents: distinct from the Scheduling Conflict agent (which maximizes the COUNT of double-booking-free appointments) and the Caseload Balancing agent (which bin-packs patients across care managers) — this picks the max-VALUE non-overlapping set for one contended resource. TIME IS DATA: the windows are plain numbers (epoch-minutes / slot indices) and the selection is a pure function of the requests (no real clock, no randomness), so the same request always yields the same determination. A schedule — all-scheduled / contended — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresSchedulerReview:true, autoBooked:false), which is how a legitimate schedule is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.block-schedule.selection-sourced (signal blockScheduleSourced, violating value false) blocks a selection that isn't a real, feasible subset of the submitted requests — every selected id must be a SUBMITTED request (no fabricated block, none double-counted), the selected windows must be pairwise NON-OVERLAPPING (the resource is never double-booked), the reported totalWeight must equal the sum of the selected weights, the counts must add up (scheduled + contended = total = requests), and the disposition must follow — the sourced + feasibility gate (mirroring the Scheduling Conflict Agent's intervals-sourced + conflict-free and the Care Routing Agent's path-sourced) — backed by the pure guard selectionSourced; policy.block-schedule.schedule-optimal (signal blockScheduleOptimal, violating value false) blocks a sub-optimal schedule that silently leaves clinical value unbooked — re-running the weighted-interval DP over the submitted requests must reproduce the reported totalWeight and the same all-scheduled / contended disposition — this is the load-bearing correctness gate, and it recomputes the optimum from the requests INDEPENDENT of the reported selection (it recomputes the max weight, not the reported selected set, so a fabricated-block selection that still reports the optimal total fails sourced only, and a real-but-sub-optimal selection fails optimal only — the two gates are isolable) (mirroring the Care Routing Agent's route-optimal and the Outreach Prioritization Agent's selection-optimal) — backed by the guard selectionOptimal; and policy.block-schedule.no-autonomous-booking (signal blockScheduleNoAutonomousBooking, violating value false) blocks a determination that autonomously booked, bumped, or confirmed a block (autoBooked:true — each is a scheduling action that must be authorized) or did not require scheduler review (requiresSchedulerReview:false) — the agent SELECTS on paper, and every schedule is a RECOMMENDATION requiring a scheduler to confirm — backed by the guard noAutonomousBooking (mirroring the Scheduling Conflict Agent's no-autonomous-booking and the Caseload Balancing Agent's no-autonomous-assignment; the harmful action is enforced-off). It IS PHI-bearing — each request references the patient being scheduled — so it is on the HIPAA-audit policy (phiAccessed:true throughout) and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/resource-scheduling/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — schedule.receive-requests → schedule.optimize-selection → schedule.classify-disposition → schedule.log-audit — with phiAccessed:true, returning the BlockScheduleDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Resource Scheduling panel (a contended infusion-chair preset → the max-weight subset {infusion-1101, infusion-1104} = weight 11; an all-scheduled preset; a weight-beats-count preset where the DP takes one weight-10 block over two weight-3 blocks; plus fabricated-block / sub-optimal / auto-booked governance-block presets), a seeded schedule.receive-requests→optimize-selection→classify-disposition→log-audit trace showing the contended case (2 of 5 scheduled, total weight 11, requiresSchedulerReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'ninety-five agents', with the Resource Scheduling agent on the care-coordination tier alongside the Scheduling Conflict and Caseload Balancing agents) all reflect it. Menopause-relevant: a menopause-care program competing for a scarce infusion chair, an imaging slot, or a specialist block against higher- and lower-acuity requests is exactly the contention this DP resolves by delivered clinical value — without ever booking the block on its own. Frontend tests green (4,034 tests — + resource-scheduling weighted-interval max-weight-subset / weight-over-count / all-non-overlapping / empty, contended / all-scheduled / determinism, and three-guards-on-produced with fabricated-block + double-booked + totalWeight-mismatch + count-mismatch + selection-sourced-vs-schedule-optimal-isolation + sub-optimal + auto-booked + skipped-review guard cases, the route's envelope / three governance blocks / contended + all-scheduled + weight-over-count happy paths with a PHI trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to ninety-five agents); the resource + requests are clearly-labeled illustrative synthetics — NOT a certified scheduling / capacity system (real resource scheduling uses provider availability calendars, appointment-type durations, buffer / turnover times, room / equipment constraints, and staffing ratios). Lint + build clean.

f34d515 agent fabric: add the Resource-Block Scheduling / Max-Value Non-Overlapping Selection agent (95th) — deterministic weighted interval scheduling (dynamic programming) that selects the max-total-weight non-overlapping set of competing requests for one contended resource, with every selection sourced + feasible, a recomputing DP optimum, and never an autonomous booking

Agent Fabric: added the Clinical Code Taxonomy / Longest-Prefix Classification agent — deterministic trie (prefix tree) longest-prefix match that classifies a batch of clinical codes to their most-specific taxonomy category (all-classified / unclassified-present), with every classification sourced, a recomputing match, and never an autonomous re-code (the 94th agent)

Shipped
Details

Added the ninety-fourth agent on the fabric — code-taxonomy-agent, a DETERMINISTIC (no-Claude) data-substrate terminology / value-set service on the platform & data-substrate plane, reusing the existing data-plane tier as a SIBLING to the Identifier Validation, Source Consensus, Master-Patient-Index, and Timeline Merge agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the Source Consensus agent's BOYER–MOORE MAJORITY VOTE, the Care Routing agent's DIJKSTRA'S WEIGHTED SHORTEST PATH, the KPI Trend agent's LEAST-SQUARES LINEAR REGRESSION, the Outreach Prioritization agent's 0/1 KNAPSACK DYNAMIC PROGRAMMING, the Quality Shift agent's CUSUM CHANGE-POINT DETECTION, the Timeline Merge agent's K-WAY MERGE OF SORTED STREAMS, the Reportable Condition agent's RECURSIVE BOOLEAN EXPRESSION-TREE EVALUATION, the PCP Matching agent's TWO-SIDED STABLE MATCHING (Gale–Shapley), the Network Adequacy agent's GEOSPATIAL GREAT-CIRCLE DISTANCE, the Household Composition agent's UNION-FIND CONNECTED COMPONENTS, the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS, the MLR Rebate agent's LARGEST-REMAINDER APPORTIONMENT, the Schedule Conflict agent's GREEDY INTERVAL SELECTION, the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, the Audit Log Integrity agent's HASH CHAIN, or the Claim Lifecycle agent's BFS REACHABILITY, and — CRUCIALLY — it is NOT the Identifier Validation agent's MODULAR-ARITHMETIC CHECKSUM (character math on a single identifier's Luhn check digit), the Medication Name Safety agent's STRING EDIT DISTANCE (how far apart two drug NAMES are), or the HCC Risk Adjustment agent's HIERARCHY + COEFFICIENT SUM (rolling confirmed conditions up a clinical hierarchy and summing RAF coefficients): the heart of the service is a TRIE (PREFIX TREE) LONGEST-PREFIX MATCH. In a new pure lib/code-taxonomy.ts, evaluateCodeTaxonomy(request) takes a BATCH of clinical codes (ICD-10 diagnosis, HCPCS / CPT procedure) and a TAXONOMY of category PREFIXES (a code-group value-set) and DETERMINISTICALLY inserts the prefixes into a trie, then walks each code character-by-character down the trie remembering the DEEPEST terminal node reached — the longest taxonomy prefix that is a prefix of the code (the most specific category) — classifying each code to its most-specific category or leaving it unclassified when no prefix matches, and deriving the disposition: all-classified or unclassified-present. A shallow substring match (E28 when E28.3 also applies) mis-buckets a code into a less specific group; the longest-prefix rule picks the most specific category the taxonomy defines. It COMPLEMENTS, not duplicates, the other terminology / coding agents: distinct from the Identifier Validation agent (which validates an NPI's Luhn check digit), the Medication Name Safety agent (which flags look-alike drug names by edit distance), and the HCC Risk Adjustment agent (which scores confirmed conditions up a hierarchy) — this maps codes to a value-set taxonomy by longest prefix. TIME IS DATA: the classification is a pure function of the taxonomy + codes (no real clock, no randomness), so the same request always yields the same determination. A batch — all-classified / unclassified-present — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresCoderReview:true, autoApplied:false), which is how a legitimate classification is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.code.classifications-sourced (signal codeClassificationsSourced, violating value false) blocks a batch that doesn't correspond exactly to the submitted codes — exactly one classification per submitted code, in the same order (no fabricated code, none dropped, none duplicated), every matched prefix a SUBMITTED taxonomy prefix (no invented category), each classification self-consistent (a category iff a matched prefix), the counts adding up (classified + unclassified = total = codes), and the disposition following — the sourced + completeness gate (mirroring the Identifier Validation Agent's identifiers-sourced and the Enrollment Reconciliation Agent's reconciliation-complete) — backed by the pure guard classificationsSourced; policy.code.classification-consistent (signal codeClassificationConsistent, violating value false) blocks a wrong bucket or a missed match — rebuilding the trie from the taxonomy and re-running the longest-prefix match over each submitted code must reproduce the reported category + matched prefix — this is the load-bearing correctness gate, and it recomputes the match from the taxonomy INDEPENDENT of the reported classifications (it filters them to the ones whose code is a real submitted code before checking their category + prefix, so a fabricated-code classification that still reports a correct match fails sourced only, and a real-code but wrong-bucket classification fails consistent only — the two gates are isolable) (mirroring the Identifier Validation Agent's checksum-consistent and the Source Consensus Agent's consensus-consistent) — backed by the guard classificationConsistent; and policy.code.no-autonomous-recode (signal codeNoAutonomousRecode, violating value false) blocks a determination that autonomously re-coded a claim, submitted the codes, or overwrote the coded record (autoApplied:true — each is a consequential coding action that must be authorized) or did not require coder review (requiresCoderReview:false) — the agent CLASSIFIES on paper, and every classification is a RECOMMENDATION requiring a coder to confirm — backed by the guard noAutonomousRecode (mirroring the Identifier Validation Agent's no-autonomous-reject and the Enrollment Reconciliation Agent's no-autonomous-change; the harmful action is enforced-off). It is DELIBERATELY NOT PHI-bearing — a code is a terminology token, classified against a value-set taxonomy, not patient health information — so, like the Identifier Validation agent, it is NOT on the HIPAA-audit policy (phiAccessed:false throughout) and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/code-taxonomy/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — taxonomy.receive-codes → taxonomy.match-prefixes → taxonomy.classify-disposition → taxonomy.log-audit — with phiAccessed:false, returning the CodeTaxonomyDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Code Taxonomy panel (a mixed menopause / endocrine ICD-10 preset → unclassified-present with E28.310 bucketed to E28.3 not the shallower E28; an all-classified preset; a longest-prefix specificity preset (E28.319 → E28.3, E28.1 → E28); plus fabricated-code / wrong-bucket / auto-applied governance-block presets), a seeded taxonomy.receive-codes→match-prefixes→classify-disposition→log-audit trace showing the mixed case (4 of 5 codes classified, requiresCoderReview:true, phiAccessed:false), the console subtitle, and the investor brief (now 'ninety-four agents', with the Code Taxonomy agent on the data-substrate tier alongside the Identifier Validation and Source Consensus agents) all reflect it. Menopause-relevant: a menopause visit's diagnosis codes (E28.3 primary ovarian failure, N95.x menopausal disorders) and the endocrine comorbidities that ride alongside are exactly the codes this trie buckets to their most-specific value-set category — feeding quality measures, risk models, and analytics — without ever re-coding the claim on its own. Frontend tests green (3,996 tests — + code-taxonomy trie longest-prefix / shallow-fallback / no-match, mixed / all-classified / specificity / determinism, and three-guards-on-produced with fabricated-code + invented-category + count-mismatch + self-inconsistent + classifications-sourced-vs-classification-consistent-isolation + wrong-bucket + missed-match + auto-applied + skipped-review guard cases, the route's envelope / three governance blocks / mixed + all-classified + specificity happy paths with a non-PHI trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to ninety-four agents); the taxonomy + codes are clearly-labeled illustrative synthetics — NOT a certified terminology / code-set engine (real terminology services resolve full code systems — ICD-10-CM, SNOMED CT, LOINC, RxNorm — with versioned value sets, inclusion/exclusion logic, and semantic relationships, not a bare longest-prefix match). Lint + build clean.

94a6b5a agent fabric: add the Clinical Code Taxonomy / Longest-Prefix Classification agent (94th) — deterministic trie (prefix tree) longest-prefix match that classifies a batch of clinical codes to their most-specific taxonomy category, with every classification sourced, a recomputing match, and never an autonomous re-code

Agent Fabric: added the Source-of-Truth Consensus / Golden-Record Field Reconciliation agent — deterministic Boyer–Moore majority vote that reconciles a field's conflicting source-system values into a golden-record value (consensus / no-consensus), with the per-source attribution sourced, a recomputing consensus, and never an autonomous golden-record write (the 93rd agent)

Shipped
Details

Added the ninety-third agent on the fabric — source-consensus-agent, a DETERMINISTIC (no-Claude) data-substrate master-data / golden-record service on the platform & data-substrate plane, reusing the existing data-plane tier as a SIBLING to the Enrollment Reconciliation, Master-Patient-Index, Identifier Validation, and Timeline Merge agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the Care Routing agent's DIJKSTRA'S WEIGHTED SHORTEST PATH, the KPI Trend agent's LEAST-SQUARES LINEAR REGRESSION, the Outreach Prioritization agent's 0/1 KNAPSACK DYNAMIC PROGRAMMING, the Quality Shift agent's CUSUM CHANGE-POINT DETECTION, the Timeline Merge agent's K-WAY MERGE OF SORTED STREAMS, the Reportable Condition agent's RECURSIVE BOOLEAN EXPRESSION-TREE EVALUATION, the PCP Matching agent's TWO-SIDED STABLE MATCHING (Gale–Shapley), the Network Adequacy agent's GEOSPATIAL GREAT-CIRCLE DISTANCE, the Identifier Validation agent's MODULAR-ARITHMETIC CHECKSUM, the Household Composition agent's UNION-FIND CONNECTED COMPONENTS, the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS, the MLR Rebate agent's LARGEST-REMAINDER APPORTIONMENT, the Medication Name Safety agent's STRING EDIT DISTANCE, the Schedule Conflict agent's GREEDY INTERVAL SELECTION, the Audit Log Integrity agent's HASH CHAIN, or the Claim Lifecycle agent's BFS REACHABILITY, and — CRUCIALLY — it is NOT the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE (which diffs WHO is on two rosters — enroll / terminate / update) or the Master-Patient-Index agent's WEIGHTED identity MATCHING (which decides whether two RECORDS are the same person): the heart of the service is the BOYER–MOORE MAJORITY VOTE — the classic linear-time, constant-space strict-majority election. In a new pure lib/source-consensus.ts, evaluateConsensus(request) takes a single logical FIELD whose value is reported by several SOURCE SYSTEMS (an EHR feed, a claims feed, a credentialing feed, an HIE feed) and DETERMINISTICALLY runs one cancellation pass (hold a candidate + a counter; increment on a match, decrement on a mismatch, reset the candidate when the counter hits zero) plus one verification pass confirming the survivor occurs in more than half the votes, deriving the disposition: consensus (a value carries a strict majority — with the winner, its count, and per-source agreement) or no-consensus (no value does). When two feeds disagree, a naive 'last write wins' or 'first source wins' silently picks a wrong value; a majority vote picks the value the SOURCES themselves corroborate. It COMPLEMENTS, not duplicates, the other data-plane agents: distinct from the Enrollment Reconciliation agent (a keyed set-difference between two rosters), the Master-Patient-Index agent (weighted record identity matching), and the Timeline Merge agent (a k-way merge of event streams) — this reconciles ONE field's conflicting source values into a golden-record value. TIME IS DATA: the consensus is a pure function of the votes themselves (no real clock, no randomness), so the same request always yields the same determination. A reconciliation — consensus / no-consensus — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresStewardReview:true, autoWritten:false), which is how a legitimate reconciliation is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.consensus.votes-sourced (signal consensusVotesSourced, violating value false) blocks a per-source attribution that doesn't correspond exactly to the submitted votes — every agreement must trace to a SUBMITTED vote (same sourceId + value; no fabricated source), every submitted vote must be attributed exactly once (none dropped, none double-listed), and the total must equal the number of votes — the sourced + completeness gate (mirroring the Enrollment Reconciliation Agent's reconciliation-complete and the Timeline Merge Agent's events-sourced) — backed by the pure guard votesSourced; policy.consensus.consensus-consistent (signal consensusConsistent, violating value false) blocks a wrong winner or a false consensus — re-running the Boyer–Moore majority vote over the submitted votes must reproduce the reported candidate, its count, the has-consensus flag, the disposition, and every real source's agreement flag — this is the load-bearing correctness gate, and it recomputes the winner from the votes INDEPENDENT of the reported agreements (it filters them to the ones that correspond to a real submitted vote before checking their flags, so a fabricated-source agreement that still reports the true winner fails sourced only, and a real-source but mis-flagged or wrong-winner determination fails consistent only — the two gates are isolable) (mirroring the Timeline Merge Agent's merge-consistent and the Identifier Validation Agent's checksum-consistent) — backed by the guard consensusConsistent; and policy.consensus.no-autonomous-write (signal consensusNoAutonomousWrite, violating value false) blocks a reconciliation that autonomously wrote the consensus value to the golden record / master data, overwrote a source system, or promoted a value to system-of-record (autoWritten:true — each is a data-integrity action that must be authorized) or did not require steward review (requiresStewardReview:false) — the agent RECONCILES on paper, and every reconciliation is a RECOMMENDATION requiring a data steward to confirm — backed by the guard noAutonomousWrite (mirroring the Timeline Merge Agent's no-autonomous-merge and the Enrollment Reconciliation Agent's no-autonomous-change; the harmful action is enforced-off). It is DELIBERATELY NOT PHI-bearing — a golden-record reference attribute (a provider's specialty, an org's tax id), not patient health information — so, like the Identifier Validation agent, it is NOT on the HIPAA-audit policy (phiAccessed:false throughout) and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/source-consensus/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — consensus.receive-votes → consensus.run-majority-vote → consensus.classify-consensus → consensus.log-audit — with phiAccessed:false, returning the ConsensusDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Source Consensus panel (a 4-of-5 provider-specialty preset → consensus 'Endocrinology'; a 2-2-1 network-status preset → no-consensus; a unanimous tax-id preset → consensus; plus fabricated-source / wrong-winner / auto-written governance-block presets), a seeded consensus.receive-votes→run-majority-vote→classify-consensus→log-audit trace showing the consensus case (candidate 'Endocrinology', 4 of 5 sources, requiresStewardReview:true, phiAccessed:false), the console subtitle, and the investor brief (now 'ninety-three agents', with the Source Consensus agent on the data-substrate tier alongside the Identifier Validation and Timeline Merge agents) all reflect it. Menopause-relevant: the gynecologists, endocrinologists, and compounding pharmacies a menopause plan lists carry a specialty, a network status, and an identifier that four different feeds each report differently — a majority vote across the sources is exactly what turns those conflicting feeds into one trustworthy directory value, without ever overwriting a system of record on its own. Frontend tests green (3,957 tests — + source-consensus boyer-moore strict-majority / plurality / unanimity / ordering, consensus / no-consensus / unanimous / determinism, and three-guards-on-produced with fabricated-source + dropped-source + total-mismatch + votes-sourced-vs-consensus-consistent-isolation + wrong-winner + false-consensus + mis-flagged-source + auto-written + skipped-review guard cases, the route's envelope / three governance blocks / consensus + no-majority + unanimous happy paths with a non-PHI trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to ninety-three agents); the fields + sources + values are clearly-labeled illustrative synthetics — NOT a certified master-data-management / golden-record system (real MDM weights sources by trust and recency, resolves value semantics, and survives field-by-field with lineage — not a bare majority of raw string votes). Lint + build clean.

cefaf25 agent fabric: add the Source-of-Truth Consensus / Golden-Record Field Reconciliation agent (93rd) — deterministic Boyer–Moore majority vote that reconciles a field's conflicting source-system values into a golden-record value, with the per-source attribution sourced, a recomputing consensus, and never an autonomous golden-record write

Agent Fabric: added the Care-Transition Routing / Least-Burden Path agent — deterministic Dijkstra's weighted shortest path that finds the minimum-total-burden route from a patient's current care setting to a goal setting through a weighted graph of permitted transitions (route-found / no-route), with the path sourced, a recomputing optimal route, and never an autonomous transition (the 92nd agent)

Shipped
Details

Added the ninety-second agent on the fabric — care-routing-agent, a DETERMINISTIC (no-Claude) care-coordination / transition-planning service on the patient / clinical plane, reusing the existing care-coordination tier as a SIBLING to the Care Pathway, Transitions of Care, Caseload Balancing, Outreach Prioritization, and Schedule Conflict agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the KPI Trend agent's LEAST-SQUARES LINEAR REGRESSION, the Outreach Prioritization agent's 0/1 KNAPSACK DYNAMIC PROGRAMMING, the Quality Shift agent's CUSUM CHANGE-POINT DETECTION, the Timeline Merge agent's K-WAY MERGE OF SORTED STREAMS, the Reportable Condition agent's RECURSIVE BOOLEAN EXPRESSION-TREE EVALUATION, the PCP Matching agent's TWO-SIDED STABLE MATCHING (Gale–Shapley), the Network Adequacy agent's GEOSPATIAL GREAT-CIRCLE DISTANCE, the Identifier Validation agent's MODULAR-ARITHMETIC CHECKSUM, the Household Composition agent's UNION-FIND CONNECTED COMPONENTS, the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS, the MLR Rebate agent's LARGEST-REMAINDER APPORTIONMENT, the Medication Name Safety agent's STRING EDIT DISTANCE, the Schedule Conflict agent's GREEDY INTERVAL SELECTION, the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, or the Audit Log Integrity agent's HASH CHAIN, and — CRUCIALLY — it is NOT the Care Pathway agent's TOPOLOGICAL ORDERING (which sequences ALL the required steps of ONE protocol into a dependency order — no weights, no source/target, no choosing among alternative routes), the Claim Lifecycle agent's BFS REACHABILITY (which finds the fewest-HOPS path across an UNWEIGHTED status state machine — edge count, not edge weight), or the Transitions of Care agent's MEDICATION RECONCILIATION (which reconciles meds across ONE encounter — it routes nothing): the heart of the service is DIJKSTRA'S WEIGHTED SHORTEST PATH — the classic single-source shortest-path over a graph with non-negative edge weights. In a new pure lib/care-routing.ts, evaluateCareRoute(request) takes a patient's current care SETTING (a start node), a goal setting, and a directed graph of PERMITTED transitions between settings each carrying a non-negative BURDEN weight (wait days + travel + cost proxy + risk), and DETERMINISTICALLY settles the nearest unsettled node and relaxes its out-edges (dist[v] = min(dist[v], dist[u] + w(u,v)); tie-break by lowest node id), reconstructs the minimum-total-weight path by walking predecessors back, and derives the disposition: route-found (with the path + total burden + hop count) or no-route (the goal is unreachable). A greedy or hand-picked route sends a patient the long way round — more waiting, more travel, more cost. It COMPLEMENTS, not duplicates, the other care-coordination agents: distinct from the Care Pathway agent (which topologically orders one protocol's steps), the Transitions of Care agent (medication reconciliation), and the Schedule Conflict agent (double-booking guard) — this finds the least-burden PATH through a weighted graph of care settings. TIME IS DATA: the route is a pure function of the graph's own edges + weights (no real clock, no randomness), so the same graph always yields the same route. A route — route-found / no-route — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresCareLeadReview:true, autoRouted:false), which is how a legitimate route is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.route.path-sourced (signal routePathSourced, violating value false) blocks a path that isn't a real walk of the submitted graph — for a route-found determination it must start at the start, end at the goal, every consecutive pair must be a SUBMITTED edge (no fabricated transition), and the totalCost must equal the sum of those edges' weights; an honest no-route must carry an empty path, a null cost, and reachable:false — the sourced + well-formedness gate (mirroring the Claim Lifecycle Agent's states-sourced and the Care Pathway Agent's steps-sourced) — backed by the pure guard pathSourced; policy.route.route-optimal (signal routeOptimal, violating value false) blocks a sub-optimal route or a false 'unreachable' — recomputing Dijkstra over the submitted edges must reproduce the reported minimum total burden, the reachable flag, and the disposition — this is the load-bearing correctness gate, and it recomputes the optimum from the edges INDEPENDENT of the reported path (it compares only the reported totalCost + reachability, so a fabricated-edge path that still reports the true optimum fails sourced only, and a real-edge but sub-optimal path fails optimal only — the two gates are isolable) (mirroring the Claim Lifecycle Agent's transition-consistent and the Outreach Agent's allocation-optimal) — backed by the guard routeOptimal; and policy.route.no-autonomous-routing (signal routeNoAutonomousRouting, violating value false) blocks a route that autonomously initiated the transition, booked the setting, or moved the patient (autoRouted:true — each is a care-delivery action that must be authorized) or did not require care-lead review (requiresCareLeadReview:false) — the agent ROUTES on paper, and every route is a RECOMMENDATION requiring a care lead to confirm — backed by the guard noAutonomousRouting (mirroring the Care Gap Agent's human-review posture and the Outreach Agent's no-autonomous-schedule; the harmful action is enforced-off). It IS PHI-bearing — the route is a patient's care plan — so it reuses, by extending appliesTo, the HIPAA-audit policy (phiAccessed:true throughout), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/care-routing/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — route.receive-graph → route.compute-path → route.classify-disposition → route.log-audit — with phiAccessed:true, returning the CareRouteDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Care Routing panel (a hospital→home discharge preset → route-found via SNF + home-health at total burden 7; a clinic→specialist preset → route-found on the cheapest direct edge; a goal-unreachable preset → no-route with an empty path; plus fabricated-transition / sub-optimal-route / auto-routed governance-block presets), a seeded route.receive-graph→compute-path→classify-disposition→log-audit trace showing the route-found case (path hospital → snf → home-health → home, total burden 7, hops 3, requiresCareLeadReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'ninety-two agents', with the Care Routing agent on the care-coordination tier alongside the Care Pathway and Transitions of Care agents) all reflect it. Menopause-relevant: a midlife woman being discharged from a hospital stay who could go home directly, via a skilled-nursing stay, or through home-health — each transition carrying its own wait, travel, and cost burden — is exactly the least-total-burden routing this Dijkstra path produces for her care team, without ever booking a bed or moving her on its own. Frontend tests green (3,917 tests — + care-routing dijkstra multi-hop / cheapest-direct / unreachable, route-found / direct / no-route / determinism, and three-guards-on-produced with fabricated-edge + wrong-start + total-mismatch + no-route-with-path + path-sourced-vs-route-optimal-isolation + sub-optimal + false-unreachable + auto-routed + skipped-review guard cases, the route's envelope / three governance blocks / route-found + direct + no-route happy paths with a PHI-bearing trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to ninety-two agents); the settings + transitions are clearly-labeled illustrative synthetics — NOT a certified care-transition / discharge-planning system (real transition planning weighs clinical appropriateness, bed availability, payer authorization, patient preference, and caregiver capacity — not a single scalar burden per edge). Lint + build clean.

1f6eb6f agent fabric: add the Care-Transition Routing / Least-Burden Path agent (92nd) — deterministic Dijkstra's weighted shortest path that finds the minimum-total-burden route from a patient's current care setting to a goal setting through a weighted graph of permitted transitions, with the path sourced, a recomputing optimal route, and never an autonomous transition

Agent Fabric: added the Commercial KPI Trend & Projection agent — deterministic ordinary least-squares linear regression that fits a best-fit line to a business-metric series (slope + intercept + R²), classifies the trend rising / flat / declining, and projects the metric to a future horizon, with every point sourced, a recomputing fit, and never an autonomous forecast commit (the 91st agent, on the commercial CRM plane — no patient PHI)

Shipped
Details

Added the ninety-first agent on the fabric — kpi-trend-agent, a DETERMINISTIC (no-Claude) commercial-operations / analytics service on the COMMERCIAL CRM plane (NO patient PHI, NOT on the HIPAA-audit policy), reusing the existing commercial-operations tier as a SIBLING to the Pipeline Management, Account Management, Provider Contracting, Provider Benchmarking, and Deal Desk agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the Outreach Prioritization agent's 0/1 KNAPSACK DYNAMIC PROGRAMMING, the Quality Shift agent's CUSUM CHANGE-POINT DETECTION, the Timeline Merge agent's K-WAY MERGE OF SORTED STREAMS, the Reportable Condition agent's RECURSIVE BOOLEAN EXPRESSION-TREE EVALUATION, the PCP Matching agent's TWO-SIDED STABLE MATCHING (Gale–Shapley), the Network Adequacy agent's GEOSPATIAL GREAT-CIRCLE DISTANCE, the Identifier Validation agent's MODULAR-ARITHMETIC CHECKSUM, the Household Composition agent's UNION-FIND CONNECTED COMPONENTS, the MLR Rebate agent's LARGEST-REMAINDER APPORTIONMENT, the Claim Lifecycle agent's FSM TRANSITION VALIDATION, the Medication Name Safety agent's STRING EDIT DISTANCE, the Schedule Conflict agent's GREEDY INTERVAL SELECTION, the Caseload Balancing agent's GREEDY BIN-PACKING, the Care Pathway agent's TOPOLOGICAL ORDERING, the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, or the Audit Log Integrity agent's HASH CHAIN, and — CRUCIALLY — it is NOT the Pipeline Management agent's FORECAST ROLLUP (which SUMS CRM opportunity records into committed / best-case figures — an aggregation of records, no fitted model), the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS (which ranks ONE value against a static distribution; it fits no line and projects nothing), the Quality Shift agent's CUSUM (which accumulates a running deviation to catch a SUSTAINED shift; it fits no model and extrapolates nothing), or the Remote Patient Monitoring agent's WINDOW-VS-BASELINE trend classification (which compares a recent window to a baseline window; it fits no line): the heart of the service is ORDINARY LEAST-SQUARES LINEAR REGRESSION — the closed-form best-fit line minimizing the sum of squared residuals. In a new pure lib/kpi-trend.ts, evaluateKpiTrend(request) takes a time-ordered series of a business METRIC (monthly provider-org adoption, active enrolled patients, ARR, bookings) plus a projection horizon and a flat tolerance, and DETERMINISTICALLY computes slope = (n·Σxy − Σx·Σy) / (n·Σx² − (Σx)²), intercept = (Σy − slope·Σx) / n, and R² = 1 − SSres/SStot, emits one fitted point per observation (with its fitted value + residual), classifies the trend rising / flat / declining against the flat tolerance, and projects ŷ = slope·horizon + intercept. A mis-fit line reports a trend the data doesn't support and a projection nobody should plan against. It COMPLEMENTS, not duplicates, the other commercial agents: distinct from the Pipeline Management agent (which rolls up opportunity records into a forecast) and the Account Management agent (which health-scores signed accounts) — this fits a least-squares trend line to a KPI series and projects it. TIME IS DATA: the fit is a pure function of the observations' own indices + values + the parameters (no real clock, no randomness), so the same series always yields the same line. A trend — rising / flat / declining — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresAnalystReview:true, autoCommitted:false), which is how a legitimate fit is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.kpi.series-sourced (signal kpiSeriesSourced, violating value false) blocks a fit not drawn from the submitted observations — every fitted point must trace to a SUBMITTED observation (same index + value; no fabricated point), every submitted observation must appear exactly once (none dropped, none double-plotted), and the fit parameters (horizon, flatTolerance) must be present numbers — the sourced + completeness gate (mirroring the Quality Shift Agent's observations-sourced and the Timeline Merge Agent's events-sourced) — backed by the pure guard seriesSourced; policy.kpi.fit-consistent (signal kpiFitConsistent, violating value false) blocks a mis-fit line — recomputing the ordinary least-squares regression over the submitted observations must reproduce the reported slope, intercept, R², trend classification, projection, and every point's fitted value + residual — this is the load-bearing correctness gate, and it recomputes the fit from the observations INDEPENDENT of the point-correspondence (a fabricated point is filtered out by the recompute, so it fails sourced while the real observations still recompute — the two gates are isolable) (mirroring the Quality Shift Agent's cusum-consistent and the Provider Benchmarking Agent's stats-consistent) — backed by the guard fitConsistent; and policy.kpi.no-autonomous-commit (signal kpiNoAutonomousCommit, violating value false) blocks a projection that autonomously committed itself as an official forecast, adjusted a quota / target, or notified finance (autoCommitted:true — each is a consequential commercial action that must be authorized) or did not require analyst review (requiresAnalystReview:false) — the agent PROJECTS, and every projection is a RECOMMENDATION requiring a revenue analyst to confirm — backed by the guard noAutonomousCommit (mirroring the Pipeline Management Agent's human-owner posture and the Account Management Agent's never-commit-a-contract posture; the harmful action is enforced-off). It operates ONLY on the commercial CRM plane — it carries NO patient PHI (phiAccessed:false throughout), is NOT on the HIPAA-audit policy, and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/kpi-trend/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — kpi.receive-series → kpi.fit-regression → kpi.classify-trend → kpi.log-audit — with phiAccessed:false, returning the KpiTrendDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new KPI Trend panel (a climbing-adoption preset → rising with a positive slope + high R² projected forward; a constant-metric preset → flat inside the tolerance band; a shrinking-cohort preset → declining projected lower; plus phantom-point / mis-fit-line / auto-committed governance-block presets), a seeded kpi.receive-series→fit-regression→classify-trend→log-audit trace showing the rising case (slope 11, R² 1, trend rising, projection 86, requiresAnalystReview:true, phiAccessed:false), the console subtitle, and the investor brief (now 'ninety-one agents', with the KPI Trend agent on the commercial-operations tier alongside the Pipeline Management and Account Management agents) all reflect it. Menopause-relevant only at the business layer: Pause's own go-to-market tracking provider-org adoption or enrolled-member growth month over month, whose slope + projection this least-squares fit reports for a revenue analyst — with no patient PHI ever touched and no forecast committed on its own. Frontend tests green (3,878 tests — + kpi-trend computeRegression rising / constant-R²-1 / single-point, classifyTrend, rising / flat / declining / determinism, and three-guards-on-produced with phantom-point + dropped-observation + value-mismatch + missing-parameter + sourced-vs-consistent-isolation + mis-fit-slope + fabricated-projection + wrong-trend + mis-computed-residual + auto-committed + skipped-review guard cases, the route's envelope / three governance blocks / rising + flat + declining happy paths with a non-PHI trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to ninety-one agents); the metrics are clearly-labeled illustrative synthetics carrying NO patient PHI — NOT a certified forecasting / FP&A system (real commercial forecasting weighs seasonality, pipeline mix, cohort dynamics, macro conditions, and human judgment — not a single straight line through past points). Lint + build clean.

c54a3c3 agent fabric: add the Commercial KPI Trend & Projection agent (91st) — deterministic ordinary least-squares linear regression that fits a best-fit line to a business-metric series (slope + intercept + R²), classifies the trend, and projects to a future horizon, with every point sourced, a recomputing fit, and never an autonomous forecast commit (commercial CRM plane — no patient PHI)

Agent Fabric: added the Care-Management Capacity Allocation / Outreach Prioritization agent — deterministic 0/1 knapsack dynamic programming that, given a care team's fixed capacity (its outreach hours this cycle) and a set of candidate proactive interventions (each with an hours cost and a projected benefit), selects the max-benefit subset that fits the budget and defers (never denies) the rest, with every selection sourced, a recomputing optimal + feasible allocation, and never an autonomous schedule (the 90th agent)

Shipped
Details

Added the ninetieth agent on the fabric — outreach-prioritization-agent, a DETERMINISTIC (no-Claude) care-coordination / capacity-planning service on the patient / clinical plane, reusing the existing care-coordination tier as a SIBLING to the Caseload Balancing, Population Health, HEDIS Quality, Care Gap, PCP Matching, Reportable Condition, Quality Shift, and Schedule Conflict agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the Quality Shift agent's CUSUM CHANGE-POINT DETECTION, the Timeline Merge agent's K-WAY MERGE OF SORTED STREAMS, the Reportable Condition agent's RECURSIVE BOOLEAN EXPRESSION-TREE EVALUATION, the PCP Matching agent's TWO-SIDED STABLE MATCHING (Gale–Shapley), the Network Adequacy agent's GEOSPATIAL GREAT-CIRCLE DISTANCE, the Identifier Validation agent's MODULAR-ARITHMETIC CHECKSUM, the Household Composition agent's UNION-FIND CONNECTED COMPONENTS, the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS, the MLR Rebate agent's LARGEST-REMAINDER APPORTIONMENT, the Claim Lifecycle agent's FSM TRANSITION VALIDATION, the Medication Name Safety agent's STRING EDIT DISTANCE, the Schedule Conflict agent's GREEDY INTERVAL SELECTION, the Care Pathway agent's TOPOLOGICAL ORDERING, the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, or the Audit Log Integrity agent's HASH CHAIN, and — CRUCIALLY — it is NOT the Caseload Balancing agent's GREEDY BIN-PACKING (which distributes EVERY member across managers' capacities by acuity — a partition where everyone is placed) or the Population Health agent's RISK RANKING (which orders a whole panel; it selects no subset under a budget): the heart of the service is the 0/1 KNAPSACK via DYNAMIC PROGRAMMING — the classic capacity-constrained maximum-value-subset optimization, filling a DP table dp[i][c] = max(dp[i-1][c], dp[i-1][c-cost_i] + benefit_i) and reconstructing the optimal set by walking the table back. In a new pure lib/outreach-prioritization.ts, evaluateOutreachPrioritization(request) takes a care team's fixed CAPACITY for the cycle (its available outreach HOURS this week) and a set of candidate proactive INTERVENTIONS (an HRT-titration call, a DEXA-screening reminder, an SDOH check-in, an education packet — each with an hours COST and a projected clinical BENEFIT) and DETERMINISTICALLY runs the 0/1 knapsack DP to select the subset that MAXIMIZES total projected benefit while fitting the capacity, defers (never denies) the rest, tallies the total cost / benefit + remaining capacity, and derives the disposition: all-scheduled (every candidate fits) or some-deferred. A greedy or hand-picked allocation leaves benefit on the table — patients who could have been reached this cycle are not. It COMPLEMENTS, not duplicates, the other care-coordination agents: distinct from the Caseload Balancing agent (which bin-packs a WHOLE panel across managers), the Population Health agent (which RANKS a panel by risk), and the Care Gap agent (which ACTS on a measure gap) — this selects a max-benefit SUBSET of interventions under a single capacity budget. TIME IS DATA: the allocation is a pure function of the candidates' own costs + benefits + the capacity (no real clock, no randomness), so the same request always yields the same plan. An allocation — all-scheduled or some-deferred — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresCareLeadReview:true, autoScheduled:false), which is how a legitimate allocation is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.outreach.selections-sourced (signal outreachSelectionsSourced, violating value false) blocks an allocation not built from the submitted candidates — every selected AND deferred intervention must trace to a SUBMITTED candidate (same id + cost + benefit; no fabricated intervention), every submitted candidate must appear exactly once across selected ∪ deferred (none dropped, none double-counted, none in both), and the tallies (total cost, total benefit, remaining capacity) must add up — the sourced + completeness gate (mirroring the Caseload Balancing Agent's assignment-complete and the Timeline Merge Agent's events-sourced) — backed by the pure guard selectionsSourced; policy.outreach.allocation-optimal (signal outreachAllocationOptimal, violating value false) blocks a sub-optimal / over-capacity allocation — recomputing the 0/1 knapsack DP over the submitted candidates + capacity must reproduce the reported maximum total benefit, and the reported selection must be FEASIBLE (its cost within capacity) and OPTIMAL (its benefit equals the DP optimum) — this is the load-bearing correctness gate, and it recomputes the optimum from the candidates INDEPENDENT of the selection-correspondence (a fabricated intervention is filtered out by the recompute, so it fails sourced while the real selection still recomputes — the two gates are isolable) (mirroring the Caseload Balancing Agent's capacity-respected and the Quality Shift Agent's cusum-consistent) — backed by the guard allocationOptimal; and policy.outreach.no-autonomous-schedule (signal outreachNoAutonomousSchedule, violating value false) blocks an allocation that autonomously launched the outreach, committed the plan, or booked the interventions (autoScheduled:true — each is a care-delivery action that must be authorized) or did not require care-lead review (requiresCareLeadReview:false) — the agent PRIORITIZES, and every allocation is a RECOMMENDATION requiring a care lead to confirm, with deferred interventions deferred to a later cycle, never denied — backed by the guard noAutonomousSchedule (mirroring the Caseload Balancing Agent's no-autonomous-assignment and the Care Gap Agent's human-review posture; the harmful action is enforced-off). It IS PHI-bearing — the interventions reference patients — so it reuses, by extending appliesTo, the HIPAA-audit policy (phiAccessed:true throughout), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/outreach-prioritization/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — outreach.receive-candidates → outreach.optimize-allocation → outreach.classify-disposition → outreach.log-audit — with phiAccessed:true, returning the OutreachDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Outreach Prioritization panel (a 10-hour-capacity preset → some-deferred with the max-benefit trio scheduled and the SDOH check-in deferred; an ample-capacity preset → all-scheduled; a 5-hour-capacity preset → two deferred; plus phantom-intervention / sub-optimal / auto-scheduled governance-block presets), a seeded outreach.receive-candidates→optimize-allocation→classify-disposition→log-audit trace showing the some-deferred case (selectedCount 3, totalBenefit 140, requiresCareLeadReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'ninety agents', with the Outreach Prioritization agent on the care-coordination tier alongside the Caseload Balancing and Population Health agents) all reflect it. Menopause-relevant: a menopause-care team with a fixed number of outreach hours this week and more high-value proactive touches (HRT-titration calls, DEXA reminders, SDOH check-ins, education) than it can complete is exactly the max-benefit-within-capacity selection this knapsack produces — deferring, never denying, the rest to next cycle, and never dialing a patient on its own. Frontend tests green (3,836 tests — + outreach-prioritization knapsack optimum / all-fit, some-deferred / all-scheduled / two-deferred / determinism, and three-guards-on-produced with phantom-intervention + dropped-candidate + cost-mismatch + miscounted-tally + sourced-vs-optimal-isolation + sub-optimal + over-capacity + auto-scheduled + skipped-review guard cases, the route's envelope / three governance blocks / some-deferred + all-scheduled + tight happy paths with a PHI-bearing trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to ninety agents); the interventions are clearly-labeled illustrative synthetics — NOT a certified care-management / capacity-planning system (real capacity planning weighs clinical urgency, member consent, staffing mix, regulatory timeliness, and equity — not a single benefit score under one hours budget; a deferred intervention is deferred, never denied). Lint + build clean.

c114642 agent fabric: add the Care-Management Capacity Allocation / Outreach Prioritization agent (90th) — deterministic 0/1 knapsack dynamic programming that selects the max-benefit subset of proactive interventions fitting a care team's fixed capacity and defers (never denies) the rest, with every selection sourced, a recomputing optimal + feasible allocation, and never an autonomous schedule

Agent Fabric: added the Clinical Quality-Measure Shift Detection (Statistical Process Control) agent — deterministic change-point detection via a two-sided tabular CUSUM control chart that watches a clinical quality-measure series for a sustained shift away from its target (in-control / shift-up-detected / shift-down-detected), with every point sourced, a recomputing CUSUM, and never an autonomous intervention (the 89th agent)

Shipped
Details

Added the eighty-ninth agent on the fabric — quality-shift-agent, a DETERMINISTIC (no-Claude) care-coordination / quality-analytics service on the patient / clinical plane, reusing the existing care-coordination tier as a SIBLING to the Population Health, HEDIS Quality, Reportable Condition, PCP Matching, and Schedule Conflict agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the Timeline Merge agent's K-WAY MERGE OF SORTED STREAMS, the Reportable Condition agent's RECURSIVE BOOLEAN EXPRESSION-TREE EVALUATION, the PCP Matching agent's TWO-SIDED STABLE MATCHING (Gale–Shapley), the Network Adequacy agent's GEOSPATIAL GREAT-CIRCLE DISTANCE, the Identifier Validation agent's MODULAR-ARITHMETIC CHECKSUM, the Household Composition agent's UNION-FIND CONNECTED COMPONENTS, the MLR Rebate agent's LARGEST-REMAINDER APPORTIONMENT, the Claim Lifecycle agent's FSM TRANSITION VALIDATION, the Medication Name Safety agent's STRING EDIT DISTANCE, the Schedule Conflict agent's GREEDY INTERVAL SELECTION, the Caseload Balancing agent's GREEDY BIN-PACKING, the Care Pathway agent's TOPOLOGICAL ORDERING, the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, or the Audit Log Integrity agent's HASH CHAIN, and — CRUCIALLY — it is NOT the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS (which ranks one value against a static peer distribution; this watches ONE series evolve over time) or the Access Anomaly agent's SLIDING-WINDOW COUNTING (which counts events in a fixed recent window to catch a spike; this accumulates a running deviation to catch a SUSTAINED small shift a window would miss): the heart of the service is CHANGE-POINT DETECTION via a two-sided TABULAR CUSUM (cumulative-sum) control chart. In a new pure lib/quality-shift.ts, evaluateQualityShift(request) takes a time-ordered series of a clinical QUALITY MEASURE (a weekly mammography-screening rate, a monthly HbA1c-control rate, a daily lab-QC value) plus a target, a slack k, and a decision threshold h, and DETERMINISTICALLY accumulates a one-sided upper sum SH_i = max(0, SH_{i-1} + (x_i − target) − k) and a one-sided lower sum SL_i = max(0, SL_{i-1} + (target − x_i) − k), signals the first observation whose SH or SL exceeds h (up wins a tie by documented precedence), and classifies the series as in-control / shift-up-detected / shift-down-detected. A missed shift lets a quality measure decay unnoticed; a false alarm sends a team chasing noise. It COMPLEMENTS, not duplicates, the other quality / clinical agents: distinct from the HEDIS agent (which COMPUTES a measure rate), the Population Health agent (which PRIORITIZES a panel by risk), the Provider Benchmarking agent (which RANKS a value against peers), and the Remote Monitoring agent (which checks ONE patient's vitals against a threshold) — this watches a quality-measure series for a SUSTAINED shift over time. TIME IS DATA: the chart is a pure function of the observations' own values + the parameters (no real clock, no randomness), so the same series always yields the same signal. A signal — in-control / shift-up-detected / shift-down-detected — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresQualityReview:true, autoActioned:false), which is how a legitimate signal is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.quality.observations-sourced (signal qualityObservationsSourced, violating value false) blocks a chart not drawn from the submitted observations — every charted point must trace to a SUBMITTED observation (same index + value; no fabricated point), every submitted observation must appear exactly once (none dropped, none double-charted), and the chart parameters (target, slack, threshold) must be present numbers — the sourced + completeness gate (mirroring the Timeline Merge Agent's events-sourced and the Enrollment Reconciliation Agent's reconciliation-complete) — backed by the pure guard observationsSourced; policy.quality.cusum-consistent (signal qualityCusumConsistent, violating value false) blocks a mis-charted CUSUM — recomputing the two-sided tabular CUSUM from the submitted observations + parameters must reproduce every charted SH_i / SL_i, the first-alarm index, the alarm direction, the signal, and the peak sums — this is the load-bearing correctness gate, and it recomputes the chart from the observations INDEPENDENT of the point-correspondence (a fabricated point is filtered out by the recompute, so it fails sourced while the real points still recompute — the two gates are isolable) (mirroring the Timeline Merge Agent's merge-consistent and the Provider Benchmarking Agent's stats-consistent) — backed by the guard cusumConsistent; and policy.quality.no-autonomous-intervention (signal qualityNoAutonomousIntervention, violating value false) blocks a detection that autonomously launched a corrective action, a recall / outreach campaign, or a process change (autoActioned:true — each is a consequential action that must be authorized) or did not require quality review (requiresQualityReview:false) — the agent DETECTS, and every signal is a RECOMMENDATION requiring a quality reviewer to confirm — backed by the guard noAutonomousIntervention (mirroring the HEDIS Agent's no-autonomous-submission and the Care Gap Agent's human-review posture; the harmful action is enforced-off). It charts DE-IDENTIFIED aggregate rate series, but because the measures are derived from patient clinical data it reuses, by extending appliesTo, the HIPAA-audit policy (phiAccessed:true throughout), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/quality-shift/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — quality.receive-series → quality.run-cusum → quality.classify-signal → quality.log-audit — with phiAccessed:true, returning the QualityShiftDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Quality Shift panel (a climbing-screening-rate preset → shift-up-detected when the upper CUSUM crosses h; a within-band preset → in-control; a falling-control-rate preset → shift-down-detected; plus phantom-point / mis-charted-CUSUM / auto-actioned governance-block presets), a seeded quality.receive-series→run-cusum→classify-signal→log-audit trace showing the shift-up case (signal shift-up-detected, alarmIndex 5, peakHigh 15, requiresQualityReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'eighty-nine agents', with the Quality Shift agent on the care-coordination tier alongside the Population Health and HEDIS agents) all reflect it. Menopause-relevant: a menopause-care program tracking its bone-density-screening or mammography-completion rate week over week, whose sustained downward drift is exactly the sustained shift this CUSUM chart catches before the care gap widens — without ever launching an outreach campaign on its own. Frontend tests green (3,798 tests — + quality-shift computeCusum / shift-up / in-control / shift-down / one-point-per-observation / determinism, and three-guards-on-produced with phantom-point + dropped-observation + value-mismatch + missing-parameter + sourced-vs-consistent-isolation + mis-charted-CUSUM + wrong-signal + wrong-alarm-index + auto-actioned + skipped-review guard cases, the route's envelope / three governance blocks / shift-up + in-control + shift-down happy paths with a PHI-bearing trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to eighty-nine agents); the measures are clearly-labeled illustrative de-identified aggregate rate series — NOT a certified SPC / quality-surveillance platform (real statistical process control tunes k and h to a target ARL, combines CUSUM with Shewhart / EWMA charts, and accounts for autocorrelation and measure specifications). Lint + build clean.

b6e0b3d agent fabric: add the Clinical Quality-Measure Shift Detection (Statistical Process Control) agent (89th) — deterministic change-point detection via a two-sided tabular CUSUM control chart that watches a clinical quality-measure series for a sustained shift, with every point sourced, a recomputing CUSUM, and never an autonomous intervention

Agent Fabric: added the Clinical Event Timeline Merge / Multi-Source Record Reconciliation agent — deterministic k-way merge of sorted streams (the merge-k-sorted-lists / external-sort merge phase) that merges a patient's clinical events from several source streams into one chronological deduplicated timeline (clean-merge / duplicates-found), with every event sourced, a recomputing merge order + dedup, and never an autonomous write-back (the 88th agent)

Shipped
Details

Added the eighty-eighth agent on the fabric — timeline-merge-agent, a DETERMINISTIC (no-Claude) data-substrate / record-reconciliation service on the platform & data-substrate plane, reusing the existing data-plane tier as a SIBLING to the Master Patient Index, Provider-Identifier (NPI) Validation, Consent & Preferences, Break-the-Glass, and Audit-Log-Integrity agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the Reportable Condition agent's RECURSIVE BOOLEAN EXPRESSION-TREE EVALUATION, the PCP Matching agent's TWO-SIDED STABLE MATCHING (Gale–Shapley), the Network Adequacy agent's GEOSPATIAL GREAT-CIRCLE DISTANCE, the Identifier Validation agent's MODULAR-ARITHMETIC CHECKSUM, the Household Composition agent's UNION-FIND CONNECTED COMPONENTS, the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS, the MLR Rebate agent's LARGEST-REMAINDER APPORTIONMENT, the Claim Lifecycle agent's FSM TRANSITION VALIDATION, the Medication Name Safety agent's STRING EDIT DISTANCE, the Schedule Conflict agent's GREEDY INTERVAL SELECTION, the Caseload Balancing agent's GREEDY BIN-PACKING, the Access Anomaly agent's SLIDING-WINDOW COUNTING, the Care Pathway agent's TOPOLOGICAL ORDERING, the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, or the Audit Log Integrity agent's HASH CHAIN, and — CRUCIALLY — it is NOT the Coverage Continuity agent's INTERVAL MERGING (which merges OVERLAPPING date SPANS into continuous coverage; this merges POINT events from many streams into one order) or the Master-Patient-Index agent's WEIGHTED identity MATCHING (which resolves WHO a record belongs to; this runs AFTER identity is known): the heart of the service is the K-WAY MERGE OF SORTED STREAMS — the classic 'merge k sorted lists' / external-sort merge phase that repeatedly takes the earliest head across the k stream cursors to produce one globally-ordered sequence in linear time, plus a content-key DEDUPLICATION pass. In a new pure lib/timeline-merge.ts, evaluateTimelineMerge(request) takes a patient's clinical EVENTS as they arrive in several already-sorted source STREAMS (an EHR, another EHR, a pharmacy, a claims feed — each stream in ascending time order) and DETERMINISTICALLY k-way merges them into one chronologically-ordered unified TIMELINE (ties broken by source then eventId), flags the DUPLICATES (the second-and-later report of the same clinical event, by content key), tallies the per-source contributions, and derives the disposition: clean-merge (no duplicates) or duplicates-found. A mis-ordered timeline hides a trend and a mis-flagged duplicate fakes a double dose. It COMPLEMENTS, not duplicates, the other data / provider agents: distinct from the Master Patient Index agent (which RESOLVES identity across systems), the Enrollment Reconciliation agent (a keyed set-difference between two rosters), and the Transitions of Care agent (medication reconciliation for ONE encounter) — this MERGES a patient's already-resolved event streams into one timeline. TIME IS DATA: the timeline is a pure function of the streams' own timestamps (no real clock, no randomness), so the same streams always yield the same timeline. A merge — clean-merge or duplicates-found — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresStewardReview:true, autoWritten:false), which is how a legitimate merge is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.timeline.events-sourced (signal timelineEventsSourced, violating value false) blocks a timeline not built from the submitted streams — every entry must trace to a SUBMITTED stream event (same source + eventId + timestamp + kind; no fabricated event), every submitted event must appear exactly once (none dropped, none double-listed), and the per-source contributions + tallies must add up — the sourced + completeness gate (mirroring the Enrollment Reconciliation Agent's reconciliation-complete and the Caseload Balancing Agent's assignment-complete) — backed by the pure guard eventsSourced; policy.timeline.merge-consistent (signal timelineMergeConsistent, violating value false) blocks a mis-ordered / mis-deduplicated timeline — recomputing the k-way merge from the submitted streams must reproduce the reported chronological order and duplicate flags (timestamps non-decreasing) — this is the load-bearing correctness gate, and it recomputes the merge from the streams INDEPENDENT of the submitted-event correspondence (a phantom entry is filtered out by the recompute, so a fabricated event fails sourced while the real events still recompute — the two gates are isolable) (mirroring the Reportable Condition Agent's classification-consistent and the Care Pathway Agent's sequence-valid) — backed by the guard mergeConsistent; and policy.timeline.no-autonomous-merge (signal timelineNoAutonomousMerge, violating value false) blocks a merge that autonomously wrote the timeline back to a source of record, purged a duplicate, or overwrote a chart (autoWritten:true — each is a data-integrity action that must be authorized) or did not require steward review (requiresStewardReview:false) — the agent MERGES, and every merge is a RECOMMENDATION requiring a data steward to confirm — backed by the guard noAutonomousMerge (mirroring the Enrollment Reconciliation Agent's no-autonomous-change and the Audit Log Integrity Agent's read-only posture; the harmful action is enforced-off). It IS PHI-bearing — the events are a patient's clinical data — so it reuses, by extending appliesTo, the HIPAA-audit policy (phiAccessed:true throughout), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/timeline-merge/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — timeline.receive-streams → timeline.merge-streams → timeline.classify-disposition → timeline.log-audit — with phiAccessed:true, returning the TimelineMergeDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Timeline Merge panel (a three-stream two-duplicate preset → duplicates-found with the duplicate visit + lab flagged; a distinct-events preset → clean-merge across two sources; a single-ordered-stream preset → clean-merge; plus phantom-event / out-of-order / auto-written governance-block presets), a seeded timeline.receive-streams→merge-streams→classify-disposition→log-audit trace showing the duplicates-found case (keptCount 4, duplicateCount 2, requiresStewardReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'eighty-eight agents', with the Timeline Merge agent on the data-plane tier alongside the Master Patient Index and the other data-substrate agents) all reflect it. Menopause-relevant: a 45-64 woman whose records are scattered across her gynecologist's EHR, a hospital, a pharmacy, and a claims feed — the same HRT start reported by two of them — is exactly the multi-source timeline this k-way merge unifies and de-duplicates for her care team, without ever overwriting a source chart on its own. Frontend tests green (3,759 tests — + timeline-merge kWayMerge / dedupKeyOf / duplicates-found / clean-merge / single-stream / determinism / per-source-tallies, and three-guards-on-produced with phantom-event + dropped-event + timestamp-mismatch + source-miscount + sourced-vs-consistent-isolation + out-of-order + wrong-dedup-flag + auto-written + skipped-review guard cases, the route's envelope / three governance blocks / duplicates-found + clean-merge + single-stream happy paths with a PHI-bearing trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to eighty-eight agents); the event streams are clearly-labeled illustrative synthetics — NOT a certified record-reconciliation / EMPI system (real reconciliation resolves identity first via an EMPI, reconciles with FHIR resource provenance, and applies source-of-truth precedence rules). Lint + build clean.

8623171 agent fabric: add the Clinical Event Timeline Merge / Multi-Source Record Reconciliation agent (88th) — deterministic k-way merge of sorted streams that merges a patient's clinical events from several source streams into one chronological deduplicated timeline, with every event sourced, a recomputing merge order + dedup, and never an autonomous write-back

Agent Fabric: added the Reportable / Notifiable Condition Case Classification agent — deterministic recursive boolean expression-tree evaluation (a nested all-of / any-of / not case-definition tree over the case's facts) that classifies a patient case as confirmed / probable / suspect / not-a-case, with every criterion sourced, a recomputing classification, and never an autonomous public-health report (the 87th agent)

Shipped
Details

Added the eighty-seventh agent on the fabric — reportable-condition-agent, a DETERMINISTIC (no-Claude) care-coordination / public-health-compliance service on the patient / clinical plane, reusing the existing care-coordination tier as a SIBLING to the PCP Matching, Caseload Balancing, Care Team & Case Management, Schedule Conflict, and Population Health agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the PCP Matching agent's TWO-SIDED STABLE MATCHING (Gale–Shapley), the Network Adequacy agent's GEOSPATIAL GREAT-CIRCLE DISTANCE, the Identifier Validation agent's MODULAR-ARITHMETIC CHECKSUM, the Household Composition agent's UNION-FIND CONNECTED COMPONENTS, the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS, the MLR Rebate agent's LARGEST-REMAINDER APPORTIONMENT, the Claim Lifecycle agent's FSM TRANSITION VALIDATION, the Medication Name Safety agent's STRING EDIT DISTANCE, the Schedule Conflict agent's GREEDY INTERVAL SELECTION, the Caseload Balancing agent's GREEDY BIN-PACKING, the Access Anomaly agent's SLIDING-WINDOW COUNTING, the Coverage Continuity agent's INTERVAL MERGING, the Care Pathway agent's TOPOLOGICAL ORDERING, the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, or the Audit Log Integrity agent's HASH CHAIN: the heart of the service is RECURSIVE BOOLEAN EXPRESSION-TREE EVALUATION — the recursive walk of a nested all-of (AND) / any-of (OR) / not (NOT) tree whose leaves are predicates over the case's facts, the exact shape a public-health case definition takes ('confirmed = lab-positive OR (clinically-compatible AND epi-linked)'). In a new pure lib/reportable-condition.ts, evaluateReportableCase(request) takes a patient CASE's structured facts plus a CASE DEFINITION (an ordered, highest-precedence-first list of classifications — confirmed / probable / suspect — each a nested criteria tree) and DETERMINISTICALLY evaluates each classification's tree recursively (a leaf is its fact's value, not negates, all-of is AND, any-of is OR), selects the highest-precedence classification whose tree holds (else not-a-case), and derives the reportable flag. A mis-evaluated tree over-reports a notifiable condition (a false alarm to public health) or under-reports it (a missed case). It COMPLEMENTS, not duplicates, the other compliance / clinical agents: distinct from the Adverse-Event Reporting agent (which DRAFTS a MedWatch / VAERS report for a drug / vaccine event), the Utilization Review agent (medical-necessity criteria for a service), and the Lab Result agent (a single analyte vs a reference range) — this classifies a case against a nested public-health CASE DEFINITION. TIME IS DATA: the classification is a pure function of the request's own facts + definition (no real clock, no randomness), so the same case always yields the same classification. A classification — confirmed / probable / suspect / not-a-case — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresEpiReview:true, autoReported:false), which is how a legitimate classification is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + boolean signal wired into the shared governance-signals metadata: policy.reportable.facts-sourced (signal caseFactsSourced, violating value false) blocks a classification not built from the submitted definition + facts — every leaf predicate must reference a SUBMITTED fact (no fabricated criterion inventing a requirement the definition never stated), the reported classification results must be exactly the definition's classifications in order, the referenced-fact set must match the definition's actual leaves, and the reported classification must be a defined one (or not-a-case) — the sourced + completeness gate (mirroring the PCP Matching Agent's matching-sourced and the Network Adequacy Agent's providers-sourced) — backed by the pure guard factsSourced; policy.reportable.classification-consistent (signal classificationConsistent, violating value false) blocks a mis-evaluated tree — recomputing the recursive boolean evaluation of each classification's criteria tree from the facts must reproduce each reported met flag, the selected classification (highest-precedence met tree, else not-a-case), and the reportable flag — this is the load-bearing correctness gate, and it recomputes the boolean recursion from the definition + facts INDEPENDENT of the submitted-fact correspondence (a phantom classification result is ignored by the recompute — scoped to the definition's classifications by name — so a fabricated result fails sourced while the real classifications still recompute, the two gates are isolable) (mirroring the PCP Matching Agent's matching-stable and the Care Pathway Agent's sequence-valid) — backed by the guard classificationConsistent; and policy.reportable.no-autonomous-report (signal noAutonomousReport, violating value false) blocks a classification that autonomously reported the case to a public-health authority (autoReported:true — a consequential legal action that must be authorized) or did not require epidemiologist review (requiresEpiReview:false) — the agent CLASSIFIES, and every classification is a RECOMMENDATION requiring an epidemiologist / infection-preventionist to confirm before any report is filed — backed by the guard noAutonomousReport (mirroring the Adverse-Event Reporting Agent's human-review posture and the HEDIS Agent's no-autonomous-submission; the harmful action is enforced-off). It IS PHI-bearing — the case is a patient's clinical data — so it reuses, by extending appliesTo, the HIPAA-audit policy (phiAccessed:true throughout), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/reportable-condition/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — rc.receive-case → rc.evaluate-criteria → rc.classify → rc.log-audit — with phiAccessed:true, returning the ReportableCaseDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Reportable Condition panel (a lab-positive-not-chronic preset → confirmed via (lab-positive OR antigen) AND NOT chronic; a clinical-plus-epi-linked preset → probable when no confirmed tree holds; a nothing-holds preset → not-a-case; plus phantom-classification / mis-evaluated-tree / auto-reported governance-block presets), a seeded rc.receive-case→evaluate-criteria→classify→log-audit trace showing the confirmed case (classification confirmed, reportable:true, requiresEpiReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'eighty-seven agents', with the Reportable Condition agent on the care-coordination tier alongside the PCP Matching and the other care-coordination agents) all reflect it. Menopause-relevant: a 45-64 woman presenting with an acute illness during a menopause-care encounter whose labs + clinical picture must be evaluated against a jurisdiction's notifiable-condition case definition is exactly the classification this recursive boolean tree produces — without ever filing a public-health report on its own. Frontend tests green (3,719 tests — + reportable-condition evaluateNode leaf / not / all-of / any-of / empty / nested recursion, referencedFactsOf, confirmed / probable / not-a-case / echo / determinism, and three-guards-on-produced with phantom-classification + fabricated-criterion + wrong-referenced-facts + sourced-vs-consistent-isolation + mis-evaluated-flag + wrong-precedence + wrong-reportable + auto-reported + skipped-review guard cases, the route's envelope / three governance blocks / confirmed + probable + not-a-case happy paths with a PHI-bearing trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to eighty-seven agents); the condition + definition + facts are clearly-labeled illustrative synthetics — NOT a certified surveillance / case-reporting system (real notifiable-condition reporting uses the jurisdiction's official CSTE / CDC case definitions, eCR / eICR electronic case reporting, and an epidemiologist's judgment). Lint + build clean.

b3def12 agent fabric: add the Reportable / Notifiable Condition Case Classification agent (87th) — deterministic recursive boolean expression-tree evaluation (a nested all-of / any-of / not case-definition tree) that classifies a patient case as confirmed / probable / suspect / not-a-case, with every criterion sourced, a recomputing classification, and never an autonomous public-health report

Agent Fabric: added the Primary Care Provider (PCP) Assignment / Member–Provider Matching agent — deterministic two-sided stable matching (the member-proposing Gale–Shapley deferred-acceptance algorithm) that assigns a panel of members to primary care providers with no blocking pair (all-matched / partial-match), with every assignment sourced, a stable recompute, and never an autonomous commit (the 86th agent)

Shipped
Details

Added the eighty-sixth agent on the fabric — pcp-matching-agent, a DETERMINISTIC (no-Claude) care-coordination service on the patient / clinical plane, reusing the existing care-coordination tier as a SIBLING to the Caseload Balancing, Care Team & Case Management, Schedule Conflict, and Population Health agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the Network Adequacy agent's GEOSPATIAL GREAT-CIRCLE DISTANCE, the Identifier Validation agent's MODULAR-ARITHMETIC CHECKSUM, the Household Composition agent's UNION-FIND CONNECTED COMPONENTS, the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS, the Master-Patient-Index agent's WEIGHTED identity MATCHING, the MLR Rebate agent's LARGEST-REMAINDER APPORTIONMENT, the Claim Lifecycle agent's FSM TRANSITION VALIDATION, the Medication Name Safety agent's STRING EDIT DISTANCE, the Schedule Conflict agent's GREEDY INTERVAL SELECTION, the Access Anomaly agent's SLIDING-WINDOW COUNTING, the Coverage Continuity agent's INTERVAL MERGING, the Care Pathway agent's TOPOLOGICAL ORDERING, the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, or the Audit Log Integrity agent's HASH CHAIN, and — CRUCIALLY — it is NOT the Caseload Balancing agent's GREEDY BIN-PACKING (which allocates a panel across managers' capacity by acuity, with NO preferences and NO stability guarantee): the heart of the service is TWO-SIDED STABLE MATCHING — the member-proposing Gale–Shapley DEFERRED-ACCEPTANCE algorithm (the many-to-one 'hospitals/residents' variant). In a new pure lib/pcp-matching.ts, evaluatePcpMatching(request) takes a panel of unassigned MEMBERS (each with a ranked list of preferred primary care providers) plus a set of PROVIDERS (each with a panel CAPACITY and a ranked list of the members it would accept) and DETERMINISTICALLY runs the member-proposing deferred acceptance — free members propose down their lists in id order, each provider tentatively holds up to its capacity of its most-preferred acceptable proposers and rejects the rest, rejected members propose on — terminating at the member-optimal STABLE matching (the unique assignment with no blocking pair), recording one assignment per member (with the member's 1-based preference rank), the provider loads, and the disposition: all-matched (every member matched to a preferred provider) or partial-match (some members unmatched — capacity exhausted or short preference lists). A matching that leaves a member and a provider who each prefer the other over their current lot (a BLOCKING pair) is UNSTABLE — it unravels as the pair defects, leaving a patient without a real PCP. It COMPLEMENTS, not duplicates, the other care-coordination agents: distinct from the Caseload Balancing agent (which BIN-PACKS a panel across managers' capacity to balance load, no preferences), the Care Team & Case Management agent (the multi-disciplinary team around ONE patient), the Transitions of Care agent (moving ONE patient), and the Population Health agent (prioritizing a panel) — this produces a STABLE two-sided matching of members to primary care providers. TIME IS DATA: the matching is a pure function of the request's own preferences + capacities (no real clock, no randomness; the free members propose in a deterministic id order), so the same panel always yields the same matching. A matching — all-matched or partial-match — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresCoordinatorReview:true, autoAssigned:false), which is how a legitimate matching is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.pcp.matching-sourced (signal matchingSourced, violating value false) blocks a matching not built from the submitted panel — one assignment per SUBMITTED member (all present, none dropped or invented), every assigned provider a SUBMITTED provider, the provider loads echoing the submitted capacities + actual assignment counts, and the matched / unmatched / total tallies agreeing — the sourced + completeness gate (mirroring the Network Adequacy Agent's providers-sourced and the Caseload Balancing Agent's assignment-complete) — backed by the pure guard matchingSourced; policy.pcp.matching-stable (signal matchingStable, violating value false) blocks an unstable / mis-recomputed matching — recomputing the Gale–Shapley deferred acceptance from the echoed preferences + capacities must reproduce the reported assignment + each member's preference rank, no provider may be over capacity, and there must be NO blocking pair — this is the load-bearing correctness gate, and it recomputes the matching from the preferences INDEPENDENT of the submitted-list↔assignment correspondence (a phantom member is ignored by the recompute, so a fabricated assignment fails sourced while the real members still recompute stably — the two gates are isolable) (mirroring the Network Adequacy Agent's distances-consistent and the Household Composition Agent's partition-consistent) — backed by the guard matchingStable (with a hasBlockingPair helper that directly checks capacity + blocking pairs); and policy.pcp.no-autonomous-assignment (signal pcpNoAutonomousAssignment, violating value false) blocks a matching that autonomously committed an assignment, reassigned a patient, or overrode a provider's panel (autoAssigned:true — each is a care-ownership decision that must be authorized) or did not require coordinator review (requiresCoordinatorReview:false) — the agent PROPOSES a matching, and every matching is a RECOMMENDATION requiring a care-coordination lead to confirm — backed by the guard noAutonomousAssignment (mirroring the Caseload Balancing Agent's and the Care Team Agent's no-autonomous-assignment posture; the harmful action is enforced-off). It IS PHI-bearing — the members are patients — so it reuses, by extending appliesTo, the HIPAA-audit policy (phiAccessed:true throughout), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/pcp-matching/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — pcp.receive-panel → pcp.run-deferred-acceptance → pcp.classify-disposition → pcp.log-audit — with phiAccessed:true, returning the PcpMatchingDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new PCP Matching panel (an interlocking-preferences preset → a stable all-matched result m1→p2 / m2→p1 / m3→p3; a capacity-exhausted preset → a stable partial-match leaving one member unmatched; a capacity-2 preset → a provider whose panel of two absorbs two members; plus phantom-member / unstable-matching / auto-assigned governance-block presets), a seeded pcp.receive-panel→run-deferred-acceptance→classify-disposition→log-audit trace showing the all-matched case (matchedCount 3, unmatchedCount 0, requiresCoordinatorReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'eighty-six agents', with the PCP Matching agent on the care-coordination tier alongside the Caseload Balancing and the other care-coordination agents) all reflect it. Menopause-relevant: a 45-64 woman newly enrolling who ranks the in-network gynecologists and internists she'd accept as her PCP, matched against those providers' panel capacities, is exactly the stable assignment this Gale–Shapley matching produces — without ever committing her to a panel on its own. Frontend tests green (3,678 tests — + pcp-matching deferred-acceptance / capacity-exhausted / capacity-2 plus all-matched / partial-match / provider-loads / member+provider-echo / determinism, hasBlockingPair stable / blocking-pair / over-capacity, and three-guards-on-produced with phantom-member + provider-load-miscount + off-network-provider + sourced-vs-stable-isolation + unstable-blocking-pair + wrong-rank + wrong-disposition + auto-assigned + skipped-review guard cases, the route's envelope / three governance blocks / all-matched + partial-match + capacity-2 happy paths with a PHI-bearing trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to eighty-six agents); the members + providers + preferences + capacities are clearly-labeled illustrative synthetics, NOT a certified panel-management system — real PCP assignment also weighs geography, language, continuity of care, plan-network rules, and member choice, and runs against a live attribution system. Lint + build clean.

81c3918 agent fabric: add the Primary Care Provider (PCP) Assignment / Member–Provider Matching agent (86th) — deterministic two-sided stable matching (the member-proposing Gale–Shapley deferred acceptance) that assigns a panel of members to PCPs with no blocking pair, with every assignment sourced, a stable recompute, and never an autonomous commit

Agent Fabric: added the Network Adequacy / Time-and-Distance agent — deterministic geospatial great-circle (haversine) distance + nearest-neighbor scan + threshold that decides whether a plan's in-network providers meet a required specialty's time-and-distance adequacy standard (adequacy-met / adequacy-gap), with every provider sourced, exact recomputed distances, and never an autonomous certification (the 85th agent)

Shipped
Details

Added the eighty-fifth agent on the fabric — network-adequacy-agent, a DETERMINISTIC (no-Claude) claims / payer-operations service on the payer & plan operations plane, reusing the existing payer-operations tier as a SIBLING to the Enrollment Reconciliation, Coordination of Benefits, Member Cost-Share, Household Composition, and Claim Lifecycle agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the Identifier Validation agent's MODULAR-ARITHMETIC CHECKSUM (the NPI Luhn check digit), the Household Composition agent's UNION-FIND / DISJOINT-SET CONNECTED COMPONENTS, the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS, the Master-Patient-Index agent's WEIGHTED identity MATCHING, the Claim Lifecycle agent's FSM TRANSITION VALIDATION, the Medication Name Safety agent's STRING EDIT DISTANCE, the Schedule Conflict agent's GREEDY INTERVAL SELECTION, the Caseload Balancing agent's GREEDY BIN-PACKING, the Access Anomaly agent's SLIDING-WINDOW COUNTING, the Coverage Continuity agent's INTERVAL MERGING, the Care Pathway agent's TOPOLOGICAL ORDERING, the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, or the Audit Log Integrity agent's HASH CHAIN: the heart of the service is GEOSPATIAL GREAT-CIRCLE DISTANCE — the haversine formula that converts two (latitude, longitude) pairs into a distance in miles, plus a NEAREST-NEIGHBOR scan and a THRESHOLD comparison against the regulatory standard. In a new pure lib/network-adequacy.ts, evaluateNetworkAdequacy(request) takes a MEMBER's location plus the plan's IN-NETWORK PROVIDERS (each with a specialty + coordinates) and a required specialty + a time-and-distance standard (miles), and DETERMINISTICALLY filters the providers to the required specialty, computes the haversine great-circle distance from the member to each, sorts ascending (with a stable providerId tie-break), takes the NEAREST, and derives the disposition: adequacy-met (a nearest in-network provider within the standard) or adequacy-gap (the nearest exceeds the standard, or there is NO in-network provider of that specialty at all — a null nearest). A member with no in-network specialist within the standard distance has a network-adequacy GAP — both a compliance failure (CMS 42 CFR 422.116 / state QHP time-and-distance standards) and an access-to-care failure. It COMPLEMENTS, not duplicates, the other provider / network agents: distinct from the Provider Credentialing agent (whether a provider is QUALIFIED and in the directory), the Referral Management agent (routing a specific referral), and the Provider Benchmarking agent (a provider's cost / quality percentile) — this measures whether the network is geographically ADEQUATE. TIME IS DATA: the finding is a pure function of the request's own coordinates + standard (no real clock, no randomness), so the same request always yields the same result. A finding — adequacy-met or adequacy-gap — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresNetworkReview:true, autoCertified:false), which is how a legitimate finding is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.adequacy.providers-sourced (signal providersSourced, violating value false) blocks a finding not built from the submitted in-network providers — every evaluated provider must be a SUBMITTED one (same id + coordinates + the required specialty; no PHANTOM provider fabricating coverage that isn't in the network), every submitted provider of that specialty must be evaluated (none dropped), the counts must agree, and the nearest must be one of the evaluated — the sourced + completeness gate (mirroring the Identifier Validation Agent's identifiers-sourced and the Household Composition Agent's links-sourced) — backed by the pure guard providersSourced; policy.adequacy.distances-consistent (signal distancesConsistent, violating value false) blocks a finding whose distances do not recompute — recomputing the haversine distance from the member to each evaluated provider's OWN coordinates must reproduce every reported distance, the ascending order, the nearest, the nearest distance, and the adequacy disposition against the standard; a mis-measured distance understates a gap (falsely certifying adequacy so a member can't reach care) or overstates one — this is the load-bearing correctness gate, and it recomputes the geometry from the evaluated rows' coordinates INDEPENDENT of the providers↔evaluated correspondence (a phantom provider's coordinates recompute self-consistently, so a fabricated provider fails sourced while the distances still recompute — the two gates are isolable) (mirroring the Medication Name Safety Agent's distances-consistent and the Provider Benchmarking Agent's stats-consistent) — backed by the guard distancesConsistent; and policy.adequacy.no-autonomous-network-change (signal noAutonomousNetworkChange, violating value false) blocks a finding that autonomously certified the network as adequate to a regulator, closed a gap, or added / removed a provider (autoCertified:true — each is a consequential action that must be authorized) or did not require network review (requiresNetworkReview:false) — the agent ASSESSES adequacy, and every finding is a RECOMMENDATION requiring a network manager to confirm — backed by the guard noAutonomousNetworkChange (mirroring the Provider Benchmarking Agent's no-autonomous-tiering and the Provider Credentialing Agent's no-referral-to-expired-or-sanctioned posture; the harmful action is enforced-off). It IS PHI-bearing — the member's location + the specialty they need is health information — so it reuses, by extending appliesTo, the HIPAA-audit policy (phiAccessed:true throughout), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/network-adequacy/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — adequacy.receive-request → adequacy.compute-distances → adequacy.classify-disposition → adequacy.log-audit — with phiAccessed:true, returning the NetworkAdequacyDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Network Adequacy panel (a cardiology-within-10-mi preset → adequacy-met with the nearest of two cardiologists 0.54 mi away; an endocrinology-too-far preset → adequacy-gap with both endocrinologists beyond the 10 mi standard; a no-in-network-specialist preset → adequacy-gap with a null nearest; plus phantom-provider / mis-measured-distance / auto-certified governance-block presets), a seeded adequacy.receive-request→compute-distances→classify-disposition→log-audit trace showing the endocrinology gap (matchingProviderCount 2, nearest 16.44 mi, adequacy-gap, requiresNetworkReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'eighty-five agents', with the Network Adequacy agent on the payer-operations tier alongside the Household Composition and the other member / enrollment agents) all reflect it. Menopause-relevant: a 45-64 woman who needs an in-network gynecologist or endocrinologist for menopause care but whose nearest one is 30 miles away has exactly the network-adequacy gap this haversine distance surfaces to a network manager — without ever certifying the network as adequate on its own. Frontend tests green (3,635 tests — + network-adequacy haversine zero / known-distance / symmetry plus adequacy-met / ascending-sort / adequacy-gap / no-provider-null-nearest / member+provider-echo / determinism and three-guards-on-produced with phantom-provider + dropped-provider + count-mismatch + sourced-vs-consistent-isolation + mis-measured-distance + wrong-disposition + wrong-nearest + phantom-geometry-isolation + auto-certified + skipped-review guard cases, the route's envelope / three governance blocks / adequacy-met + adequacy-gap + no-provider happy paths with a PHI-bearing trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to eighty-five agents); the member + providers + coordinates are clearly-labeled illustrative synthetics, computing STRAIGHT-LINE great-circle distance only — NOT drive time / road distance, and NOT the full CMS / state ratio, county-designation, provider-capacity, or telehealth rules — NOT a certified network-adequacy engine. Lint + build clean.

8733f90 agent fabric: add the Network Adequacy / Time-and-Distance agent (85th) — deterministic geospatial great-circle (haversine) distance + nearest-neighbor + threshold that decides whether a plan's in-network providers meet a specialty's time-and-distance adequacy standard, with every provider sourced, exact recomputed distances, and never an autonomous certification

Agent Fabric: added the Provider Identifier (NPI) Validation & Integrity agent — deterministic modular-arithmetic checksum (the CMS/NPI Luhn mod-10 check digit over the 80840 prefix + the 9-digit base) that validates a batch of NPIs as valid / invalid-format / invalid-checksum, with every result sourced, an exact recomputed check digit, and never an autonomous reject (the 84th agent)

Shipped
Details

Added the eighty-fourth agent on the fabric — identifier-validation-agent, a DETERMINISTIC (no-Claude) platform / data-substrate integrity service on the platform & data substrate plane, reusing the existing data-plane tier as a SIBLING to the Master Patient Index, Break-the-Glass, De-Identification, Minimum-Necessary, and Audit Log Integrity agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the Household Composition agent's UNION-FIND / DISJOINT-SET CONNECTED COMPONENTS, the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS, the Master-Patient-Index agent's WEIGHTED identity MATCHING, the Claim Lifecycle agent's FSM TRANSITION VALIDATION, the Medication Name Safety agent's STRING EDIT DISTANCE, the Schedule Conflict agent's GREEDY INTERVAL SELECTION, the Caseload Balancing agent's GREEDY BIN-PACKING, the Access Anomaly agent's SLIDING-WINDOW COUNTING, the Coverage Continuity agent's INTERVAL MERGING, the Care Pathway agent's TOPOLOGICAL ORDERING, the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, the Member Cost-Share agent's SEQUENTIAL dollar waterfall, the DDI agent's PAIRWISE KNOWLEDGE-BASE LOOKUP, or the Audit Log Integrity agent's HASH CHAIN: the heart of the service is a MODULAR-ARITHMETIC CHECKSUM — the Luhn (mod-10) check-digit computation the NPI standard uses. In a new pure lib/identifier-validation.ts, evaluateIdentifierValidation(request) takes a batch of National Provider Identifiers and DETERMINISTICALLY validates each one: the format (exactly 10 decimal digits beginning with 1 or 2) and the check digit — the 10th digit must equal the Luhn checksum recomputed over the '80840' ISO issuer prefix + the first 9 digits (doubling every second digit from the right, summing, and taking (10 − sum mod 10) mod 10) — classifying each as valid, invalid-format, or invalid-checksum (a well-formed NPI whose 10th digit does not match the recomputed check digit — a likely transposition / typo), tallying the per-kind counts, and deriving the batch disposition: all-valid or invalids-flagged. An NPI with a transposed or mistyped digit fails the checksum; catching it before it lands on a claim or in a provider directory prevents a claim rejection or a ghost-directory entry. It COMPLEMENTS, not duplicates, the other provider-data agents: distinct from the Provider Credentialing agent (which cites an npi-registry as a verification SOURCE but does not validate the check digit) and the OIG Exclusion agent (which MATCHES an NPI against the sanctions list) — this validates that the NPI itself is well-formed and its check digit is correct. TIME IS DATA: the finding is a pure function of the request's own identifiers (no real clock, no randomness), so the same batch always yields the same result. A finding — all-valid or invalids-flagged — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresStewardReview:true, autoRejected:false), which is how a legitimate finding is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.identifier.identifiers-sourced (signal identifiersSourced, violating value false) blocks a finding not built from the submitted batch — there must be one result per submitted identifier (same NPI, same order; no fabricated result, no dropped identifier), the reported total must equal the identifier count, the per-kind counts must sum to the total, and the batch disposition must follow — the sourced + completeness gate (mirroring the Household Composition Agent's links-sourced and the Enrollment Reconciliation Agent's reconciliation-complete) — backed by the pure guard identifiersSourced; policy.identifier.checksum-consistent (signal checksumConsistent, violating value false) blocks a finding whose checksums do not recompute — recomputing each identifier's format classification and Luhn check digit from the NPI itself must reproduce the reported disposition, expected check digit, and per-kind counts; a miscomputed checksum waves through a mistyped NPI or fails a correct one — this is the load-bearing correctness gate, and it recomputes each result from its own NPI INDEPENDENT of the identifiers↔results correspondence (a fabricated extra result recomputes self-consistently, so it fails sourced while the checksums still recompute — the two gates are isolable) (mirroring the Provider Benchmarking Agent's stats-consistent and the OIG Exclusion Agent's match-not-overstated) — backed by the guard checksumConsistent; and policy.identifier.no-autonomous-reject (signal identifierNoAutonomousReject, violating value false) blocks a finding that autonomously rejected a claim, removed a provider from the directory, or corrected a number (autoRejected:true — each is a consequential action that must be authorized) or did not require steward review (requiresStewardReview:false) — the agent VALIDATES and FLAGS, and every finding is a RECOMMENDATION requiring a data steward to confirm — backed by the guard identifierNoAutonomousReject (mirroring the Provider Credentialing Agent's no-referral-to-expired-or-sanctioned and the Enrollment Reconciliation Agent's no-autonomous-change posture; the harmful action is enforced-off). It is DELIBERATELY NOT PHI-bearing — an NPI is a PROVIDER identifier, not patient health information — so, like the OIG Exclusion agent, it is NOT on the HIPAA-audit policy (phiAccessed:false throughout); it is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/identifier-validation/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — identifier.receive-batch → identifier.validate-checksums → identifier.classify-disposition → identifier.log-audit — with NO phiAccessed marker, returning the IdentifierValidationDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Identifier Validation panel (a 3-NPI preset → 1 valid, 1 transposed (invalid-checksum), 1 malformed (invalid-format); an all-valid preset → 3 well-formed NPIs with correct check digits; a single-malformed preset → invalid-format on a leading-3 NPI; plus fabricated-identifier / miscomputed-checksum / auto-rejected governance-block presets), a seeded identifier.receive-batch→validate-checksums→classify-disposition→log-audit trace showing the mixed batch (validCount 1, invalidFormatCount 1, invalidChecksumCount 1, requiresStewardReview:true, NOT PHI), the console subtitle, and the investor brief (now 'eighty-four agents', with the Identifier Validation agent on the data-plane tier alongside the Master Patient Index and the other platform agents) all reflect it. Menopause-relevant: the gynecologists, endocrinologists, and compounding pharmacies a menopause plan pays each carry an NPI on every claim and directory entry — a single transposed digit is exactly what this checksum catches before it becomes a claim rejection or a ghost-directory listing that keeps a patient from finding a specialist. Frontend tests green (3,592 tests — + identifier-validation check-digit / mixed-batch / all-valid / single-malformed / non-digit / leading-digit-range / 2-prefix / empty-batch / identifier-echo / determinism plus three-guards-on-produced with fabricated-result + counts-don't-sum + disposition-mismatch + result-npi-mismatch + reported-as-valid + wrong-counts + sourced-vs-consistent-isolation + auto-rejected + skipped-review guard cases, the route's envelope / three governance blocks / invalids-flagged + all-valid + single-malformed happy paths with a NOT-PHI trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to eighty-four agents); the identifiers are clearly-labeled illustrative synthetics, and this validates STRUCTURE + check digit only — it does NOT confirm the NPI is assigned, active, or belongs to a particular provider (that requires an NPPES / registry lookup). Lint + build clean.

91396fe agent fabric: add the Provider Identifier (NPI) Validation & Integrity agent (84th) — deterministic modular-arithmetic checksum (the CMS/NPI Luhn mod-10 check digit) that validates a batch of NPIs, with every result sourced, an exact recomputed check digit, and never an autonomous reject

Agent Fabric: added the Household / Family-Unit Composition agent — deterministic union-find / disjoint-set connected components that groups plan members into households by the transitive closure of their relationship links, with every link + household sourced, an exact recomputed partition, and never an autonomous merge (the 83rd agent)

Shipped
Details

Added the eighty-third agent on the fabric — household-composition-agent, a DETERMINISTIC (no-Claude) claims / payer-operations service on the payer & plan operations plane, reusing the existing payer-operations tier as a SIBLING to the Enrollment Reconciliation, Coordination of Benefits, Member Cost-Share, and Claim Lifecycle agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the Provider Benchmarking agent's PERCENTILE / RANK STATISTICS, the Claim Lifecycle agent's FSM TRANSITION VALIDATION, the Medication Name Safety agent's STRING EDIT DISTANCE, the Schedule Conflict agent's GREEDY INTERVAL SELECTION, the Caseload Balancing agent's GREEDY BIN-PACKING, the Access Anomaly agent's SLIDING-WINDOW COUNTING, the Coverage Continuity agent's INTERVAL MERGING, the Care Pathway agent's TOPOLOGICAL ORDERING, the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, the Member Cost-Share agent's SEQUENTIAL dollar waterfall, the DDI agent's PAIRWISE KNOWLEDGE-BASE LOOKUP, or the Audit Log Integrity agent's HASH CHAIN, and — CRUCIALLY — it is NOT the Master-Patient-Index agent's identity MATCHING (which links records of the SAME person across systems; THIS one instead groups DIFFERENT people who share a household): the heart of the service is UNION-FIND / DISJOINT-SET CONNECTED COMPONENTS — clustering members by the transitive closure of their relationship links. In a new pure lib/household-composition.ts, evaluateHouseholdComposition(request) takes a batch of plan MEMBERS plus a set of PAIRWISE relationship LINKS (shared subscriber, shared address, a tax-dependent tie) and DETERMINISTICALLY de-dupes the members, unions every link whose BOTH endpoints are submitted members (a link to a non-member is ignored — it can't join the graph), groups members by their set representative (with path compression; the lexicographically smaller id becomes the root), sorts each household's members, and assigns deterministic household ids (hh-1, hh-2, … by each component's minimum member) — so a member linked to a member linked to a third all land in ONE household even when the first and third are NOT directly linked (transitivity) — and derives the disposition: all-singletons (no household has more than one member — no links formed a group) or households-formed (at least one multi-member household). It COMPLEMENTS, not duplicates, the other member / enrollment agents: distinct from the Master-Patient-Index agent (same-person matching), the Enrollment Reconciliation agent (WHO is enrolled between employer and carrier via a keyed set-difference), and the Coordination of Benefits agent (the ORDER of a member's coverages) — this GROUPS distinct members into family units. A household drives a family deductible / out-of-pocket maximum, household-level outreach, and consent scoping; a wrong grouping mis-applies a family accumulator or LEAKS one member's data to another. TIME IS DATA: the finding is a pure function of the request's own members + links (no real clock, no randomness), so the same input always yields the same households. A finding — all-singletons or households-formed — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresStewardReview:true, autoMerged:false), which is how a legitimate finding is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.household.links-sourced (signal householdLinksSourced, violating value false) blocks a finding not built from the submitted batch — every link must connect two SUBMITTED members (no phantom relationship to a member not in the batch), and the households must PARTITION exactly the submitted members (each member in exactly one household, all covered, none invented) — the sourced + completeness gate (mirroring the Enrollment Reconciliation Agent's reconciliation-complete and the Caseload Balancing Agent's assignment-complete) — backed by the pure guard householdLinksSourced; policy.household.partition-consistent (signal householdPartitionConsistent, violating value false) blocks a finding whose grouping does not add up — recomputing the union-find from the echoed members + links must reproduce the reported households (same ids, members, sizes), household count, largest-household size, member count, and disposition; a wrong grouping (two unlinked members merged, or two linked members split apart) mis-applies a family accumulator or leaks data — this is the load-bearing correctness gate, and it recomputes the connected components from the links INDEPENDENT of the sourced check (a phantom link endpoint is ignored by the recompute, so a fabricated link fails sourced while the partition still recomputes — the two gates are isolable) (mirroring the Provider Benchmarking Agent's stats-consistent and the Claim Lifecycle Agent's transition-consistent) — backed by the guard householdPartitionConsistent; and policy.household.no-autonomous-merge (signal householdNoAutonomousMerge, violating value false) blocks a finding that autonomously merged member records, changed enrollment, or applied a family accumulator (autoMerged:true — each is a consequential action that must be authorized) or did not require steward review (requiresStewardReview:false) — the agent PROPOSES a grouping, and every finding is a RECOMMENDATION requiring a data steward to confirm — backed by the guard householdNoAutonomousMerge (mirroring the Enrollment Reconciliation Agent's no-autonomous-change and the Master-Patient-Index Agent's no-autonomous-merge posture; the harmful action is enforced-off). It IS PHI-bearing — the members are patients — so it reuses, by extending appliesTo, the HIPAA-audit policy (phiAccessed:true throughout), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/household-composition/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — household.receive-batch → household.compute-components → household.classify-disposition → household.log-audit — with phiAccessed:true, returning the HouseholdCompositionDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Household Composition panel (a 6-member preset → 3 households showing a transitive 3-member family, a pair, and a singleton; a 5-member-chain preset → one household of 5 proving transitivity when m1 and m5 are never directly linked; a no-links preset → all-singletons; plus phantom-link / mis-grouped-partition / auto-merged governance-block presets), a seeded household.receive-batch→compute-components→classify-disposition→log-audit trace showing the 6-member / 3-household case (householdCount 3, largest 3, requiresStewardReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'eighty-three agents', with the Household Composition agent on the payer-operations tier alongside the Enrollment Reconciliation and the other member / enrollment agents) all reflect it. Menopause-relevant: a 45-64 woman, her spouse, and a dependent on one plan — linked by a shared subscriber and address — are exactly the household this connected-components grouping assembles so a family deductible / OOP maximum and household outreach apply correctly, without ever autonomously merging their records. Frontend tests green (3,544 tests — + household-composition three-households / transitive-chain / all-singletons / non-member-link-ignored / member-dedupe / determinism / member+link-echo / min-member-id-ordering plus three-guards-on-produced with phantom-link + household-names-non-member + member-in-two-households + not-all-covered + merged-unlinked-member + wrong-count + wrong-disposition + sourced-vs-consistent-isolation + auto-merged + skipped-review guard cases, the route's envelope / three governance blocks / households-formed + chain + all-singletons happy paths with a PHI-bearing trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to eighty-three agents); the members + links are clearly-labeled illustrative synthetics, NOT a certified enrollment / MDM system — real household / family-unit composition uses the 834 subscriber / dependent structure, address normalization, tax-household rules, and a master-data-management steward's judgment. Lint + build clean.

f2fea5a agent fabric: add the Household / Family-Unit Composition agent (83rd) — deterministic union-find / disjoint-set connected components that groups members into households by the transitive closure of their relationship links, with every link + household sourced, an exact recomputed partition, and never an autonomous merge

Agent Fabric: added the Provider Cost & Quality Percentile Benchmarking agent — deterministic percentile / rank statistics (sort + midpoint percentile rank + quartile band) that ranks a provider within a peer cohort's distribution, with the cohort sourced, exact recomputed statistics, and never an autonomous tiering (the 82nd agent)

Shipped
Details

Added the eighty-second agent on the fabric — provider-benchmarking-agent, a DETERMINISTIC (no-Claude) commercial-operations service on the commercial plane, reusing the existing commercial-operations tier as a SIBLING to the Provider Contracting, Pipeline Management, Account Management, and Deal Desk agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the Claim Lifecycle agent's FINITE-STATE-MACHINE TRANSITION VALIDATION, the Medication Name Safety agent's STRING EDIT DISTANCE, the Schedule Conflict agent's GREEDY INTERVAL SELECTION, the Caseload Balancing agent's GREEDY BIN-PACKING, the Access Anomaly agent's SLIDING-WINDOW COUNTING, the Coverage Continuity agent's INTERVAL MERGING, the Care Pathway agent's TOPOLOGICAL ORDERING, the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, the Member Cost-Share agent's SEQUENTIAL dollar waterfall, the DDI agent's PAIRWISE KNOWLEDGE-BASE LOOKUP, the OIG Exclusion agent's EXACT identity MATCHING, or the Audit Log Integrity agent's HASH CHAIN, and — crucially — it is NOT the DATE-DEADLINE agents (Timely Filing, Right of Access, Amendment) that add N days to a SINGLE date: the heart of the service is PERCENTILE / RANK STATISTICS over a numeric distribution — sort the cohort, count how many peers fall below / at / above the target, compute the target's midpoint percentile rank, the cohort median, and a quartile band. Provider benchmarking drives value-based-care tiering, incentive payments, and network decisions; a wrong percentile mis-tiers a provider. In a new pure lib/provider-benchmarking.ts, evaluateProviderBenchmarking(request) takes a target provider's metric value plus a peer cohort of providers' values and a metric direction (lower-is-better for cost, higher-is-better for quality), DETERMINISTICALLY computes the percentile rank (the standard midpoint method: (below + 0.5·equal) / n), adjusts for the direction so a higher EFFECTIVE percentile always means better, computes the median, derives a performance band (top-quartile / above-median / below-median / bottom-quartile), and derives the disposition — benchmark-favorable (above-median-or-better) or benchmark-review (below-median, flagged for network review). It COMPLEMENTS, not duplicates, the other provider / quality agents: distinct from the Provider Contracting agent (which computes a single VBC benchmark-DRIFT vs a contract threshold), the HEDIS Quality agent (the measure RATES), the Quality-Measure Attribution agent (the DENOMINATOR), and the Provider Credentialing agent (network integrity) — this ranks a provider within a peer DISTRIBUTION via percentile. TIME IS DATA: the finding is a pure function of the request's own value + cohort + direction (no real clock, no randomness), so the same input always yields the same finding. A finding — benchmark-favorable or benchmark-review — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresNetworkReview:true, autoTiered:false), which is how a legitimate finding is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.benchmark.cohort-sourced (signal benchmarkCohortSourced, violating value false) blocks a finding whose peer cohort is not intact — every cohort member must be a well-formed { providerId, numeric value }, the reported cohort size must equal the actual cohort, and the target value must be numeric, because a phantom or omitted peer silently mis-sizes the denominator and misrepresents the percentile — the sourced gate (mirroring the Claim Lifecycle Agent's states-sourced and the Access Anomaly Agent's events-sourced) — backed by the pure guard benchmarkCohortSourced; policy.benchmark.stats-consistent (signal benchmarkStatsConsistent, violating value false) blocks a finding whose statistics do not add up — recomputing the rank statistics from the echoed cohort (independent of the cohortSize field, so the two gates are isolable) must reproduce the reported counts, percentile rank, direction-adjusted effective percentile, median, performance band, and disposition; a miscomputed / inverted percentile or a band that doesn't follow mis-tiers the provider — this is the load-bearing correctness gate (mirroring the Claim Lifecycle Agent's transition-consistent and the Member Cost-Share Agent's math-consistent) — backed by the guard benchmarkStatsConsistent; and policy.benchmark.no-autonomous-tiering (signal benchmarkNoAutonomousTiering, violating value false) blocks a finding that autonomously tiered the provider, adjusted their payment, or removed them from the network (autoTiered:true — each is a commercially consequential action that must be authorized) or did not require network review (requiresNetworkReview:false) — the agent BENCHMARKS, and every finding is a RECOMMENDATION requiring a network manager to confirm — backed by the guard benchmarkNoAutonomousTiering (mirroring the Provider Contracting Agent's no-autonomous-term-change and the Timely Filing Agent's no-autonomous-write-off posture; the harmful action is enforced-off). It is DELIBERATELY NOT PHI-bearing — it operates on PROVIDER-LEVEL aggregate metrics, not patient health information — so, like the OIG Exclusion agent, it lives on the commercial plane and is NOT on the HIPAA-audit policy; it is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/provider-benchmarking/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — benchmark.receive-metric → benchmark.compute-percentile → benchmark.classify-band → benchmark.log-audit — with NO phiAccessed marker, returning the ProviderBenchmarkingDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Provider Benchmarking panel (a low-cost preset → top-quartile favorable; a high-cost preset → bottom-quartile review with 8 of 9 peers cheaper; a low-quality preset → bottom-quartile review demonstrating the higher-is-better direction inversion; plus mis-sized-cohort / inverted-percentile / auto-tiered governance-block presets), a seeded benchmark.receive-metric→compute-percentile→classify-band→log-audit trace showing the high-cost bottom-quartile case (percentileRank 88.89, effectivePercentile 11.11, requiresNetworkReview:true, NOT PHI), the console subtitle, and the investor brief (now 'eighty-two agents', with the Provider Benchmarking agent on the commercial-operations tier alongside the Provider Contracting and the other commercial agents) all reflect it. Menopause-relevant: a menopause-specialty provider whose risk-adjusted cost-per-episode a payer is about to tier for a value-based-care program is exactly the case where an inverted percentile or a mis-sized peer cohort would wrongly penalize the provider — which this agent surfaces to a network manager without ever tiering. Frontend tests green (3,502 tests — + provider-benchmarking top-quartile / bottom-quartile / direction-inversion / midpoint-equal-values / empty-cohort / determinism / cohort-echo / even-length-median plus three-guards-on-produced with mis-sized-cohort + malformed-member + non-numeric-target + inverted-percentile + wrong-disposition + wrong-median + sourced-vs-consistent-isolation + auto-tiered + skipped-review guard cases, the route's envelope / three governance blocks / favorable + review + quality happy paths with a NOT-PHI trace assertion, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to eighty-two agents); the peer cohorts + metric values are clearly-labeled illustrative synthetics, NOT a certified benchmarking system — real provider benchmarking uses risk / case-mix adjustment, statistically valid peer grouping, minimum denominators, confidence intervals, and the network team's judgment. Lint + build clean.

032c1f3 agent fabric: add the Provider Cost & Quality Percentile Benchmarking agent (82nd) — deterministic percentile / rank statistics (sort + midpoint percentile rank + quartile band) that ranks a provider within a peer cohort, with the cohort sourced, exact recomputed statistics, and never an autonomous tiering

Agent Fabric: added the Claim Lifecycle / Status-Transition Guard agent — deterministic finite-state-machine transition validation (transition-table lookup + BFS reachability) that decides whether a claim-status move is a legal single step, reachable only via a longer path, or impossible, with every state sourced, exact transition logic, and never an autonomous advance (the 81st agent)

Shipped
Details

Added the eighty-first agent on the fabric — claim-lifecycle-agent, a DETERMINISTIC (no-Claude) claims / payer-operations service on the payer & plan operations plane, reusing the existing payer-operations tier as a SIBLING to the Claims Adjudication Assistant, Coordination of Benefits, Claims Overpayment & Recovery, Timely Filing, and Subrogation agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the Medication Name Safety agent's STRING EDIT DISTANCE, the Schedule Conflict agent's GREEDY INTERVAL SELECTION, the Caseload Balancing agent's GREEDY BIN-PACKING, the Access Anomaly agent's SLIDING-WINDOW COUNTING, the Coverage Continuity agent's INTERVAL MERGING, the Care Pathway agent's TOPOLOGICAL ORDERING (which orders a DAG's nodes — THIS one instead answers reachability + shortest path over a CYCLIC state graph), the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, the Member Cost-Share agent's SEQUENTIAL dollar waterfall, the DDI agent's PAIRWISE KNOWLEDGE-BASE LOOKUP, the OIG Exclusion agent's EXACT identity MATCHING, or the Audit Log Integrity agent's HASH CHAIN, and — crucially — it is NOT the DATE-DEADLINE agents (Timely Filing, Right of Access, Amendment) that add N days to a SINGLE date: the heart of the service is FINITE-STATE-MACHINE TRANSITION VALIDATION — a transition-table lookup (is current → requested a legal edge?) plus a BREADTH-FIRST SEARCH over the state graph (is requested reachable from current, and what is the shortest legal path?). A claim moves through a lifecycle — draft, submitted, acknowledged, adjudicated, paid, denied, appealed, void — and skipping a step (e.g., draft → paid with no adjudication) is a control failure and a leakage / fraud risk. In a new pure lib/claim-lifecycle.ts, evaluateClaimLifecycle(request) takes a claim's current status plus a requested next status and, against a claim-status state machine (states, transitions, terminal states), DETERMINISTICALLY looks up whether current → requested is a legal single-step edge, runs a BFS (shortestTransitionPath, neighbors explored in sorted order for determinism) for reachability + the shortest legal path, and derives the disposition — transition-allowed (a legal single step), transition-illegal-but-reachable (not a single step, but a valid future state — the path shows the required intermediate steps), or transition-unreachable (the target can never follow the current status, e.g., paying a voided claim). It COMPLEMENTS, not duplicates, the other claim agents: distinct from the Claims Adjudication Assistant (per-claim edits), the Coordination of Benefits agent (payer ORDER across coverages), the Claims Overpayment & Recovery agent (POST-payment clawback), the Timely Filing agent (was the claim FILED IN TIME), and the Subrogation agent (third-party liability) — this validates one narrow, purely STRUCTURAL question: is this STATUS TRANSITION legal, and if not, is the target even reachable. TIME IS DATA: the finding is a pure function of the request's own statuses + state machine (no real clock, no randomness), so the same input always yields the same finding. A finding — transition-allowed, transition-illegal-but-reachable, or transition-unreachable — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresAdjusterReview:true, autoAdvanced:false), which is how a legitimate finding is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Medication Name Safety and Care Pathway agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.claim.states-sourced (signal claimStatesSourced, violating value false) blocks a finding that names a status — in the allowed-next set or in the shortest path — that is not a defined state of the machine, or a path step that is not a real transition, because a fabricated state invents a lifecycle stage that doesn't exist and a fabricated edge invents a legal move that isn't allowed — the sourced gate (mirroring the Care Pathway Agent's steps-sourced and the Medication Name Safety Agent's candidates-sourced) — backed by the pure guard claimStatesSourced; policy.claim.transition-consistent (signal claimTransitionConsistent, violating value false) blocks a finding whose transition logic does not add up — recomputing the transition table + the BFS from the machine must reproduce the reported direct-edge flag, the reachability flag, the allowed-next set, the shortest-path length + endpoints, and the disposition; a wrong direct-edge flag would wave through an illegal transition (skipping adjudication) or block a legal one, a wrong reachability / path would misroute the claim — this is the load-bearing correctness gate, and it recomputes from the machine using the path ENDPOINTS (leaving interior-edge sourcing to the states-sourced guard, so the two gates are independent and isolable) (mirroring the Care Pathway Agent's sequence-valid and the Medication Name Safety Agent's distances-consistent) — backed by the guard claimTransitionConsistent; and policy.claim.no-autonomous-advance (signal claimNoAutonomousAdvance, violating value false) blocks a finding that autonomously advanced the claim, posted a payment, or finalized a denial (autoAdvanced:true — each is a payer action that must be authorized) or did not require adjuster review (requiresAdjusterReview:false) — the agent VALIDATES, and every finding is a RECOMMENDATION requiring an adjuster to confirm the transition — backed by the guard claimNoAutonomousAdvance (mirroring the Timely Filing Agent's no-autonomous-write-off and the Overpayment Recovery Agent's no-autonomous-clawback posture; the harmful action is enforced-off). It IS PHI-bearing — the claim references a patient — so it reuses, by extending appliesTo, the HIPAA-audit policy (phiAccessed:true throughout), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/claim-lifecycle/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — claim.receive-transition → claim.check-transition → claim.compute-reachability → claim.log-audit — with phiAccessed:true, returning the ClaimLifecycleDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Claim Lifecycle panel (an 'adjudicated → paid' preset → transition-allowed; a 'draft → paid' preset → illegal-but-reachable in 4 steps with the BFS path shown; a 'void → paid' preset → unreachable; plus fabricated-state / wrong-direct-edge / auto-advanced governance-block presets), a seeded claim.receive-transition→check-transition→compute-reachability→log-audit trace showing the draft→paid illegal-but-reachable case (directEdge false, pathLength 4, requiresAdjusterReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'eighty-one agents', with the Claim Lifecycle agent on the payer-operations tier alongside the Timely Filing and the other claim agents) all reflect it. Menopause-relevant: a 45-64 patient's menopause-care claim that a downstream automation tries to push straight from draft to paid — skipping acknowledgement and adjudication — is exactly the control failure this state-machine guard catches and routes to an adjuster, without ever advancing the claim itself. Frontend tests green (3,461 tests — + claim-lifecycle allowed / illegal-but-reachable / unreachable / unknown-status / determinism / machine-echo plus shortestTransitionPath unit tests and three-guards-on-produced with fabricated-state + wrong-direct-edge + wrong-path-length + wrong-disposition + sourced-vs-consistent-isolation + auto-advanced + skipped-review guard cases, the route's envelope / three governance blocks / allowed + illegal + unreachable happy paths, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to eighty-one agents); the claim-status state machine is a clearly-labeled illustrative synthetic, NOT a certified claims-processing system — real claim-status management uses the X12 277 claim-status category / status codes, the payer's adjudication system, and the plan's business rules. Lint + build clean.

3cdec22 agent fabric: add the Claim Lifecycle / Status-Transition Guard agent (81st) — deterministic finite-state-machine transition validation (transition-table lookup + BFS reachability) with every state sourced, exact transition logic, and never an autonomous advance

Agent Fabric: added the Medication Name Safety (LASA) agent — deterministic Levenshtein edit-distance matching that flags look-alike / sound-alike drug-name confusion against a formulary catalog, with every candidate sourced from the catalog, exact recomputed distances, and never an autonomous substitution (the 80th agent)

Shipped
Details

Added the eightieth agent on the fabric — medication-name-safety-agent, a DETERMINISTIC (no-Claude) clinical-decision service on the patient / clinical plane, reusing the existing clinical-decision tier as a SIBLING to the Drug–Drug Interaction, Controlled Substance / PDMP, Formulary & DUR Review, Care Pathway, and Lab Result agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the Schedule Conflict agent's GREEDY INTERVAL SELECTION, the Caseload Balancing agent's GREEDY BIN-PACKING, the Access Anomaly agent's SLIDING-WINDOW COUNTING, the Coverage Continuity agent's INTERVAL MERGING, the Care Pathway agent's TOPOLOGICAL ORDERING, the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, the Member Cost-Share agent's SEQUENTIAL dollar waterfall, the Drug–Drug Interaction agent's PAIRWISE KNOWLEDGE-BASE LOOKUP, the OIG Exclusion agent's EXACT identity MATCHING (which explicitly does NO fuzzy / phonetic matching), or the Audit Log Integrity agent's HASH CHAIN, and — crucially — it is NOT the DATE-DEADLINE agents (Timely Filing, Right of Access, Amendment) that add N days to a SINGLE date: the heart of the service is STRING EDIT DISTANCE (the classic Levenshtein dynamic-programming algorithm — the minimum single-character insertions, deletions, and substitutions to turn one name into another). Look-alike / sound-alike (LASA) medication-name confusion (premarin vs primaxin, hydroxyzine vs hydralazine) is one of the most persistent sources of medication error — the ISMP maintains a LASA list and the Joint Commission requires organizations to manage it. In a new pure lib/medication-name-safety.ts, evaluateMedicationNameSafety(request) takes a prescribed / typed drug name plus a formulary catalog and a confusability threshold, DETERMINISTICALLY normalizes the name (lowercase / trim / collapse whitespace), computes the Levenshtein distance to every catalog drug, finds the nearest match, collects the look-alikes within the threshold (0 < distance ≤ threshold — near but not an exact match), and derives the disposition — recognized-clear (an exact match with no look-alike), lasa-warning (a look-alike within the threshold — a possible wrong-drug confusion or near-miss misspelling), or unrecognized (no exact match and nothing within the threshold). It COMPLEMENTS, not duplicates, the other medication agents: distinct from the Drug–Drug Interaction agent (whether two drugs INTERACT), the Formulary & DUR agent (whether a drug is COVERED / appropriate), the Controlled-Substance / PDMP agent (opioid MME safety), and the Medication Adherence agent (refill nudges) — this catches a name CONFUSABLE with a DIFFERENT drug before it becomes a wrong-drug error. TIME IS DATA: the finding is a pure function of the request's own name + catalog + threshold (no real clock, no randomness), so the same input always yields the same finding. A finding — recognized-clear, lasa-warning, or unrecognized — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresPharmacistReview:true, autoSubstituted:false), which is how a legitimate finding is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Schedule Conflict and Caseload Balancing agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.lasa.candidates-sourced (signal lasaCandidatesSourced, violating value false) blocks a finding that names a candidate — the nearest match or a confusable look-alike — not backed by the catalog (its drugId must be in the catalog and its echoed name must equal that drug's catalog name), because a fabricated candidate invents a look-alike that doesn't exist and a mislabeled one attaches the wrong name — the sourced gate (mirroring the Drug–Drug Interaction Agent's interaction-sourced and the Schedule Conflict Agent's intervals-sourced) — backed by the pure guard lasaCandidatesSourced; policy.lasa.distances-consistent (signal lasaDistancesConsistent, violating value false) blocks a finding whose edit distances do not add up — recomputing the Levenshtein distances from the echoed catalog (using the catalog names, so this gate is independent of the sourced check) must reproduce the reported nearest match, every distance, the exact-match flag, the confusable set (exactly those within the threshold), and the disposition; a miscomputed distance, a wrong nearest match, an omitted or spurious look-alike, or a disposition that doesn't follow drives a wrong finding — this is the load-bearing correctness gate (mirroring the Schedule Conflict Agent's conflict-free and the Access Anomaly Agent's window-count-consistent) — backed by the guard lasaDistancesConsistent; and policy.lasa.no-autonomous-substitution (signal lasaNoAutonomousSubstitution, violating value false) blocks a finding that autonomously substituted, corrected, or dispensed a drug (autoSubstituted:true — each is a clinical action that must be authorized) or did not require pharmacist review (requiresPharmacistReview:false) — the agent FLAGS, and every finding is a RECOMMENDATION requiring a pharmacist to confirm the intended medication — backed by the guard lasaNoAutonomousSubstitution (mirroring the Drug–Drug Interaction Agent's no-autonomous-hold-or-override and the Schedule Conflict Agent's no-autonomous-booking posture; the harmful action is enforced-off). It IS PHI-bearing — the prescribed name is for a patient's medication order — so it reuses, by extending appliesTo, the HIPAA-audit policy (phiAccessed:true throughout), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/medication-name-safety/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — lasa.receive-name → lasa.compute-distances → lasa.flag-lookalike → lasa.log-audit — with phiAccessed:true, returning the MedicationNameSafetyDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Medication Name Safety panel (a 'gabapentin' preset → recognized-clear; a 'premarin' preset → lasa-warning against the look-alike primaxin at edit distance 2; a 'trelagliptin' preset → unrecognized; plus fabricated-candidate / wrong-disposition / auto-substituted governance-block presets), a seeded lasa.receive-name→compute-distances→flag-lookalike→log-audit trace showing the premarin LASA case (nearest premarin distance 0, look-alike primaxin distance 2, requiresPharmacistReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'eighty agents', with the Medication Name Safety agent on the clinical-decision tier alongside the Drug–Drug Interaction and the other clinical agents) all reflect it. Menopause-relevant: a hurried order for 'premarin' (conjugated estrogens for menopausal symptoms) that is two keystrokes from 'primaxin' (an IV antibiotic) is exactly the wrong-drug confusion this edit-distance check surfaces for a pharmacist — without ever autonomously changing the order. Frontend tests green (3,419 tests — + medication-name-safety recognized-clear / lasa-warning-exact-plus-lookalike / near-miss-misspelling / unrecognized / custom-threshold / determinism / catalog-echo plus levenshtein + normalize unit tests and three-guards-on-produced with fabricated-candidate + mislabeled-candidate + wrong-disposition + wrong-distance + omitted-lookalike + sourced-vs-consistent-isolation + auto-substituted + skipped-review guard cases, the route's envelope / three governance blocks / clear + lasa + unrecognized happy paths, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to eighty agents); the formulary catalog + names are clearly-labeled illustrative synthetics, NOT a certified medication-safety system — real LASA safety uses the ISMP / FDA LASA lists, tall-man lettering, RxNorm / First Databank vocabularies, indication / dose context, and barcode scanning. Lint + build clean.

1dae212 agent fabric: add the Medication Name Safety (LASA) agent (80th) — deterministic Levenshtein edit-distance matching that flags look-alike / sound-alike drug-name confusion against a formulary catalog, with every candidate sourced, exact recomputed distances, and never an autonomous substitution

Agent Fabric: added the Scheduling Conflict / Double-Booking Guard agent — deterministic greedy interval selection (activity-selection) that computes a resource's maximum conflict-free schedule and waitlists the collisions, with every appointment sourced and accounted for once, a conflict-free (no double-booking) schedule, and never an autonomous booking (the 79th agent)

Shipped
Details

Added the seventy-ninth agent on the fabric — schedule-conflict-agent, a DETERMINISTIC (no-Claude) care-coordination service on the patient / clinical plane, reusing the existing care-coordination tier as a SIBLING to the Appointment Scheduling, Caseload Balancing, Care Team & Case Management, Transitions of Care, and Population Health agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the Caseload Balancing agent's GREEDY BIN-PACKING under a capacity constraint, the Access Anomaly agent's SLIDING-WINDOW COUNTING, the Coverage Continuity agent's INTERVAL MERGING + GAP DETECTION (that one MERGES overlapping intervals into continuous spans; THIS one SELECTS a maximum NON-overlapping subset), the Care Pathway agent's TOPOLOGICAL ORDERING, the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, the Member Cost-Share agent's SEQUENTIAL dollar waterfall, the OIG Exclusion agent's identity MATCHING, or the Audit Log Integrity agent's HASH CHAIN, and — crucially — it is NOT the DATE-DEADLINE agents (Timely Filing, Right of Access, Amendment) that add N days to a SINGLE date: the heart of the service is GREEDY INTERVAL SELECTION (the classic activity-selection algorithm: sort the requested intervals by EARLIEST FINISH time and admit each one that does not overlap the last admitted, provably maximizing the number of non-overlapping appointments). Double-booking a provider, a room, or an infusion chair is a real operational failure mode; this agent guards a whole batch of requests for one resource. In a new pure lib/schedule-conflict.ts, evaluateScheduleConflict(request) takes a resource plus a batch of requested appointment intervals (each a start/end time for a patient — ISO strings or epoch-ms), validates them (parseable start < end, unique id), DETERMINISTICALLY sorts by earliest finish (ties by start, then id), runs the two-pointer activity-selection greedy to admit the maximum conflict-free set, and WAITLISTS each request that overlaps the last admitted (recording which scheduled appointment it conflicts with) — reporting the disposition (conflict-free or conflicts-waitlisted), the scheduled appointments, and the waitlist. It COMPLEMENTS, not duplicates, the Appointment Scheduling agent (which BOOKS a SINGLE slot against a provider calendar and never double-books THAT slot): this validates a WHOLE BATCH for a resource, computes the conflict-free schedule + the waitlist, and hands it to a scheduler — the double-booking guard for a day, not the booker of one appointment. TIME IS DATA: the schedule is a pure function of the request's own intervals (times accepted as data, no real clock), so the same batch always yields the same schedule, and the greedy MAXIMIZES the number scheduled (two short appointments beat one long one) rather than 'first request wins'. A schedule — fully conflict-free OR partial with a waitlist — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresSchedulerReview:true, autoBooked:false), which is how a legitimate schedule is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Caseload Balancing and Coverage Continuity agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.schedule.intervals-sourced (signal scheduleIntervalsSourced, violating value false) blocks a determination whose appointments do not trace to submitted requests or do not account for every request exactly once — every scheduled / waitlisted appointment's id, member, start, and end must match a submitted interval, and the scheduled set and the conflict set must be disjoint and cover every request (no fabricated appointment, no dropped patient, no double-count) — the sourced + completeness gate (mirroring the Caseload Balancing Agent's assignment-complete and the Coverage Continuity Agent's segments-sourced) — backed by the pure guard scheduleIntervalsSourced; policy.schedule.conflict-free (signal scheduleConflictFree, violating value false) blocks a determination that is not conflict-free — the scheduled appointments must be pairwise NON-overlapping (no double-booking), every waitlisted appointment must genuinely overlap the scheduled appointment named in its conflictsWith, and the counts must add up; the guard recomputes every pairwise overlap and re-checks each waitlist justification (this is the load-bearing correctness gate, mirroring the Caseload Balancing Agent's capacity-respected and the Access Anomaly Agent's window-count-consistent) — backed by the guard scheduleConflictFree; and policy.schedule.no-autonomous-booking (signal scheduleNoAutonomousBooking, violating value false) blocks a determination that autonomously booked, cancelled, or bumped an appointment (autoBooked:true — each is a scheduling action that must be authorized) or did not require scheduler review (requiresSchedulerReview:false) — the agent RECOMMENDS, and every schedule is a RECOMMENDATION requiring a scheduler to confirm — backed by the guard scheduleNoAutonomousBooking (mirroring the Caseload Balancing Agent's no-autonomous-assignment and the Appointment Scheduling Agent's governance posture; the harmful action is enforced-off). It IS PHI-bearing — the requests reference the patients being scheduled — so it reuses, by extending appliesTo, the HIPAA-audit policy (phiAccessed:true throughout), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/schedule-conflict/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — schedule.receive-requests → schedule.select-intervals → schedule.check-conflicts → schedule.log-audit — with phiAccessed:true, returning the ScheduleConflictDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Scheduling Conflict panel (a 3-spaced-requests preset → conflict-free; an overlapping-requests preset → partial with a waitlist; a maximize preset → two short appointments admitted over one long one, proving the greedy MAXIMIZES; plus fabricated-appointment / double-booked / auto-booked governance-block presets), a seeded schedule.receive-requests→select-intervals→check-conflicts→log-audit trace showing the waitlist case (2 of 4 scheduled conflict-free, 2 waitlisted, requiresSchedulerReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'seventy-nine agents', with the Scheduling Conflict agent on the care-coordination tier alongside the Appointment Scheduling and the other care-coordination agents) all reflect it. Menopause-relevant: a busy menopause-specialist clinic day where four midlife women request overlapping visit windows is exactly where a double-booking guard picks the maximum conflict-free set and surfaces the rest for rescheduling — without ever autonomously booking or bumping a patient. Frontend tests green (3,373 tests — + schedule-conflict conflict-free / waitlist-earliest-finish / maximize-two-over-one / invalid-skip / determinism / three-guards-on-produced plus fabricated-appointment + altered-attribution + dropped-request + double-booked + unjust-waitlist + phantom-conflictsWith guard cases, the route's envelope / three governance blocks / conflict-free + waitlist + maximize happy paths, the panel's presets / request-body / view-lift / hhmm, and the registry + brief drift guards raised to seventy-nine agents); the resource + intervals are clearly-labeled illustrative synthetics, NOT a certified scheduling system — real scheduling uses provider availability calendars, appointment-type durations, buffer / turnover times, and room / equipment constraints. Lint + build clean.

728e96b agent fabric: add the Scheduling Conflict / Double-Booking Guard agent (79th) — deterministic greedy interval selection (activity-selection) that computes a resource's maximum conflict-free schedule and waitlists the collisions, with every appointment sourced and accounted for once, a conflict-free schedule, and never an autonomous booking

Agent Fabric: added the Caseload Balancing (Care-Manager Panel Assignment) agent — deterministic greedy bin-packing that allocates a panel of members across care managers within capacity, waitlisting the overflow, with every member accounted for exactly once, no manager over capacity, and never an autonomous assignment (the 78th agent)

Shipped
Details

Added the seventy-eighth agent on the fabric — caseload-balancing-agent, a DETERMINISTIC (no-Claude) care-coordination service on the patient / clinical plane, reusing the existing care-coordination tier as a SIBLING to the Care Team & Case Management, Complex Care Management, Transitions of Care, Care Coordination Handoff, and Population Health agents — it does NOT invent a new tier or plane, and it RETURNS TO THE PATIENT / CLINICAL plane after the platform Access Anomaly agent. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the Access Anomaly agent's SLIDING-WINDOW COUNTING, the Coverage Continuity agent's INTERVAL MERGING + GAP DETECTION, the Care Pathway agent's TOPOLOGICAL ORDERING, the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, the Member Cost-Share agent's SEQUENTIAL dollar waterfall, the OIG Exclusion agent's identity MATCHING, or the Audit Log Integrity agent's HASH CHAIN, and — crucially — it is NOT the DATE-DEADLINE agents (Timely Filing, Right of Access, Amendment) that add N days to a SINGLE date: the heart of the service is GREEDY ALLOCATION UNDER A CAPACITY CONSTRAINT (a bin-packing / worst-fit-decreasing assignment of weighted items into capacity-limited bins). A care manager's 'panel' is the set of patients they actively manage; each patient carries an acuity (how much attention they need), and each manager has a finite capacity — over-loading a panel is a patient-safety risk, so the allocation must respect capacity and surface the overflow rather than silently drop it. In a new pure lib/caseload-balancing.ts, evaluateCaseloadBalancing(request) takes a panel of members (each with an acuity weight) and a set of care managers (each with a weighted-slot capacity), validates them (positive-integer acuity; non-negative-integer capacity, unique manager id), and DETERMINISTICALLY runs a worst-fit-decreasing greedy bin-packing: it processes members in DESCENDING acuity (ties by member id) and, for each, places it into the manager with the GREATEST remaining capacity that can still fit it (remaining ≥ acuity; ties by manager id) — spreading load evenly — or WAITLISTS it when no manager has room, reporting the disposition (fully-assigned or partially-assigned-waitlist), the per-manager loads, and the waitlist. It COMPLEMENTS, not duplicates, the other care-coordination agents: distinct from the Care Team & Case Management agent (which assembles the multi-disciplinary team around ONE patient and picks that patient's case manager), the Complex Care Management agent (CCM time-tracking + billing for ONE patient), the Transitions of Care agent (moving ONE patient between settings), and the Population Health agent (which PRIORITIZES / stratifies a panel) — this ALLOCATES a whole panel across the managers' finite capacity, the balancing of caseloads. TIME IS DATA: the allocation is a pure function of the request's own members + managers (no real clock), so the same panel always yields the same assignment. An allocation — fully assigned OR partially assigned with a waitlist — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresCareLeadReview:true, autoAssigned:false), which is how a legitimate allocation is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Access Anomaly and Coverage Continuity agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.caseload.assignment-complete (signal caseloadAssignmentComplete, violating value false) blocks a determination that does not account for EVERY member EXACTLY once — the assigned set and the waitlisted set must be disjoint and together cover every submitted member (no dropped member, no double-assignment), and the reported counts must match; a dropped member is a patient who falls through the cracks with no manager owning their care, a double-assigned member is confused ownership — this is the completeness gate (mirroring the Enrollment Reconciliation Agent's reconciliation-complete and the Accounting of Disclosures Agent's accountable-disclosures-complete) — backed by the pure guard caseloadAssignmentComplete; policy.caseload.capacity-respected (signal caseloadCapacityRespected, violating value false) blocks a determination that violates capacity — each manager's assigned acuity must equal the sum of their assigned members' acuities, must not exceed their capacity, and the remaining capacity must be exact, and every waitlisted member's acuity must exceed EVERY manager's final remaining capacity (a member waitlisted while a manager had room is a wrong, unsafe allocation); the guard recomputes each manager's load from the assignments, checks it against capacity, and verifies every waitlist is justified (this is the load-bearing correctness gate, mirroring the Access Anomaly Agent's window-count-consistent and the Member Cost-Share Agent's math-consistent) — backed by the guard caseloadCapacityRespected; and policy.caseload.no-autonomous-assignment (signal caseloadNoAutonomousAssignment, violating value false) blocks a determination that autonomously committed an assignment (autoAssigned:true — committing an assignment, reassigning a patient, or overriding a manager's caseload is a care-ownership decision that must be authorized) or did not require care-lead review (requiresCareLeadReview:false) — the agent RECOMMENDS, and every allocation is a RECOMMENDATION requiring a care-management lead to confirm — backed by the guard caseloadNoAutonomousAssignment (mirroring the Care Team Agent's no-autonomous-assignment and the Coverage Continuity Agent's no-autonomous-determination posture; the harmful action is enforced-off). It IS PHI-bearing — the members reference the patients on the panel — so it reuses, by extending appliesTo, the HIPAA-audit policy (phiAccessed:true throughout), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/caseload-balancing/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — caseload.receive-panel → caseload.allocate → caseload.check-capacity → caseload.log-audit — with phiAccessed:true, returning the CaseloadBalancingDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Caseload Balancing panel (a 6-member / 3-manager preset → fully assigned within capacity; an over-capacity preset → partially assigned with a waitlist; an equal-members preset → evenly balanced 2-and-2; plus dropped-member / over-capacity / auto-assigned governance-block presets), a seeded caseload.receive-panel→allocate→check-capacity→log-audit trace showing the fully-assigned case (6 members across 3 managers, assigned acuity 21 of 24, requiresCareLeadReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'seventy-eight agents', with the Caseload Balancing agent on the care-coordination tier alongside the Care Team and the other care-coordination agents) all reflect it. Menopause-relevant: a care-management program for 45-64 women with high-acuity midlife needs — complex perimenopausal symptoms, cardiovascular and bone-health risk, behavioral health — is exactly the kind of panel this balances across a finite set of nurse care managers so no manager is over-loaded and no patient is left without an owner. Frontend tests green (3,332 tests — + caseload full-assign / waitlist-overflow / even-balance / accounted-once / invalid-skip / no-managers / determinism / three-signal-true-and-false guards including over-capacity + miscounted-load + unjust-waitlist + acuity-mismatch, the route's envelope / three governance blocks / full + waitlist + balanced happy paths, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to seventy-eight agents); the members + managers + acuity + capacity are clearly-labeled illustrative synthetics, NOT a certified caseload / staffing system — real panel assignment uses validated acuity instruments, care-manager licensure / specialty / language fit, geographic match, and continuity of an existing relationship. Lint + build clean.

d380f19 agent fabric: add the Caseload Balancing (Care-Manager Panel Assignment) agent (78th) — deterministic greedy bin-packing that allocates a panel of members across care managers within capacity, waitlisting the overflow, with every member accounted for exactly once, no manager over capacity, and never an autonomous assignment

Agent Fabric: added the Access Anomaly Detection agent — deterministic sliding-window counting of an actor's PHI-access events, flagging an anomalous access volume when the peak in any rolling window exceeds the threshold (HIPAA §164.308 information-system activity review), with every counted access sourced, an exact window count, and never an autonomous access action (the 77th agent)

Shipped
Details

Added the seventy-seventh agent on the fabric — access-anomaly-agent, a DETERMINISTIC (no-Claude) control-plane / data-substrate service on the platform & data substrate plane, reusing the existing data-plane tier as a SIBLING to the Audit Log Integrity, Accounting of Disclosures, Break-the-Glass, Minimum Necessary, De-Identification, Consent, Master Patient Index, Records Retention, Right of Access, Amendment, and Information Blocking agents — it does NOT invent a new tier or plane, and it RETURNS TO THE PLATFORM plane after the payer Creditable Coverage Continuity agent. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the Coverage Continuity agent's INTERVAL MERGING + GAP DETECTION, the Care Pathway agent's TOPOLOGICAL ORDERING, the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, the Member Cost-Share agent's SEQUENTIAL dollar waterfall, the OIG Exclusion agent's identity MATCHING, or the Audit Log Integrity agent's HASH CHAIN, and — crucially — it is NOT the DATE-DEADLINE agents (Timely Filing, Right of Access, Amendment) that add N days to a SINGLE date: the heart of the service is SLIDING-WINDOW COUNTING over timestamped events (a two-pointer scan for the peak count in any window of a fixed length). The HIPAA Security Rule's information-system-activity-review safeguard (§164.308(a)(1)(ii)(D)) requires covered entities to regularly review records of information-system activity such as audit logs and access reports; an unusual VOLUME of PHI accesses by one workforce member in a short window is a classic snooping / breach indicator. In a new pure lib/access-anomaly.ts, evaluateAccessAnomaly(request) takes an actor's PHI-access events (each a timestamped read of a patient record) plus a window length and a threshold, DETERMINISTICALLY parses the timestamps to epoch-ms, sorts them, runs a two-pointer sliding-window scan to find the PEAK number of accesses in any window of the configured length, and flags an ANOMALOUS ACCESS VOLUME when that peak exceeds the threshold — reporting the peak window (its span, count, distinct patients, and event ids). It COMPLEMENTS, not duplicates, the other platform agents: distinct from the Audit Log Integrity agent (whether the audit TRAIL is tamper-evident), the Break-the-Glass agent (whether a SINGLE emergency access is authorized), the Minimum Necessary agent (how much PHI a purpose may see), the Accounting of Disclosures agent (WHO a patient's PHI was disclosed to), and the Consent agent (whether a patient may be contacted / data used) — this detects an unusual VOLUME of accesses by one actor OVER TIME. TIME IS DATA: the analysis is a pure function of the request's own events + window + threshold (no real clock), so the same events always yield the same peak + finding, and the detection is WINDOWED (a high daily total spread into small bursts is NOT flagged), not a naive total count. A finding — normal activity OR an anomalous spike — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresPrivacyReview:true, autoLockedAccount:false, autoRevokedAccess:false), which is how a legitimate finding is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Coverage Continuity and Audit Log Integrity agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.access.events-sourced (signal accessEventsSourced, violating value false) blocks a finding whose peak window does not trace to submitted access events — the peak window's event ids must be a subset of the submitted events and its count must equal the number of those ids, because a fabricated access (an event in the peak not backed by a submitted one) would manufacture a false anomaly and a phantom count would overstate the spike — backed by the pure guard accessEventsSourced (mirroring the Coverage Continuity Agent's segments-sourced and the Audit Log Integrity Agent's hash-chain-verified posture); policy.access.window-count-consistent (signal accessWindowCountConsistent, violating value false) blocks a finding whose window count does not add up — recomputing the sliding-window peak from the events must reproduce the reported peak count, the peak window's events must all fall within a span of at most windowMinutes, and the anomaly flag must equal whether the peak exceeds the threshold; the guard recomputes the peak, checks the window span, and re-derives the flag (this is the load-bearing correctness gate, mirroring the Coverage Continuity Agent's math-consistent and the Audit Log Integrity Agent's sequence-complete) — backed by the guard accessWindowCountConsistent; and policy.access.no-autonomous-action (signal accessNoAutonomousAction, violating value false) blocks a finding that autonomously took an access / employment action (autoLockedAccount:true or autoRevokedAccess:true — locking an account, revoking access, or disciplining a workforce member is an action that must be authorized) or did not require privacy review (requiresPrivacyReview:false) — the agent MEASURES, and every flag is a RECOMMENDATION requiring a privacy officer to review — backed by the guard accessNoAutonomousAction (mirroring the Coverage Continuity Agent's no-autonomous-determination and the Audit Log Integrity Agent's no-autonomous-redaction posture; the harmful action is enforced-off). It IS PHI-bearing — the events reference the patients whose records were accessed — so it reuses, by extending appliesTo, the HIPAA-audit policy (phiAccessed:true throughout), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/access-anomaly/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — access.receive-events → access.scan-window → access.flag-anomaly → access.log-audit — with phiAccessed:true, returning the AccessAnomalyDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Access Anomaly panel (a 24-accesses-in-46-minutes preset → anomalous over the 20-in-60-minutes threshold; a spread-out-access preset → normal; a high-total-small-bursts preset → normal, proving the detection is WINDOWED not a total count; plus fabricated-peak / mismatched-flag / auto-locked-account governance-block presets), a seeded access.receive-events→scan-window→flag-anomaly→log-audit trace showing the anomalous case (peak 24 in a 60-minute window across 24 distinct patients, requiresPrivacyReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'seventy-seven agents', with the Access Anomaly agent on the data-plane tier alongside the Audit Log Integrity and the other platform agents) all reflect it. Menopause-relevant: a 45-64 woman's menopause care record being viewed 24 times in under an hour by a single non-treating staff member is exactly the snooping pattern this activity review flags for a privacy officer — without ever autonomously locking the account. Frontend tests green (3,294 tests — + access-anomaly window-boundary-inclusive / just-outside-window-excluded / windowed-not-total / empty-set / invalid-timestamp-skip / defaults / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / anomalous + normal + burst happy paths, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to seventy-seven agents); the events + window + threshold are clearly-labeled illustrative synthetics, NOT a certified breach-detection / SIEM system — real activity review uses the full audit trail, user-behavior analytics, role / relationship context, and the privacy officer's judgment. Lint + build clean.

e79043a agent fabric: add the Access Anomaly Detection agent (77th) — deterministic sliding-window counting of an actor's PHI-access events, flagging an anomalous access volume when the peak in any rolling window exceeds the threshold (HIPAA §164.308 activity review), with every counted access sourced, an exact window count, and never an autonomous access action

Agent Fabric: added the Creditable Coverage Continuity agent — deterministic interval-merge + gap-detection over a member's coverage segments, flagging a significant break (>63-day gap) in creditable coverage, with every merged span sourced, exact coverage math, and never an autonomous coverage determination (the 76th agent)

Shipped
Details

Added the seventy-sixth agent on the fabric — coverage-continuity-agent, a DETERMINISTIC (no-Claude) claims / payer-operations service on the payer & plan operations plane, reusing the existing payer-operations tier as a SIBLING to the Benefits Verification, Coordination of Benefits, Enrollment Reconciliation, Member Cost-Share, MLR Rebate, Claims Adjudication, and OIG Exclusion agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: it is NOT the Care Pathway agent's TOPOLOGICAL ORDERING, the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, the Member Cost-Share agent's SEQUENTIAL dollar waterfall, the OIG Exclusion agent's identity MATCHING, or the MLR Rebate agent's RATIO + apportionment, and — crucially — it is NOT the DATE-DEADLINE agents (Timely Filing, Right of Access, Amendment) that add N days to a SINGLE date: the heart of the service is INTERVAL MERGING + GAP DETECTION over a set of date ranges. 'Creditable coverage' is prior health coverage that counts toward waiting-period / pre-existing-condition rules; a break longer than 63 days (a 'significant break') resets it and can trigger a special-enrollment loss or a Medicare Part D late-enrollment penalty. In a new pure lib/coverage-continuity.ts, evaluateCoverageContinuity(request) takes a member's coverage segments (each a start/end date from an employer, individual, or public plan) and DETERMINISTICALLY sorts them, MERGES the overlapping / adjacent ones into continuous spans (a gap of 0 days — the next starts the day after the previous ends — still merges), totals the inclusive covered days, measures the GAPS between consecutive spans, and flags a SIGNIFICANT BREAK when a gap exceeds the threshold (63 days by the HIPAA / ACA rule, DEFAULT_MAX_GAP_DAYS). It COMPLEMENTS, not duplicates, the other payer-operations agents: distinct from the Benefits Verification agent (is coverage active NOW), the Coordination of Benefits agent (the ORDER of concurrent coverages), the Enrollment Reconciliation agent (employer-vs-carrier roster drift), the Member Cost-Share agent (splitting a claim), and the MLR Rebate agent (a plan-year rebate) — this measures the CONTINUITY of a member's coverage OVER TIME. TIME IS DATA: the analysis is a pure function of the segments + the request's own asOfDate (no real clock; all interval math via UTC epoch-day integers), so the same segments always yield the same spans + gaps + determination. A determination — continuous coverage OR a significant break — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresEligibilityReview:true, autoDetermined:false), which is how a legitimate determination is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Enrollment Reconciliation and MLR Rebate agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.coverage.segments-sourced (signal coverageSegmentsSourced, violating value false) blocks a determination whose merged span does not trace to submitted segments — each span's start / end must come from a real segment boundary and every submitted segment must fall within a merged span, because fabricated coverage (a span not backed by a segment) would wrongly certify continuity and dropped coverage would wrongly find a break — backed by the pure guard coverageSegmentsSourced (mirroring the Care Pathway Agent's steps-sourced and the Drug Interaction Agent's interaction-sourced posture); policy.coverage.math-consistent (signal coverageMathConsistent, violating value false) blocks a determination whose math does not add up — the merged spans must be ordered + non-overlapping (each start ≤ end, strictly gapped from the previous), the total covered days must equal the sum of the spans' inclusive lengths, each reported gap must equal the exact day distance between consecutive spans, and the significant-break flag must equal whether any gap exceeds the threshold; the guard recomputes the totals, the gaps, and the break flag from the spans (this is the load-bearing correctness gate, mirroring the Member Cost-Share Agent's math-consistent and the MLR Rebate Agent's allocation-consistent) — backed by the guard coverageMathConsistent; and policy.coverage.no-autonomous-determination (signal coverageNoAutonomousDetermination, violating value false) blocks a determination that autonomously issued a creditable-coverage determination (autoDetermined:true — issuing a determination, denying special enrollment, or imposing a late-enrollment penalty is a coverage decision that must be authorized) or did not require eligibility review (requiresEligibilityReview:false) — the agent MEASURES, and every determination is a RECOMMENDATION requiring an eligibility reviewer to confirm — backed by the guard coverageNoAutonomousDetermination (mirroring the Enrollment Reconciliation Agent's no-autonomous-change and the MLR Rebate Agent's no-autonomous-disbursement posture; the harmful action is enforced-off). It IS PHI-bearing — the segments reference the member's coverage history — so it reuses, by extending appliesTo, the HIPAA-audit policy (phiAccessed:true throughout), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/coverage-continuity/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — coverage.receive-segments → coverage.merge-intervals → coverage.detect-gaps → coverage.log-audit — with phiAccessed:true, returning the CoverageContinuityDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Coverage Continuity panel (a 14-day-gap preset → continuous; a 153-day-gap preset → significant break; an overlapping-coverage preset → merged into a single continuous span with no gaps; plus fabricated-span / miscounted-math / auto-determined governance-block presets), a seeded coverage.receive-segments→merge-intervals→detect-gaps→log-audit trace showing the continuous case (352 covered days across 2 spans, requiresEligibilityReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'seventy-six agents', with the Coverage Continuity agent on the payer-operations tier alongside the Enrollment Reconciliation and the other payer agents) all reflect it. Menopause-relevant: a 45-64 woman who leaves an employer plan and has a 2-month gap before her individual-market coverage begins is exactly the case this checks — a 14-day gap keeps her creditable coverage intact, but a break over 63 days would cost her the pre-existing-condition protection she needs for ongoing menopause care. Frontend tests green (3,251 tests — + coverage date-helper round-trip / continuous-under-threshold / significant-break / overlap-merge / adjacent-merge / invalid-segment-skip / custom-threshold / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / continuous + break + overlap happy paths, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to seventy-six agents); the segments + threshold are clearly-labeled illustrative synthetics, NOT a certified creditable-coverage system — real determination uses the certificate of creditable coverage, plan-specific rules, and the full HIPAA / ACA / Medicare Part D frameworks. Lint + build clean.

94a42c6 agent fabric: add the Creditable Coverage Continuity agent (76th) — deterministic interval-merge + gap-detection over a member's coverage segments, flagging a significant break (>63-day gap) in creditable coverage, with every merged span sourced, exact coverage math, and never an autonomous coverage determination

Agent Fabric: added the Care Pathway Sequencing agent — deterministic topological ordering (Kahn's algorithm) of a clinical pathway's steps to respect their prerequisite dependencies, detecting dependency cycles and missing prerequisites, with every step sourced, an order that never violates a prerequisite, and never an autonomous step execution (the 75th agent)

Shipped
Details

Added the seventy-fifth agent on the fabric — care-pathway-agent, a DETERMINISTIC (no-Claude) clinical-decision service on the patient / clinical plane, reusing the existing clinical-decision tier as a SIBLING to the Care Plan, Drug Interaction, Controlled Substance / PDMP, Formulary & DUR, Medication Adherence, Prior Authorization, Immunization, and Lab Result agents — it does NOT invent a new tier or plane, and it is a RETURN TO THE PATIENT / CLINICAL PLANE after two payer-operations agents (Member Cost-Share, MLR Rebate, Enrollment Reconciliation). It is DELIBERATELY a DIFFERENT KIND of logic — a genuinely NEW computation pattern for the fabric: there is NO date math (unlike the Amendment / Right of Access / Timely Filing agents), NO dollar waterfall (unlike the Member Cost-Share agent), NO single-record classifier (unlike the Information Blocking agent), NO pairwise lookup (unlike the Drug Interaction agent), and — crucially — it is NOT the Enrollment Reconciliation agent's KEYED SET-DIFFERENCE, the OIG Exclusion agent's identity MATCHING, or the MLR Rebate agent's RATIO + apportionment: the heart of the service is a TOPOLOGICAL ORDERING (Kahn's algorithm) over a dependency graph + CYCLE DETECTION. A clinical pathway — a staged, evidence-based plan such as a menopause work-up-to-treatment pathway — is a set of steps with prerequisite dependencies; sequencing puts them in a safe order. In a new pure lib/care-pathway.ts, evaluateCarePathway(request) takes a pathway (a pathway reference, a patient reference, and the steps, each declaring the prerequisite step ids that must precede it) and DETERMINISTICALLY runs Kahn's algorithm (repeatedly emitting a ready step — in-degree 0 — with the smallest step id, so ties break deterministically), reporting the disposition — sequenced (the ordered steps, with each step's stage = longest-prerequisite-chain depth), cannot-sequence-cycle-detected (the steps in a circular dependency, where no valid order exists), or cannot-sequence-missing-prerequisite (the steps whose prerequisites reference ids absent from the pathway). It COMPLEMENTS, not duplicates, the other clinical agents: distinct from the Care Plan agent (which AUTHORS a plan's goals / interventions / cadence from a template), the Transitions of Care and Care Coordination Handoff agents (moving a patient between settings / teams), the Prior Authorization agent (assembling a PA package), and the Drug Interaction / Controlled Substance agents (medication safety) — this ORDERS the steps of a pathway so no step is scheduled before its prerequisites. The determination is a pure function of the pathway's steps (no randomness, no clock), so the same pathway always yields the same order. A determination — a sequenced pathway, a detected cycle, OR a missing prerequisite — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresClinicianReview:true, autoExecuted:false), which is how a legitimate determination is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Drug Interaction and Enrollment Reconciliation agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.pathway.steps-sourced (signal pathwayStepsSourced, violating value false) blocks a determination that references a step id — in its ordered sequence, stage map, reported cycle members, or missing-prerequisite holders — that is not one of the submitted pathway steps, because a fabricated / dangling step id would order or flag care that doesn't exist — backed by the pure guard pathwayStepsSourced (mirroring the Drug Interaction Agent's interaction-sourced and the Enrollment Reconciliation Agent's actions-sourced posture); policy.pathway.sequence-valid (signal pathwaySequenceValid, violating value false) blocks a determination whose sequence is inconsistent with its steps — when reported SEQUENCED, the ordered steps must be a complete permutation of the pathway's steps (none dropped or duplicated) and every step must appear AFTER all of its prerequisites (ordering a treatment step before its safety-screening prerequisite is the worst failure mode), and when reported un-sequenceable no order may be asserted; the guard re-derives the ordering constraints from the steps and verifies them (this is the load-bearing correctness gate, mirroring the Member Cost-Share Agent's math-consistent and the Enrollment Reconciliation Agent's reconciliation-complete) — backed by the guard pathwaySequenceValid; and policy.pathway.no-autonomous-execution (signal pathwayNoAutonomousExecution, violating value false) blocks a determination that autonomously executed a step (autoExecuted:true — ordering a lab, a screening, or a therapy is a clinical action that must be authorized) or did not require clinician review (requiresClinicianReview:false) — the agent SEQUENCES, and every determination is a RECOMMENDATION requiring a clinician to confirm and order — backed by the guard pathwayNoAutonomousExecution (mirroring the Drug Interaction Agent's no-autonomous-hold-or-override and the Lab Result Agent's no-autonomous-clinical-action posture; the harmful action is enforced-off). It IS PHI-bearing — the pathway references the patient — so it reuses, by extending appliesTo, the HIPAA-audit policy (phiAccessed:true throughout), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/care-pathway/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — pathway.receive-steps → pathway.check-prerequisites → pathway.topological-sort → pathway.log-audit — with phiAccessed:true, returning the CarePathwayDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Care Pathway panel (a menopause work-up pathway preset → sequenced into 5 stages, shown staged; a circular-dependency preset → cannot-sequence-cycle-detected; a missing-prerequisite preset → cannot-sequence-missing-prerequisite; plus fabricated-step / invalid-order / auto-executed governance-block presets), a seeded pathway.receive-steps→check-prerequisites→topological-sort→log-audit trace showing the sequenced menopause pathway (6 steps across 5 stages, requiresClinicianReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'seventy-five agents', with the Care Pathway agent on the clinical-decision tier alongside the Care Plan and the other clinical agents) all reflect it. Menopause-relevant: a menopause work-up pathway — baseline labs, then confirm-diagnosis + cardiovascular / breast-cancer risk screening in parallel, then a shared decision-making visit, then initiate MHT or non-hormonal therapy, then a 3-month follow-up — is exactly the kind of dependency-ordered pathway this sequences so the risk screening always precedes the treatment decision. Frontend tests green (3,213 tests — + care-pathway topological-sort / respects-prerequisites / cycle-detection / missing-prerequisite / determinism / tie-break-by-id / three-signal-true-and-false guards, the route's envelope / three governance blocks / sequenced + cycle + missing happy paths, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to seventy-five agents); the pathways + steps are clearly-labeled illustrative synthetics, NOT a certified clinical pathway engine — real pathway management uses evidence-based order sets, the patient's clinical context, scheduling / timing constraints, and the care team's judgment. Lint + build clean.

269919b agent fabric: add the Care Pathway Sequencing agent (75th) — deterministic topological ordering (Kahn's algorithm) of a clinical pathway's steps to respect their prerequisite dependencies, detecting dependency cycles and missing prerequisites, with every step sourced, an order that never violates a prerequisite, and never an autonomous step execution

Agent Fabric: added the Eligibility & Enrollment (834) Reconciliation agent — deterministic keyed set-difference + field-level comparison of a group's employer roster against the carrier's roster, producing enroll / terminate / update / no-change actions, with every member accounted for exactly once, every action sourced (no fabricated discrepancy), and never an autonomous enrollment change (the 74th agent)

Shipped
Details

Added the seventy-fourth agent on the fabric — enrollment-reconciliation-agent, a DETERMINISTIC (no-Claude) claims / payer-operations service on the payer & plan operations plane, reusing the existing payer-operations tier as a SIBLING to the Claims Adjudication, Coordination of Benefits, Claims Overpayment & Recovery, Timely Filing, Subrogation, Member Cost-Share / EOB, Medical Loss Ratio (MLR) Rebate, and OIG Exclusion agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic from every prior agent: there is NO date math (unlike the Amendment, Right of Access, and Timely Filing agents), NO single-record classifier (unlike the Information Blocking agent), NO pairwise lookup (unlike the Drug Interaction agent), and — crucially — it is NOT the Member Cost-Share agent's SEQUENTIAL dollar waterfall, the OIG Exclusion agent's identity MATCHING, or the MLR Rebate agent's RATIO + apportionment: the heart of the service is a KEYED SET-DIFFERENCE + a FIELD-LEVEL COMPARISON. The X12 834 EDI transaction is how employers send enrollment to carriers; the two sides drift — a new hire the carrier hasn't loaded, a departed employee still on the carrier, a coverage-tier change that didn't propagate — and reconciliation finds the delta. In a new pure lib/enrollment-reconciliation.ts, evaluateEnrollmentReconciliation(request) takes a reconciliation request (a group reference, the source-of-truth roster — the employer / HR feed, the carrier's current roster, and optionally which fields to compare) and DETERMINISTICALLY keys both rosters by member id, walks the UNION, and classifies each member — in source only → enroll; in carrier only → terminate; in both with a differing compared field → update (listing the field deltas); in both and identical → no-change. It COMPLEMENTS, not duplicates, the other payer-operations agents: distinct from the Claims Adjudication agent (the allowed amount), the Member Cost-Share agent (splitting ONE claim into member vs. plan), the Coordination of Benefits agent (the order of coverages), the MLR Rebate agent (a plan-year rebate), and the OIG Exclusion agent (screening a party against the sanctions list) — this reconciles WHO is enrolled, the membership roster itself, between the employer and the carrier. The determination is a pure function of the two rosters (no randomness, no clock), so the same two rosters always yield the same actions. A reconciliation — any set of actions, including all-no-change — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresBenefitsAdminReview:true, autoApplied:false), which is how a legitimate reconciliation is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Member Cost-Share, MLR Rebate, and OIG Exclusion agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.enrollment.reconciliation-complete (signal reconciliationComplete, violating value false) blocks a determination that does not account for EVERY member EXACTLY once — the per-kind counts must sum to the number of actions, the total-members count must equal the number of actions, the counts must match the actual per-kind tallies, and no member may appear twice; a dropped member is the worst failure mode (a terminated employee who keeps coverage, or a new hire who never gets enrolled) — this is the load-bearing correctness gate (mirroring the Member Cost-Share Agent's math-consistent and the MLR Rebate Agent's allocation-consistent) — backed by the pure guard reconciliationComplete; policy.enrollment.actions-sourced (signal reconciliationActionsSourced, violating value false) blocks a determination carrying a fabricated discrepancy or a mis-shaped action — every UPDATE must carry at least one genuinely-differing field (each delta's source value actually differs from its carrier value), and every NO-CHANGE / ENROLL / TERMINATE must carry none; an 'update' whose fields don't actually differ, or a 'no-change' that hides a real difference, drives wrong enrollment writes — backed by the guard reconciliationActionsSourced (mirroring the OIG Exclusion Agent's match-not-overstated and the Drug Interaction Agent's interaction-sourced posture); and policy.enrollment.no-autonomous-change (signal reconciliationNoAutonomousChange, violating value false) blocks a determination that autonomously applied the enrollment changes (autoApplied:true — enrolling / terminating / updating a member is a coverage decision that must be authorized) or did not require benefits-admin review (requiresBenefitsAdminReview:false) — the agent RECONCILES, and every determination is a RECOMMENDATION requiring a benefits administrator to confirm and post — backed by the guard reconciliationNoAutonomousChange (mirroring the Member Cost-Share Agent's no-autonomous-member-charge and the MLR Rebate Agent's no-autonomous-disbursement posture; the harmful action is enforced-off). It IS PHI-bearing — the rosters reference members and their coverage — so it reuses, by extending appliesTo, the HIPAA-audit policy (phiAccessed:true throughout, unlike the NON-PHI MLR Rebate and OIG Exclusion agents), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/enrollment-reconciliation/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — enrollment.receive-rosters → enrollment.diff-rosters → enrollment.classify-actions → enrollment.log-audit — with phiAccessed:true, returning the EnrollmentReconciliationDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Enrollment Reconciliation panel (a drifted-rosters preset → one of each action, with the coverageTier delta shown; an agreeing-rosters preset → all no-change; a new-group empty-carrier preset → all enroll; plus dropped-member / fabricated-discrepancy / auto-applied governance-block presets), a seeded enrollment.receive-rosters→diff-rosters→classify-actions→log-audit trace showing the four-member drift (1 enroll / 1 terminate / 1 update / 1 no-change, requiresBenefitsAdminReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'seventy-four agents', with the Enrollment Reconciliation agent on the payer-operations tier alongside the Member Cost-Share, MLR Rebate, and the other payer agents) all reflect it. Menopause-relevant: a 45-64 woman whose employer changed her from employee-only to family coverage after a qualifying event is exactly the kind of tier-change this reconciliation catches when it didn't propagate to the carrier — so her claims adjudicate correctly. Frontend tests green (3,178 tests — + enrollment field-deltas / drift-classification / all-no-change / all-enroll / sort-and-determinism / custom-compared-fields / three-signal-true-and-false guards, the route's envelope / three governance blocks / drift + clean + new-group happy paths, the panel's presets / request-body / view-lift, and the registry + brief drift guards raised to seventy-four agents); the rosters + compared fields are clearly-labeled illustrative synthetics, NOT a certified 834 / enrollment system — real reconciliation uses the full X12 834 transaction set, effective-dating / retroactivity rules, dependent / COBRA / qualifying-event handling, and the carrier's eligibility system. Lint + build clean.

1ecbb84 agent fabric: add the Eligibility & Enrollment (834) Reconciliation agent (74th) — deterministic keyed set-difference + field-level comparison of a group's employer roster against the carrier's roster, producing enroll / terminate / update / no-change actions, with every member accounted for exactly once, every action sourced, and never an autonomous enrollment change

Agent Fabric: added the Medical Loss Ratio (MLR) Rebate Calculation agent — deterministic ACA MLR computation that, when a plan falls short of its market standard, apportions the rebate owed across subscribers penny-exactly, with the standard sourced to the market catalog, an MLR + apportionment that always add up, and never an autonomous disbursement (the 73rd agent)

Shipped
Details

Added the seventy-third agent on the fabric — mlr-rebate-agent, a DETERMINISTIC (no-Claude), NON-PHI claims / payer-operations service on the payer & plan operations plane, reusing the existing payer-operations tier as a SIBLING to the Claims Adjudication, Coordination of Benefits, Claims Overpayment & Recovery, Timely Filing, Subrogation, Member Cost-Share / EOB, and OIG Exclusion agents — it does NOT invent a new tier or plane. It is DELIBERATELY a DIFFERENT KIND of logic from the recent agents: there is NO date math (unlike the Amendment, Right of Access, and Timely Filing agents), NO single-record classifier (unlike the Information Blocking agent), NO pairwise lookup (unlike the Drug Interaction agent), and — crucially — it is NOT the Member Cost-Share agent's SEQUENTIAL dollar waterfall or the OIG Exclusion agent's identity MATCHING: the heart of the service is a RATIO-vs-THRESHOLD test + an EXACT PROPORTIONAL APPORTIONMENT (largest-remainder / Hamilton method). The ACA (45 CFR Part 158) requires insurers to spend a minimum share of premium on care + quality improvement (80% individual / small-group, 85% large-group) and to REBATE the shortfall to subscribers. In a new pure lib/mlr-rebate.ts, evaluateMlrRebate(request) takes a rebate request (a plan reference, the market, the plan-year earned premium / incurred claims / quality-improvement expense / taxes & fees, and the subscriber premium roster) and DETERMINISTICALLY computes the MLR = (incurred claims + quality improvement) / (earned premium − taxes & fees), decides whether it meets the market standard, computes the total rebate owed = max(0, standard − MLR) × earned premium, and apportions it across the subscribers penny-exactly via apportionLargestRemainder() — every share gets the floor of its exact proportional cents, then the leftover cents go one-at-a-time to the largest fractional remainders, so the allocated cents sum EXACTLY to the total (no penny lost or invented). It COMPLEMENTS, not duplicates, the other payer-operations agents: distinct from the Claims Adjudication agent (the allowed amount), the Member Cost-Share agent (splitting ONE claim's allowed amount into member vs. plan), the Coordination of Benefits agent (the order of coverages), the Overpayment & Recovery agent (clawing back an overpayment), and the Subrogation agent (third-party recovery) — this computes a PLAN-YEAR-level rebate owed to subscribers under the ACA MLR rule and apportions it fairly. The determination is a pure function of the request's own fields + the market standard (no randomness, no clock), so the same plan year always yields the same MLR + rebate + apportionment. A determination — a rebate owed OR the standard met (no rebate) — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresTreasuryReview:true, autoDisbursed:false), which is how a legitimate determination is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Member Cost-Share and OIG Exclusion agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.mlr.inputs-sourced (signal mlrInputsSourced, violating value false) blocks a determination whose applied standard is off-catalog or does not match its market — the applicable standard must resolve in the recorded MLR_STANDARDS catalog for the market, because a mis-stated standard wrongly triggers or wrongly avoids a rebate — backed by the pure guard mlrInputsSourced (mirroring the Member Cost-Share Agent's benefit-design-sourced and the Good Faith Estimate Agent's charge-master-sourced posture); policy.mlr.allocation-consistent (signal mlrAllocationConsistent, violating value false) blocks a determination whose MLR does not equal (claims + quality improvement) / (earned premium − taxes & fees), whose total rebate does not equal max(0, standard − MLR) × earned premium, or whose per-subscriber allocations do not sum EXACTLY (to the penny) to the total rebate (or where an allocation is negative) — a rebate that doesn't add up, or an apportionment that loses / invents pennies, is a compliance and accounting defect; the guard recomputes the ratio, the total, and the penny-exact sum (this is the load-bearing correctness gate, mirroring the Member Cost-Share Agent's math-consistent and the Risk Adjustment Agent's score-consistent) — backed by the guard mlrAllocationConsistent; and policy.mlr.no-autonomous-disbursement (signal mlrNoAutonomousDisbursement, violating value false) blocks a determination that autonomously disbursed the rebate (autoDisbursed:true — a movement of money to members that must be authorized) or did not require treasury review (requiresTreasuryReview:false) — the agent CALCULATES, and every determination is a RECOMMENDATION requiring a treasury / compliance reviewer to confirm and issue payment — backed by the guard mlrNoAutonomousDisbursement (mirroring the Member Cost-Share Agent's no-autonomous-member-charge and the OIG Exclusion Agent's no-autonomous-block-or-clear posture; the harmful action is enforced-off). It is deliberately NOT PHI-bearing — it works on AGGREGATE plan-year financials + a subscriber premium roster, no patient health information — so it is NOT on the HIPAA-audit policy (phiAccessed:false throughout, like the OIG Exclusion agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/mlr-rebate/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — mlr.receive-financials → mlr.compute-ratio → mlr.apportion-rebate → mlr.log-audit — with phiAccessed:false, returning the MlrRebateDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new MLR Rebate panel (an individual 77.89% < 80% preset → $21,100 rebate apportioned 8,440 / 7,385 / 5,275; a large-group 89.58% ≥ 85% preset → standard met, no rebate; a small-group $8,400 preset whose uneven premiums exercise the largest-remainder penny distribution; plus off-catalog-standard / inconsistent-apportionment / auto-disbursed governance-block presets), a seeded mlr.receive-financials→compute-ratio→apportion-rebate→log-audit trace showing the individual-market rebate ($21,100, requiresTreasuryReview:true, phiAccessed:false), the console subtitle, and the investor brief (now 'seventy-three agents', with the MLR Rebate agent on the payer-operations tier alongside the Member Cost-Share and the other payer agents) all reflect it. Menopause-relevant: a 45-64 woman in an individual-market plan is exactly a subscriber who receives an MLR rebate check when her insurer under-spends on care — and who benefits from the apportionment being exact and audit-defensible. Frontend tests green (3,142 tests — + mlr standards-catalog / largest-remainder-sums-exactly / leftover-cent-to-largest-remainder / individual-rebate / large-group-meets / small-group-uneven / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / individual + large-group + small-group happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to seventy-three agents); the market standards + simplified MLR formula are clearly-labeled illustrative synthetics (no NAIC MLR Annual Reporting Form, credibility adjustments, multi-year averaging, or permitted claim / premium adjustments), NOT a certified MLR filing system — real MLR reporting is governed by 45 CFR Part 158. Lint + build clean.

1f90490 agent fabric: add the Medical Loss Ratio (MLR) Rebate Calculation agent (73rd) — deterministic ACA MLR ratio-vs-threshold test + exact largest-remainder apportionment of the rebate owed across subscribers, with the standard sourced, an MLR + apportionment that always add up, and never an autonomous disbursement

Agent Fabric: added the Drug–Drug Interaction (DDI) Safety Check agent — deterministic screening of a proposed medication against the patient's active list, with every interaction sourced to the knowledge base, an overall severity that can never be inflated or suppressed, and never an autonomous order hold or alert override (the 72nd agent)

Shipped
Details

Added the seventy-second agent on the fabric — drug-interaction-agent, a DETERMINISTIC (no-Claude) clinical-decision service on the patient / clinical plane, reusing the existing clinical-decision tier as a SIBLING to the Controlled Substance / PDMP Safety Check, Formulary & DUR Review, Medication Adherence, Prior Authorization, Immunization Forecasting, Lab Result, and Claude Care Router agents — it does NOT invent a new tier or plane, and it is a RETURN TO THE PATIENT / CLINICAL PLANE after three platform / data-substrate agents (Amendment, Information Blocking, and the Accounting-of-Disclosures substrate work). It is DELIBERATELY a DIFFERENT KIND of logic from the recent agents: there is NO date math (unlike the Amendment, Right of Access, and Timely Filing agents), NO dollar waterfall (unlike the Member Cost-Share agent), and NO single-record exception classifier (unlike the Information Blocking agent) — the heart of the service is a PAIRWISE KNOWLEDGE-BASE LOOKUP + a SEVERITY RANKING. In a new pure lib/drug-interaction.ts, evaluateDrugInteractions(request) takes a screen request (a patient reference, a proposed / new drug, and the patient's active medication list) and DETERMINISTICALLY pairs the proposed drug with each active medication, looks up every recorded interaction in an illustrative DDI_INTERACTIONS knowledge base (order-independent via a sorted-pair key), ranks the detected interactions by severity (contraindicated > major > moderate > minor via DDI_SEVERITY_RANK), reports the overall severity + each interaction's mechanism + management, and decides the disposition (no-interaction-detected / monitor / review-recommended / review-required / do-not-coadminister-needs-review). It COMPLEMENTS, not duplicates, the other clinical / medication agents: distinct from the Controlled Substance / PDMP agent (the TOTAL controlled-substance MME burden across prescribers), the Formulary & DUR Review agent (plan-level coverage / step therapy), the Medication Adherence agent (taking an already-prescribed drug), the Prior Authorization agent (assembling a PA package), and the Immunization agent (the vaccine schedule) — this screens whether a NEW drug INTERACTS with what the patient already takes. The determination is a pure function of the request's own fields (no randomness, no clock), so the same proposed drug + active list always yields the same interactions + overall severity + disposition. A finding — an interaction of any severity OR no interaction — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresClinicianReview:true, autoHeldOrder:false, autoOverrodeAlert:false), which is how a legitimate finding is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Controlled Substance and Lab Result agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.ddi.interaction-sourced (signal ddiInteractionSourced, violating value false) blocks a determination that reports an interaction that is off-catalog, or dresses a mismatched severity onto a recorded interaction — every flagged interaction must resolve in the recorded knowledge base with a matching pair + severity, because a fabricated interaction erodes clinician trust and drives alert fatigue — backed by the pure guard ddiInteractionSourced (mirroring the Controlled Substance Agent's guideline-sourced and the Immunization Agent's schedule-sourced posture); policy.ddi.severity-consistent (signal ddiSeverityConsistent, violating value false) blocks a determination whose overall severity does not equal the highest cataloged severity among the detected interactions — an INFLATED severity drives wrongful order cancellation and alert fatigue, and a SUPPRESSED severity hides a contraindication; the guard recomputes the maximum severity from the detected interactions' catalog records and verifies it matches (this is the load-bearing correctness gate, mirroring the Member Cost-Share Agent's math-consistent and the OIG Exclusion Agent's match-not-overstated) — backed by the guard ddiSeverityConsistent; and policy.ddi.no-autonomous-hold-or-override (signal ddiNoAutonomousHoldOrOverride, violating value false) blocks a determination that autonomously held / cancelled the order (autoHeldOrder:true — which could deny needed therapy), overrode the interaction alert (autoOverrodeAlert:true — which could push through a contraindicated combination), or did not require clinician review (requiresClinicianReview:false) — the agent SCREENS, and every finding is a RECOMMENDATION requiring a pharmacist / prescriber to act on or review — backed by the guard ddiNoAutonomousHoldOrOverride (mirroring the Controlled Substance Agent's no-autonomous-prescribing-decision and the Lab Result Agent's no-autonomous-clinical-action posture; the harmful action is enforced-off). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — the screen references the patient's active medication list), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/drug-interaction/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — ddi.receive-order → ddi.match-interactions → ddi.rank-severity → ddi.log-audit — with phiAccessed:true, returning the DrugInteractionDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Drug Interaction panel (a paroxetine+tamoxifen preset → major interaction, review required; a nitroglycerin+sildenafil preset → contraindicated, do-not-coadminister; a rifampin+estradiol preset → moderate, review recommended; an acetaminophen preset → no interaction; plus off-catalog-interaction / inflated-severity / auto-held-order governance-block presets), a seeded ddi.receive-order→match-interactions→rank-severity→log-audit trace showing the paroxetine+tamoxifen major interaction (review-required, requiresClinicianReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'seventy-two agents', with the Drug Interaction agent on the clinical-decision tier alongside the Controlled Substance and the other clinical agents) all reflect it. Menopause-relevant: a 45-64 patient on tamoxifen who is newly prescribed paroxetine for hot flashes is exactly the major CYP2D6 interaction this screen catches before it reaches the pharmacy. Frontend tests green (3,104 tests — + drug-interaction catalog / normalize / order-independent-lookup / disposition-mapping / major / contraindicated / moderate / none / highest-severity / duplicate-med / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / major + contraindicated + none happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to seventy-two agents); the interaction knowledge base + severity assignments are clearly-labeled illustrative synthetics (no dose / route / timing context, no patient-specific factors, no normalized drug vocabularies), NOT a certified clinical decision support system — real interaction checking uses a maintained compendium, RxNorm, and the pharmacist's / prescriber's clinical judgment. Lint + build clean.

3cee86a agent fabric: add the Drug–Drug Interaction (DDI) Safety Check agent (72nd) — deterministic pairwise knowledge-base screen of a proposed medication against the patient's active list, with every interaction sourced, an overall severity that can never be inflated or suppressed, and never an autonomous order hold or alert override

Agent Fabric: added the Information Blocking (21st Century Cures Act / 45 CFR Part 171) agent — deterministic adjudication of whether an actor's practice that interfered with EHI access is information blocking or fits a recorded exception, with exception-sourced claims, an exception that can never be overstated, and never an autonomous EHI withhold or release — the enforcement flip-side of the HIPAA patient-rights trilogy (the 71st agent)

Shipped
Details

Added the seventy-first agent on the fabric — information-blocking-agent, a DETERMINISTIC (no-Claude) control-plane / data-substrate compliance service on the platform plane, reusing the existing data-plane tier (planeForTier('data-plane') === 'platform') as a SIBLING to the Consent & Preferences Management, Master Patient Index, Break-the-Glass, Data Retention, De-Identification, Minimum Necessary, Audit Log Integrity, Accounting of Disclosures, Right of Access, and Amendment / Correction agents — it does NOT invent a new tier or plane, and it is the ENFORCEMENT FLIP-SIDE of the HIPAA PATIENT-RIGHTS TRILOGY: where the trilogy (Right of Access §164.524, Amendment §164.526, Accounting of Disclosures §164.528) gives a patient the RIGHT to get / fix / audit their record, the 21st Century Cures Act's information-blocking rule (45 CFR Part 171) prohibits a provider, health-IT developer, or HIE/HIN from INTERFERING with the access, exchange, or use of electronic health information (EHI) unless the practice satisfies ALL the conditions of a recorded exception. It COMPLEMENTS, not duplicates, the HIPAA privacy agents: they grant a patient's RIGHTS to their record; this enforces that an actor does not INTERFERE with EHI access. It is DELIBERATELY a DIFFERENT KIND of logic from the recent agents — there is NO date math (unlike the Amendment, Right of Access, and Timely Filing agents) and NO dollar waterfall (unlike the Member Cost-Share agent): the heart of the service is a CONDITIONS-SATISFACTION classifier. In a new pure lib/information-blocking.ts, evaluateInformationBlocking(request) takes a practice review (an actor reference + type — provider / health-IT developer / HIE-HIN, the EHI request type — access / exchange / use, a short practice description, whether the practice actually interfered with access, an optional claimed exception, and the set of exception CONDITIONS the actor asserts are satisfied) and DETERMINISTICALLY checks the claimed exception against an illustrative BLOCKING_EXCEPTIONS catalog of the eight 45 CFR Part 171 exceptions across two categories (not-fulfilling requests: preventing harm §171.201, privacy §171.202, security §171.203, infeasibility §171.204, health IT performance §171.205; procedures for fulfilling requests: content & manner §171.301, fees §171.302, licensing §171.303), each carrying an illustrative set of required conditions, then VERIFIES via the shared missingConditionsFor() helper that EVERY required condition of that exception is satisfied, and decides the disposition (not-information-blocking-no-interference when the practice did not interfere; not-information-blocking-exception-met when a cataloged exception's every condition is satisfied; potential-information-blocking-needs-review otherwise — a missing condition, an off-catalog exception, or interference with no exception claimed). The determination is a pure function of the request's own fields (no randomness, no clock), so the same practice review always yields the same exception analysis + disposition. A determination — exception-met, no-interference, OR potential-blocking-needs-review — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresComplianceReview:true, autoBlockedEhi:false, autoReleasedEhi:false), which is how a legitimate determination is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Right of Access and OIG Exclusion agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.information-blocking.exception-sourced (signal blockingExceptionSourced, violating value false) blocks a determination that claims an exception that is off-catalog — a practice escapes the Cures Act information-blocking rule only on a recorded 45 CFR Part 171 exception, and an ad-hoc / un-sourced exception is not a lawful basis to interfere with EHI — backed by the pure guard blockingExceptionSourced (mirroring the Right of Access Agent's ground-sourced and the Amendment Agent's ground-sourced posture); policy.information-blocking.determination-not-overstated (signal blockingDeterminationNotOverstated, violating value false) blocks a determination that reports an exception as SATISFIED (or under-reports its missing conditions) when a required condition of that exception is not met — each exception's conditions must ALL be satisfied, and an overstated 'exception met' is how unlawful interference with EHI is dressed up as a compliant practice; the guard recomputes the missing conditions from the claimed exception + the asserted conditions and verifies exceptionSatisfied / missingConditions match (this is the load-bearing correctness gate, mirroring the OIG Exclusion Agent's match-not-overstated and the Member Cost-Share Agent's math-consistent) — backed by the guard blockingDeterminationNotOverstated; and policy.information-blocking.no-autonomous-block-or-release (signal blockingNoAutonomousBlockOrRelease, violating value false) blocks a determination that autonomously withheld EHI (autoBlockedEhi:true — which could itself be information blocking, or delay urgent care), force-released EHI (autoReleasedEhi:true — which could breach privacy), or did not require compliance review (requiresComplianceReview:false) — the agent ADJUDICATES, and every determination is a RECOMMENDATION requiring a compliance officer to confirm and act — backed by the guard blockingNoAutonomousBlockOrRelease (mirroring the OIG Exclusion Agent's no-autonomous-block-or-clear and the Right of Access Agent's no-autonomous-denial-or-release posture; the harmful action is enforced-off). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is EHI-bearing — the review references a request for the patient's electronic health information), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/information-blocking/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — blocking.receive-practice → blocking.assess-exception → blocking.check-conditions → blocking.log-audit — with phiAccessed:true, returning the InformationBlockingDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Information Blocking panel (a privacy-exception-fully-met preset → not information blocking; a request-fulfilled-normally preset → not information blocking, no interference; an infeasibility-missing-a-condition preset → potential information blocking, needs review; an interference-with-no-exception preset → potential information blocking, needs review; plus off-catalog-exception / overstated-exception / auto-blocked-EHI governance-block presets), a seeded blocking.receive-practice→assess-exception→check-conditions→log-audit trace showing a privacy-precondition hold with every condition satisfied (not-information-blocking-exception-met, requiresComplianceReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'seventy-one agents', with the Information Blocking agent on the platform data-plane tier alongside the Right of Access, Amendment, and the other substrate agents — the enforcement flip-side of the patient-rights trilogy) all reflect it. Frontend tests green (3,058 tests — + information-blocking exception-catalog / missing-conditions / exception-met / no-interference / missing-condition / no-exception / off-catalog / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / exception-met + no-interference + missing-condition happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to seventy-one agents); the exception catalog + condition sets are clearly-labeled illustrative synthetics, NOT certified information-blocking compliance counsel — real analysis is governed by the 21st Century Cures Act and 45 CFR Part 171 (the full text of the eight exceptions and every sub-condition), the ONC / ASTP rules, and OIG enforcement (§171 penalties / disincentives). Lint + build clean.

7e2cee0 agent fabric: add the Information Blocking (Cures Act / 45 CFR Part 171) agent (71st) — deterministic conditions-satisfaction adjudication of whether a practice is information blocking or fits a recorded exception, with exception-sourced claims, an exception that can never be overstated, and never an autonomous EHI withhold or release, the enforcement flip-side of the HIPAA patient-rights trilogy

Agent Fabric: added the Amendment / Correction (HIPAA §164.526) agent — deterministic adjudication of a patient's right to FIX their record, with ground-sourced denials, a computed 60/90-day response deadline, and never an autonomous amendment or denial — completing the HIPAA patient-rights trilogy (the 70th agent)

Shipped
Details

Added the seventieth agent on the fabric — amendment-request-agent, a DETERMINISTIC (no-Claude) control-plane / data-substrate privacy service on the platform plane, reusing the existing data-plane tier (planeForTier('data-plane') === 'platform') as a SIBLING to the Consent & Preferences Management, Master Patient Index, Break-the-Glass, Data Retention, De-Identification, Minimum Necessary, Audit Log Integrity, Accounting of Disclosures, and Right of Access agents — it does NOT invent a new tier or plane, and it CAPSTONES the HIPAA PATIENT-RIGHTS TRILOGY: it is the third leg alongside the Right of Access agent (§164.524 — the right to GET a copy of your record) and the Accounting of Disclosures agent (§164.528 — the right to know WHO your PHI was disclosed to); this answers the §164.526 right to FIX your record. It COMPLEMENTS, not duplicates, the other platform / privacy agents: distinct from the Right of Access agent (§164.524 — GET a copy), the Accounting of Disclosures agent (§164.528 — WHO it was disclosed to), the Consent & Preferences Management agent (WHETHER a patient may be contacted / data used), the Minimum Necessary agent (HOW MUCH PHI a purpose may see), and the Data Retention agent (records disposition), this answers the patient's §164.526 RIGHT to request an AMENDMENT / CORRECTION of the record, and BY WHEN. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/amendment-request.ts, evaluateAmendment(request) takes an amendment request (a patient reference, the record and request type, the request date, an as-of date, whether the PHI is in a designated record set, whether the covered entity created the PHI and whether the originator is available, whether the PHI is available for access under §164.524, whether the PHI is already accurate and complete, and whether the single 30-day extension was invoked) and DETERMINISTICALLY computes the §164.526 response deadline (request date + 60 days, or + 90 when the extension is invoked, via pure UTC date math — addDays / daysBetween, dates taken as data, NO Date.now()), derives which denial ground (if any) applies via the shared deriveDenialGround() helper in statutory precedence order against an illustrative AMENDMENT_DENIAL_GROUNDS catalog (the covered entity did not create the PHI and the originator is available; the PHI is not part of the designated record set; the PHI is not available for access under §164.524; or the PHI is already accurate and complete), and decides the disposition (recommend-accept / recommend-deny, the latter carrying the patient's statement-of-disagreement rights). The determination is a pure function of the request's own fields (no randomness, no clock), so the same request always yields the same deadline + ground + disposition. A determination — accept OR deny — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresHumanReview:true, autoAmended:false, autoDenied:false), which is how a legitimate determination is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Right of Access and Accounting of Disclosures agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.amendment.ground-sourced (signal amendmentGroundSourced, violating value false) blocks a determination that denies (or asserts a denial ground) that is off-catalog — a §164.526 denial is permitted only on a recorded statutory ground, and an ad-hoc / un-sourced ground is not a lawful basis to refuse a patient's amendment (it also rejects an accept that improperly asserts a denial ground) — backed by the pure guard amendmentGroundSourced (mirroring the Right of Access Agent's ground-sourced and the Accounting of Disclosures Agent's purpose-category-sourced posture); policy.amendment.deadline-computed (signal amendmentDeadlineComputed, violating value false) blocks a determination whose response deadline (or days-until) does not equal the request date + 60 days (+ 30 more when the single extension is invoked) — a guessed / mis-stated deadline is how an amendment request quietly runs past its §164.526 legal clock (this is the load-bearing correctness gate, mirroring the Right of Access Agent's deadline-computed and the Timely Filing Agent's deadline-computed — the determination echoes its own requestDate / asOfDate so the guard is self-contained and recomputes the deadline) — backed by the guard amendmentDeadlineComputed; and policy.amendment.no-autonomous-write-or-denial (signal amendmentNoAutonomousWrite, violating value false) blocks a determination that autonomously amended the record (autoAmended:true — a data write to the medical record that ripples to every downstream holder the PHI was shared with), denied the request (autoDenied:true — a legal act carrying the patient's statement-of-disagreement rights), or did not require human review (requiresHumanReview:false) — the agent ADJUDICATES, and every determination is a RECOMMENDATION requiring a records / privacy officer to act on or review — backed by the guard amendmentNoAutonomousWrite (mirroring the Right of Access Agent's no-autonomous-denial-or-release and the Minimum Necessary Agent's no-autonomous-over-disclosure posture; the harmful action is enforced-off). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — the amendment decision references the patient's record), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/amendment-request/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — amendment.receive-request → amendment.assess-grounds → amendment.compute-deadline → amendment.log-audit — with phiAccessed:true, returning the AmendmentDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Amendment Request panel (a correctable-clinical-note preset → recommend accept, due in 60 days; an accurate-and-complete preset → recommend deny with statement-of-disagreement rights; a not-originator preset → recommend deny with a referral; a complex-request preset → recommend accept with the single 30-day extension invoked, deadline computed at 90 days; plus off-catalog-ground / wrong-deadline / auto-amended governance-block presets), a seeded amendment.receive-request→assess-grounds→compute-deadline→log-audit trace showing a correctable note (recommend-accept, due 2026-10-14 with 37 days remaining, requiresHumanReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'seventy agents', with the Amendment / Correction agent on the platform data-plane tier alongside the Right of Access and the other substrate agents — completing the patient-rights trilogy) all reflect it. Frontend tests green (3,013 tests — + amendment date-math / derive-ground precedence / accept / accurate-and-complete-deny / not-originator-deny / extension / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / accept + accurate-deny + extension happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to seventy agents); the denial-ground catalog + 60/90-day math are clearly-labeled illustrative synthetics, NOT a certified HIM system — real amendment is governed by HIPAA §164.526 (the full denial grounds, the written-denial + statement-of-disagreement + rebuttal process, and the duty to notify other holders of an accepted amendment) and the covered entity's Notice of Privacy Practices. Lint + build clean.

139dffd agent fabric: add the Amendment / Correction (HIPAA §164.526) agent (70th) — deterministic adjudication of a patient's right to fix their record with ground-sourced denials, a computed 60/90-day deadline, and never an autonomous amendment or denial, completing the HIPAA patient-rights trilogy

Agent Fabric: added the OIG Exclusion / Sanctions Screening agent — deterministic screening of a party against the OIG LEIE before payment, with a match-record-sourced catalog, a match strength that can never be overstated, and never an autonomous payment block or clear (the 69th agent)

Shipped
Details

Added the sixty-ninth agent on the fabric — exclusion-screening-agent, a DETERMINISTIC (no-Claude) claims / payer-operations service on the payer & plan operations plane, reusing the existing payer-operations tier as a SIBLING to the Claims Adjudication, Coordination of Benefits, Claims Overpayment & Recovery, Timely Filing, Subrogation, Member Cost-Share, Good Faith Estimate, and Balance Billing agents — it does NOT invent a new tier or plane. Federal law (Social Security Act §1128 / §1128A(a)(6); 42 CFR §1001) prohibits federal-program payment for items or services furnished, ordered, or prescribed by an OIG-EXCLUDED party, so plans and providers must SCREEN parties against the OIG List of Excluded Individuals / Entities (LEIE) before payment / contracting — and this agent does exactly that: in a new pure lib/exclusion-screening.ts, evaluateScreening(request) takes a screening request (a party reference and the party's identifiers — last name, first name, and optionally an NPI and a date of birth) and DETERMINISTICALLY matches the party against an illustrative EXCLUSION_RECORDS catalog, reporting a match STRENGTH grounded in which identifiers actually matched (via the shared supportableStrength() helper): a confirmed match requires an NPI match OR a full-name AND date-of-birth match; a full-name match with no DOB / NPI is probable; a last-name coincidence the first name / DOB doesn't corroborate is possible; otherwise no-match — with a recommended disposition (recommend-clear / recommend-review-possible / recommend-review-probable / recommend-block-pending-review). It COMPLEMENTS, not duplicates, the other agents: distinct from the Provider Credentialing agent (whether a provider is QUALIFIED — license, board certification, education), the Claims Adjudication Assistant (the allowed amount), and the FWA agent (suspected fraud on a claim), this screens a party's IDENTITY against the OIG exclusion list to prevent an improper PAYMENT to a sanctioned party. The match is a pure function of the party's own fields + the catalog (no randomness, no clock), so the same party always yields the same match strength. A determination — match OR no-match — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresComplianceReview:true, autoBlockedPayment:false, autoCleared:false), which is how a legitimate determination is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Member Cost-Share and Subrogation agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.exclusion.match-record-sourced (signal exclusionMatchSourced, violating value false) blocks a determination that reports a match (anything other than no-match) without citing a matchedExclusionId that resolves in the recorded LEIE catalog — a match asserted without a sourced exclusion record is not a lawful basis to hold a payment — backed by the pure guard exclusionMatchSourced (mirroring the Right of Access Agent's ground-sourced and the Subrogation Agent's basis-sourced posture); policy.exclusion.match-not-overstated (signal exclusionMatchNotOverstated, violating value false) blocks a determination whose reported match strength exceeds what the identifier signals support — a name coincidence dressed up as a confirmed exclusion — because overstating a match is how a legitimate provider's payment is wrongly held on a shared name (this is the load-bearing correctness gate, mirroring the Member Cost-Share Agent's math-consistent and the Subrogation Agent's recoverable-within-paid; the guard recomputes the supportable strength from the determination's own npiMatch / nameMatch / dobMatch signals) — backed by the guard exclusionMatchNotOverstated; and policy.exclusion.no-autonomous-block-or-clear (signal exclusionNoAutonomousBlockOrClear, violating value false) blocks a determination that autonomously blocked a payment (autoBlockedPayment:true), cleared a party (autoCleared:true), or did not require compliance review (requiresComplianceReview:false) — the screening is a RECOMMENDATION, and a compliance officer confirms the identity and acts, because a wrongful block denies a legitimate provider income and a wrongful clear risks paying a sanctioned party — backed by the guard exclusionNoAutonomousBlockOrClear (mirroring the Advance Beneficiary Notice Agent's no-autonomous-beneficiary-liability and the Member Cost-Share Agent's no-autonomous-member-charge posture; the harmful action is enforced-off). It is deliberately NOT PHI-bearing — it screens a provider / vendor's identity against a public exclusion list, not a patient's health information, so it is NOT on the HIPAA-audit policy (phiAccessed:false throughout), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/exclusion-screening/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — exclusion.receive-party → exclusion.match-leie → exclusion.recommend-disposition — with phiAccessed:false, returning the ScreeningDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Exclusion Screening panel (an exact-NPI-hit preset → confirmed match, recommend HOLD payment; a shared-last-name preset → possible coincidence honestly reported as NOT confirmed; a clean-party preset → no-match / recommend clear; plus unsourced-match / overstated-match / auto-block governance-block presets), a seeded exclusion.receive-party→match-leie→recommend-disposition trace showing a confirmed NPI hit (leie-1001, recommend-block-pending-review, requiresComplianceReview:true, phiAccessed:false), the console subtitle, and the investor brief (now 'sixty-nine agents', with the Exclusion Screening agent on the payer-operations tier alongside the Member Cost-Share and the other payer agents) all reflect it. Frontend tests green (2,964 tests — + exclusion-screening confirmed-NPI / possible-coincidence / no-match / probable / name+DOB-confirm / determinism / supportable-strength / three-signal-true-and-false guards, the route's envelope / three governance blocks / confirmed + coincidence + no-match happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to sixty-nine agents); the exclusion catalog + match rules are clearly-labeled illustrative synthetics (no fuzzy / phonetic matching, no monthly LEIE reload, no SAM.gov / state Medicaid exclusion lists, no reinstatement handling), NOT a certified exclusion-screening system — real screening is governed by the OIG LEIE, the OIG Special Advisory Bulletin on the effect of exclusion, and the payer's screening policy. Lint + build clean.

1f73f5e agent fabric: add the OIG Exclusion / Sanctions Screening agent (69th) — deterministic screening of a party against the OIG LEIE before payment with a match-record-sourced catalog, a match strength that can never be overstated, and never an autonomous payment block or clear

Agent Fabric: added the Member Cost-Share / EOB Calculation agent — deterministic split of an adjudicated claim's allowed amount into member vs. plan via the deductible → coinsurance → out-of-pocket-max waterfall, with a benefit-design-sourced catalog, a bounded split (member + plan = allowed), and never an autonomous member charge (the 68th agent)

Shipped
Details

Added the sixty-eighth agent on the fabric — member-cost-share-agent, a DETERMINISTIC (no-Claude) claims / payer-operations service on the payer & plan operations plane, reusing the existing payer-operations tier as a SIBLING to the Claims Adjudication, Coordination of Benefits, Claims Overpayment & Recovery, Timely Filing, Subrogation, Good Faith Estimate, and Balance Billing agents — it does NOT invent a new tier or plane. Once a claim is adjudicated to an ALLOWED AMOUNT, the member's share must be split from the plan's, and this agent does exactly that: in a new pure lib/member-cost-share.ts, evaluateCostShare(request) takes a cost-share request (a claim reference, a member reference, the member's plan id, the adjudicated allowed amount, and the member's current accumulators — deductible-met and out-of-pocket-met to date) and DETERMINISTICALLY loads the plan benefit design (deductible, coinsurance rate, out-of-pocket maximum) from an illustrative BENEFIT_PLANS catalog and runs the classic deductible → coinsurance → out-of-pocket-max WATERFALL: the deductible is applied first (up to the remaining deductible), the post-deductible remainder is split by the coinsurance rate (the member's share), and the member's total is capped at the remaining OOP maximum — the plan pays the rest. It COMPLEMENTS, not duplicates, the other payer & plan operations agents: distinct from the Claims Adjudication Assistant (WHAT the allowed amount / medical necessity is — it produces the allowed amount this agent CONSUMES), the Coordination of Benefits agent (the ORDER of coverages), the Subrogation agent (recovery from a liable third party), the Good Faith Estimate agent (the pre-service uninsured / self-pay estimate), and the Balance Billing agent (surprise-bill protection at claim time), this splits the ALREADY-adjudicated allowed amount into member vs. plan responsibility using the benefit design + accumulators. The split is a pure function of the claim's own fields + the plan (no randomness, no clock), so the same claim always yields the same member / plan split. A determination — whatever the member's share works out to — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresAdjudicationReview:true, autoPostedCharge:false), which is how a legitimate determination is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Subrogation and Good Faith Estimate agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.costshare.benefit-design-sourced (signal costShareBenefitSourced, violating value false) blocks a determination whose plan is off-catalog (a missing or unrecognized plan id — the deductible / coinsurance rate / OOP maximum must come from the member's recorded benefit design, and an ad-hoc plan cannot be correctly cost-shared) — backed by the pure guard costShareBenefitSourced (mirroring the Good Faith Estimate Agent's charge-master-sourced and the Deal Desk Agent's pricing-catalog-sourced posture); policy.costshare.math-consistent (signal costShareMathConsistent, violating value false) blocks a determination whose split does not add up — member + plan ≠ allowed, the member share is negative or exceeds the allowed / remaining OOP maximum, the member total ≠ deductible + coinsurance − OOP-cap reduction, or the coinsurance ≠ the rate applied to the post-deductible remainder — because a split that doesn't add up is how a member is silently over-charged (this is the load-bearing correctness gate, mirroring the Subrogation Agent's recoverable-within-paid and the Good Faith Estimate Agent's math-consistent; the guard recomputes the split from the determination's own fields) — backed by the guard costShareMathConsistent; and policy.costshare.no-autonomous-member-charge (signal costShareNoAutonomousCharge, violating value false) blocks a determination that posted a charge / invoice / balance to the member (autoPostedCharge:true) or did not require adjudication review (requiresAdjudicationReview:false) — the EOB cost-share is an ESTIMATE / BREAKDOWN, and the claims system / a human finalizes it — backed by the guard costShareNoAutonomousCharge (mirroring the Balance Billing Agent's no-autonomous-balance-bill and the Advance Beneficiary Notice Agent's no-autonomous-beneficiary-liability posture; the harmful action is enforced-off). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — the claim references the patient's care), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/member-cost-share/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — costshare.receive-claim → costshare.load-benefits → costshare.compute-cost-share → costshare.log-audit — with phiAccessed:true, returning the CostShareDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Member Cost-Share panel (a partway-through-deductible preset → a $500 deductible + $700 coinsurance = $1,200 member / $2,800 plan mixed split; a near-OOP-max preset → $1,000 coinsurance capped to $500, plan absorbs the rest; a no-deductible-met preset → the $800 allowed all lands on the member, plan pays $0; plus off-catalog-plan / bad-math / posted-charge governance-block presets), a seeded costshare.receive-claim→load-benefits→compute-cost-share→log-audit trace showing the mixed split ($4,000 allowed → $1,200 member / $2,800 plan on a Silver PPO, requiresAdjudicationReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'sixty-eight agents', with the Member Cost-Share agent on the payer-operations tier alongside the Subrogation and the other payer agents) all reflect it. Frontend tests green (2,919 tests — + member-cost-share waterfall / mixed-split / OOP-cap / full-deductible / off-catalog / accumulator / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / mixed + OOP-cap + full-deductible happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to sixty-eight agents); the plan catalog + deductible / coinsurance / OOP-max waterfall are clearly-labeled illustrative synthetics (no copays, tiering, family accumulators, or out-of-network penalties), NOT a certified claims / adjudication system — real cost-share is governed by the member's certificate of coverage / SBC, the payer's adjudication system, and applicable state / federal law. Lint + build clean.

62736a8 agent fabric: add the Member Cost-Share / EOB Calculation agent (68th) — deterministic split of an adjudicated claim into member vs. plan via the deductible → coinsurance → OOP-max waterfall, with a benefit-design-sourced catalog, a bounded split (member + plan = allowed), and never an autonomous member charge

Agent Fabric: added the Right of Access (HIPAA §164.524) agent — deterministic adjudication of a patient's right to GET a copy of their own PHI, with ground-sourced denials, a computed 30/60-day response deadline, and never an autonomous release or denial (the 67th agent)

Shipped
Details

Added the sixty-seventh agent on the fabric — right-of-access-agent, a DETERMINISTIC (no-Claude) control-plane / data-substrate privacy service on the platform plane, reusing the existing data-plane tier (planeForTier('data-plane') === 'platform') as a SIBLING to the Consent & Preferences Management, Master Patient Index, Break-the-Glass, Data Retention, De-Identification, Minimum Necessary, Audit Log Integrity, and Accounting of Disclosures agents — it does NOT invent a new tier or plane, and it CAPSTONES the PRIVACY SUITE by pairing the patient's §164.524 RIGHT to GET a copy of their record with the §164.528 accounting of who it was disclosed to. It COMPLEMENTS, not duplicates, the other platform / privacy agents: distinct from the Accounting of Disclosures agent (WHO the PHI was disclosed to, §164.528), the Consent & Preferences Management agent (WHETHER a patient may be contacted / data used), the Minimum Necessary agent (HOW MUCH PHI a purpose may see), the De-Identification agent (whether a dataset is still PHI), the Data Retention agent (records disposition), and the Audit Log Integrity agent (whether the audit TRAIL is tamper-evident), this answers the patient's §164.524 RIGHT to GET a copy of their own record, and BY WHEN. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/right-of-access.ts, evaluateAccess(request) takes an access request (a patient reference, the request type, the request date, an as-of date, whether the requested PHI is in a designated record set, an optional cited denial-ground / exception, and whether the single 30-day extension was invoked) and DETERMINISTICALLY computes the §164.524 response deadline (request date + 30 days, or + 60 when the extension is invoked, via pure UTC date math — addDays / daysBetween, dates taken as data, NO Date.now()), classifies any cited exception against an illustrative ACCESS_EXCEPTIONS catalog (unreviewable grounds — psychotherapy notes, information compiled for a legal proceeding, a CLIA-exempt lab; reviewable grounds — access reasonably likely to endanger, a reference to another person), and decides the disposition (grant-in-full / deny-unreviewable / deny-reviewable-needs-review / not-accessible-outside-record-set). The determination is a pure function of the request's own fields (no randomness, no clock), so the same request always yields the same deadline + classification + disposition. A determination — grant OR deny — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresHumanReview:true, autoReleased:false), which is how a legitimate determination is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Accounting of Disclosures and Audit Log Integrity agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.access.ground-sourced (signal accessGroundSourced, violating value false) blocks a determination that denies (in part or full) on a cited ground that is off-catalog (a missing or unrecognized exception id — a §164.524 denial is permitted only on a recorded statutory ground, and an ad-hoc / un-sourced ground is not a lawful basis to withhold a patient's own record) — backed by the pure guard accessGroundSourced (mirroring the Accounting of Disclosures Agent's purpose-category-sourced and the Minimum Necessary Agent's purpose-of-use-sourced posture); policy.access.deadline-computed (signal accessDeadlineComputed, violating value false) blocks a determination whose response deadline (or days-until) does not equal the request date + 30 days (+ 30 more when the single extension is invoked) — a guessed / mis-stated deadline is how an access request quietly runs past its §164.524 legal clock (this is the load-bearing correctness gate, mirroring the Timely Filing Agent's deadline-computed and the Good Faith Estimate Agent's math-consistent — the guard recomputes the deadline from the determination's own fields) — backed by the guard accessDeadlineComputed; and policy.access.no-autonomous-denial-or-release (signal accessNoAutonomousDenialOrRelease, violating value false) blocks a determination that autonomously released the record (autoReleased:true) or did not require human review (requiresHumanReview:false) — the agent ADJUDICATES, it never releases the record (a privacy risk) or issues a denial (a legal act with appeal rights) on its own, and every determination is a RECOMMENDATION requiring a records / privacy officer to fulfill or review — backed by the guard accessNoAutonomousDenialOrRelease (mirroring the Accounting of Disclosures Agent's no-autonomous-suppression and the Minimum Necessary Agent's no-autonomous-over-disclosure posture; the harmful action is enforced-off). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — the access decision references the patient's record), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/right-of-access/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — access.receive-request → access.assess-grounds → access.compute-deadline → access.log-audit — with phiAccessed:true, returning the AccessDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Right of Access panel (a routine-copy preset → grant in full, due in 30 days; a psychotherapy-notes preset → unreviewable denial; an endangerment preset → reviewable denial requiring a licensed reviewer; a complex-request preset → grant with the single 30-day extension invoked, deadline computed at 60 days; plus off-catalog-ground / wrong-deadline / auto-released governance-block presets), a seeded access.receive-request→assess-grounds→compute-deadline→log-audit trace showing a psychotherapy-notes request (deny-unreviewable, due 2026-09-24 with 17 days remaining, requiresHumanReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'sixty-seven agents', with the Right of Access agent on the platform data-plane tier alongside the Accounting of Disclosures and the other substrate agents) all reflect it. Frontend tests green (2,880 tests — + right-of-access date-math / grant / unreviewable / reviewable / extension / outside-record-set / off-catalog / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / grant + unreviewable + reviewable + extension happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to sixty-seven agents); the exception catalog + 30/60-day math are clearly-labeled illustrative synthetics, NOT a certified release-of-information system — real access is governed by HIPAA §164.524 (the full set of grounds for denial, the reviewable-denial review process, the fee limits, and the designated-record-set definition), the HITECH electronic-copy rules, and the covered entity's Notice of Privacy Practices. Lint + build clean.

0a68cc5 agent fabric: add the Right of Access (HIPAA §164.524) agent (67th) — deterministic adjudication of a patient's right to get a copy of their own PHI with ground-sourced denials, a computed 30/60-day deadline, and never an autonomous release or denial

Agent Fabric: added the Deal Desk / Quote Approval (CPQ) agent — deterministic validation of an enterprise quote's discounts against the deal-desk guardrail catalog, with pricing-catalog-sourced, discount-math-consistent, and never an autonomous out-of-guardrail approval (the 66th agent)

Shipped
Details

Added the sixty-sixth agent on the fabric — deal-desk-agent, a DETERMINISTIC (no-Claude) commercial-operations service on the strictly PHI-separated commercial plane, reusing the existing commercial-operations tier as a SIBLING to the Pipeline Management, Account Management, and Provider Contracting agents — it does NOT invent a new tier or plane, and it finally BALANCES the thinnest plane (commercial ops is now pipeline, account management, provider contracting, and deal desk). This is Pause's OWN go-to-market tooling (selling the platform to health systems / payers / employers), NOT a patient-facing agent: it runs on Sales Cloud commercial data only and never reads, joins, or derives patient PHI — so it is on the commercial no-PHI policy, NOT the HIPAA-audit policy. It COMPLEMENTS, not duplicates, the other commercial-operations agents: distinct from the Pipeline Management agent (the B2B opportunity pipeline / forecast roll-up), the Account Management agent (post-close renewals / expansion / health), and the Provider Contracting agent (the payer↔provider network CONTRACT, a different plane relationship), this validates a proposed SALES QUOTE's pricing and discounting against the deal-desk guardrails. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/deal-desk.ts, evaluateQuote(request) takes a proposed quote (an account and a set of line items, each a product, its list price, a quantity, and a proposed discount %) and DETERMINISTICALLY prices each line, sums the list / net / discount totals, computes the effective blended discount, checks each line's discount against its product's max auto-approve guardrail from an illustrative DEAL_DESK_PRODUCTS catalog (a per-provider-org Platform Core at a 15% guardrail, Data 360 Activation at 20%, Premium Support at 10%, Implementation Services at 25%), and decides the disposition (auto-approve when every line is within guardrail / escalate-to-deal-desk when any line is over). The decision is a pure function of the quote's own line items + the catalog (no randomness, no clock — NO Date.now()), so the same quote always yields the same totals + guardrail result + disposition. A decision — auto-approve OR escalate — is a SAFE, honest OUTPUT: the task COMPLETES (an out-of-guardrail quote carries requiresDealDeskApproval:true), and a within-guardrail quote is genuinely auto-approvable (a standard-discount quote does not need a human — a low-risk commercial action, NOT a PHI / clinical decision), which is how a legitimate decision is distinguished from a governance block (the block fires only on a caller-asserted DECISION that violates a guard, mirroring the Provider Contracting and Account Management agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.dealdesk.pricing-catalog-sourced (signal dealDeskCatalogSourced, violating value false) blocks a decision that prices a line whose product is off-catalog (a missing or unrecognized product id — an ad-hoc product cannot be correctly priced or guardrailed against the recorded price book) — backed by the pure guard dealDeskCatalogSourced (mirroring the Provider Contracting Agent's contract-type-catalog-sourced and the Good Faith Estimate Agent's charge-master-sourced posture); policy.dealdesk.discount-math-consistent (signal dealDeskMathConsistent, violating value false) blocks a decision whose list / net / discount totals or effective discount do not equal the recomputed sums of its line items — a guessed / hidden total is how an out-of-guardrail quote is dressed up as compliant (this is the load-bearing correctness gate, mirroring the Good Faith Estimate Agent's math-consistent and the Subrogation Agent's recoverable-within-paid; the guard recomputes every line's list / net and the quote totals from the decision's own fields) — backed by the guard dealDeskMathConsistent; and policy.dealdesk.no-autonomous-out-of-guardrail-approval (signal dealDeskNoAutonomousApproval, violating value false) blocks a decision that auto-approves (autoApproved:true) — or does not require deal-desk approval for — a quote with any line whose discount exceeds its product's max auto-approve guardrail — an out-of-guardrail discount is a RECOMMENDATION that must escalate to a human deal-desk owner, never an autonomous approval — backed by the guard dealDeskNoAutonomousApproval (mirroring the Account Management Agent's human-owner-before-contract-change and the Provider Contracting Agent's no-autonomous-term-change posture; the harmful action is enforced-off). It reuses, by extending appliesTo, the commercial no-PHI policy (phiAccessed:false throughout — the commercial plane never touches patient PHI), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/deal-desk/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — dealdesk.receive-quote → dealdesk.validate-pricing → dealdesk.decide-approval → dealdesk.record-audit — with phiAccessed:false, returning the QuoteDecision as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Deal Desk panel (a standard-discounts preset → every line within guardrail, auto-approved; a 25%-on-Platform-Core preset → over the 15% guardrail, escalated to a human deal-desk owner; a services-at-the-25%-cap preset → a boundary case, still auto-approvable; plus off-catalog-product / totals-don't-add-up / out-of-guardrail-auto-approved governance-block presets), a seeded dealdesk.receive-quote→validate-pricing→decide-approval→record-audit trace showing an out-of-guardrail quote ($285,000 list / $216,000 net / 24.21% effective discount, escalate-to-deal-desk, requiresDealDeskApproval:true, phiAccessed:false), the console subtitle, and the investor brief (now 'sixty-six agents', with the Deal Desk agent on the commercial-operations tier alongside the Pipeline Management, Account Management, and Provider Contracting agents) all reflect it. Frontend tests green (2,838 tests — + deal-desk pricing / within-guardrail / out-of-guardrail-escalation / boundary / off-catalog / divide-by-zero / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / auto-approve + escalate + boundary happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to sixty-six agents); the product catalog + guardrail percentages are clearly-labeled illustrative synthetics, NOT a certified CPQ / pricing system — real quoting is governed by the company's CPQ (e.g. Salesforce Revenue Cloud), its approved price book, and its deal-desk / finance discount-approval matrix. Lint + build clean.

45eba8f agent fabric: add the Deal Desk / Quote Approval (CPQ) agent (66th) — deterministic validation of an enterprise quote's discounts against the guardrail catalog with pricing-catalog-sourced, discount-math-consistent, and never an autonomous out-of-guardrail approval

Agent Fabric: added the Subrogation / Third-Party Liability (TPL) agent — deterministic recovery of a plan's injury-claim payments from a liable third party's settlement, with basis-sourced, a bounded recoverable (≤ plan paid), and never an autonomous lien (the 65th agent)

Shipped
Details

Added the sixty-fifth agent on the fabric — subrogation-agent, a DETERMINISTIC (no-Claude) claims / payer-operations service on the payer & plan-operations plane, reusing the existing payer-operations tier as a SIBLING to the Claims Adjudication, Coordination of Benefits, Claims Overpayment & Recovery, Timely Filing, FWA Detection, and Utilization Review agents — it does NOT invent a new tier or plane, and it deepens the PAYER / REVENUE-CYCLE recovery side of the fabric. It COMPLEMENTS, not duplicates, the other payer-operations agents: distinct from the Claims Adjudication Assistant (per-claim edits / medical necessity), the Coordination of Benefits agent (the ORDER of coverages that both cover the member), the Claims Overpayment & Recovery agent (POST-payment clawback of the plan's OWN overpayment), the Timely Filing agent (was the claim filed in time), and the FWA agent (suspected fraud), this recovers the plan's injury-claim payments from a LIABLE THIRD PARTY's settlement. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/subrogation.ts, evaluateSubrogation(request) takes a subrogation case (whether the claim is injury-related, the accident type, whether a liable third party is identified, what the plan PAID, the cited subrogation basis, the settlement amount if known, and whether the made-whole / common-fund doctrines apply) and DETERMINISTICALLY decides eligibility (injury-related AND a liable third party AND a real accident AND a recovery-allowing basis from an illustrative SUBROGATION_BASES catalog — an ERISA plan reimbursement clause, a state subrogation statute, a workers-comp lien, a contractual reimbursement provision), computes a BOUNDED recoverable amount (capped at the plan's paid amount, capped again at the settlement, barred by the made-whole doctrine, reduced by the common-fund attorney-fee share), and decides the disposition (no-subrogation-interest / notify-made-whole-bar / assert-lien-with-review). The determination is a pure function of the case's own fields + the cited basis (no randomness, no clock — NO Date.now()), so the same case always yields the same eligibility + recoverable + disposition. A determination — eligible or not — is a SAFE, honest OUTPUT: the task COMPLETES (an eligible case carries requiresHumanReview:true), which is how a legitimate determination is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Overpayment Recovery and Timely Filing agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.subrogation.basis-sourced (signal subrogationBasisSourced, violating value false) blocks a recovery decision that cites no recorded subrogation basis (a missing or off-catalog basis id — a subrogation interest exists only under a recorded legal basis, and an ad-hoc / un-sourced basis is not a real legal right) — backed by the pure guard subrogationBasisSourced (mirroring the Overpayment Recovery Agent's reason-catalog-sourced and the Timely Filing Agent's filing-limit-sourced posture); policy.subrogation.recoverable-within-paid (signal subrogationRecoverableWithinPaid, violating value false) blocks a determination whose recoverable is negative, exceeds the plan's paid amount, or exceeds the third-party settlement — a subrogation lien is REIMBURSEMENT, not profit: the plan may recover at most what it PAID and never more than the member's settlement (this is the load-bearing correctness gate, mirroring the Good Faith Estimate Agent's math-consistent and the Timely Filing Agent's deadline-computed — the guard recomputes the bound from the determination's own fields) — backed by the guard subrogationRecoverableWithinPaid; and policy.subrogation.no-autonomous-lien (signal subrogationNoAutonomousLien, violating value false) blocks a determination that autonomously asserts / perfects a lien (autoAssertedLien:true), or finds a subrogation interest (eligible:true) without requiring human review — a subrogation determination is a RECOMMENDATION requiring a subrogation specialist / plan counsel to review, and the agent never asserts or perfects a lien, reduces the member's settlement, or recovers funds — backed by the guard subrogationNoAutonomousLien (mirroring the Overpayment Recovery Agent's no-autonomous-clawback and the Balance Billing Agent's no-autonomous-balance-bill posture; the harmful action is enforced-off). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — injury claims reference patient care), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/subrogation/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — subrogation.receive-case → subrogation.assess-eligibility → subrogation.compute-recoverable → subrogation.log-audit — with phiAccessed:true, returning the SubrogationDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Subrogation panel (an auto-accident preset → fully recoverable $42,000 under an ERISA plan clause, review-gated; a common-fund preset → $30,000 reduced 33% to $20,100; a made-whole preset → recovery BARRED at $0, notify and hold; a no-interest preset → non-injury claim, nothing to recover; plus off-catalog-basis / recoverable-exceeds-paid / auto-asserted-lien governance-block presets), a seeded subrogation.receive-case→assess-eligibility→compute-recoverable→log-audit trace showing a common-fund premises-liability case ($20,100 recoverable, assert-lien-with-review, requiresHumanReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'sixty-five agents', with the Subrogation agent on the payer-operations tier alongside the Coordination of Benefits, Overpayment & Recovery, Timely Filing, and Balance Billing agents) all reflect it. Frontend tests green (2,799 tests — + subrogation eligibility / common-fund / made-whole / settlement-cap / no-interest / off-catalog / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / fully-recoverable + common-fund + made-whole + no-interest happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to sixty-five agents); the subrogation bases, made-whole / common-fund reductions, and dollar figures are clearly-labeled illustrative synthetics, NOT a certified subrogation engine — real subrogation is governed by the plan document (for a self-funded ERISA plan, 29 U.S.C. §1132(a)(3) and cases such as US Airways v. McCutchen and Montanile), state subrogation / made-whole / common-fund law, and state workers-compensation statutes. Lint + build clean.

e7d0e10 agent fabric: add the Subrogation / Third-Party Liability agent (65th) — deterministic recovery of a plan's injury-claim payments from a liable third party's settlement with basis-sourced, a bounded recoverable, and never an autonomous lien

Agent Fabric: added the Accounting of Disclosures (HIPAA §164.528) agent — deterministic accounting of who a patient's PHI was disclosed to, with purpose-category-sourced, every-accountable-disclosure-complete, and never an autonomous suppression (the 64th agent)

Shipped
Details

Added the sixty-fourth agent on the fabric — accounting-of-disclosures-agent, a DETERMINISTIC (no-Claude) control-plane / data-substrate privacy service on the platform plane, reusing the existing data-plane tier (planeForTier('data-plane') === 'platform') as a SIBLING to the Consent & Preferences Management, Master Patient Index, Break-the-Glass, Data Retention, De-Identification, Minimum Necessary, and Audit Log Integrity agents — it does NOT invent a new tier or plane, and it completes the PRIVACY SUITE with the patient's §164.528 RIGHT to know WHO their PHI was disclosed to. It COMPLEMENTS, not duplicates, the other platform / privacy agents: distinct from the Consent & Preferences Management agent (WHETHER a patient may be contacted / data used), the Minimum Necessary agent (HOW MUCH PHI a purpose may see), the De-Identification & Safe Harbor agent (whether a dataset is still PHI), the Data Retention agent (records disposition), and the Audit Log Integrity agent (whether the audit TRAIL is tamper-evident), this answers WHO the patient's PHI was disclosed to, and for what non-TPO purpose, over the prior years. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/accounting-of-disclosures.ts, evaluateAccounting(request) takes an accounting request (a patient reference, an as-of date, a lookback window in years, and the patient's disclosure log — each disclosure a date, a recipient, and the cited purpose-of-disclosure) and DETERMINISTICALLY computes the lookback window (as-of date − lookback years, via pure UTC date math — subtractYears, dates taken as data, NO Date.now()), classifies each disclosure against an illustrative DISCLOSURE_PURPOSES catalog (treatment / payment / operations and patient-authorized disclosures are EXCLUDED from the accounting; non-TPO disclosures — public-health mandates, law enforcement, judicial orders, research without authorization — ARE accountable) as in-accounting / excluded-TPO / excluded-authorized / out-of-window, and assembles the accounting of every accountable, in-window disclosure. The classification is a pure function of the request's own fields (no randomness, no clock), so the same log always yields the same classification + accounting + counts. A determination — however many accountable disclosures it lists — is a SAFE, honest OUTPUT: the task COMPLETES (it carries requiresPrivacyOfficerReview:true), which is how a legitimate determination is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Audit Log Integrity and Minimum Necessary agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.accounting.purpose-category-sourced (signal accountingPurposeSourced, violating value false) blocks a determination that classifies a disclosure whose purpose-of-disclosure is off-catalog (a missing or unrecognized purpose id — an ad-hoc purpose cannot be correctly decided as accountable or excluded under §164.528) — backed by the pure guard accountingPurposeSourced (mirroring the Minimum Necessary Agent's purpose-of-use-sourced and the Data Retention Agent's schedule-sourced posture); policy.accounting.accountable-disclosures-complete (signal accountingDisclosuresComplete, violating value false) blocks a determination that omits an accountable, in-window disclosure from the accounting (a non-TPO, non-authorized disclosure within the lookback window classified as anything other than in-accounting) — dropping an accountable disclosure understates the accounting and defeats the patient's §164.528 right (this is the load-bearing completeness gate, mirroring the Good Faith Estimate Agent's expected-items-complete and the Audit Log Integrity Agent's sequence-complete; the guard recomputes, from the determination's own classified list, which disclosures should be accounted and verifies none was dropped) — backed by the guard accountingComplete; and policy.accounting.no-autonomous-suppression (signal accountingNoAutonomousSuppression, violating value false) blocks a determination that claims it suppressed / redacted / deleted a logged disclosure (autonomousSuppression:true), or that does not require privacy-officer review — the agent CLASSIFIES and ASSEMBLES, it never deletes or suppresses a logged disclosure (that would falsify the accounting and destroy evidence), and the accounting is a RECOMMENDATION requiring privacy-officer review — backed by the guard accountingNoAutonomousSuppression (mirroring the Audit Log Integrity Agent's no-autonomous-redaction and the Minimum Necessary Agent's no-autonomous-over-disclosure posture; the harmful action is enforced-off). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — disclosures reference patient care), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/accounting-of-disclosures/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — accounting.receive-log → accounting.classify → accounting.assemble → accounting.log-audit — with phiAccessed:true, returning the AccountingDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Accounting of Disclosures panel (a mixed-log preset → 2 accountable / 2 excluded-TPO / 1 out-of-window, privacy-officer review; a judicial+research preset → both accountable, an authorized disclosure excluded; a TPO-only preset → an empty accounting, still review-gated; plus off-catalog-purpose / dropped-accountable-disclosure / auto-suppressed governance-block presets), a seeded accounting.receive-log→classify→assemble→log-audit trace showing a mixed log (2 accountable, 6-year window from 2020-09-01, phiAccessed:true), the console subtitle, and the investor brief (now 'sixty-four agents', with the Accounting of Disclosures agent on the platform data-plane tier alongside the other substrate agents) all reflect it. Frontend tests green (2,768 tests — + accounting date-math / mixed-log / judicial+research / TPO-only / off-catalog / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / mixed + judicial + TPO-only happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to sixty-four agents); the purpose catalog + accountability rules are clearly-labeled illustrative synthetics, NOT a certified accounting-of-disclosures system — real accountings are governed by HIPAA §164.528 (the full exclusion set, the six-year window, and the electronic-health-record disclosure rules) and the covered entity's Notice of Privacy Practices. Lint + build clean.

0e2d020 agent fabric: add the Accounting of Disclosures (HIPAA §164.528) agent (64th) — deterministic accounting of who a patient's PHI was disclosed to with purpose-category-sourced, every-accountable-disclosure-complete, and never an autonomous suppression

Agent Fabric: added the Advance Beneficiary Notice (Medicare ABN) agent — deterministic Medicare coverage / pre-service-ABN decisioning with coverage-rule-sourced, ABN-required-when-non-covered, and never an autonomous patient bill (the 63rd agent)

Shipped
Details

Added the sixty-third agent on the fabric — advance-beneficiary-notice-agent, a DETERMINISTIC (no-Claude) patient-access / benefits-verification service on the patient & clinical plane, reusing the existing benefits-verification tier as a SIBLING to the Benefits & Coverage Verification (EBV), Patient Financial Assistance & Charity Care, and Good Faith Estimate agents — it does NOT invent a new tier or plane, and it deepens the PATIENT-ACCESS / price-transparency side of the fabric with the Medicare-specific ABN instrument. It COMPLEMENTS, not duplicates, its patient-access / financial siblings: distinct from the Good Faith Estimate agent (the No Surprises Act SELF-PAY / uninsured pre-service estimate), the Balance Billing agent (the No Surprises Act CLAIM-time surprise-bill prohibition), the EBV agent (plan eligibility), and the Financial Assistance agent (501(r) charity care), this decides one narrow Medicare question — is a signed pre-service ABN (Form CMS-R-131) required before a service Medicare is likely to DENY as not-reasonable-and-necessary (or statutorily excluded), and may the beneficiary be billed for it. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/advance-beneficiary-notice.ts, evaluateAbn(request) takes a proposed service (the cited Medicare coverage rule, whether the service meets its coverage criteria or exceeds a frequency limit, and whether an ABN was issued and signed BEFORE the service) and DETERMINISTICALLY assesses coverage against an illustrative MEDICARE_COVERAGE_RULES catalog (a reasonable-necessary vitamin-D lab, a frequency-limited DEXA bone-density scan, a statutorily-excluded cosmetic procedure) as likely-covered / likely-non-covered / statutorily-excluded, decides whether a signed pre-service ABN is required, computes whether a valid pre-service ABN is on file (issued AND signed before the service), decides whether the beneficiary may be billed, assigns the CMS liability modifier (none / GA waiver-on-file / GZ expected-denial-no-ABN / GY statutorily-excluded), and decides the disposition (proceed-covered / issue-abn-before-service / bill-beneficiary-with-abn / notify-statutory-exclusion). The determination is a pure function of the request's own fields + the cited rule (no randomness, no clock — NO Date.now()), so the same service always yields the same coverage assessment + ABN requirement + modifier + disposition. A determination — covered, non-covered, or excluded — is a SAFE, honest OUTPUT: the task COMPLETES (a non-covered / excluded determination carries requiresHumanReview:true), which is how a legitimate determination is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Good Faith Estimate and Timely Filing agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.abn.coverage-rule-sourced (signal abnCoverageRuleSourced, violating value false) blocks a coverage / ABN decision that cites no recorded Medicare coverage rule (a missing or off-catalog rule id — an ad-hoc / un-sourced coverage decision is not a real determination) — backed by the pure guard abnCoverageRuleSourced (mirroring the Good Faith Estimate Agent's charge-master-sourced and the Timely Filing Agent's filing-limit-sourced posture); policy.abn.abn-required-when-noncovered (signal abnRequiredWhenNoncovered, violating value false) blocks a determination that assesses a service as likely NON-covered but marks it as needing no ABN (abnRequired:false) — a likely-denied Medicare service requires a signed ABN issued BEFORE the service, and understating this is how a surprise denial lands on the beneficiary (this is the load-bearing completeness gate, mirroring the Good Faith Estimate Agent's expected-items-complete) — backed by the guard abnRequiredWhenNoncovered; and policy.abn.no-autonomous-beneficiary-liability (signal abnNoAutonomousBeneficiaryLiability, violating value false) blocks a determination that assigns patient liability autonomously (autoAssignedLiability:true), bills the beneficiary for a likely-non-covered service WITHOUT a valid pre-service ABN, or assigns liability on a non-covered / excluded service without requiring human review — the beneficiary may be billed for a non-covered service ONLY with a valid ABN (the GA modifier), otherwise the PROVIDER is liable (the GZ modifier), and every liability decision is a RECOMMENDATION requiring human review — backed by the guard abnNoAutonomousBeneficiaryLiability (mirroring the Balance Billing Agent's no-autonomous-balance-bill and the Timely Filing Agent's no-autonomous-write-off posture; the harmful action is enforced-off). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — services reference patient care), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/advance-beneficiary-notice/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — abn.receive-request → abn.assess-coverage → abn.decide-liability → abn.log-audit — with phiAccessed:true, returning the AbnDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Advance Beneficiary Notice panel (a meets-criteria preset → likely covered, no ABN required, proceed; a fails-criteria-no-ABN preset → likely non-covered, issue an ABN before the service, provider liable / GZ, beneficiary not billed, human review; a fails-criteria-with-valid-ABN preset → likely non-covered, beneficiary billable / GA, human review; a statutorily-excluded preset → GY, voluntary ABN, human review; plus un-sourced-rule / non-covered-no-ABN-required / billed-without-valid-ABN governance-block presets), a seeded abn.receive-request→assess-coverage→decide-liability→log-audit trace showing a likely-non-covered vitamin-D screen (abnRequired:true, GZ, issue-abn-before-service, requiresHumanReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'sixty-three agents', with the Advance Beneficiary Notice agent on the benefits-verification tier alongside the EBV, Financial Assistance, and Good Faith Estimate agents) all reflect it. Frontend tests green (2,738 tests — + ABN coverage-assessment / GZ / GA / GY / after-service-ABN / within-frequency-limit / off-catalog / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / covered + non-covered + valid-ABN + excluded happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to sixty-three agents); the coverage rules, categories, and modifier logic are clearly-labeled illustrative synthetics, NOT a certified Medicare coverage engine — real ABN decisions are governed by the Medicare National / Local Coverage Determinations (NCD/LCD), the Social Security Act §1862(a), the CMS Medicare Claims Processing Manual (Ch. 30), and Form CMS-R-131. Lint + build clean.

fe50590 agent fabric: add the Advance Beneficiary Notice (Medicare ABN) agent (63rd) — deterministic Medicare coverage / pre-service-ABN decisioning with coverage-rule-sourced, ABN-required-when-non-covered, and never an autonomous patient bill

Agent Fabric: added the Controlled Substance / PDMP Safety Check agent — deterministic opioid MME screening with guideline-sourced, a computed (not guessed) MME total, and never an autonomous prescribing decision (the 62nd agent)

Shipped
Details

Added the sixty-second agent on the fabric — controlled-substance-agent, a DETERMINISTIC (no-Claude) clinical-decision service on the patient & clinical plane, reusing the existing clinical-decision tier (planeForTier('clinical-decision') === 'patient-care') as a SIBLING to the Care Router, Care Plan, Prior Authorization, Lab Result, and Immunization agents — it does NOT invent a new tier or plane, and it deliberately broadens the CLINICAL / medication-safety side of the fabric. It COMPLEMENTS, not duplicates, the other clinical / medication agents: distinct from the Formulary & DUR Review agent (plan-level coverage, step therapy, and drug-utilization-review alerts), the Medication Adherence agent (whether the patient is taking an already-prescribed drug), the Prior Authorization agent (assembling a payer PA package), and the Immunization Forecasting agent (vaccine schedule), this screens the TOTAL controlled-substance burden across ALL prescribers per the PDMP. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/controlled-substance.ts, evaluateControlledSubstance(request) takes a proposed controlled-substance prescription (a drug, its class, its dose in MME/day, days supply, prescriber, pharmacy) and the patient's active PDMP (Prescription Drug Monitoring Program) history, and DETERMINISTICALLY sums the total opioid MME/day (morphine milligram equivalents; the proposed opioid contribution + the concurrent active opioids), flags a concurrent opioid+benzodiazepine combination (a respiratory-depression risk) and multi-prescriber / multi-pharmacy patterns, compares the total against the cited guideline's caution (50 MME/day) and high-risk (90 MME/day) thresholds, and classifies the risk (low / elevated / high). The finding is a pure function of the request's data + the cited guideline (no randomness, no clock — NO Date.now()), so the same request always yields the same total + risk + disposition. A determination — low or high risk — is a SAFE, honest OUTPUT: the task COMPLETES (an elevated / high-risk finding carries requiresPrescriberReview:true), which is how a legitimate determination is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Immunization and Lab Result agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.controlledsubstance.guideline-sourced (signal controlledSubstanceGuidelineSourced, violating value false) blocks a risk finding that cites no recorded guideline (a missing or off-catalog guideline id — an ad-hoc / un-sourced MME threshold is not a real clinical standard) — backed by the pure guard controlledSubstanceGuidelineSourced (mirroring the Immunization Agent's schedule-sourced and the Lab Result Agent's reference-range-sourced posture); policy.controlledsubstance.mme-computed (signal controlledSubstanceMmeComputed, violating value false) blocks a determination whose stated total MME/day does not equal the proposed opioid contribution + the concurrent opioid MME/day — a guessed / hidden dose is how an over-threshold prescription is wrongly called safe (this is the load-bearing correctness gate, mirroring the Timely Filing Agent's deadline-computed and the Good Faith Estimate Agent's math-consistent — the guard recomputes the sum from the determination's own fields) — backed by the guard controlledSubstanceMmeComputed; and policy.controlledsubstance.no-autonomous-prescribing-decision (signal controlledSubstanceNoAutonomousDecision, violating value false) blocks a determination that auto-decides (autoDecision:true), or that reports an elevated / high-risk finding without requiring prescriber review — a controlled-substance risk finding is a RECOMMENDATION requiring prescriber review, and the agent never autonomously approves, denies, dispenses, or writes the prescription — backed by the guard controlledSubstanceNoAutonomousDecision (mirroring the Immunization Agent's no-autonomous-administration and the Lab Result Agent's no-autonomous-clinical-action posture; the harmful action is enforced-off). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — it screens a patient's controlled-substance history), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/controlled-substance/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — controlledsubstance.receive-request → controlledsubstance.compute-mme → controlledsubstance.classify → controlledsubstance.log-audit — with phiAccessed:true, returning the ControlledSubstanceDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Controlled Substance panel (a modest-opioid-no-history preset → low risk / proceed, no review; a stacked-opioids preset → total 100 MME/day over the 90 high-risk threshold → high risk / prescriber review; an opioid+benzo preset → high risk from the respiratory-depression combination; plus un-sourced-guideline / guessed-MME-total / auto-approved-high-risk governance-block presets), a seeded controlledsubstance.receive-request→compute-mme→classify→log-audit trace showing a stacked-opioid screen (100 MME/day, high risk, requiresPrescriberReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'sixty-two agents', with the Controlled Substance agent on the clinical-decision tier alongside the Care Router, Care Plan, Prior Authorization, Lab Result, and Immunization agents) all reflect it. Frontend tests green (2,707 tests — + controlled-substance MME-sum / stacked-opioid / opioid-benzo / non-opioid / off-catalog / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / allow + high-risk + benzo happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to sixty-two agents); the MME thresholds, drug classes, and MME/day figures are clearly-labeled illustrative synthetics, NOT a certified PDMP or clinical decision support — real monitoring uses the state PDMP, the CDC MME conversion factors, the CDC 2022 Clinical Practice Guideline for Prescribing Opioids, and the prescriber's clinical judgment. Lint + build clean.

79c67ae agent fabric: add the Controlled Substance / PDMP Safety Check agent (62nd) — deterministic opioid MME screening with guideline-sourced, a computed (not guessed) MME total, and never an autonomous prescribing decision

Agent Fabric: added the Timely Filing Compliance agent — deterministic claim filing-deadline compliance with filing-limit-sourced, a computed (not guessed) deadline, and never an autonomous write-off (the 61st agent)

Shipped
Details

Added the sixty-first agent on the fabric — timely-filing-agent, a DETERMINISTIC (no-Claude) claims / payer-operations service on the payer & plan-operations plane, reusing the existing payer-operations tier as a SIBLING to the Claims Adjudication, Coordination of Benefits, Claims Overpayment & Recovery, FWA Detection, and Utilization Review agents — it does NOT invent a new tier or plane, and it deliberately broadens the PAYER / REVENUE-CYCLE side of the fabric. It COMPLEMENTS, not duplicates, the other payer-operations agents: distinct from the Claims Adjudication Assistant (per-claim edits / medical-necessity adjudication), the Coordination of Benefits agent (payer ORDER across coverages), the Claims Overpayment & Recovery agent (POST-payment clawback of a legitimate overpayment), the FWA Detection agent (suspected fraud patterns), and the Utilization Review agent (medical necessity), this decides one narrow, purely temporal question — was the claim FILED IN TIME. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/timely-filing.ts, evaluateTimelyFiling(request) takes a claim (a date of service, a submission date, and the cited payer filing-limit rule, plus an optional claimed exception) and DETERMINISTICALLY computes the filing DEADLINE (date of service + the rule's limit in days, via pure UTC date math — addDays / daysBetween, dates taken as data, NO Date.now()), compares the submission date to it, computes how many days late an untimely claim is, honors a recognized filing-limit EXCEPTION when one is claimed (resolved against the rule's allowed exceptions — COB-primary-delay, retroactive eligibility, proof-of-timely-filing, provider-of-record error, administrative error), and decides the disposition (accept / appeal-with-exception / write-off-review). The decision is a pure function of the claim's dates + the cited rule (no randomness, no clock), so the same claim always yields the same deadline + timely flag + days-late + disposition. A determination — timely or untimely — is a SAFE, honest OUTPUT: the task COMPLETES (an untimely claim carries requiresHumanReview:true), which is how a legitimate determination is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Overpayment Recovery and Balance Billing agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.timelyfiling.filing-limit-sourced (signal timelyFilingRuleSourced, violating value false) blocks a timeliness decision that cites no recorded payer filing-limit rule (a missing or off-catalog rule id — an ad-hoc / un-sourced limit is not a real deadline) — backed by the pure guard timelyFilingRuleSourced (mirroring the Overpayment Recovery Agent's reason-catalog-sourced and the Data Retention Agent's schedule-sourced posture); policy.timelyfiling.deadline-computed (signal timelyFilingDeadlineComputed, violating value false) blocks a determination whose stated deadline does not equal the recomputed date of service + the rule's limit days — a guessed / hidden deadline is how a claim is wrongly called timely or untimely (this is the load-bearing correctness gate, mirroring the Good Faith Estimate Agent's math-consistent — the guard recomputes the deadline from the determination's own serviceDate + limitDays and compares) — backed by the guard timelyFilingDeadlineComputed; and policy.timelyfiling.no-autonomous-write-off (signal timelyFilingNoAutonomousWriteOff, violating value false) blocks a determination that marks the claim written-off, or that reports an untimely claim without requiring human review — an untimely claim is a RECOMMENDATION (file an appeal with a recognized exception, or route to a write-off decision) requiring human review, and the agent never autonomously writes off the balance or bills the patient — backed by the guard timelyFilingNoAutonomousWriteOff (mirroring the Overpayment Recovery Agent's no-autonomous-clawback and the Balance Billing Agent's no-autonomous-balance-bill posture; the harmful action is enforced-off). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — claims reference patient care), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/timely-filing/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — timelyfiling.receive-claim → timelyfiling.compute-deadline → timelyfiling.decide → timelyfiling.log-audit — with phiAccessed:true, returning the TimelyFilingDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Timely Filing panel (a filed-within-90-days preset → timely / accept, no review; a late-but-exception preset → untimely with a recognized COB-primary-delay exception → appeal-with-exception, human review; a late-no-exception preset → untimely → write-off-review, human review, never auto-written-off; plus un-sourced-rule / guessed-deadline / auto-write-off governance-block presets), a seeded timelyfiling.receive-claim→compute-deadline→decide→log-audit trace showing a late-with-exception commercial claim (52 days late past a 2026-04-10 deadline, appeal-with-exception, requiresHumanReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'sixty-one agents', with the Timely Filing agent on the payer-operations tier alongside the Coordination of Benefits, Overpayment & Recovery, and Balance Billing agents) all reflect it. Frontend tests green (2,678 tests — + timely-filing date-math / accept / exception-appeal / write-off-review / off-catalog / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / allow + exception-appeal happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to sixty-one agents); the filing-limit rules, day windows, and exception catalog are clearly-labeled illustrative synthetics, NOT a certified timely-filing engine — real limits are governed by each payer's provider contract, Medicare (generally 12 months / 42 CFR 424.44), state Medicaid rules, and state prompt-pay law. Lint + build clean.

4e1673a agent fabric: add the Timely Filing Compliance agent (61st) — deterministic claim filing-deadline compliance with filing-limit-sourced, a computed (not guessed) deadline, and never an autonomous write-off

Agent Fabric: added the Audit Log Integrity (Tamper-Evidence) agent — deterministic hash-chain + sequence verification with hash-chain-verified, sequence-complete, and never an autonomous redaction (the 60th agent)

Shipped
Details

Added the sixtieth agent on the fabric — audit-log-integrity-agent, a DETERMINISTIC (no-Claude) control-plane / data-substrate service on the platform plane, reusing the existing data-plane tier (planeForTier('data-plane') === 'platform') as a SIBLING to the Consent & Preferences Management, Master Patient Index, Break-the-Glass, Data Retention, De-Identification, and Minimum Necessary agents — it does NOT invent a new tier or plane, and it caps the PLATFORM & DATA SUBSTRATE story with the meta-guarantee: every agent on the fabric writes a HIPAA audit span, and THIS agent verifies the audit TRAIL itself is tamper-evident. It COMPLEMENTS, not duplicates, the other platform agents: distinct from the Consent & Preferences Management agent (WHETHER a patient may be contacted / data used), the De-Identification & Safe Harbor agent (whether a dataset is no longer PHI), the Minimum Necessary agent (HOW MUCH PHI a purpose may see), the Master Patient Index (identity / dedup), the Break-the-Glass agent (emergency PHI access), and the Data Retention agent (records disposition), this verifies that the AUDIT TRAIL of everything the fabric did has not been tampered with. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/audit-log-integrity.ts, evaluateAuditLogIntegrity(request) takes an audit log (an ordered list of entries, each with a sequence number, actor, action, target, timestamp, the prior entry's hash, and its own hash) and DETERMINISTICALLY recomputes each entry's hash (a small dependency-free non-cryptographic FNV-1a so the chain is isomorphic across the node route, the browser panel, and the tests), verifies each chain link (the entry's prevHash against the prior entry's recomputed hash, chaining from a genesis), checks the sequence numbers for gaps, and decides whether the log is VERIFIED (hash chain intact AND sequence complete). Verification is a pure function of the log's entries (no randomness, no clock — NO Date.now()), so the same log always yields the same verified / hash-chain / sequence result. A determination — verified OR tamper-suspected — is a SAFE, honest OUTPUT: the task COMPLETES (a tampered / incomplete log carries requiresForensicReview:true), which is how a legitimate determination is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Minimum Necessary and De-Identification agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.auditlog.hash-chain-verified (signal auditLogHashChainVerified, violating value false) blocks a determination that marks a log VERIFIED while its hash chain is not intact (a recomputed hash or a prevHash link does not match — a single broken link is tampering, and a verified label over a broken chain HIDES it) — backed by the pure guard auditLogHashChainVerified (mirroring the Minimum Necessary Agent's minimum-necessary-scoped posture — an integrity obligation that cannot be skipped); policy.auditlog.sequence-complete (signal auditLogSequenceComplete, violating value false) blocks a determination that marks a log VERIFIED while its sequence has a gap (a gap means an entry was deleted — which the hash chain alone would not catch at the tail — and a verified label over a gap HIDES the deleted record) — the load-bearing completeness gate — backed by the guard auditLogSequenceComplete; and policy.auditlog.no-autonomous-redaction (signal auditLogNoAutonomousRedaction, violating value false) blocks a determination that claims it repaired / rewrote / re-sealed the log — the agent VERIFIES and FLAGS, it NEVER deletes, rewrites, or repairs an audit entry (that would destroy evidence), and a broken log is flagged for human forensic review — backed by the guard auditLogNoAutonomousRedaction (mirroring the Data Retention Agent's no-autonomous-purge and the Minimum Necessary Agent's no-autonomous-over-disclosure posture; the harmful action is enforced-off). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — audit entries reference patient targets), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/audit-log-integrity/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — auditlog.receive-log → auditlog.verify → auditlog.attest → auditlog.log-audit — with phiAccessed:true, returning the AuditLogDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Audit Log Integrity panel (an intact 5-entry preset → verified, no forensic review; an altered-entry preset → the tampered entry's hash no longer matches, flagged for forensic review, NOT repaired; a deleted-entry preset → a sequence gap 3 → 5; plus verified-over-broken-chain / verified-with-sequence-gap / auto-repaired governance-block presets), a seeded auditlog.receive-log→verify→attest→log-audit trace showing a verified 5-entry log (0 broken links, 0 sequence gaps, phiAccessed:true), the console subtitle, and the investor brief (now 'sixty agents', with the Audit Log Integrity agent on the platform data-plane tier alongside the other substrate agents) all reflect it. Frontend tests green (2,649 tests — + audit-log hashing / sealing / verify / tamper / gap / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / allow + tampered + gap happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to sixty agents); the FNV-1a hash chain + sequence check are clearly-labeled illustrative synthetics, NOT a certified tamper-evidence system — a real control uses a cryptographic hash (SHA-256), append-only / WORM storage, and signed checkpoints. Lint + build clean.

0ff9790 agent fabric: add the Audit Log Integrity (Tamper-Evidence) agent (60th) — deterministic hash-chain + sequence verification with hash-chain-verified, sequence-complete, and never an autonomous redaction

Agent Fabric: added the Minimum Necessary (HIPAA) agent — deterministic purpose-of-use disclosure scoping with purpose-of-use-sourced, minimum-necessary-scoped, and never an autonomous over-disclosure (the 59th agent)

Shipped
Details

Added the fifty-ninth agent on the fabric — minimum-necessary-agent, a DETERMINISTIC (no-Claude) control-plane / data-substrate service on the platform plane, reusing the existing data-plane tier (planeForTier('data-plane') === 'platform') as a SIBLING to the Consent & Preferences Management, Master Patient Index, Break-the-Glass, Data Retention, and De-Identification agents — it does NOT invent a new tier or plane, and it rounds out the PLATFORM & DATA SUBSTRATE privacy story. It COMPLEMENTS, not duplicates, the other platform agents: distinct from the Consent & Preferences Management agent (WHETHER a patient may be contacted / data used for a scope), the De-Identification & Safe Harbor agent (whether a dataset is no longer PHI), the Master Patient Index (identity / dedup), the Break-the-Glass agent (emergency PHI access), and the Data Retention agent (records disposition), this decides HOW MUCH of an identified patient's PHI a given purpose-of-use may see. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/minimum-necessary.ts, evaluateMinimumNecessary(request) takes a disclosure request (a requestor role, a purpose-of-use, the specific fields requested — each mapped to a field CATEGORY — and the record scope: single-patient / cohort / bulk) and DETERMINISTICALLY resolves the governing purpose-of-use rule from a PURPOSE_RULES catalog (treatment, payment, healthcare-operations, research, marketing), then decides per field whether its category is within the minimum-necessary scope for that purpose (release) or beyond it (withhold), yielding a disclosure limited to the minimum necessary (45 CFR 164.502(b) / 164.514(d)). Treatment / disclosure-to-the-individual / authorized / required-by-law purposes are EXEMPT from the standard (all fields released). The determination is a pure function of the request + the purpose catalog (no randomness, no clock — time taken as data, NO Date.now()), so the same request always yields the same field decisions + released/withheld sets + flags. A determination — minimum-necessary or narrowed — is a SAFE, honest OUTPUT: the task COMPLETES (a narrowed / bulk disclosure carries requiresHumanReview:true), which is how a legitimate determination is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the De-Identification and Balance Billing agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.minnec.purpose-of-use-sourced (signal minNecPurposeSourced, violating value false) blocks a determination that cites no recorded purpose-of-use (an ad-hoc / un-sourced disclosure, a missing or off-catalog purpose id) — backed by the pure guard minNecPurposeSourced (mirroring the De-Identification Agent's method-cited and the Data Retention Agent's schedule-sourced posture); policy.minnec.minimum-necessary-scoped (signal minNecScoped, violating value false) blocks a determination that RELEASES a field whose category is beyond what the stated purpose-of-use permits — no field beyond the minimum necessary may be disclosed; releasing an out-of-scope field over-discloses PHI (this is the load-bearing privacy gate, mirroring the De-Identification Agent's no-release-of-reidentifiable — a privacy obligation that cannot be skipped) — backed by the guard minNecScoped; and policy.minnec.no-autonomous-over-disclosure (signal minNecNoAutonomousOverDisclosure, violating value false) blocks a determination that is not-minimum-necessary as submitted (fields had to be withheld) or that is a bulk / cohort disclosure but does not require human review — an over-scope or bulk disclosure is a RECOMMENDATION requiring human review, never autonomously released — backed by the guard minNecNoAutonomousOverDisclosure (mirroring the De-Identification Agent's no-release-of-reidentifiable and the Balance Billing Agent's no-autonomous-balance-bill posture; the harmful action is enforced-off). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — it scopes patient PHI disclosures), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/minimum-necessary/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — minnec.receive-request → minnec.scope → minnec.decide → minnec.log-audit — with phiAccessed:true, returning the MinimumNecessaryDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Minimum Necessary panel (a payment-with-clinical-note preset → the note withheld as out-of-scope, human review; a payment-in-scope preset → all released, no review; a treatment preset → exempt, all released; a research-cohort preset → in-scope but bulk, human review; plus un-sourced-purpose / out-of-scope-release / over-scope-auto-approved governance-block presets), a seeded minnec.receive-request→scope→decide→log-audit trace showing a narrowed payment disclosure (4 released, 1 withheld, requiresHumanReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'fifty-nine agents', with the Minimum Necessary agent on the platform data-plane tier alongside the other substrate agents) all reflect it. Frontend tests green (2,619 tests — + minimum-necessary purpose-catalog / scoping / exempt / bulk / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / allow + treatment-exempt happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to fifty-nine agents); the purpose-of-use catalog, requestor roles, field categories, and allowed-category mappings are clearly-labeled illustrative synthetics, NOT a certified minimum-necessary engine — a real determination uses the covered entity's role-based access policies and its minimum-necessary standard under 45 CFR 164.502(b) / 164.514(d). Lint + build clean.

56e9af8 agent fabric: add the Minimum Necessary (HIPAA) agent (59th) — deterministic purpose-of-use disclosure scoping with purpose-of-use-sourced, minimum-necessary-scoped, and never an autonomous over-disclosure

Agent Fabric: added the Immunization Forecasting (ACIP) agent — deterministic vaccine forecasting with schedule-sourced, contraindication-honored, and never an autonomous administration (the 58th agent)

Shipped
Details

Added the fifty-eighth agent on the fabric — immunization-agent, a DETERMINISTIC (no-Claude) clinical-decision service on the patient & clinical plane, reusing the existing clinical-decision tier (planeForTier('clinical-decision') === 'patient-care') as a SIBLING to the Care Router, Care Plan, Prior Authorization, and Lab Result agents — it does NOT invent a new tier or plane, and it deliberately broadens the CLINICAL side of the fabric (recent additions had leaned payer / data-substrate). It COMPLEMENTS, not duplicates, the other clinical / care agents: distinct from the Care Gap Closure agent (broad missing preventive measures), the Lab Result agent (discrete diagnostic results), the Care Plan agent (the longitudinal plan), and the Care Router (triage), this forecasts the specific vaccine SCHEDULE — dose series, booster intervals, and age-eligibility — against ACIP-style rules. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/immunization.ts, evaluateImmunization(request) takes a patient (a synthetic reference, a birth date, an immunization history, and any recorded contraindications) evaluated against a provided asOfDate, DETERMINISTICALLY computes the patient's age, and forecasts each vaccine (up-to-date / due / overdue / contraindicated / not-indicated) against an ACIP_SCHEDULE catalog (influenza annual, Td/Tdap booster every 10 years, recombinant zoster/RZV 2-dose series at 50+, pneumococcal at 65+, updated COVID-19), applying age-eligibility, dose-series / booster-interval logic, and any recorded contraindications, citing the governing schedule rule + the next-due date. The forecast is a pure function of the request + its own asOfDate + the schedule catalog (no randomness, no clock — time taken as data, NO Date.now()), so the same patient always yields the same forecast + cited rules + next-due dates. A forecast — with due / overdue vaccines — is a SAFE, honest OUTPUT: the task COMPLETES (due / overdue vaccines carry requiresClinicianOrder:true), which is how a legitimate forecast is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Lab Result and Balance Billing agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.immunization.schedule-sourced (signal immunizationScheduleCited, violating value false) blocks a vaccine recommendation that cites no recorded ACIP schedule rule (an ad-hoc / un-sourced recommendation, a missing or off-catalog rule id) — backed by the pure guard immunizationScheduleCited (mirroring the Lab Result Agent's reference-range-sourced and the Data Retention Agent's schedule-sourced posture); policy.immunization.contraindication-honored (signal immunizationContraindicationHonored, violating value false) blocks a forecast that RECOMMENDS (due / overdue) a vaccine for which the patient has a recorded contraindication — a contraindicated vaccine must be withheld and flagged, never recommended; recommending it is a patient-safety hazard (this is the load-bearing safety gate, mirroring the Lab Result Agent's critical-value-notified — a clinical-safety obligation that cannot be skipped) — backed by the guard immunizationContraindicationHonored; and policy.immunization.no-autonomous-administration (signal immunizationNoAutonomousAdministration, violating value false) blocks a determination that reports due / overdue vaccines but does not require a clinician order — a due / overdue vaccine is a RECOMMENDATION requiring a clinician order, and the agent never administers, orders, or records a vaccine autonomously — backed by the guard immunizationNoAutonomousAdministration (mirroring the Lab Result Agent's no-autonomous-clinical-action and the Balance Billing Agent's no-autonomous-balance-bill posture; the harmful action is enforced-off). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — it forecasts patient immunizations), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/immunization/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — immunization.receive-patient → immunization.forecast → immunization.recommend → immunization.log-audit — with phiAccessed:true, returning the ImmunizationDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Immunization panel (a 52-year-old preset → flu up-to-date, Tdap + zoster overdue, pneumococcal not-indicated, COVID due, requiring a clinician order; a zoster-contraindicated preset → withheld / never recommended; a 40-year-old preset → all up-to-date; plus off-catalog-rule / recommended-contraindicated / due-without-clinician-order governance-block presets), a seeded immunization.receive-patient→forecast→recommend→log-audit trace showing a midlife patient's forecast (1 due + 2 overdue, requiresClinicianOrder:true, phiAccessed:true), the console subtitle, and the investor brief (now 'fifty-eight agents', with the Immunization agent on the clinical-decision tier alongside the Care Router, Care Plan, Prior Authorization, and Lab Result agents) all reflect it. Frontend tests green (2,590 tests — + immunization schedule-catalog / forecast / contraindication / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / allow + contraindicated-withheld happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to fifty-eight agents); the ACIP-style schedule, age-eligibility, dose series, and booster intervals are clearly-labeled illustrative synthetics, NOT a certified immunization forecaster — a real forecast uses the current ACIP recommendations, the CDC immunization schedules, and the patient's full clinical context. Lint + build clean.

9c77b42 agent fabric: add the Immunization Forecasting (ACIP) agent (58th) — deterministic vaccine forecasting with schedule-sourced, contraindication-honored, and never an autonomous administration

Agent Fabric: added the De-Identification & Safe Harbor agent — deterministic HIPAA Safe Harbor screening with all-eighteen-categories-screened, method-cited, and never a re-identifiable release (the 57th agent)

Shipped
Details

Added the fifty-seventh agent on the fabric — deidentification-agent, a DETERMINISTIC (no-Claude) control-plane / data-substrate service on the platform plane, reusing the existing data-plane tier (planeForTier('data-plane') === 'platform') as a SIBLING to the Consent & Preferences Management, Master Patient Index, Break-the-Glass, and Data Retention agents — it does NOT invent a new tier or plane, and it deliberately broadens the PLATFORM & DATA SUBSTRATE (which recent additions had not touched) rather than piling onto the payer / patient-access side. It COMPLEMENTS, not duplicates, the other platform agents: distinct from the Consent & Preferences Management agent (patient consent scopes for outreach / data-sharing), the Master Patient Index (identity / dedup), the Break-the-Glass agent (emergency PHI access), the Data Retention agent (records disposition), and the Data-Sharing / TEFCA agent (interoperability exchange), this decides whether a dataset is DE-IDENTIFIED (no longer PHI) under HIPAA Safe Harbor before a secondary use / disclosure. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/deidentification.ts, evaluateDeidentification(request) takes a dataset described by its FIELDS (each a name, the Safe Harbor identifier category it maps to — or non-identifier — and the action taken: removed / generalized / retained), the chosen METHOD (safe-harbor or expert-determination), the categories attested absent, and (for expert determination) the cited determination reference, and DETERMINISTICALLY screens the dataset against the EIGHTEEN HIPAA Safe Harbor identifier categories (45 CFR 164.514(b)(2)(i)(A)–(R) — names, geographic, dates, phone, fax, email, SSN, MRN, health-plan-id, account, certificate/license, vehicle, device, URL, IP, biometric, photo, and any-other-unique), computes which categories remain identifiable after the field actions (a retained identifier, or a generalization that does not satisfy Safe Harbor — only geographic → first three ZIP digits and dates → year only qualify, every other category must be removed), computes whether all eighteen categories were screened (present as a field or attested absent), validates the method citation, and decides whether the dataset qualifies as de-identified: de-identified iff a recognized method is cited, all eighteen categories were screened, and no identifier category remains. The determination is a pure function of the dataset's fields + the category catalog (no randomness, no clock — NO Date.now()), so the same dataset always yields the same de-identification decision + remaining categories + release flag. A determination — de-identified or NOT — is a SAFE, honest OUTPUT: the task COMPLETES (a not-de-identified dataset carries requiresHumanReview:true and releaseApproved:false), which is how a legitimate determination is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Balance Billing and Data Retention agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.deid.all-categories-screened (signal deidAllCategoriesScreened, violating value false) blocks a determination whose screen SKIPPED a Safe Harbor category (a category neither present as a field nor attested absent) — an incomplete screen may hide a re-identifying identifier, so a dataset cannot be claimed de-identified without accounting for every category (this is the load-bearing completeness gate, mirroring the Good Faith Estimate Agent's expected-items-complete and the Lab Result Agent's critical-value-notified — a completeness obligation that cannot be skipped) — backed by the pure guard deidAllCategoriesScreened; policy.deid.method-cited (signal deidMethodCited, violating value false) blocks an ad-hoc / un-cited de-identification that names no recognized method — neither HIPAA Safe Harbor (§164.514(b)(2)) nor a qualified Expert Determination with a cited determination reference (§164.514(b)(1)) — backed by the guard deidMethodCited (mirroring the Data Retention Agent's schedule-sourced and the Balance Billing Agent's protection-basis-sourced posture); and policy.deid.no-release-of-reidentifiable (signal deidNoReleaseOfReidentifiable, violating value false) blocks a determination that marks a dataset de-identified / release-approved while an identifier category still REMAINS (a retained identifier, or a generalization that does not satisfy Safe Harbor) — a re-identifiable dataset is NOT de-identified and may never be released as de-identified; releasing re-identifiable data requires human review under a data use agreement — backed by the guard deidNoReleaseOfReidentifiable (mirroring the Balance Billing Agent's no-autonomous-balance-bill and the Master Patient Index Agent's no-autonomous-merge posture; the harmful action is enforced-off). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — it screens patient datasets), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/deidentification/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — deid.receive-dataset → deid.screen → deid.determine → deid.log-audit — with phiAccessed:true, returning the DeidentificationDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new De-Identification panel (a Safe Harbor scrub preset → de-identified / release approved, an expert-determination-with-cited-ref preset → de-identified, an MRN-retained preset → not de-identified / release withheld, an incomplete-screen preset → not de-identified, plus incomplete-screen-marked-de-identified / no-cited-method / re-identifiable-release governance-block presets), a seeded deid.receive-dataset→screen→determine→log-audit trace showing a fully-scrubbed Safe Harbor dataset (18/18 categories screened, 0 remaining identifiers, release approved, phiAccessed:true), the console subtitle, and the investor brief (now 'fifty-seven agents', with the De-Identification agent on the platform data-plane tier alongside the other substrate agents) all reflect it. Frontend tests green (2,562 tests — + de-identification catalog / screen / method / generalization / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / allow + not-de-identified happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to fifty-seven agents); the Safe Harbor category catalog + generalization rules are clearly-labeled illustrative synthetics, NOT a certified de-identification engine — a real determination applies the full Safe Harbor method (including the actual-knowledge clause) or a qualified statistician's Expert Determination under 45 CFR 164.514(b). Lint + build clean.

9e449ca agent fabric: add the De-Identification & Safe Harbor agent (57th) — deterministic HIPAA Safe Harbor screening with all-eighteen-categories-screened, method-cited, and never a re-identifiable release

Agent Fabric: added the Balance Billing Protection (No Surprises Act) agent — deterministic claim-time protection with protection-basis-sourced, in-network (QPA) cost-share basis, and never an autonomous balance bill (the 56th agent)

Shipped
Details

Added the fifty-sixth agent on the fabric — balance-billing-agent, a DETERMINISTIC (no-Claude) payer & plan operations service on the PHI-bearing payer plane, reusing the existing payer-operations tier as a SIBLING to the Claims Adjudication, Coordination of Benefits, Overpayment & Recovery, Utilization Review, and FWA agents — it does NOT invent a new tier or plane, and it is the CLAIM-time complement to the patient-access Good Faith Estimate agent (the two sides of the No Surprises Act: the provider-estimate side and the payer/claims side). It COMPLEMENTS, not duplicates, the other payer agents: distinct from Claims Adjudication (per-claim edits), Coordination of Benefits (payer ORDER), Overpayment & Recovery (POST-payment clawback), Utilization Review (medical necessity), and FWA (fraud) — this decides, at claim time, whether the No Surprises Act PROHIBITS balance-billing an out-of-network claim and on what basis a protected patient's cost-share is computed. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/balance-billing.ts, evaluateBalanceBilling(request) takes a claim (its protection basis — the service setting / provider network status — plus the service type, whether it is an ancillary service, the billed charge, the in-network allowed / Qualifying Payment Amount, and whether a valid notice-and-consent waiver was obtained) and DETERMINISTICALLY resolves the protection basis from a PROTECTION_BASES catalog (emergency, out-of-network at an in-network facility, air ambulance, ground ambulance, in-network), applies any EFFECTIVE waiver (valid only for a waivable, non-ancillary service — ancillary services like anesthesiology / radiology / pathology can NEVER be waived), decides whether the patient is PROTECTED, computes the patient's cost-share BASIS (the in-network QPA for a protected claim, never the out-of-network billed charge), and computes the balance-bill amount (0 + prohibited for a protected claim; billedCharge − allowed for a permitted one). Protection applies to emergency services, an out-of-network provider at an in-network facility, and air ambulance; an out-of-network ground ambulance is NOT protected (a known NSA gap). The determination is a pure function of the request + the basis catalog (no randomness, no clock — time taken as data, NO Date.now()), so the same claim always yields the same protection + cost-share basis + balance-bill flags. A determination — protected or not — is a SAFE, honest OUTPUT: the task COMPLETES (a permitted balance bill on a NON-protected claim carries requiresHumanReview:true), which is how a legitimate determination is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Overpayment & Recovery and Good Faith Estimate agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.balancebill.protection-basis-sourced (signal balanceBillBasisCited, violating value false) blocks an ad-hoc / un-sourced protection call that doesn't cite a recorded protection basis (a missing or off-catalog basis id) — backed by the pure guard balanceBillBasisCited (mirroring the Overpayment & Recovery agent's reason-catalog-sourced and the Good Faith Estimate agent's charge-master-sourced posture); policy.balancebill.cost-share-in-network-basis (signal balanceBillCostShareInNetwork, violating value false) blocks a determination that bases a PROTECTED patient's cost-share on the out-of-network billed charge instead of the in-network (QPA) basis — basing it on the billed charge OVER-CHARGES the patient, and the No Surprises Act (45 CFR 149.110–149.130) requires cost-sharing for a protected service to be based on the recognized amount (the QPA) (this is the load-bearing gate, mirroring the Overpayment & Recovery agent's within-lookback-window — a legal basis bounds the dollar figure) — backed by the guard balanceBillCostShareInNetwork; and policy.balancebill.no-autonomous-balance-bill (signal balanceBillProhibitionHonored, violating value false) blocks a determination that ALLOWS a balance bill on a PROTECTED claim — a protected claim can NEVER be balance-billed (the difference between the billed charge and the allowed amount may not be billed to the patient, and a balance bill is never issued autonomously against a protected patient); a permitted balance bill on a NON-protected claim (a valid waiver, an out-of-network ground ambulance) is a RECOMMENDATION requiring human review — backed by the guard balanceBillProhibitionHonored (mirroring the Overpayment & Recovery agent's no-autonomous-clawback and the Lab Result agent's no-autonomous-clinical-action posture). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — a payer-operations agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/balance-billing/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — balancebill.receive-claim → balancebill.evaluate → balancebill.recommend → balancebill.log-audit — with phiAccessed:true, returning the BalanceBillingDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Balance Billing Protection panel (an OON emergency preset → protected / in-network cost-share / no balance bill, an OON anesthesiology (ancillary) preset → protected (cannot be waived), an OON elective-surgery + valid-waiver preset → permitted balance bill requiring review, an OON ground-ambulance preset → not protected / permitted balance bill, plus no-cited-basis / protected-on-billed-charge / balance-bill-on-protected governance-block presets), a seeded balancebill.receive-claim→evaluate→recommend→log-audit trace showing a protected out-of-network emergency (cost-share on the $1,200 in-network QPA, balance billing prohibited, phiAccessed:true), the console subtitle, and the investor brief (now 'fifty-six agents', with the Balance Billing agent on the payer-operations tier alongside the other payer agents) all reflect it. Frontend tests green (2,530 tests — + balance-billing catalog / protection / waiver / cost-share-basis / determinism / off-catalog / three-signal-true-and-false guards, the route's envelope / three governance blocks / allow + permitted-bill happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to fifty-six agents); the protection bases, waiver rules, ancillary handling, and QPA amounts are clearly-labeled illustrative synthetics, NOT a certified No Surprises Act engine — a real determination uses the actual Qualifying Payment Amount, the federal Independent Dispute Resolution process, the notice-and-consent requirements, and the provider's network contracts under 45 CFR 149. Lint + build clean.

082da97 agent fabric: add the Balance Billing Protection (No Surprises Act) agent (56th) — deterministic claim-time protection with protection-basis-sourced, in-network (QPA) cost-share basis, and never an autonomous balance bill

Agent Fabric: added the Good Faith Estimate (No Surprises Act) agent — deterministic itemized self-pay estimate with charge-master-sourced pricing, expected-items-complete, and estimate-not-binding (the 55th agent)

Shipped
Details

Added the fifty-fifth agent on the fabric — good-faith-estimate-agent, a DETERMINISTIC (no-Claude) patient-access service on the PHI-bearing patient & clinical plane, reusing the existing benefits-verification (patient-access) tier (planeForTier('benefits-verification') === 'patient-care') as a SIBLING to the Benefits & Coverage Verification (EBV) and Patient Financial Assistance & Charity Care agents — it does NOT invent a new tier or plane, and it completes the patient-access financial TRIAD: plan eligibility (EBV) → itemized self-pay estimate (this) → charity screening (Financial Assistance). It COMPLEMENTS, not duplicates, its siblings: the EBV agent verifies what the PLAN covers (eligibility + the estimated COVERED visit cost) and the Financial Assistance agent screens the patient-responsibility remainder for CHARITY CARE — this assembles the itemized SELF-PAY / uninsured estimate of expected charges required BEFORE care under the No Surprises Act. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/good-faith-estimate.ts, evaluateGoodFaithEstimate(request) takes a scheduled primary service + the expected line items (each a charge-master service id + quantity) and DETERMINISTICALLY prices each line item from an illustrative CHARGE_MASTER (established visit $220, comprehensive menopause consult $400, hormone panel $180, DEXA $250, pelvic ultrasound $450, HRT admin $90), verifies the estimate includes the primary service AND every reasonably-expected co-item from EXPECTED_COITEMS (a comprehensive consult expects a hormone panel; a DEXA / pelvic ultrasound expects an ordering office visit), sums the total expected charge, and returns a Good Faith Estimate that is an ESTIMATE (binding:false) requiring patient confirmation, with the No Surprises Act $400 dispute threshold recorded (if the actual bill exceeds the GFE by $400 or more the patient has dispute rights). The estimate is a pure function of the request's line items + the charge master (no randomness, no clock — time taken as data, NO Date.now()), so the same request always yields the same total + completeness + sourcing flags. A GFE is a SAFE, honest OUTPUT: the task COMPLETES (binding:false, requiresPatientConfirmation:true), which is how a legitimate estimate is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Lab Result and Patient Financial Assistance agents' output-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.gfe.charge-master-sourced (signal gfeChargeMasterSourced, violating value false) blocks a determination with a line item that is NOT charge-master-sourced (an off-catalog service id or an amount that doesn't match the charge master — an ad-hoc / fabricated charge) — backed by the pure guard gfeChargeMasterSourced (mirroring the Overpayment & Recovery Agent's reason-catalog-sourced and the Lab Result Agent's reference-range-sourced posture); policy.gfe.expected-items-complete (signal gfeExpectedItemsComplete, violating value false) blocks an INCOMPLETE estimate that omits the primary service or a reasonably-expected co-item — an incomplete estimate UNDERSTATES the total and misleads the patient, and the No Surprises Act (45 CFR 149.610) requires the convening provider to include items/services reasonably expected to be furnished (this is the load-bearing gate, mirroring the Care Coordination Handoff Agent's SBAR-completeness and the Lab Result Agent's critical-value-notified — a completeness obligation that cannot be skipped) — backed by the guard gfeExpectedItemsComplete; and policy.gfe.estimate-not-binding (signal gfeEstimateNotBinding, violating value false) blocks a determination presented as a BINDING / final bill (binding:true) — a GFE is an ESTIMATE requiring patient confirmation, never a final charge — backed by the guard gfeEstimateNotBinding (mirroring the Lab Result Agent's no-autonomous-clinical-action and the Financial Assistance Agent's no-autonomous-denial posture; the agent recommends, a human confirms). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — a patient-access agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/good-faith-estimate/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — gfe.receive-request → gfe.price → gfe.assemble → gfe.log-audit — with phiAccessed:true, returning the GoodFaithEstimateDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Good Faith Estimate panel (a complete-consult preset → $580, a complete-imaging DEXA preset → $470, plus off-catalog-charge / missing-item / binding-bill governance-block presets), a seeded gfe.receive-request→price→assemble→log-audit trace showing a complete $580 consult estimate (phiAccessed:true), the console subtitle, and the investor brief (now 'fifty-five agents', with the Good Faith Estimate agent on the patient-access tier alongside EBV + Financial Assistance) all reflect it. Frontend tests green (2,499 tests — + good-faith-estimate charge-master / pricing / completeness / determinism / three-signal-true-and-false guards, the route's envelope / three governance blocks / allow happy path, the panel's request-body + view-lift, and the registry + brief drift guards raised to fifty-five agents); the charge master, categories, amounts, and expected-co-item rules are clearly-labeled illustrative synthetics, NOT a certified hospital chargemaster, machine-readable price-transparency file, or a real provider's charges — a real GFE is governed by the No Surprises Act (45 CFR 149.610), the provider's actual charges, and HHS guidance. Lint + build clean.

a5910e1 agent fabric: add the Good Faith Estimate (No Surprises Act) agent (55th) — deterministic itemized self-pay estimate with charge-master-sourced, expected-items-complete, and estimate-not-binding

Agent Fabric: added the Lab Result & Critical-Value Notification agent — deterministic result classification with critical-value-notified, reference-range-sourced, and no autonomous clinical action (the 54th agent)

Shipped
Details

Added the fifty-fourth agent on the fabric — lab-result-agent, a DETERMINISTIC (no-Claude) clinical-decision service on the PHI-bearing patient & clinical plane, reusing the existing clinical-decision tier (the Care Router / Care Plan / Prior Auth tier, planeForTier('clinical-decision') === 'patient-care') as a deterministic SIBLING to the live-Claude Care Router — it does NOT invent a new tier or plane, and it deliberately broadens the fabric into the CLINICAL side (the clinical-decision tier previously held only the Care Router + Care Plan + Prior Auth) rather than piling onto the payer / patient-financial side. It COMPLEMENTS, not duplicates, the other clinical / care agents: distinct from the Remote Patient Monitoring agent (continuous wearable / RPM streams), the Clinical Summary agent (chart summarization), and the Care Gap Closure agent (missing preventive measures), this manages DISCRETE diagnostic LAB results + the critical-value notification workflow. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/lab-result.ts, evaluateLabResult(request) takes a discrete diagnostic lab result (an analyte id + numeric value + unit, with the patient + ordering-provider references) and DETERMINISTICALLY classifies the value against the analyte's reference range + critical thresholds from a LAB_ANALYTES catalog (potassium, sodium, glucose, calcium, hemoglobin — the electrolyte / glucose / calcium / hemoglobin panel a midlife patient on HRT or under bone-health monitoring routinely has drawn) as normal / abnormal-high / abnormal-low / critical-high / critical-low, flags whether the result requires MANDATORY clinician notification (a critical / panic value) and whether it requires clinician review (any abnormal result); critical thresholds take precedence over the reference range. The classification is a pure function of the value + the analyte's catalog range (no randomness, no clock — time taken as data, NO Date.now()), so the same result always yields the same classification + notification + review flags. A classification — even a CRITICAL one — is a SAFE, honest OUTPUT: the task COMPLETES (a critical result carries requiresProviderNotification:true; any non-normal result carries requiresClinicianReview:true), which is how a legitimate result is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Patient Financial Assistance and Overpayment & Recovery agents' recommendation-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.lab.critical-value-notified (signal labCriticalValueNotified, violating value false) blocks a determination that asserts a CRITICAL (panic) value that does NOT require provider notification — a critical value is NEVER suppressed or auto-closed, because CLIA §493.1291(g) requires the laboratory to immediately alert the responsible provider (this is the load-bearing parallel to the Care Coordination Handoff agent's SBAR-completeness — a life-safety obligation that cannot be skipped) — backed by the pure guard labCriticalValueNotified; policy.lab.reference-range-sourced (signal labRangeCited, violating value false) blocks an ad-hoc / un-sourced result interpretation that doesn't cite a recorded analyte reference range (a missing or off-catalog analyte id) — backed by the guard labRangeCited (mirroring the Overpayment & Recovery agent's reason-catalog-sourced and the Data Retention agent's schedule-sourced posture); and policy.lab.no-autonomous-clinical-action (signal labClinicianReviewed, violating value false) blocks a determination that would autonomously ACT on a non-normal result (an abnormal / critical result not gated on clinician review) — the agent NEVER orders a test, prescribes, treats, or changes a care plan; every non-normal result is a flag escalated for clinician review (requiresClinicianReview:true) — backed by the guard labClinicianReviewed (mirroring the Utilization Review agent's no-autonomous-denial and the Risk Adjustment agent's no-autonomous-submission posture). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — a clinical-decision agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/lab-result/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — lab.receive-result → lab.classify → lab.recommend → lab.log-audit — with phiAccessed:true, returning the LabResultDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Lab Result panel (a normal-potassium preset → no notification, a critical-high-potassium preset → mandatory notification, an abnormal-high-glucose preset → clinician review only, a critical-low-sodium preset → mandatory notification, plus suppress-critical / no-cited-range / autonomous-action governance-block presets), a seeded lab.receive-result→classify→recommend→log-audit trace showing a critical-high potassium (6.8 mmol/L, requiresProviderNotification:true, phiAccessed:true), the console subtitle, and the investor brief (now 'fifty-four agents', with the Lab Result agent on the clinical-decision tier alongside the Care Router) all reflect it. Frontend tests green (2,470 tests — + lab-result catalog / classification / determinism / off-catalog / three-signal-true-and-false guards, the route's envelope / three governance blocks / allow + normal happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to fifty-four agents); the analyte catalog, reference ranges, units, and critical thresholds are clearly-labeled illustrative synthetics, NOT a certified laboratory information system or a CLIA-validated critical-value policy — real ranges are method-/instrument-/population-specific and set by each laboratory's medical director under CLIA (42 CFR 493) + CAP accreditation. Lint + build clean.

3677d40 agent fabric: add the Lab Result & Critical-Value Notification agent (54th) — deterministic result classification with critical-value-notified, reference-range-sourced, and no autonomous clinical action

Agent Fabric: added the Patient Financial Assistance & Charity Care agent — deterministic 501(r) charity-care screening with no-collections-before-screening, FAP-schedule-sourced eligibility, and no autonomous denial (the 53rd agent)

Shipped
Details

Added the fifty-third agent on the fabric — financial-assistance-agent, a provider-side patient-financial-experience service on the PHI-bearing patient & clinical plane, reusing the existing benefits-verification tier as a SIBLING to the Benefits & Coverage Verification (EBV) agent (planeForTier('benefits-verification') === 'patient-care') — it does NOT invent a new tier or plane, and it deliberately balances the fabric toward the patient-access side rather than piling onto the payer plane. It COMPLEMENTS, not duplicates, the EBV agent: EBV verifies what the PLAN covers (eligibility + the estimated covered visit cost); this screens the PATIENT-RESPONSIBILITY remainder for CHARITY CARE — a different question — and is also distinct from the SDOH Screening agent (health-related social needs). It is a DETERMINISTIC, no-Claude agent: in a new pure lib/financial-assistance.ts, evaluateFinancialAssistance(request) takes a household size + annual income (plus the FPL guideline year, an optional presumptive-eligibility signal, whether the FAP application is complete, and whether an extraordinary collection action is being requested) and DETERMINISTICALLY computes the household's income as a percentage of the Federal Poverty Level (from the household size's FPL base in an illustrative FPL_TABLE + per-person increment), cites the governing FAP tier from an illustrative FAP_SCHEDULE (≤200% FPL → full charity 100% discount, 201–300% → 75%, 301–400% → 50%, >400% → not eligible), and classifies the patient as full-charity / partial-charity / not-eligible with a discount percentage under an IRS 501(r) Financial Assistance Policy; a recorded presumptive-eligibility reason (PRESUMPTIVE_REASONS — Medicaid-eligible, homelessness, SNAP-enrolled, deceased-no-estate) grants full charity regardless of documented income. The determination is a pure function of the household size + income + FPL year + the request's own flags (no randomness, no clock — time taken as data, NO Date.now()), so the same household always yields the same tier + discount + eligibility. GRANTING full or partial charity — and even a not-eligible determination — are SAFE, honest OUTPUTS: the task COMPLETES (a not-eligible determination carries requiresHumanReview:true and never an autonomous denial), which is how a legitimate recommendation is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Overpayment & Recovery and Data Retention agents' recommendation-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.finassist.no-eca-before-screening (signal ecaGatedOnScreening, violating value false) blocks a determination that asserts an extraordinary collection action (ECA — collections, credit reporting, a lien) while financial screening is NOT complete — under IRS 501(r)(6) a hospital must make reasonable efforts to determine FAP eligibility BEFORE any ECA (this is the load-bearing parallel to the Data Retention agent's legal-hold-overrides-purge and the Overpayment & Recovery agent's within-lookback-window: a legal precondition bounds the action) — backed by the pure guard ecaGatedOnScreening; policy.finassist.fap-schedule-sourced (signal finAssistScheduleCited, violating value false) blocks an ad-hoc / un-sourced eligibility decision that doesn't cite a recorded FAP tier — backed by the guard finAssistScheduleCited (mirroring the Data Retention agent's schedule-sourced and the Overpayment & Recovery agent's reason-catalog-sourced posture); and policy.finassist.no-autonomous-denial (signal finAssistHumanReviewed, violating value false) blocks a determination that would autonomously DENY charity care — a not-eligible determination is a RECOMMENDATION requiring human review with written notice + appeal rights under 501(r)(4) (requiresHumanReview:true) — backed by the guard finAssistHumanReviewed (mirroring the Overpayment & Recovery agent's no-autonomous-clawback, the Utilization Review agent's no-autonomous-denial, and the Claims Adjudication agent's no-autonomous-denial posture; granting charity is a benefit but denying it is legally consequential). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — a patient-access agent, not a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/financial-assistance/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — finassist.receive-application → finassist.evaluate → finassist.recommend → finassist.log-audit — with phiAccessed:true, returning the FinancialAssistanceDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Patient Financial Assistance panel (a full-charity preset → 100% discount, a partial-charity preset → 75% discount, a Medicaid presumptive-eligibility preset → full charity, a not-eligible preset → a denial requiring human review, plus eca-before-screening / no-cited-tier / autonomous-denial governance-block presets), a seeded finassist.receive-application→evaluate→recommend→log-audit trace showing a full-charity grant (household of 3 at 116% FPL, 100% discount, phiAccessed:true), the console subtitle, and the investor brief (now 'fifty-three agents', with the Patient Financial Assistance agent on the patient-access tier paired with the EBV agent) all reflect it. Frontend tests green (2,438 tests — + financial-assistance catalog / FPL-table / classification / determinism / ECA-gating / three-signal-true-and-false guards, the route's envelope / three governance blocks / allow + denial happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to fifty-three agents); the FAP tier schedule, discount percentages, FPL table, and presumptive-eligibility reasons are clearly-labeled illustrative synthetics, NOT a certified financial-assistance system — real hospital FAPs are governed by IRS 501(r) / 26 CFR 1.501(r), the HHS Federal Poverty Guidelines, and each hospital's Board-approved FAP + state charity-care law. Lint + build clean.

9923500 agent fabric: add the Patient Financial Assistance & Charity Care agent (53rd) — deterministic 501(r) charity-care screening with no-eca-before-screening, fap-schedule-sourced, and no autonomous denial

Week of August 30, 2026

The regulated payer & patient-rights agents — COB through Right of Access (51st–67th)

A run of deterministic, human-cosign-gated payer-operations and patient-rights agents: Coordination of Benefits, Claims Overpayment & Recovery, Patient Financial Assistance, Lab Result & Critical-Value Notification, Good Faith Estimate, Balance Billing Protection, De-Identification, Immunization Forecasting, Minimum Necessary, Audit Log Integrity, Timely Filing, Controlled Substance / PDMP, Advance Beneficiary Notice, Accounting of Disclosures, Subrogation, Deal Desk, and Right of Access — each catalog-sourced and never an autonomous adverse determination.

Agent Fabric: added the Claims Overpayment & Recovery agent — deterministic post-payment integrity with within-lookback-window, reason-catalog-sourced, and no autonomous clawback (the 52nd agent)

Shipped
Details

Added the fifty-second agent on the fabric — overpayment-recovery-agent, a plan-side (health-plan / TPA) payer & plan operations service on the PHI-bearing payer & plan operations plane, reusing the existing payer-operations tier the Claims Adjudication, Formulary/DUR, Fraud-Waste-Abuse, Utilization Review, and Coordination of Benefits agents use (planeForTier('payer-operations') === 'payer-plane') — it does NOT invent a new tier or plane. It is the POST-payment integrity layer, and COMPLEMENTS, not duplicates, the other payer agents: distinct from the Claims Adjudication Assistant (first-pass PRE-payment adjudication), the Fraud, Waste & Abuse Detection agent (suspected fraud patterns), and the Coordination of Benefits agent (which decides payer ORDER), this recovers a legitimate overpayment already made — and its cob-primary-elsewhere reason pairs directly with the COB agent's output. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/overpayment-recovery.ts, evaluateRecovery(request) takes a PAID claim (what was paid, what should have been paid, the recovery reason, the paid date, and an explicit asOfDate) and DETERMINISTICALLY computes the overpayment (max(paid − correct, 0)), cites the governing recovery reason from a RECOVERY_REASONS catalog (duplicate-payment → 1-year lookback, cob-primary-elsewhere → 2-year, retroactive-termination → 1-year, pricing-error → 18-month, services-not-rendered → 3-year), derives the recovery deadline from the paid date + the reason's statutory lookback window, and classifies the claim as recoverable / not-recoverable-within-window / no-overpayment. The determination is a pure function of the claim's amounts + dates + the request's own asOfDate (no randomness, no clock — time taken as data, NO Date.now()), so the same claim always yields the same overpayment + cited reason + recoverability. A `recoverable` determination (an overpayment within its lookback window) is a SAFE, honest RECOMMENDATION requiring human review with member/provider notice (requiresHumanReview:true) — the task COMPLETES, NOT a block, and NEVER means money was clawed back — which is how a legitimate recovery recommendation is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the COB and Data Retention agents' recommendation-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.recovery.within-lookback-window (signal recoveryWithinLookback, violating value false) blocks a determination that asserts a claim as recoverable while it is PAST its statutory lookback window — an overpayment past its window is NEVER recoverable, and clawing back beyond the lookback is an unlawful recoupment (this is the load-bearing parallel to the Data Retention agent's legal-hold-overrides-purge and the UR agent's SLA-integrity: a window bounds the action) — backed by the pure guard recoveryWithinLookback; policy.recovery.reason-catalog-sourced (signal recoveryReasonCited, violating value false) blocks an ad-hoc / un-sourced clawback that doesn't cite a recorded recovery reason — backed by the guard recoveryReasonCited (mirroring the Data Retention agent's schedule-sourced and the Claims Adjudication agent's edit-catalog-sourced posture); and policy.recovery.no-autonomous-clawback (signal recoveryClawbackHumanReviewed, violating value false) blocks a determination that would autonomously / unreviewedly claw back — a recoverable overpayment is a recommendation requiring human review (requiresHumanReview:true) — backed by the guard recoveryClawbackHumanReviewed (mirroring the FWA agent's no-autonomous-denial and the Data Retention agent's no-autonomous-purge posture). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — a payer & plan operations agent, not a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/overpayment-recovery/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — recovery.receive-claim → recovery.evaluate → recovery.recommend → recovery.log-audit — with phiAccessed:true, returning the RecoveryDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Claims Overpayment & Recovery panel (a duplicate-payment preset → recoverable within its 1-year window, a cob-primary-elsewhere preset → recoverable within its 2-year window, a retro-termination-past-window preset → not-recoverable-within-window, plus past-window / no-reason / autonomous-clawback governance-block presets), a seeded recovery.receive-claim→evaluate→recommend→log-audit trace showing a recoverable duplicate payment (overpaymentAmount 600, requiresHumanReview:true, phiAccessed:true), the console subtitle, and the investor brief (now 'fifty-two agents', with the Claims Overpayment & Recovery agent on the payer & plan operations plane paired with Claims Adjudication + Formulary/DUR + FWA + Utilization Review + Coordination of Benefits) all reflect it. Frontend tests green (2,405 tests — + overpayment-recovery catalog / classification / determinism / past-window / no-overpayment / three-signal-true-and-false guards, the route's envelope / three governance blocks / allow + past-window happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to fifty-two agents); the recovery reason catalog, lookback windows, and reason ids are clearly-labeled illustrative synthetics, NOT a certified payment-integrity system — real overpayment recovery is governed by the ACA §6402 60-day overpayment rule, CMS recovery rules, ERISA, and state insurance code. Lint + build clean.

5c9a4e8 agent fabric: add the Claims Overpayment & Recovery agent (52nd) — deterministic post-payment integrity with within-lookback-window, reason-catalog-sourced, and no autonomous clawback

Agent Fabric: added the Coordination of Benefits agent — deterministic order-of-benefits with custody-decree-overrides-birthday, rule-sourced ordering, and no autonomous adjudication (the 51st agent)

Shipped
Details

Added the fifty-first agent on the fabric — coordination-of-benefits-agent, a plan-side (health-plan / TPA) payer & plan operations service on the PHI-bearing payer & plan operations plane, reusing the existing payer-operations tier the Claims Adjudication, Formulary/DUR, Fraud-Waste-Abuse, and Utilization Review agents use (planeForTier('payer-operations') === 'payer-plan') — it does NOT invent a new tier or plane. It COMPLEMENTS, not duplicates, the other payer agents: distinct from the Claims Adjudication Assistant (first-pass PER-CLAIM edits AFTER the payer order is known), the Benefits & Coverage Verification / EBV agent (single-plan eligibility), and the Utilization Review agent (medical necessity), this one decides the ORDER OF BENEFITS ACROSS multiple coverages BEFORE a claim is adjudicated. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/coordination-of-benefits.ts, evaluateCoordinationOfBenefits(request) takes a patient's set of COVERAGES (each: how the patient is covered — as the subscriber/employee or as a dependent — the plan type, whether the coverage is through current active employment, the covering parent/subscriber's birthday as month/day for the birthday rule, and the coverage start date) plus whether the patient is a dependent child and an evaluation atTime, and DETERMINISTICALLY ORDERS the coverages (primary → secondary → tertiary) by applying the NAIC-model order-of-benefits rules + Medicare Secondary Payer + the birthday rule, with a documented precedence (custody-decree > Medicaid-payer-of-last-resort > Medicare-secondary-payer > subscriber-before-dependent > active-before-inactive > birthday-rule > longer-coverage tie-break), citing the governing COB rule from a COB_RULES catalog on every ordering decision. The ordering is a pure function of the coverages + the request's own context (no randomness, no clock — time taken as data, NO Date.now()), so the same coverages always yield the same order + cited rules. An order-of-benefits determination is a SAFE, honest RECOMMENDATION requiring human cosign — the task COMPLETES, NOT a block, and NEVER an autonomous payment — which is how a legitimate payer-order recommendation is distinguished from a governance block (the block fires only on a caller-asserted DETERMINATION that violates a guard, mirroring the Data Retention agent's recommendation-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.cob.custody-decree-overrides-birthday (signal cobDecreeHonored, violating value false) blocks an ordering that ignores an active custody / court decree naming a dependent child's primary coverage — a decree ALWAYS overrides the birthday rule (this is the load-bearing parallel to the Data Retention agent's legal-hold-overrides-purge: a legal instrument overrides the default rule) — backed by the pure guard cobDecreeHonored; policy.cob.order-of-benefits-rule-sourced (signal cobRuleCited, violating value false) blocks an ad-hoc ordering that doesn't cite a recorded COB rule — backed by the guard cobRuleCited (mirroring the Data Retention agent's schedule-sourced and the Claims Adjudication agent's edit-catalog-sourced posture); and policy.cob.no-autonomous-adjudication (signal cobHumanCosigned, violating value false) blocks a determination that would autonomously adjudicate / pay a claim — a COB determination sets payer ORDER only and is a recommendation requiring human cosign (requiresHumanCosign:true) — backed by the guard cobHumanCosigned (mirroring the Claims Adjudication and Utilization Review agents' no-autonomous-denial posture). It also reuses, by extending appliesTo, the HIPAA-audit policy (it is PHI-bearing — a payer & plan operations agent, not a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/coordination-of-benefits/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — cob.receive-coverages → cob.order-benefits → cob.recommend → cob.log-audit — with phiAccessed:true, returning the CobDetermination as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Coordination of Benefits panel (a subscriber-before-dependent preset → the patient's own plan primary, a birthday-rule preset → the earlier-birthday parent's plan primary, a custody-decree preset → the decree-named plan primary overriding the birthday rule, and a Medicare-secondary preset → the active-employment group plan primary, plus decree-ignored / no-cited-rule / autonomous-adjudication governance-block presets), a seeded cob.receive-coverages→order-benefits→recommend→log-audit trace showing the custody-decree case (the father's plan primary despite the mother's earlier birthday; custodyDecreeApplied:true, phiAccessed:true), the console subtitle, and the investor brief (now 'fifty-one agents', with the Coordination of Benefits agent on the payer & plan operations plane paired with Claims Adjudication + Formulary/DUR + FWA + Utilization Review) all reflect it. Frontend tests green (+ coordination-of-benefits catalog / each-rule / determinism / decree-override / sole-and-no-coverage / three-signal-true-and-false guards, the route's envelope / three governance blocks / allow + decree-allow happy paths, the panel's request-body + view-lift, and the registry + brief drift guards raised to fifty-one agents); the COB rule catalog, plan types, and payer labels are clearly-labeled illustrative synthetics, NOT a certified coordination-of-benefits engine — real COB is governed by the NAIC COB Model Regulation, Medicare Secondary Payer (42 CFR 411), Medicaid third-party liability (42 CFR 433.139), ERISA plan documents, and state insurance code. Lint + build clean.

ff6bed7 agent fabric: add the Coordination of Benefits agent (51st) — deterministic order-of-benefits with custody-decree-overrides-birthday

Week of August 2, 2026

Identity, emergency access, and records lifecycle — plus the four-plane governance split

The platform & data-substrate governance agents landed — Master Patient Index / identity resolution, Break-the-Glass emergency access, and Data Retention & Records Lifecycle — alongside Risk Adjustment & HCC coding. Then a governance-taxonomy pass split the overloaded care-coordination tier into a fourth, PHI-bearing 'Payer & plan operations' plane, re-homing the payer-side agents with no logic change.

Agent Fabric: split the overloaded care-coordination tier — introduced a fourth, PHI-bearing 'Payer & plan operations' plane (payer-operations tier) and moved the four payer-side agents onto it, still on the HIPAA-audit policy, no logic change

Shipped
Details

A cross-plane consistency / governance-taxonomy pass on the Agent Fabric — no new agent, no capability change, no policy-logic change. The care-coordination tier on the patient/clinical plane had grown into a catch-all of twenty agents, several of which are not patient-care at all but PLAN-SIDE payer operations. This change relieves that overload by introducing a FOURTH governed plane — 'Payer & plan operations · PHI' (plane slug payer-plan) — and a new payer-operations tier on it, then re-homing exactly four agents from care-coordination onto the new tier: the Claims Adjudication Assistant, the Formulary & Drug Utilization Review agent, the Fraud, Waste & Abuse Detection agent, and the Utilization Review (MCG/InterQual analog) agent. care-coordination drops from twenty to sixteen agents; payer-operations holds four; the fabric now spans four planes (patient/clinical, payer & plan operations, platform & data substrate, and the PHI-separated commercial plane). CRITICALLY, the new plane is PHI-BEARING — unlike the commercial plane (which is deliberately PHI-separated and OFF the HIPAA audit policy), these four agents still touch PHI and REMAIN on policy.audit.hipaa-log-every-turn; their policies arrays and the HIPAA policy's appliesTo are untouched, so there is no change to what they can do or how they are governed — only how they are grouped and displayed. The change is small and type-safe by construction: payer-operations is added to the GovernanceTier union and payer-plan to the GovernancePlane union in the single source of truth (lib/governance-tiers.ts), which makes the GOVERNANCE_TIERS + GOVERNANCE_PLANES records exhaustive (a missing label/plane is a compile error); the four agents' governanceTier flips from 'care-coordination' to 'payer-operations' in the registry (lib/agent-fabric.ts); the four matching brief cards flip their tier in agent-cards.ts; and the plane display order renumbers so planes read patient-care (0), payer-plan (1), platform (2), commercial (3). The console (/demo/agent-fabric) and the investor brief (/proposal/agent-fabric) group agents dynamically by planeForTier, so the new 'Payer & plan operations · PHI' group with its four cards renders automatically — no hand-maintained card list to edit. The brief+console prose was updated to enumerate four planes (not three): the four payer items were lifted out of the patient/clinical lifecycle sentence into a dedicated 'A PHI-bearing payer & plan operations plane runs claims adjudication, formulary/DUR review, fraud-waste-abuse detection, and utilization review — plan-side, human-cosign-gated, never an autonomous adverse determination' sentence, and both registry intros now say the patient/clinical AND payer & plan operations planes are PHI-bearing (on the HIPAA audit policy) while the commercial plane is strictly PHI-separated. The brief↔registry drift guard (agent-cards.test.ts) still passes because its per-tier histogram compares the brief to the registry dynamically (both now show payer-operations: 4, care-coordination: 16); frontend tests + lint + build all green.

a7aeb71 agent fabric: split care-coordination — add a PHI-bearing payer & plan operations plane (4 agents)

Proposal + console: consolidated the runaway agent-fabric brief + console subtitles into concise, plane-structured summaries — a copy edit, no agent / registry / tier change

Shipped
Details

A pure copy-edit pass on the two agent-fabric surfaces — no new agent, no registry change, no tier change, no test change. The investor brief at /proposal/agent-fabric and the console at /demo/agent-fabric had each grown a single multi-thousand-word prose string (the brief's ProposalShell subtitle and its Phase-0 detail, and the console's DemoShell subtitle) that enumerated all ~50 agents and their per-agent governance postures inline, so the same detail was repeated in the summary prose AND in the card grid / dynamic registry cards below it. Three string literals were replaced with concise, plane-structured summaries that name the three governed planes (patient/clinical, the platform & data substrate, and the PHI-separated commercial plane), list each plane's agents at a glance, and call out the four live-Claude agents + deterministic fallback and the end-to-end A2A → Care Router → MCP trace, without re-listing every per-agent policy — because the per-agent governance detail already lives in the card grid (brief) and the dynamic registry cards (console). The brief's Phase-0 detail stays a template literal so the ${AGENT_CARD_COUNT_WORD} count interpolation still leads; the two shell subtitles stay plain double-quoted props. Nothing else changed — the page titles, the card arrays, agent-cards.ts, the registry, and every test are untouched. The three strings dropped from roughly fourteen thousand characters combined to under three thousand. Frontend tests + lint + build all green.

e94e4d2 proposal + console: consolidate the runaway agent-fabric subtitles into concise plane summaries

Investor brief: locked the agent-fabric brief to the live registry (drift guard) and derived the spelled-out count — a consistency + consolidation pass, no new agent

Shipped
Details

A consolidation + cross-plane consistency pass on the investor brief at /proposal/agent-fabric — no new agent, no registry change, no tier change. The brief rendered its agents from a hand-maintained 50-entry array defined inline in page.tsx and hard-coded the spelled-out count 'Fifty' in two places (the page title and the Phase-0 detail), so the card list and the count could silently drift from the live registry in lib/agent-fabric.ts (the source of truth) as agents are added. Two changes fix that. FIRST, the inline array was extracted VERBATIM into a colocated app/proposal/agent-fabric/agent-cards.ts that exports the AgentCard type + the agentCards list (bytes-for-byte the same 50 cards — no prose reflowed or re-quoted), plus AGENT_CARD_COUNT = agentCards.length and AGENT_CARD_COUNT_WORD derived through a small dependency-free, pure integer-to-English-word helper (0-120, hyphenated tens+ones, capitalized; e.g. 50 -> 'Fifty'); the page now imports agentCards and renders the exact same plane groupings, per-plane counts, and card markup as before. SECOND, the two hard-coded 'Fifty' numerals — the page title and the leading word of the Phase-0 detail — now interpolate ${AGENT_CARD_COUNT_WORD}, so the count can never again disagree with the list (the curated subtitle / Phase-0 prose are otherwise untouched). The lock is a new drift-guard test (agent-cards.test.ts): it asserts agentCards.length equals listAgents().length (both 50), that the per-TIER histogram of the brief cards deep-equals the registry's per-governanceTier histogram (catching a card filed under the wrong tier or a missing/extra card in any tier, and transitively the per-plane counts), that every card tier is a real GOVERNANCE_TIERS key resolving to a plane, that every plane with cards is in PLANES_IN_ORDER, and that the derived count word stays 'Fifty' at the current registry size (plus direct unit assertions on the word helper: 21 -> 'Twenty-one', 50 -> 'Fifty'). On failure the REGISTRY is authoritative — the fix is to correct the brief card's tier, never the registry. The guard passed on first run (the brief's 50 tiers already matched the registry 1:1). Frontend tests + lint + build all green.

2425134 proposal: lock the agent-fabric brief to the registry (drift guard + derived count)

Agent Fabric: added the Data Retention & Records Lifecycle Management agent — deterministic records disposition with legal-hold-overrides-purge, schedule-sourced decisions, and no autonomous purge (the 50th agent)

Shipped
Details

Added the fiftieth agent on the fabric — records-retention-agent, the MuleSoft control-plane / data-substrate RECORDS-MANAGEMENT service, the records-disposition layer of the data substrate. Registered on the PLATFORM plane, reusing the existing data-plane tier the Consent & Preferences Management, Master Patient Index, and Break-the-Glass agents use (planeForTier('data-plane') === 'platform') — it does NOT invent a new tier. It COMPLEMENTS, not duplicates, the other platform agents: distinct from the Consent & Preferences Management agent (which manages patient consent scopes for outreach / data-sharing), the Master Patient Index (identity / dedup), and the Break-the-Glass / Emergency Access Governance agent (which governs emergency PHI ACCESS), this governs records RETENTION / DISPOSITION under records-management + legal-hold obligations. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/records-retention.ts, evaluateRetention(request) takes a record (type/category, patient, created and last-touched dates, patient DOB, jurisdiction, and any active legal hold) plus an evaluation atTime and DETERMINISTICALLY produces a disposition RECOMMENDATION — retain / eligible-for-purge / hold — citing the governing retention rule from a RETENTION_SCHEDULES catalog (adult clinical record → 7-year, minor's record → until age of majority + 3 years, billing/claim → 7-year, behavioral-health → 10-year, diagnostic imaging → 7-year; an off-catalog record type retains by default under a default retain-unscheduled rule so a record is never purged without a cited schedule) and the computed retention expiry (derived from the record's dates + the schedule period + request.atTime — time taken as data, NO Date.now()). An active LEGAL HOLD short-circuits to `hold` (a legal hold ALWAYS overrides a purge — a held record is never marked eligible-for-purge, no matter how far past its expiry); otherwise a record past its retention expiry with no hold is `eligible-for-purge`; otherwise `retain`. It returns { recommendation, retentionRuleId, retentionRuleLabel, retentionExpiresAt, underLegalHold, requiresHumanApproval, reason, synthetic:true, note }. It is a pure function of the record + its own atTime (no randomness, no clock), so the same request always yields the same recommendation + cited rule + expiry. An eligible-for-purge RECOMMENDATION (a record past its retention expiry with no active hold) is a SAFE, honest OUTPUT — the task COMPLETES, NOT a block, and NEVER a deletion (requiresHumanApproval:true) — which is how a legitimately-recommended purge is distinguished from a governance block (the block fires only on a caller-asserted DISPOSITION that violates a guard, mirroring the Break-the-Glass agent's deny-is-not-a-block and the Master Patient Index agent's possible-match-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.retention.legal-hold-overrides-purge (signal retentionRespectsLegalHold, violating value false) blocks a record on an active legal hold marked eligible-for-purge (a purge under a preservation obligation is spoliation) — backed by the pure guard retentionRespectsLegalHold; policy.retention.schedule-sourced (signal retentionRuleCited, violating value false) blocks an ad-hoc disposition that doesn't cite a recorded retention schedule — backed by the guard retentionRuleCited (mirroring the Master Patient Index agent's transparent-matching and the HEDIS agent's measure-catalog-sourced posture); and policy.retention.no-autonomous-purge (signal purgeHumanApproved, violating value false) blocks an autonomous / unapproved purge — an eligible-for-purge is a recommendation requiring human approval — backed by the guard purgeHumanApproved (mirroring the Master Patient Index agent's no-autonomous-merge and the Break-the-Glass agent's minimum-necessary-time-boxed posture). It also reuses, by extending appliesTo, the HIPAA-audit policy (it manages the lifecycle of PHI records — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/records-retention/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — retention.receive-record → retention.evaluate → retention.recommend → retention.log-audit — with phiAccessed:true, returning the RetentionDisposition as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Data Retention panel (six presets: a within-retention → retain, a past-expiry-no-hold → eligible-for-purge recommendation + human-approval-required, a legal-hold → hold that overrides the purge, plus purge-under-hold / no-cited-schedule / autonomous-purge governance-block presets), a seeded retention.receive-record→evaluate→recommend→log-audit trace showing an eligible-for-purge billing/claim record (past its 2023 expiry, no hold, requiresHumanApproval:true; phiAccessed:true), the console subtitle, and the investor brief (now 'fifty agents across three planes', with the Data Retention agent on the platform substrate paired with Consent & Preferences Management + the Master Patient Index + Break-the-Glass) all reflect it. Frontend tests green (+ records-retention catalog/expiry-derivation/determinism/retain-vs-eligible-for-purge-vs-hold/legal-hold-override/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow + eligible-for-purge-is-not-a-block happy paths, the panel's request-body + view-lift, and the registry drift guards raised to fifty agents); the retention schedules, periods, and rule ids are clearly-labeled illustrative synthetics, NOT a certified records-management system — real retention is jurisdiction-specific and legally reviewed (federal + state medical-record statutes, HIPAA §164.316(b)(2), CMS conditions of participation, statutes of limitations, and organizational records-management policy all differ). Lint + build clean.

1349508 agent fabric: add the Data Retention & Records Lifecycle Management agent (deterministic records disposition with legal-hold-overrides-purge + schedule-sourced decisions + no autonomous purge, the 50th agent)

Agent Fabric: added the Break-the-Glass / Emergency Access Governance agent — deterministic emergency-override access with justification-required, minimum-necessary + time-boxed grants, and mandatory audit + post-access review (the 49th agent)

Shipped
Details

Added the forty-ninth agent on the fabric — break-the-glass-agent, the MuleSoft control-plane / data-substrate SECURITY service, the emergency-access governance layer of the data substrate. Registered on the PLATFORM plane, reusing the existing data-plane tier the Consent & Preferences Management and Master Patient Index agents use (planeForTier('data-plane') === 'platform') — it does NOT invent a new tier. It COMPLEMENTS, not duplicates, the other platform agents: distinct from the Consent & Preferences Management agent (which manages patient consent scopes for outreach / data-sharing) and the Master Patient Index (identity / dedup), this governs EMERGENCY clinician 'break-the-glass' override access to PHI under the HIPAA minimum-necessary (§164.502) + audit-controls (§164.312) requirements. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/break-the-glass.ts, evaluateEmergencyAccess(request) takes an access request (requester role, target patient, stated purpose, an emergency flag, and a free-text clinical justification) and DETERMINISTICALLY decides whether to grant access — GRANTING only when an emergency is declared AND a non-empty justification is recorded AND the purpose is in the MINIMUM_NECESSARY_SCOPES catalog, and a grant is ALWAYS time-boxed (an expiry derived from request.atTime + the purpose's ACCESS_DURATIONS time-box — time taken as data, NO Date.now()) and minimum-necessary (the purpose's scoped field set — e.g. emergency-treatment → allergies / medications / problems / vitals, NEVER the full chart), ALWAYS emitting a mandatory audit event and flagging the grant for mandatory post-access review; otherwise it DENIES with a stable reason. It returns { granted, grantedScope, expiresAt, durationMinutes, justificationRecorded, auditEventId, requiresPostAccessReview, reason, synthetic:true, note }. It is a pure function of the request + its own atTime (no randomness, no clock), so the same request always yields the same grant/deny + scope + expiry + audit id. A DENY (no emergency declared, no recorded justification, or an off-catalog purpose with no derivable scope) is a SAFE, honest OUTPUT — the task COMPLETES, NOT a block — which is how a legitimately-denied request is distinguished from a governance block (the block fires only on a caller-asserted GRANT that violates a guard, mirroring the Master Patient Index agent's possible-match-is-not-a-block posture). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.btg.justification-required (signal accessHasJustification, violating value false) blocks a granted access with no recorded clinical justification — backed by the pure guard accessHasJustification; policy.btg.minimum-necessary-time-boxed (signal accessIsMinimumNecessaryTimeBoxed, violating value false) blocks a standing / full-record / non-expiring grant (an over-broad or full-chart scope, or a grant with no expiry) — backed by the guard accessIsMinimumNecessaryTimeBoxed (mirroring the Master Patient Index agent's no-autonomous-merge and the Population Health agent's no-autonomous-care-decision posture); and policy.btg.mandatory-audit-review (signal accessLoggedForReview, violating value false) blocks an un-audited / un-reviewed grant — backed by the guard accessLoggedForReview. It also reuses, by extending appliesTo, the HIPAA-audit policy (it governs PHI access — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/break-the-glass/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — btg.receive-request → btg.evaluate → btg.grant-scoped → btg.log-audit — with phiAccessed:true, returning the EmergencyAccessDecision as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Break-the-Glass panel (five presets: a valid emergency → a time-boxed, minimum-necessary grant with an audit event flagged for review, a no-emergency → safe deny, plus no-justification / standing-full-record / un-audited governance-block presets), a seeded btg.receive-request→evaluate→grant-scoped→log-audit trace showing a minimum-necessary emergency-treatment grant (4 fields, 60-minute time-box, logged, review-flagged; phiAccessed:true), the console subtitle, and the investor brief (now 'forty-nine agents across three planes', with the Break-the-Glass agent on the platform substrate paired with Consent & Preferences Management + the Master Patient Index) all reflect it. Frontend tests green (+ break-the-glass catalog/duration/determinism/grant-vs-deny/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow + deny-is-not-a-block happy paths, the panel's request-body + view-lift, and the registry drift guards raised to forty-nine agents); the purpose catalog, minimum-necessary scopes, access durations, and audit-event ids are clearly-labeled illustrative synthetics, NOT a certified break-the-glass / emergency-access system. Lint + build clean.

eaa66d2 agent fabric: add the Break-the-Glass / Emergency Access Governance agent (deterministic emergency-override access with justification-required + minimum-necessary + time-boxed grants + mandatory audit + post-access review, the 49th agent)

Agent Fabric: added the Master Patient Index / Identity Resolution agent — deterministic, transparent demographic matching with human-review-gated merges and no protected-class attributes (the 48th agent)

Shipped
Details

Added the forty-eighth agent on the fabric — master-patient-index-agent, the MuleSoft control-plane / data-substrate identity service, the identity/dedup layer of the data substrate. Registered on the PLATFORM plane, reusing the existing data-plane tier the Consent & Preferences Management agent uses (planeForTier('data-plane') === 'platform') — it does NOT invent a new tier. It COMPLEMENTS, not duplicates, the other platform agents (Salesforce Data 360 grounding, Consent & Preferences Management, the MuleSoft ingest process): this is the layer that decides whether two records are the SAME person. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/master-patient-index.ts, scoreCandidate(incoming, candidate) scores a candidate against a TRANSPARENT weighted demographic feature set (MATCH_FEATURES — name 30, DOB 25, member/MRN identifier 20, address 12, phone 8, administrative sex 5; MAX_SCORE 100), returning { candidateId, score, matchedFeatures[], classification } where the score is the additive sum of the matched features' weights and the classification is derived from FIXED MATCH_THRESHOLDS (auto-match 85, possible-match 55) by classifyScore; resolveIdentity(incoming, candidates) scores every candidate, orders them score-descending with a stable documented candidateId-ascending tie-break, and returns the full IdentityResolution { candidates[], bestMatch, recommendation: 'link' | 'merge' | 'manual-review' | 'no-action', requiresHumanReview, synthetic:true, note }. It is a pure function of the records (no randomness, no clock; text normalized case/space-insensitively, phones to trailing 10 digits), so the same incoming + candidates always yield the same scores + classifications + recommendation. It is a RECOMMENDER + integrity gate: a match at/above the auto-match threshold surfaces a merge (when a shared identifier corroborates it) or link, but a candidate in the possible-match review band is a manual-review recommendation carrying requiresHumanReview:true — a SAFE, honest OUTPUT for a human steward, NOT a block, and there is never an 'auto-merged' state. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.mpi.transparent-matching (signal matchTracesToFeatures, violating value false) blocks a match decision that doesn't trace to the defined MATCH_FEATURES spec — an opaque / off-spec / black-box match, an off-catalog feature, a score that doesn't sum from its matched features, or a classification that doesn't follow from the thresholds — backed by the pure guard matchTracesToFeatures (mirroring the Population Health Agent's transparent-risk-model and the Risk Adjustment Agent's evidence-supported-coding posture); policy.mpi.no-autonomous-merge (signal mergeRequiresHumanReview, violating value false) blocks a merge / link below the auto-match threshold performed autonomously (requiresHumanReview:false) — a low-confidence merge must be reviewed by a human steward — backed by the guard mergeRequiresHumanReview (mirroring the Population Health Agent's no-autonomous-care-decision and the Remote Patient Monitoring Agent's no-autonomous-escalation posture); and policy.mpi.no-protected-class-matching (signal excludesProtectedAttributesInMatching, violating value false — a DISTINCT signal key from population-health's excludesProtectedAttributes) blocks a matching feature set that uses a protected-class attribute (race, ethnicity, religion, national origin, gender identity, sexual orientation, disability status, marital status) — a fairness / responsible-AI requirement — backed by the guard excludesProtectedAttributesInMatching. It also reuses, by extending appliesTo, the HIPAA-audit policy (it handles patient identifiers — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/master-patient-index/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — mpi.load-candidates → mpi.score → mpi.resolve → mpi.flag-for-review — with phiAccessed:true, returning the IdentityResolution as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Master Patient Index panel (six presets: a clear match → merge across every feature, an ambiguous possible-match → manual-review requiring human review, a no-match → no-action, plus opaque-match / autonomous-merge / protected-class-feature governance-block presets), a seeded mpi.load-candidates→score→resolve→flag-for-review trace showing a clear match at 100/100 → merge with a possible-match candidate flagged for a human steward (phiAccessed:true, mergeRequiresHumanReview:true), the console subtitle, and the investor brief (now 'forty-eight agents across three planes', with the Master Patient Index agent on the platform substrate paired with Data 360 grounding + Consent & Preferences Management + the MuleSoft ingest process) all reflect it. Frontend tests green (+ master-patient-index feature-catalog/threshold/determinism/clear-match-vs-possible-match-vs-no-match/protected-attributes-ignored/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow + manual-review-is-not-a-block happy paths, the panel's request-body + view-lift, and the registry drift guards raised to forty-eight agents); the match features, weights, thresholds, and patient records are clearly-labeled illustrative synthetics, NOT a certified enterprise master-patient-index (EMPI) algorithm (IBM Initiate, Verato, NextGate, the FHIR $match operation). Lint + build clean.

e55a56e agent fabric: add the Master Patient Index / Identity Resolution agent (deterministic transparent demographic matching with human-review-gated merges + no protected-class attributes, the 48th agent)

Agent Fabric: added the Risk Adjustment & HCC Coding agent — deterministic value-based-care documentation integrity with evidence-supported HCCs, a RAF-style score, clinician-validated recommendations, and never an autonomous code submission (the 47th agent)

Shipped
Details

Added the forty-seventh agent on the fabric — risk-adjustment-agent, the Salesforce 'Agentforce for Health' / Health Cloud risk-adjustment analog. Registered on the care-coordination tier (patient-care plane) as a clinical-documentation-integrity agent for value-based care that COMPLEMENTS, not duplicates, the HEDIS & Quality Reporting and Quality-Measure Attribution agents (those score quality MEASURES; this is risk-adjustment CONDITION coding). It is a DETERMINISTIC, no-Claude agent: in a new pure lib/risk-adjustment.ts, suspectHccs(context) iterates a synthetic HCC_CATALOG and, for each category, reads the documented supporting-evidence signals (from a shared SUPPORTING_EVIDENCE catalog) and classifies as confirmed (a diagnosis code is on the claim AND every catalog evidence signal is documented) / suspected (evidence documented but no code — a coding gap) / unsupported (a code on the claim but the evidence not documented — over-coded); computeRafScore(confirmed) sums the confirmed HCCs' illustrative RAF weights (rounded to three decimals for a stable total); assessRiskAdjustment(context) returns the full RiskAdjustmentAssessment { hccs[], rafScore, codingGaps[], unsupportedFlags[], requiresClinicianValidation:true, submitted:false, synthetic:true, note }. It is a pure function of the clinical context (no randomness, no clock; any dates accepted as data), so the same context always yields the same HCCs + RAF + gaps + flags, with stable catalog ordering. The illustrative catalog spans the chronic-condition neighborhood a midlife / menopause panel carries (diabetes with / without complication, morbid obesity, CKD stage 3, major depression, COPD, CHF) including a menopause-relevant osteoporosis-with-fragility-fracture category; the demo patient surfaces two confirmed HCCs (RAF 0.739) plus a suspected major-depression coding gap, and a second demo context surfaces an over-coded COPD flag. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.riskadj.evidence-supported-coding (signal codesTraceToClinicalEvidence, violating value false) blocks a confirmed / suspected HCC PRESENTED AS supported that does not trace to the documented clinical evidence the catalog defines (an off-catalog HCC, or one whose evidence doesn't cover the required set) — upcoding — while a coding gap and an unsupported / over-coded flag are SAFE, honest OUTPUTS surfaced for a clinician to validate / correct (NOT blocks), backed by the pure guard codesTraceToClinicalEvidence which exempts an honestly-labeled unsupported flag (it makes no support claim) and rejects only a supported-status HCC that doesn't trace to catalog evidence (mirroring the Care Gap Closure Agent's clinical-measure-sourced, the HEDIS Agent's measure-catalog-sourced, and the Clinical Trials Agent's eligibility-criteria-sourced posture); policy.riskadj.clinician-validation-required (signal codingRequiresClinicianValidation, violating value false) blocks a suspected code finalized / submitted without a clinician validating it — every suspected code is a recommendation only — backed by the guard codingRequiresClinicianValidation which passes an assess and a clinician-validated submit and rejects a submit that skips validation; and policy.riskadj.no-autonomous-submission (signal noAutonomousCodeSubmission, violating value false) blocks a caller-asserted autonomous code submission / claim adjustment — the agent is a recommender + integrity checker, so every assessment is submitted:false and a code submission is a human action after clinician validation (mirroring the Prior Authorization Agent's no-autonomous-submission, the HEDIS Agent's no-autonomous-submission, and the Complex Care Management Agent's no-autonomous-billing posture). It also reuses, by extending appliesTo, the HIPAA-audit policy (it reviews patient clinical context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/risk-adjustment/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — riskadj.review-documentation → riskadj.suspect-hccs → riskadj.score → riskadj.flag-for-validation — with phiAccessed:true, returning the RiskAdjustmentAssessment as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Risk Adjustment & HCC Coding panel (four presets: a documented patient → confirmed HCCs + RAF score + a suspected coding gap, plus upcoding / skip-clinician-validation / autonomous-submission governance-block presets), a seeded riskadj.review-documentation→suspect-hccs→score→flag-for-validation trace showing two confirmed HCCs (RAF 0.739) + a suspected coding gap flagged for clinician validation (phiAccessed:true, submitted:false), the console subtitle, and the investor brief (now 'forty-seven agents across three planes', with the Risk Adjustment agent on the patient/clinical plane complementing HEDIS + Quality-Measure Attribution and mirroring Prior Authorization's clinician-approval + no-autonomous-submission posture) all reflect it. Frontend tests green (+ risk-adjustment catalog/determinism/RAF-scoring/coding-gap-vs-over-coded/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow happy paths, the panel's request-body + view-lift, and the registry drift guards raised to forty-seven agents); the HCC catalog, RAF weights, and supporting-evidence catalog are clearly-labeled illustrative synthetics, NOT the certified CMS-HCC model, real RAF coefficients, an ICD-10 → HCC crosswalk, or a certified risk-adjustment / coding engine. Lint + build clean.

c2d3237 agent fabric: add the Risk Adjustment & HCC Coding agent (deterministic value-based-care documentation integrity with evidence-supported HCCs + RAF-style score + clinician-validated recommendations + no autonomous code submission, the 47th agent)

Week of July 19, 2026

The Agent Fabric marches from the 28th to the 46th agent — care, quality, and the first regulated payer & commercial agents

A dense stretch of Agent Fabric build-out: the patient/clinical lifecycle filled in (clinical trials, language access, HEDIS, advance care planning, care-team management, transitions of care, grievance & appeals, provider credentialing, quality attribution, complex care management), then the first regulated payer-side and commercial agents landed — claims adjudication, formulary/DUR, fraud-waste-abuse, utilization review, clinical-trial payments, provider contracting — each deterministic, catalog-sourced, and human-cosign-gated, never an autonomous adverse determination, up through the Data-Sharing / TEFCA interoperability gateway.

Agent Fabric: added the Data-Sharing / TEFCA Interoperability agent — deterministic cross-org PHI exchange with HIPAA §164.506 TPO gate + TEFCA participant verification + consent-scope enforcement (the 46th agent)

Shipped
Details

Added the forty-sixth agent on the fabric — data-sharing-tefca-agent, the Salesforce 'Agentforce for Health' / Health Cloud interoperability analog. Registered on the care-coordination tier as the cross-organization PHI-exchange gateway paired with the Consent & Preferences Management agent (consent scopes), the Provider Credentialing agent (participant registry — same source-integrity discipline), and the Care Coordination Handoff agent (transfer-consent sibling for same-org handoffs). It is a DETERMINISTIC, no-Claude agent: in a new pure lib/data-sharing-tefca.ts, evaluateDataSharingRules(req) applies five catalog rules — rule.tpo-release-authorized (fires release-authorized for HIPAA §164.506 TPO purposes), rule.non-tpo-consented-release (fires release-authorized when a matching consent scope is on file for a non-TPO purpose), rule.non-tpo-consent-missing (fires blocked-consent-required-non-tpo when consent is absent for non-TPO), rule.non-catalog-purpose (fires blocked-non-catalog-purpose for off-catalog purposes), rule.participant-unverified (fires blocked-participant-unverified when the requester is not on the TEFCA / Carequality / CommonWell registry); evaluateDataSharing(req) returns the full DataSharingDecision with primary reason from DS-100/101/200/300/400, isTpo flag pinned from the purpose catalog, and routing to auto-release / privacy-officer-review / consent-capture / participant-registry-verification / blocked-hold. Every non-release decision is requiresPrivacyOfficerCosign:true / cosigned:false — the agent NEVER autonomously releases PHI for a non-TPO purpose without an active consent scope. EXCHANGE_NETWORKS catalog holds four networks (TEFCA QHIN, Carequality, CommonWell, Direct Secure Messaging); EXCHANGE_PURPOSES holds six illustrative purposes (treatment, payment, operations, patient-request, public-health, research), with the first three flagged as isTpo (the HIPAA §164.506 consent-not-required exception). It is a pure function of the request + catalog + caller-provided asOfDate (no randomness, no clock; timestamps and consent scope lists accepted as data), so the same context always yields the same decision + isTpo + primary reason, with a documented decision precedence (blocked-participant-unverified > blocked-non-catalog-purpose > blocked-consent-required-non-tpo > pend-purpose-verification > release-authorized) and stable rule-id ordering. Distinct from the Consent & Preferences Management agent (which owns the consent LEDGER — this agent reads consent scopes) and the Care Coordination Handoff agent (which handles same-org cross-setting transitions — this handles cross-org PHI exchanges over federated networks). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.data-sharing.purpose-catalog-sourced (signal purposesTraceToCatalog, violating value false) blocks a decision citing an off-catalog exchange purpose, network, rule, or reason code — a bespoke exchange purpose doesn't map to a HIPAA disclosure permission and would open the network to unauthorized aggregation (mirroring the Claims Adjudication Agent's edit-catalog-sourced, the FWA Agent's pattern-catalog-sourced, the Trial Payments Agent's schedule-catalog-sourced, the UR Agent's criteria-catalog-sourced, the Handoff Agent's SBAR-completeness, and the Adverse Event Reporting Agent's event-catalog-sourced posture), backed by the pure guard purposesTraceToCatalog which validates the purpose + network + applied rules + reason codes all trace to the catalog; policy.data-sharing.no-autonomous-non-tpo-release (signal releaseHonorsNonTpoConsent, violating value false) blocks a release-authorized decision for a non-TPO purpose without an active consent scope on file for that exact purpose — this is the load-bearing HIPAA §164.506 boundary (TPO = treatment / payment / operations doesn't need consent; everything else does), and unauthorized non-TPO disclosures are the documented breach pattern behind the majority of OCR HIPAA enforcement actions (mirroring the Consent & Preferences Management Agent's no-scope-override, the Grievance & Appeals Agent's no-phi-in-routing-summary, and the Handoff Agent's transfer-consent posture), backed by the guard releaseHonorsNonTpoConsent which treats decision:'blocked-consent-required-non-tpo' as the safe path, trivially passes on non-release decisions (no PHI leaves), exempts TPO purposes (isTpo:true), and rejects only lies that claim release-authorized for a non-TPO purpose without a matching consent scope; and policy.data-sharing.participant-verified (signal participantIdentityVerified, violating value false) blocks a release-authorized decision to an unverified requester — under 45 CFR 171 + the TEFCA Common Agreement a QHIN / participant / sub-participant must be identity-attested before a cross-org exchange is authorized (mirroring the Provider Credentialing Agent's source-integrity, the Adverse Event Reporting Agent's reporter-verified, and the Handoff Agent's receiving-clinician-credentialed posture), backed by the guard participantIdentityVerified which treats decision:'blocked-participant-unverified' as the safe path and rejects only lies that claim a release-authorized despite an unverified requester. It also reuses, by extending appliesTo, the HIPAA-audit policy (it handles cross-org PHI exchanges — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/data-sharing-tefca/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — data-sharing-tefca.evaluate-rules → data-sharing-tefca.decide — with phiAccessed:true, returning the DataSharingDecision as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Data-Sharing / TEFCA panel (eight presets: TPO treatment release over TEFCA QHIN, non-TPO research release over Carequality with consent, blocked non-TPO research without consent, blocked unverified requester on TPO treatment, patient right-of-access release over Direct Secure Messaging, plus off-catalog-purpose / non-TPO-release-lie / unverified-participant-lie governance-block presets), a seeded data-sharing-tefca.evaluate-rules→data-sharing-tefca.decide trace showing a TPO treatment release-authorized over TEFCA (isTpo:true, phiAccessed:true), the console subtitle, and the investor brief (now 'forty-six agents across three planes', with the Data-Sharing / TEFCA agent on the patient/clinical plane paired with Consent + Provider Credentialing + Care Coordination Handoff) all reflect it. Frontend tests green (+ data-sharing-tefca catalog/determinism/rule-precedence/TPO-vs-non-TPO-branching/consent-scope-matching/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow happy paths across all five decision tiers, the panel's request-body + view-lift, and the registry drift guards raised to forty-six agents); the exchange-network catalog, exchange-purpose catalog, rules, and reason codes are clearly-labeled illustrative synthetics, NOT an actual TEFCA QHIN implementation, the Carequality Interoperability Framework, the CommonWell Health Alliance node stack, or a certified ONC data-sharing gateway. Lint + build clean.

cc57969 agent fabric: add the Data-Sharing / TEFCA Interoperability agent (deterministic cross-org PHI exchange with HIPAA §164.506 TPO gate + TEFCA participant verification + consent-scope enforcement, the 46th agent)

Agent Fabric: added the Adverse Event Reporting agent (FDA MedWatch / VAERS analog) — deterministic pharmacovigilance classification with regulatory-team-cosign-gated FDA submissions + reporter-identity verification (the 45th agent)

Shipped
Details

Added the forty-fifth agent on the fabric — adverse-event-reporting-agent, the Salesforce 'Agentforce for Health' / Health Cloud pharmacovigilance / device-safety-reporting analog. Registered on the care-coordination tier as the FDA-channel drafting engine that pairs with the Medication Adherence agent (nudge-only refill), the Formulary & DUR agent (drug utilization review), and the Clinical Trials Matching + Trial Payments agents (research pharmacovigilance signal). It is a DETERMINISTIC, no-Claude agent: in a new pure lib/adverse-event-reporting.ts, evaluateAdverseEventRules(req) applies four catalog rules — rule.medwatch-eligible (fires draft-medwatch for drug ADRs / device malfunctions / medication errors / therapeutic failures), rule.vaers-eligible (fires draft-vaers for vaccine reactions), rule.non-catalog-event (fires blocked-non-catalog-event for off-catalog events), rule.reporter-unverified (fires blocked-reporter-unverified when the reporter identity is not attested); computeSeriousnessTier(input) classifies the 21-CFR-314.80 seriousness tier from caller-provided outcome flags (resultedInDeath > isLifeThreatening > requiredHospitalization / causedDisability / causedBirthDefect / medicallyImportant → serious → non-serious) with strict precedence; evaluateAdverseEvent(req) returns the full AdverseEventDecision with primary reason from AE-100/101/300/400, seriousness tier, and routing to regulatory-team-medwatch-queue / regulatory-team-vaers-queue / blocked-hold. Every draft-medwatch or draft-vaers decision is requiresRegulatoryTeamCosign:true / cosigned:false — the agent NEVER autonomously files to the FDA. ADVERSE_EVENT_TYPES catalog holds five event types (drug-adr, vaccine-reaction, device-malfunction, medication-error, therapeutic-failure), each pinned to its target FDA channel (MedWatch vs VAERS); SERIOUSNESS_TIERS holds four illustrative tiers (non-serious, serious, life-threatening, death) aligned with 21 CFR 314.80 criteria; illustrative ReporterType covers clinician / patient / consumer / manufacturer / other-health-professional. It is a pure function of the request + catalog + caller-provided asOfDate (no randomness, no clock; timestamps and outcome flags accepted as data), so the same context always yields the same decision + channel + seriousness + primary reason, with a documented decision precedence (blocked-reporter-unverified > blocked-non-catalog-event > draft-medwatch / draft-vaers) and stable rule-id ordering. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.adverse-event.event-catalog-sourced (signal eventsTraceToCatalog, violating value false) blocks a decision citing an off-catalog event type, seriousness tier, rule, or reason code — a bespoke event doesn't map to an FDA channel and poisons the pharmacovigilance signal (mirroring the Claims Adjudication Agent's edit-catalog-sourced, the FWA Agent's pattern-catalog-sourced, the Trial Payments Agent's schedule-catalog-sourced, the UR Agent's criteria-catalog-sourced, and the Handoff Agent's SBAR-completeness posture), backed by the pure guard eventsTraceToCatalog which validates the event + seriousness + applied rules + reason codes all trace to the catalog; policy.adverse-event.no-autonomous-submission (signal submissionRequiresRegulatoryTeamCosign, violating value false) blocks an autonomously-cosigned FDA submission — MedWatch (3500 / 3500A) and VAERS submissions are legally consequential under 21 CFR 314.80 (mandatory reporting) with sponsor / manufacturer / clinician liability (mirroring the Claims Adjudication Agent's no-autonomous-denial, the UR Agent's no-autonomous-denial, the Formulary Agent's no-autonomous-override, the FWA Agent's no-autonomous-denial, the Trial Payments Agent's no-autonomous-irb-deviation, and the HEDIS Agent's no-autonomous-submission posture), backed by the guard submissionRequiresRegulatoryTeamCosign which trivially passes on blocked decisions and enforces requiresRegulatoryTeamCosign:true / cosigned:false on every draft; and policy.adverse-event.reporter-verified (signal reporterIdentityVerified, violating value false) blocks a draft with an unattested reporter identity — an anonymous or unverified reporter is not admissible under FDA reporting requirements and poisons the surveillance signal, backed by the guard reporterIdentityVerified which treats decision:'blocked-reporter-unverified' as the safe path and rejects only lies that claim a draft despite unverified reporter. It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches patient / reporter context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/adverse-event-reporting/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — adverse-event-reporting.evaluate-rules → adverse-event-reporting.decide — with phiAccessed:true, returning the AdverseEventDecision as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Adverse Event Reporting panel (eight presets: MedWatch draft for a serious hospitalized drug ADR (fezolinetant), VAERS draft for a vaccine reaction (seasonal flu), MedWatch draft for a life-threatening estradiol reaction, MedWatch draft for a non-serious voluntary paroxetine report, blocked-unverified-reporter for an anonymous consumer report, plus off-catalog-event / autonomous-cosign / unverified-reporter-lie governance-block presets), a seeded adverse-event-reporting.evaluate-rules→adverse-event-reporting.decide trace showing a MedWatch draft for a serious drug ADR routed to the regulatory-team queue, the console subtitle, and the investor brief (now 'forty-five agents across three planes', with the Adverse Event Reporting agent on the patient/clinical plane paired with Medication Adherence + Formulary & DUR + Clinical Trials Matching + Trial Payments) all reflect it. Frontend tests green (+ adverse-event-reporting catalog/determinism/seriousness-precedence/channel-selection/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow happy paths across all four decision tiers, the panel's request-body + view-lift, and the registry drift guards raised to forty-five agents); the event-type catalog, seriousness tiers, rules, and reason codes are clearly-labeled illustrative synthetics, NOT FDA MedWatch, VAERS, EudraVigilance, an actual sponsor's pharmacovigilance database, or a certified 21 CFR 314.80 submission pipeline. Lint + build clean.

97a9bb0 agent fabric: add the Adverse Event Reporting agent (deterministic FDA MedWatch / VAERS classification with regulatory-team-cosign-gated FDA submissions + reporter-identity verification, the 45th agent)

Agent Fabric: added the Care Coordination Handoff agent (cross-setting) — deterministic Joint-Commission-NPSG-2 SBAR with receiving-clinician credentialing + transfer-consent gates (the 44th agent)

Shipped
Details

Added the forty-fourth agent on the fabric — care-coordination-handoff-agent, the Salesforce 'Agentforce for Health' / Health Cloud cross-setting care-coordination analog. Registered on the care-coordination tier as the GENERAL cross-setting handoff engine that pairs with the Provider Credentialing agent (network gate on the receiving clinician), the Consent & Preferences Management agent (transfer-consent scope), and the Transitions of Care agent (post-discharge hospital→home + med reconciliation, the sibling — this is the general case). It is a DETERMINISTIC, no-Claude agent: in a new pure lib/care-coordination-handoff.ts, evaluateHandoffRules(req) applies four catalog rules — rule.sbar-complete (fires handoff-accepted when all four SBAR sections populated + no other rules fire), rule.sbar-incomplete (pend-sbar-incomplete when any of situation/background/assessment/recommendation missing), rule.clinician-not-credentialed (blocked-clinician-not-credentialed when receiving credentialing is expired/incomplete/sanctioned), rule.transfer-consent-missing (blocked-no-consent when the transition requires consent and none is on file); evaluateHandoff(req) classifies as handoff-accepted / pend-sbar-incomplete / blocked-clinician-not-credentialed / blocked-no-consent with primary reason from HO-100/200/300/400, computes missingSbarSections from the caller's structured SBAR (SBAR is structured labels — NOT free-text PHI), and routes to receiving-clinician-inbox / sending-clinician-completion / credentialing-remediation / consent-capture. Every accepted handoff is requiresReceivingClinicianCosign:true / cosigned:false — the agent NEVER autonomously accepts on behalf of the receiving clinician. CARE_SETTINGS catalog holds eight settings (hospital inpatient, ED, SNF, home health, hospice, PCP clinic, specialist clinic, behavioral health clinic); TRANSITION_TYPES catalog holds six illustrative transitions (hospital→SNF, SNF→home, home→hospice, ED→PCP, PCP→specialist, PCP→behavioral-health), each flagged for whether it typically requires documented transfer consent (all cross-facility PHI-sharing transitions do; intra-system ED→PCP and PCP→specialist do not). It is a pure function of the request + catalog + caller-provided asOfDate (no randomness, no clock; SBAR fields and consent flags accepted as data), so the same context always yields the same decision + missing-sections list + primary reason, with a documented decision precedence (blocked-no-consent > blocked-clinician-not-credentialed > pend-sbar-incomplete > handoff-accepted) and stable rule-id ordering. Distinct from the Discharge & Transitions of Care agent (which is POST-DISCHARGE hospital→home only, and owns the medication reconciliation — this agent is any cross-setting handoff, no med reconciliation) and the Referral Management agent (which drafts an outbound specialist referral to be sent by a clinician — this agent is the SBAR handoff on an in-progress transition). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.handoff.sbar-completeness (signal sbarIsComplete, violating value false) blocks a handoff-accepted claim that admits any missing SBAR section — the Joint Commission National Patient Safety Goal 2 requires standardized handoff communication (situation, background, assessment, recommendation), and incomplete SBAR is a well-documented patient-safety failure — backed by the pure guard sbarIsComplete which treats decision:'pend-sbar-incomplete' as the safe path (agent surfaced the gap) and rejects only lies that claim acceptance despite missing sections; policy.handoff.receiving-clinician-credentialed (signal receivingClinicianIsCredentialed, violating value false) blocks a handoff-accepted claim to a receiving clinician whose credentialing status is expired / incomplete / sanctioned — this is a ghost-network variant and a Section 1557 / due-process failure (mirroring the Provider Credentialing Agent's no-referral-to-expired-or-sanctioned posture), backed by the guard receivingClinicianIsCredentialed which treats decision:'blocked-clinician-not-credentialed' as the safe path and enforces current-unsanctioned status on every acceptance; and policy.handoff.consent-on-file (signal handoffHasConsent, violating value false) blocks a handoff-accepted claim without transfer consent on a transition type that requires it (hospital→SNF, SNF→home, home→hospice, PCP→behavioral-health) — sharing PHI with a new setting without patient consent is a HIPAA disclosure failure (mirroring the Consent & Preferences Management Agent's consent-scope posture), backed by the guard handoffHasConsent which treats decision:'blocked-no-consent' as the safe path, exempts transitions that don't require consent (ED→PCP, PCP→specialist), and rejects only lies that claim acceptance without documented consent. It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches patient / receiving-clinician context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/care-coordination-handoff/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — care-coordination-handoff.evaluate-rules → care-coordination-handoff.decide — with phiAccessed:true, returning the HandoffDecision as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Care Coordination Handoff panel (eight presets: handoff-accepted hospital→SNF SBAR-complete happy path, pend-sbar-incomplete SNF→home missing assessment+recommendation, blocked-uncredentialed ED→PCP with expired credentialing, blocked-no-consent home→hospice without transfer consent, handoff-accepted ED→PCP without consent (not required), plus SBAR-lie / uncredentialed-lie / no-consent-lie governance-block presets), a seeded care-coordination-handoff.evaluate-rules→care-coordination-handoff.decide trace showing an accepted hospital→SNF handoff routed to receiving-clinician-inbox, the console subtitle, and the investor brief (now 'forty-four agents across three planes', with the Care Coordination Handoff agent on the patient/clinical plane paired with Provider Credentialing + Consent + Transitions of Care) all reflect it. Frontend tests green (+ care-coordination-handoff catalog/determinism/rule-precedence/missing-SBAR-detection/consent-not-required-transitions/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow happy paths across all four decision tiers, the panel's request-body + view-lift, and the registry drift guards raised to forty-four agents); the care-setting catalog, transition-type catalog, SBAR rule set, and reason codes are clearly-labeled illustrative synthetics, NOT Epic Care Everywhere, Cerner CareAware, an actual health system's handoff protocol, or a certified Joint Commission / ONC-approved handoff module. Lint + build clean.

50290ac agent fabric: add the Care Coordination Handoff agent (deterministic cross-setting Joint-Commission-NPSG-2 SBAR with receiving-clinician credentialing + transfer-consent gates, the 44th agent)

Agent Fabric: added the Provider Contracting & VBC Terms agent — deterministic commercial-plane contract classification with account-owner-cosign-gated term changes + catalog-sourced VBC benchmarks (the 43rd agent)

Shipped
Details

Added the forty-third agent on the fabric — provider-contracting-agent, the Salesforce 'Agentforce for Health' / Health Cloud provider-contracting analog. Registered on the commercial-operations tier as the CONTRACT-SIDE engine paired with the Pipeline Management and Account Management agents (and the Quality-Measure Attribution + HEDIS agents on the clinical plane, which read the resulting contract terms). It is a DETERMINISTIC, no-Claude agent: in a new pure lib/provider-contracting.ts, evaluateContractingRules(req) applies five catalog rules — rule.quality-and-spend-in-band (in-good-standing), rule.quality-gate-missed (benchmark-drift review), rule.spend-drift-exceeded (benchmark-drift review), rule.term-change-requested (draft-term-change), rule.non-catalog-contract (blocked-non-catalog-contract); evaluateContract(req) classifies as in-good-standing / benchmark-drift-review / draft-term-change / blocked-non-catalog-contract with primary reason from PC-100/200/201/300/400, computes the spend drift (actual − benchmark) / benchmark against the methodology's tolerance, and routes to auto-continue / account-manager-drift-review / account-owner-cosign / blocked-hold. Every draft-term-change decision is requiresAccountOwnerCosign:true / cosigned:false — the agent NEVER autonomously commits a contract-term change. CONTRACT_TYPES holds six payment models (fee-for-service, capitation, shared-savings, bundled-payment, MA-value-based, commercial-VBC), each flagged for whether it has a VBC quality-gate + spend-benchmark shape; BENCHMARK_METHODOLOGIES holds four illustrative methodologies (Medicare MSSP MY2026 with 0.7 quality gate + 5% spend tolerance, MA Star VBC MY2026 with 0.75 gate + 3% tolerance, Commercial VBC MY2026 with 0.65 gate + 5% tolerance, Bundled-episode flat-benchmark with 0.6 gate + 10% tolerance) — each drives the quality-gate threshold + spend-drift tolerance for its contracts. It is a pure function of the request + catalog + caller-provided reporting-period (no randomness, no clock), so the same context always yields the same decision + drift + reason code, with a documented decision precedence (blocked-non-catalog-contract > draft-term-change > benchmark-drift-review > in-good-standing) and stable rule-id ordering. Distinct from the Quality-Measure Attribution agent (which decides whose panel a patient counts on) and the HEDIS agent (which scores measures against a contract's methodology) — this one handles the CONTRACT ITSELF. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.contracting.contract-type-catalog-sourced (signal contractsTraceToCatalog, violating value false) blocks a decision citing an off-catalog contract type, methodology, rule, or reason code (mirroring the Claims Adjudication Agent's edit-catalog-sourced, the Formulary Agent's catalog-sourced, the FWA Agent's pattern-catalog-sourced, the Trial Payments Agent's schedule-catalog-sourced, and the UR Agent's criteria-catalog-sourced posture), backed by the pure guard contractsTraceToCatalog which validates the contract type + methodology + applied rules + reason codes all trace to the catalog; policy.contracting.no-autonomous-term-change (signal contractChangeRequiresOwnerCosign, violating value false) blocks an autonomously-cosigned term change — contract-term changes are legally consequential under state insurance code, provider-contract law, and CMS Medicare Advantage (mirroring the Claims Adjudication Agent's no-autonomous-denial, the UR Agent's no-autonomous-denial, the Formulary Agent's no-autonomous-override, the FWA Agent's no-autonomous-denial, the Trial Payments Agent's no-autonomous-irb-deviation, and the Account Management Agent's human-owner-before-contract-change posture), backed by the guard contractChangeRequiresOwnerCosign which trivially passes on non-term-change decisions and enforces requiresAccountOwnerCosign:true / cosigned:false on every draft-term-change; and policy.contracting.benchmark-methodology-catalog-sourced (signal benchmarksTraceToMethodology, violating value false) blocks a bespoke / opaque / 'we-picked-a-number' benchmark that doesn't derive from the methodology catalog — an opaque benchmark polluts every downstream shared-savings / bonus / clawback calculation, mirroring the Quality-Measure Attribution Agent's methodology-catalog-sourced posture, backed by the guard benchmarksTraceToMethodology which recomputes the expected quality-gate threshold + spend-drift tolerance from the methodology catalog and rejects any mismatch. Because it operates on business-side contract terms rather than patient PHI, this agent is on the commercial-operations plane and shares the commercial-plane policy.commercial.no-phi-in-commercial-plane (with its appliesTo extended to include the new agent); it is NOT on the HIPAA-audit policy (it never touches PHI), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/provider-contracting/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — provider-contracting.evaluate-rules → provider-contracting.decide — with phiAccessed:false (commercial plane), returning the ProviderContractDecision as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Provider Contracting panel (eight presets: in-good-standing MA VBC quality+spend-in-band, quality-gate-missed MSSP shared-savings, spend-drift-exceeded commercial VBC, term-change-drafted MA VBC quality-gate lower proposal, non-VBC FFS good-standing, plus off-catalog-contract / autonomous-cosign / opaque-benchmark governance-block presets), a seeded provider-contracting.evaluate-rules→provider-contracting.decide trace showing a benchmark-drift review for a shared-savings quality miss on the commercial plane (phiAccessed:false), the console subtitle, and the investor brief (now 'forty-three agents across three planes', with the Provider Contracting agent on the commercial plane paired with Pipeline + Account Management) all reflect it. Frontend tests green (+ provider-contracting catalog/determinism/rule-precedence/spend-drift-computation/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow happy paths across all four decision tiers, the panel's request-body + view-lift, and the registry drift guards raised to forty-three agents); the contract-type catalog, methodology catalog, rules, and reason codes are clearly-labeled illustrative synthetics, NOT Salesforce Health Cloud Provider Network Management, Optum Contract Manager, or a real payer's contract-lifecycle system. Lint + build clean.

7aee30f agent fabric: add the Provider Contracting & VBC Terms agent (deterministic commercial-plane contract classification with account-owner-cosign-gated term changes + catalog-sourced VBC benchmarks, the 43rd agent)

Agent Fabric: added the Utilization Review agent (MCG/InterQual analog) — deterministic pre-service medical-necessity screen with clinician-cosign-gated denials + catalog-sourced SLA deadlines (the 42nd agent)

Shipped
Details

Added the forty-second agent on the fabric — utilization-review-agent, the Salesforce 'Agentforce for Health' / Health Cloud utilization-management analog. Registered on the care-coordination tier as the PRE-SERVICE medical-necessity engine paired with the Prior Authorization agent (assembly), the Claims Adjudication Assistant (post-service edits), and the Grievance & Appeals agent (post-denial intake). It is a DETERMINISTIC, no-Claude agent: in a new pure lib/utilization-review.ts, evaluateUrRules(req) evaluates catalog criteria evidence against the service-type's criteria set and applies five catalog rules — rule.all-required-met (clean-approve), rule.missing-required-criterion (pend for clinical review), rule.partial-criteria-p2p (escalate to peer-to-peer when provider requests it), rule.non-covered-service (blocked at first pass), rule.sla-window-required (every non-approved case carries a catalog SLA); reviewUtilization(req) classifies as approves-meets-criteria / pend-for-clinical-review / require-peer-to-peer / blocked-non-covered with primary reason from UR-100/200/201/300, computes the SLA deadline from catalog urgency window + received asOfDate (standard 72h, urgent 24h, concurrent-review 24h), and routes to auto-approve / clinical-reviewer-queue / peer-to-peer-scheduling / blocked-non-covered-appeal. Every non-approved decision is requiresClinicianCosign:true / cosigned:false — the agent NEVER autonomously denies. The illustrative service-type catalog holds five menopause-relevant services: DEXA bone-density (age gate + interval + symptom documentation), hysterectomy for abnormal uterine bleeding (bleed pattern + first-line failure + malignancy workup), inpatient medical admission (severity-of-illness + intensity-of-service + observation-insufficient), sleep-study for OSA workup (symptoms + home-test-inappropriate), and an illustrative cosmetic non-covered example. It is a pure function of the request + criteria evidence + urgency + catalog + caller-provided asOfDate (no randomness, no clock; timestamps and evidence flags accepted as data), so the same context always yields the same decision + met/missing criteria lists + primary reason + SLA deadline, with a documented decision precedence (blocked-non-covered > require-peer-to-peer > pend-for-clinical-review > approves-meets-criteria) and stable rule-id ordering. Distinct from the Prior Authorization Agent (which ASSEMBLES a clinician-gated PA submission for a specific payer), the Claims Adjudication Assistant (which decides POST-SERVICE clean-pay vs deny with mechanical NCCI-style edits), and the Grievance & Appeals Agent (POST-DENIAL intake) — this is the first-pass PRE-SERVICE medical-necessity engine. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.ur.criteria-catalog-sourced (signal criteriaTraceToCatalog, violating value false) blocks a decision citing an off-catalog service, an off-catalog criterion, an off-catalog rule, or an off-catalog reason code (mirroring the Claims Adjudication Agent's edit-catalog-sourced, the Formulary Agent's catalog-sourced, the FWA Agent's pattern-catalog-sourced, and the Trial Payments Agent's schedule-catalog-sourced posture), backed by the pure guard criteriaTraceToCatalog which validates the service + criteria met/missing lists + applied rules + reason codes all trace to the catalog; policy.ur.no-autonomous-denial (signal denialRequiresClinicianCosign, violating value false) blocks an autonomously-cosigned non-approved decision — UR denials are legally consequential under Medicare Advantage / state utilization-review-agent codes with notice + due-process rights, and denying medical necessity on the agent's own authority is a Section 1557 / state-code violation (mirroring the Claims Adjudication Agent's no-autonomous-denial, the Formulary Agent's no-autonomous-override, the FWA Agent's no-autonomous-denial, and the Trial Payments Agent's no-autonomous-irb-deviation posture), backed by the guard denialRequiresClinicianCosign which trivially passes on approved decisions and enforces requiresClinicianCosign:true / cosigned:false on every non-approved decision; and policy.ur.sla-integrity (signal slaTracesToCatalog, violating value false) blocks a case deadline that doesn't match the catalog urgency window applied against the received asOfDate OR one that's been silently extended past the regulatory maximum — silently extending a UR deadline breaches Medicare Advantage Chapter 4 / state UR-agent timelines (mirroring the Grievance & Appeals Agent's deadline-integrity posture), backed by the guard slaTracesToCatalog which recomputes the expected deadline from urgency + asOfDate and rejects any mismatch. It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches member context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/utilization-review/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — utilization-review.evaluate-criteria → utilization-review.decide — with phiAccessed:true, returning the UtilizationReviewDecision as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Utilization Review panel (eight presets: approves-meets-criteria DEXA all-required-met, pend-for-clinical-review hysterectomy missing first-line, require-peer-to-peer inpatient with provider-requested P2P, urgent-pend sleep-study with 24h SLA, blocked-non-covered cosmetic case, plus off-catalog-service / autonomous-cosign / silently-extended-SLA governance-block presets), a seeded utilization-review.evaluate-criteria→utilization-review.decide trace showing a pend-for-clinical-review for a hysterectomy with a 72h standard SLA, the console subtitle, and the investor brief (now 'forty-two agents across three planes', with the Utilization Review agent on the patient/clinical plane paired with PA + Claims Adjudication + Grievance & Appeals) all reflect it. Frontend tests green (+ utilization-review catalog/determinism/rule-precedence/SLA-deadline-computation/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow happy paths across all four decision tiers, the panel's request-body + view-lift, and the registry drift guards raised to forty-two agents); the service-type catalog, criteria sets, rules, reason codes, and SLA windows are clearly-labeled illustrative synthetics, NOT MCG (Milliman Care Guidelines / Indicia), InterQual, an actual payer's UR rule set, or a certified medical-necessity engine. Lint + build clean.

bbf1a89 agent fabric: add the Utilization Review agent (deterministic pre-service medical-necessity screen with clinician-cosign-gated denials + catalog-sourced SLA deadlines, the 42nd agent)

Agent Fabric: added the Clinical Trial Payments & Stipends agent — deterministic IRB-schedule payment engine with study-coordinator cosign + participant-consent gate (the 41st agent)

Shipped
Details

Added the forty-first agent on the fabric — trial-payments-agent, the Salesforce 'Agentforce for Health' / Health Cloud clinical-trial payments analog. Registered on the care-coordination tier as the payments-side counterpart to the Clinical Trials Matching agent (which selects candidates). It is a DETERMINISTIC, no-Claude agent: in a new pure lib/trial-payments.ts, evaluateTrialPaymentRules(req) applies five catalog rules — rule.standard-visit-completed (schedule stipend applies), rule.missed-visit-partial-comp (pend for coord review), rule.travel-out-of-range (pend when miles exceed IRB max), rule.extra-procedure-comp (pend when extra procedure requested), rule.consent-missing (blocked when no research-payment consent); evaluatePayment(req) classifies as schedule-approved / pend-coordinator-review / blocked-no-consent with primary reason from FORMULARY-style TP-100/200/201/202/300 codes, computes the stipend + travel reimbursement (per-mile rate capped at maxReimbursableMiles), and routes to schedule-auto-pay / study-coordinator-review / blocked-hold. Every non-schedule-approved decision is requiresCoordinatorCosign:true / cosigned:false — the agent NEVER autonomously deviates from an IRB-approved schedule. The illustrative schedule catalog holds three menopause trials: menopause vasomotor fezolinetant Phase 3, menopause HRT transdermal Phase 4 observational (with a follow-up stipend override), and menopause bone-density Phase 3 — each with an IRB approval ref, travel rate, and max reimbursable miles. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.trial-payments.schedule-catalog-sourced (signal paymentsTraceToCatalog, violating value false) blocks a payment citing an off-catalog trial, visit type, or rule (mirroring the Claims Adjudication Agent's edit-catalog-sourced, the Formulary Agent's catalog-sourced, and the FWA Agent's pattern-catalog-sourced posture), backed by the pure guard paymentsTraceToCatalog; policy.trial-payments.no-autonomous-irb-deviation (signal deviationRequiresCoordinatorCosign, violating value false) blocks an autonomously-cosigned deviation — IRB deviations require study-coordinator human review because autonomous deviations could invalidate the study (mirroring the Claims Adjudication Agent's no-autonomous-denial, the Formulary Agent's no-autonomous-override, and the FWA Agent's no-autonomous-denial posture), backed by the guard deviationRequiresCoordinatorCosign; and policy.trial-payments.participant-consented (signal paymentHasParticipantConsent, violating value false) blocks a payment to a non-consented participant — Common Rule / 45 CFR 46 requires informed consent for research payments — with the safe answer of decision:'blocked-no-consent' with zero payment, backed by the guard paymentHasParticipantConsent which validates consent OR the safe-blocked state. It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches participant context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/trial-payments/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — trial-payments.evaluate-rules → trial-payments.decide — with phiAccessed:true, returning the TrialPaymentDecision as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Trial Payments panel (eight presets: schedule-approved standard visit ($150 stipend + $8.40 travel), missed-visit pend, travel-out-of-range pend, extra-procedure pend, blocked-no-consent case, plus off-catalog-trial / autonomous-cosign / no-consent-lied-about governance-block presets), a seeded trial-payments.evaluate-rules→trial-payments.decide trace showing a $150 + $8.40 auto-pay, the console subtitle, and the investor brief (now 'forty-one agents across three planes', with the Trial Payments agent on the patient/clinical plane paired with Clinical Trials Matching) all reflect it. Frontend tests green (+ trial-payments catalog/determinism/rule-precedence/stipend-computation/travel-capping/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow happy paths across all decision tiers, the panel's request-body + view-lift, and the registry drift guards raised to forty-one agents); the trial catalog, IRB payment schedules, visit types, rules, and travel rate are clearly-labeled illustrative synthetics, NOT IRBNet, WCG IRB, Advarra IRB, or an actual sponsor's payment protocol. Lint + build clean.

20a600a agent fabric: add the Clinical Trial Payments & Stipends agent (deterministic IRB-schedule payment engine with study-coordinator cosign + participant-consent gate, the 41st agent)

Agent Fabric: added the Fraud, Waste & Abuse Detection agent — deterministic pattern-based SIU screening with no autonomous denials + no protected-class factors (the 40th agent)

Shipped
Details

Added the fortieth agent on the fabric — fwa-detection-agent, the Salesforce 'Agentforce for Health' / Health Cloud FWA analog. Registered on the care-coordination tier as the payer-side pattern-based screener paired with the Claims Adjudication Assistant (mechanical edits) and Prior Authorization (pre-service). It is a DETERMINISTIC, no-Claude agent: in a new pure lib/fwa-detection.ts, evaluateFwaPatterns(req) applies six pattern rules — pattern.unbundling (repeated-unbundling history), pattern.upcoding (E/M level > peer median+1), pattern.duplicate-billing (same DOS + CPT in prior submissions), pattern.quantity-outlier (units-per-member > 3× peer baseline), pattern.impossible-day-billing (total daily service minutes > 1440), pattern.phantom-service (no matching EHR encounter); screenClaim(req) classifies as clear or flag-for-siu-review with a primary pattern chosen by severity precedence (high > medium > low, lexical tie-break by pattern-id), routes to clear-no-action / siu-standard-queue / siu-priority-queue, and hardcodes investigationOpened:false / paymentFrozen:false on every report — the agent NEVER autonomously acts on suspicion. PROTECTED_CLASS_ATTRIBUTES catalog (race, ethnicity, religion, national origin, disability, gender identity, sexual orientation, marital status + provider-demographic proxies) is checked against the factor list to enforce the load-bearing fairness guard; DEFAULT_FWA_FACTORS is the pattern-id list + non-protected peer-baseline metrics. It is a pure function of the claim + baseline + catalog + caller-provided asOfDate (no randomness, no clock), so the same context always yields the same flags + primary + severity + routing. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.fwa.pattern-catalog-sourced (signal patternsTraceToCatalog, violating value false) blocks a fabricated / off-catalog flag or category-of-one 'we-just-don't-like-this-provider' pattern (mirroring the Claims Adjudication Agent's edit-catalog-sourced, the Formulary Agent's catalog-sourced, the ACP Agent's directive-source-integrity, and the CCM Agent's eligibility-catalog-sourced posture), backed by the pure guard patternsTraceToCatalog; policy.fwa.no-autonomous-denial (signal reportRequiresSiuReview, violating value false) blocks an autonomous investigation opening or payment freeze — suspected fraud requires SIU human review because denying on unproven suspicion is a Section 1557 / state code / due-process failure (mirroring the Claims Adjudication Agent's no-autonomous-denial, the PA Agent's no-autonomous-submission, and the CCM Agent's no-autonomous-billing posture), backed by the guard reportRequiresSiuReview which validates the requiresSiuReview flag matches the decision AND investigationOpened + paymentFrozen are both false; and policy.fwa.no-protected-class-factors (signal noProtectedClassFactors, violating value false) blocks a factor list that includes any protected-class attribute or provider-demographic proxy — bias in FWA is a well-documented compliance failure (algorithmic-audit reports of payer systems that disproportionately targeted minority-owned clinics led to consent decrees), mirroring the Population Health Agent's no-protected-class-factors posture, backed by the guard noProtectedClassFactors. It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches patient / member context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/fwa-detection/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — fwa.evaluate-patterns → fwa.decide — with phiAccessed:true, returning the FwaScreeningReport as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new FWA Detection panel (eight presets: clear happy path, upcoding-medium routed to SIU standard queue, impossible-day-high routed to SIU priority queue, phantom-service-high, multi-flag with precedence example (duplicate-billing high wins), plus off-catalog-pattern / autonomous-investigation / protected-class-factor governance-block presets — rendering the classified decision + primary pattern + severity + routing + applied patterns + hard invariants, synthetic labels, and a trace deep link), and a seeded fwa.evaluate-patterns→fwa.decide trace showing an impossible-day flag routed to SIU priority queue, the console subtitle, and the investor brief (now 'forty agents across three planes', with the FWA Detection agent on the patient/clinical plane paired with Claims Adjudication + Prior Auth) all reflect it. Frontend tests green (+ fwa-detection catalog/determinism/severity-precedence/multi-flag-ordering/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow happy paths across clear/upcoding/impossible-day/phantom/multi, the panel's request-body + view-lift, and the registry drift guards raised to forty agents); the pattern catalog, peer baselines, severity thresholds, and detection windows are clearly-labeled illustrative synthetics, NOT SAS Detection and Investigation, LexisNexis Provider Insight, an actual payer SIU rule set, or a certified fraud-detection engine. Lint + build clean.

3533e5a agent fabric: add the Fraud, Waste & Abuse Detection agent (deterministic pattern-based SIU screening with no autonomous denials + no protected-class factors, the 40th agent)

Agent Fabric: added the Formulary & Drug Utilization Review agent — deterministic first-pass DUR: tier + step-therapy + quantity + interactions + clinician-cosign-gated formulary exceptions (the 39th agent)

Shipped
Details

Added the thirty-ninth agent on the fabric — formulary-review-agent, the Salesforce 'Agentforce for Health' / Health Cloud formulary + drug-utilization-review analog. Registered on the care-coordination tier as the first-pass DUR piece paired with the Prior Authorization agent (broader UM), the Medication Adherence agent (nudge-only refill), and the Claims Adjudication Assistant (post-service). It is a DETERMINISTIC, no-Claude agent: in a new pure lib/formulary-review.ts, evaluateFormularyRules(req) applies four catalog rules against a proposed drug — rule.step-therapy-required (verifies a documented prior-therapy trial from STEP_THERAPY_CHAINS, ignoring self-reported / undocumented history), rule.quantity-limit-exceeded (compares requested quantity vs. plan quantity limit), rule.drug-drug-interaction (matches against INTERACTION_PAIRS on the member's current-medication list), and rule.non-formulary (fires when the drug's tier is non-formulary); reviewFormularyRequest(req) classifies each request as preferred-approved / pend-step-therapy / pend-quantity-limit / pend-interaction-review / pend-non-formulary with a specific reason code from FORMULARY_REASON_CODE_CATALOG (PF-100 preferred / PF-200 step / PF-201 quantity / PF-202 interaction / PF-203 non-formulary), routes pends to a clinician (or pharmacist for interactions), and sets requiresClinicianCosign:true / cosigned:false on every non-preferred decision — the agent NEVER autonomously overrides a formulary exception. Menopause-relevant: FORMULARY_DRUG_CATALOG includes estradiol (oral, patch, vaginal cream), progesterone, paroxetine (Brisdelle), venlafaxine, fezolinetant (Veozah), alendronate, zolpidem, warfarin — with tier placements that model the SHAPE of a real payer's formulary (transdermal estradiol Tier 2, fezolinetant non-formulary, etc.). It is a pure function of the request + patient history + payer catalog + caller-provided asOfDate (no randomness, no clock; timestamps and quantities accepted as data), so the same context always yields the same decision + applied rules + reason code, with a documented decision precedence (pend-non-formulary > pend-step-therapy > pend-interaction-review > pend-quantity-limit > preferred-approved) and stable rule-id ordering. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.formulary.catalog-sourced (signal rulesTraceToCatalog, violating value false) blocks a fabricated drug or rule (mirroring the Claims Adjudication Agent's edit-catalog-sourced, the ACP Agent's directive-source-integrity, the HEDIS Agent's measure-catalog-sourced, and the CCM Agent's eligibility-catalog-sourced posture), backed by the pure guard rulesTraceToCatalog; policy.formulary.step-therapy-honored (signal stepTherapyIsHonored, violating value false) blocks a preferred-approved decision on step-therapy-required drugs when only undocumented / self-reported history is on file (approving on claimed-but-unverified history is a common payer-audit finding), backed by the guard stepTherapyIsHonored — trivially satisfied when the decision is a pend (agent isn't claiming step therapy is satisfied); and policy.formulary.no-autonomous-override (signal exceptionRequiresClinicianCosign, violating value false) blocks an autonomously-cosigned override — formulary exceptions are legally consequential under Medicare Advantage Chapter 6 + Part D and must have a prescriber's documented rationale (mirroring the Claims Adjudication Agent's no-autonomous-denial, the PA Agent's no-autonomous-submission, and the CCM Agent's no-autonomous-billing posture), backed by the guard exceptionRequiresClinicianCosign. It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches patient / member context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/formulary-review/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — formulary.evaluate-rules → formulary.decide — with phiAccessed:true, returning the FormularyReviewDecision as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Formulary & DUR panel (eight presets: preferred-approved Tier 1 estradiol oral, pend-step-therapy on patch with self-reported oral trial, pend-quantity-limit on 60 units vs 30 limit, pend-interaction-review on estradiol + warfarin routed to pharmacist, pend-non-formulary on fezolinetant with multi-rule precedence, plus off-catalog-rule / step-therapy-lied-about / auto-cosign governance-block presets — rendering the classified decision + tier + primary reason + routing + applied catalog rules + clinician-cosign flags, synthetic labels, and a trace deep link), and a seeded formulary.evaluate-rules→formulary.decide trace showing a pend-step-therapy decision, the console subtitle, and the investor brief (now 'thirty-nine agents across three planes', with the Formulary & DUR agent on the patient/clinical plane paired with PA + Medication Adherence + Claims Adjudication) all reflect it. Frontend tests green (+ formulary-review catalog/determinism/single-and-multi-rule-precedence/step-therapy-documentation-guard/off-catalog-behaviors/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow happy paths across preferred/step-therapy/quantity/interaction/non-formulary, the panel's request-body + view-lift, and the registry drift guards raised to thirty-nine agents); the drug catalog, rule catalog, reason-code catalog, step-therapy chains, and interaction pairs are clearly-labeled illustrative synthetics, NOT Medi-Span, First Databank, RxNorm, an actual payer's formulary file, or a certified DUR engine. Lint + build clean.

d4a6192 agent fabric: add the Formulary & Drug Utilization Review agent (deterministic first-pass DUR: tier + step-therapy + quantity + interactions + clinician-cosign-gated formulary exceptions, the 39th agent)

Agent Fabric: added the Claims Adjudication Assistant — deterministic first-pass payer-side edits + catalog reason codes + adjudicator-cosign-gated denials (the 38th agent)

Shipped
Details

Added the thirty-eighth agent on the fabric — claims-adjudication-agent, the Salesforce 'Agentforce for Health' / Health Cloud claims-adjudication analog. Registered on the care-coordination tier as the FIRST-PASS PAYER-SIDE adjudicator paired with the Prior Auth (pre-service), Member Service (billing self-service), Grievance & Appeals (post-denial intake), and HEDIS + Attribution + CCM (quality/reimbursement) agents. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/claims-adjudication.ts, evaluateClaimEdits(req) applies eight payer-side edits from the CLAIM_EDIT_CATALOG catalog (NCCI-PTP unbundling, LCD coverage, NCD coverage, benefit-limit exhausted, prior-auth missing, duplicate submission, out-of-network, timely-filing-window), each with a documented default decision tier (deny-drafted / pend-clinical-review / pend-adjudicator-review) and a mapping to a specific catalog reason code (illustrative CO-97, CO-50, CO-96, CO-119, CO-197, CO-18, CO-242, CO-29); summarizeDecision() picks the highest-severity edit and routes accordingly (deny → adjudicator, pend-clinical → clinical-reviewer, pend-adjudicator → adjudicator, clean-pay → auto-post); adjudicateClaim(req) returns the full ClaimAdjudicationDecision with cosigned:false and requiresAdjudicatorCosign:true on every deny-drafted — the agent NEVER autonomously finalizes a denial. It is a pure function of the claim + member benefits + edit-catalog + caller-provided asOfDate (no randomness, no clock; timestamps and windows accepted as data), so the same context always yields the same decision + applied edits + primary reason code, with a documented decision precedence (deny > pend-clinical > pend-adjudicator > clean-pay) and stable edit-id ordering. It is distinct from the Prior Authorization agent (pre-service utilization management), the Member Service / Billing agent (member-facing self-service), and the Grievance & Appeals agent (post-denial intake) — this one is the first-pass PAYER-SIDE adjudicator that decides which claims are clean-pay and which need human review. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.claims.edit-catalog-sourced (signal editsTraceToCatalog, violating value false) blocks a fabricated / off-catalog edit (mirroring the ACP Agent's directive-source-integrity, the HEDIS Agent's measure-catalog-sourced, the Credentialing Agent's source-integrity, the Attribution Agent's methodology-catalog-sourced, and the CCM Agent's eligibility-catalog-sourced posture), backed by the pure guard editsTraceToCatalog; policy.claims.no-autonomous-denial (signal denialRequiresAdjudicatorCosign, violating value false) blocks an autonomously-cosigned denial — denial letters are legally consequential under CMS / ERISA / state insurance code and must have an adjudicator sign-off (mirroring the PA Agent's no-autonomous-submission, the HEDIS Agent's no-autonomous-submission, and the CCM Agent's no-autonomous-billing posture), backed by the guard denialRequiresAdjudicatorCosign which trivially passes on non-denial decisions; and policy.claims.reason-code-integrity (signal decisionsCiteReasonCodes, violating value false) blocks a non-clean-pay decision that doesn't cite a specific catalog reason code — under Section 1557 / state insurance code / CMS, a denial notice must state the specific reason, backed by the guard decisionsCiteReasonCodes which enforces the primary reason code AND every applied edit's reason code trace to CLAIM_REASON_CODE_CATALOG. It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches patient / member context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/claims-adjudication/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — claims.evaluate-edits → claims.decide — with phiAccessed:true, returning the ClaimAdjudicationDecision as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Claims Adjudication panel (seven presets: clean-pay office visit + DEXA happy path, deny-drafted duplicate-submission (CO-18), pend-clinical-review LCD (CO-50), multi-edit precedence example (timely-filing CO-29 wins over PA + OON pends), plus off-catalog-edit, auto-cosign-denial, and reasonless-denial governance-block presets — rendering the classified decision + primary reason + routing + applied catalog edits + billed amount + cosign flags, synthetic labels, and a trace deep link), and a seeded claims.evaluate-edits→claims.decide trace showing a CO-18 duplicate-submission deny-drafted decision, the console subtitle, and the investor brief (now 'thirty-eight agents across three planes', with the Claims Adjudication Assistant on the patient/clinical plane paired with PA + Member Service + Grievance & Appeals) all reflect it. Frontend tests green (+ claims-adjudication catalog/determinism/single-edit-and-multi-edit-precedence/decision-severity/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow happy paths across clean-pay/pend/deny, the panel's request-body + view-lift, and the registry drift guards raised to thirty-eight agents); the edit catalog, reason-code catalog, and benefit-rule shape are clearly-labeled illustrative synthetics, NOT CMS X12 837 claim spec, an NCCI PTP edit table, an LCD/NCD medical-necessity registry, or a real payer's benefit configuration. Lint + build clean.

d28ffcc agent fabric: add the Claims Adjudication Assistant (deterministic first-pass payer-side edits + catalog reason codes + adjudicator-cosign-gated denials, the 38th agent)

Agent Fabric: added the Complex Care Management (CCM) agent — deterministic reimbursable time-tracking with catalog-sourced eligibility + CPT-coded billing + human-approval gate + phantom-minute integrity (the 37th agent)

Shipped
Details

Added the thirty-seventh agent on the fabric — complex-care-management-agent, the Salesforce 'Agentforce for Health' / Health Cloud CCM analog. Registered on the care-coordination tier as the REIMBURSABLE TIME-TRACKING piece paired with the Care Team + Care Plan agents. It is a DETERMINISTIC, no-Claude agent: in a new pure lib/complex-care-management.ts, evaluateCcmEligibility(ctx) confirms Medicare CCM eligibility by tracing chronic conditions to CHRONIC_CONDITION_CATALOG (illustrative synthetic — hypertension, T2DM, osteoporosis, chronic anxiety/depression, chronic migraine, hypothyroidism, CKD, hyperlipidemia; ≥ 2 required), checking the Medicare age gate (MEDICARE_ELIGIBLE_AGE = 65), the Medicare-coverage flag, and the CCM consent flag; summarizeCcmTime(entries) rolls up per-activity minutes against CCM_ACTIVITY_CATALOG (medication reconciliation, care-plan update, patient communication, referral follow-up, care-team coordination, patient education, resource navigation — the 'we-just-called-it-care-coord' catch-all is deliberately excluded), sorts activities by activityId ascending for a stable display, and reports whether every logged activity is catalog-sourced; pickCptCode(totalMinutes, complexity) maps the monthly total to the CPT ladder (99490 non-complex 20-39min → 99491 non-complex 40-59min → 99487 complex 60-89min → 99489 complex ≥ 90min with moderate/high complexity; non-complex complexity never escalates to 99487/99489; complex complexity under 60min falls back to the non-complex ladder); assembleCcmBillingPackage() produces a package that is ALWAYS requiresQualityTeamApproval:true / submitted:false — the agent NEVER autonomously submits a CMS claim. Eligibility, time totals, and CPT selection are pure functions of the caller-provided context (no randomness, no clock; timestamps and per-activity minutes accepted as data), so the same context always yields the same eligibility + time summary + CPT selection + billing package. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.ccm.eligibility-catalog-sourced (signal eligibilityTracesToCatalog, violating value false) blocks a fabricated chronic-condition claim (mirroring the ACP Agent's directive-source-integrity, the HEDIS Agent's measure-catalog-sourced, the Credentialing Agent's source-integrity, and the Attribution Agent's methodology-catalog-sourced posture), backed by the pure guard eligibilityTracesToCatalog; policy.ccm.no-autonomous-billing (signal billingRequiresHumanApproval, violating value false) blocks an autonomous CMS submission — every package requires human quality-team approval (mirroring the HEDIS Agent's no-autonomous-submission, the Prior Authorization Agent's no-autonomous-submission, and the ACP Agent's no-autonomous-directive-change posture), backed by the guard billingRequiresHumanApproval which trivially passes on a null package (no submission possible); and policy.ccm.time-integrity (signal timeEntriesAddUp, violating value false) blocks a time report where entries don't sum to the reported total OR where any entry cites an off-catalog activity — the guard against the classic CCM audit finding of phantom-minute inflation, backed by the guard timeEntriesAddUp. It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches patient context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/complex-care-management/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — ccm.evaluate-eligibility → ccm.summarize-time → ccm.assemble-billing-package — with phiAccessed:true, returning the CcmMonthReport as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Complex Care Management panel (six presets: non-complex 99490 happy path, complex 99487 happy path, ineligible-under-Medicare-age case, plus off-catalog-condition, autonomous-CMS-submit, and phantom-minutes governance-block presets — rendering the per-patient eligibility outcome + qualifying conditions, per-activity time summary + total, CPT selection with billing state, synthetic labels, and a trace deep link), and a seeded ccm.evaluate-eligibility→ccm.summarize-time→ccm.assemble-billing-package trace, the console subtitle, and the investor brief (now 'thirty-seven agents across three planes', with the Complex Care Management agent on the patient/clinical plane paired with Care Team + Care Plan) all reflect it. Frontend tests green (+ complex-care-management catalog/determinism/eligibility-branching/CPT-ladder-boundaries/off-catalog-condition-not-counted/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow happy paths + eligible/complex/ineligible flows, the panel's request-body + view-lift, and the registry drift guards raised to thirty-seven agents); the chronic-condition catalog, CCM activity catalog, CPT thresholds, and Medicare-eligibility flags are clearly-labeled illustrative synthetics, NOT CMS Chapter 12 / MLN Booklet 909188 CCM billing, an actual CPT coding manual, or a live Medicare claim-submission system. Lint + build clean.

1a6db7a agent fabric: add the Complex Care Management (CCM) agent (deterministic reimbursable time-tracking with catalog-sourced eligibility + CPT-coded billing + human-approval gate + phantom-minute integrity, the 37th agent)

Agent Fabric: added the Quality-Measure Attribution agent — deterministic patient-to-provider / -to-contract attribution with catalog-sourced methodologies + contract-terms enforcement + documented tie-breaks (the 36th agent)

Shipped
Details

Added the thirty-sixth agent on the fabric — quality-attribution-agent, the Salesforce 'Agentforce for Health' / Health Cloud attribution analog and the OTHER HALF of the HEDIS story: HEDIS computes the rates; this agent decides WHOSE PANEL each patient counts on. Registered on the care-coordination tier as a quality-accountability agent, paired with hedis-quality-agent. It is a DETERMINISTIC, no-Claude agent modeled on the HEDIS Quality + Care Team + Grievance & Appeals agents: in a new pure lib/quality-attribution.ts, attributePatient(ctx) picks a provider/clinic under one of four catalog-sourced methodologies — plurality-of-visits (counts primary-care visits inside the contract's attribution window, breaks ties with a documented chain: most-recent-visit-wins → provider-ref-lexical-ascending), pcp-of-record (uses the patient's designated PCP regardless of visits), prospective-medicare-advantage (uses the payer's prospective assignment), contract-defined-window (plurality against the contract's own window) — and evaluates the VBC contract's explicit exclusion terms (age band, network status, exclusion codes) so a patient whose contract excludes them is flagged excludedByContract:true and dropped from the downstream HEDIS denominator; attributePanel(panel) rolls up per-provider counts (attributed / excluded / tie-broken), sorted by provider ref ascending for a stable display. It is a pure function of the visit history + contract terms + caller-provided asOfDate (no randomness, no clock; timestamps and windows accepted as data), so the same context always yields the same attribution + rollup. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.attribution.methodology-catalog-sourced (signal attributionsTraceToCatalog, violating value false) blocks a bespoke / off-catalog methodology or contract (mirroring the HEDIS Agent's measure-catalog-sourced, the ACP Agent's directive-source-integrity, and the Credentialing Agent's source-integrity posture), backed by the pure guard attributionsTraceToCatalog; policy.attribution.no-conflicting-contract-terms (signal attributionsHonorContractTerms, violating value false) blocks a caller-asserted excludedByContract:false on a patient the contract actually excludes — the guard against polluting a contract's scorecard with patients the contract never covered, backed by the guard attributionsHonorContractTerms which re-checks each asserted attribution against the actual contract terms; and policy.attribution.tie-break-documented (signal attributionTieBreaksAreDocumented, violating value false) blocks a coin-flip / opaque / undocumented tie-break rule — turning tie-break resolution from gameable non-determinism into a fabric-verifiable invariant, backed by the guard attributionTieBreaksAreDocumented. It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches patient context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/quality-attribution/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — attribution.attribute → attribution.rollup — with phiAccessed:true, returning the QualityAttributionReport as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Quality-Measure Attribution panel (a five-patient demo panel happy path spanning three methodologies with one tie-break and one contract-exclusion, plus off-catalog-methodology, contract-terms-lied-about, and opaque-tie-break governance-block presets — rendering the per-patient attribution with provider/clinic/contract/exclusion/tie-break, the per-provider rollup with attributed/excluded/tie-broken counts, synthetic labels, and a trace deep link), and a seeded attribution.attribute→attribution.rollup trace, the console subtitle, and the investor brief (now 'thirty-six agents across three planes', with the Quality-Measure Attribution agent on the patient/clinical plane paired with HEDIS) all reflect it. Frontend tests green (+ quality-attribution catalog/determinism/four-methodology-behavior/tie-break-chain/contract-exclusion-precedence/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow happy paths with override-based block demonstrations, the panel's request-body + view-lift, and the registry drift guards raised to thirty-six agents); the methodology catalog, contract catalog, tie-break rules, and refs are clearly-labeled illustrative synthetics, NOT CMS Shared Savings Program attribution, an ACO REACH prospective assignment, an NCQA HEDIS attribution appendix, or a real payer's VBC contract terms. Lint + build clean.

096cff3 agent fabric: add the Quality-Measure Attribution agent (deterministic patient-to-provider / -to-contract attribution with catalog-sourced methodologies + contract-terms enforcement + documented tie-breaks, the 36th agent)

Agent Fabric: added the Provider Credentialing & Directory agent — deterministic network-integrity gate: verify credentials against approved sources + block referrals to expired / sanctioned providers + enforce No-Surprises-Act directory freshness (the 35th agent)

Shipped
Details

Added the thirty-fifth agent on the fabric — provider-credentialing-agent, the Salesforce 'Agentforce for Health' / Health Cloud provider-credentialing / provider-directory analog — as a first-class INTEGRATION-plane agent (sitting alongside the data substrate, not the patient-care plane). It is a DETERMINISTIC, no-Claude agent modeled on the HEDIS Quality, ACP, and TOC agents: in a new pure lib/provider-credentialing.ts, verifyProvider(request) computes the credentialing status against a defined CREDENTIAL_KINDS catalog (state-license, DEA, board-certification, sanctions-clearance, NPI) and APPROVED_VERIFICATION_SOURCES list (state-medical-board, DEA-registry, ABMS-board, OIG-LEIE-sanctions, NPI-registry; self-reported / verbal deliberately excluded), applying a stable precedence — sanctioned > incomplete > expired > verified — so a sanctioned provider never slips through even when other credentials look complete; the directoryProfile carries a No-Surprises-Act 90-day freshness flag (verifiedAsOf vs. asOfDate); the record emits three gate flags — canReferPatient / canBookAppointment / canReturnInDirectoryResponse — that the Referral Management, Appointment Scheduling, and Transitions of Care agents can consult before every handoff. It is a pure function of the credentials + directory profile + caller-provided asOfDate (no randomness, no clock; timestamps are accepted as data), so the same context always yields the same status + gates. This is where the GHOST-NETWORK problem gets fixed at the network boundary: the fabric never hands a referral or scheduled appointment to an expired / incomplete / sanctioned provider. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.credentialing.source-integrity (signal credentialsTraceToVerifiedSource, violating value false) blocks a credential citing a self-reported / verbal / off-catalog source (mirroring the ACP Agent's directive-source-integrity, the HEDIS Agent's measure-catalog-sourced, and the TOC Agent's reconciliation-source-integrity posture), backed by the pure guard credentialsTraceToVerifiedSource; policy.credentialing.no-referral-to-expired-or-sanctioned (signal noReferralToExpiredOrSanctioned, violating value false, intent-gated to referral / scheduling calls) blocks a referral or booking to an expired / incomplete / sanctioned provider — the load-bearing ghost-network guard — backed by the guard noReferralToExpiredOrSanctioned; and policy.credentialing.no-surprises-act-directory-accuracy (signal directoryIsFresh, violating value false, intent-gated to directory-lookup calls) blocks a stale directory record returned as authoritative past the NSA 90-day window, backed by the guard directoryIsFresh. Intent-aware enforcement means a stale directory record can still support a referral (the provider IS verified) — only the directory-response gate closes on NSA freshness; conversely a directory-lookup on a verified-but-stale record is blocked at NSA even when the provider itself is fine. It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches patient-adjacent context — a provider's status is required to safely refer a patient), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/provider-credentialing/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace span — credentialing.verify — with phiAccessed:true — returning the ProviderCredentialingRecord as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Provider Credentialing & Directory panel (a verified-MSCP happy path → all gates open, plus expired-license, sanctioned-provider, and stale-directory governance-block presets — rendering the per-credential state with source / expiry pills, the directory profile with an NSA freshness flag, the overall status and gate flags, synthetic labels, and a trace deep link), and a seeded credentialing.verify trace, the console subtitle, and the investor brief (now 'thirty-five agents across three planes', with the Provider Credentialing & Directory agent on the integration plane alongside the MCP server, MCP Bridge, MuleSoft, and Data 360) all reflect it. Frontend tests green (+ provider-credentialing catalog/determinism/status-precedence/stale-directory-vs-verified/off-source-not-counted/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow + intent-aware happy paths, the panel's request-body + view-lift, and the registry drift guards raised to thirty-five agents); the credential-kind catalog, verification sources, NSA freshness window, and directory schema are clearly-labeled illustrative synthetics, NOT NCQA / CAQH credentialing, a real state-medical-board API, an OIG-LEIE sanction feed, or a live directory. Lint + build clean.

0806609 agent fabric: add the Provider Credentialing & Directory agent (deterministic network-integrity gate: verify credentials against approved sources + block referrals to expired / sanctioned providers + enforce NSA directory freshness, the 35th agent)

Agent Fabric: added the Grievance & Appeals agent — deterministic regulated-intake: classify + route to a human queue + stamp a regulatory deadline with a PHI-safe routing summary (the 34th agent)

Shipped
Details

Added the thirty-fourth agent on the fabric — grievance-appeals-agent, the Salesforce 'Agentforce for Health' / Health Cloud grievance-and-appeals analog — as a first-class patient-facing member-service intake agent that REUSES the existing patient-facing governance tier. It is a DETERMINISTIC, no-Claude agent modeled on the Care Team, ACP, and HEDIS agents: in a new pure lib/grievance-appeals.ts, classifyCase(intake) is a pure keyword-rule pipeline — coverage-denial + expedited request → expedited coverage-denial appeal (3d deadline, clinical-review queue); coverage-denial by flag or keyword → standard coverage-denial appeal (30d, clinical-review); billing keywords → billing-dispute grievance (30d, member-services); everything else → quality-of-service grievance (30d, member-services); the CASE_TYPES catalog holds every case type's kind (grievance / appeal), default urgency, target queue, deadlineDays, and maxDeadlineDays (regulatory ceiling), all illustrative synthetics that model the SHAPE of Medicare Advantage Chapter 13 / state-insurance-code timelines without being certified; assembleGrievanceCase() stamps the deadline (receivedDate + deadlineDays), assigns a stable case id, and emits a STRUCTURED PhiSafeRoutingSummary (memberRef + caseType + urgency + queue + deadlineDate + phiSafe:true) — never free-text PHI. proposeCaseResolution() returns a proposal that is ALWAYS requiresHumanQueueAction:true, applied:false — the agent NEVER resolves, approves, or denies a case on its own. It is a pure function of the intake keywords + flags + receivedDate (accepted as data, no clock, no randomness), so the same intake always yields the same case type / urgency / queue / deadline / summary. It is distinct from the Member Service / Billing agent (billing self-service one-shot answers) and the Prior Authorization agent (pre-service utilization management) — this one runs the regulated grievance-and-appeals INTAKE workflow. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.grievance.no-autonomous-resolution (signal caseResolutionRequiresHumanQueue, violating value false) blocks a resolution bypassing the human queue (mirroring the ACP Agent's no-autonomous-directive-change, the HEDIS Agent's no-autonomous-submission, the Prior Authorization Agent's no-autonomous-submission, and the Care Team Agent's no-autonomous-assignment posture), backed by the pure guard caseResolutionRequiresHumanQueue; policy.grievance.deadline-integrity (signal deadlineTracesToCatalog, violating value false) blocks a deadline that doesn't trace to the case-type catalog OR that exceeds the regulatory maximum — the load-bearing regulatory-compliance guard against breaching Chapter 13 / state timelines, backed by the guard deadlineTracesToCatalog; and policy.grievance.no-phi-in-routing-summary (signal routingSummaryIsPhiSafe, violating value false) blocks a routing summary containing free-text PHI or an extra free-text key beyond the structured allow-list (memberRef / caseType / urgency / queue / deadlineDate / phiSafe) — a heuristic PHI-safety check that lets the routing summary be delivered via lower-trust channels (Slack, email, ticketing) without leaking PHI, backed by the guard routingSummaryIsPhiSafe. It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches patient/member context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/grievance-appeals/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — grievance.classify → grievance.route-to-queue, every span phiAccessed:true — returning the GrievanceAppealCase + a human-queue-action-gated ResolutionProposal as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Grievance & Appeals panel (an expedited HRT-denial happy path → 3-day deadline + clinical-review queue + PHI-safe routing summary, a billing-dispute grievance → 30-day member-services routing, plus autonomous-resolve, deadline-extension, and PHI-in-routing governance-block presets — rendering the case classification, urgency, queue, deadline, the structured PHI-safe routing summary, the human-queue-action-gated proposal, synthetic labels, and a trace deep link), and a seeded grievance.classify→grievance.route-to-queue trace, the console subtitle, and the investor brief (now 'thirty-four agents across three planes', with the Grievance & Appeals agent on the patient/clinical plane) all reflect it. Frontend tests green (+ grievance-appeals catalog/determinism/four-way-classification/deadline-math/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow + billing happy paths, the panel's request-body + view-lift, and the registry drift guards raised to thirty-four agents); the case-type catalog, deadline windows, expedited-eligibility rules, and queue mapping are clearly-labeled illustrative synthetics, NOT Medicare Advantage Chapter 13 or a real appeal-adjudication engine. Lint + build clean.

f2f0b85 agent fabric: add the Grievance & Appeals agent (deterministic regulated-intake: classify + route to a human queue + stamp a regulatory deadline with a PHI-safe routing summary, the 34th agent)

Agent Fabric: added the Discharge & Transitions of Care agent — deterministic close-the-loop after a hospitalization: medication reconciliation + scheduled follow-up + PCP handoff (the 33rd agent)

Shipped
Details

Added the thirty-third agent on the fabric — transitions-of-care-agent, the Salesforce 'Agentforce for Health' / Health Cloud transitions-of-care analog — as a first-class patient/clinical-plane agent that REUSES the existing care-coordination governance tier. It is a DETERMINISTIC, no-Claude agent modeled on the HEDIS Quality, ACP, and Care Team agents: in a new pure lib/transitions-of-care.ts, assembleTransitionOfCare(ctx) runs the close-the-loop workflow after a hospitalization / ED / observation encounter — reconcileMedications() classifies each medication as added / removed / dose-changed / unchanged (sorted by medication id for a stable display; entries with an unapproved / verbal / ad-hoc source are FILTERED from the reconciliation lines but surface via the source-integrity signal — a fabricated med cannot slip in), the follow-up is either a real scheduled slot (with slotStart + providerRef + modality) or explicitly state:'awaiting-schedule' with a handoff body pointing at the Appointment Scheduling agent — NEVER a text recommendation, the red-flag warning signs come from an illustrative RED_FLAG_CATALOG keyed by encounter-reason category (vasomotor / cardiovascular / behavioral / musculoskeletal / general, with an off-catalog category falling through to general so the demo still exercises the pipeline), the teach-back checklist is a rule-based UNIVERSAL_TEACH_BACK, and the PCP handoff summary + package note are rule-based / templated; proposeMedicationChange() returns a proposal that is ALWAYS requiresClinicianSignoff:true, applied:false — the agent NEVER autonomously commits a medication change. It is a pure function of the context + discharge date + provided medication lists (no randomness, no clock; timestamps are accepted as data), so the same context always yields the same reconciliation + red-flag list + teach-back checklist + PCP summary. It is distinct from the Care Plan agent (active treatment planning), the Medication Adherence agent (nudge-only refill / adherence prompts), and the Referral Management agent (specialist triage) — this one runs the CLOSE-THE-LOOP workflow after an acute event. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.toc.reconciliation-source-integrity (signal medicationsTraceToApprovedSource, violating value false) blocks a reconciliation with a verbal / ad-hoc / undocumented medication source — the load-bearing safety guard against a fabricated med slipping in, backed by the pure guard medicationsTraceToApprovedSource; policy.toc.no-autonomous-medication-change (signal reconciliationChangeRequiresClinician, violating value false) blocks a medication change bypassing clinician sign-off (mirroring the Medication Adherence Agent's no-autonomous-refill, the ACP Agent's no-autonomous-directive-change, the Prior Authorization Agent's no-autonomous-submission, and the HEDIS Agent's no-autonomous-submission posture), backed by the guard reconciliationChangeRequiresClinician; and policy.toc.follow-up-scheduled-not-recommended (signal followUpScheduledNotRecommended, violating value false) blocks a follow-up marked scheduled/complete without a real slot — the load-bearing 30-day-readmission guard against 'recommended' follow-ups masquerading as complete, backed by the guard followUpScheduledNotRecommended (which also accepts the safe awaiting-schedule interim answer). It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches patient context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/transitions-of-care/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — toc.reconcile → toc.assemble-package, every span phiAccessed:true — returning the TransitionOfCarePackage + a clinician-signoff-gated ReconciliationChangeProposal for the first added / dose-changed medication as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Discharge & Transitions of Care panel (a CV-hospitalization happy path → dose-changed Metoprolol + added Apixaban + scheduled cardiology follow-up in 7 days, a behavioral ED → awaiting-schedule interim answer, plus verbal-source, autonomous-med-change, and fake-scheduled governance-block presets — rendering the medication reconciliation with change kinds, the follow-up with slot/provider/days, the red-flag warning-sign list, the teach-back checklist, the sign-off-gated proposal, the PCP handoff summary, synthetic labels, and a trace deep link), and a seeded toc.reconcile→toc.assemble-package trace, the console subtitle, and the investor brief (now 'thirty-three agents across three planes', with the Discharge & Transitions of Care agent on the patient/clinical plane) all reflect it. Frontend tests green (+ transitions-of-care catalog/determinism/reconciliation-classification/off-source-filter/awaiting-schedule-safe-answer/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow + awaiting-schedule happy paths, the panel's request-body + view-lift, and the registry drift guards raised to thirty-three agents); the encounter categories, red-flag catalog, follow-up window, approved-source labels, and teach-back items are clearly-labeled illustrative synthetics, NOT a certified TOC schema or a real ADT / discharge system. Lint + build clean.

d751501 agent fabric: add the Discharge & Transitions of Care agent (deterministic close-the-loop after a hospitalization: medication reconciliation + scheduled follow-up + PCP handoff, the 33rd agent)

Agent Fabric: added the Care Team & Case Management agent — deterministic multi-disciplinary team assembly + case-manager assignment + PCP-anchor invariant (the 32nd agent)

Shipped
Details

Added the thirty-second agent on the fabric — care-team-management-agent, the Salesforce 'Agentforce for Health' / Health Cloud care-team / case-management analog — as a first-class patient/clinical-plane agent that REUSES the existing care-coordination governance tier. It is a DETERMINISTIC, no-Claude agent modeled on the Population Health, HEDIS Quality, and ACP agents: in a new pure lib/care-team-management.ts, assembleCareTeam(ctx) reasons over a SINGLE high-need menopause/midlife patient (distinct from the panel-level Population Health & Risk Stratification agent, which prioritizes people across a whole panel), resolves needed roles from the patient's active clinical needs against a CARE_ROLES catalog + ROLE_TRIGGERS condition→role trigger map (PCP + MSCP universally required; cardiology / endocrinology / bone-health / pelvic-floor PT / behavioral health triggered by cardiovascular / bone-health / pelvic-floor / behavioral needs), orders the roster in role catalog order, ranks gaps (PCP → urgent, universal → elevated, conditional → routine), and emits a shared team snapshot; assignCaseManager(patientRef) picks a case manager from a synthetic CASE_MANAGERS pool via a stable djb2-style hash on the patient ref, so the same patient always yields the same manager (no randomness, no clock); proposeTeamChange() returns a proposal that is ALWAYS requiresCaseManagerApproval:true, applied:false — the agent NEVER autonomously adds, removes, or reassigns a team member. It is a pure function of the context + asOfDate (no randomness, no clock), so the same context always yields the same team + case manager + snapshot with a stable, documented gap ordering. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.careteam.role-catalog-sourced (signal rolesTraceToCatalog, violating value false) blocks a roster or needed-role set that includes an off-catalog / fabricated discipline label — the guard against padding a team with an invented role, backed by the pure guard rolesTraceToCatalog; policy.careteam.no-autonomous-assignment (signal teamChangeRequiresCaseManager, violating value false) blocks a team-change that bypasses case-manager sign-off (mirroring the ACP Agent's no-autonomous-directive-change, the HEDIS Agent's no-autonomous-submission, and the Prior Authorization Agent's no-autonomous-submission posture), backed by the guard teamChangeRequiresCaseManager; and policy.careteam.pcp-required (signal teamIncludesPcp, violating value false) blocks a roster shipping without a PCP anchor — the continuity-of-care invariant every specialist coordinates around, backed by the guard teamIncludesPcp. It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches patient context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/care-team/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — careteam.assemble → careteam.draft-proposals, every span phiAccessed:true — returning the CareTeamAssembly + a case-manager-approval-gated TeamChangeProposal for the first open gap as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Care Team & Case Management panel (a high-need happy path → 4-of-6-role coverage + stable case-manager assignment + 2-gap flag, plus off-catalog-role, autonomous-assign, and missing-PCP governance-block presets — rendering the roster in role catalog order, per-role coverage, the flagged gaps, the assigned case manager, the shared team snapshot, the sign-off-gated team-change proposal, synthetic labels, and a trace deep link), and a seeded careteam.assemble→careteam.draft-proposals trace, the console subtitle, and the investor brief (now 'thirty-two agents across three planes', with the Care Team & Case Management agent on the patient/clinical plane) all reflect it. Frontend tests green (+ care-team-management catalog/determinism/roster-order/coverage-and-gap-ordering/off-catalog-filter/case-manager-stable-hash/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow happy paths, the panel's request-body + view-lift, and the registry drift guards raised to thirty-two agents); the care-role catalog, condition→role triggers, case-manager pool, member refs, and responsibility labels are clearly-labeled illustrative synthetics, NOT a certified care-team schema or a real provider directory. Lint + build clean.

e71e1d0 agent fabric: add the Care Team & Case Management agent (deterministic multi-disciplinary team assembly + case-manager assignment + PCP-anchor invariant, the 32nd agent)

Agent Fabric: added the Advance Care Planning agent — deterministic midlife-touchpoint directive assessment + human-signoff-gated proposals + LEP-safe conversation prompts (the 31st agent)

Shipped
Details

Added the thirty-first agent on the fabric — advance-care-planning-agent, a whole-person-care ACP TOUCHPOINT agent for the midlife/menopause patient, and the Salesforce 'Agentforce for Health' / Health Cloud advance-care-planning analog — as a first-class patient/clinical-plane agent that REUSES the existing whole-person-care governance tier (an equity / preventive whole-person activity, not a new clinical decision). It is a DETERMINISTIC, no-Claude agent modeled on the HEDIS Quality and Language Access agents: in a new pure lib/advance-care-planning.ts, assessAdvanceCarePlanning(ctx) surfaces which advance directives are on file (living will, DPOA-HC; POLST only when a serious-illness flag is on) against an illustrative ACP_DIRECTIVES catalog + an APPROVED_SOURCES list (verbal-not-documented deliberately excluded so it fails source-integrity), applies a stable staleness threshold (5 years) and per-directive denominator narrowing, and drafts a consent-gated ConversationPrompt for the care team — WITHHOLDING the active prompt (a safe completed answer, not a block) for an LEP patient with no qualified-interpreter plan, deferring in copy to the Language Access & Health Equity agent; proposeDirectiveChange() returns a proposal that is ALWAYS requiresClinicianAndPatientSignoff:true, applied:false — the agent NEVER autonomously creates, updates, or overrides a directive. It is a pure function of the caller-provided asOfDate + directives-on-file (no randomness, no clock), so the same context always yields the same assessment (with a stable, documented flag ordering). It is distinct from the Consent & Preferences Management agent (data-use consent, not directive-of-care) and the Care Plan agent (active treatment planning) — this one is about preserving the patient's voice if they lose decisional capacity, held at a midlife touchpoint rather than during acute illness. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.acp.directive-source-integrity (signal directivesTraceToCatalog, violating value false) blocks a claimed directive that doesn't trace to the catalog + an approved source + a recorded execution date — the guard against fabricating a directive on file to inflate ACP completeness, backed by the pure guard directivesTraceToCatalog; policy.acp.no-autonomous-directive-change (signal directiveChangeRequiresHumanSignoff, violating value false) blocks a directive change bypassing clinician + patient sign-off (mirroring the Prior Authorization Agent's no-autonomous-submission, the Medication Adherence Agent's no-autonomous-refill, the HEDIS Agent's no-autonomous-submission, and the Clinical Trials Agent's no-autonomous-enrollment posture), backed by the guard directiveChangeRequiresHumanSignoff; and policy.acp.language-access-integrity (signal languageAccessSatisfied, violating value false) blocks an active ACP conversation for an LEP patient with no documented qualified-interpreter plan — an ACP conversation is legally consequential and must not be held in a language the patient cannot participate in, backed by the guard languageAccessSatisfied. It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches patient context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/advance-care-planning/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — acp.assess → acp.draft-conversation, every span phiAccessed:true — returning the AcpAssessment + a clinician + patient sign-off gated DirectiveChangeProposal as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Advance Care Planning panel (an English happy path → drafted conversation prompt with a missing-universal-directive flag, an LEP-withheld case → withheld active prompt + language-access-required flag as a safe answer, plus verbal-source, autonomous-apply, and LEP-active governance-block presets — rendering the per-directive status, the illustrative completeness percentage, the flagged ACP gaps, the conversation prompt with its language + interpreter metadata, the sign-off gated directive-change proposal, synthetic labels, and a trace deep link), and a seeded acp.assess→acp.draft-conversation trace, the console subtitle, and the investor brief (now 'thirty-one agents across three planes', with the Advance Care Planning agent on the patient/clinical plane) all reflect it. Frontend tests green (+ advance-care-planning catalog/determinism/staleness-threshold/POLST-conditional/LEP-withheld-vs-actionable/off-catalog-source-flag/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow + LEP-withheld happy paths, the panel's request-body + view-lift, and the registry drift guards raised to thirty-one agents); the directive catalog, approved-source labels, staleness threshold, and language handling are clearly-labeled illustrative synthetics, NOT a certified advance-directives registry, a POLST/MOLST program, or a legal instrument. Lint + build clean.

ebd6631 agent fabric: add the Advance Care Planning agent (deterministic midlife-touchpoint directive assessment + human-signoff-gated proposals + LEP-safe conversation prompts, the 31st agent)

Agent Fabric: added the HEDIS & Quality Reporting agent — deterministic panel-level HEDIS measure rollup + catalog-sourced exclusions + human-approved submission (the 30th agent)

Shipped
Details

Added the thirtieth agent on the fabric — hedis-quality-agent, the Salesforce 'Agentforce for Health' / Health Cloud quality-reporting analog — as a first-class patient/clinical-plane agent that REUSES the existing care-coordination governance tier (a quality / care-management activity, not a new clinical decision). It is a DETERMINISTIC, no-Claude agent modeled on the Population Health and Clinical Trials agents: in a new pure lib/hedis-quality.ts, rollUpPanel(panel, asOfPeriod) rolls a panel of menopause/midlife patients up against a synthetic HEDIS_MEASURES catalog covering the menopause-relevant preventive-and-screening (OSW, BCS), cardiovascular (CBP, SPC), and behavioral (TCC) domains — computing eligible / excluded / denominator / numerator / rate per measure with a per-measure gap list, applying only exclusions that trace to that measure's allowedExclusions spec, with a stable, documented per-measure denominator narrowing (an unknown / ineligible patient is 'not-in-denominator', a catalog-sourced exclusion shrinks the denominator, everything else is compliant vs. non-compliant per the numerator criterion); assembleSubmission(report) assembles a submission package whose state is ALWAYS 'ready-for-quality-team-review' — requiresQualityTeamApproval:true, submitted:false, a stable illustrative packageId derived from the period. It is a pure function of the panel + the caller-provided asOfPeriod accepted as data (no randomness, no clock), so the same panel + period always yields the same rates and gap lists. Unlike the single-patient Care Gap Closure Agent (which drafts outreach for one patient's gaps) and the panel-level Population Health & Risk Stratification Agent (which prioritizes people), this one reports a whole PANEL against a defined HEDIS measure catalog — the artifact provider organizations owe payers under value-based-care contracts. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.hedis.measure-catalog-sourced (signal measuresTraceToCatalog, violating value false) blocks a report scoring an off-catalog / fabricated measure — backed by the pure guard measuresTraceToCatalog; policy.hedis.exclusion-integrity (signal exclusionsTraceToCatalog, violating value false) blocks an ad-hoc / unlisted denominator exclusion — the load-bearing rate-integrity guard against inflating a rate by shrinking the denominator with an unlisted exclusion, backed by the guard exclusionsTraceToCatalog; and policy.hedis.no-autonomous-submission (signal submissionRequiresHumanApproval, violating value false) blocks any autonomous submission — the agent may only assemble a human-approval-gated draft (mirroring the Prior Authorization Agent's no-autonomous-submission, the Population Health Agent's no-autonomous-care-decision, and the Clinical Trials Agent's no-autonomous-enrollment posture), backed by the guard submissionRequiresHumanApproval. It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches patient context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/hedis-quality/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — hedis.rollup → hedis.assemble-submission, every span phiAccessed:true — returning the PanelQualityReport + submission package as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new HEDIS Quality panel (a roll-up-the-demo-panel happy path plus off-catalog-measure, ad-hoc-exclusion, and autonomous-submission governance-block presets — rendering per-measure eligible / excluded / denominator / numerator / rate with a gap list, the submission package with its human-approval gate, synthetic labels, and a trace deep link), and a seeded hedis.rollup→hedis.assemble-submission trace, the console subtitle, and the investor brief (now 'thirty agents across three planes', with the HEDIS & Quality Reporting agent on the patient/clinical plane) all reflect it. Frontend tests green (+ hedis-quality catalog/determinism/denominator-narrowing/exclusion-integrity/submission-human-approval/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow happy paths, the panel's request-body + view-lift, and the registry drift guards raised to thirty agents); the HEDIS measure catalog, denominator windows, numerator thresholds, and exclusion lists are clearly-labeled illustrative synthetics, NOT NCQA-certified specifications, real value sets, or a certified HEDIS engine. Lint + build clean.

2f18998 agent fabric: add the HEDIS & Quality Reporting agent (deterministic panel-level HEDIS measure rollup + catalog-sourced exclusions + human-approved submission, the 30th agent)

Agent Fabric: added the Language Access & Health Equity agent — deterministic qualified-interpreter-only language access + approved-source materials + equity-gap flagging (the 29th agent)

Shipped
Details

Added the twenty-ninth agent on the fabric — language-access-agent, a patient-care HEALTH-EQUITY agent that ensures limited-English-proficiency (LEP) patients can actually understand their care — as a first-class patient/clinical-plane agent that REUSES the existing whole-person-care governance tier (the SDOH / equity tier — a health-equity / access activity, not a new clinical decision). It is a DETERMINISTIC, no-Claude agent modeled on the Clinical Trials and Care Gap Closure agents: in a new pure lib/language-access.ts, assessLanguageAccess(patient) determines the patient's PREFERRED LANGUAGE (deferring in copy to the Consent & Preferences Management agent's preferred-language preference — English is the clinical default), decides whether a QUALIFIED MEDICAL INTERPRETER is required and of which modality (in-person / video / phone) against a synthetic SUPPORTED_LANGUAGES catalog, checks whether the needed patient materials exist in that language against an APPROVED_MATERIALS catalog (each translation carrying an approved-source / translation-provenance label), and FLAGS EQUITY / ACCESS GAPS (no qualified interpreter available for a language, a consent form only in English) with a stable, documented severity ordering; arrangeInterpreter(assessment) returns a request that is always qualified:true — when no qualified interpreter is available it is an EQUITY-GAP ESCALATION to a human language-access coordinator, never a fallback to an unqualified option. It is a pure function of the context (no randomness, no clock), so the same context always yields the same assessment. It NEVER substitutes machine translation or an untrained / family interpreter for clinical communication or consent. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.langaccess.qualified-interpreter-only (signal usesQualifiedInterpreter, violating value false) blocks a plan that would use an untrained / ad-hoc / family interpreter (or machine translation) for clinical communication — backed by the pure guard usesQualifiedInterpreter, with a missing qualified interpreter surfaced as an equity-gap escalation (a safe completed answer, not a block); policy.langaccess.translated-material-source-integrity (signal materialsTraceToApprovedSource, violating value false) blocks an in-language material presented as official that doesn't trace to the approved translated-materials catalog (an unverified / ad-hoc translation), backed by the guard materialsTraceToApprovedSource; and policy.langaccess.no-machine-translation-for-consent (signal noMachineTranslationForConsent, violating value false) blocks machine / auto translation of clinical consent or clinical decision communication, backed by the guard noMachineTranslationForConsent. It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches patient context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/language-access/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — langaccess.detect-language → langaccess.assess → langaccess.arrange-interpreter, every span phiAccessed:true — returning the LanguageAccessAssessment + interpreter request as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Language Access panel (a Spanish-patient happy path → qualified video interpreter + full in-language materials, an equity-gap case → rare language with no qualified interpreter → escalation, plus family-interpreter, unapproved-translation, and machine-translated-consent governance-block presets — rendering the preferred language, the interpreter modality + qualified flag, the in-language materials with provenance, the equity gaps, synthetic labels, and a trace deep link), and a seeded detect-language→assess→arrange-interpreter trace with an equity-gap example, the console subtitle, and the investor brief (now 'twenty-nine agents across three planes', with the Language Access & Health Equity agent on the patient/clinical plane) all reflect it. Frontend tests green (+ language-access catalog/determinism/qualified-interpreter-only/approved-source-materials/equity-gap-escalation/three-signal-true-and-false guards, the route's envelope/three governance blocks/allow + equity-gap-completes happy paths, the governance-evaluate passthrough for the three new signals, the panel's request-body + view-lift, and the registry drift guards raised to twenty-nine agents); the supported-language list, interpreter availability, materials, and translation provenance are clearly-labeled illustrative synthetics, NOT a certified language-access system. Lint + build clean.

4e5c0f0 agent fabric: add the Language Access & Health Equity agent (deterministic qualified-interpreter-only language access + approved-source materials + equity-gap flagging, the 29th agent)

Agent Fabric: added the Clinical Trials & Research Matching agent — deterministic criteria-sourced trial-eligibility matching + consent-gated outreach (the 28th agent)

Shipped
Details

Added the twenty-eighth agent on the fabric — clinical-trials-agent, the Salesforce 'Agentforce for Health' / Health Cloud clinical-trials / research-matching analog — as a first-class patient/clinical-plane agent that REUSES the existing care-coordination governance tier (research matching is a care-navigation / coordination activity, not a new clinical decision). It is a DETERMINISTIC, no-Claude agent modeled on the Care Gap Closure and Population Health agents: in a new pure lib/clinical-trials.ts, matchTrials(patient, {researchConsent}) evaluates a single menopause/midlife patient's STRUCTURED context (age band, symptom profile, comorbidities, geography, prior therapy, HRT status, postmenopausal status) against a synthetic STUDY_CATALOG whose eligibility is composed from a defined TRIAL_CRITERIA catalog (inclusion + exclusion criteria), returns the matching studies ranked with per-criterion match explanations (eligible first, then match score, then studyId — a stable, documented tie-break), and draftTrialOutreach(recommended, researchConsent) drafts a CONSENT-GATED outreach that NEVER auto-enrolls. It is a pure function of the context + research-consent flag (no randomness, no clock), so the same inputs always yield the same matches + ranking + outreach state. It ties thematically to the Consent & Preferences Management agent's `research` consent scope (withheld by default in that agent's demo ledger) — deferring to that authoritative research-consent state before any outreach — but does its own eligibility logic. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.trials.eligibility-criteria-sourced (signal eligibilityTracesToCriteria, violating value false) blocks a fabricated / ad-hoc / off-catalog eligibility determination that doesn't trace to a defined study criterion (the pure guard eligibilityTracesToCriteria backs it); policy.trials.research-consent-required (signal researchConsentPresent, violating value false) blocks an active trial outreach drafted without the patient's research consent — and when consent is absent the agent WITHHOLDS outreach (a safe completed answer, not a block) via the guard outreachHasResearchConsent; and policy.trials.no-autonomous-enrollment (signal enrollmentRequiresHuman, violating value false) blocks any attempt to enroll a patient autonomously — enrollment requires informed consent AND a human (every outreach is requiresHuman:true / enrolled:false, there is no 'enrolled' state), backed by the guard enrollmentRequiresHuman. It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches patient clinical context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/clinical-trials/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — trials.load-catalog → trials.match → trials.draft-outreach, every span phiAccessed:true — returning the TrialMatchResult as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Clinical Trials panel (match-with-consent and match-no-consent-withheld happy-path presets plus fabricated-eligibility, outreach-without-consent, and autonomous-enrollment governance-block presets — rendering the per-study matched/failed criteria, the recommended studies, the consent-gated outreach state, synthetic labels, and a trace deep link), and a seeded load-catalog→match→draft-outreach trace, the console subtitle, and the investor brief (now 'twenty-eight agents across three planes', with the Clinical Trials & Research Matching agent on the patient/clinical plane) all reflect it. Frontend tests green (+ clinical-trials catalog/criteria-integrity/determinism/ranking-tie-break/consent-gated-outreach/never-enrolled/traces-to-criteria-true-and-false/consent-and-enrollment guards, the route's envelope/three governance blocks/allow + withheld-outreach happy paths, the governance-evaluate passthrough for the three new signals, the panel's request-body + view-lift, and the registry drift guards raised to twenty-eight agents); the study catalog, sponsors, criteria, and patient references are clearly-labeled illustrative synthetics, NOT real studies or a certified trial-eligibility engine. Lint + build clean.

68ab655 agent fabric: add the Clinical Trials & Research Matching agent (deterministic criteria-sourced trial-eligibility matching + consent-gated outreach, the 28th agent)

Agent Fabric: added the Consent & Preferences Management agent — the authoritative consent ledger + deterministic consent-decision service (the 27th agent)

Shipped
Details

Added the twenty-seventh agent on the fabric — consent-management-agent, the MuleSoft control-plane / data-substrate consent service — as the AUTHORITATIVE, cross-cutting consent & communication-preferences service the rest of the fabric's consent-before-outreach / consent-before-referral / consent-to-monitor gates logically defer to. Unlike every other agent (which CONSUMES consent), this one is the SOURCE OF TRUTH FOR consent, so it REUSES the existing data-plane governance tier (platform plane — a control-plane / data-substrate service) rather than inventing one, and is a DETERMINISTIC, no-Claude agent. In a new pure lib/consent-management.ts it holds, per patient, a consent LEDGER (a set of consent scopes — contact-outreach, data-sharing, remote-monitoring, research, marketing — each with a status granted / withheld / revoked, a recorded basis/source, a timestamp, and an optional expiry) and communication PREFERENCES (allowed channels sms/email/voice, quiet hours, preferred language, frequency cap), and evaluateConsent(ledger, {scope, channel, atTime, priorTouches}) DETERMINISTICALLY answers one question — may this patient be contacted / have data used for this scope over this channel at this time? — denying a withheld / revoked / expired / unrecorded scope, an unpermitted channel, a quiet-hours touch (quiet hours are read from the query's own atTime, not a clock), or a frequency-cap breach (priorTouches is taken as data), and otherwise allowing, always citing the consent record it relied on (matchedConsentEventId). It is a pure function of the ledger + the query's own atTime + priorTouches (no randomness, no clock), so the same inputs always yield the same decision. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.consent.recorded-source (signal consentTracesToRecord, violating value false) blocks an asserted-but-unrecorded consent that doesn't trace to a recorded event/basis — an off-catalog scope, an unrecognized status, or a missing recorded source (the pure guard consentTracesToRecord backs it); policy.consent.honor-revocation (signal honorsRevocation, violating value false) blocks any decision that would ALLOW outreach against a revoked / expired scope — a revocation must be honored immediately (the guard honorsRevocation backs it); and policy.consent.no-scope-override (signal respectsConsentScope, violating value false) blocks any decision that overrides a withheld scope or borrows consent for a scope the patient never granted — an allow requires a granted, current record for that exact scope (the guard respectsConsentScope backs it). It also reuses, by extending appliesTo, the HIPAA-audit policy (it holds patient consent data — it is NOT a commercial-plane agent even though it's on the platform plane), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/consent-management/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — consent.load-ledger → consent.evaluate → consent.decision, every span phiAccessed:true — returning the ConsentDecision + ledger as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Consent & Preferences Management panel (granted→allowed, withheld→denied, and quiet-hours→denied happy-path presets plus unrecorded-consent, allow-against-revoked, and scope-override governance-block presets — rendering the consent ledger, the decision with its reason + matched consent record, the comms preferences, synthetic labels, and a trace deep link), and a seeded load-ledger→evaluate→decision trace, the console subtitle, and the investor brief (now 'twenty-seven agents across three planes', with the Consent & Preferences Management agent on the platform & data substrate) all reflect it. Frontend tests green (+ consent-management catalog/time-helper/resolve-latest/determinism/decision-order/traces-to-record-true-and-false/honor-revocation-true-and-false/no-scope-override guards, the route's envelope/three governance blocks/allow + honored-denial happy paths, the governance-evaluate passthrough for the three new signals, the panel's request-body + view-lift, and the registry drift guards raised to twenty-seven agents); the consent scopes, recorded sources, preferences, and patient references are clearly-labeled illustrative synthetics, NOT a certified consent-management system. Lint + build clean.

750caad agent fabric: add the Consent & Preferences Management agent (authoritative consent ledger + deterministic consent-decision service, the 27th agent)

Agent Fabric: added the Population Health & Risk Stratification agent — deterministic panel-level risk tiering + prioritized outreach worklist (the 26th agent)

Shipped
Details

Added the twenty-sixth agent on the fabric — population-health-agent, the Salesforce 'Agentforce for Health' / Health Cloud population-health / risk-stratification analog — as a first-class patient/clinical-plane agent that REUSES the existing care-coordination governance tier (population health / care-management triage, not a new clinical decision). It is a DETERMINISTIC, no-Claude agent modeled on the Care Gap Closure and Remote Patient Monitoring agents, and introduces a NEW granularity: unlike every other patient-plane agent (which reasons over a SINGLE patient), it reasons over a whole PANEL/COHORT at once. In a new pure lib/population-health.ts, stratifyPanel(panel) DETERMINISTICALLY scores each patient from already-produced per-patient signals (intake severity, validated-assessment band, open care gaps, positive SDOH domains, medication-adherence status, monitored-symptom trend) with a TRANSPARENT additive/weighted risk model — a defined RISK_FACTORS spec (each factor carrying a synthetic weight + rationale) and fixed TIER_CUTOFFS mapping a numeric score to a low / rising / high tier — a pure function of the signals (no randomness, no clock), so the same panel always yields the same tiers + worklist ordering with a stable, documented tie-break (score desc, then patientRef asc), and every patient's tier cites the contributing factors that produced it. It then emits a prioritized outreach worklist (which patients to reach first, and why) for a human care manager. THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.pophealth.transparent-risk-model (signal riskScoreTracesToFactors, violating value false) blocks an opaque / off-spec / black-box score whose tier doesn't trace to the documented risk-factor spec (the pure guard riskScoreTracesToFactors backs it); policy.pophealth.no-protected-class-factors (signal excludesProtectedAttributes, violating value false) blocks any attempt to score on a protected-class attribute (race, ethnicity, gender identity, religion, national origin, disability status, sexual orientation, marital status) — a fairness / responsible-AI requirement (the guard excludesProtectedAttributes backs it); and policy.pophealth.no-autonomous-care-decision (signal tierReviewedByHuman, violating value false) blocks any attempt to let a risk tier trigger an autonomous care action — a tier is a prioritization signal only, every tier→action requires human / care-manager review. It also reuses, by extending appliesTo, the HIPAA-audit policy (panel-level PHI — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/population-health/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — pophealth.ingest-panel → pophealth.score → pophealth.stratify → pophealth.build-worklist, every span phiAccessed:true — returning the PanelStratification as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Population Health panel (mixed-panel and high-risk-cohort happy-path presets producing a mix of low/rising/high tiers + a prioritized worklist, plus opaque-score, protected-class-factor, and autonomous-care-decision governance-block presets — rendering the tier counts, the per-patient tiers with their contributing factors, the ordered worklist, synthetic labels, and a trace deep link), and a seeded ingest-panel→score→stratify→build-worklist trace, the console subtitle, and the investor brief (now 'twenty-six agents across three planes', with the Population Health & Risk Stratification agent on the patient/clinical plane) all reflect it. Frontend tests green (+ population-health catalog/cutoff-integrity/determinism/tier-mapping/worklist-ordering/traces-to-factors-true-and-false/excludes-protected-true-and-false/human-review guards, the route's envelope/three governance blocks/happy-path, the governance-evaluate passthrough for the three new signals, the panel's request-body + view-lift, and the registry drift guards raised to twenty-six agents); the risk factors, weights, cutoffs, and patient references are clearly-labeled illustrative synthetics, NOT a certified risk-stratification model. Lint + build clean.

1fccf16 agent fabric: add the Population Health & Risk Stratification agent (deterministic panel-level risk tiering + prioritized outreach worklist, the 26th agent)

Agent Fabric: added the Remote Patient Monitoring & Symptom-Trend Tracking agent — deterministic longitudinal trend detection + clinician-routed escalation (the 25th agent)

Shipped
Details

Added the twenty-fifth agent on the fabric — remote-monitoring-agent, the remote-patient-monitoring (RPM) analog — as a first-class patient/clinical-plane agent that REUSES the existing care-coordination governance tier (longitudinal monitoring + coordinating a clinician escalation, not a new clinical decision). It is a DETERMINISTIC, no-Claude agent modeled on the Care Gap Closure and Medication Adherence agents, and is distinct from all four: it ingests longitudinal (time-series) symptom/vital readings — self-reported or from wearables/devices — for a menopause/midlife patient (hot-flash frequency, sleep hours, mood score, resting heart rate, weight). In a new pure lib/remote-monitoring.ts, assessMonitoring(readings) DETERMINISTICALLY detects a per-metric trend (improving / stable / worsening) by comparing a recent window against a baseline window against a defined monitored-metrics catalog (each metric carrying a synthetic unit, stable band, worsening direction, and red-flag cutoff), then raises escalations for worsening or red-flag trends — a pure function of the reading series (timestamps are accepted as data, no randomness, no clock), so the same series always yields the same trend + escalation decision, and every escalation cites the metric + the threshold rule that triggered it and is routed to a clinician (routedTo:'clinician-review'). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.rpm.reading-source-integrity (signal readingsTraceToSource, violating value false) blocks a fabricated / off-source reading or an off-catalog metric (the pure guard readingsTraceToSource backs it); policy.rpm.no-autonomous-escalation (signal escalationRoutedToHuman, violating value false) blocks any attempt to act on a trend autonomously — every escalation must be routed to a human clinician, never an autonomous clinical action (no auto-ordering, auto-medication, auto-titration); and policy.rpm.consent-to-monitor (signal monitoringHasConsent, violating value false) blocks longitudinal monitoring / trend outreach without the patient's consent. It also reuses, by extending appliesTo, the HIPAA-audit policy (it touches patient clinical context — it is NOT a commercial-plane agent), and is deliberately NOT on the live-Claude model allow-list (no Claude). A runnable A2A endpoint (POST /api/agents/remote-monitoring/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — rpm.ingest → rpm.detect-trends → rpm.route-to-clinician, every span phiAccessed:true — returning the MonitoringAssessment as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Remote Patient Monitoring panel (improving/stable/worsening multi-metric, benign, and red-flag happy-path presets plus fabricated-reading, autonomous-escalation, and no-consent governance-block presets — rendering the per-metric trends, escalations with their triggering rule + 'routed to clinician review', synthetic labels, and a trace deep link), and a seeded ingest→detect→route-to-clinician trace, the console subtitle, and the investor brief (now 'twenty-five agents across three planes', with the Remote Patient Monitoring & Symptom-Trend Tracking agent on the patient/clinical plane) all reflect it. Frontend tests green (+ remote-monitoring catalog-integrity/determinism/trend-classification/red-flag/escalation-routing/source-guard-true-and-false, the route's envelope/three governance blocks/happy-path, the governance-evaluate passthrough for the three new signals, the panel's request-body + view-lift, and the registry drift guards raised to twenty-five agents); the monitored-metric catalog, thresholds, and red-flag cutoffs are clearly-labeled illustrative synthetics, NOT a certified remote-monitoring or clinical-alerting engine. Lint + build clean.

5db88e4 agent fabric: add the Remote Patient Monitoring & Symptom-Trend Tracking agent (deterministic longitudinal trend detection + clinician-routed escalation, the 25th agent)

Agent Fabric: added the Patient Education & Health Coaching agent — evidence-sourced education + live-Claude coaching (the fourth live-Claude agent)

Shipped
Details

Added the twenty-fourth agent on the fabric — patient-education-agent, the Salesforce 'Agentforce for Health' patient-education / health-coaching analog — as a first-class patient/clinical-plane agent that REUSES the existing patient-engagement governance tier (patient-facing education + coaching, not a new clinical decision). It is distinct from the clinician-authored Care Plan agent and the refill-focused Medication Adherence agent: it turns already-produced signals (intake symptoms/severity, an optional validated-instrument assessment, Care Plan focus areas, and detected care gaps) into a personalized, evidence-sourced menopause/midlife education curriculum and a warm coaching message. In a new pure lib/patient-education.ts, buildEducationCurriculum(context) DETERMINISTICALLY selects modules from a defined evidence-sourced catalog (bone health, cardiovascular risk, sleep hygiene, vasomotor self-management, mood/stress, nutrition, physical activity — each carrying a synthetic source label: The Menopause Society, USPSTF, NAMS/ACOG-style) — a pure function of the inputs (no randomness, no clock), so the same context always yields the same curriculum. coachEducation(curriculum) then phrases a motivational coaching message with live Anthropic Claude — the FOURTH live-Claude agent after the Care Router, Care Plan, and Clinical Summary agents — falling back to a DETERMINISTIC scripted message (scriptedCoachEducation, with a recorded fallbackReason) when ANTHROPIC_API_KEY is unset or the API call fails, exactly like the Care Plan agent, returning an EducationCoachingResult (coachingMessage, moduleIds, via: 'claude-api' | 'scripted-fallback', optional fallbackReason, synthetic:true). THREE load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.education.evidence-sourced (signal educationTracesToEvidenceSource, violating value false) blocks a fabricated / off-catalog topic that doesn't trace to a defined evidence source (the pure guard curriculumTracesToEvidenceSource backs it); policy.education.no-medical-advice (signal staysWithinEducationScope, violating value false) blocks content that strays beyond general education into diagnosis, medication dosing, or individualized medical advice; and policy.education.consent-before-outreach (signal coachingOutreachHasConsent, violating value false) blocks a coaching push without the patient's consent — every outreach is consent-gated and human-approval-gated. It also reuses, by extending appliesTo, the anthropic-claude-sonnet model allow-list (live-Claude) and the HIPAA-audit policy (it touches patient clinical context — it is NOT a commercial-plane agent). A runnable A2A endpoint (POST /api/agents/patient-education/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — patient-education.curate → patient-education.coach, every span phiAccessed:true, the coach span carrying via + any fallbackReason and the consent/human-approval/never-sent flags — returning the curriculum + coaching as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is surfaced on /demo/intake via a new Patient Education panel (vasomotor, postmenopausal-prevention, and mood-dominant happy-path presets plus off-catalog, medical-advice, and no-consent governance-block presets — rendering the selected modules with their source labels, the coaching message with a via/fallbackReason badge, the evidence-source signal, and a trace deep link), and a seeded curate→coach (scripted-fallback) trace, the console subtitle, and the investor brief (now 'twenty-four agents across three planes', with the Patient Education & Health Coaching agent on the patient/clinical plane) all reflect it. Frontend tests green (+ patient-education determinism/module-selection/evidence-source-guard-true-and-false/scope-guard/live-Claude-success-via-mocked-SDK + SDK-error + missing-key fallback with fallbackReason, the route's envelope/three governance blocks/model-allow-list/happy-path, the governance-evaluate passthrough for the three new signals, the panel's request-body + view-lift, and the registry drift guards raised to twenty-four agents); the education modules + source labels are clearly-labeled illustrative synthetics, NOT a certified patient-education engine. Lint + build clean.

e8a7383 agent fabric: add the Patient Education & Health Coaching agent (evidence-sourced education + live-Claude coaching, the fourth live-Claude agent)

Intake: the assistant greets the patient by name

Shipped
Details

Made the intake experience address the patient by name across both surfaces. The scripted intake assistant (agentforce-fallback.tsx) now greets and closes using the name typed at step 0 — a subtle acknowledgment on the next turn ("Thanks, Maggie! …") and the completion / red-flag messages ("Thanks, Maggie. I've drafted your intake…"), with a graceful fallback to the name-less copy when no usable name is captured. Name parsing lives in pure, unit-tested helpers in lib/agentforce.ts (firstNameFromInput, withNameAcknowledgment, intakeCompletionMessage, intakeRedFlagMessage). For the LIVE Salesforce Agentforce agent, the intake stage now forwards the Salesforce-standard _firstName/_lastName hidden prechat fields in-band (auto-accepted, no org registration), and — because a static welcome message can't interpolate a name and the LLM may not see the standard field in its reasoning — a durable context-variable route was wired end to end, mirroring the Patient_Zip plumbing exactly: a new MessagingSession.Pause_Patient_First_Name__c field (Text 80), a Patient_First_Name input + assignment on the Pause_Intake_Prechat_Router Flow, a Patient_First_Name channel customParameter, FLS on the Pause_Health_Intake_Prechat_Dossier permission set, both package manifests + deploy.sh inventory + README track-table, and /api/intake/prechat-context emitting Patient_First_Name (intake-patient-stage forwards it in-band) so the agent can greet by $Context.Pause_Patient_First_Name. Deployable XML is comment-free (the documented deploy trap) and validates with xmllint; frontend tests + lint + build green. Org-side remainder (documented in docs/AGENTFORCE_PROVIDER_ACTION_RUNBOOK.md "Greeting the patient by name"): deploy the metadata, register Patient_First_Name as a hidden prechat field, add the Pause_Patient_First_Name bot context variable, reference it in the Agent-Level Instructions, then re-Publish the Embedded Service Deployment + Deactivate → Save → Activate the agent.

0fc0903 intake: personalize the assistant greeting by the patient's name59a3ad0 salesforce: wire Patient_First_Name prechat → context var (greet the patient by name)

Agent Fabric: added the SDOH Screening agent — validated social-needs screening + consent-gated community referral (whole-person care)

Shipped
Details

Added the twenty-third agent on the fabric — sdoh-screening-agent, the Salesforce 'Agentforce for Health' whole-person-care analog — as a first-class patient/clinical-plane agent on a NEW whole-person-care governance tier (screening + referral for social determinants of health is a distinct kind of work from the clinical-decision and care-coordination agents, so it warrants its own tier rather than overloading an existing one; the tier maps to the patient-care plane so the console/proposal grouping and drift guards render it). In a new pure lib/sdoh.ts it screens a patient for health-related social needs / social determinants of health with a validated, public-domain instrument — the CMS Accountable Health Communities HRSN (AHC-HRSN) screening tool's five CORE domains (housing instability, food insecurity, transportation needs, utility needs, interpersonal safety) — where screenSocialNeeds(response) DETERMINISTICALLY flags the positive social-need domains with real rule-based scoring (the Hunger Vital Sign two-item food screen; the HITS interpersonal-safety cutoff of >10) — no LLM, no randomness, no clock, so the same responses always screen identically — and returns an SdohScreeningResult (per-domain positive/negative, a count of positive domains, and any interpersonal-safety red flag). Like the Assessment Agent's validated-instrument allow-list, it refuses to administer any screener not on ALLOWLISTED_SDOH_SCREENERS. draftCommunityReferralsForResult(result, {patientConsent}) then drafts CONSENT-GATED, catalog-sourced community-resource referrals (211, food bank, housing assistance, utility/LIHEAP assistance, a domestic-violence hotline for the safety domain) — each referencing a defined community-resource catalog id, human-approval-gated, and never an autonomous enrollment. TWO load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.sdoh.validated-screener-only (signal usesValidatedSdohScreener, violating value false) blocks a screener outside the validated allow-list, and policy.sdoh.consent-before-referral (signal sdohReferralHasConsent, violating value false) blocks a community referral drafted without the patient's explicit consent. A positive interpersonal-safety screen is a mandatory escalation to a human social worker (mirroring the Assessment Agent's PHQ-9 item 9 handling), recorded as its own trace span. SDOH is SEPARATE from clinical severity — sdohToIntakeSignal(result) raises a whole-person care-coordination flag (and a safety escalation), NOT an intake clinical severity — so it composes with the intake spine WITHOUT ever changing IntakeRecord.severity. It reuses, by extending appliesTo, the HIPAA-audit policy (it touches patient social/clinical context — it is NOT a commercial-plane agent). A runnable A2A endpoint (POST /api/agents/sdoh-screening/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — sdoh.screen → sdoh.safety.escalate (when the red flag fires) → sdoh.refer, every span phiAccessed:true — returning the result + consent-gated referral drafts as an artifact with metadata.agentFabric carrying the trace ids and the honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is also threaded ADDITIVELY into POST /api/intake/route-to-care-router (when a body.sdoh is present it screens + drafts consented referrals, attaching _sdoh to the response meta with its own spans, and never mutates the routing decision), surfaced on /demo/intake via a new SDOH Screening panel (multi-domain positive screen with consented referrals, an interpersonal-safety escalation, a consent-withheld governance block, and a non-allow-listed screener block — rendering the positive domains, the safety escalation, the consent/human-approval/no-autonomous-enrollment referral flags, synthetic labels, and a trace deep link), and a seeded screen→refer + safety-escalation trace, the console subtitle, and the investor brief (now 'twenty-three agents across three planes', with the SDOH Screening agent on the patient/clinical plane) all reflect it. Frontend tests green (+ sdoh determinism/per-domain-scoring/safety-red-flag-escalation/allow-list-rejection/referral-draft-shape-and-consent-gating, the route's envelope/consent-block/allow-list-block/safety-escalation/happy-path, the panel's request-body + view-lift, and the registry drift guards raised to twenty-three agents with the new whole-person-care tier covered); the community-resource catalog is a clearly-labeled illustrative synthetic, NOT a live directory of real programs. Lint + build clean.

8248f2e agent fabric: add the SDOH Screening agent (validated social-needs screening + consent-gated community referral)

Agent Fabric: added the Clinical Summary agent — after-visit summary + clinician handoff (the third live-Claude agent)

Shipped
Details

Added the twenty-second agent on the fabric — clinical-summary-agent, the Salesforce 'Agentforce for Health' After-Visit Summary / clinical-documentation analog — as a first-class patient/clinical-plane agent on the existing care-coordination governance tier (it is a documentation/coordination artifact, not a new clinical decision, so it REUSES a tier rather than proliferating one). It runs POST-VISIT, downstream of the whole lifecycle, and COMPOSES the outputs the other agents already produced — the intake severity/symptoms, the Care Router pathway, and (optionally) a validated-instrument assessment, an instantiated care plan, and detected care gaps — into TWO artifacts: a patient-friendly After-Visit Summary and a clinician handoff note. In a new pure lib/clinical-summary.ts, assembleClinicalSummaryContext(inputs) DETERMINISTICALLY gathers ONLY the facts present in the provided lifecycle inputs and records the exact sourceRecords the context was assembled from (intake, care-router:<pathway>, assessment:<instrument>, care-plan:<id>, care-gap:<id>) — the agent never invents a clinical fact or a source. summarizeClinical(context, opts?) then phrases the two artifacts with live Anthropic Claude — the THIRD live-Claude agent after the Care Router and the Care Plan agent — falling back to a DETERMINISTIC scripted composition (scriptedSummarizeClinical, with a recorded fallbackReason) when ANTHROPIC_API_KEY is unset or the API call fails, exactly like the Care Plan agent, and returns a ClinicalSummaryResult (patientSummary, clinicianHandoff, sourceRecords, via: 'claude-api' | 'scripted-fallback', optional fallbackReason, synthetic:true). The load-bearing honesty property — every summary must trace to the defined source records the context was assembled from — is genuinely governance-enforced by a NEW enforced-block policy, policy.clinical-summary.source-record-sourced, with its matching boolean signal (summaryTracesToSourceRecords, violating value false) wired into the shared governance-signals metadata so evaluateGovernance() blocks a fabricated / off-context summary that cites a record absent from the assembled context; the pure guard summaryTracesToSourceRecords(result, context) backs it and the route sets the signal honestly from the domain. It also reuses, by extending appliesTo, the anthropic-claude-sonnet model allow-list (live-Claude), the no-prescribing, consent-before-grounding, and HIPAA-audit policies (it touches clinical data — it is NOT a commercial-plane agent) and commits no clinical action. A runnable A2A endpoint (POST /api/agents/clinical-summary/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — clinical-summary.assemble → clinical-summary.summarize, every span phiAccessed:true, the summarize span carrying via + any fallbackReason — returning both artifacts + the sourceRecords as an artifact with metadata.agentFabric carrying the trace ids and the grounding signal, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. It is also threaded ADDITIVELY into POST /api/intake/route-to-care-router (when clinicalSummary is present it assembles + summarizes after the care-router decision and any care plan, attaching _clinicalSummary to the response meta with its own spans), surfaced on /demo/intake via a new Clinical Summary panel (happy-path + governance-blocked 'ungrounded summary' presets, both artifacts, the sourceRecords provenance, via/fallbackReason badges, a synthetic label, and a trace deep link), and a seeded assemble→summarize (scripted-fallback) trace, the console subtitle, and the investor brief (now 'twenty-two agents across three planes', with the Clinical Summary agent on the patient/clinical plane) all reflect it. Frontend tests green (+ clinical-summary determinism/grounding-guard-true-and-false/live-Claude-success-via-mocked-SDK/SDK-error + missing-key fallback with fallbackReason, the route's envelope/governance-block-on-ungrounded-summary/model-allow-list/happy-path, the panel's request-body + view-lift, and the registry drift guards raised to twenty-two agents); both artifacts are clearly-labeled illustrative synthetics — a composition of already-synthetic records for two audiences that requires clinician review — NOT a certified clinical-documentation engine. Lint + build clean.

598796f agent fabric: add the Clinical Summary agent (after-visit summary + clinician handoff, the third live-Claude agent)

Agent Fabric: added the Prior Authorization agent — clinician-gated, documentation-complete PA assembly

Shipped
Details

Added the twenty-first agent on the fabric — prior-authorization-agent, the Salesforce 'Agentforce for Health' / Health Cloud CareRequest + Utilization Management analog — as a first-class clinical-plane agent that REUSES the Care Router / Care Plan clinical-decision governance tier (PA is a clinical / utilization decision). It is the HEAVIEST agent and, deliberately, the LEAST demo-honest of the set: real prior authorization is a genuinely multi-system X12 278 (or FHIR PAS / Da Vinci) EDI workflow against a payer's utilization-management system, so the mock is labeled especially clearly, and — per Salesforce's own guidance to do PA last — we did it last. In a new pure lib/prior-auth.ts a small catalog of PA-requiring menopause items (systemic HRT / compounded estradiol, a bone-density DEXA scan, and a specialized hormone lab panel), each carrying the payer medical-necessity criteria it must satisfy and its required supporting-documentation checklist, backs assemblePriorAuth(request), which DETERMINISTICALLY matches the criteria against the (synthetic) clinical context, assembles the required-documentation checklist (present vs missing), and returns a PriorAuthPackage — matched criteria (every one referencing a defined catalog id), documentation completeness, a synthetic Health Cloud CareRequest / authorization id (hashed from stable request keys — no randomness, no clock), a status (draft / ready-for-clinician / submitted / approved / denied), requiresClinicianApproval:true, submitted:false, and a source/provenance block marked synthetic:true. TWO load-bearing honesty properties are genuinely governance-enforced, each with its own NEW enforced-block policy + matching boolean signal wired into the shared governance-signals metadata: policy.pa.no-autonomous-submission (signal paHasClinicianApproval, violating value false) blocks a caller-asserted submit-without-clinician-approval — the agent may only assemble a clinician-gated draft, and a clinician must approve before submission; and policy.pa.documentation-integrity (signal paDocumentationComplete, violating value false) blocks a submission missing a required supporting document — assembling a DRAFT with missing docs is fine (it honestly lists what's outstanding), only a submission must be documentation-complete. The route sets both signals honestly from the domain (priorAuthHasClinicianApproval / priorAuthDocumentationComplete), and submitPriorAuth() refuses (throws) on either violation as defense in depth. It also reuses, by extending appliesTo, the no-prescribing, consent-before-grounding, and HIPAA-audit policies. A runnable A2A endpoint (POST /api/agents/prior-authorization/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — priorauth.criteria.match → priorauth.docs.assemble → priorauth.await-clinician (the human-approval gate; a clinician-approved + documentation-complete submit instead advances to priorauth.submit) — returning the PA package as an artifact with metadata.agentFabric carrying the trace ids and the two honesty signals, failed-task on a block) and a /.well-known/agent.json card whose policies derive from the registry round it out. As a standalone agent (downstream of the Care Plan / clinical decision) a seeded criteria-match→docs-assemble→await-clinician trace (drafted, not submitted), the console subtitle, and the investor brief (now 'twenty-one agents across three planes', with a Prior Authorization card noting it's the heaviest, deliberately-last workflow and the two new policies in the enforcement paragraph) all reflect it. Frontend tests green (+ prior-auth determinism/criteria-matching/documentation-completeness/clinician-gated-package-shape/off-catalog-rejection, the route's envelope/governance-block-for-both-policies/happy-path + submit, and the registry drift guards raised to twenty-one agents); the payer criteria + document checklists are clearly-labeled illustrative synthetics, NOT a certified utilization-management engine — and no PA assembled here is a real coverage determination or a real 278/EDI / payer PA portal submission. Lint + build clean.

397de6a agent fabric: add the Prior Authorization agent (clinician-gated, documentation-complete PA assembly)

Agent Fabric: added the Member Service / Billing agent — claim-sourced billing answers + human routing

Shipped
Details

Added the twentieth agent on the fabric — member-service-agent, the Salesforce 'Agentforce for Health' Claims & Coverage / patient-service analog — as a first-class, patient-facing self-service agent on the patient/clinical plane that REUSES the intake agent's patient-facing governance tier. It answers a member's BILLING & COVERAGE self-service questions — claim status, copay / patient responsibility, outstanding balance, and EOB explanation — grounded on the member's synthetic claim/EOB records, and routes anything out of scope (a clinical, prescription, or scheduling request) to a human member-services specialist with a PII-safe billing context bundle, keeping it scoped to billing/coverage self-service so it stays distinct from the Engagement Agent. In a new pure lib/member-service.ts a ClaimRecord model (claim id, date-of-service, provider, billed / allowed / plan-paid / patient-responsibility, and a submitted / adjudicated / paid / denied status) is generated DETERMINISTICALLY by hashing the member/claim key (FNV-1a) into realistic figures (billed $150–$1,025; allowed 55–70% of billed; member coinsurance 10–30%; dates counted back from a fixed anchor — no randomness, no clock), so the same member always yields the same claims. classifyIntent() maps a free-text question to one of the four in-scope billing intents or out-of-scope, and answerBillingQuestion(query, claims) returns a structured BillingAnswer that ALWAYS cites the specific ClaimRecord(s) it derived from (a source + citedClaims block, synthetic:true) plus a routeToHuman escalation path with a PII-safe context bundle when out of scope. The critical honesty property is that a billing/claim answer must trace to a synthetic claim/EOB record — the agent may NOT fabricate claim data. That is genuinely enforced by a NEW enforced-block policy, policy.billing.claim-data-sourced, with its matching boolean signal (billingTracesToClaim, violating value false) wired into the shared governance-signals metadata so evaluateGovernance() blocks a caller-asserted billing answer that cites no claim — the route sets the signal honestly from the domain's answerTracesToClaim() (a route-to-human handoff asserts no billing figure, so it is source-clean; an in-scope answer must cite a claim). It also reuses, by extending appliesTo, the no-free-text-pii policy (structured, claim-referenced answers only) and the HIPAA audit. A runnable A2A endpoint (POST /api/agents/member-service/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — billing.claim.lookup → billing.answer → an optional billing.route-to-human handoff — returning the answer + cited claims as an artifact with metadata.agentFabric carrying the trace ids, the intent, the cosign signal, and nextAgent on a handoff) and a /.well-known/agent.json card whose policies derive from the registry round it out. As a standalone patient-service node (not threaded into route-to-care-router) a seeded claim-lookup→answer→route-to-human trace, the console subtitle, and the investor brief (now 'twenty agents across three planes', with a Member Service / Billing card and the new policy in the enforcement paragraph, noting it's scoped to billing/coverage self-service) all reflect it. Frontend tests green (+ member-service determinism/claim-generation-ranges/every-answer-cites-a-claim/route-to-human-context-bundle/unsourced-rejection, the route's envelope/governance-block/happy-path + route-to-human, and the registry drift guards raised to twenty agents); the claim/EOB records are clearly-labeled illustrative synthetics, NOT a real claims / 835-ERA / payer system. Lint + build clean.

397de6a agent fabric: add the Member Service / Billing agent (claim-sourced billing answers + human routing)

Agent Fabric: added the Referral Management agent — clinician-cosigned outbound referrals

Shipped
Details

Added the nineteenth agent on the fabric — referral-management-agent, the Salesforce 'Agentforce for Health' Referrals ('Create Referral') analog — as a first-class care-coordination agent on the patient/clinical plane that REUSES the Scheduling agent's care-coordination governance tier. It GENERALIZES the Care Router's behavioral-health-handoff into a full outbound-referral node: rather than expressing a single handoff pathway, it triages a patient's intake + Care Router routing signals into referrals across the adjacent specialists menopause commonly touches — cardiology / CVD risk, endocrinology, bone health, pelvic-floor PT, and behavioral health. In a new pure lib/referrals.ts a small illustrative ReferralSpecialty catalog (each with an id, label, and typical trigger) backs triageReferrals(context), which DETERMINISTICALLY derives recommended referral(s) from age/cycle/symptom/severity/red-flag signals + explicit risk flags (red-flag mood → behavioral-health; osteoporosis / high-fracture-risk → bone-health; high cholesterol / CVD signals → cardiology; GSM / pelvic-floor dysfunction → pelvic-floor-PT; menopause-pattern symptoms under 40 → endocrinology for a POI workup) — no randomness, no clock — so the same context always yields the same recommendations. The load-bearing integrity property is that EVERY recommended referral references a defined specialty-catalog id AND carries a documented reason (never fabricated, never reasonless), and draftReferral(specialty, context) builds a referral request marked requiresClinicianCosign:true, status:'drafted', sent:false. The critical honesty property is that it can only DRAFT: an outbound referral requires a clinician's sign-off before it is sent — a human-in-the-loop clinical action. That is genuinely enforced by a NEW enforced-block policy, policy.referral.clinician-cosign, with its matching boolean signal (referralHasClinicianCosign, violating value false) wired into the shared governance-signals metadata so evaluateGovernance() blocks a caller-asserted send-without-cosign — the route sets the signal honestly from the domain's referralHasClinicianCosign(); a draft (or a clinician-cosigned send) passes. It also reuses, by extending appliesTo, the rationale-required policy (adapted so a referral must carry a documented reason) and the HIPAA audit. A runnable A2A endpoint (POST /api/agents/referral-management/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — referral.triage → per-referral referral.draft → a referral.await-cosign marker — returning recommendations + referrals as an artifact with metadata.agentFabric carrying the trace ids and the cosign signal) and a /.well-known/agent.json card whose policies derive from the registry round it out. As a standalone agent (it complements the Care Router; not threaded into route-to-care-router) a seeded triage→draft→await-cosign trace, the console subtitle, and the investor brief (now 'nineteen agents across three planes', with a Referral Management card and the new policy in the enforcement paragraph, noting it generalizes the behavioral-health handoff) all reflect it. Frontend tests green (+ referrals determinism/triage/catalog-integrity/off-catalog-rejection/cosign-signal, the route's envelope/governance-block/happy-path, and the registry drift guards raised to nineteen agents); the specialties + triage rules are clearly-labeled illustrative synthetics, NOT a certified clinical referral engine. Lint + build clean.

397de6a agent fabric: add the Referral Management agent (clinician-cosigned outbound referrals)

Agent Fabric: added the Medication Adherence agent — nudge-only HRT/SSRI adherence + refill prompts

Shipped
Details

Added the eighteenth agent on the fabric — medication-adherence-agent, the Salesforce 'Agentforce for Health' / Health Cloud MedicationRequest + MedicationTherapyReview analog — as a first-class, PROACTIVE patient-care agent on the patient-engagement tier (patient/clinical plane), a sibling of the Care Gap Closure agent. In a new pure lib/medication-adherence.ts it tracks menopause-medication adherence + refill timing across a small illustrative catalog — transdermal estradiol + oral micronized progesterone (HRT) and paroxetine (SSRI) / venlafaxine (SNRI) for vasomotor symptoms or mood, each with a days-supply — and DETERMINISTICALLY computes a good / at-risk / lapsed adherence status and a refill-due call from days-since-fill vs supply against an EXPLICIT as-of date (no randomness, no clock), so the same inputs always yield the same assessment. It drafts consent- and quiet-hours-aware refill/adherence NUDGES (draftAdherenceNudges) for each medication due or off-track, and flags adherence drop-off (a lapsed medication) to the care team. The load-bearing honesty property is that it can only NUDGE: every nudge is marked requiresHumanApproval:true, sent:false, nudgeOnly:true, and the agent must NEVER autonomously submit or order a refill — a refill is a clinical action that requires a human-in-the-loop. That is genuinely enforced: a NEW enforced-block policy, policy.medication.no-autonomous-refill, with its matching boolean signal (refillRequiresHumanApproval, violating value false) wired into the shared governance-signals metadata so evaluateGovernance() blocks a caller-asserted autonomous refill (a submit-refill without human approval) — the route sets the signal honestly from the domain's refillRequiresHumanApproval(), and an autonomous refill also trips the reused no-prescribing block (an autonomous refill is a clinical action committed without a clinician). It also reuses the engagement outreach guards extended onto the agent — contact-consent-required, human-approval-before-send, quiet-hours + channel preference, and the HIPAA audit. A runnable A2A endpoint (POST /api/agents/medication-adherence/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — medication.adherence.assess → per-med medication.nudge.draft → a medication.dropoff.flag routed to the care team → an engagement.outreach.handoff span attributed to the Engagement Agent — returning assessments + nudges as an artifact with metadata.agentFabric carrying the trace ids and nextAgent) and a /.well-known/agent.json card whose policies derive from the registry round it out. As a proactive agent it isn't threaded into route-to-care-router; a seeded assess→nudge→dropoff→engagement-handoff trace, the console subtitle, and the investor brief (now 'eighteen agents across three planes', with a Medication Adherence card and the new policy in the enforcement paragraph) all reflect it. Frontend tests green (+ medication-adherence determinism/status-computation/refill-due/nudge-shape/drop-off, the route's envelope/governance-block/happy-path + engagement-handoff, and the registry drift guards raised to eighteen agents); the medications + refill intervals are clearly-labeled illustrative synthetics, NOT a certified pharmacy / e-prescribing system. Lint + build clean.

397de6a agent fabric: add the Medication Adherence agent (nudge-only HRT/SSRI adherence + refill prompts)

Demo: front doors for the Scheduling, Care Gap, and Care Plan agents on the intake demo

Shipped
Details

The three newest agents (Appointment Scheduling, Care Gap Closure, Care Plan) shipped as runnable A2A endpoints but had no UI; this adds their front doors on /demo/intake, mounted after the Benefits panel as exact siblings of the Assessment and Benefits panels (five panels now read as one coherent set). All presentational + client-fetch only — no changes to any agent, domain logic, governance, or API route. components/scheduling-panel.tsx: book / reschedule presets plus BOTH governance blocks — policy.scheduling.no-double-book and policy.scheduling.honor-provider-availability (taken/open slots are derived from getProviderAvailability so the block presets are honest, not hard-coded) — rendering the confirmed slot, the synthetic ServiceAppointment provenance, and the engagement-reminder handoff (nextAgent = engagement-agent, drafted / quiet-hours-aware / human-approval-gated / never auto-sent). components/care-gap-panel.tsx: gap-detection presets (postmenopausal-on-HRT; perimenopausal with partial history, where an up-to-date mammogram is skipped while an overdue lipid panel surfaces) plus consent-required and off-catalog-gap (policy.caregap.clinical-measure-sourced) blocks, rendering per-gap cards (measure, status + priority, rationale, measure id) with their consent-/quiet-hours-aware, human-approval-gated outreach drafts, the grounding/integrity note, and the engagement handoff. components/care-plan-panel.tsx: template-selection presets (vasomotor / on-HRT / behavioral-mood) plus the policy.careplan.template-sourced block, rendering the instantiated plan (goals, interventions, follow-up cadence) and the summary with a green 'live Claude' vs amber 'scripted fallback' badge and, on fallback, the fallbackReason — both branches unit-tested (the sandbox with no ANTHROPIC_API_KEY renders the scripted-fallback branch; a keyed environment renders the claude-api branch). Every panel carries a deep link to the multi-agent trace and honest 'synthetic / illustrative / not a certified engine' framing. 1007 frontend tests green (+35: 11 scheduling, 11 care-gap, 13 care-plan), mirroring the repo's node-env panel-test style; lint + build clean.

9cf7231 demo: add Scheduling, Care Gap, and Care Plan panels to the intake demo

Agent Fabric: added the Care Plan agent — template-instantiated plan + live-Claude progress summary (second Claude agent)

Shipped
Details

Added the seventeenth agent on the fabric — care-plan-agent, the Salesforce 'Agentforce for Health' / Health Cloud CarePlan + care-plan-summarization analog — as a first-class clinical-plane sibling of the Care Router that REUSES the existing clinical-decision governance tier. Post-visit, it does two things in a new lib/care-plan.ts. First, instantiateCarePlan() DETERMINISTICALLY instantiates a menopause care plan from a defined template catalog — HRT-management, vasomotor/lifestyle, bone-health, and mood/behavioral, each with structured goals, interventions, and a follow-up cadence — selected from the Care Router's pathway/severity + intake with an explicit precedence order and a severity-adjusted cadence (no randomness, no clock), so the same context always yields the same plan and every plan references a defined template id. Second, summarizeCarePlan() is the SECOND live-Claude agent after the Care Router: it mirrors lib/care-router.ts EXACTLY — a dynamic @anthropic-ai/sdk import gated by ANTHROPIC_API_KEY, the same model + PAUSE_CARE_PLAN_MODEL override, a via: 'claude-api' | 'scripted-fallback' discriminator, and a non-clinical fallbackReason stamped on every fallback branch (missing key + any SDK error) — producing a concise, NON-PRESCRIPTIVE patient/clinician progress summary that falls back to a deterministic scripted summary. The honest core is governance: a NEW enforced-block policy, policy.careplan.template-sourced, with its matching boolean signal (planTracesToTemplate) wired into the shared governance-signals metadata so evaluateGovernance() genuinely blocks a caller-asserted off-template (fabricated) plan, PLUS the Care Router's model allow-list, no-prescribing, rationale-required, consent-before-grounding, and HIPAA-audit policies reused by extending appliesTo. A runnable A2A endpoint (POST /api/agents/care-plan/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate INCLUDING the model allow-list, real parented trace spans — careplan.instantiate (deterministic) → careplan.summarize (records via + a conditional fallbackReason attribute exactly like the Care Router route) — returning the plan + summary as an artifact with metadata.agentFabric) and a /.well-known/agent.json card whose policies derive from the registry round it out. It also threads into the spine the light way: POST /api/intake/route-to-care-router accepts an optional carePlan request and, after the Care Router hop, instantiates a plan and attaches a summary to the trace + response meta — additive, so absent = today's behavior unchanged. A seeded router→instantiate→summarize trace shows a deterministic scripted-fallback summary (so it never implies a live call happened at seed time), and the console subtitle + investor brief (now 'seventeen agents across three planes', with a Care Plan card noting it's the second live-Claude agent and the new policy in the enforcement paragraph) reflect it. Tests mirror care-router.test.ts (vi.mock('@anthropic-ai/sdk'): a mocked success yields via: claude-api; a mocked SDK error and the missing-key path both yield via: scripted-fallback WITH a fallbackReason), plus deterministic instantiation + template-integrity, the route's envelope/governance/block/model-allow-list/happy paths, and the registry drift guards raised to seventeen agents — none require a real ANTHROPIC_API_KEY. Lint + build clean.

7744ed4 agent fabric: add the Care Plan agent (template-instantiated plan + live-Claude progress summary)

Agent Fabric: added the Care Gap Closure agent — proactive, Data-360-grounded, clinical-measure-sourced

Shipped
Details

Added the sixteenth agent on the fabric — care-gap-closure-agent, the Salesforce 'Agentforce for Health' / Health Cloud care-gap-closure analog — as a first-class, PROACTIVE patient-care agent on the patient/clinical plane (its own NEW care-gap governance tier). Unlike the reactive intake→router spine, it grounds on the patient's Data 360 context + age/cycle/symptom signals and DETERMINISTICALLY detects menopause-relevant preventive-care gaps in a new pure lib/care-gaps.ts: a small catalog of illustrative clinical measures (bone-density/DEXA for osteoporosis risk, lipid panel, screening mammogram, HRT follow-up visit — each with an id, label, guideline/rationale, and recommended interval), the CareGap type (referencing a clinical-measure catalog id, open/overdue status, dueSince/lastDone, priority), and detectCareGaps(context) that derives gaps against an EXPLICIT as-of date (no randomness, no clock) so the same context always yields the same gaps. The load-bearing property is integrity, not clinical authority: every detected gap references a defined clinical-measure catalog id — never a fabricated one — and the clinical measures + intervals are clearly-labeled illustrative synthetics, NOT a certified guideline engine. It also drafts consent- and quiet-hours-aware outreach per gap (draftGapOutreach), always human-approval-gated and never auto-sent, for handoff to the Engagement Agent. The honest core is governance: a NEW enforced-block policy, policy.caregap.clinical-measure-sourced, with its matching boolean signal (gapsTraceToClinicalMeasure) wired into the shared governance-signals metadata so evaluateGovernance() genuinely blocks a caller-asserted off-catalog gap (the drift guards would have failed otherwise), plus the reused engagement/outreach guards extended onto the agent — contact-consent-required, human-approval-before-send, quiet-hours + channel preference, consent-before-grounding, and the HIPAA audit. A runnable A2A endpoint (POST /api/agents/care-gap-closure/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans — data360.grounding → caregap.detect → per-gap caregap.outreach.draft → an engagement.outreach.handoff span attributed to the Engagement Agent — returning detected gaps + drafts as an artifact with metadata.agentFabric carrying the trace ids and nextAgent) and a /.well-known/agent.json card whose policies derive from the registry round it out. As a proactive agent it isn't threaded into route-to-care-router; a seeded grounding→detect→draft→engagement-handoff trace, the console subtitle, and the investor brief (now 'sixteen agents across three planes', with a Care Gap Closure card and the new policy in the enforcement paragraph) all reflect it. Frontend tests green (+ care-gaps determinism/detection/catalog-integrity/outreach-consent/off-catalog-rejection, the route's envelope/governance/happy-path + engagement-handoff, and the registry drift guards raised to sixteen agents); lint + build clean.

7744ed4 agent fabric: add the Care Gap Closure agent (proactive, Data-360-grounded, clinical-measure-sourced)

Demo: gave the Benefits & Coverage Verification (EBV) agent a front door on the intake demo

Shipped
Details

The EBV agent shipped as a runnable A2A endpoint but had no UI; this adds its front door on /demo/intake, mounted directly under the Assessment panel and mirroring its look and honest framing. A new client component (components/benefits-panel.tsx) leads with one-click presets that each POST a coverage query to /api/agents/benefits-verification/tasks: an in-network plan with the deductible met (Aetna Choice PPO, $1,500 met, 20% coinsurance on a $420 visit → ~$84 patient responsibility); a high-deductible plan not yet met (UnitedHealthcare Saver HDHP, $0 of $6,000 met → the full $260 visit lands on the patient); self-pay / no active coverage (inactive, but still a sourced no-active-coverage EBV response); and a caller-asserted coverage object with no source that trips policy.benefits.eligibility-source-integrity so the governance block renders in the UI (blocking policy + reason + policies evaluated). A tidy 'build your own query' affordance (payer / member id / ZIP / service type) rounds it out. Results render the plan name + eligibility/network status pills, deductible met/total/remaining, cost share (copay or coinsurance %), estimated visit cost and estimated patient responsibility, and a labeled SYNTHETIC payer/clearinghouse provenance block (payer, clearinghouse, transaction type/id, response code, honesty note) so the mock nature of the EBV round-trip is explicit. A deep link (Open the multi-agent trace →) jumps to /demo/agent-fabric?taskId=<id>, and an optional 'Carry this coverage into the Care Router →' follow-on POSTs the query to /api/intake/route-to-care-router and shows the returned pathway + acuity, noting the routing was preceded by a verified coverage check. Presentational + client-fetch only — no changes to the agent, domain logic, governance, or API routes. 911 frontend tests green (+14, mirroring the repo's node-env panel-test style); lint + build clean.

5ecff9d demo: add the Benefits & Coverage Verification (EBV) panel to the intake demo

Agent Fabric: added the Appointment Scheduling agent — closes the intake→routing→booking loop

Shipped
Details

Added the fifteenth agent on the fabric — appointment-scheduling-agent, the Salesforce 'Agentforce for Health — Book/Reschedule/Update Appointment' analog — as a first-class care-coordination agent on the patient/clinical plane (its own NEW care-coordination governance tier). It books (and can reschedule) the MSCP menopause-specialist visit the Care Router recommends, honoring the requested modality (telehealth / in-person) against a deterministic synthetic provider availability calendar, and returns a structured AppointmentBooking in a new pure lib/scheduling.ts: a synthetic Salesforce ServiceAppointment id, the confirmed slot start/end, modality, provider, status (booked / rescheduled), and a source provenance block marked synthetic:true. It is DETERMINISTIC on its inputs — getProviderAvailability() hashes providerId + date + slot index into a stable set of 30-minute business-hours slots (09:00–16:30, weekdays only), ~a third pre-'booked', each offered in telehealth and/or in-person, with no randomness and no clock — so the same provider + date always produces the same calendar, and it is clearly NOT a real Salesforce Scheduler / ServiceAppointment write. The honest core is governance: TWO NEW enforced-block policies with matching boolean signals wired into the shared governance-signals metadata so evaluateGovernance() genuinely blocks — policy.scheduling.no-double-book (signal requestedSlotIsFree; the scheduler refuses an already-taken slot) and policy.scheduling.honor-provider-availability (signal slotWithinProviderAvailability; the scheduler refuses a time outside the provider's published availability for the modality) — set honestly by the route from the domain layer's checks, with bookAppointment() also throwing on either violation as defense in depth; plus the reused HIPAA-audit policy extended onto the agent. A runnable A2A endpoint (POST /api/agents/appointment-scheduling/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans, and a handoff span to the Engagement Agent for reminders) and a /.well-known/agent.json card whose policies derive from the registry round it out. It wires into the existing spine the light way: POST /api/intake/route-to-care-router now accepts an optional scheduling request and, when the routing decision recommends MSCP provider(s), books the top recommendation (modality defaulted from the pathway) and attaches the booking summary to the trace + response meta after the Care Router hop — additive, so absent = today's behavior unchanged. A seeded care-router→booking→engagement trace, the console subtitle, and the investor brief (now 'fifteen agents across three planes', with an Appointment Scheduling card and the two new policies in the enforcement paragraph) all reflect the closed loop: acquisition → intake → routing → booking → engagement. Frontend tests green (+ scheduling determinism/availability/no-double-book/honor-availability/reschedule/source-provenance, the route's envelope/governance/happy-path + engagement-handoff, and the registry drift guards raised to fifteen agents); lint + build clean.

7908fc4 agent fabric: add the Appointment Scheduling agent (intake→routing→booking→engagement)

Agent Fabric: added the Benefits & Coverage Verification (EBV) agent

Shipped
Details

Added the fourteenth agent on the fabric — benefits-verification-agent, the Salesforce 'Agentforce for Health — Eligibility & Benefit Verification' analog — as a first-class patient-access agent on the patient/clinical plane (its own new benefits-verification governance tier). It verifies a patient's insurance coverage for a menopause specialist (MSCP) visit and returns a structured, DEMO-HONEST synthetic eligibility result in a new pure lib/benefits.ts: plan status (active/inactive), in/out-of-network, deductible + amount met + remaining, coinsurance/copay, and an estimated visit cost + patient out-of-pocket, plus a source provenance block naming a MOCK payer/clearinghouse and a synthetic EBV transaction id. It is DETERMINISTIC on its inputs — the member/plan string is hashed to pick a plausible-but-fake plan profile (deductible $1,500–$6,000, coinsurance 10–30%, visit $180–$420, $500-increment amount-met), with no randomness and no clock — and it is clearly NOT a real 270/271 EDI transaction or FHIR CoverageEligibilityResponse; a known-payer allow-list (Aetna, BCBS, Cigna, UnitedHealthcare, Kaiser in-network; Humana/Medicare and unrecognized payers out-of-network; self-pay → inactive) drives the network logic. The honest core is governance: a NEW enforced-block policy, policy.benefits.eligibility-source-integrity, with its matching boolean signal (eligibilityTracesToSource) wired into the shared governance-signals metadata so evaluateGovernance() genuinely blocks a returned coverage result that doesn't trace to a payer/clearinghouse EBV response — the agent may not fabricate coverage without a source — plus the reused consent-before-grounding and HIPAA-audit policies extended onto the agent. A runnable A2A endpoint (POST /api/agents/benefits-verification/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans) and a /.well-known/agent.json card whose policies derive from the registry round it out. It wires into the existing spine the light way: POST /api/intake/route-to-care-router now runs a coverage check when the intake carries patientInsurance (or an explicit coverageQuery) and attaches the eligibility summary to the trace + response meta before the Care Router hop — additive, so absent = today's behavior unchanged. A seeded coverage→intake→routing trace, the console subtitle, and the investor brief (now 'fourteen agents across three planes', with a Benefits & Coverage Verification card and the new policy in the enforcement paragraph) all reflect it. Frontend tests green (+ benefits scoring/range/network/source-provenance/allow-list determinism, the route's envelope/governance/happy paths, and the registry drift guards raised to fourteen agents); lint + build clean.

4ea4212 agent fabric: add the Benefits & Coverage Verification (EBV) agent

Demo: gave the Assessment Agent a front door on the intake demo

Shipped
Details

The Assessment Agent shipped as a runnable A2A endpoint but had no UI; this adds its front door on /demo/intake, mirroring the acquisition-funnel panel's look and honest framing. A new client component (components/assessment-panel.tsx) leads with one-click presets that each POST a valid response vector to /api/agents/assessment/tasks: a moderate PHQ-9; a PHQ-9 whose item-9 (self-harm) red flag escalates intake severity to severe even though the total band stays moderate — the escalation gap made visible; a severe multi-domain MRS with per-domain subscore bands; and an off-allow-list GAD-7 that trips policy.assessment.validated-instrument-only so the governance block renders in the UI (blocking policy + reason + policies evaluated). A 'build your own responses' toggle reveals the four-instrument picker and compact per-item segmented 0..max controls (Greene's 21 items gated behind the toggle so the default view stays tidy). Results render the instrument name, total/maxTotal · band, normalized + intake-severity pills, subscore bands, and a calm role=note 'safety escalation' callout for red flags, plus a deep link (Open the multi-agent trace →) to /demo/agent-fabric?taskId=<id>. An optional 'Carry this score into the Care Router →' follow-on POSTs the assessment to /api/intake/route-to-care-router and shows the returned pathway + acuity, noting when severity was assessment-driven. Presentational + client-fetch only — no changes to the agent, domain logic, governance, or API routes. 836 frontend tests green (+11, mirroring the repo's node-env panel-test style); lint + build clean.

7a02f9d demo: add the Assessment Agent panel to the intake demo

UI: layered surface tokens + a restrained sans-serif polish pass (no display serif)

Shipped
Details

A cohesive, presentational-only polish of the shared design language — done entirely in globals.css, with all text staying on Inter (an earlier pass that introduced a Fraunces display serif was rejected, so this one adds no serif/display typeface at all). The load-bearing part is a real bug fix: --surface-2 and --surface-3 were referenced by page.tsx, the roadmap, and the changelog itself but were never defined, so those raised panels and borders silently resolved to nothing. This defines a proper layered surface scale (bg → surface → surface-2 → surface-3) plus --line-strong / --brand-soft and a radius scale, so those planes finally read as distinct depths. On top of that: tighter heading letter-spacing with balanced heading wrap and pretty paragraph wrap, tabular + lining figures on stat/metric values so number columns stop jittering, a comfortable hero measure and 1.6 body line-height (elegance through weight/size/spacing, not a new face); softer layered card shadows where only interactive a.card/button.card earn a 2px lift + brand-tinted border on hover; refined button hover/active/:focus-visible states; and — the one deliberate accessibility call — primary button text moved to dark plum on the pink brand, lifting contrast from ~2.8:1 (failing) to ~6:1 (WCAG AA). Rounded out with a crisper sticky nav (blur+saturate + hairline highlight), a softened hero glow, and a site-wide prefers-reduced-motion safeguard. No content, routes, component APIs, or logic changed; 825 tests still green, lint + build clean.

ecb3a88 ui: define layered surface tokens + restrained sans-serif polish pass

Agent Fabric: added the Assessment Agent — validated-instrument scoring feeds intake severity

Shipped
Details

Added the thirteenth agent on the fabric — assessment-agent, the Salesforce 'Agentforce for Health — Assessments' analog — as a first-class patient-facing agent on the patient/clinical plane. It administers and DETERMINISTICALLY scores an allow-listed set of validated instruments (Menopause Rating Scale, Greene Climacteric Scale, PHQ-9, Insomnia Severity Index) in a new pure lib/assessments.ts: real cutoff-based math, no LLM, producing per-instrument subscores, a total, and a severity band normalized onto intake's mild/moderate/severe vocabulary. Cutoffs are faithful to each instrument's published scoring (PHQ-9 0-4/5-9/10-14/15-19/20-27; ISI 0-7/8-14/15-21/22-28; MRS 0-4/5-8/9-16/17+ plus the published subscale cutoffs); the Greene scale has no agreed total-score band, so its three total cutoffs are marked // inferred. Red-flag items are handled explicitly — PHQ-9 item 9 (self-harm ideation) on any non-zero response escalates as its own trace span and forces the intake severity to severe regardless of band. The honest core of the change is governance: a NEW enforced-block policy, policy.assessment.validated-instrument-only, with its matching boolean signal wired into the shared governance-signals metadata so evaluateGovernance() genuinely blocks any instrument off the allow-list (the drift guards would have failed otherwise), plus the reused no-free-text-PII, red-flag-mandatory, and HIPAA-audit policies extended onto the agent. A runnable A2A endpoint (POST /api/agents/assessment/tasks, JSON-RPC tasks/send validated with parseTasksSendEnvelope, a pre-flight governance gate, real parented trace spans) and a /.well-known/agent.json card whose policies derive from the registry round it out. The result wires into the existing spine the light way: POST /api/intake/route-to-care-router now accepts an optional assessment, and when present the scored severity drives IntakeRecord.severity (and the red-flag screen) before the Care Router hop — a real instrument score behind the routing decision instead of a self-report — additive, so absent = today's behavior unchanged. A seeded assessment→intake→routing trace, the console subtitle, and the investor brief (now 'thirteen agents across three planes', with an Assessment Agent card and the new policy in the enforcement paragraph) all reflect it. 825 frontend tests green (+32: instrument scoring correctness, band cutoffs, red-flag handling, allow-list rejection, the route's envelope/governance/happy paths, and the registry drift guards); lint + build clean.

9d07a69 agent fabric: add the Assessment Agent (validated-instrument scoring → intake severity)

Home: promoted the Care Router card to a “live” status pill

Shipped
Details

With the Care Router's live Claude Sonnet 4.5 path confirmed working in production (provider: anthropic / via: claude-api), the homepage's 'Anthropic-backed Care Router agent' card graduated from 'partial' to a new, distinct 'live' status. Added a `live` variant to StatusPillStatus (label 'Today · live', rendered TODAY · LIVE) backed by a saturated emerald --live tone in globals.css — visually distinct from the mint tone that prototype/partial share, so 'genuinely live in production' reads at a glance while the graceful scripted fallback still exists. Purely additive: audited every StatusPill consumer (homepage, changelog, ~25 proposal/marketing pages) and none needed changes. 793 frontend tests green; lint + build clean.

dd435cc home: promote the Care Router card to a “live” status pill

Intake: routed a completed Agentforce chat intake to the Care Router

Shipped
Details

The live Agentforce Embedded Messaging chat on /demo/intake never handed off to the Pause Care Router. Because the V2 SDK exposes no dependable end-of-conversation event on this deployment (only onEmbeddedMessagingReady / onEmbeddedMessagingInitError are confirmed to fire — trusting an unverified 'closed' event would repeat the prechatAPI no-op-Proxy mistake), a new <ChatToCareRouterHandoff/> renders an explicit 'Complete intake → route to Care Router' affordance beneath the chat. It POSTs the selected persona's deterministic intake to the existing /api/intake/route-to-care-router handoff and renders the live decision inline (pathway, acuity, provider/model/via, and any fallbackReason) with a deep link to the multi-agent trace. An optional origin — sanitized to a strict ^[a-z0-9-]{1,40}$ slug so no free text or PHI leaks — is threaded through the handoff and stamped on every span in the parented tree (intake → Data 360 identity/grounding → care-router → mcp-bridge), so the chat-originated route reads origin=agentforce-chat and stays one continuous task in the viewer, distinct from the /demo/routing button. 793 frontend tests green (+7); lint + build clean.

b10054f intake: route completed agentforce chat intake to the care router

Care Router: hardened the Claude response parsing and surfaced the fallback reason

Shipped
Details

Once the production key was live, the Care Router's Claude call was firing (a ~6s span, vs ~250ms when the key was absent) but still landing on the deterministic fallback: the model wraps its JSON in markdown fences or a lead-in sentence, so a bare JSON.parse threw and the catch swallowed it — and the 800-token cap risked truncating the JSON outright. Added extractJsonObject() to strip code fences and pull the first balanced {…} object, normalized the returned pathway, and raised max_tokens to 1500. Crucially, the scripted-fallback path now records a non-clinical fallbackReason attribute on the care-router trace span (the leading 'Claude API call failed (…)' / 'ANTHROPIC_API_KEY not set…' sentence only — no patient text), present only on fallback and absent on a live claude-api success, so a fallback's cause is visible in the Agent Fabric trace viewer instead of invisible. Verified live on production: the care-router span now reads provider=anthropic / via=claude-api with no fallbackReason. 786 frontend tests green; lint + build clean.

a217be1 care router: harden Claude response parsing + surface fallback reason

Week of July 5, 2026

The acquisition funnel gets wired into the intake agent

The patient-acquisition agents — Inbound Lead Generation, Qualification, and Prospecting & Nurture — were registry seeds with illustrative traces. This week they became runnable A2A endpoints that actually hand off down the funnel and into the existing Intake → Care Router flow, as one governed, traced pipeline you can fire from the intake demo.

Intake: added osteoporosis and high cholesterol as menopause symptoms

Shipped
Details

Added 'Osteoporosis / bone density loss' and 'High cholesterol' to the scripted intake symptom picker (after weight gain), and added osteoporosis + high_cholesterol to the acquisition funnel's recognized-symptom set so leads flagging either still screen as in-ICP. Both route through the Care Router on the normal severity-based pathway — no red-flag special case. Tests + lint clean.

7a1fadc intake: add osteoporosis and high cholesterol as menopause symptoms

Intake: added weight gain as a perimenopause symptom

Shipped
Details

Added 'Weight gain / metabolism changes' to the scripted intake symptom picker (between vaginal/urinary symptoms and unexpected bleeding), and added weight_gain to the acquisition funnel's recognized-symptom set so a weight-gain lead still screens as in-ICP. It routes through the Care Router on the normal severity-based pathway — no red-flag special case. Tests + lint clean.

e2b28d8 intake: add weight gain as a perimenopause symptom

Agent Fabric: wired the acquisition funnel into the intake agent

Shipped
Details

Turned the Inbound Lead Generation, Qualification, and Prospecting & Nurture agents from registry-only seeds into runnable Google A2A endpoints, each mirroring the Care Router contract (JSON-RPC tasks/send envelope, a pre-flight evaluateGovernance() gate, real parented Agent Fabric trace spans, and a /.well-known/agent.json card whose policies derive from the registry so it can't overclaim). POST /api/agents/inbound-lead/tasks captures a lead, runs the ICP screen, resolves identity against Data 360, and hands off — enforcing explicit-opt-in+source and identity-resolution-before-create. POST /api/agents/qualification/tasks returns a qualified/disqualified decision with a route (intake | nurture | none) and a mandatory rationale, never touching a protected-class attribute; disqualifications emit a human-review span. POST /api/agents/prospecting/tasks drafts a consent-aware nurture touch that is always human-approval-required and never sent. A new orchestrator, POST /api/intake/acquisition-funnel, chains the hops over real A2A calls under a single taskId, threading each hop's span id as the next hop's parentSpanId so the whole funnel renders as one parented tree at /demo/agent-fabric — branching qualified-&-ready to Intake → Care Router, qualified-but-warming to Prospecting/Nurture, and disqualified to a logged dead-end, with any governance block short-circuiting as outcome:“blocked”. The scoring/branching rubric lives in a pure, deterministic lib/agent-funnel.ts (tuned so a consented lead can land in intake OR nurture), the A2A envelope validation was extracted into a shared parseTasksSendEnvelope, and the three agents' registry endpoints now point at the runnable routes. A new <AcquisitionFunnelPanel/> on /demo/intake runs four one-click scenarios (web-chat→intake, content-download→nurture, no-consent→blocked, out-of-ICP→disqualified) and deep-links to the resulting multi-agent trace. 770 frontend tests green (+25: the funnel rubric, all three routes' happy/blocked paths, and an end-to-end orchestrator test that stubs fetch to dispatch each hop through the real in-process handler); lint + build clean.

fd1df2f agent fabric: wire the acquisition funnel into the intake agent

Week of June 28, 2026

Governance & grounding honesty: agents, cards, and cohorts stop advertising what they don't enforce

A run of high-integrity fixes across the two highest-stakes surfaces. On Data 360, the cohort comparison's patientPercentile stopped posing as a live segment. On the Agent Fabric, the Care Router's governance policy list — hand-copied into the registry AND its public A2A Agent Card — had drifted from the policies the /tasks handler actually enforces (and even named a policy that doesn't exist); it now derives from a single source of truth so the discovery document can't overclaim.

Agent Fabric: added the MCP Bridge — the A2A ↔ MCP egress surface — as a first-class agent

Shipped
Details

Pause’s outbound MCP host already existed in code (lib/mcp/host.ts + provider-lookup.ts: the Care Router calling find_menopause_providers on external MCP servers, loopback-first with graceful fallback) but it wasn’t represented on the fabric, and live tool calls were only observable as attributes folded into the Care Router’s A2A span. Registered it as its own agent — mcp-bridge (new kind ‘mcp-bridge’, protocol mcp, integration tier on the platform plane) — the outbound complement to the inbound Pause MCP Server. Gave it three enforced-block policies that each map to real host.ts behavior (so they’re genuinely enforced, not advertised-only): a remote allow-list (only the same-origin loopback and remotes declared in PAUSE_MCP_HOST_REMOTES), an egress-side tool allow-list, and a no-cross-origin-bearer rule (an inbound bearer is forwarded only to the same-origin loopback, never to an external MCP server). All three are wired into the shared governance-signals metadata so evaluateGovernance() actually blocks on each, and the bridge is on the HIPAA audit policy since it brokers patient-context tool calls. For observability, the live Care Router route now emits each MCP host attempt as a first-class protocol:‘mcp’ span attributed to the bridge (parented to the A2A span) rather than only as A2A-span attributes, and a seeded trace shows the failover story end-to-end: an external partner remote errors with no bearer forwarded → the same-origin loopback succeeds → the Pause MCP Server executes the tool. Console subtitle and the investor brief updated to twelve agents across three planes (the brief gains a bridge card and the egress guards in its policy paragraph). The drift guards did their job throughout — the new block policies had to be given evaluator checks or the coverage test would have failed. 745 frontend tests green (+6); lint + build clean.

b512e43 agent fabric: add the MCP Bridge (A2A ↔ MCP egress) as a first-class surface

Investor brief: grouped the Agent Fabric page by plane to match the console (and fixed a stale count)

Shipped
Details

Made /proposal/agent-fabric tell the identical two-plane story the console now does. The brief had drifted: a flat agent grid tagged with raw tier slugs, a stale ‘Four agents, two open protocols’ title, and a Phase-0 line claiming ‘Ten agents registered’ while the registry actually holds eleven (the brief had silently omitted the Data 360 grounding agent that the console lists). Grouped the brief’s cards into the same three planes — Patient & clinical, Platform & data substrate, Commercial · PHI-separated — reading the shared lib/governance-tiers.ts single source of truth, so tiers render as friendly labels and each plane leads with the same PHI-boundary description as the console. Added the missing Data 360 grounding card (zero-copy federation, consent-before-grounding, allow-listed activation) so the brief enumerates the same eleven agents as the registry, and updated the title to ‘Eleven agents across three planes…’, plus the Phase-0 count and subtitle to match. The agents array is now typed to the GovernanceTier union, so a typo’d tier is a compile error rather than an unlabeled card. lint + build clean; 740 tests green.

33bfeef proposal/agent-fabric: group the brief by plane to match the console

Agent Fabric console: grouped the registry by plane so the PHI boundary is visible

Shipped
Details

The console listed all agents in one flat grid labeled with raw governanceTier slugs (‘commercial-operations’, ‘lead-qualification’, ‘data-grounding’) — which buried the two-plane story the rest of the product tells. Added a dependency-free lib/governance-tiers.ts as the single source of truth for the GovernanceTier union (now referenced directly by AgentRecord, so the union and its metadata can’t drift) plus each tier’s friendly label and the plane it belongs to. The registry now renders in three grouped sections — Patient & clinical plane, Platform & data substrate, and Commercial plane · PHI-separated — each with a heading, an agent count, and a one-line description that states the PHI boundary out loud (patient/clinical and commercial are the boundary; platform is the shared substrate serving the patient plane). Tiers show as labels, not slugs. Added an exhaustiveness guard: every registered agent’s tier must resolve to a known plane + non-empty label (and because the metadata is keyed on the GovernanceTier union, adding a tier without a label/plane is already a compile error). Pairs with the new Governance pre-flight panel directly below it. 740 frontend tests green (+1 guard); lint + build clean.

c8890f4 agent fabric console: group the registry by plane (PHI boundary visible)

Agent Fabric console: a Governance pre-flight panel for any agent + two more drift guards

Shipped
Details

Follow-on to making the block policies real: the /demo/agent-fabric console can now exercise that gate for EVERY agent, not just the Care Router. Extracted the task-signal metadata into a dependency-free lib/governance-signals.ts (GovernanceTask + BOOLEAN_BLOCK_SIGNALS) that both the server evaluator and the client console import, so the UI can't advertise a signal the gate doesn't actually check; evaluateGovernance() now generates its boolean block checks from that same list (the lone string+regex model allow-list check stays spelled out). The new 'Governance pre-flight' panel lets you pick any agent, see its enforced-block policies, toggle whether the inbound task would violate each one, and evaluate against the real /api/agent-fabric/governance/evaluate endpoint — rendering the allow/block decision, the applicable-policy count, and each blocking violation with its reason. Defaults to all-compliant (the gate only blocks on an explicitly-violating signal), with a one-click reset. Added two more drift guards: every seeded console trace span must name a registered agent (catches an orphaned or typo'd agentId in the illustrative traces), and the shared signal metadata must be well-formed and — together with the model policy — exactly equal the evaluable set, keeping the UI, the evaluator, and the policy catalog on a single source of truth. 739 frontend tests green (+2 guards +1 metadata check, and a metadata-driven refactor that left the existing evaluator tests untouched); lint + build clean.

b9dcfe6 agent fabric: governance pre-flight panel for any agent + drift guards

Agent Fabric: made every enforced-block policy actually evaluated (not advertised-only)

Shipped
Details

Closed a real advertised-vs-actual gap in the governance pre-flight. evaluateGovernance() only ever checked the Care Router's three signals (red-flag screen, model allow-list, rationale); every other policy marked enforcement:'block', status:'enforced' was displayed as an enforced block in the registry, the A2A Agent Card, and the /proposal narrative — but the evaluator never looked at it, so it could not fire. Refactored the evaluator into a per-policy check table: a shared GovernanceTask signal shape plus BLOCK_POLICY_CHECKS mapping each block policy id to a predicate, keeping the established 'fire only on an explicitly-violating signal, never on an absent one' convention so partial fixtures and the demo form don't trip a gate by omission. All 20 enforced-block policies are now wired across the intake, clinical, integration/MuleSoft, Data 360, patient-lifecycle, and commercial planes. Added a drift guard — evaluableBlockPolicyIds() plus two tests — asserting every enforced-block policy has an evaluator check and every check maps back to a real enforced-block policy, so the roster can't grow a new 'enforced' block that silently does nothing. The guard immediately paid for itself: it surfaced SEVEN pre-existing advertised-but-unevaluated blocks (no-free-text-pii, no-prescribing, mcp-tools-allowlisted, fhir-r5-only, and all three Data 360 policies — zero-copy-federation, consent-before-grounding, segment-activation-allowlist), all now genuinely enforced. The evaluate route reuses the shared GovernanceTask type so the HTTP contract can't drift from what the evaluator checks, with a route test pinning the new signals through the boundary. The live Care Router path is unchanged (it passes the same three fields; new signals default absent → allow). 737 frontend tests green (+13); lint + build clean.

3d48812 agent fabric: make every enforced-block policy actually evaluated

Agent Fabric: added Pipeline Management + Account Management — a PHI-separated commercial plane

Shipped
Details

Extended the fabric past the patient-care lifecycle into Pause's own B2B go-to-market with the two commercial Agentforce agents — Pipeline Management (works provider-organization / health-system / employer opportunities in Sales Cloud: stage progression, deal health, next-best-action, and committed/best-case/pipeline forecast roll-ups) and Account Management (post-close customer success: health scoring, renewal & QBR drafts, churn-risk and expansion signals). Both registered in lib/agent-fabric.ts as prototype Agentforce agents on a new commercial-operations governance tier. The honest heart of the change is plane separation: three commercial policies (derived from POLICIES[].appliesTo) — policy.commercial.no-phi-in-commercial-plane (block, both agents: the Sales Cloud commercial plane and the clinical/PHI plane are strictly separated, cross-plane reads blocked), policy.commercial.forecast-integrity (block, pipeline: every forecast figure must trace to a CRM opportunity record, no fabricated/inflated pipeline), and policy.commercial.human-owner-before-contract-change (block, account: no renewal/pricing/contract change without a human owner). Deliberately kept BOTH commercial agents OFF the HIPAA audit policy — an intentional honesty signal, asserted by a test: the commercial plane is not PHI-scoped, so it isn't on the HIPAA-named audit, whereas every clinical/patient-plane agent still is. Seeded a fourth illustrative trace (task-seed-commercial-001) on the commercial plane — pipeline.opportunity.review (at-risk) → pipeline.forecast.rollup (sourcedFromCrm:true) → pipeline.opportunity.close-won → account.onboard → account.renewal.draft (committed:false, humanOwnerApprovalRequired:true) — with EVERY span carrying phiAccessed:false, so the console shows the deal-to-customer arc while making the PHI boundary visible. Narrative synced: /proposal/agent-fabric now lists ten agents with the commercial pair framed as a separate PHI-separated plane, the commercial guards added to the policy paragraph, and the console + metadata enumerations updated. No autonomous send/commit path. 723 frontend tests green (+5: registration on the new tier, the PHI-separation block, the HIPAA-off honesty signal, the forecast/contract policy split, and the phiAccessed:false seeded-trace invariant); lint + build clean.

25a0117 agent fabric: add pipeline + account management (commercial plane)

Agent Fabric: added the Agentforce Qualification agent — the authoritative gate between acquisition and intake

Shipped
Details

Closed the funnel gap between acquisition and conversion. Both acquisition agents (Inbound Lead Generation and Prospecting & Nurture) were feeding intake with their own local notion of 'ready', so there was no single, explainable qualification step. The new Qualification agent is that gate: one consistent rubric (menopause-care fit + eligibility + expressed intent/readiness) applied to inbound and outbound leads alike, producing a qualified/disqualified decision with human-readable rationale, then routing qualified-and-ready leads to intake and qualified-but-warming ones back into nurture. Registered in lib/agent-fabric.ts as a prototype Agentforce agent on a new lead-qualification governance tier. To keep boundaries honest, reworded the Inbound agent's second capability from 'Qualifies visitors' to 'Runs a first-pass ICP screen' and pointed its handoff at Qualification (not straight to intake); the Prospecting agent likewise now hands a warmed prospect 'onward for qualification and intake'. Three qualification-specific governance policies, all derived from POLICIES[].appliesTo: policy.qualification.rationale-required (block — every decision, qualified or disqualified, carries rationale or is rejected), policy.qualification.no-protected-class-criteria (block — race/ethnicity/disability/etc. may never be qualification inputs; only care-fit, eligibility, consent, and intent), and policy.qualification.human-review-on-disqualify (audit — no lead is permanently excluded on an automated decision alone); it also inherits the HIPAA audit policy. Threaded qualification.decide into BOTH seeded traces so the gate is visible on either path: the inbound trace now runs capture → first-pass screen → identity.resolve → handoff → qualification.decide (score 84, protectedClassUsed:false) → intake, and the outbound growth trace inserts qualification.decide (score 88) between the final nurture touch and intake. Narrative synced across the /proposal/agent-fabric brief (now eight agents, with the qualification rubric in the policy paragraph) and the console + metadata enumerations. No autonomous send path. 718 frontend tests green (+4: registration on the new tier, the rationale/no-protected-class blocks + reviewable-disqualify audit, and the gate-before-intake ordering on both traces); lint + build clean.

a7bdcc5 agent fabric: add agentforce qualification agent

Agent Fabric: added the Agentforce Inbound Lead Generation agent — the inbound complement to outbound prospecting

Shipped
Details

Completed the top-of-funnel with the inbound acquisition path. Where the Prospecting & Nurture agent reaches OUT (Data 360 segments → outreach), the new Inbound Lead Generation agent handles interest coming IN: it captures a visitor from the marketing site, Agentforce web chat, or a symptom-check form; qualifies them against the menopause-care ICP (age band, symptom signals, geography/insurance fit) and scores readiness; creates an opt-in-consented Data 360 lead with acquisition-source attribution; and routes a ready lead straight to intake or a not-yet-ready lead into the nurture cadence — both over A2A. Registered in lib/agent-fabric.ts as a prototype Agentforce agent on the same patient-acquisition tier as prospecting (its outbound sibling). Two inbound-specific governance policies, both enforced blocks and both derived from POLICIES[].appliesTo: policy.lead.explicit-optin-and-source-required (a lead is only persisted with an explicit, timestamped opt-in and a recorded source — anonymous/un-consented captures are discarded at the boundary, never stored) and policy.lead.identity-resolution-before-create (every lead is resolved against Data 360 Identity Resolution before creation, so a returning patient or existing prospect is merged rather than duplicated); it also inherits the HIPAA audit-every-turn policy. Seeded a third illustrative trace (task-seed-inbound-lead-001) showing the inbound arc end-to-end — lead.capture (consentOptIn:true) → lead.qualify (icpMatch, leadScore 81, readiness ready) → lead.identity.resolve (matched:false → create) → lead.route.handoff (a2a, destination agentforce-intake) → intake.complete (convertedFromInboundLead:true) — so the /demo/agent-fabric console shows the capture-to-intake path on first load. Narrative kept in sync: the /proposal/agent-fabric brief lists all seven agents (the Phase-0 line now reads 'seven agents'), the two inbound guards join the policy paragraph, and the metadata/subtitle enumerations include inbound lead generation. No autonomous send path. 714 frontend tests green (+5: agent registration on the acquisition tier, the opt-in + identity-resolution blocks, exclusion of the outbound nurture/marketing policies, and the seeded-trace honesty invariants); lint + build clean.

d5965fe agent fabric: add agentforce inbound lead generation agent

Agent Fabric: expanded the Prospecting Agent into Prospecting & Nurture (lead scoring + multi-touch cadence)

Shipped
Details

Follow-up to the lifecycle-agents change, resolving a taxonomy gap: the Engagement Agent is a POST-conversion care-continuity agent (enrolled patients — check-ins, adherence), so lead nurturing (warming prospects who aren't ready to convert) had no home. Rather than overload the retention agent or add a third agent, expanded the top-of-funnel agent into a 'Prospecting & Nurture Agent' (v1.0.0 → v1.1.0). It now scores and warms leads across a multi-touch nurture cadence, advancing only prospects who engage, and drops a prospect from every active sequence the instant they convert, unsubscribe, or revoke consent. Added one nurture-specific governance policy — policy.marketing.nurture-cadence-cap (rate-limit, enforced): sequences are capped in length and cadence per rolling window, with convert/opt-out suppression baked in so there's no post-conversion nurture noise. It's prospecting-only (the enrolled-patient frequency cap stays on the Engagement Agent), and sends stay human-approval-gated via the existing human-approval-before-send block policy — the prototype still never messages a prospect autonomously. The seeded growth-lifecycle trace gained a prospect.nurture.advance span (touch 2, leadScore 72, sent:false) between the first outreach draft and conversion, and intake.complete now records nurtureTouches, so the /demo/agent-fabric console shows the warm-then-convert arc. Narrative kept in sync: the /proposal/agent-fabric brief renames the agent, reframes its role to 'Acquisition + lead nurture', and adds the cadence cap to the policy paragraph. 709 frontend tests green (+1: the cadence-cap policy is rate-limited + prospecting-only, and the seeded nurture span is scored, unsent, and approval-gated); lint + build clean.

3772205 agent fabric: expand prospecting agent into prospecting & nurture

Agent Fabric: added the Prospecting + Engagement agents — the patient-lifecycle agents that bracket the clinical core

Shipped
Details

Extended the multi-agent architecture beyond the clinical spine (intake → Care Router → MCP/MuleSoft) with the two Agentforce lifecycle agents that bracket it: a Prospecting Agent (top of funnel) that turns Data 360 population segments into consented prospect audiences, drafts consent-aware Marketing Cloud outreach for human review, and hands a qualified prospect to intake over A2A; and an Engagement Agent (post-routing) that picks up the Care Router's pathway output and schedules the follow-up cadence — check-ins and adherence nudges — honoring quiet-hours, channel preference, and frequency caps from Data 360. Both register in lib/agent-fabric.ts as prototype Agentforce agents (salesforce:// endpoints, like the intake agent) under two new governance tiers, patient-acquisition and patient-engagement. Governance is the honest core of the change: four new policies join the catalog and are DERIVED onto each agent from POLICIES[].appliesTo (the same single-source-of-truth path the rest of the fabric uses, so the registry, console, and any Agent Card can never disagree) — contact-consent-required (block: nobody without an active Data 360 contact consent enters an audience), human-approval-before-send (block: the prototype NEVER sends autonomously — every message is drafted for a human-in-the-loop), quiet-hours-and-channel-preference (block, engagement only), and frequency-cap (rate-limit, engagement only); both agents also inherit the HIPAA audit-every-turn policy. To make them tangible rather than static registry rows, seeded a second illustrative trace (task-seed-growth-lifecycle-001) that runs the full lifecycle in one correlated span tree — prospect.audience.qualify → prospect.outreach.draft (sent:false, humanApprovalRequired:true) → intake.complete (convertedFromProspect:true) → Care Router a2a.tasks/send → engagement.followup.schedule — so the /demo/agent-fabric console shows both agents in an actual trace on first load. Kept the investor narrative honest: the /proposal/agent-fabric brief now lists all six agents in lifecycle order (the stale 'four agents' framing is gone), the Phase-0 line reads 'six agents', and the policy paragraph dropped its brittle hardcoded 'twelve' count in favor of describing the catalog (which now includes the lifecycle guards). No runtime send path was added — the agents are wired and governed, and the one thing they will not do without a human is message a patient. 708 frontend tests green (+5, covering agent registration, the consent/approval gates, the engagement-only policies, and the seeded-trace honesty invariant); lint + build clean.

ff6562d agent fabric: add prospecting + engagement lifecycle agents + governance

Agentforce Voice: surfaced the voice entry point on the intake demo (fulfilling a written promise) + made the launch toast dismissible

Shipped
Details

Turned to the Agentforce Voice surface. The seam was already honest and well-built — lib/agentforce-voice.ts's env-driven {designed, prototype, shipped} state machine, the secret-omitting /api/agentforce/voice/config route, and the <AgentforceVoiceButton/> that degrades to a disabled 'designed' affordance on the public site. But two gaps stood out. First: both the /proposal/agentforce-voice page ('This is the same <AgentforceVoiceButton/> the intake demo WILL mount') and the component's own docstring ('The /about and /demo/intake pages can mount this in the marketing slot without any side effects') described the button living on the intake demo — yet it was only ever mounted on the proposal page. Delivered on that promise: mounted the button on /demo/intake in an 'Another way in' channel strip beneath the chat intake, with copy that keeps the honest framing (same agent, same subagents, same Data 360 grounding, same Care Router handoff — voice is the channel, not a different agent). On the public deployment (no env vars) it renders the disabled 'designed' pill + link to the activation plan, so it advertises the roadmap channel without claiming a capability the runtime can't prove. Second: a small but real UX bug — the post-click launch toast ('verification pending' in prototype, 'launching…' in shipped) was set once and never cleared, so it lingered on the page indefinitely with no way to dismiss it. Gave it a dismiss button (aria-labelled) and a 12s auto-clear, with the timeout tracked in a ref and torn down on unmount so no stray timer fires after navigation. Component testing tooling isn't wired in this package (vitest runs the node environment; no jsdom/testing-library), so this shipped as a scoped feature + UX fix rather than dragging in a new test toolchain. Build clean; no contract or API changes.

5bfe2b0 agentforce voice: mount button on intake demo + dismissible launch toast

Provider directory: a booking-relevant 'accepting new patients only' filter — the one patient-facing filter the search was missing

Shipped
Details

First feature work after a full live end-to-end verification pass (booted the app and drove the real intake→Data360→A2A→Agent-Fabric-trace flow, the provider search, and the MCP initialize handshake against the running server — everything green, including the secret-omission guarantees, so no fixes were needed). The /provider browse directory already exposed ZIP, insurance, MSCP-certified-only, relevant/telehealth fallback, and telehealth filters — but not panel status, which meant a patient (or an agent surfacing a recommendation) could be pointed at a provider whose panel is closed. Added an acceptingNewPatients filter to queryProviderDirectory, applied BEFORE the tier ladder alongside the insurance and telehealth filters so every tier (certified-local, relevant-local, certified-remote, certified-national) honors it rather than silently broadening past the patient's intent, and wired an 'Accepting new patients only' checkbox into the directory's filter form (with the Reset affordance updated to notice it). Deliberately scoped to the browse surface: the filter is NOT added to the agent-facing Experience API or the MCP tool, and it does NOT touch the echoed `query` object — so the API/MCP response shape and the Agentforce OAS contract stay byte-identical (verified: the OAS contract test still passes untouched). Five new tests pin the strict narrowing (open-panel total < unfiltered total; every returned row acceptingNewPatients=true), the before-the-ladder application, composition with the telehealth filter, and the response-shape invariant (no acceptingNewPatients key leaks into query). 703 frontend tests green (+5); build clean.

cffef36 provider directory: add 'accepting new patients only' filter

cli/ + mcp/ audit → covered the four pause CLI commands and guarded the standalone MCP package version (the last two untouched packages)

Shipped
Details

Turned the coverage/drift audit onto the two packages the session hadn't looked at: the standalone `pause` CLI and the published `@pause-health/mcp` stdio server. The mcp/ package turned out already well-defended — tools.parity.test.ts enforces byte-identity between mcp/src/tools.ts and the frontend's lib/mcp/tools.ts copy, so the provider-count and tool-surface guards added earlier this session cover the stdio transport transitively; and its tool LOGIC is exercised through the frontend's InMemoryTransport behavior tests against the byte-identical copy. server.ts is a thin stdio bootstrap (env → createPauseMcpServer → StdioServerTransport) with no meaningful unit seam. That left two real gaps. First: the CLI's lib/ (client, options) was tested but the four COMMANDS were not. Added commands.test.ts (+11) driving providers/timeline/intake/health with a stubbed global fetch and captured stdout — asserting query-string construction from flags (zip/menopause/limit/insurance/telehealth, and that absent flags are omitted), the --json branch emitting the raw payload vs the human summary (matchType, returned/total, distance formatting like '4.2mi'), the exactly-one-positional guards on timeline/intake, and patient-id URL-encoding into the path. Second: the standalone @pause-health/mcp package version in mcp/package.json had NO guard tying it to SERVER_VERSION (the value the server reports on the MCP initialize handshake). That string has drifted before — the build journal once advertised v0.2.0 while the code reported 0.3.0 — so a frontend-hosted parity guard (standalone-package-parity.test.ts) now binds mcp/package.json.version === SERVER_VERSION, failing loudly if a future bump touches one and not the other. Test-only; no runtime change. cli 28 pass (+11); frontend 698 pass (+1). Both untouched packages are now audited and the version-drift hole is closed.

aa3ec53 cli + mcp: cover the four pause commands + guard the standalone package version

Python ingest audit → a stale contract test had left provider_ingest RED; fixed it and covered centroids / mscp / FHIR (the untested pipeline modules)

Shipped
Details

Carried the coverage/drift hunt onto the Python side (the provider_ingest + pause_ingest pipelines that generate the committed directory + wearable artifacts). The audit's first finding was severe: the provider_ingest suite was RED. ProviderRecord had gained a credentialSource field — the provenance of the menopauseCertified flag, mirroring the TS ProviderRecord and BOTH OAS schemas (curated-overlay = authoritative MSCP roster; self-reported = a self-reported token in NPPES credential text) — but test_record_shape_matches_contract, the guard whose entire job is to fail when the record shape drifts from the frozen cross-language contract, was never updated to include it. So the guard had silently rotted into a failing test that nobody had reconciled. Fixed the expected key set AND strengthened it with a semantics invariant (credentialSource is None exactly when a provider is not certified, else one of the two allowed provenances) so it now pins meaning, not just presence. Then closed the untested pipeline modules (+27 tests). centroids.py — the ZIP→(lat,lng) lookup that powers the directory's distance-first ranking — was entirely untested: added coverage for the Census-Gazetteer parsing edge cases (malformed GEOID rows, unparseable coordinates, and the stray-trailing-whitespace INTPTLONG column header the real file actually ships with), the write/load round-trip and its 6-decimal rounding + key-sort contract, the missing-file → empty-map fallback that keeps a sparse checkout from erroring, a bundled-map sanity check, and the regen CLI. mscp.py — the MSCP overlay loader that is the sole source of the certified flag — now pins that it accepts either a bare NPI list or {"npis":[...]}, coerces JSON-numeric NPIs to strings (so they still match the string NPI on a record), and trims/drops blanks on both the load and query sides. fhir.py — the OMH→FHIR R5 Observation wrappers the uploader POSTs to JupyterHealth Exchange, ~220 lines untested — now covers the raw path (OMH payload preserved verbatim through the base64 valueAttachment round-trip, schema code derived from the OMH header with safe omh:unknown:0 defaults, effective-time precedence body→header→now) and the derived-HRV path (dataclass/dict duck-typing with a TypeError guard, the private pause-derived schema, derivedFrom back-pointers, and the FHIR R5 rule that an Observation carries effectiveDateTime XOR effectivePeriod, never both). Test-only apart from the one stale-assertion fix. provider_ingest 98 pass (was 84 + red); pause_ingest 108 pass / 7 skipped.

34f4d1d python: fix stale provider contract test + cover centroids/mscp/fhir

Coverage audit → the last four untested API routes get tests (intake orchestration, prechat-context, voice-config secret-omission, fabric registry)

Shipped
Details

Ran an objective coverage/drift audit across the frontend instead of guessing the next gap: enumerated all 28 app/api route handlers and every lib module. Result — 24/28 routes had co-located tests, every logic-bearing lib had a test (only static data/config like zip-centroids / site / page-metadata / menopause-society don't, and aren't worth pinning), and no NEW advertised-vs-actual drift surfaced beyond what the existing parity guards already cover. The audit's finding was four untested routes; this closes all four (+18). intake/route-to-care-router (5) — the most logic-dense route in the app and the main A2A handoff (Agentforce intake → Data 360 identity → federated grounding → Care Router): 400 JSON guard; the happy path with SF unset (mock identity+grounding) posting an A2A tasks/send to the origin-derived care-router URL and lifting the decision out of the returned artifact's data part (fetch stubbed at the boundary, no live server); the multi-agent trace — intake.complete + data360.identity.resolve + data360.grounding.federated-query spans all recorded under one taskId with the grounding span honestly reporting _source:"mock"; optional personaId threaded onto every span; and the 502 path where an A2A transport failure records an a2a.tasks/send.transport-error span (status:error) instead of throwing. intake/prechat-context (6) — the closed-list persona guard (400 missing / 404 unknown), the string-ONLY hidden-prechat field bag every value clamped ≤255 chars (Salesforce's channel hard cap), the Patient_Percentile_Basis honesty marker reading "intake-estimate", the deliberate omission of the ~1.4KB Patient_Context_JSON from the in-band payload, and no-store. agentforce/voice/config (3) — the SECURITY invariant on a public route: it reports designed/prototype/shipped for the client button but the serialized response NEVER contains baseUrl or deploymentRef (partner-side identifiers a third party could use to open a CCaaS session) — asserted by string-scanning the whole body for both keys and their secret values. agent-fabric/agents (4) — the registry listing IS listAgents() with a derived _agentCount and the discovery fields (protocol/version/policies) the console renders. Test-only; no runtime change. 697 frontend tests green (+18); build clean. This closes the frontend route-coverage gap end to end.

cd54426 routes: test the last four untested API handlers (intake/voice/fabric)

Data 360 routes & mock: first co-located route tests for the whole federated-read surface (four routes, zero before this) + the real→mock fallback

Shipped
Details

Closing the last flagged coverage gap on Data 360. The four routes under /api/data-360/* — segments, patient/[id]/record, patient/[id]/grounding, identity/resolve — had NO route tests, and lib/data-360.ts's mock helpers (getFederatedRecord, resolveIdentity, listSegments) were only ever touched indirectly through the Care Router. Two of the four routes are dual-mode (real Salesforce org preferred, deterministic mock fallback) and NEITHER had a test proving the fallback actually degrades instead of 500ing. Added co-located route tests + a mock unit test (+20). lib/data-360.test.ts (7): listSegments returns a defensive copy (mutating the result can't corrupt the catalog); resolveIdentity echoes the demo id with confidence 0.97 + the v3 IR ruleset; getFederatedRecord keys the record to the requested id, carries only granted consents, and attaches a bounded two-segment subset whose ids are real catalog entries. segments route (3): meta._segmentCount and _totalPatients are DERIVED from listSegments rather than hardcoded, so they can't drift; cacheable header. record route (4): record echoes the requested id, meta reports requested-vs-demo id, empty path segment falls back to the demo id, cacheable header. grounding route (6): mock path reports _source:"mock" + _salesforceConfigured:false with the cacheable header AND — the load-bearing one — the real→mock fallback (SF_* set, fetch stubbed to throw) degrades to _source:"mock" without 500ing, while _salesforceConfigured reports true (it reflects env, not the served source) and the cache header follows the SOURCE not the config. identity route (3): 400 on invalid JSON, mock resolution to the demo id with no-store, and the same real→mock degrade proven not to 500. Test-only; no runtime change. 679 frontend tests green (+20); build clean.

6ab700d data-360: route tests for all four routes + mock unit test (incl. real→mock fallback)

Data 360 grounding: the Phase-2 provenance label overclaimed live Data Cloud CIs when the org returned no wearable rows

Shipped
Details

Carrying the advertised-vs-actual drift hunt onto the Salesforce grounding layer that feeds the Care Router. lib/salesforce/grounding.ts stamps every GroundingContext with a groundingProvenance block — federatedQuery ("Phase 1: SOQL ..." vs "Phase 2: ... Data Cloud Calculated Insights (HRV/vasomotor/sleep)") and sourcesQueried — that the Agent Fabric trace surfaces so a reviewer can see which parts of the grounding came from the real org vs the intake baseline. The bug: that label branched on whether the `wearable` object was truthy. But getWearableInsights (data-cloud.ts) returns a NON-null { hrv, vasomotor, sleep } object whenever Data Cloud is merely configured — each field is independently null when its Calculated Insight returns no rows (only unconfigured/error returns null). So an org with Data Cloud wired up but no CI rows for a given patient produced provenance that advertised "Data Cloud Calculated Insights (HRV/vasomotor/sleep)" and listed dbdp-wearable-features + jupyterhealth-fhir as queried — while every one of those insights had actually fallen back to the intake baseline (vasomotor/sleep via `?? {intake}`, HRV omitted). The trace claimed Phase-2 federation that never fired. Fix: provenance now keys on whether any CI actually returned data and names ONLY the live ones — all-null wearable reports Phase 1 with base sources; a single live CI reads "Data Cloud Calculated Insights (vasomotor)" and adds only the sources that CI genuinely carries (union of the live insights' federatedFrom, so jupyterhealth-fhir doesn't appear unless an HRV/sleep CI actually returned). buildGroundingContext is now exported and pinned by grounding.provenance.test.ts (+5): wearable=null → Phase 1; all-null object → Phase 1 (the regression, NOT Phase 2, no DC sources); single-live → named + scoped sources; all-live → full label + unioned sources with base sources un-duplicated; computedInsightsCount stays in step. The mock path (data-360.ts) was already honest via `basis: "intake-estimate"`; this aligns the real path. 659 frontend tests green (+5); build clean.

d3a5d87 data-360: stop grounding provenance claiming Phase-2 CIs that returned no rows + pin it

Salesforce Headless 360: first route-level coverage of the entire OAuth PKCE seam — six endpoints, zero tests before this

Shipped
Details

The Headless 360 LIBRARY (salesforce-headless360.ts — config, PKCE, cookie signing, validateMcpApiBearer + its introspect/userinfo/cache paths) was already deeply unit-tested, but the six ROUTES that wire it into the actual OAuth flow under /api/salesforce/headless-360/* had NO tests at all — including the two most security-load-bearing steps in the whole surface: the PKCE authorize kickoff and the CSRF-guarded callback. Added co-located route tests for all six (+33). authorize (7): 503 when unprovisioned; a 302 to Salesforce /services/oauth2/authorize carrying response_type=code + client_id + redirect_uri + scope + state + code_challenge_method=S256; the pending cookie set with the hardened flags (HttpOnly, Secure, SameSite=Lax, Path=/, Max-Age=90); a binding check that the state in the signed cookie equals the state sent upstream AND that the redirect's code_challenge is exactly S256(the cookie's verifier); and open-redirect defense (?next=https://evil and ?next=//evil both collapse to '/'). callback (10): the CSRF core — a returned state that doesn't match the signed cookie's state is refused 400 state-mismatch and the token endpoint is NEVER contacted; a missing or tampered pending cookie is refused; a Salesforce ?error is propagated 400 and clears pending; the happy path exchanges the code (presenting the cookie's code_verifier), sets a session cookie that decodes back to the exchanged tokens, clears pending, and 302s to the post-login path; a signed-but-protocol-relative post-login path is still refused off-site (defense in depth → '/'); and upstream failure / missing access_token both surface 502. me (5): the session-state ladder — 503 unprovisioned, 401 not-signed-in, 401 session-expired past expiry, 200 with identity on a live session, and a userinfo failure degrading into user._userinfo_error without breaking the shape. token/refresh (7): 401 with no session / no refresh token; success mints a new access token INTO the cookie and never into the body; a non-rotated refresh token is preserved; a rejected refresh clears the session cookie and returns 502. config (3): the only route that answers unprovisioned, reporting designed/prototype without ever leaking the client id, secret, or Salesforce base URL. logout (1): clears both cookies with Max-Age=0 and the hardened flags. Test-only; no runtime change. 654 frontend tests green (+33); build clean.

84d0d75 headless-360: route tests for all six OAuth endpoints (authorize/callback/me/refresh/config/logout)

MCP Streamable-HTTP route: first direct coverage of the /api/mcp endpoint Agentforce 3.0 connects to (round-trip, base-URL derivation, auth wiring)

Shipped
Details

Last unguarded seam on the MCP surface. The tool handlers are now behavior-tested (in-memory transport) and the auth gate is unit-tested, but the /api/mcp route itself — the HTTP-fronted MCP server the Agentforce 3.0 Registry actually connects to — had only INDIRECT coverage. Its own logic was untested: a genuine Streamable-HTTP round-trip through the SDK's WebStandardStreamableHTTPServerTransport, and the request-origin base-URL derivation (pauseBaseUrl) that decides which Experience-API plane the tools front — the guard that keeps a preview deploy fronting its OWN mocks instead of prod, and lets PAUSE_MCP_BASE_URL repoint at a customer's Anypoint tier. Added app/api/mcp/route.test.ts (+9), driving the exported GET/POST/DELETE with hand-built JSON-RPC frames and parsing the SSE the transport emits: initialize returns serverInfo {name: pause-health-mcp, version: 0.3.0} + a tools capability; tools/list surfaces exactly the four tools; a tools/call for experience_api_health (global fetch stubbed) proves base-URL derivation end to end — by default it fronts the request's own origin (http://localhost:3000/api/mulesoft/health) and the summary echoes that origin, while PAUSE_MCP_BASE_URL overrides it (trailing slash trimmed) to https://anypoint.example.com/... ; the transport still enforces its spec contract through our handler (406 without a text/event-stream Accept, 415 on a non-JSON content type); and — importantly — all three verbs run through the same guardMcpAuth: with SF_HEADLESS360_REQUIRE_MCP_AUTH=on but unprovisioned, POST, GET, and DELETE each return 503 mcp-auth-misconfigured, confirming GET is gated BEFORE it can open a standing SSE stream rather than leaking an unauthenticated channel. (Discovered while writing it: the tool's async fetch only fires as the SSE body is consumed, so the test drains res.text() before asserting the captured URL — the same reason the route must NOT eagerly close the transport.) Test-only; no runtime change. 621 frontend tests green (+9); build clean.

105b048 mcp: cover the /api/mcp Streamable-HTTP route (round-trip, base-url, auth wiring)

MCP tool handlers: first behavioral coverage of what the four tools actually DO (URL construction, headers, summary narration, error path)

Shipped
Details

The MCP tool layer was pinned three ways for NAMES and versions — tools.parity (byte-identity vs the standalone mcp/ package), registry-parity (Agent Fabric ⇄ SERVER_VERSION + tool names), public-descriptor-parity (mcp.json ⇄ same) — but nothing exercised the handler bodies. So the Experience-API URL each tool builds, the request headers it sends, and the human-readable summary string it returns (the text an LLM reads FIRST when deciding how to phrase a result to a patient) could all have regressed silently. Added lib/mcp/tools.behavior.test.ts (+12): it stands up a real McpServer over an InMemoryTransport with an injected recording fetch — the same in-process rig host.integration.test uses — so every assertion rides a genuine tools/call round-trip, not a re-implementation. Coverage: tools/list surfaces exactly the four tools; get_patient_timeline builds /api/mulesoft/patient/{id}/timeline, URL-encodes an id with a slash, and narrates the FHIR entry count; get_patient_intake narrates 'acuity: chief complaint' and falls back to a bare summary when the record has none; find_menopause_providers assembles the query string in order (zip, menopause, limit, insurance), narrates distance-sort with distanceMiles-ascending phrasing and a per-NPI profile URL carrying the zip, and — with no zip — drops zip from the query, narrates graphScore-descending, and emits the browse-directory hint instead; experience_api_health hits /health and reports reachability + entry count; request shaping sends the default User-Agent (pause-health-mcp/0.3.0) + Accept and NO Authorization without an apiKey, attaches Bearer when an apiKey is set, honors a custom userAgent, and trims trailing slashes on baseUrl; and the error path returns an isError result carrying the upstream 502 when the Experience API is not ok. Test-only; no runtime change. 612 frontend tests green (+12); build clean.

28a92ce mcp: behavioral coverage for the four tool handlers (url/headers/summary/error)

MuleSoft Experience APIs: route tests for the two untested patient endpoints + a drift guard on the provider counts baked into the MCP tool description

Shipped
Details

Closing the remaining coverage + honesty gaps on the MuleSoft surface. Two things were unguarded. (1) The GET /api/mulesoft/patient/{id}/timeline and /intake routes — the mocked Experience APIs standing in for pause-patient-bundle-process-api and pause-intake-process-api, and the exact HTTP surface the MCP get_patient_timeline / get_patient_intake tools call — had ZERO route tests, while their siblings /health and /providers were thoroughly covered. Added 13 route cases pinning what actually matters on these mock-only endpoints: a well-formed FHIR searchset Bundle / intake record echoing the requested id; meta._bundleEntries staying in lockstep with the real entry count (it's derived — a mismatch would mean the summary lies); the meta._idAliased bookkeeping that lets an operator or agent tell when they asked for a non-demo id and transparently got the single-synthetic-patient demo shape; the empty-segment fallback to DEMO_PATIENT_ID; provenance/source stamps carrying the MuleSoft process-API identifiers; the _mcpToolEquivalent stamp; and the CDN Cache-Control header. (2) The find_menopause_providers MCP tool description hands the agent hardcoded dataset numbers — "2,015 NPPES-derived providers" and "1,720 dropped this build" (sanctioned, from CA Medi-Cal + NY OPMC + TX TMB) — as static strings with nothing tying them to provider-directory.generated.meta.json, which is regenerated whenever the directory is rebuilt. So the next `total` / `sanctionedFiltered` change would silently make the tool lie to every agent that reads it. Because tools.ts must stay byte-identical to the standalone mcp/ package copy (can't import the meta file at runtime), added tools-provider-counts.parity.test.ts to pin-not-couple: it asserts the description's numbers equal meta.providers.total / sanctionedFiltered and that the named sanction sources match the meta's per-source keys exactly (ca/ny/tx) — the same "guard, don't couple" approach registry-parity uses. Verified the guard bites by bumping the meta total and watching it fail. Test-only; no runtime change. 600 frontend tests green (+16); build clean.

e3c1f52 mulesoft: cover patient timeline/intake routes + pin provider counts to generated meta

Public MCP descriptor: the .well-known/mcp.json external clients read had re-drifted (stale version + inverted provider-ranking claim)

Shipped
Details

Carrying the registry-vs-reality drift hunt to the one MCP surface that faces OUTWARD. public/.well-known/mcp.json is the discovery descriptor an external MCP client — Claude Desktop, Cursor, the Agentforce 3.0 Registry — reads to learn the Pause server's name, version, and tool list. It's hand-authored, so it drifts exactly the way the internal Agent Fabric registry did — and it had, in two ways. (1) It advertised version "0.1.0" while the server reports SERVER_VERSION "0.3.0" on initialize (both transports). This is the SAME "0.1.0 vs 0.3.0" bug registry-parity.test.ts was written to kill for the Agent Fabric entry — but that guard only pinned agent-fabric.ts, so the public descriptor was left out and re-drifted to the identical stale number. (2) Worse, the find_menopause_providers blurb claimed results are "ranked by Pause's internal graph score" — the INVERSE of the real behavior: mulesoft-mocks ranks distance-first when a ZIP's Census ZCTA centroid is known (sort:"distance"), and graph score is only the fallback when distance can't be computed. The canonical tools.ts description has said distance-first all along; only the public descriptor lied, so an agent reading the descriptor to decide how to phrase results ("ranked by an opaque internal score" vs "about 4 miles away") was mis-primed. Fix: bumped the descriptor to 0.3.0 and rewrote the provider blurb to lead with distance ranking (graph-score fallback named honestly), plus the insurance filter and build-time license filtering it already supports. Then closed the guard gap that let it re-drift: new lib/mcp/public-descriptor-parity.test.ts binds the descriptor to the same source of truth as the internal registry — name === SERVER_NAME, version === SERVER_VERSION, tools a name-for-name bijection with the four registerTool() calls in tools.ts (extracted from source), and a honesty assertion that the provider tool's description mentions distance and does NOT carry the old graph-score-primary claim. Now a version bump or a tool add/rename/remove that skips the public descriptor fails CI, exactly like the internal registry. 584 frontend tests green (+4); build clean.

76c9b59 mcp: fix stale version + inverted ranking claim in public mcp.json + pin it

MCP auth gate: direct contract tests for guardMcpAuth + first-ever coverage of attachIdentityHeaders

Shipped
Details

Continuing the MCP hardening pass, from the host wiring down to the bearer gate itself. lib/mcp/http-auth.ts holds the Streamable HTTP auth seam: guardMcpAuth(request) is called by BOTH /api/mcp and /api/mcp/whoami and returns a discriminated result — {kind:"off"} when the gate env is unset, {kind:"blocked", response} carrying the exact HTTP rejection, or {kind:"allowed", identity} — and attachIdentityHeaders(response, identity) stamps the resolved Salesforce user onto the outgoing response. The whoami route test exercised guardMcpAuth INDIRECTLY through one endpoint's HTTP shape, but the discriminated union that the /api/mcp route branches on was never asserted directly, and attachIdentityHeaders had zero coverage — a regression in either could have changed how every MCP response is gated or identity-stamped without a red test. Added lib/mcp/http-auth.test.ts: 5 guardMcpAuth cases pin the full contract (off when unset; blocked/503 mcp-auth-misconfigured when the gate is on but Headless 360 is unprovisioned; blocked/401 with an RFC 6750 realm="mcp_api" error="missing-bearer" challenge when no bearer is sent; blocked/403 error="scope-mismatch" when the bearer lacks the mcp_api scope; and allowed with {username, via:"introspect"} on a valid bearer — introspect stubbed so no network), and 3 attachIdentityHeaders cases prove it returns the SAME response object untouched when identity is null (gate off), stamps X-Pause-MCP-User + X-Pause-MCP-Via while preserving status and streaming the body through unchanged, and omits X-Pause-MCP-User but still sets Via when the identity has no username. Test-only; no runtime change. 580 frontend tests green (+8); build clean.

7fcbb72 mcp: cover guardMcpAuth contract + attachIdentityHeaders

MCP host: test coverage for the request entry point's bearer parsing + cross-origin guard

Shipped
Details

Closed a coverage gap on a security-relevant seam. createMCPHostFromRequest is what the Care Router route actually calls to build a per-request MCP host: it derives the loopback origin from the inbound Request url and lifts an Authorization: Bearer token onto the loopback remote (so a tool call made under a Salesforce user identity carries that identity to our own /api/mcp). resolveRemotesFromEnv underneath it was thoroughly tested, but the header-parsing + origin-derivation wrapper in front — including the same-origin token-leak guard — had no direct test, so a regex or origin regression could have slipped through silently. Added 8 cases that assert via host.listRemotes(): the loopback origin is protocol+host+port with path/query dropped; a Bearer token lands on the loopback remote; the scheme match is case-insensitive and the token is whitespace-trimmed; a missing header, a non-Bearer scheme (Basic), and an empty-token Bearer all leave loopback unheadered; the inbound Salesforce bearer is NOT forwarded to an external PAUSE_MCP_HOST_REMOTES remote (the cross-origin trust boundary, now pinned at the entry point and not just in the helper); and PAUSE_MCP_HOST_LOOPBACK=off yields no remotes so the token goes nowhere. Test-only; no runtime change. 572 frontend tests green (+8); build clean.

2af004f mcp: cover createMCPHostFromRequest header parsing + origin derivation

Agent Fabric: the registry advertised a stale Pause MCP version (0.1.0 vs the server's 0.3.0)

Shipped
Details

Carrying the registry-vs-reality drift hunt from A2A onto the sibling protocol, MCP. The Agent Fabric registry entry for the Pause MCP server — what the fabric console renders and what GET /api/agent-fabric/agents returns — hard-coded version "0.1.0". But the server actually reports SERVER_VERSION "0.3.0" on the MCP `initialize` handshake, and it does so on BOTH transports (the published stdio binary and the Streamable HTTP /api/mcp route, which both build the server through createPauseMcpServer). So an operator reading the console — or an Agentforce 3.0 Registry ingesting the fabric — saw a two-minor-versions-stale build number for a server that's very much on 0.3.0. Same class as the A2A Agent Card fix: a discovery/registry surface asserting something the runtime contradicts. Corrected the registry to 0.3.0 and added lib/mcp/registry-parity.test.ts to make it self-guarding: it pins that the registry version === the MCP SERVER_VERSION, and that the registry's advertised capabilities are a name-for-name bijection with the four tools tools.ts actually registers (get_patient_timeline, get_patient_intake, find_menopause_providers, experience_api_health) — extracted from source, the same technique the existing tools.parity test uses. Now a version bump, or a tool added/renamed/removed, without updating the registry fails CI instead of silently misrepresenting the server in the console. (Deriving the version by importing SERVER_VERSION into agent-fabric.ts was rejected on purpose: it would drag the full MCP SDK into the import graph of a module loaded by nearly every route. The test-based pin matches how the repo already handles the tools.ts duplication — guard, don't couple.) 564 frontend tests green (+2); build clean.

8e5e441 agent-fabric: fix stale pause-mcp version in the registry (0.1.0 -> 0.3.0) + pin it

A2A: the Care Router now accepts the current-spec kind:"data" part tag (spec-current clients were silently blocked)

Shipped
Details

Direct follow-up to the smoke-test fix, which surfaced the underlying interop gap. The Google A2A spec renamed the message Part discriminator from `type` ("text"|"data", the early-draft form) to `kind`. Pause's A2APart type and every one of its own agents still EMIT `type`, and the Care Router's inbound POST /api/agents/care-router/tasks handler matched only p.type === "data". So any spec-current external client — Vertex AI Agent Builder, an OpenAI Responses harness, a partner orchestrator — that tags its intake part kind:"data" had that part silently ignored: intake collapsed to {}, and the task was rejected by the red-flag-mandatory policy. Clinically the block is correct (never route on an empty intake), but it fired for the wrong reason and was invisible to the caller, who sent a perfectly valid task. Fix: two defensive readers in lib/a2a.ts — partKind() (reads `type`, falls back to `kind`) and findDataPart() (returns the first data part under either discriminator, but only when it actually carries an object `data`, skipping text parts) — and the /tasks route now extracts intake via findDataPart(). Pause deliberately keeps EMITTING the `type` form for its own agents; the readers take `unknown` because inbound bytes come off the wire, not from our typed builders. The empty-intake safety property is explicitly preserved: a message with no data part in EITHER form still routes intake={} into the gate and fails closed. Verified live against a fresh production build — kind:"data" now returns state:"completed"/decision:"allow" with a RoutingDecision (mscp-virtual-visit), type:"data" is unchanged, and a text-only message still blocks. Tests: +6 a2a helper cases (both discriminators, precedence, junk, non-object data, first-match) and +1 route case proving a kind:"data" task completes. 562 frontend tests green (+8); build clean.

626e6da a2a: accept the current-spec kind:"data" part tag on inbound tasks/send

Smoke test: the A2A multi-agent checks were passing on governance-blocked tasks (false green)

Shipped
Details

While hardening the Agent Fabric I found the flagship end-to-end smoke checks were green for the wrong reason. scripts/smoke-test.mjs judged API calls on HTTP status + JSON-parse only — but the A2A layer returns HTTP 200 for JSON-RPC governance BLOCKS too (a blocked task is a 200 with status:"failed"), so the probe couldn't tell a completed routing from a rejection. Two payload bugs meant the checks were in fact hitting the block path every run: (1) the POST /api/agents/care-router/tasks case tagged its intake part kind:"data", but the route and lib/a2a.ts read type:"data" — so the part was silently ignored, intake collapsed to {}, and the red-flag-mandatory policy blocked the task; it also passed redFlagScreen instead of the redFlagsAcknowledged field the gate actually reads. (2) The POST /api/intake/route-to-care-router case sent only personaId, which the handler does NOT expand into an intake (it uses body.intake ?? {}), so it too routed an empty record and blocked. Net effect: the entire Care Router routing surface — the thing these checks exist to protect — could break end to end and the smoke suite would stay green. Confirmed live against a local prod server: the kind:"data" payload returns state:"failed"/decision:"block", the corrected type:"data" payload returns state:"completed" with a RoutingDecision artifact. Fix: a shared well-formed SMOKE_INTAKE (the exact shape the tasks route unit test proves completes to mscp-virtual-visit), both payloads corrected, and a per-call validate() hook in probeApi so a 200 is necessary but no longer sufficient — the A2A + handoff cases now assert task.status.state === "completed" carrying a RoutingDecision, and the governance pass-case asserts decision === "allow". Full suite re-run against a local production build: 139 pass / 0 warn / 0 fail. A green smoke run now means the multi-agent path actually worked, not merely that the server answered.

97132c0 smoke-test: stop the A2A checks passing on governance-blocked tasks (false green)

Agent Fabric: the governance gate now enforces the rationale policy it advertised (+ tests for all four fabric routes)

Shipped
Details

Follow-up on the same surface. evaluateGovernance() accepted task.hasRationaleField — it's in the function's type, in the POST /api/agent-fabric/governance/evaluate request body, and in the route's own docstring — but the evaluator never read it. So policy.clinical.rationale-required, which is enforcement:"block" / status:"enforced" and applies to care-router-claude, was structurally unenforceable: you could submit hasRationaleField:false and the gate would happily allow. A dead knob wired to the API sitting next to a policy labelled "enforced" is the same advertise-what-you-don't-enforce gap the Agent Card fix just closed. Now hasRationaleField === false raises the blocking violation, mirroring the existing red-flag rule exactly — blocks only when the signal is explicitly false, never when it's merely absent, so partial test fixtures and the demo "Run test case" form don't trip the gate by omission. No caller regresses: the A2A /tasks handler and the smoke test always pass true. Separately, the four Agent Fabric HTTP routes had zero route-level tests; added them. governance/evaluate: agentId/task defaults, 400 on unparseable JSON, no-store caching, and the newly-wired rationale block surfacing end-to-end. policies: the payload mirrors the library and the meta _policyCount/_enforcedCount are asserted to be DERIVED from the catalog rather than hardcoded (so they can't drift). traces: the recent-task-index branch vs the ?taskId span-tree branch, per-task scoping, and ?limit clamping — every assertion scoped to a per-test unique task id so the shared, seeded span-store global can't make them flaky. sf-sink/config: the leak guard that matters most on a public curl-able probe (never echoes clientId / clientSecret / baseUrl at any nesting depth) plus the always-present emit counters. 554 frontend tests green (+16); build clean.

150b9fa agent-fabric: enforce the rationale policy the gate already advertised + cover all four fabric routes

Agent Fabric: agent + A2A Agent Card policies now derive from one source of truth

Shipped
Details

An agent's governance policy set was hand-maintained in THREE places that had silently drifted apart: REGISTRY[].policies in the fabric registry (lib/agent-fabric.ts), the Care Router's public A2A Agent Card (/api/agents/care-router/.well-known/agent.json — the document any A2A client reads to learn what the agent supports), and the authoritative POLICIES[].appliesTo that evaluateGovernance() actually checks on every tasks/send. For care-router-claude the three disagreed 6 vs 4 vs 7: the registry omitted the red-flag, HIPAA-audit, and Data-360 consent policies the router genuinely applies (the red-flag one is a hard block the handler enforces), and the card omitted consent. The registry also under-listed pause-mcp (missing policy.data.fhir-r5-only) and mulesoft-ingest, where it referenced policy.audit.correlation-id-mandatory — a policy id that exists nowhere in the catalog (the real one is policy.audit.return-mulesoft-correlation-id). A public discovery document advertising governance the server doesn't enforce — and a registry pointing at a phantom policy — is the same overclaim/drift class this project keeps deleting. Fix: appliesTo is now the ONE source. REGISTRY entries are seeds with no policies field (type AgentSeed = Omit<AgentRecord,"policies">); listAgents()/getAgent() attach policies via getPoliciesForAgent(), and the Agent Card derives pauseGovernance.policies the same way, so registry ⇄ card ⇄ enforcement can no longer disagree. The demo Agent Fabric UI already grouped policies by appliesTo, so this corrects the raw /api/agent-fabric/agents payload and the card without touching the console. Tests: agent-fabric.test.ts gains registry⇄appliesTo parity + referential integrity (every appliesTo names a real agent; every agent policy id exists in the catalog — the phantom id is now caught). New route.test.ts pins the Agent Card contract: shape, url is the agent base not the /tasks endpoint, capabilities.streaming + pushNotifications asserted false (the /tasks handler is single-turn — a2a.ts documents SSE + push as out of scope, so flipping either is a lie until implemented), and policies exactly equal getPoliciesForAgent. New a2a.test.ts finally covers the untested sendA2ATask client — request shaping, trailing-slash normalization, and all four response outcomes (ok, HTTP error, JSON-RPC error, missing result) — plus the userMessage/agentMessage/newTaskId helpers. 538 frontend tests green (+42); build clean.

5c303cb agent-fabric: derive agent + Agent Card policies from one source of truth (kill the drifted copies)

Data 360: a preflight "doctor" that brackets the manual org-side activation clicks

Shipped
Details

The final Data 360 step is the maintainer clicking through the Salesforce Data Cloud UI (per docs/PHASE_2_INGESTION_API_RUNBOOK.md) — no code can click those for them. But the clicking can be de-risked from both ends: the verifier (shipped last commit) confirms the END (CIs return real values); this adds the FRONT. New examples/data_cloud_preflight.py (pause-dc-preflight console script) probes the org and prints a [x]/[ ]/[?] checklist mapped to the runbook steps — Step 1 (client_credentials + a360 token exchange succeed → creds + Data Cloud enabled), Steps 2-3 (the Pause_Wearable_Feature__dlm DMO exists + is queryable), Step 4 (the DMO holds pushed rows), Step 5 (all three Calculated Insights reachable by __cio API name) — with a specific remediation pointer on each unfinished step and an auth-failure short-circuit that marks everything downstream blocked. Exit 0 = fully wired, run the verifier next; 1 = steps remain; 2 = not configured. So the operator runs it before starting and between clicks, always seeing what's actually taken effect instead of clicking blind. Reused/extended the tested client: added DataCloudQueryClient.query() (generic POST /api/v1/query, mirrors the frontend dcQuery) to probe the DMO, and DataCloudClientBase.check_auth() to isolate an auth failure (bad creds / DC not enabled / missing CDP grant) from a data failure (DMO/CI not created yet). The runbook gained a "Preflight — know where you stand" section up front. Tests: test_preflight.py pins the pure assess() classifier across every scenario (auth-fail blocks downstream, missing DMO blocks push, empty DMO → push TODO, missing CI flagged by name, empty-but-reachable CIs still pass with a note) plus the ready_to_verify gate; +3 client cases (query() two-legged HTTP contract, check_auth success + exchange-failure). Ran against a real Python 3.13 venv: 67 relevant pause_ingest tests green. With preflight + verify, the entire manual runbook is now bracketed by automated checks — the only thing left that a human must do is the clicking itself.

c1fc8b5 data-360: add the org activation preflight doctor (probe DMO/CIs, map to runbook steps)

Data 360: a read-back verifier that proves the org-side CI activation actually worked

Shipped
Details

The one remaining Data 360 gap is org-side: activating the three Calculated Insights (swapping the MAX(constant) mock SQL for the real per-CI aggregates) is a manual Salesforce Data Cloud step the maintainer runs per docs/PHASE_2_INGESTION_API_RUNBOOK.md — it can't be done from this repo. What CAN be de-risked is proving the flip worked. Step 6 of the runbook was an eyeball check ("does Deepa's HRV look lower than Carmen's?") against a deployed frontend endpoint. Replaced it with a deterministic read-back verifier — the live-org companion to the static contract test shipped earlier. New pause_ingest tooling: (1) DataCloudQueryClient — refactored data_cloud.py to pull the two-legged a360 token exchange into a shared DataCloudClientBase, then added a query client that GETs each CI exactly the way the frontend does (GET /api/v1/insight/calculated-insights/{name}__cio?filters=[unified_id__c=…]); the existing ingest client now extends the same base (its 8 tests unchanged). (2) expected.py — independently recomputes, in Python, the per-patient aggregates each CI should return, using the SAME formulas as the CI SQL (AVG rmssd → z=(avg−42)/12, SUM severity/30*100, nights<0.80/7); this is a deliberate THIRD encoding of the formulas — the verifier's whole job is to catch a mismatch, so the redundancy IS the check. (3) examples/data_cloud_verify.py (also exposed as the pause-dc-verify console script) — queries all three CIs for every demo persona and asserts the returned columns match expected (counts exact, averaged metrics within tolerance), with an explicit "every patient identical → mock still active" guard that names the offending CI; exit 0 = verified, 1 = mismatch/mock-still-live, 2 = not configured; it prints a per-patient table and supports --push to ingest-then-verify. 19 new pause_ingest tests (test_expected.py, test_verify.py, +3 query-client cases in test_data_cloud.py) pin the aggregation math, the mock-detection guard, and the query HTTP contract (two-legged auth, tenant host, bracketed filter, HTTP-error handling) against an httpx MockTransport. Runbook Step 6 rewritten around the verifier (curl kept as a secondary spot-check); data-cloud/README notes it. When the maintainer runs the activation, `python -m examples.data_cloud_verify` now turns "did it work?" into one green line instead of a judgment call.

4033816 data-360: add the Data Cloud CI read-back verifier (query client + expected + verify CLI)

Data 360: removed the fabricated pathwayOutcomes resolution rates from the grounding context

Shipped
Details

Follow-up to the cohort-percentile honesty pass. cohortComparison carried a pathwayOutcomes array — per-pathway resolution rates (mscp-virtual-visit 0.71, mscp-in-person 0.78, self-care-tracking 0.34) with cohort counts (n=1840/612/690) — hardcoded identically in BOTH the mock (data-360.ts) and the real grounding path (grounding.ts), and emitted inside a context whose provenance string reads "Phase 2: SOQL + Data Cloud Calculated Insights." Two problems: (1) the numbers are pure fabrication — the demo org has no pathway-outcome / resolution data model, and the n values don't even reconcile with the real cohortSize (a live SOQL COUNT() of CareProgramEnrollee), so they can't be sourced from real CareProgram aggregates; (2) they were dead — audited every consumer (Care Router rationale + routing, both intake API routes, the Agentforce prechat dossier, the Care Detail UI, all 516 tests) and NOTHING reads pathwayOutcomes or resolutionRate; it existed only in the type + the two builders + a mirror in care-detail-stage.tsx's local prop type. Unused fabricated data sitting inside a "grounding" object next to real Data Cloud provenance is exactly the overclaim this workstream keeps removing, and it's a latent trap — a future dev could wire it into the dossier believing it's org-derived. Removed pathwayOutcomes from the CohortComparison type, both builders, and the care-detail-stage mirror; tightened the CohortBasis JSDoc (it no longer has to caveat pathwayOutcomes — `basis` is now purely the provenance of patientPercentile). cohortSize (real SOQL COUNT), patientPercentile (honestly flagged intake-estimate), cohortName, and metric are untouched. If per-pathway outcomes are ever wanted, they should come from a real CareProgram outcome aggregate with its own provenance marker, not a constant. 516 tests green; build clean.

628e22c data-360: remove the fabricated, unused pathwayOutcomes from the grounding context

Data 360: a contract test that de-risks flipping the Calculated Insights off the MAX(constant) mocks

Shipped
Details

The three activated Calculated Insights are still the MAX(constant) placeholders in data-cloud/_mock_path.sql. The real-data flip — the maintainer's Ingestion-API step in docs/PHASE_2_INGESTION_API_RUNBOOK.md — swaps them for the three committed per-CI SQL files (Pause_HRV_RMSSD_30d / Pause_Vasomotor_Burden_30d / Pause_Sleep_Disruption_7d), which aggregate the Pause_Wearable_Feature__dlm DMO that pause_ingest pushes into. That flip only works if FOUR artifacts agree on column names, observation_type literals, and the aggregate output shape: the DLO schema JSON (ingested fields → __c columns + the observation_type enum), pause_ingest's pushed rows (grain + field names), the real CI SQL (which DMO columns it reads, which types it filters, which columns it emits), and data-cloud.ts (which output columns getWearableInsights reads + the __cio CI names it queries). Any single rename silently returns empty/wrong rows and grounding degrades to the baseline with NO error — the exact ssot__Id__c-vs-unified_id__c class of drift that already bit the mock path. Audited all four end-to-end and confirmed they line up today (30 HRV rows AVG'd, 7 sleep nights, N vasomotor events SUM'd — the row grain matches each CI's aggregation), then pinned it: a new TS contract test (data-cloud.real-path.contract.test.ts, 20 cases) reads the committed .sql + schema JSON + data-cloud.ts source directly — no Python runtime needed — and asserts each CI only reads DMO columns that exist as DLO fields, filters exactly the observation_type values the push emits (all in-enum, no type claimed twice), emits exactly its documented output columns, groups by the unified_id__c dimension (never the validator-rejected ssot__Id__c), and that every column the frontend reads is one the CI emits and every __cio name matches. Also corrected a misleading comment in cohort.py that claimed the 850 ms resting NN-interval mean (an input to RMSSD synthesis) "matches the CI z-score denominator" — the z-score anchor (42 ms mean / 12 ms SD normative RMSSD) actually lives only in the HRV CI SQL. The activation itself is still an org-side step Pause can't run from here; this makes the flip fail loudly in CI instead of silently in production if any artifact drifts. 516 frontend tests green (+20); build clean; cohort.py byte-compiles.

7dd7fa9 data-360: pin the real-CI ingestion contract (DLO schema ⇄ SQL ⇄ frontend)

Data 360: stopped presenting the intake-scaled cohort percentile as a live Data Cloud segment

Shipped
Details

Truthfulness fix in the highest-stakes surface. Even on the real grounding path, cohortComparison.patientPercentile is scaled straight from the patient's OWN intake vasomotor score (not her rank within a real cohort distribution), and pathwayOutcomes are hardcoded reference resolution rates — yet they're emitted right next to a "Phase 2: SOQL + Data Cloud Calculated Insights" provenance string, so the Care Router rationale and the agent dossier would read an intake-derived number as live segment analytics. Same in the mock. Added an explicit `basis` discriminator to CohortComparison ("intake-estimate" | "data-cloud-segment"); both the mock and the real builder set "intake-estimate" (today's truth), and the field is required so any future builder must declare provenance. cohortSize is untouched — in the real path it's a genuine SOQL COUNT() of CareProgramEnrollee. Consumers made honest: the Care Router rationale now says "…intake-reported vasomotor symptom burden maps to an estimated Nth-percentile burden (intake-derived estimate, not a live Data Cloud segment)" instead of "patient sits at the Nth percentile of <cohort>", reserving the confident phrasing for a real data-cloud-segment; the Agentforce prechat dossier gains Patient_Percentile_Basis and both grounding telemetry spans carry patientPercentileBasis. Routing behavior is unchanged (the percentile-≥75 promotion still fires as a burden proxy) — only the labeling stops overclaiming. Tests: the rationale hedges by default, uses confident phrasing only for data-cloud-segment, and the mock cohort is flagged intake-estimate. 496 frontend tests green; next build clean (after the build fix below).

a50cbfb data-360: stop presenting the intake-scaled cohort percentile as a live segment

Build fix: main was red — guardMcpAuth exported from the /api/mcp route module

Shipped
Details

Caught while verifying the Data 360 work: `npm run build` was failing on main (introduced by the Headless-360 gap-#2 follow-ups) with "Route app/api/mcp/route.ts does not match the required types of a Next.js Route — guardMcpAuth is not a valid Route export field." Next.js App Router route files may only export HTTP method handlers plus a small config allowlist (runtime, dynamic, …), so exporting the bearer-gate helper directly from the route module fails type-checking and left main un-buildable / un-deployable. Extracted guardMcpAuth (plus the McpAuthIdentity / GuardResult types and attachIdentityHeaders) into lib/mcp/http-auth.ts and imported it from both /api/mcp and /api/mcp/whoami. Behavior is identical — the gate still calls the same validateMcpApiBearer with the introspect-first / userinfo-fallback trust model, and the whoami diagnostic tests pass unchanged. 496 tests green; next build clean.

177c2e8 fix(build): move guardMcpAuth out of the /api/mcp route module

Week of June 21, 2026

MuleSoft Phase 3 = 9 Exchange assets (full API-led coverage + 5 wearable specs); Headless 360 audit reaches all-prototype

Big consolidation week. (1) MuleSoft Phase 3 — the /proposal/mulesoft page's Phase 3 (multi-customer fabric) was pilled `future` since launch; this week shipped nine Exchange assets. 2026-06-26: pause-omh-to-fhir-library v1.0.0 + CloudHub worker 1.0.5 consuming it (end-to-end dependency story proven). 2026-06-27: eight spec-tier assets — pause-jhe-system-api-spec, pause-dbdp-system-api-spec, pause-oura-system-api-spec (the per-wearable template), pause-ingest-process-api-spec (the orchestration tier that ties them together), then four per-wearable clones covering both architectural patterns: pull-from-vendor (Whoop, Garmin) and upload-to-Pause (HealthKit iOS-app-side, Empatica E4 researcher-uploaded .zip archives). With the Process-tier spec published, the full MuleSoft API-led three-tier story is on Exchange — System (Oura/Whoop/Garmin/HealthKit/Empatica/JHE/DBDP) + Process (pause-ingest-process-api-spec) + Experience (pause-provider-experience-api-spec, on Exchange since the Phase 1 worker rollout). (2) Headless 360 audit gap #2 — env-gated `mcp_api` bearer validator on /api/mcp (introspect-first + userinfo fallback; loopback-bearer propagation in the Care Router's MCP host with a structural same-origin guarantee). (3) Headless 360 audit gap #4 — the third Headless 360 surface (CLI), shipped as a new in-repo `@pause-health/cli` Node package wrapping /api/mulesoft/*. With #4 closed, ALL FOUR audit gaps on /proposal/headless-360 read `prototype`. Audit is structurally complete; the only path to `shipped` per gap is operator-side env-var procurement.

Headless 360 gap #2 follow-ups — introspect cache + identity threading + /api/mcp/whoami

Shipped
Details

Closed the two runbook-flagged limitations of the original gap #2 ship. (1) Introspect caching: bounded process-local Map<token, {expiresAt, result}> in lib/salesforce-headless360.ts with a 60s TTL, 1024-entry LRU-on-insert cap, only positive results cached so a freshly-issued token isn't stuck rejected. Cuts Salesforce introspect round-trips by ~30x on a hot Vercel instance handling a tools/list + tools/call sequence. (2) Identity threading: guardMcpAuth now returns the validated identity (username + via) instead of swallowing it. /api/mcp attaches X-Pause-MCP-User + X-Pause-MCP-Via headers to every successful response so the Agent Fabric trace plane can attribute tool calls. New GET /api/mcp/whoami diagnostic endpoint (route.ts) returns {gate: "off"} when unset, {gate: "on", via, username} when a valid bearer resolves, and the same 401/403/503 errors as /api/mcp on failure — lets operators verify gate wiring without parsing the SSE stream. 12 new unit tests pin the cache behavior (positive-cached, TTL-expires, userinfo-fallback-cached, negatives-no-cache, per-token-isolation, no-cache-on-missing-bearer) and the whoami envelope (gate-off, no-bearer 401, misconfig 503, ok-with-username, scope-mismatch 403, ok-without-username). Found and fixed two test-side bugs along the way: vi.fn().mockResolvedValue(Response) returns the same Response object across calls, but Response bodies can only be consumed once — second call's .json() throws and triggers an unintended userinfo fallback. mockImplementation(async () => new Response(...)) returns a fresh Response per call and is the correct pattern; existing tests called validateMcpApiBearer once each so they didn't hit the bug, but the new TTL + negative-cache tests call it twice each and revealed the issue. 493/493 vitest tests green (was 481; +12). tsc clean. Runbook (docs/HEADLESS_360_RUNBOOK.md) updated: 'Known limitations' section split into 'Follow-ups shipped 2026-06-27' + 'Still open' (only the userinfo-fallback-doesn't-enforce-scope item remains, and that's a Salesforce-side org-config choice Pause can't close from this side). Audit page gap #2 needed-column rewritten to reflect the follow-ups landing.

ec056ad headless-360: ship gap #2 follow-ups (cache + identity headers + whoami)

MuleSoft Phase 3 — four per-wearable clones (HealthKit + Whoop + Garmin + Empatica E4) published to Anypoint Exchange

Shipped
Details

Four per-wearable System API specs at v1.0.0 each, published to Anypoint Exchange under the Pause Health business group. Demonstrates BOTH architectural patterns the Phase 3 plan describes. Pull-from-vendor (Oura template): pause-whoop-system-api-spec extends with Whoop's data-type catalog (synthetic OMH schemas recovery-score:1.0 and cardiovascular-strain:1.0 for Whoop's composite scoring metrics that aren't in the OMH catalog, plus standard sleep-episode + physical-activity + heart-rate + heart-rate-variability); pause-garmin-system-api-spec extends with body-temperature + oxygen-saturation (Garmin's Body Battery + Pulse Ox feeds) and documents the OAuth 1.0a quirk (Garmin Health API hasn't migrated to OAuth 2.0; the Mule app speaks 1.0a upstream while downstream callers still use OAuth 2.0 client_credentials), and the webhook-ping + pull-on-receipt upstream cadence. Upload-to-Pause (distinct architectural pattern): pause-healthkit-system-api-spec has POST /healthkit/{patient}/upload that accepts iOS-app-shaped HealthKit batches (the iOS app reads HKHealthStore on-device with Apple's per-type consent and uploads JSON; there is no Apple Cloud REST API to poll), plus GET /healthkit/{patient}/types so the iOS app can skip consent prompts for types Pause won't ingest, plus the cycle-tracking types (HKCategoryTypeIdentifierMenstrualFlow etc.) that no other vendor exposes; pause-empatica-system-api-spec has POST /empatica/{patient}/upload accepting multipart .zip archives (E4 session export — one CSV per signal: HR, IBI, EDA, TEMP, ACC, BVP, TAGS), POST /empatica/{patient}/derive for re-running feature derivation against a previously-uploaded session when DBDP feature algorithms improve, plus GET /empatica/{patient}/sessions for audit. The Empatica spec is honestly anchored to pause_ingest/pause_ingest/empatica.py, which currently raises EmpaticaIngestNotImplemented because devicely's numpy<2.0 pin breaks the Python 3.13 scientific stack — Phase 2 of the DBDP integration. All four specs follow the same plain-jar Maven packaging and the curl-PUT publish recipe (POM with Content-Type: application/xml; jar with application/java-archive). All four spec files parse clean (no missing $refs) and registered on Exchange with status: published. Page updates: /proposal/mulesoft Phase 3 detail expanded from five to nine total Exchange assets and explicitly calls out the two architectural patterns covered; metadata description refreshed. Honest framing in every spec's info.description: this is contract-only; no Mule wrapper exists for any of these vendors today; the contracts let customer-side Mule apps and the future Pause integrations wire against a stable shape now.

90e9cc4 mulesoft: ship four per-wearable Phase 3 specs (HealthKit/Whoop/Garmin/Empatica)

MuleSoft Phase 3 fifth asset — pause-ingest-process-api-spec v1.0.0 (Process tier; completes API-led coverage on Exchange)

Shipped
Details

Fifth Phase 3 artifact on Anypoint Exchange under the Pause Health business group and the one that completes the MuleSoft API-led three-tier story on Exchange. Single endpoint: POST /samples, the canonical Process-tier orchestration entrypoint. Validates an OMH IEEE 1752.1 envelope → transforms to FHIR R5 via pause-omh-to-fhir-library's dw::pause::health::omh → writes to JHE via pause-jhe-system-api-spec's POST /fhir/r5/Observation → fires DBDP feature compute via pause-dbdp-system-api-spec's POST /features/hrv:compute (fire-and-forget, async per the reference flow's <async> block) → returns {status: accepted, observationId, source, featureComputeTriggered}. The contract is anchored to the real reference Mule XML at mulesoft/flows/pause-process-api.example.xml — five-step <flow> documented step-by-step in the spec's info.description and per-step in the operation description. Error envelope mirrors the reference flow's <error-handler> on-error-propagate: {status: error, error, errorType} with the Mule errorType.identifier propagated (HTTP:CONNECTIVITY, JSON:SCHEMA_NOT_HONOURED, HTTP:UNAUTHORIZED) so the runbook can diagnose without re-decoding. Four schemas: IngestSampleRequest (source + OMH header + body), OmhHeader (IEEE 1752.1), IngestSampleResponse, ProcessApiError. Spec parses clean (no missing $refs). Honest framing in the info block: this is contract-only — the reference XML is labeled REFERENCE, not deployable (lacks customer property files + the bundled OMH JSON schema); Phase 1c materializes the deployable Mule project; today pause_ingest's Python worker does the equivalent orchestration in-process. Plain-jar Maven packaging, same curl-PUT publish recipe as the four prior spec assets. Verified: Exchange asset listing returns status:published. Page updates: /proposal/mulesoft Phase 3 detail now names all five shipped assets and explicitly calls out the full API-led tier coverage (System + Process + Experience); metadata description refreshed.

3c82200 mulesoft: ship pause-ingest-process-api-spec v1.0.0 (Phase 3 fifth asset; Process tier)

MuleSoft Phase 3 fourth asset — pause-oura-system-api-spec v1.0.0 (per-wearable template)

Shipped
Details

Fourth Phase 3 artifact on Anypoint Exchange under the Pause Health business group, and the template for additional per-wearable specs (HealthKit, Whoop, Garmin, Empatica E4). OAS 3.0 contract at mulesoft/specs/pause-oura-system-api-spec/src/main/resources/oura-system-api.oas3.yaml describes the HTTP surface a future Mule app wrapping the Oura Cloud API would expose downstream to Process APIs. Two endpoints: GET /oura/{patient}/{dataType}?from=&to=&tz=&limit= (returns an array of IEEE 1752.1 envelopes; six supported dataType values pinned to pause_ingest.convert.SUPPORTED["oura_raw"] — heart-rate, heart-rate-variability, step-count, sleep-duration, sleep-episode, physical-activity) and GET /oura/{patient}/account (lightweight diagnostic returning {linked, tokenFresh, scopes, lastSyncIso} so the Care Router can fail fast on revoked Oura access instead of polling forever). Five schemas: OmhSamplesResponse, the OMH envelope + header (shape fixed by IEEE 1752.1 / omh_shim v1.0.1), AccountStatus, and a SystemApiError envelope with a tight code enum (unsupported-data-type, invalid-time-window, missing-timezone, patient-not-found, account-not-linked, upstream-unavailable, internal-error). Honest framing inside the spec's info.description: this is contract-only, no Mule wrapper exists; pause_ingest's Oura ingest today reads from a synthetic JSON fixture in oura_sample_upload.py, not Oura's live REST API. Phase 1c will materialize the Mule app. README explicitly calls out the per-wearable template story — future HealthKit/Whoop/Garmin specs are near-clones with vendor-specific dataType lists + auth model on securitySchemes. Plain-jar Maven packaging, same curl-PUT publish recipe as the other spec assets. Verified: Exchange asset listing returns status:published. Page updates: /proposal/mulesoft Phase 3 detail now names all four shipped assets; metadata description refreshed.

2ec0d2e mulesoft: ship pause-oura-system-api-spec v1.0.0 (Phase 3 fourth asset, per-wearable template)

MuleSoft Phase 3 third asset — pause-dbdp-system-api-spec v1.0.0 published to Anypoint Exchange

Shipped
Details

Third Phase 3 artifact on Exchange under the Pause Health business group. OAS 3.0 contract at mulesoft/specs/pause-dbdp-system-api-spec/src/main/resources/dbdp-system-api.oas3.yaml describes the HTTP surface a future dbdp-system-api Mule project would expose on top of the existing pause_ingest.features Python layer. Single endpoint, parameterized by mode: POST /features/hrv:compute with mode=sliding-window (wraps hrv_features_flirt — FLIRT-backed, sliding-window default 180s/60s, multiple feature domains td+fd+stat) or mode=time-domain-fallback (wraps hrv_time_domain_fallback — dependency-light, Kubios-validated, single aggregate). Honest framing inside the spec's info.description: this is contract-only; no live REST surface exists today; the existing pause_ingest.features Python functions are called in-process from pause_ingest/examples/oura_sample_upload.py, NOT over HTTP. Phase 1c will materialize the Mule wrapper. Shape pinned to three real things — the endpoint sketch in mulesoft/flows/pause-process-api.example.xml, the Python function signatures in pause_ingest/pause_ingest/features.py, and the FHIR derivation shape (urn:pause-health:code:dbdp-features / hrv_rmssd_sliding_180s with derivedFrom lineage) the CloudHub worker already returns. Five schemas: HrvComputeRequest, two response shapes (sliding-window vs time-domain-fallback), shared HrvTimeDomain (1:1 mirror of pause_ingest.features.HrvTimeDomain dataclass — meanNnMs/sdnnMs/rmssdMs/nn50Count/pnn50Pct/meanHrBpm/sampleCount, Task Force 1996 standard), DbdpError envelope. 400-response examples cover the real validation failures pause_ingest enforces (IBI series outside 100-5000 ms range as unit-confusion check; size < 5 for fallback / < 2 for sliding-window). Plain-jar Maven packaging, same curl-PUT publish path as the JHE spec (mvn-deploy-plugin sends wrong Content-Type for .pom files; the workaround is documented in the README). Verified: Exchange asset listing returns status:published. Page updates: /proposal/mulesoft Phase 3 detail now names all three shipped assets and notes the implementation gating; metadata description refreshed. No code paths in pause-health.ai consume the spec yet — this is contract-first publishing.

a4258ad mulesoft: ship pause-dbdp-system-api-spec v1.0.0 (Phase 3 third asset)

Headless 360 audit gap #4 closed — @pause-health/cli ships (REST + MCP + CLI triad complete)

Shipped
Details

Salesforce's Headless 360 trust model exposes every agent capability through three surfaces — REST API, MCP tool, AND `sf`-style CLI command. The /proposal/headless-360 audit had gap #4 pilled `future` since launch, framed as 'low priority since investors interact via the web surfaces.' Shipped anyway because: completing the triad is a small lift, and the CLI is genuinely useful for operator smoke-tests against preview deploys. New cli/ in-repo package: zero-runtime-dep CLI with four commands wrapping /api/mulesoft/{health,providers,patient/<id>/timeline,patient/<id>/intake}. Pretty default output for human consumption; `--json` for jq piping. Honors PAUSE_BASE_URL + PAUSE_API_KEY env and `--base-url` per-invocation. Hand-rolled argv parser (BOOLEAN_FLAGS + VALUE_FLAGS sets, positional collection, unknown-flag rejection) — keeps the install lean vs commander/yargs for a four-endpoint shim. Same package shape as mcp/ (npm bin entry, tsc → dist/, scripts/smoke.mjs against live endpoints). 17 unit tests pin the parser (flag matrix, value-flag-missing-value, unknown-flag rejection, env precedence) + the http client (Accept + User-Agent headers, PAUSE_API_KEY → Authorization, --base-url override, trailing-slash strip, non-2xx error format). 6/6 smoke cases green against pause-health.ai (--help, --version, unknown-command 2-exit, pause health, pause providers pretty + --json). Audit page intro copy updated to note all four gaps now read prototype as of 2026-06-27. NOT publishing to npm yet — the audit gap ships the artifact; npm-scope ownership is a separate ops decision. New cli/README.md covers install (npm install + npm run build + optional npm link), the four commands, the configuration env vars, what's explicitly not in scope (write commands, OAuth flow, npm publish), and the development workflow. tsc clean across the new package + the frontend. Total project test count: 481 frontend + 17 cli = 498 passing.

0626bf6 cli: ship @pause-health/cli (gap #4 closed; REST + MCP + CLI triad complete)

Headless 360 audit gap #2 closed — `mcp_api` bearer gate on /api/mcp (dormant until SF_HEADLESS360_REQUIRE_MCP_AUTH=on)

Shipped
Details

Shipped the second of four Headless 360 audit gap closures. /api/mcp now honors a Salesforce-issued OAuth bearer with `mcp_api` scope when the operator opts in via SF_HEADLESS360_REQUIRE_MCP_AUTH=on. Default stays public — the Agentforce 3.0 Registry's public-mock posture is preserved. New helpers in lib/salesforce-headless360.ts: isMcpApiAuthRequired() (truthy-string env reader) and validateMcpApiBearer(req, cfg, fetch?) — RFC 7662 introspect first (POST /services/oauth2/introspect, strict path: requires `active=true` AND scope contains `mcp_api`); userinfo fallback (GET /services/oauth2/userinfo, permissive path: verifies token aliveness only; result self-documents as `via: "userinfo-fallback"` + `scope: null` so callers can log the weaker guarantee). The validator returns a discriminated union — `{ok, via, scope, username} | {ok: false, reason}` where reason ∈ {missing-bearer, token-inactive, scope-mismatch, introspect-error}. Wired into app/api/mcp/route.ts as `guardMcpAuth()` that runs before the existing handle() — returns 401 (missing-bearer / token-inactive / introspect-error), 403 (scope-mismatch), or 503 (env gate on but Headless 360 unprovisioned, fail-closed posture). All non-2xx responses include WWW-Authenticate: Bearer realm="mcp_api", error="<reason>" per RFC 6750 so MCP clients can prompt for re-auth. Cross-origin protection on lib/mcp/host.ts: resolveRemotesFromEnv(origin, {loopbackBearer}) now attaches the inbound bearer to the loopback MCPRemoteConfig only; external remotes from PAUSE_MCP_HOST_REMOTES keep their own headers. createMCPHostFromRequest(req) reads the Authorization header off the inbound request and threads it through — Salesforce user identity gets propagated to the loopback MCP server but never cross-origin (same-origin guarantee is structural, not a check that could regress). 25 new vitest tests pin: isMcpApiAuthRequired truthy/falsy matrix (12 cases), validateMcpApiBearer for missing-bearer + non-Bearer scheme rejection + introspect success/scope-mismatch/inactive + the two userinfo fallback branches + network errors + bogus 200 body + whitespace trim, and the host loopback-bearer attachment + same-origin guarantee + loopback-off interaction (3 cases). 481/481 vitest tests green (was 456; +25). Audit page updated: /proposal/headless-360 gap #2 pill flipped designed → prototype with the activation snippet rewritten to reflect the actually-shipped behavior. New runbook section in docs/HEADLESS_360_RUNBOOK.md § "Closing gap #2" covers validation flow, HTTP semantics table, operator activation + smoke-test commands, rollback (single env-var deletion), and three honestly-flagged known limitations (no validated-username threading into MCP handler, no caching, userinfo-fallback doesn't enforce scope). tsc clean.

3202a2a headless-360: ship mcp_api bearer gate on /api/mcp (gap #2 closed)

MuleSoft Phase 3 second asset — pause-jhe-system-api-spec v1.0.0 published to Anypoint Exchange

Shipped
Details

Published the JHE System API contract as a versioned Anypoint Exchange asset under the Pause Health business group. The spec at mulesoft/specs/pause-jhe-system-api-spec/src/main/resources/jhe-system-api.oas3.yaml documents three real JHE REST endpoints — POST /o/token/ (OAuth2 client_credentials, openid+email scopes only — anything else 400s with invalid_scope), POST /fhir/r5/Observation (with the mapped-vs-auxiliary handler routing keyed on code.coding[0].system, and the X-JHE-FHIR-Source-ID header gotcha the auxiliary handler 400s without), and GET /fhir/r5/Observation?patient=… (no-filter-on-unknown-patient invariant pinned by pause_ingest's real-JHE tests). Plus 10 data-plane schemas (Study, Patient, DataSource, FhirSource, etc.) documenting JHE's Django ORM models — honest framing: those are NOT exposed as REST today, they're seeded by jhe-local/bootstrap.sh; documenting them here gives any customer-side Mule app the JHE-internal vocabulary in one place. Packaging is plain Maven jar (same approach as pause-omh-to-fhir-library to dodge Exchange's mule-plugin extension-extraction 502s); consumers add `<dependency>...pause-jhe-system-api-spec...</dependency>` and read the yaml off the classpath. Published via the curl-PUT publish recipe (POM as application/xml, jar as application/java-archive — the Exchange v2 mvn-deploy Content-Type gotcha already documented for the DataWeave library applies here too). Spec validates clean (17 schemas, no missing $refs). Verified: Exchange asset listing returns status: published. Page updates: /proposal/mulesoft Phase 3 detail now names both shipped assets and notes the implementation gating; metadata description refreshed. No code paths in pause-health.ai consume the spec yet — this is contract-first publishing. Phase 1c will materialize the implementation.

6742c9a mulesoft: ship pause-jhe-system-api-spec v1.0.0 (Phase 3 second asset)

MuleSoft Phase 3 opens — pause-omh-to-fhir-library v1.0.0 published to Anypoint Exchange

Shipped
Details

Promoted the OMH (IEEE 1752.1) → FHIR R5 Observation DataWeave transform out of the pause-mulesoft-health-v1 worker and into a versioned, reusable Anypoint Exchange asset on the Pause Health business group (groupId 56707cc3-a0e3-4318-b110-78126aace370). Shipped: a new mulesoft/pause-omh-to-fhir-library/ Maven project (plain `jar` packaging, no classifier — see below) with the canonical `omhToObservation(sample, patientRef, idx)` function at `dw/pause/health/omh.dwl`, importable as `dw::pause::health::omh` from any Mule DataWeave script. The CloudHub worker bumped to v1.0.5 with the new artifact as a `<dependency>`; the deployable mule-application jar now bundles `repository/.../pause-omh-to-fhir-library-1.0.0.jar`, proving end-to-end consumption of the Exchange asset. Worker flow XML unchanged, so the runtime `/health` and `/providers` responses stay byte-identical to 1.0.4 — this entry is about Phase 3 wiring, not a refactor of the existing flow. Two non-obvious gotchas found and documented: (1) Anypoint Exchange v2 500s on the .pom upload with `application/x-www-form-urlencoded` (mvn-deploy-plugin's default for .pom files), so the publish recipe uses a direct curl PUT with `Content-Type: application/xml` — the .jar upload through mvn is fine because aether sends octet-stream for jars; (2) tagging the library jar `classifier=mule-plugin` triggers Exchange's `ms-exchange-tooling-service` extension-model extraction, which 502s on a no-SDK jar (`invalid json response body: Error proc...`). DataWeave libraries don't need the classifier — the Mule runtime discovers the `dw/` namespace from any jar on the classpath. Page updates: /proposal/mulesoft Phase 3 pill flipped `future` → `prototype`, with a new detail block naming the asset coordinates and the consumer wiring; the protoVsProd table's `OMH → FHIR transform` row now describes the shipped Exchange asset (was: 'reference dwl in the repo'). Verified: Exchange asset listing returns `status: published`; HEAD on both 1.0.0 artifacts returns 200; worker 1.0.5 deployed to CloudHub-US-West-1 Sandbox in 2:12 (BUILD SUCCESS); direct CloudHub `/health` + `/providers` smoke green. New docs at mulesoft/pause-omh-to-fhir-library/README.md (consumer pom snippet, DataWeave import example, the curl-PUT publish recipe with both gotchas inline) and an updated docs/MULESOFT_RUNBOOK.md.

b7f143b mulesoft: ship pause-omh-to-fhir-library v1.0.0 + worker 1.0.5 (Phase 3 first asset)

Week of June 13, 2026

Phase 2 across the stack: provider-graph + Data 360 + MuleSoft contract update

Two big streams landed and a third caught up. Provider-graph Phase 2 shipped end-to-end: distance ranking from Census 2020 ZCTA centroids, six NPPES board-cert + multi-specialty signals, three state license-sanction overlays dropping 1,720 sanctioned candidates at build, real-shaped synthetic insurance, /provider browseable index + /provider/[npi] profile pages, and a contract-shape vitest pinning live ⇄ mock parity. Data 360 Phase 2 went live on trailsignup — three Calculated Insights (HRV / vasomotor burden / sleep disruption) authored over ssot__Individual__dlm, with SF_DC_TENANT_URL wired into Vercel and the grounding endpoint now returning "Phase 2: SOQL (Health Cloud) + Data Cloud Calculated Insights"; PHASE_2_ACTIVATION_CHECKLIST.md captures the five things the original runbook got wrong (notably that a core Salesforce token is not valid against the c360a tenant and must be exchanged at /services/a360/token first). The MuleSoft live worker's DataWeave was rewritten to match the same Phase-2 contract and is now deployed to CloudHub 2.0 as v1.0.4; production /api/mulesoft/providers reports meta._source: 'live-mulesoft' end-to-end through Auth0-JWT → Flex Gateway → ngrok → the worker. The Care Router and the agent's MCP tool consume both streams: an MSCP-pathway routing decision now attaches a distance-ranked, plan-narrowed, modality-aware recommended-provider list backed by the same queryProviderDirectory the /provider UI reads.

Headless 360 audit gap #3 closed — Salesforce Platform Event egress (sink wired, dormant until env vars set)

Shipped
Details

The /proposal/headless-360 audit page originally framed gap #3 as 'Agent Fabric event-monitoring trace export' with the implication that we'd write into Salesforce's Real-Time Event Monitoring stream. Research before writing code corrected that: RTEM's event catalog (LoginEvent, ApiEvent, etc. — ~50 types) is Salesforce-platform-internal. External apps cannot define a new RTEM event type and cannot POST records into the RTEM stream — Pub/Sub API's own comparison table explicitly lists RTEM under SUBSCRIBE capabilities and 'platform events' under PUBLISH capabilities. So we shipped the actual partner-supported pattern: custom Platform Events via REST sObjects. lib/salesforce-platform-event-sink.ts emits each Agent Fabric span as a Pause_Agent_Trace__e Platform Event record (POST /services/data/v60.0/sobjects/Pause_Agent_Trace__e/) authenticated via OAuth 2.0 Client Credentials against a dedicated Connected App. spanToEventPayload maps every TraceSpan field to a custom-field shape (Span_Id__c, Task_Id__c, Operation__c, Protocol__c, Status__c, Duration_Ms__c, Started_At__c, Attributes_Json__c) with sensible truncation on attribute JSON. The sink is hooked into lib/agent-fabric.recordSpan via `void emitSpanEvent(finalSpan)` — fire-and-forget, never blocks routing, swallows all Salesforce errors, bumps process-local counters (attempted/succeeded/failed/lastError) exposed at GET /api/agent-fabric/sf-sink/config. Token cached for expires_in − 60s; 401 wipes the cache so the next call re-mints. 22 unit tests pin env parsing (non-https rejection, __e suffix requirement, trailing-slash normalization), the three-state machine, schema mapping (every field, parent-span optional, truncation tag, circular-reference safety), the no-throw invariant on 401 / network failures, and token-cache reuse across emits. Audit page updated: gap #3 row renamed to 'Agent Fabric → Salesforce Platform Event egress', wording corrected to flag that RTEM is read-only for external clients, pill flipped designed → prototype. Live-verified locally: with env unset, /config returns designed + zero counters and Care Router spans short-circuit emitSpanEvent to 'skipped' (Care Router task still completes cleanly); with env set to a bad Salesforce URL, /config returns prototype + provisioned metadata AND the Care Router task STILL completes successfully (sink fails non-blocking, exactly as designed). docs/SF_PLATFORM_EVENT_SINK_RUNBOOK.md covers Connected App procurement, the exact custom-field schema with API names that match spanToEventPayload(), end-to-end verification, rollback, and the failure modes the sink intentionally swallows. tsc clean; 456/456 vitest tests green (was 434; +22 sink unit tests); smoke 168/168 (was 167; +1 /sf-sink/config probe).

830bb8e headless-360: ship Platform Event egress sink (gap #3 of audit; dormant until activated)

Provider directory filter UI: checkboxes now read as `[ ] label`, not separated by half the page

Shipped
Details

The three checkbox filters on /provider — Only MSCP-certified, Include nearby/relevant fallback, Telehealth only — were rendering with the checkbox at the far-left of its column and the text floating to the right with a large gap. Root cause: the filter form reused `.contact-form-row` (a 2-column grid: `grid-template-columns: 1fr 1fr`) for the checkboxes, AND the global `.contact-form input { width: 100% }` stretched each checkbox to fill its grid cell — so the box sat at column-left while the span text aligned to the right of the same cell. Fixed: new container `.provider-filter-checks` (flex-wrap row, gap 0.4rem × 1.25rem) and new class `.provider-filter-check` (inline-flex with the checkbox `width: 1rem; height: 1rem; margin: 0; flex-shrink: 0`, overriding the global stretch). Markup simplified from three nested labels-with-inline-styles to three clean `<label class=provider-filter-check>` rows. accent-color: var(--brand) so the check itself reads in the Pause pink. Verified live: rendered HTML now shows each label tight-coupled to its checkbox in a single visual unit; tsc clean; 434/434 vitest; smoke 167/167 unchanged.

b3cc0d2 provider: fix filter-checkbox UI (checkbox glued to its label, no 2-col grid stretch)

Headless 360 PKCE seam shipped (gap #1 of the audit closed; dormant until External Client App env vars set)

Shipped
Details

The previous entry shipped the /proposal/headless-360 audit page — a four-row table naming the gaps between today's prototype and full Headless 360 conformance. This entry closes the first gap (PKCE External Client App OAuth flow) in the same env-driven pattern as Agentforce Voice. Shipped: lib/salesforce-headless360.ts (env-driven config validating https-only URLs + ≥32-byte session secrets; RFC 7636 PKCE helpers — base64url verifier ≥43 chars, S256 challenge via crypto.subtle; HMAC-SHA256 signed cookie envelope with timingSafeEqual verification and tamper-evidence; 3-state status machine designed/prototype/shipped) + six API routes: GET /api/salesforce/headless-360/config (public status probe, never leaks clientId/redirectUri/secret), GET /authorize (302 to Salesforce /services/oauth2/authorize with state + code_challenge + scopes + httpOnly+SameSite=Lax pending cookie), GET /callback (verifies state, exchanges code for tokens via Salesforce /services/oauth2/token, stores session in a fresh signed cookie, 302 to the originally-requested next path with open-redirect protection), POST /token/refresh (rotates the access token, updates the cookie, clears the cookie if Salesforce refuses), GET /me (calls /services/oauth2/userinfo under the session's access token), POST /logout (idempotent cookie clear). 25 unit tests pin: env-var parsing + the three-state matrix + secret omission from /config + PKCE alphabet + S256 derivation + signed-cookie tamper detection (tampered payload, forged MAC, truncation, missing separator) + JSON round-trip through serialize/sign/verify/parse. New docs/HEADLESS_360_RUNBOOK.md walks the External Client App procurement (Setup → External Client Apps → New → enable PKCE, require PKCE Verifier, scopes mcp_api+refresh_token+api, callback URL match) + the deploy-side env-var checklist + end-to-end verification + rollback. Audit page updated: gap #1 pill flipped designed → prototype, activation snippet rewritten to reflect the actually-shipped routes (not the speculative version). Live-verified against the local dev server in two modes: unset env → /config returns designed, /authorize+others 503 with actionable messages; provisioned env → /config returns prototype with scopes + authorizeUrl, /authorize returns 302 to https://test.my.salesforce.com/services/oauth2/authorize with response_type=code + S256 code_challenge + 256-bit state + scope=mcp_api+refresh_token + HMAC-signed pause_h360_pending cookie. tsc clean; 434/434 vitest tests (was 409; +25); smoke 167/167 (was 166; +1 API endpoint /config).

a20806e headless-360: ship PKCE External Client App seam (gap #1 of audit; six routes, 25 tests, dormant until activated)

Headless 360 — conformance audit page maps every Pause surface onto Salesforce's TDX 2026 architecture (REST + MCP + A2A)

Shipped
Details

Salesforce announced Headless 360 at TDX 2026 — the umbrella architecture that ties Agentforce 360 + Agent Fabric (MuleSoft) + Data Cloud + the Salesforce-hosted MCP server under three integration patterns (REST/SOAP, MCP, A2A) with one identity model (OAuth 2.0 Authorization Code + PKCE via an External Client App, scopes mcp_api + refresh_token). The PO asked for it. Honest framing matters: 'Headless 360' as of June 2026 is a Salesforce Architects blog family (TDX 2026), not yet a developer.salesforce.com doc family — so 'add Headless 360' doesn't map to a single SDK install. What CAN ship today is the conformance audit: a single-page mapping of every Pause surface onto the three patterns, with status pills on every row, plus the explicit list of what's MISSING for full Headless 360 conformance (the PKCE External Client App seam under the new mcp_api scope). Shipped: new /proposal/headless-360 page. Three sections worth calling out: (1) Three-card pattern overview (REST + MCP + A2A) with the live Pause surfaces in each — Data 360 grounding / MuleSoft Experience APIs / Agentforce embedded chat for REST; the Pause MCP server + host for MCP; the A2A Care Router endpoint + Agent Card for A2A. (2) Surface-map table — 8 rows, every Pause Salesforce-adjacent surface classified by pattern + auth model + state + pill, with cross-links to the per-surface briefs. (3) Audit table — 4 named gaps between today's prototype and full Headless 360 conformance: PKCE External Client App OAuth flow (designed); mcp_api scope on the Pause MCP server (designed); Event Monitoring sink from the Agent Fabric (designed); Salesforce CLI parity (future). Each gap names the missing module + the activation path, mirroring the env-driven pattern just used for Agentforce Voice. Cross-linked from /proposal/mcp + /proposal/agentforce + /proposal/agentforce-voice + /proposal/data-360 as the new 'where this fits' anchor in each readDeeper section. Also includes the activation-shape OAuth snippet (SF_HEADLESS360_CLIENT_ID + base URL + redirect + mcp_api + refresh_token scopes) plus the 4 routes that would land when the PKCE seam ships. Smoke jumped 163 → 166 (+1 route + 2 cross-link probes). tsc clean; 409 vitest tests still green.

d357625 headless-360: ship conformance audit page + cross-links from MCP/Agentforce/Voice/Data-360

Agentforce Voice — partner-web seam wired (env-driven; audio round-trip gated on Agentforce Contact Center licensing)

Shipped
Details

Salesforce announced Agentforce Voice GA on 2025-10-13 and shipped Agentforce Contact Center (the add-on that bundles native voice + CCaaS partner integrations) on 2026-03-10. The PO asked for it on the Pause prototype. Honest framing matters here: the partner-web developer surface is sales-gated as of 2026-06-24 (no public LWC, no Agent API voice endpoint, no SDK index page that survives a curl), and the audio round-trip requires Agentforce Contact Center licensing + a CCaaS partner contract (Amazon Connect / Five9 / NiCE / Vonage). Shipping the licensing-dependent integration without the licensing would either be vaporware or a lie. Shipped instead: the prototype-side seam, fully env-driven and degrading honestly. lib/agentforce-voice.ts defines a 4-env-var contract (PROVIDER + BASE_URL + DEPLOYMENT_REF + AGENT_DEPLOYMENT) with an optional 5th (LANGUAGE) and a 6th verification flag (VERIFIED) that promotes status from 'prototype' to 'shipped' after the operator records a verified round-trip. GET /api/agentforce/voice/config returns a public-safe payload (status + provider + agentDeployment + language) and INTENTIONALLY omits baseUrl + deploymentRef (those are partner-side opaque identifiers a third party could use to initiate a session). A new <AgentforceVoiceButton/> component renders one of three affordances driven by /api/agentforce/voice/config: 'designed' (disabled with activation-plan copy), 'prototype' (enabled, click shows 'verification pending' toast), 'shipped' (enabled, real handshake lands on activation day). New /proposal/agentforce-voice page hosts the button + a Why-voice-first cards section + the activation table + the 5-env-var checklist. docs/AGENTFORCE_VOICE_RUNBOOK.md is the operator-readable procurement+activation checklist (Salesforce sales path, CCaaS partner pick, deploy-side env vars, verification, rollback). 16 unit tests pin the env-var parsing + 3-state matrix + secret-omission invariant. Smoke probe added: /api/agentforce/voice/config in the API matrix + /proposal/agentforce-voice in static routes. tsc clean; 409/409 vitest tests green (was 393; +16 voice unit tests); smoke 163/163 (was 161; +1 route +1 API). Three live states verified end-to-end against a local dev server: unset → designed; provisioned → prototype with secrets omitted from /config; provisioned + VERIFIED=true → shipped. The page deliberately does NOT claim 'voice input via Web Speech API' as Agentforce Voice — that's a separate product (voice input for chat), explicitly out of scope here for clarity.

7c2e57f agentforce-voice: ship partner-web seam (env-driven, gated on Contact Center licensing)

Founder bio refreshed from real LinkedIn content (career arc, education, alumniOf)

Shipped
Details

The earlier polish pass added structure (Person JSON-LD, LinkedIn CTA) but explicitly didn't touch the prose because the public LinkedIn fetcher returned HTTP 999 (their anti-scrape signal) — I refused to invent career history. Now sourced directly from the founder's PDF LinkedIn export: bio paragraph 1 names her current role (Principal Agentforce/Data Cloud Activation Solution Engineer at Salesforce, TMT, Dec 2025–present) and the prior platform-vendor arc (First American → VMware Tanzu → MuleSoft → Salesforce ISV Evangelist → Red Hat), plus the healthcare-domain context from her TriZetto tour on the Facets / NetworX claims platform. Bio paragraph 2 adds the in-flight education (USC Marshall Executive MBA May 2027; UC Berkeley Haas Executive Program in AI and Digital Strategy June 2026) and the earlier degrees (MS Software Engineering Kansas State; BS Computer Science UMKC). The verification line under the LinkedIn CTA now quotes the actual LinkedIn headline verbatim so a visitor confirming the profile sees text that matches what's on the LinkedIn page. JSON-LD enriched with `alumniOf` for all four institutions, with .edu URLs as the verifiable bridge. The career arc explains why she's the right founder for this specific company — every platform layer the Pause prototype talks to today (Agentforce + Data Cloud + MuleSoft + Salesforce + JBoss/Red Hat infra) has been her actual day job in a previous chapter. tsc clean; 393/393 vitest tests; smoke 161/161.

12fecf5 about: refresh founder bio from real LinkedIn content (career arc + education + JSON-LD alumniOf)

Founder bio: richer LinkedIn affordance + Person JSON-LD on /about

Shipped
Details

The founder card on /about had a small icon-link to LinkedIn — fine for discoverability but a thin signal for previewers (LinkedIn / Google) trying to resolve the page to a Person identity. The actual bio content didn't change (no LinkedIn-scraped claims; LinkedIn returns HTTP 999 to unauthenticated fetchers, and inventing career history would be the wrong call). What did change: (1) Added a standalone Person JSON-LD block to /about scoped to Maggie C. Hu — same shape as the founder block already in the root Organization JSON-LD at app/layout.tsx, with sameAs to LinkedIn + GitHub, so search engines and LinkedIn's own scraper can resolve the founder card to her LinkedIn identity directly from this page (not just from the org graph at /). (2) Promoted the icon-only LinkedIn link to a labeled CTA — 'Connect on LinkedIn' button with the visible handle 'linkedin.com/in/hucmaggie' alongside, brand-tinted background, hover + focus states, and rel='me author' microformat hints. (3) Added a short verification line right below the CTA so a visitor can confirm they're on the right profile ('the LinkedIn page lists Pause-Health.AI as the current company, with this site in the contact info'). On narrow phones the long handle text is hidden so the CTA + label stay legible; the verify line below names the URL out loud. 393/393 vitest tests still green; smoke unchanged at 161/161; tsc clean.

446a2e5 about: richer founder LinkedIn affordance + Person JSON-LD on /about

MCP Bridge: turned ON in production — Care Router host-mode is now serving live traffic at pause-health.ai

Shipped
Details

The previous entry shipped the MCP Bridge code path (per-request MCP host inside the Care Router task handler, loopback to /api/mcp, fallback to direct-call on host failure). This entry activates it: PAUSE_MCP_HOST_ENABLED=on added to Vercel production env; triggered a new prod deploy (dpl_BkoYS1iDj4zUF1xZhr6vpJfhpdXq, aliased to pause-health.ai); verified end-to-end against production with a POST to /api/agents/care-router/tasks (patientZip=92614). The agent fabric span on the verifier task carries `mcpHostEnabled=true`, `mcpHostRemoteCount=1`, and `mcpHostAttempts=[{remoteId:'loopback',ok:true}]` — proving the production Care Router resolved its provider recommendation by calling find_menopause_providers as an MCP tool against https://pause-health.ai/api/mcp, NOT by directly calling /api/mulesoft/providers. Response shape identical to the direct-call path (same 2 MSCP providers, same distance ranks); durationMs 1731 stays in the existing latency band. Rollback is a one-liner if anything goes wrong: `vercel env rm PAUSE_MCP_HOST_ENABLED production` + redeploy; the adapter's direct-call fallback is exercised on every host error anyway, so the surface degrades cleanly even without the env removal. The external slot (PAUSE_MCP_HOST_REMOTES) is still empty — turning on production loopback first is the honest 'eat your own dogfood' move before pointing the host at a partner's MCP server.

0dcc65c changelog: turn MCP Bridge on in production (host-mode live at pause-health.ai)

MCP Bridge: Pause's Care Router agent is now an MCP HOST — calls external MCP servers, not just exposes its own

Shipped
Details

The MCP work to date has been server-side: any AI agent can use Pause as a tool source via npx @pause-health/mcp (stdio) or https://pause-health.ai/api/mcp (Streamable HTTP). The other direction — Pause's own agents using a partner's MCP server as a tool source — was unwired. Closed: new lib/mcp/host.ts (MCPHost class, per-request lifecycle, multi-remote with first-ok-wins iteration, last-error surfaced for traces, configurable timeouts, idempotent close()) + lib/mcp/provider-lookup.ts (an adapter satisfying the existing ProviderLookup contract via find_menopause_providers tool calls; falls back to the legacy direct-call path on host failure so routing decisions NEVER regress when an MCP remote is down). Two remote slots ship today: a loopback to <origin>/api/mcp (always-on, demonstrates host architecture without a partner dep) and a configurable external slot via PAUSE_MCP_HOST_REMOTES (JSON-encoded array of {id,url,headers?}). The Care Router task endpoint at /api/agents/care-router/tasks now opens an MCP host per request (no module-level state — matches Vercel's serverless model) when PAUSE_MCP_HOST_ENABLED is set, threads providerLookup through route(), records per-attempt host attribution on the agent fabric span (mcpHostEnabled, mcpHostRemoteCount, mcpHostAttempts[]), and tears the host down in a finally block. Live end-to-end verified: POST tasks/send with patientZip=92614 returns identical RoutingDecision shape under host-on and host-off (same 2 providers, same distance ranks, same source 'mock' because loopback fronts the in-process directory). 17 new tests (10 host config + iteration; 6 adapter shape + fallback chains; 1 in-process integration round-trip using InMemoryTransport) bring total to 393 passed (was 376). tsc clean. /proposal/mcp now has a prototype-pilled 'Pause as MCP host' section laying out the why-ship-both-directions story. Smoke unchanged at 161/161.

f333c2d mcp: ship MCP Bridge — Care Router is now an MCP host

MCP server now ships a Streamable HTTP transport at /api/mcp — discoverable by the Agentforce 3.0 Registry

Shipped
Details

The mcp/ package shipped stdio-only — fine for Claude Desktop and Cursor, but Salesforce Agentforce 3.0 (the June 2025 release that introduced the native MCP client) registers external MCP servers through the Agentforce Registry which expects an HTTP-fronted server; stdio is not registry-callable. The prior README pointed at an 'External Services connector or Agentforce MCP gateway' — wording that's obsolete for 3.0 intake. Closed: extracted the four tool registrations (get_patient_timeline, get_patient_intake, find_menopause_providers, experience_api_health) into mcp/src/tools.ts behind a transport-agnostic createPauseMcpServer factory; mcp/src/server.ts now imports from there for the stdio path. Added a Next.js App Router route at frontend/app/api/mcp/route.ts using @modelcontextprotocol/sdk's WebStandardStreamableHTTPServerTransport (web-standard Request/Response, drops directly into the App Router handler shape; pinned runtime='nodejs' because the SDK uses Node-only APIs). Stateless mode (no sessionIdGenerator) matches Vercel's serverless invocation model and is what the Registry's connection profile expects today. The frontend's tools.ts is duplicated from mcp/src/tools.ts because frontend/ and mcp/ are separate npm packages (no monorepo); a parity vitest (frontend/lib/mcp/tools.parity.test.ts) compares the two file bodies and fails CI if they drift. Both transports verified end-to-end: stdio (cd mcp && npm run smoke) lists 4 tools + calls each one against the local dev server; Streamable HTTP (an MCP Client over StreamableHTTPClientTransport against http://localhost:3000/api/mcp) lists 4 tools and successfully calls all four. Smoke matrix extended with a new step [4/4] that POSTs an MCP initialize and asserts the SSE response carries serverInfo={name:pause-health-mcp,version:0.3.0} + tools capability advertised — 161/161 pass (was 160). README + /proposal/mcp + /proposal/agentforce updated with the actual Agentforce 3.0 Registry flow (Setup → Agentforce Registry → New MCP server → paste https://pause-health.ai/api/mcp → allowlist tools → land in Asset Library → attach to a Topic in Builder → validate in Plan Canvas). Auth specifics for the Registry's connection profile live in the gated 'MCP for Agentforce' help article and are flagged accordingly in both the README and the prototype page; we'll wire OAuth or Named-Credential auth when a partner needs it. The prototype endpoint serves the public mock APIs and runs unauthenticated by design. tsc clean; 376 vitest tests green (was 375; +1 for the parity test).

0da5070 mcp: ship Streamable HTTP transport at /api/mcp for Agentforce 3.0 Registry

Smoke test now writes per-target reports — prod runs no longer clobber the committed local-evidence file

Shipped
Details

frontend/scripts/smoke-test.mjs always wrote to SMOKE_TEST_RESULTS.md regardless of BASE_URL, so running it against production (BASE_URL=https://pause-health.ai) overwrote the committed local-evidence file the /roadmap page points at. The diff after a prod run looked like a regression because production was lagging the deploy and had fewer rendered changelog entries → fewer internal links → fewer passing probes, even though both targets were healthy on their own. Burned ~30 min in this session figuring it out. Fixed: localhost / 127.0.0.1 still writes to SMOKE_TEST_RESULTS.md (the committed evidence file); any other URL writes to SMOKE_TEST_RESULTS.<host-slug>.md (e.g. SMOKE_TEST_RESULTS.pause-health-ai.md). Per-target reports are gitignored so ad-hoc prod runs don't sneak into a commit. A REPORT_PATH env var overrides either way for future flexibility. Production smoke was green (131/131) and prod is just one deploy behind main — once 861b3e9 + this commit ship, prod's counts will catch up to local's 160/160.

861b3e9 smoke: correct the API-endpoints count (16, not 17) and break out persona routes2671fcb smoke: write per-target reports so prod runs don't clobber committed evidence

End-to-end smoke test refreshed (132/132 → 160/160) against the post-Phase-2 surface

Shipped
Details

Committed SMOKE_TEST_RESULTS.md was dated 2026-06-08 — the surface has grown 20+ commits since (provider directory pages, telehealth filter end-to-end, recommended-providers helper, JHE bootstrap docs, MuleSoft iteration 8 deploy, real-JHE pytest marker, roadmap+integration reconciliation), and none of the new routes/links were in the smoke matrix. Re-ran against a fresh `next dev`: pass 160, warn 0, fail 0. Static pages 35→38, unique internal links 77→102, elapsed 15s→10s. API endpoints stayed at 16 (the smoke matrix was already complete on that axis at the previous run). Roadmap Now-horizon line bumped to the new counts and explicitly broken out as '38 static routes + 4 persona-specific routes + 102 unique internal links + 16 API endpoints' so the totals reconcile to the 160-pass headline. No regressions surfaced. tsc clean; 375 vitest tests green.

ab6d6af smoke: refresh end-to-end smoke-test results (160/160 pass)

Roadmap + integration page: reconcile pill states with the work shipped over the past two weeks

Shipped
Details

Roadmap had drifted relative to what's actually on main. Three corrections: (1) /roadmap MuleSoft iteration 8 — Phase-2 contract DataWeave was pilled 'planned' with a 'committed but undeployed' detail, but iteration 8 actually shipped 2026-06-16 as v1.0.4 on CloudHub 2.0 (commit ca2229a); flipped to 'shipped' and replaced the detail with the live verification (direct CloudHub returns the full Phase-2 field set; pause-health.ai/api/mulesoft/providers reports meta._source:'live-mulesoft') plus the two non-obvious deploy gotchas the maintainer captured (Connected App needs Runtime Manager + Exchange scopes per surface; -DmuleDeploy doesn't publish to Exchange so the deploy is two commands). (2) /roadmap pause_ingest → real JHE round-trip entry extended to mention the 2026-06-23 PAUSE_USE_REAL_JHE=1 pytest marker shipping — same 7 contract assertions now run against the live JHE Django instance, not just the periodic manual smoke; surfaced + documented 2 more mock-vs-real divergences. (3) /roadmap MuleSoft iterations 1–7 → iterations 1–8 (the same iteration-8 ship), and Now-horizon explainer trimmed accordingly. /proposal/integration Phase 0 + Phase 1 details extended in parallel so the integration brief's claim line ('verified against real JupyterHealth Exchange') is backed by the new automated contract suite rather than a manual smoke run. tsc clean; 375 vitest tests green.

0f8bc99 roadmap+integration: reconcile pill states with shipped work

JupyterHealth Exchange: opt-in pytest marker now runs pause_ingest's contract test against a real JHE instance, not just the wire-level mock

Shipped
Details

The JHE_SETUP_RUNBOOK called out Path B as a sketch — an opt-in PAUSE_USE_REAL_JHE=1 pytest marker that would swap the in-process JheMockServer fixture for IngestConfig.from_env() so the same contract assertions run against a real JHE Django instance, but the sketch was never wired. Closed: shipped pause_ingest/tests/conftest.py (registers the real_jhe marker + a collection hook that swaps modes on PAUSE_USE_REAL_JHE and skips the mock-only test_exchange_integration module when the real mode is on) and pause_ingest/tests/test_exchange_real_jhe.py (7 tests mirroring the mock contract suite: token exchange, mapped-handler OMH write, auxiliary-handler write with X-JHE-FHIR-Source-ID, invalid-credentials 4xx, FHIR validator rejection on missing subject reference, no-cross-patient-leakage on unknown patient_id, and the end-to-end raw-plus-derived round-trip with derivedFrom pointers resolving to the JHE-assigned ids). Default pytest run unchanged: 67 passed, 7 skipped (real_jhe gated off). PAUSE_USE_REAL_JHE=1 pytest run against the live jhe-local Docker stack: 66 passed, 8 skipped (mock contract gated off) — 7/7 real_jhe tests green. Two more mock-vs-real divergences the first real-mode run surfaced beyond the 3 fixed on 2026-06-16: (1) real JHE's POST /Observation response body does NOT include valueAttachment — only the envelope — so the test validates the OMH payload via the read-back path instead of the POST response, and the runbook now documents the divergence; (2) real JHE's GET /Observation?patient=<unknown> does NOT return an empty Bundle — it returns whatever the OAuth client is authorized to see across its studies, ignoring the unknown patient= filter — so the test asserts the no-leakage invariant (no result is subject-referenced at the unknown patient) rather than fetched==[]. The JHE Exchange line on /proposal/integration and /roadmap can now claim a continuously-verified real-JHE contract, not just a wire-level mock + periodic manual smoke run.

3b08d6b jhe: ship the PAUSE_USE_REAL_JHE=1 opt-in pytest marker for pause_ingest's contract suite

JupyterHealth Exchange: pause_ingest now exercises both JHE write paths end-to-end (mapped + auxiliary)

Shipped
Details

Closing out the loose end called out in the previous JHE entry. The first real-JHE run only wrote the raw OMH heart-rate observation (which routes to JHE's mapped Observation handler); the derived HRV-features path was left undone because it routes to JHE's *auxiliary* FhirAuxResource handler, which 400s without an X-JHE-FHIR-Source-ID header pointing at a registered FhirSource row. Plumbed end-to-end: IngestConfig grew an optional fhir_source_id field loaded from JHE_FHIR_SOURCE_ID; upload_observation now sends the X-JHE-FHIR-Source-ID header whenever the config carries it (mapped handler ignores the header, so always sending it is safe); examples/oura_sample_upload.py uploads BOTH observations on every run and now ends with 'OK — uploaded and round-tripped 2 observation(s)' (raw → server pk integer 60014; derived → server pk UUID 1d752859-… with derivedFrom pointing at 60014); jhe-local/bootstrap.sh reads back the FhirSource pk after creation and surfaces it in the printed env block as JHE_FHIR_SOURCE_ID=90003 so the next contributor's first run uploads through both paths without extra Django shell work; .env.example documents the new field. The wire-level mock was tightened in lockstep — codings outside https://w3id.org/openmhealth now 400 without the header, mirroring real JHE's mapped-vs-aux routing contract; a new test_upload_aux_routed_observation_requires_fhir_source_id_header pins both directions (no fhir_source_id → HTTPStatusError 400 with the JHE error string in the body; with fhir_source_id → success and the mock observed the header value), and the existing core test was tightened to assert the mock did NOT observe the header on a mapped-handler write so the symmetric direction can't drift back. The fourth runbook 'known unknown' (derivedFrom resolution against real JHE) is closed empirically: JHE accepts the derived row with its derivedFrom pointer to the raw row's server-issued integer id and renders the same Bundle search for the patient with both kinds present. 67 pause_ingest tests + 375 frontend tests + tsc all green; transcript appended in docs/JHE_REAL_RUN_2026-06-16.md.

141e148 jhe: wire pause_ingest's auxiliary-handler write path (derived HRV features) end-to-end

JupyterHealth Exchange: pause_ingest now round-trips against a real JHE Django instance, not a wire-level mock

Shipped
Details

The integration line on /proposal/integration and /roadmap was correctly pilled `designed` because pause_ingest was only passing against an in-process JHE mock — there had never been a real JHE Django instance behind it. Closed today: stood up real JupyterHealth Exchange end-to-end on the local Docker host (postgres:16 on 127.0.0.1:5433, a locally-built jhe-local:latest image from the upstream Dockerfile, an RS256 OIDC signing key, the canonical seed fixtures including 5 Patients / 6 DataSources / 16 OMH CodeableConcepts), wired a client_credentials OAuth app named pause-ingest whose user is the Patient's JheUser (so client_credentials tokens authenticate as that patient and pass JHE's `subject == user.get_patient()` write check), bound it to the Oura DataSource through a Study with explicit per-scope StudyScopeRequest + StudyPatientScopeConsent rows for every OMH coding pause_ingest writes, and ran the full pipeline end-to-end: examples/oura_sample_upload.py converted a real Oura sample through omh-shim, built a FHIR R5 Observation, POSTed it to /fhir/r5/Observation, got back a server-issued Observation id, and read it back via JupyterHealthClient. `OK — uploaded and round-tripped 1 observation`. The JHE_SETUP_RUNBOOK predicted ~5 known unknowns; three of them fired on the first real-JHE run and were all pause_ingest-side bugs the over-permissive mock had not pinned: (1) pause_ingest requested OAuth scope strings observation.read / observation.write, but JHE's OAuth2 vocabulary is fixed at openid+email and rejects everything else with invalid_scope (JHE authorizes FHIR writes by Study/Patient/Scope consent, not by OAuth scope) — fixed by making `_fetch_oauth_token`'s scope arg optional and dropping it at both call sites; (2) Content-Type and Accept were application/fhir+json which JHE's DRF parser rejects with 415, must be application/json — fixed in upload_observation; (3) the OMH coding shape `system: https://w3id.org/openmhealth/schemas/<ns>` + `code: <schema-name>` did not match JHE's mapped-Observation routing criteria (`code=https://w3id.org/openmhealth|`), so writes silently fell through to the auxiliary FhirAuxResource handler which then 400'd on the missing X-JHE-FHIR-Source-ID header — fixed in omh_to_fhir_observation to emit `system: https://w3id.org/openmhealth` with `code: omh:<schema>:<version>` (matches the seeded CodeableConcept.coding_code shape verbatim). The mock was tightened in the same pass — its round-trip assertion now pins {`omh:heart-rate:2.0`, `hrv-time-domain`} so the routing-criteria shape can't drift back. Captured the full transcript at docs/JHE_REAL_RUN_2026-06-16.md and shipped jhe-local/bootstrap.sh + teardown.sh — idempotent scripts that bring the entire stack up from `./bootstrap.sh` and tear it down from `./teardown.sh`, so the next contributor can repeat the run in 5 min instead of an hour. Status pills flipped: JHE Exchange `designed → prototype`, Phase 1 `designed → prototype` (now reads 'Shipped 2026-06-16'). 66 pause_ingest tests + 375 frontend tests + tsc all green.

d49cd2d jhe: pause_ingest round-trips against a real JupyterHealth Exchange instance

MuleSoft: Phase-2 /providers contract is live on CloudHub (v1.0.4 deployed end-to-end)

Shipped
Details

The Phase-2 DataWeave rewritten in commit cf4a42d (2026-06-15) was sitting committed but undeployed — direct curl to the CloudHub worker still returned the pre-Phase-2 shape (no lat/lng, no serviceSignals/licenseStatus/insuranceAccepted/credentialSource, no top-level matchType/sort), and production /api/mulesoft/providers degraded cleanly to mock-fallback because the ngrok tunnel had gone dormant. Closed both: bumped pom.xml to 1.0.4, restarted ngrok against the pinned cattail-reactive-sassy.ngrok-free.dev domain pointing at the still-running Flex Gateway Docker container (up 7 days, healthy, port 8081), and pushed the new artifact through Anypoint. Two non-obvious deploy gotchas were captured for next time: (1) the rotated pause-prototype-cloudhub Connected App needed scopes added per surface — Runtime Manager (View Environment, View Organization, Read/Create/Delete/Download Applications) on Pause Health > Sandbox AND Exchange (Contributor + Viewer/Administrator) at the Pause Health business-group level (Exchange is org-wide, not env-scoped); without the Exchange grants the deploy phase looked further than 'business group invalid' and made it as far as creating the deployment record, but Runtime Manager then 403'd trying to read the artifact from Exchange and the new replica went into Kubernetes CrashLoopBackOff while the previous-config replica kept serving traffic. (2) mule-maven-plugin's -DmuleDeploy goal does NOT publish to Exchange — it assumes the artifact already exists and just calls Runtime Manager. So the deploy is two commands: a plain mvn deploy:deploy-file against the Exchange v2 maven endpoint (`https://maven.anypoint.mulesoft.com/api/v2/organizations/<bgId>/maven`) — Exchange v3 returns 412 because it requires a runId-precondition handshake the standard maven-deploy-plugin doesn't perform — followed by mvn -DmuleDeploy deploy for the runtime side. Verified end-to-end: direct CloudHub /providers?zip=92614&menopause=true&limit=2 returns the full Phase-2 field set (latitude/longitude/distanceMiles, serviceSignals, licenseStatus, insuranceAccepted with 5 plans, credentialSource:'curated-overlay', top-level sort:'score'); production proxy at pause-health.ai/api/mulesoft/{health,providers} reports meta._source:'live-mulesoft' through the gateway. Local shell still can't reach the tunnel (TLS reset on handshake — VPN/Zscaler edge issue documented in the iteration-3 runbook) but Vercel's network reaches it fine, which is what the demo runs on.

ca2229a mulesoft: deploy v1.0.4 with the Phase-2 /providers contract end-to-end

Data 360: reconciled the committed CI SQL + runbooks with the unified_id__c contract that actually runs

Shipped
Details

Documentation/artifact drift cleanup, and a real trap: the committed Data Cloud mock SQL would have been REJECTED if anyone pasted it. data-cloud/_mock_path.sql grouped by ssot__Id__c and emitted bare (non-__c) measure columns — but the DC Calculated-Insight validator rejects the ssot__Id__c alias (the inner __ trips it) and requires output columns to end in __c, and the client (getWearableInsights) filters [unified_id__c=<contact-id>] and reads the *__c columns. So the committed mock SQL contradicted both the validator and the code, and didn't reflect the CIs that are actually activated on trailsignup (which were hand-fixed during activation). The real per-CI .sql files already had the right shape; the mock and the prose hadn't caught up. Fixed: _mock_path.sql now aliases the Individual's ssot__Id__c → unified_id__c, suffixes every measure column with __c, fully-qualifies its column refs, and documents the three validator rules inline so it stays in lockstep with the real CI SQL and data-cloud.ts (also corrected the stale header comment that claimed the code filters on ssot__Id__c). PHASE_2_ACTIVATION_CHECKLIST.md's Step-5 verification query now selects from the __cio object filtered by unified_id__c, and its dated session-2 snapshot carries a session-3 correction. MULESOFT_PHASE_2_DATA_CLOUD.md got a callout that the canonical copy-paste SQL is the committed data-cloud/*.sql (its inline snippets predate the validator rules and are conceptual only), plus fixes to the verify query, the unified-individual mapping, and the failure-mode entry. Docs + SQL only — not executed by app code, so no runtime/test/build impact; the point is that the committed artifacts now match what's live.

40d9461 data-360: reconcile committed CI SQL + runbooks with the activated unified_id__c contract

Data 360: the live Data Cloud client finally has tests (a360 token exchange + CI mapping)

Shipped
Details

The Phase-2 Data Cloud client (lib/salesforce/data-cloud.ts) is the grounding path production trailsignup actually runs — and it had zero TypeScript coverage, to the point where it exported a _resetDataCloudTokenCacheForTests hook that literally nothing called. The riskiest, most fiddly piece is the a360 two-legged token exchange: a normal Salesforce client-credentials token is NOT valid against the c360a tenant, so it has to be swapped at /services/a360/token for a Data-Cloud-scoped token (the single thing the original runbook got wrong — see PHASE_2_ACTIVATION_CHECKLIST.md). New data-cloud.test.ts (19 tests) drives the module through a URL-routing fetch mock that distinguishes the four endpoints it touches (core /services/oauth2/token, the a360 exchange, the CI endpoint, and /api/v1/query), so request ordering and the Promise.all fan-out don't matter. It pins: the config gate (needs SF + SF_DC_TENANT_URL, and that the tenant URL does NOT auto-derive); the exchange's CDP grant_type + subject_token shape; the exchange-returned instance_url winning as the tenant host over the configured SF_DC_TENANT_URL (and the CI call carrying the exchanged DC bearer, not the core one); token caching, re-exchange after expiry, the reset hook, and graceful degradation to null when the exchange fails or omits access_token/instance_url; the CI request shape (GET /insight/calculated-insights/{name}?filters=[unified_id__c=…] with literal brackets, filter omitted when absent), dcQuery POSTing SQL, and non-ok surfacing the status; and the row→CalculatedInsight mapping — including the source-independent `kind` the Care Router now branches on, id sanitization, per-insight null on empty rows, and whole-call degrade to null on any CI error. No runtime change; pure coverage of the live path. 375 frontend tests green; next build clean.

cfd1b8e data-360: test the live Data Cloud client (a360 exchange + CI mapping)

Data 360: grounding insights now match by a stable kind, not the id that drifts live

Shipped
Details

A silent mock⇄live drift in the highest-stakes path. The Care Router grounds its routing rationale on Data 360 Calculated Insights, but it keyed on the mock's insight ids — insight.hrv-zscore-30d and insight.days-since-mscp-contact. The live Data Cloud + Health Cloud path emits different ids for the very same concepts (insight.hrv-rmssd-30d off the HRV RMSSD CI; insight.days-since-last-clinical-contact off the latest Health Cloud Case), so the moment trailsignup flipped from mock to the real org the HRV and last-contact rationales silently stopped firing and groundingUsed.insightsCited collapsed to vasomotor-only — with no error, because the only insight whose id happened to match on both paths was the vasomotor one. The tests never caught it: they only ever fed mock ids. Fixed it at the contract: CalculatedInsight gains a source-independent `kind` classifier (InsightKind: hrv-variability | vasomotor-burden | sleep-disruption | days-since-clinical-contact | care-program-enrollment | care-plan-status), set on every mock insight (data-360.ts) and every live insight (grounding.ts's SOQL insights + baselines, data-cloud.ts's three CIs). The router now matches by kind first and falls back to the known mock+live id-aliases for any fixture that predates the field, and it cites the ACTUAL matched id so insightsCited is honest on whichever path produced it. The last-contact rationale text is now source-agnostic ('no documented clinician contact in N days') since the live signal is any clinical Case, not specifically an MSCP encounter. Three new tests pin it shut: a live-id grounding fires all three rationales (the exact regression), a renamed id carrying the right kind still matches and cites under its own id, and the real mock GroundingContext is fed straight through to assert its kinds line up with what the router branches on. 356 frontend tests green; next build clean.

f4b9664 data-360: match grounding insights by stable kind, not the drifting id

MSCP feed: certification provenance is now visible per-provider (curated vs self-reported)

Shipped
Details

The MSCP feed flags a provider menopauseCertified two honest ways — a curated overlay roster (today synthetic, tomorrow the licensed Menopause Society feed) and a self-reported MSCP/NCMP credential token in the provider's own NPPES record. But the ingest pipeline appended an 'MSCP' badge to overlay providers, which erased the distinction in the credentials array, and the flag itself was a bare boolean — so the UI and the agent literally could not tell a curated-roster provider from a heuristic keyword match. Added a credentialSource field ('curated-overlay' | 'self-reported', present only on certified rows) across the whole surface in mock⇄live⇄OAS parity. The Python dataclass + nppes.py now record it natively going forward (computed BEFORE the badge append, with overlay membership authoritative so it wins over a coincident self-report). For the already-committed national artifact (built before the field existed), the frontend reconstructs it with deriveCredentialSource() — prefer a value the record carries, else derive from overlay membership — backed by a new lib/mscp-overlay.ts that single-sources the 7 overlay NPIs and is pinned against provider_ingest's fixture so the two can't drift. The live CloudHub worker's DataWeave derives the same value off the same NPI list (so live matches mock), both OAS specs declare it, and the /provider/[npi] profile shows an honest source line ('The Menopause Society certified-practitioner roster (curated)' vs 'self-reported … not independently verified by Pause'). This also closes a silent-refresh trap: a new committed-artifact invariant asserts a non-overlay (self-reported) certified cohort survives, and the mock tests assert both sources appear nationally — so a monthly NPPES refresh that dropped every self-reporter fails loudly instead of hiding behind the 7 hardcoded overlay personas. Frontend: 353 tests green; next build clean; both OAS + the worker XML parse. Python: records/nppes/tests py_compile clean (full pytest runs on the maintainer's py3.10+ refresh box).

f50d2c7 mscp: surface certification provenance (curated-overlay vs self-reported) end-to-end

Provider UI: single-sourced the display-label maps (the last duplication)

Shipped
Details

Refactor closing out the Provider UI thread. Three surfaces render the same provider data — the directory index (/provider), the profile (/provider/[npi]), and the shared RecommendedProviders list (live Care Router card + scripted intake fallback) — and each carried its own copies of the service-line signal + insurance plan label maps. Adding a new NPPES signal token or insurance plan was a three-file edit that silently drifted (the maps had already diverged once). Extracted everything into lib/provider-labels.ts. The one subtlety worth preserving: the profile deliberately uses spelled-out signal labels ('Board-certified OB/GYN', 'Women's Health Nurse Practitioner') where it has the room, while the chip rows and the inline recommendation list use compact ones ('Board-cert OB/GYN', 'Women's Health NP') — so the module exports two vocabularies (SIGNAL_LABELS + SIGNAL_LABELS_VERBOSE) over a single token key set, plus one shared PLAN_LABELS. The directory and profile import the helpers directly; recommended-providers keeps its recommendedSignalLabel / recommendedPlanLabel exports as thin delegates so its consumers and tests are untouched. New lib/provider-labels.test.ts (5 tests) pins both vocabularies, the raw-token fallback, PLAN_OPTIONS↔PLAN_LABELS mirroring, and the real guard — that the compact and verbose signal maps cover exactly the same tokens so they can't drift apart again. No UI change; 345 frontend tests green; next build clean.

334c6ae provider: single-source the provider display-label maps

Provider UI: made the directory discoverable + fixed the live card's missing ?from

Shipped
Details

Two smaller Provider-UI follow-ups. (1) Discoverability: /provider was a real patient-facing page reachable only from the homepage CTA and proposal prose — it was missing from the sitemap, the footer, and the smoke test, so it was effectively invisible to crawlers and to anyone not on the landing page. Added it to app/sitemap.ts (weekly, priority 0.75), the footer 'Product' group as 'Find a Provider', and scripts/smoke-test.mjs (the index, a filtered query that also exercises the new ?telehealth + ?menopause params, and a /provider/[npi] profile with ?from for the distance chip). Deliberately left the curated top + mobile primary nav alone — that's a marketing-IA decision, not a defect. (2) ?from consistency: the live 'Latest Care Router decision' card rendered its recommended providers without fromZip, so unlike the scripted intake fallback its profile links never carried ?from and the profile's distance-from-your-ZIP chip silently never appeared. The Care Router span now records recommendedProvidersZip (the same query ZIP that drove the distance ranking), and the card reads it and threads fromZip through RecommendedProviders. 340 frontend tests green; next build clean.

58776aa provider: discoverability (sitemap/footer/smoke) + carry ?from through the live decision card

Provider UI: telehealth filter end-to-end + fixed the profile navigation dead-end

Shipped
Details

Provider-directory polish in two parts. (1) Telehealth filter: telehealth already drove a whole fallback tier (certified-remote) and showed as a chip on every card and profile, but a patient who specifically wanted a virtual visit had no way to filter for it. Added an opt-in telehealth filter and threaded it through the entire surface in mock⇄live⇄OAS parity — the standard the rest of this stack holds: queryProviderDirectory gained a telehealth? opt applied to the candidate pool BEFORE the tier ladder (exactly like the insurance filter, so a 'relevant-local telehealth provider' stays relevant-local and we never silently broaden past the filter), echoed in result.query.telehealth; GET /api/mulesoft/providers parses ?telehealth=true and the live providers.ts client forwards it to the CloudHub worker, whose DataWeave got the matching telehealthOnly param + offersTelehealth predicate + query echo (kept 1:1 with the mock); both OpenAPI specs (the published experience-API and the Agentforce External Services slice) now declare the param so the live agent can use it too; and the /provider UI got a 'Telehealth only' checkbox wired through the GET form + reset. (2) Dead-end fix: a /provider/[npi] profile's only navigation was '← Back to demo intake' (→ /demo/intake) — a patient who arrived from the directory had no way back to their results. Replaced it with a '← Back to directory' link that preserves the ?from ZIP as the directory's search ZIP (so distance ranking resumes), keeping the intake link as a secondary action. Tests: a new telehealth mock suite (off-by-default strictly narrows the matched total, telehealth-only returns only telehealth providers, applies before the ladder for certified-national, composes with the insurance filter), route forwarding + mock-mode echo, the live-worker snapshot's query echo, and the Agentforce OAS contract param list. 340 frontend tests green; next build clean.

9f4f4e6 provider: telehealth filter end-to-end (UI → mock → live → OAS) + fix profile dead-end

Docs: refreshed the MuleSoft prose to match the live-on-CloudHub reality

Shipped
Details

The MuleSoft Experience worker has been live on CloudHub 2.0 (serving /health + /providers behind Flex Gateway with JWT Validation) since Phase 1b, but several docs still told readers nothing was deployed — a credibility risk for anyone reading the repo. Corrected the flatly-stale claims while preserving the point-in-time runbooks as historical record. mulesoft/README.md: split the intro into live-deployable (the Experience worker) vs reference-grade (the not-yet-built ingestion .example files), updated the worker section to /health + /providers + Flex Gateway/JWT, rescoped the 'why these aren't a real Mule project yet' section to the ingestion references only, and replaced the old 'Mocked Experience API … no live MuleSoft runtime behind it' section with the live-or-mock proxy contract. docs/mulesoft-integration.md: header bumped from 'Draft v0.1 / 2026-05-25' to 'Phase 1 live', and the 'Live mock / no live runtime' section rewritten as the live-or-mock Experience API (both endpoints live, Auth0 Bearer-JWT, transparent mock fallback). docs/MULESOFT_RUNBOOK.md (a 2026-06-02 investigation snapshot) got an EXECUTED/SUPERSEDED banner so its 'no live Mule app deployed' line reads as the starting point, not today. docs/FLEX_GATEWAY_RUNBOOK.md status flipped from 'Not yet started' to DONE, noting JWT Validation replaced Client ID Enforcement. Docs-only.

f1893af docs: refresh MuleSoft prose to the live-on-CloudHub reality

MuleSoft: single-sourced live auth on Bearer-JWT + a complete env template

Shipped
Details

Auth cleanup + operator-onboarding fix. The live gateway enforces a JWT Validation policy (Auth0 RS256/JWKS) which replaced Client ID Enforcement on 2026-06-09 — but both Experience-API clients (health.ts, providers.ts) still carried a dead, copy-pasted, untested fallback that built a Basic Authorization + client_id/client_secret header from MULESOFT_CLIENT_ID/SECRET, credentials the JWT policy simply ignores. Replaced it with a single buildMulesoftAuthHeaders() in auth.ts (Bearer-JWT when an Auth0 M2M token is available, empty otherwise) used by both clients, and added X-Pause-Source to the providers client for parity with health. Added auth.ts's first test suite (9 tests): token mint via the client-credentials grant, caching, the non-2xx and missing-access_token failure paths, the header shape, and a guard that no Basic/client_id header is ever emitted even with the legacy vars set. Separately, frontend/.env.example was missing the vars needed to actually turn live MuleSoft on — completed it with MULESOFT_PROVIDERS_BASE_URL and the AUTH0_MULESOFT_* quartet (domain/audience/client id/secret), and flagged the retired MULESOFT_CLIENT_ID/SECRET as no-ops, so an operator can enable the live path from the template alone. 333 frontend tests green; tsc clean.

36ff0ae mulesoft: single-source live auth on Bearer-JWT + complete the env template

MuleSoft: the live /health worker now carries the DBDP feature lineage it always claimed to

Shipped
Details

Second silent mock⇄live drift on the MuleSoft surface, this time on /health. In mock mode /api/mulesoft/health serves buildPatientTimelineBundle() — a 5-entry FHIR bundle where the raw RR-interval window (obs-hrv-raw-001) and the derived RMSSD feature (obs-feature-rmssd-001) are both present and the feature carries a derivedFrom reference back to the raw window. That's the exact lineage the /proposal/mulesoft page advertises ('every DBDP-computed feature Observation carries a derivedFrom reference back to the raw window'). But the deployed CloudHub worker emitted only 4 flat Observations with no raw window and no derivedFrom — despite the worker's own header comment claiming shape-compatibility with the mock — so the moment /health flipped to live, the provenance would vanish. Rewrote the worker's /health DataWeave to mirror the mock 1:1 (same ids, codes, ordering; raw RR-interval components + RMSSD feature with derivedFrom, using the project's `as String` concat convention), updated the worker README, and extended the published OAS /health example to show the raw→derived lineage. Pinned the contract on the mock with 4 new tests: the timeline bundle is a searchset with exactly one Patient, has ≥1 DBDP feature Observation, every feature carries a non-empty derivedFrom, and every derivedFrom reference resolves to an Observation in the same bundle (no dangling lineage). XML well-formed; both OAS specs parse; 324 frontend tests green; tsc clean.

3847935 mulesoft: restore the /health DBDP lineage on the live worker

MuleSoft: insurance synonyms now resolve on the LIVE providers path (mock⇄live parity)

Shipped
Details

Found and fixed a silent mock⇄live contract gap on GET /api/mulesoft/providers: the route forwarded the raw ?insurance value to the live Mule worker, which only lowercases (no alias mapping), while the mock path normalizes synonyms inside queryProviderDirectory. So ?insurance=United matched in mock mode but returned ZERO providers against the live CloudHub API — a patient filtering by 'UnitedHealthcare' would see an empty directory only once the integration went live. Now the route normalizes at the boundary with the shared normalizeInsurancePlan, so both paths receive the canonical token (United→uhc, 'Blue Cross'→bcbs); it's idempotent for the mock and is exactly the job the live worker's own DataWeave comment defers to the route handler. Also shipped the providers route's first test suite (12 tests) — mock mode, cache header, limit clamp, synonym normalization, the live path capturing the outbound URL to prove the canonical token is forwarded (and omitted when absent), and the degrade-to-mock-fallback failure modes (5xx / network error / wrong shape, never throws). 320 frontend tests green; tsc clean.

802c998 mulesoft: normalize insurance synonyms before the live providers call

Agentforce: hardened the live embed — readiness watchdog + hidden-prechat sanitizer

Shipped
Details

Polished the real Embedded Messaging surface (components/agentforce-embed.tsx). (1) Readiness watchdog: init() resolves synchronously, but the chat launcher only appears once the SDK fires onEmbeddedMessagingReady — and the two most common production failures (a deployment that was never Published, or the host domain missing from the Embedded Service allow-list) leave init() succeeding while that event never fires, so the widget spun on 'Connecting…' indefinitely. After a 12s timeout it now surfaces an actionable hint that names the deployment and points at the publish/allow-list checks; the timer clears on ready, init-error, and unmount. (2) sanitizePrechatFields: now that the fixed V2 prechatAPI actually transmits registered fields to SCRT2, handing an empty string for a registered field like Patient_Zip would overwrite real MessagingSession context with blank — so the embed trims and drops empty/whitespace entries (skipping the setHiddenPrechatFields call entirely when nothing usable remains) and the UI's prechat-field count reflects the sanitized set. Both the sanitizer and the timeout constant moved into lib/agentforce.ts with a new lib/agentforce.test.ts (10 tests) that also backfills coverage for the previously untested getAgentforceConfig (missing/whitespace env vars → null, trailing-slash normalization, bootstrap-URL derivation). 308 frontend tests green; tsc clean; next build OK.

68b7352 agentforce: harden the live embed — readiness watchdog + prechat sanitizer

Agentforce: contract guard so the live agent's OAS slice can't silently drift again

Shipped
Details

The drift fixed in the previous entry (matchType referenced by the agent instructions but undeclared in the External Services slice, so it never reached the action output) was silent for a while because nothing tied the lean Agentforce spec to the live /api/mulesoft/providers contract. Added frontend/lib/agentforce-provider-oas.contract.test.ts (7 tests) to pin both ends: it reads the YAML slice as raw text (no YAML dependency in the package) and asserts every agent-facing query param (zip/menopause/limit/insurance/fallback), top-level matchType with all five honest-framing tiers named in its description, and every per-row provider field the runbook tells the agent to present (name, specialty, location, telehealth, accepting, distanceMiles, insuranceAccepted, serviceSignals) are DECLARED — then cross-checks against a real queryProviderDirectory result that those same fields are actually PRODUCED, plus a guard that the slice never re-adds the parser-hostile constructs ($ref/oneOf/nullable) the External Services parser rejects. If the slice and the live route ever disagree on an agent-relevant field again, this test fails instead of the live agent silently dropping it. Full suite green: 298 tests.

92afa7e agentforce: guard the External Services slice ↔ live provider contract

Agentforce: the live agent's provider action gets the full honest contract (matchType + distance + insurance)

Shipped
Details

The Agentforce-facing External Services slice (salesforce/external-services/pause-provider-directory.oas.yaml — the lean spec Salesforce turns into the findMenopauseProviders action) had drifted from the live /api/mulesoft/providers contract. The drift was load-bearing: the topic instructions tell the agent to 'read the response matchType and frame the results honestly', but matchType wasn't declared in the slice, so External Services never mapped it into the action output and the honest-tiering logic had nothing to read. The runbook also mapped an `insurance` action input the spec didn't expose. Synced the slice to the live contract using only parser-safe primitives (no $ref/oneOf/nullable/enum, which the External Services parser rejects): added the `insurance` and `fallback` query params, the top-level `matchType` string (allowed values enumerated in its description), and per-provider `distanceMiles`, `serviceSignals`, and `insuranceAccepted`. Updated the runbook to note the action now generates those inputs/outputs and that the External Service must be re-registered for matchType to map, and extended both the topic instructions and the paste-ready reasoning block so the live agent presents distance ('about 4 miles away') and accepted insurance and reads matchType for honest tiering — the same framing the scripted fallback already shows the patient. Spec validated (parses; all five params + matchType + the three new provider fields present). Re-registering the External Service in the org is the maintainer's manual step.

9a36645 agentforce: sync the External Services OAS to the live provider contract

Intake: test safety net for the shared provider-recommendation rendering

Shipped
Details

The <RecommendedProviders> component (newly shared by the live Care Router card and the prototype intake) shipped without tests. The frontend suite runs in a node environment with no React Testing Library, so rather than pull in jsdom + RTL just for one component, the component's pure logic was extracted into exported helpers and tested directly: profile-link building (bare /provider/<npi> vs ?from=<zip>, with URL-encoding of both NPI and ZIP), the inline meta line (city/state, distance rounded to 0.1 mi, telehealth, correct ordering, and omission of absent fields), the plan-chip cap with '+N more' overflow (incl. undefined/empty and a custom cap), and the signal/plan label lookups with raw-token fallback for unknown payers/credentials. The component now composes these helpers with no behavior change. 14 new tests (291 total) + tsc + next build clean.

1beaf27 intake: unit-test the shared RecommendedProviders rendering logic

Intake: the scripted fallback now closes the loop to local MSCP specialists

Shipped
Details

The prototype intake (the scripted fallback shown when the live Agentforce env vars aren't set) asked the patient for their ZIP and insurance, handed off to the Care Router, and showed the routing decision — but silently dropped the provider recommendations the decision already carries, so the demo never actually surfaced the local menopause specialists the provider graph now serves nationally. Now, when the Care Router lands on an MSCP pathway and finds certified clinicians near the patient, the completed intake renders them under a 'MSCP-certified specialists near <ZIP>' heading: name + specialty, city/state, distance-from-your-ZIP, telehealth flag, board-cert / service-line signal chips, and accepted-plan chips. Each name links to /provider/<npi>?from=<ZIP> so the profile page shows the distance chip too. The Care Router path stays strict certified-only (no fallback tiers — that honesty boundary is unchanged), so anyone shown here is a genuinely certified clinician near the patient; ZIPs with no local certified provider simply show no list rather than a misleading one. Implementation extracted the provider-list rendering that lived inline in the live LatestCareRouterDecision card into a shared <RecommendedProviders> presentational component (deduped ~80 lines + the signal/plan label maps), so the live dashboard and the prototype intake now render the graph's output identically. tsc + 277 tests + next build clean.

909af34 intake: surface Care Router provider recommendations in the scripted fallback

Provider graph: committed-directory data-quality invariants (the coverage + US-ZIP wins are now test-enforced)

Shipped
Details

The coverage spread and the US-ZIP gate live in the generated artifact, not in code — so a future monthly refresh_national.sh run could silently regress them (drop --coverage, let foreign postals back in, lose a state) and every unit test would still pass. New vitest runs directly over the committed provider-directory.generated.json + its .meta.json sidecar and pins the guarantees the investor pages now claim: every provider's ZIP is exactly 5 US digits (the gate holds — zero foreign/garbage postals), ≥900 distinct ZIP-3 prefixes (coverage floor, ~930 today, with headroom for monthly wiggle), all 50 states + DC present, every NPI is 10 digits with a finite graphScore, menopause-certified providers retained (≥7 and all placeable), the row count stays within a sane server-bundle ceiling, and the sidecar metadata mirrors the array exactly (total / certified / zip3Prefixes / states can't drift from the data). Floors where a refresh legitimately moves the numbers, exact equality only where the sidecar must match the array. 277 frontend tests (7 new) + tsc green.

b1b29a4 provider-graph: pin committed-directory data-quality invariants

Provider graph: coverage-aware selection + US-ZIP gate — honest 930-prefix reach across all 50 states + DC

Shipped
Details

The national run held 2,000 real menopause-relevant providers, but they were the global top-N by graphScore — which piles into a handful of dense metros, so the committed directory covered only 532 ZIP-3 prefixes. Most ZIPs outside those metros dead-ended on general browsing and the relevant-local fallback even though the data to answer them was sitting right there. New opt-in --coverage mode in build.py (`_round_robin_by_zip3`) spends the same non-certified --limit budget for breadth instead of depth: bucket the non-certified survivors by ZIP-3 prefix, order buckets by their strongest provider, then round-robin one provider per bucket per round so every prefix that has anyone contributes its best candidate before any prefix gets a second. Then a data-quality pass made the metric honest: the first coverage run reported 1,055 'prefixes', but only 930 are real US numeric ZIP-3s — the other 125 were foreign practice addresses (Canadian 'A1B…', UK 'EC…'/'EH1…'), APO/FPO military codes, and truncated/garbage postals ('0', '44'). normalize_row now gates the directory to providers with a usable 5-digit US ZIP (138 non-placeable rows dropped), so every record can actually be local to a US patient and the coverage number is the real US count. Net: same 2,000-row budget, distinct-prefix coverage went 532 → 930 valid US ZIP-3s spanning all 50 states + DC. Certified providers are always kept (--keep-all-certified is orthogonal), so the agent's menopause=true coverage is identical and the demo personas still resolve to their curated local certified providers; --coverage is OFF by default so the old top-N callers and tests are untouched. refresh_national.sh passes --coverage by default (COVERAGE=0 opts out) and records `coverage: true` in the sidecar metadata; regenerated the committed national directory in place (2,015 providers, 15 certified, 930 ZIP-3 prefixes, sanctions unchanged at CA 588 / NY 849 / TX 283). 83 provider_ingest tests green (7 new: round-robin maximizes coverage / deepens by score / no-ops within budget / build wiring never narrows vs top-N; foreign + truncated ZIPs dropped; ZIP+4 kept & truncated) + ruff clean; 270 frontend tests + tsc green behind the unchanged provider contract.

0d7191b provider-graph: coverage-aware non-certified selection (round-robin across ZIP-3)24c5578 provider-graph: gate directory to placeable US ZIPs (honest 930 ZIP-3 reach)

Investor brief: /proposal/provider-graph rewritten for the Phase 2 shipped state

Shipped
Details

The provider-graph proposal page was reading like a plan when most of it had shipped. Rewrite closes the credibility gap. Header lead changes from "Building a defensible menopause provider graph" to "...— Phase 2 shipped" with a subtitle naming concrete counts: 2,015 providers, Census-ZCTA distance ranking, six NPPES board-cert + multi-specialty signals, three state license-sanction filters dropping 1,720 sanctioned candidates at build, synthetic-but-real-shaped insurance, /provider browseable UI. Today's Reality replaces "what's wired vs. mocked" prose with five verifiable numbers each pinned to provenance — a reader can curl /api/mulesoft/providers and confirm every count under provenance.dataset (CTA inline). Sources card grid grew 6 → 8: NPPES (now with 9.6M-row stream + 1m50s harness mention), Census 2020 ZCTA Gazetteer, state sanction overlays w/ all three states + the FL/NJ skip story, NPPES service-line signals w/ the capped-bonus rationale, insurance overlay marked synthetic-but-shape-live, clinic-site detection reframed as Phase 2-bis, licensed MSCP feed marked partnership-gated, outcomes future. New pill legend covers the `partial` (shape-live / value-pending) state. Scoring table 5 factors → 6: credential (prototype, union of MSCP overlay + self-reported NPPES MSCP/NCMP), service-line signals (NEW), license standing (prototype, filter not downweight — names the 3 overlays + the 1,720 build-time drops), geographic (prototype, real Haversine), insurance (NEW, partial w/ synthetic caveat), outcomes (future). Phases 4 → 5: Phase 0/1/2 all prototype (contract / NPPES pipeline / Phase-2 distance + signals + sanctions + insurance + UI + MuleSoft DataWeave), Phase 2-bis designed (clinic scraper + paid insurance feed — gated on need/partnership), Phase 3 future. Touch-the-architecture CTA leads with "Browse the directory (UI)" linking /provider?zip=92614&menopause=true; source-data row lists all 6 upstream public datasets directly (NPPES, Census ZCTA, CHHS S&I, NY OPMC, TX TMB, provider_ingest). Compliance posture reframed: public-domain substrate enumerated explicitly, sanctioned providers filtered not flagged. tsc + next build clean (108 KB page, registers static); smoke confirms all 10 sentinel-text counts present.

e4e2c59 proposal: rewrite /proposal/provider-graph for the Phase 2 shipped state

Provider graph: /provider browseable directory index (UI surface for the same contract)

Shipped
Details

Patient/maintainer-facing index page over the same queryProviderDirectory the agent and Care Router consume. Filters submit via a <form method="GET"> so the URL is canonical (bookmarkable, refresh-safe, no client state, no hydration cost) — inputs: ZIP (drives both the 3-prefix filter AND the distance-ranking centroid lookup so users don't have to type it twice), insurance plan dropdown, MSCP-certified-only checkbox, fallback-ladder checkbox (defaults ON for browse so empty certified-local results don't dead-end), page size capped at 50. Each result card carries the now-familiar Phase-2 surface: name + specialty + city/state/zip + distance, certified vs relevant chip, new-patients status, service-line signals (board-cert OB/GYN, Women's Health NP, multi-specialty), top 4 insurance plan chips with "+N more" overflow. Names link to /provider/<npi>?from=<zip> so the patient ZIP rides through to the profile's distance chip. Header surfaces the response's sort and matchType so a reader can see which tier and ranking actually applied ("20 of 247 providers · ranked by distance from your ZIP · matchType: certified-local"). Empty states get explicit fallback links rather than dead ends. Provenance footer surfaces sources, generatedAt timestamp, and the per-source sanction-filter counts ("CA: 588, NY: 849, TX: 283") when present. /proposal/provider-graph's CTA now leads with "Browse the directory (UI)" linking here, with the raw Experience API JSON moved to a secondary button. Server-rendered on demand (force-dynamic) so searchParams flow through; smoke-tested: default page 86 KB / 20 cards / sort=score / matchType=all; ?zip=92614&menopause=true&plan=aetna → 2 providers (Anand + Okafor) with distance ranking and matchType=certified-local. 270 tests untouched (the page is a thin GET-form driver over already-tested logic). tsc + next build clean.

bec49f7 provider-graph: /provider browseable directory index

MuleSoft: live /providers worker gets the full Phase-2 contract (matchType / signals / insurance / license / dataset)

Shipped
Details

The live Mule app (CloudHub 2.0 worker pause-mulesoft-health-v1, fronted by Flex Gateway) was still serving the pre-Phase-2 shape — 6 hand-curated providers, no lat/lng, no serviceSignals, no licenseStatus, no insuranceAccepted, no matchType / sort / dataset provenance — while the Next.js mock had moved on. This closes the live-vs-mock contract gap. providers-flow's DataWeave rewritten with a curated 9-row slice pulled from the committed provider-directory.generated.json (every demo persona resolves to a real certified-local provider; 2 relevant-local OB/GYN fallbacks for the tier ladder); each row carries the full Phase-2 field set including the synthetic insuranceAccepted draws. Tier ladder mirrors queryProviderDirectory line-for-line: certified-local → certified-national (no zip) → relevant-local (fallback only) → certified-remote (fallback only) → none. ?insurance=<plan> filter applied BEFORE the tier ladder so all tiers honor it. sort: "score" — the live worker doesn't carry the 33K-ZIP Census ZCTA centroid table (same lookup runs in the route handler instead), so it reports score-only ranking and leaves distanceMiles: null on each row; the route handler picks the higher-fidelity ranking when it has the centroid. provenance.dataset present for parity with generatedAt/sourceDate: null. README documents the two intentional differences (narrow demo slice + score-only ranking on live, national breadth + distance-aware on mock). OAS example bumped to show the full envelope; experienceApi @0.9 to match. 3 new vitest pin contract-shape parity: every record on the mock carries the full Phase-2 field set, response envelope carries the required top-level keys, and a hand-authored live-worker snapshot passes the same checks — drift either direction is caught at CI time. 270 frontend tests green; tsc clean. Deploy is the maintainer's next manual step.

cf4a42d mulesoft: live worker /providers DataWeave gets the full Phase-2 contract

Provider graph: /provider/<npi> profile page surfaces the directory's per-provider data

Shipped
Details

Patient-facing surface for everything Phase 2 added. /provider/<npi> resolves a single ProviderRecord from the same directory the agent and Care Router consume (NPPES-derived generated JSON, curated fallback if not), then renders: hero name + specialty + city/state/zip; a chip row (certified vs menopause-relevant, accepting-new-patients, telehealth, distance "4.2 mi from <zip>" when ?from=<zip> resolves to a centroid AND the provider has lat/lng, license disposition); service-line signals chip block with plain-English labels (board-certified OB/GYN, Women's Health NP, multi-specialty, etc.); insurance-accepted chips with the synthetic-data caveat front and center ("Synthetic — verify before booking"); a provenance footer enumerating NPPES, MSCP overlay, sanctions filters (CA/NY/TX), graphScore composition, and distance source. Server component, force-dynamic so ?from=<zip> actually flows through (force-static would silently treat searchParams as undefined and the distance chip would never appear). Unknown NPIs return clean 404s via notFound() — sanctioned providers filtered at build time get the same 404, which is the right answer. New findProviderByNpi() helper exposes O(1) Map<npi,record> lookup against the directory; the Care Router trace span now carries `npi` per recommendation, so LatestCareRouterDecision links each name to its profile page (clicking a recommendation now opens the full profile). 267 frontend tests green (4 new on findProviderByNpi: hit, miss, null-safety, whitespace-trimming); tsc + MCP tsc + next build all clean. Tiny CSS addition: 5 profile-chip variants in globals.css patterned on the existing routing-acuity-chip color logic; no global style changes.

ef517c8 provider-graph: /provider/[npi] profile page surfaces the directory's per-provider data

Provider graph: TX sanctions overlay (Texas Medical Board active-disposition allowlist)

Shipped
Details

Third state-license safety filter — and the design decision was load-bearing. Texas Medical Board's DataSet-01-All Licenses (data.texas.gov tm3v-pfq9, ~507K rows) is the full TX licensee registry with structured Disciplinary Status + License Status columns, so we filter on disposition rather than enumerating disciplinary orders. The naive `!= NONE` would have dropped 9,475 providers — but auditing the dataset showed many of those values are CLEARED / DISMISSED / historical references ("DISP. ACTION CLEARED", "COMPLAINT DISMISSED", "LICENSURE BOARD ORDER CLEARED", "LIC RESTRICTION REMOVED", "CLEARED BY ATTORNEY GENERAL", "SEE PREVIOUS ORDER") whose presence does NOT mean a provider is currently sanctioned. Switched to an *allowlist* of explicit active-sanction values (SUSPENDED BY BOARD, REVOKED, UNDER BOARD ORDER, AUTOMATIC LICENSURE CANCELLED, etc.) → 2,071 sanctioned licenses, an honest filter rather than a noisy one. Currently-Licensed=N is also NOT a sanction signal: a provider who let their TX license lapse cleanly may be practicing under a clean license elsewhere. Reused the (state, license_num)-keyed cross-walk machinery NY introduced. CSV loader accepts both Title Case (web download) and snake_case (SODA API) headers via a small alias helper. BuildStats gained license_drops_by_state for per-state attribution under multi-state license-keyed overlays; CLI grew --sanctions-tx (auto-detected via SANCTIONS_TX / tx_tmb*licenses*.csv beside the NPPES zip); the summary line now reads "CA filtered 588, NY filtered 849, TX filtered 283". Real impact regenerating against the June 2026 TX drop: 1,720 total candidates filtered before sort/limit (588 CA + 849 NY + 283 TX); directory size unchanged at 2,015 (limit cap refills); 15 certified untouched; every demo persona intact. 76 provider_ingest tests green (4 new: allowlist excludes NONE/NONE clean rows + lapsed-clean rows; state-isolation across CA/NY/TX; per-source license attribution under TX + NY simultaneously). 263 frontend tests + tsc clean. NJ stays out — no structured public feed.

43323e6 provider-graph: TX sanctions overlay (Texas Medical Board allowlist)

Provider graph: NY sanctions overlay (license-number cross-walk via NPPES)

Shipped
Details

Second state-license safety filter — and it found 849 more candidates to drop. NY's data.ny.gov publishes the Professional Medical Conduct Board Actions dataset (ebmi-8ctw, 17,950+ rows since 1990) with license number + license type per action; NPI is NOT in the row, so the build cross-walks (NY, license_num) against each NPPES candidate's own Provider License Number_<i>/State Code_<i> columns during the same single pass that builds the directory. NJ skipped: disciplinary actions are PDFs scraped per-action, not a structured feed — not worth a brittle scraper. SanctionOverlay refactored to carry both NPI-keyed and (state, license_num)-keyed evidence with a merge() classmethod for the build's single pass; license-number normalization (whitespace/dashes/leading zeros/state casing) handles formatting drift between NPPES and OPMC; blank / "000000" rows skipped on load (NY's pre-issuance sentinel would otherwise match every blank-license NPPES record). extract_licenses() pulls all 15 NPPES license slots; build_directory collects each surviving candidate's licenses in a side-map during the same row visit, then applies both filters post-pass with separate npi_drops + license_drops counts on BuildStats. CLI gains --sanctions-ny; harness auto-detects ny_opmc-*.csv beside the NPPES zip; the CLI summary line reads "CA filtered 588, NY filtered 849". Sidecar metadata schema bumped to v2: per-source overlay paths under `sanctionsOverlays`, per-source drop counts under `providers.sanctionedFilteredBySource`. Frontend dataset provenance + OAS document both. Legacy single-overlay key still parses for older sidecars. Real impact regenerating against the May 2026 NY drop: 588 CA-NPI + 849 NY-license = 1,437 candidates filtered before sort/limit; directory size unchanged at 2,015 (limit cap refills with the next eligible providers); 15 certified untouched. 72 provider_ingest tests green (6 new); 263 frontend tests green; tsc clean.

6d43e5f provider-graph: NY sanctions overlay (license-number cross-walk via NPPES)

Salesforce: version-control Pause_Patient_Insurance__c so the live agent can read the plan in-band

Shipped
Details

Mirrored the Patient_Zip prechat plumbing one field over so the live Agentforce embed can pass the patient's insurance plan in-band the moment Patient_Insurance is registered on the deployment's prechat form. Tracked metadata, deployable via `./salesforce/deploy.sh trailsignup`: MessagingSession.Pause_Patient_Insurance__c (Text, 32) with a description flagging insuranceAccepted as synthetically derived ("soft filter, not guarantee" reads first); Pause_Intake_Prechat_Router flow gains the Patient_Insurance String input variable + recordUpdate inputAssignment writing it onto the existing Write_Dossier_To_Session step (description bumped 20 → 21 dossier fields); Messaging_for_In_App_Web channel gains a Patient_Insurance customParameter; Pause_Health_Intake_Prechat_Dossier permission set grants FLS read+edit on the new field; both manifest/package.xml (deploy subset) and manifest/package-complete.xml (full retrieve) list the new field alongside Pause_Patient_Zip__c; deploy.sh inventory comment and the salesforce/README.md track-table updated. Org-managed remainder (Agent Builder UI, runbook documents the clicks): bot context variable Pause_Patient_Insurance, findMenopauseProviders action insurance input binding to $Context.Pause_Patient_Insurance, prechat-form hidden-field registration, agent reasoning template ("only ask when context is empty; surface match provisionally"). Repo-side wiring was already complete from last week's commit so the Care Router, /api/intake/prechat-context, intake-patient-stage, and demo-cohort tests are unchanged. XML well-formed, no comments in deployable files (the trap that broke a Patient_Zip deploy back in c7895a0 and stays documented in the README). Frontend tsc + 263 vitest unchanged.

0f304ec salesforce: deploy Pause_Patient_Insurance__c (parallel to Pause_Patient_Zip)

Intake: capture patientInsurance and thread it end-to-end through the demo

Shipped
Details

The provider directory already accepted ?insurance= and the Care Router already read intake.patientInsurance, but nothing populated the field in the live demo flow — so the synthetic insurance overlay was invisible to anyone exercising the demo. This wires it up. Each of the six demo cohort entries gains a patientInsurance plan picked from its local MSCP-certified provider's insuranceAccepted list (Anika→Aetna, Brianna→BCBS, Carmen→Medicare, Deepa→BCBS, Elena→BCBS, Fatima→UHC) so the filter actually surfaces a local provider rather than silently emptying the directory; a new demo-cohort.test invariant pins this against the live committed directory so a future synthesis drift can't break the demo without the test telling future-me to re-pick from the local provider's accepted list. The AgentforceFallback intake gains an optional "Which insurance do you have?" step (8 canonical plans + Skip; blank → undefined, never an empty-string filter); the captured plan flows through to the existing Care Router handoff and into RoutingDecision.recommendedProviders.query.insurance, which the rationale line already calls out ("...accepting Aetna..."). The live Agentforce embed gets a parallel hidden prechat field — /api/intake/prechat-context emits Patient_Insurance alongside Patient_Zip, intake-patient-stage forwards both when a persona is selected, and the Agentforce runbook gains an "Auto-passing the insurance plan" section with the same six-step Salesforce-side wiring pattern + an agent reasoning template that frames the match as a soft filter (not a guarantee) since insuranceAccepted is synthetic today. Until Patient_Insurance is registered + mapped on the org, the SDK drops it gracefully and the agent just asks. 263 frontend tests green (3 new on demo-cohort), tsc clean.

64770ec intake: capture patientInsurance and thread it end-to-end through the demo

Provider graph: insurance-acceptance overlay + ?insurance= filter (synthetic, real-shaped)

Shipped
Details

There's no public, free, structured payer/in-network feed available; a real insurance match needs a paid data partnership (Ribbon Health, Turquoise) or per-payer contracts. So this overlay is deterministic and synthetic — but every other layer is real, so when a partner feed lands the entire stack swaps in place. New module insurance.py derives `insuranceAccepted: list[str]` from a stable SHA-256 hash of each NPI; per-plan probability draws are decorrelated by salting the hash with the plan name; thresholds match real-world physician participation (Medicare ~85%, Kaiser ~20%, commercial plans 30-50%) so the population distribution looks plausible. Output is canonical-order, deterministic across rebuilds, never empty (Medicare is the conservative floor). Regenerated 2,015-row directory: medicare 85% / medicaid 67% / bcbs 51% / aetna 50% / uhc 44% / cigna 36% / humana 31% / kaiser 20%; ~3.8 plans per provider. Plumbed end-to-end: queryProviderDirectory gains an `insurance` filter applied BEFORE the tier ladder (so all tiers honor it consistently — we never broaden insurance just because the strict tier is empty); normalizeInsurancePlan() handles user-typed synonyms ("United" → "uhc", "Blue Cross" → "bcbs"); unknown plans yield zero results honestly. /api/mulesoft/providers picks up ?insurance=, OAS documents the field as an array of canonical tokens with the synthetic-data caveat, MCP find_menopause_providers gains an insurance input + framing that tells the agent to surface plan info provisionally rather than as ground truth. Care Router IntakeRecord gains patientInsurance; attachRecommendedProviders forwards it to the lookup, RecommendedProvider carries insuranceAccepted through to the agent fabric trace, and the LatestCareRouterDecision UI renders plans as small grey pill chips ("+N more" when capped at 4). Rationale line now reads "...accepting Aetna near 92614..." when a plan filter applied. Provenance.sources on every Experience API response explicitly says "Insurance acceptance is synthetically derived per-NPI" so consumers (humans + agents) see the caveat without reading the runbook. experienceApi @0.9. 66 provider_ingest tests green (6 new); 260 frontend tests green (7 new). frontend + MCP tsc clean. Phase 2's insurance match is now patient-facing; replacing the synthesis with a paid feed is a one-module swap.

8eaefe5 provider-graph: insurance-acceptance overlay + ?insurance= filter (synthetic, real-shaped)

Provider graph: filter sanctioned providers (CA Medi-Cal Suspended & Ineligible list)

Shipped
Details

First state-license safety filter — and it found real candidates to drop. The California Health & Human Services Agency publishes the Provider Suspended and Ineligible List (Medi-Cal S&I) as a free, public-domain CSV refreshed monthly at data.chhs.ca.gov, enumerating every provider barred from Medi-Cal participation (physicians, RNs, pharmacies, clinics). New module sanctions.py loads the CSV → set of suspended NPIs (\b\d{10}\b regex over the free-text 'Provider Number' column; state license IDs like 'PHA999999' don't false-positive). build_directory drops every matching NPI before sort/limit and tracks the drop count as part of a new BuildStats return; the original build_directory signature is preserved so existing callers and tests don't break. ProviderRecord gains licenseStatus (default 'active') so the contract documents what was checked; the OAS schema mirrors it as an enum. Sidecar metadata gains sanctionsOverlay (the path applied) and providers.sanctionedFiltered (the drop count), surfaced under provenance.dataset on every Experience API response (experienceApi @0.8) — /api/mulesoft/providers now carries both freshness AND safety-filter provenance. The harness auto-discovers the latest suspended-ineligible-list-*.csv beside the NPPES zip and forwards --sanctions to the build. Real impact: regenerating the committed national directory with the May 2026 CHHS list filtered out 588 post-taxonomy candidates who were on California's suspended-ineligible roster — providers who would otherwise have surfaced in the relevant-local tier. Total directory size unchanged at 2,015 (the limit cap pulls in the next eligible non-sanctioned providers); 15 certified untouched; every demo persona's local certified provider intact. 60 provider_ingest tests green (5 new: regex precision, empty overlay no-op, build filters + stats, license-status default). 253 frontend tests green (2 new: provenance.dataset surfaces sanctioned counts; every loaded provider has licenseStatus active or undefined). tsc clean. Phase 2 starts where the demo cohort lives — other states will land additively behind the same overlay interface.

4deb884 provider-graph: filter sanctioned providers (CA Medi-Cal S&I list)

Provider graph: tracked refresh harness + sidecar build metadata so the directory is honestly dated

Shipped
Details

Replaced the ad-hoc .scratch/run_national*.sh files (gitignored, easy to lose) with a tracked provider_ingest/scripts/refresh_national.sh that one-shots the monthly refresh: auto-discovers the latest NPPES_Data_Dissemination_*.zip, picks the npidata_pfile member from the zip manifest, streams it through a FIFO (no extraction; ~1m50s end-to-end), cleans up on any exit, and supports --dry-run for inspection. Override defaults via NPPES_ZIP / NPPES_OUT / NPPES_LIMIT env vars. pause-provider-build gained a sidecar metadata writer: every build emits a <out>.meta.json next to the bare-array directory JSON (the array contract is unchanged — every existing consumer keeps working). The sidecar carries generatedAt (wall-clock), sourceDate (the NPPES zip's mtime — what the dataset actually reflects, not when the build ran), nppesInputs/mscpOverlay (so a build is reproducible), limit/keepAllCertified (the flags used), and providers.{total,certified,states,zip3Prefixes}. mulesoft-mocks loads the sidecar at module init and surfaces it under provenance.dataset on every /api/mulesoft/providers response; the OAS spec documents the field as nullable (null when only the curated fallback is in use). The Experience API can finally answer the question "how fresh is this directory?" honestly — sourceDate is the answer, not generatedAt. 55 provider_ingest tests green (6 new: metadata shape + roundtrip, ISO-UTC mtime helper, end-to-end main writes both files, default --meta path). 251 frontend tests green (1 new: dataset provenance is surfaced and consistent with the array). tsc clean.

4414739 provider-graph: tracked refresh harness + sidecar build metadata

Provider graph: broaden the curated NUCC taxonomies — and find a missing certified provider in the process

Shipped
Details

The curated menopause-taxonomy set was OB/GYN-heavy by construction, which meant a small number of menopause-relevant clinicians were silently dropped at the taxonomy filter. Added six NUCC codes that close real gaps: Urogynecology & Reconstructive Pelvic Surgery (relevance 0.95 — directly addresses GSM, pelvic floor, urinary symptoms), Gynecologic Oncology (0.78 — postmenopausal-bleeding red-flag context), Internal Medicine — Geriatric Medicine (0.68), NP — Gerontology (0.72), NP — Adult Health (0.66), and CNS — Gerontology (0.66). Relevance weights are calibrated so OB/GYN (1.00) still outranks all six — pinned by a new test — so the certified-local / relevant-local tiers still prefer OB/GYNs at the same baseline. The bulk of the broadening lands in ZIP-specific relevant-local fallback, exactly where it's needed. Real impact, not abstract: regenerating the national directory against the broader set surfaces ONE NEW MSCP-certified provider who was being silently filtered out — Dr. Lindsey Mehran-Rezaii, NP — Gerontology, MSCP (Apple Valley, MN). She self-reports MSCP in NPPES, but her primary code (363LG0600X) wasn't in our curated set, so the taxonomy filter dropped her. Adding the code fixes a correctness gap, not just coverage. Counts move from 14 → 15 certified and 28 → 38 non-OB/GYN providers; total 2,014 → 2,015. 49 provider_ingest tests green (2 new); 250 frontend tests untouched; tsc clean.

978561d provider-graph: broaden NUCC menopause taxonomies (urogyn + geriatric care)

Provider graph: NPPES service-line signals sub-rank the relevant-local tier

Shipped
Details

Beyond the binary MSCP/NCMP credential, the pipeline now detects six public-registry signals from the NPPES record and stamps them onto every provider as serviceSignals: a small list of tokens (facog, faafp, face, whnp, cnm, multi-taxonomy) that suggest a non-certified provider actually delivers menopause-relevant care. Each signal feeds a +2% graphScore bump capped at +5% total — bounded so a non-certified provider with all signals still falls behind a certified provider at the same baseline, so the binary credential remains the strongest evidence. The tokens are evidence-based, not synthetic: facog/faafp/face are board-certification fellow tokens self-reported in NPPES "Provider Credential Text", whnp and cnm are the NUCC women's-health and midwifery roles, and multi-taxonomy fires when the provider lists ≥2 NUCC codes from the curated menopause set (e.g. OB/GYN + Reproductive Endocrinology). In the regenerated June 2026 national run, 435 of 2,014 providers (22%) carry at least one signal — primarily multi-taxonomy (421), with cnm (9), whnp (6), facog (3), faafp (2) rounding it out. The relevant-local tier is now sub-ranked honestly: a board-certified OB/GYN with FACOG outranks a generalist sharing the same taxonomy. Plumbed end-to-end: ProviderRecord gains serviceSignals (Python + TS, OAS additive), graph_score takes a service_signal_count, the MCP find_menopause_providers description tells the agent to surface the strongest signal in plain English when matchType=relevant-local, the Care Router's RecommendedProvider carries the signals through to the agent-fabric trace span, and the /demo dashboard's LatestCareRouterDecision card renders them as small "Board-cert OB/GYN" / "Women's Health NP" pill chips next to each recommendation. 250 frontend tests green, 47 provider_ingest tests green (7 new signal-detection tests + 2 new score-cap tests); frontend + MCP tsc clean.

2d378ce provider-graph: NPPES service-line signals sub-rank the relevant-local tier

Care Router: MSCP recommendations now show distance from the patient — and rank by it

Shipped
Details

The new ZCTA-centroid distance ranking is wired through to the Care Router's MSCP provider recommendations and surfaced in the UI. attachRecommendedProviders now resolves the patient's ZIP to a Census centroid and passes it through the ProviderLookup contract, so queryProviderDirectory ranks the candidate pool by Haversine distance ascending (graphScore desc tiebreak) before rankForModality re-orders within that for telehealth-vs-in-person preference. RecommendedProvider gained an optional distanceMiles, the rationale line reports which ranking actually applied ("ranked by distance from the patient's ZIP" vs "ranked by graph score") so the agent-fabric trace tells the truth, and the trace span itself carries a richer recommendedProviders attribute (name, specialty, city, state, telehealth, distanceMiles) alongside the legacy recommendedProviderNames array — older trace consumers still parse, newer ones get the full shape. The /demo dashboard's LatestCareRouterDecision card reads the rich attribute (with a graceful fallback to the legacy strings for traces written before this commit) and renders inline metadata next to each recommendation: e.g. "Dr. Helen Okafor · OB/GYN (Newport Beach, CA · 4.2 mi away · telehealth)". 250 frontend tests green (2 new: zipCentroid forwarded + distanceMiles propagated end-to-end, score-only rationale fallback when no centroid resolves); tsc clean.

9a4ea19 care-router: propagate distance through MSCP recommendations + UI

Provider graph: real distance ranking — providers come back sorted by miles from the patient ZIP

Shipped
Details

The directory now ranks by Haversine distance from the patient's ZIP whenever its centroid is known, instead of leaning on the ZIP-3 prefix tier as a proxy for proximity. The Census 2020 ZCTA Gazetteer (public domain, ~1 MB) is parsed into a {zip5: [lat, lng]} map by a new provider_ingest.centroids module and committed twice: once into the wheel-bundled provider_ingest/data/zip_centroids.json (so the build pipeline stamps latitude/longitude on every NPPES row whose ZIP has a ZCTA centroid — 1,931 of 2,014 in the June 2026 run, 96%) and once into frontend/lib/zip-centroids.generated.json (so a tiny server-only loader resolves the patient's query ZIP at request time). queryProviderDirectory grew an opt-in zipCentroid arg: when a centroid is supplied AND at least one in-tier provider has its own coordinates, every returned row gets a distanceMiles (rounded to 0.1 mi — false precision past that, since centroids are area middles, not addresses), the rows sort distance asc with graphScore desc as the tiebreak, and a new top-level sort field reports which ranking actually applied ("distance" vs "score"). Providers with no centroid (rare PO-box-only / very new ZIPs) get distanceMiles: null and slide to the end honestly. The tier ladder (matchType) is unchanged — distance is a within-tier sort, so certified-local still wins over relevant-local even when the latter is geographically closer. /api/mulesoft/providers wires the centroid in by default (?distance=false to opt out for callers that need the prior score-only ordering); the prefer-real client forwards the centroid (the live Mule app still ranks by score until its DataWeave is updated, which is fine because the agent reads sort=score and degrades cleanly). The OAS contract gained Provider.latitude / longitude / distanceMiles + a sort enum + a distance query param — all additive, so the registered Salesforce External Service still validates with no re-import. The MCP find_menopause_providers tool description and per-call summary now teach the model to read sort and report distance to the patient ("about 4 miles away") when present. 248 frontend tests green (4 new distance tests covering: distance ranking when centroid present, score-only fallback when not, null-distance providers slide to the end, Haversine sanity Irvine→Brooklyn ≈ 2,436 mi); 35 provider_ingest tests green (2 new centroid-stamping tests); frontend + MCP tsc clean.

fd6321a provider-graph: distance ranking from Census ZCTA centroids

Provider directory UI: the graceful fallback is now visible to humans, not just the agent

Shipped
Details

The /provider directory already consumed the new matchType field, but only as a muted one-line footnote — so the honest fallback framing the agent gets was invisible to anyone browsing the site. It now renders a clear, tier-aware banner above the results. The fallback tiers get a prominent brand-accented notice that names the patient's ZIP and distinguishes menopause-EXPERIENCED from CERTIFIED: relevant-local reads 'No menopause-certified providers in the 33101 area, so we're showing nearby menopause-experienced clinicians (not certified)'; certified-remote reads 'No providers in the 00601 area, so we're showing menopause-certified specialists elsewhere who offer telehealth'. The happy path (certified-local / certified-national) stays quiet with a subtle positive label, and zero-result searches get a clear no-match banner with widen-search links. New .match-banner styles (ok / info / empty tones) reuse the existing pink/green/muted palette and collapse responsively. frontend tsc + 270 tests + eslint all green.

19978c9 provider UI: per-tier match banner so the fallback is visible to humans

Provider graph: graceful provider fallback — any ZIP now gets a useful, honestly-labeled answer

Shipped
Details

The national NPPES run exposed a gap: the agent queries menopause=true, but self-reported MSCP/NCMP is rare (~7 nationally), so a patient outside the demo metros got an empty result while 2,000 real menopause-relevant providers sat invisible behind the certified filter. queryProviderDirectory now supports an opt-in tiered fallback that reports which tier answered via a new matchType field: certified-local (certified specialists in the ZIP-3 area — the happy path), relevant-local (no local certified, so nearby menopause-EXPERIENCED but non-certified clinicians), certified-remote (nothing local, so telehealth-capable certified specialists nationally), plus certified-national / local / all / none. Crucially the fallback is OFF by default — the Care Router's 'MSCP-credentialed' recommendation and the demo's strict certified-local invariant are untouched — and the agent-facing Experience API (/api/mulesoft/providers) opts in (?fallback=true, default-on, with a ?fallback=false escape hatch). It's plumbed through the live MuleSoft client (fetchLiveProviders / getProvidersPreferReal) and the MCP find_menopause_providers tool, whose summary + description now instruct the model to present each tier honestly (relevant-local as 'menopause-experienced, not certified'; certified-remote as 'no local match, these offer telehealth'). The OAS contract was extended additively (optional matchType + fallback param) so the already-registered Salesforce External Service still validates with no re-import, and the Agent Builder topic instructions were rewritten for honest matchType framing. 244 frontend tests green (7 new tiered-fallback tests, derived from the committed directory so they survive data regens); frontend + MCP tsc clean.

0a3b620 provider-graph: graceful provider fallback so any ZIP gets a useful, honest answer

Provider graph: version-controlled the Salesforce org + shipped a real national NPPES run (honest MSCP detection)

Wired in prototype
Details

Two infrastructure passes on the provider/agent stack. (1) Phase 18b — the Agentforce intake/provider metadata is now a real, version-controlled salesforce/ SFDX project (sfdx-project.json + force-app + manifest + deploy.sh/retrieve.sh + README), replacing the throwaway .sf-deploy/ scaffold and the ad-hoc /tmp retrieves; the duplicate Named Credential was reconciled and the runbooks point at the new layout. The deployable subset (named credential, MessagingSession.Pause_Patient_Zip__c, routing flow, messaging channel, permission set) is tracked; the remaining ~20 dossier fields + the Agent (Bot/GenAiPlannerBundle) stay org-managed and are one retrieve.sh away. (2) Provider-graph — the NPPES ingest now earns real menopause-certified coverage honestly: independent of the synthetic overlay, nppes.py flags a provider menopauseCertified when they self-report MSCP (or its former name NCMP) in the NPPES 'Provider Credential Text' field — a real public-registry signal, not a fabricated credential — and build.py accepts multiple --nppes inputs that merge + de-dupe by NPI, so the national npidata_pfile can be combined with the demo fixture in one run (demo personas stay green, every other ZIP gets real coverage). No contract, agent, or Care-Router change needed; menopause=true keeps meaning certified. Then the national run actually shipped: the CMS June 2026 npidata_pfile (8.5M rows) streamed through the pipeline and the result is now the committed directory — 2,014 providers, of which 14 are menopause-certified: the 7 demo personas plus 7 REAL practitioners who self-report MSCP/NCMP in NPPES (CA, IA, ID, MN, NC×2, NJ), with 2,000 real non-certified providers across 55 states / 534 ZIP-3 prefixes for general browsing. Three changes made that correct + fast: the reader now parses only the ~40 columns it needs (csv.reader, not a 330-column DictReader) so the full file runs in ~1m45s instead of ~30 min; NPI-collision merge switched to 'later input wins' (demo fixture listed last) so personas stay green even where their real-format NPIs also exist nationally; and a new --keep-all-certified flag means --limit caps only the non-certified breadth and never drops a certified provider (the agent queries menopause=true). Verified all 6 demo persona ZIPs return identical certified results vs the prior dataset; provider_ingest 33 tests + ruff green, frontend tsc + 23 provider tests green. Honest finding, documented in the runbook + provenance: self-reported MSCP/NCMP is rare in NPPES (~7 nationally), so dense certified coverage outside the demo metros still needs the licensed Menopause Society feed — the non-certified rows give the directory real national breadth in the meantime.

cbb760f salesforce: version-control org metadata into a canonical SFDX project (Phase 18b)f63c582 provider-graph: honest MSCP/NCMP credential detection + national-ready merge5b67376 provider-graph: ship national NPPES run behind the contract (2,014 providers)

The Agentforce agent auto-uses the intake ZIP — live + verified on trailsignup

Shipped
Details

The 'Find a Provider' subagent now reads the patient's ZIP straight from the intake context and returns local specialists without ever asking — verified end-to-end on the live trailsignup embed: persona Anika Patel (92614) → 'find a provider that specializes in menopause' → Dr. Helen Okafor DO MSCP (Newport Beach) + Dr. Priya Anand MD FACOG MSCP (Irvine), both 926-prefix Orange County, no New York / LA national fallback, and no ZIP question. This finally lit up the hidden-prechat pipeline that had been dormant since Phase 18c (the V2 Embedded Messaging prechatAPI used to be a no-op Proxy; it's now a real implementation that validates field names). Repo side: the embed re-enables the one field (agentforce-embed.tsx + /api/intake/prechat-context send Patient_Zip from the selected persona), and the Salesforce handoff stack deployed to trailsignup (Deploy ID 0AfHp00003ocxqYKAQ, 5/5) — a MessagingSession.Pause_Patient_Zip__c Text(16) field, a Patient_Zip input + Update Records on the Pause_Intake_Prechat_Router routing Flow, the Patient_Zip customParameter + parameter mapping on the Messaging_for_In_App_Web channel, and FLS via the Pause_Health_Intake_Prechat_Dossier permission set. Org side: included Pause_Patient_Zip on the agent's Messaging Session context variable, bound the PauseProviderDirectory action's zip input to it, rewrote the Find-a-Provider reasoning to use context-then-ask, and activated Agent Version 4. Two gotchas worth their weight: (1) MessagingChannel metadata has no element for 'allowed file types', so any deploy with attachments on fails the 'Allowed file types can't be null' validation — disabled inbound attachments on the channel (intake never uses them); (2) the actual blocker was that the Embedded Service Deployment had to be re-Published after adding the hidden field — setHiddenPrechatFields reported 'applied' the whole time, but the value only reached the routing Flow once the deployment was published and the ~5-15 min CDN propagation finished. Full wiring + both gotchas in docs/PHASE_3_RUNBOOK.md (Phase 18d).

f4a1654 agentforce: ship auto-ZIP to Find-a-Provider (verified live on trailsignup)

The Agentforce agent can now find providers — live on trailsignup

Shipped
Details

The live Pause_Health_Intake_Agent used to deflect on "find a provider that specializes in menopause" — it was a generic intake-only Service Agent with no action wired to the Pause provider graph. It now answers for real. The fix shipped in two halves. Repo side (no Apex needed, because /api/mulesoft/providers is a public no-auth GET): a lean External-Services-compatible OpenAPI 3.0 spec (operation findMenopauseProviders, stripped of $ref/oneOf/nullable/auth so the parser accepts it), a no-auth Named Credential pointing at https://pause-health.ai deployed via a throwaway SFDX harness, and a runbook with paste-ready Agent Builder copy. Org side, on trailsignup: registered the PauseProviderDirectory External Service from the spec, added a "Find a Provider" subagent to the agent with the findMenopauseProviders action (inputs agent-populated from descriptions — menopause=true, limit=3, zip asked of the patient), pasted the reasoning instructions, and activated Version 3. Verified end-to-end in Agent Builder Preview: "find a provider that specializes in menopause near 92614" → Agent Router transitions to Find a Provider → calls the action with zip=92614/menopause=true/limit=3 → returns two real NPPES-derived MSCP clinicians (Dr. Helen Okafor DO MSCP, Newport Beach; Dr. Priya Anand MD FACOG MSCP, Irvine) with telehealth + accepting-new-patients status → Output Evaluation: GROUNDED. Known limit: the embed's prechat is a no-op, so the agent asks the patient for their ZIP rather than reading the intake ZIP in-band; coverage tracks the demo fixture's ZIP prefixes until provider_ingest runs against the national NPPES file (same action, no agent change).

6d89fbd agentforce: stage provider-lookup action (External Service + Named Credential + runbook)8632f6f changelog + runbook: paste-ready agent copy7245d47 agentforce: SFDX deploy harness for the Named Credential

Intake captures ZIP so MSCP recommendations are local

Wired in prototype
Details

Closed the loop on the Care Router provider wiring: intake now captures an optional patient ZIP, so the MSCP recommendations narrow to the patient's area instead of falling back to top-national matches. The scripted intake assistant (agentforce-fallback) asks for a 5-digit ZIP right after the name step — optional, ZIP-validated, and sent as undefined when blank so an empty value never filters the directory. DemoPersona gained a patientZip and each of the six personas got a ZIP whose 3-digit prefix maps to an MSCP-certified clinician in the NPPES-derived directory, so the four personas that route to an MSCP pathway (Anika, Brianna, Elena, Fatima) now surface a local specialist. personaToCareRouterIntake forwards the ZIP; the intake telemetry span records patientZipProvided. Transport needed no change — the handoff already forwards the whole IntakeRecord. New demo-cohort.test pins that every persona ZIP resolves to at least one local certified provider; full frontend suite 237/237 green.

22b7dff intake: capture patientZip to geo-narrow MSCP recommendations

Care Router wiring: the provider graph now feeds triage

Wired in prototype
Details

The NPPES-backed provider directory is no longer just a demo surface — it feeds the Care Router. When the router lands on an MSCP pathway (virtual or in-person), route() now enriches the RoutingDecision with a ranked recommended-provider list pulled from getProvidersPreferReal (live MuleSoft Experience API when MULESOFT_PROVIDERS_BASE_URL is set, otherwise the in-process NPPES-derived directory). The list is re-ranked for modality (telehealth-capable first for virtual visits, accepting-new-patients first for in-person), capped at three, and narrowed to the patient's ZIP when intake carries one. Enrichment is best-effort and never throws — a provider-graph failure leaves the routing decision intact. The recommendations flow through the existing A2A RoutingDecision artifact, the Agent Fabric trace span (recommendedProviderCount / source / names), and a new 'Provider graph · MSCP recommendations' block on the live decision card at /demo/routing. RoutingDecision gained an optional recommendedProviders field and IntakeRecord an optional patientZip; 7 new care-router tests (modality ranking both ways, ZIP passthrough, empty-directory omit, failure-never-throws, route() enrichment). Full frontend suite: 234/234 green.

09bb6f9 care-router: attach NPPES provider recommendations to MSCP pathways

Provider graph Phase 1: real NPPES taxonomy filter behind the frozen contract

Wired in prototype
Details

The provider directory is no longer a hand-curated slice. New provider_ingest package (pure standard library) streams the CMS NPPES bulk schema, filters on the real menopause NUCC taxonomy codes (OB/GYN 207V*, Reproductive Endocrinology, Endocrinology 207RE0101X, Family + Internal Medicine, NP — Women's Health 363LW0102X, CNM, PA, Women's-Health CNS — each carrying a relevance weight), overlays an MSCP credential list, and computes a deterministic graphScore (relevance + accepting-new-patients + telehealth + completeness, × MSCP boost). It emits frontend/lib/provider-directory.generated.json, which queryProviderDirectory() now loads behind the unchanged /api/mulesoft/providers contract — the hand-curated rows survive only as a fallback, and provenance.sources reports "CMS NPPES (taxonomy-filtered via provider_ingest)". The committed dataset is the pipeline run over a synthetic NPPES-format fixture (real schema + real codes, with an org row and an orthopaedist correctly filtered out); pointing pause-provider-build at the national npidata_pfile produces the full ~80K-row slice with zero contract change. NPPES has no accepting/telehealth field, so those are derived deterministically from the NPI for the demo, and the MSCP list is synthetic until the Menopause Society feed lands — both called out honestly on /proposal/provider-graph. 25 provider_ingest tests + ruff green; frontend tsc + 23 provider tests green. Run + verify steps in docs/PROVIDER_GRAPH_PHASE_1_RUNBOOK.md.

7fa9973 provider-graph: Phase 1 NPPES ingest behind the frozen contract

Data 360 Phase 2 activated end-to-end on production

Shipped
Details

Authored and activated three Data Cloud Calculated Insights on the trailsignup org over ssot__Individual__dlm (the Contact_Home data stream's first ingestion failed; Individual was already populated with 1168 records incl. all six demo personas). data-cloud.ts was aligned with the live CI surface: __cio-suffixed API names, unified_id__c dimension, __c-suffixed metric columns, and the [field=value] CI filter syntax. The real fixes: (1) the CI query endpoint is GET /api/v1/insight/calculated-insights/{ci}?filters=[...], not the /insight/query?insight_api_name=... shape the code shipped with; (2) Data Cloud requires a two-legged token flow — the core client_credentials token must be exchanged at POST <instanceUrl>/services/a360/token (grant_type urn:salesforce:grant-type:external:cdp) for a DC-scoped token, and the c360a gateway rejects un-exchanged tokens with a bare 400. Added requestDataCloudToken()/getDataCloudToken() with its own cache; dcFetch now targets the authoritative tenant instance_url from the exchange. SF_DC_TENANT_URL set on Production/Preview/Development in Vercel. Verified live: anika-patel grounding returns the three wearable insights (z-score -0.3 / burden 47.5 / disruption 0.43) with 30d/30d/7d windows.

1a441a3 data-cloud: add the required Data Cloud token exchange61736a3 data-cloud: fix CI Query API endpoint shape1901f90 data-cloud: align constants + filter expression with live trailsignup CIsfeda3d4 docs: mark Phase 2 Data Cloud activation SHIPPED + record gotchas

Week of June 9, 2026

MuleSoft iterations 3–7: Flex Gateway live, JWT auth, OAS spec, rate limiting, stable tunnel

Five iterations landed in a single session. Flex Gateway (Docker + ngrok) is running with runtime enforcement active — 401 on missing/invalid JWT, 429 on rate limit exceeded. Auth0 M2M client credentials grant issues RS256 tokens; the Next.js proxy caches and forwards them automatically. Plain Rate Limiting (10 req/min global) replaced the SLA-based policy after a BadArgument conflict with JWT. The OAS 3.0 spec is published to Exchange as a REST API asset with interactive docs. ngrok static domain is pinned in docker-compose so the tunnel URL survives restarts. Policy stack: JWT Validation + Rate Limiting (plain).

MuleSoft iterations 3–7: Flex Gateway, JWT, OAS 3.0, rate limiting, stable tunnel

Shipped
Details

Iteration 3: Flex Gateway deployed as Docker + ngrok proxy, registered with Anypoint as Omni Gateway instance (ID 20955827), Client ID Enforcement policy applied — first live runtime enforcement (401 on unauthenticated requests). Iteration 4: Rate Limiting SLA (10 req/min Demo tier) added; Next.js proxy updated to send dual auth headers (Basic Auth + client_id/client_secret custom headers) because DataWeave Base64 decode is unsupported in Flex Gateway policy sandbox. Iteration 5: OAS 3.0 spec (mulesoft/pause-provider-experience-api.oas3.yaml) written and published to Exchange as pause-provider-experience-api-spec v1.0.0 (REST API type — separate from the HTTP API asset). Iteration 6: ngrok free static domain (cattail-reactive-sassy.ngrok-free.dev) pinned in docker-compose.yml with --domain flag. Iteration 7: JWT Validation policy (Auth0 RS256/JWKS, audience-validated, expiry mandatory) replaces Client ID Enforcement; Rate Limiting SLA replaced with plain Rate Limiting (SLA-based policy caused BadArgument when JWT present — contract lookup incompatible); Auth0 M2M app pause-prototype-client configured with Client Credentials grant; frontend/lib/mulesoft/auth.ts added for 24h token caching; both health.ts and providers.ts updated to send Authorization: Bearer <jwt> with Basic Auth fallback; AUTH0_MULESOFT_* vars set in Vercel; OAS spec updated to v1.0.2 with bearerAuth security scheme.

37372b4 mulesoft: iteration 3 — Flex Gateway live, runtime enforcement active981c031 mulesoft: iterations 4-7 — rate limiting, OAS spec, stable tunnel, JWT auth

Week of June 7, 2026

MuleSoft iteration 2: /providers live + API Manager governance plane wired

MuleSoft iteration 2 shipped end-to-end. A second Experience API (/providers) is live on the CloudHub 2.0 worker; the Anypoint API Manager governance plane (API instance, Client ID Enforcement policy, Rate Limiting SLA, Demo/Production SLA tiers, registered client app, credentials set in Vercel) is fully configured. Runtime policy enforcement is deferred to Flex Gateway — a topology change, not a code change (CH2 Shared Space doesn't surface the Mule agent autodiscovery channel). Credential headers are injected from Vercel into both MuleSoft proxies today so the wire-up is a single Flex Gateway deployment away. Earlier same week: MuleSoft runtime 4.11.2 upgrade, health-flow.xml fixes, and Data 360 Phase 2 code layer.

MuleSoft iteration 2: /providers live + API Manager governance configured

Shipped
Details

GET /providers?zip=&menopause=&limit= is live on the deployed CloudHub 2.0 worker (pause-mulesoft-health-v1). The Mule flow returns a DataWeave-built provider directory ranked by graphScore with zip-prefix + menopause-certified filters; DataWeave slice clamping bug (sorted[0 to N-1] returning empty when N > array length) fixed. lib/mulesoft/providers.ts implements the same prefer-real / degrade-to-mock / warn-once pattern as health.ts: activated by MULESOFT_PROVIDERS_BASE_URL, falls back to queryProviderDirectory() on any failure. 23 new unit tests (providers.test.ts); total MuleSoft lib count: 45/45. MULESOFT_PROVIDERS_BASE_URL, MULESOFT_CLIENT_ID, and MULESOFT_CLIENT_SECRET are set in Vercel production; both /health and /providers proxies inject client credentials on every request. Anypoint governance plane: API Manager instance ID 20954842 registered, Client ID Enforcement + Rate Limiting SLA policies applied, Demo tier (10 req/min, auto-approve) + Production tier (1000 req/min) created, pause-prototype-client app approved on Demo tier. Runtime enforcement deferred: CH2 Shared Space doesn't expose the Mule agent autodiscovery channel; Flex Gateway is the path to activate the 401/429 enforcement at the wire. Runbook updated to document the full state and the Flex Gateway next step.

1e4468e mulesoft: iteration 2 — /providers live + API Manager runbook

MuleSoft: runtime 4.11.2, Java 17, health-flow.xml fixes

Today · partial
Details

mule-artifact.json bumped to minMuleVersion 4.11.0 with javaSpecificationVersions: ["17"]. pom.xml bumped to app.runtime 4.11.2, mule-maven-plugin 4.7.0. health-flow.xml had two XML errors that prevented Code Builder from rendering the canvas: (1) <http:headers> used as a standalone flow processor — moved it into <http:response> nested inside <http:listener> where Mule 4 expects it; (2) double-hyphen (--) inside an XML comment — illegal in XML, replaced with single hyphen. Code Builder .vscode/launch.json and .vscode/settings.json scaffolding committed.

3662130 mulesoft: bump runtime + fix health-flow.xml

Data 360 Phase 2: Data Cloud Calculated Insights layer

Today · partial
Details

New lib/salesforce/data-cloud.ts implements the Data Cloud Query API and Calculated Insights API client, mirroring the same warn-once / prefer-real / degrade-to-null pattern as the Phase 1 SOQL path. Activated by SF_DC_TENANT_URL env var. lib/salesforce/grounding.ts updated to call getWearableInsights() in parallel with the four SOQL queries; each of the three wearable insights (Pause_HRV_RMSSD_30d, Pause_Vasomotor_Burden_30d, Pause_Sleep_Disruption_7d) falls back to its intake baseline independently. groundingProvenance.federatedQuery reflects which path served the request. frontend/.env.example documents the new vars with derivation notes. Full org setup walkthrough — DMO authoring, CI SQL, mock CI path, env var wiring, verification curls — in new docs/MULESOFT_PHASE_2_DATA_CLOUD.md. Probe result: trailsignup org has the permission sets but no provisioned DC tenant; code is ready and waiting.

8a2e55f data-360: Phase 2 Data Cloud Calculated Insights layer

Week of June 1, 2026

Honesty-pilling marathon

Thirty-plus commits across every public page on the site. The single theme: replace any present-tense claim that isn't yet true with a StatusPill-flagged 'today vs. designed' framing. The Apache-2.0 license + OSS-hygiene trio (CONTRIBUTING / CODE_OF_CONDUCT / SECURITY) landed mid-week, the polish marathon wrapped with a reproducible end-to-end smoke test (132 / 132 pass), the JupyterHealth integration jumped from designed-on-paper to wire-level prototype (27 / 27 against an in-process JHE mock), the Care Router business logic got its first test safety net (100 new tests covering ~1,100 lines of previously-untested risk-band + pathway + A2A code), and the MuleSoft Phase 1 deploy artifact got pre-staged (deployable Mule app, live/mock proxy with graceful degradation, 31 new unit tests, env-gated investor badge) so the Anypoint clickthrough is the only remaining work on the user's plate.

MuleSoft Anypoint Phase 1: deployable artifact + live/mock proxy

Today · partial
Details

Phase 1 shipped 2026-06-07. A real Mule 4.11.2 app is running on CloudHub 2.0 (Cloudhub-US-West-1, Sandbox) at https://pause-mulesoft-health-v1-zkeniz.scqos5-1.usa-w1.cloudhub.io. MULESOFT_HEALTH_BASE_URL is set in Vercel production; /api/mulesoft/health reports meta._source: 'live-mulesoft' and meta._liveUrl matches the worker. Degradation path verified: stopping the Mule app surfaces meta._source: 'mock-fallback' with _liveAttempted: true — the prototype never goes hard-down. /proposal/mulesoft shows the green LIVE badge. Build fixes required along the way: mule-http-connector dependency missing from pom.xml, property placeholder ${http.listener.port:8081} replaced with hardcoded 8081, DataWeave (idx, _) two-arg lambda syntax replaced with $ / $$ implicit vars, config.yaml added for configuration-properties. Repo-side: lib/mulesoft/health.ts prefer-real / degrade-to-mock / warn-once client, 31 unit tests, env-gated investor badge.

55e1b6d MuleSoft Phase 1 repo prep3662130 bump runtime 4.11.2, fix health-flow.xmla4635f2 add mule-http-connector dependencya4b75fc add config.yaml + configuration-propertiesbc6172b hardcode port 808138f4a24 fix DataWeave lambda syntax6a3c4ed set MULESOFT_HEALTH_BASE_URL in Vercel production

Care Router business logic: +100 unit tests, drift caught

Wired in prototype
Details

Five new test files cover the highest-leverage business logic on the site: lib/risk-band.test.ts (30 tests pinning the deterministic intake → band → pathway decision tree against every persona in the demo cohort), lib/care-router-pathways.test.ts (11 tests pinning the canonical six-pathway enum), lib/care-router.test.ts (25 tests covering scriptedRoute's red-flag / severity / cycleStatus / ageBand / Data 360 grounding branches plus the claudeRoute no-API-key fallback), lib/agent-fabric.test.ts (20 tests covering evaluateGovernance, the trace ring buffer, and listRecentTaskIds), and app/api/agents/care-router/tasks/route.test.ts (14 tests covering JSON-RPC envelope validation, governance block path, success path with RoutingDecision artifacts, and metadata.parentSpanId / personaId passthrough into recorded trace spans). The risk-band suite surfaced a real drift: Brianna Okafor's displayRisk on the public /demo/intake queue table was labeled 'Moderate' but her sleepScore=8 trips the single-axis-promotion rule and computeRisk returns 'High'. Fixed the data, the tests now pin both surfaces. Total frontend test count: 73 → 173. Smoke test still 132 / 132.

79bb9b0 Care Router test suite

pause_ingest → JHE: wire-level contract test (27 / 27 pass)

Wired in prototype
Details

New in-process JHE mock server (tests/jhe_mock_server.py) implements the OAuth2 + FHIR endpoints pause_ingest actually hits. Seven integration tests (tests/test_exchange_integration.py) exercise the production exchange.upload_observation, hrv_features_to_fhir_observation, and read_recent_observations code paths end-to-end — including a full-pipeline test that uploads 6 raw heart-rate observations, computes time-domain HRV features, uploads the derived observation with derivedFrom provenance, and reads everything back. The contract test surfaced a real bug in read_recent_observations (the JupyterHealthClient 0.2.0 API doesn't accept client_id/client_secret) that lenient unit-test doubles missed. Added hrv_features_to_fhir_observation helper. New runbook at docs/JHE_SETUP_RUNBOOK.md captures the path to swap the mock for real JHE in an afternoon (~1 afternoon, gated on Docker). Flipped the JupyterHealth pill on /roadmap from designed to prototype.

e1e43aa pause_ingest → JHE contract test

End-to-end smoke test — 132 / 132 pass

Shipped
Details

New reproducible smoke-test harness at frontend/scripts/smoke-test.mjs. Hits all 35 public routes, follows 77 unique internal links discovered by parsing rendered HTML, and POSTs realistic fixtures to 16 API endpoints (including the A2A JSON-RPC tasks/send envelope to /api/agents/care-router/tasks). Results land in SMOKE_TEST_RESULTS.md committed at the repo root. Caught one false-positive in the link extractor (query-string handling) on the first run; no real regressions on the polished surface. Wired into package.json as `npm run smoke`.

1fa3a19 smoke test + 132/132 results

/changelog + /roadmap pages

Shipped
Details

Built /changelog as a hand-curated weekly narrative with real commit SHAs linking to GitHub, and /roadmap as a Now / Next / Later horizon view drawn from the 30+ designed / planned / future items already pilled across the site. Home page got a 'momentum strip' (63 commits since May 24, 2026) with cross-links to both pages.

cd1ea17 changelog + roadmap pages

Apache-2.0 license + OSS-hygiene trio

Shipped
Details

Released the source under the Apache License, Version 2.0 — the patent grant matters more than MIT's brevity in healthcare AI. Added the standard CONTRIBUTING.md / CODE_OF_CONDUCT.md / SECURITY.md set at the repo root, taking GitHub's Community Standards checklist to 100%. NOTICE file lists upstream attributions (JupyterHealth, DBDP, FLIRT, Salesforce, MCP, Anthropic, Menopause Society directory).

83db016 docs: OSS-hygiene trio4090e33 license: Apache-2.0

/proposal/full — long-form investor brief polished

Shipped
Details

Nine high/medium-priority honesty fixes on the 4,000-line full proposal page. Hero copy softened from present-tense to 'designed to help clinicians…'. The $1,685 avoidable-spend metric deduplicated and pinned to its literature source. Anchor-provider claims softened to 'design-partner provider organizations'. whatPauseProvides and techFoundation cards each get per-card StatusPills. businessChannels ACV/PMPM table re-framed as Target ACV ranges with caveats. HIPAA/HITRUST/SOC 2 claims reconciled with the /security page.

91ee6ee proposal/full: pills + dedupe + sync

Seven supporting pages reconciled with reality

Shipped
Details

/careers, /security, /hipaa, /research, /privacy, /blog, /terms — each replaced false present-tense claims with explicit 'Today vs. Designed' tables. /security: removed 'BAAs executed' and 'SOC 2 Type II in progress' claims. /hipaa: stated outright 'Pause-Health.AI is NOT a Business Associate today.' /research: removed 'bias monitoring quarterly with clinician review' (no such program exists yet). /careers: reconciled the three founding roles (CMO, Head of AI, Head of Clinical Design) to match /about, all pilled 'future'.

b60385b careers/security/hipaa/research/privacy/blog/terms: honesty pilling

/about, /press, /contact — credibility polish

Shipped
Details

/about: hero updated to 'Pre-design-partner; prototype in the open'. Milestones split into Done vs. Planned with explicit pills. /press: replaced one-line stub with a real press kit — approved boilerplate, founder bio + headshot, brand-asset downloads, milestones, media contact with response-time SLA. /contact: each email alias now lists audience, what-to-include, response-time expectations. 'Self-route' section deflects to /careers, /press, /security, GitHub issues.

82a95db about/press/contact: honesty pilling + real press kit

Home page rebuilt with honest hero

Shipped
Details

New 'What's live today' strip with four prototype-pilled cards linking directly to /demo/intake, /demo/patient, /demo/routing, /demo/agent-fabric. Two-arc CTA section splits 'investors + partners' from 'builders + clinicians' with distinct calls-to-action. Founder credibility line links to /about and Maggie's LinkedIn. The $1,685 figure was removed from the hero (kept only in /proposal/full with proper research citation).

c3b71d3 home: honest hero + What's live today + two-arc CTAs

Persona-aware navigation across all five /demo/* pages

Shipped
Details

DemoShell top nav now preserves the selected persona across pages (clicking 'Care Router' from /demo/intake?personaId=anika-patel keeps Anika selected). PreBriefPanel grew a compact switch-persona chip row, journey shortcuts ('Open Care Detail for Anika →'), and a risk-band + suggested-pathway verdict. /demo/analytics filters its cohort-comparison view by persona. /demo/agent-fabric grew a 'View all Anika's traces' link. A new PersonaJourneyFooter renders consistently across all five demo pages.

a063a8d demo: PreBriefPanel persona-aware polish1307ac2 demo: persona-filterable agent-fabric + cross-links45344bd demo: shared PersonaJourneyFooterdb057af demo: persona-preserving shell nav + analytics filter

Week of May 25, 2026 — late

Investor-brief polish, Arc A + Arc B

Eight architecture pages and four go-to-market pages each got a per-card StatusPill retrofit. The shared <StatusPill> component was extracted and the vocabulary canonicalized so 'Designed' means the same thing on /proposal/strategy as it does on /proposal/agentforce.

Arc B — eight architecture deep-dives polished

Shipped
Details

/proposal/agentforce, /proposal/mulesoft, /proposal/mcp, /proposal/dbdp, /proposal/integration, /proposal/provider-graph, /proposal/menopause-society, /proposal/data-360. Each rewritten with per-card pills, env-variable tables where relevant, and explicit 'today contract vs. designed pipeline' framing. /proposal/menopause-society: stale ~2,500 MSCP count updated to ~4,100 with a Research-pilled source citation.

94e514b proposal/data-360: per-card pills + IR CTA95e1fb2 proposal/menopause-society: fix stale count7f7dc6b proposal/provider-graph: prototype vs designedc55eae5 proposal/dbdp: per-row status pills1630708 proposal/integration: Phase 0 + pills0805a32 proposal/mulesoft: tense + pills96db851 proposal/mcp: gate npx behind Phase 10748050 proposal/agentforce: honesty + env-table

Arc A — go-to-market pages and shared <StatusPill>

Shipped
Details

/proposal/customers, /proposal/competition, /proposal/data, and the /proposal hub page each got the status-pill retrofit. The pill component itself was extracted from inline copies and canonicalized — three tones (real / mock / info) to distinguish 'this code ships today', 'this code is designed', and 'this is a research-derived number, not a capability'. Subsequent commits retrofit eight already-polished pages onto the shared component.

3b67edc proposal: extract shared <StatusPill>, retrofit 8 pagesced0fc0 Arc A pages: customers / competition / data189e565 proposal hub: Arc A / Arc B grouping + demo links

Week of May 25, 2026 — early

Demo surface rebuild, persona-aware

The five /demo/* pages were each rebuilt around the canonical DEMO_COHORT personas. /demo/patient grew a Care Detail layout with risk gauge + axis flags + HRT suitability. /demo/routing demonstrates the Care Router decision live. /demo/analytics replaced static placeholder charts with operational metrics computed from real API trace data. /demo/agent-fabric joined the shared DemoShell nav.

Five /demo/* pages rebuilt around personas

Shipped
Details

Each demo page now accepts ?personaId=anika-patel (or any of the six seeded personas) and renders persona-aware content end-to-end. /demo/patient: Care Detail layout with risk gauge, axis flags, HRT suitability. /demo/routing: live Care Router decision with persona-specific intake hints. /demo/analytics: operational metrics + pathway-mix chart computed from real API traces.

045aa04 /demo/agent-fabric into shared DemoShell2afb917 /demo/analytics: live ops metrics + chart81b48e3 /demo/routing: persona-aware routing demoa984061 /demo/patient: persona-aware Care Detail

Pre-Brief Panel ships — Embedded Messaging context layer

Shipped
Details

After discovering Salesforce's prechatAPI is a no-op Proxy in Embedded Messaging V2, pivoted from hidden pre-chat fields to a visible Pre-Brief Panel on /demo/intake. The panel surfaces the patient's Data 360 dossier (real Salesforce when SF_* env vars are set, deterministic mock otherwise) so the agent walks in pre-grounded.

692f0a2 Pre-Brief Panel: stack long Cohort_Name row26fb582 Pre-Brief Panel ships + V2 prechatAPI dead-end documented2bb4e15 Phase 18b: full agent-side wiring

Week of May 24, 2026 — initial build

Prototype-in-the-open lands

The first week of Pause-Health.AI work. Eleven commits stood up the marketing site, investor brief, demo surface, MuleSoft integration plane, MCP server, multi-agent control plane, Salesforce Agentforce intake, and the Data 360 grounding layer — all built on top of the legacy Northstar Shipping API repo that already had CI/CD wiring.

Multi-agent control plane

Shipped
Details

Four agents (Agentforce intake, Anthropic Claude Care Router, Pause MCP server, MuleSoft Process API) wired through Google A2A + MCP, orchestrated by a MuleSoft Agent Fabric mock. Live console at /demo/agent-fabric.

ded1e63 multi-agent control plane

Salesforce Data 360 grounding layer

Shipped
Details

Care Router grounds on real Salesforce Health Cloud objects (Contact + CareProgramEnrollee + CarePlan + Case) when SF_INSTANCE_URL/CLIENT_ID/SECRET are set; deterministic mock when unset. Agent Fabric console shows LIVE badge on every span served by a real org.

57dbdfd Data 360 grounding

Agentforce intake + Menopause Society referral path

Shipped
Details

Salesforce Agentforce Service Agent intake wired into the prototype with Pause-branded fallback. /proposal/menopause-society lays out the MSCP referral path with explicit ToS guardrails (deep-link to The Menopause Society's directory rather than scraping).

1334296 Agentforce intakecc09923 Menopause Society referral path

Forward-looking

What's coming next

The roadmap groups the 31+ designed / planned / future items already pilled across the site into Now / Next / Later horizons. Each item links back to the page that describes it in detail.

Open the roadmap →

Watch the build

Subscribe to commits

The repo is public. Watch it on GitHub to get notified of new commits, or subscribe to the planned essays at /blog for the editorial version.

GitHub →Editorial →