Clinical Intake (healthcare)

A behavioral-health intake that makes compliance visible, not just claimed — for digital-health builders. Synthetic data only.

What it is — compliance you can see

clinical-intake is the healthcare-lead exemplar blueprint: a behavioral-health intake record whose PHI fields are handled by the platform, not by your app code. The point is that you can demonstrate the handling — open a record, look at its history, run a search — in about 60 seconds, rather than take a compliance claim on faith. Everything below runs on synthetic data against an invite-only 0.x preview.

What bootstrap provisions

vectros bootstrap --blueprint clinical-intake provisions one context (clinical-intake), one schema (intake, indexMode: HYBRID), a service principal, a least-privilege access profile, a narrow scoped key, and one synthetic seed record. The intake schema separates working fields from PHI:

Non-sensitive working fields (safe to index, search, and filter):

  • caseId — required; the stable dedup/lookup key.
  • presentingConcernsearchable: true; a non-PHI summary, safe to put in the index.
  • programfilterable: true; the service line the intake routes to.
  • statusfilterable: true; enum new | in_review | scheduled | closed.
  • submittedAt — ISO-8601 timestamp.

Sensitive (PHI) fields — each marked sensitive: true:

  • clientName
  • dateOfBirth
  • ssn
  • clinicalNote

The schema sets capabilities.auditHistory: true explicitly (it is the platform default, but a compliance exemplar self-documents its posture).

It declares three non-sensitive lookup fields — caseId (unique, for exact get/upsert) plus program and status (non-unique) — so a coordinator can enumerate a worklist directly via record_query lookup: "all outpatient-counseling intakes", "all new intakes". That is the deterministic, no-query counterpart to semantic hybrid_search, and a real care-ops access pattern beyond meaning-based recall. The PHI fields are deliberately not lookup fields here — enumeration runs entirely on the non-sensitive working fields.

The access profile is deliberately narrow:

allowedActions: ['records:r', 'records:c', 'records:u', 'search:r', 'schemas:r']

Note what is absent: there is no records:d (intakes are retained, not deleted) and no s reveal scope — so the bootstrapped key itself cannot un-redact the PHI fields. That is the whole point of the demo: the credential you are handed literally has no path to the plaintext sensitive data.

Before you start

Honest prerequisites:

  • An invite to the 0.x preview and the Vectros CLI.
  • A dev-portal Cognito bridge token (a human step) so the CLI can talk to the API.
  • For the visual part of the demo, access to app.vectros.ai (the reference data-plane app) and/or the MCP server wired into your agent.

Synthetic data only — never enter real PHI. This is a preview demo tenant. The seed record and every example field below are fictional. Do not type a real name, real date of birth, real SSN, or any real clinical text into it. The clientName: 'Jordan Sample', ssn: '000-00-0000', and clinical note in the seed are illustrative, not a real person.

1. Bootstrap the blueprint

# install once: npm i -g @vectros-ai/cli  (or use npx @vectros-ai/cli, below)
npx @vectros-ai/cli bootstrap --blueprint clinical-intake

This provisions the schema, context, service principal, gated access profile, and the seed record, then prints a scoped key (ssk_*). The bootstrap is idempotent. If you are driving an agent via MCP, the key is auto-merged into your Claude Desktop config (for Cursor/Cline, pass --print and paste the mcpServers.vectros block) so the agent can act as the intake service principal — with exactly the five scopes above and nothing more.

2. Create a synthetic intake

Create an intake either through the MCP server (record_create) or directly in the data-plane app. Use synthetic PHI only — for example:

{
  "caseId": "demo-intake-001",
  "presentingConcern": "Sleep difficulty and low mood over the past month; seeking counseling.",
  "program": "outpatient-counseling",
  "status": "new",
  "submittedAt": "2026-06-14",
  "clientName": "Jordan Sample",
  "dateOfBirth": "1990-01-01",
  "ssn": "000-00-0000",
  "clinicalNote": "Synthetic note for demonstration. Reports difficulty sleeping; no acute safety concerns noted."
}

The four sensitive fields are written through the same API as the rest — your app does nothing special. The platform takes over from there.

Expected: when you read the record back through this blueprint's key, the four sensitive fields come back masked ([redacted]) — that is the feature working, not a bug. The bootstrapped key deliberately carries no s reveal scope, so it cannot un-mask PHI; revealing plaintext requires a separate, more-privileged key minted with records:r:<type>:s. The non-sensitive fields read back normally.

3. Watch the redaction (the aha)

Three observations, each of which proves a specific, implemented claim.

(a) Open the record's History in app.vectros.ai. Navigate to the record detail page and look at the History card. Every version row shows the change type, when it happened, who made it, and which fields changed — but the sensitive fields are never rendered in plaintext, in any version row, regardless of your scope. Why this proves it: the PHI was redacted at write time — destroyed before the audit snapshot was ever persisted, not masked behind a permission check. There is no plaintext copy in the history to leak, so no scope can surface one.

(b) Edit a non-sensitive field and watch the audit trail grow. Change status from new to in_review and reload the History. A new immutable version row appears, recording the change to status — while the sensitive fields stay redacted across every row. Why this proves it: the audit/version history is append-only and tamper-evident (a SHA-256 state-continuity chain), so the trail of who changed what, when is preserved — without ever capturing the PHI.

(c) hybrid_search for a phrase from the clinical note → zero hits. Run a hybrid search for a distinctive phrase that exists only in clinicalNote (e.g. "difficulty sleeping"). It returns no results. Then search for a phrase from presentingConcern and confirm the record does come back. Why this proves it: sensitive fields are excluded from the search index at write time, so a note phrase can never leak through search results — while the non-PHI working fields remain fully searchable.

How it maps to Vectros compliance

Each bullet is tied to an implemented capability:

  • Redact-at-write (PHI): sensitive fields are stripped from audit snapshots and structured diffs at write time — destroyed before persist, unrecoverable regardless of scope. This is not reversible masking.
  • Immutable, tamper-evident audit / version history: every write to an audited model emits an immutable version row (change type, who, previous content, changed fields), with heavy content externalized to a WORM Object-Lock (GOVERNANCE) bucket. The state-continuity chain is tamper-evident (SHA-256), not tamper-proof.
  • Search-index exclusion: sensitive fields never enter the search index, so PHI cannot leak via search results — while non-PHI fields stay searchable.
  • Read-time masking + the s scope: in responses, sensitive fields are masked unless the token carries the s reveal scope. This blueprint's key does not carry s, so the demo credential cannot un-redact PHI.
  • Context isolation: contextId is a mandatory, auth-derived, fail-closed partition key on records/schemas/documents/folders, and lookups are same-context-only.
  • Least-privilege keys: the bootstrapped ssk_* carries exactly five data-plane scopes — no delete, no reveal, no control-plane.
  • Independent security auditing: the platform has been through independent security audits with prior Criticals remediated, and stays under active pre-launch re-auditing through the preview.

Notes & limits

  • Synthetic data only. Never enter real PHI into the demo tenant.
  • Tamper-evident, not tamper-proof. The audit chain detects tampering; a continuous external verifier is not part of this claim.
  • Not claimed here: end-subject right-to-erasure, data residency, and BYOK / per-tenant CMK are not part of this walkthrough and are not implemented for this demo. Do not read them in.
  • Legal terms. BAA and single-region posture are scoped to the partner data plane and are available for discussion under NDA — treat specific legal coverage as soft until confirmed with us directly.