PVA Local Data and AI Boundary Pass
local-data-ai-boundary-pass artifact · for Patient Visit Advocate · phase PVA-SLICE-02 · status approved
local-data-ai-boundary-pass artifact · for Patient Visit Advocate · phase PVA-SLICE-02 · status approved
No explicit evidence field yet. Require tests, screenshots, linked PRs, or reviewed outputs before marking complete.
- phase: id: string, name: string, status: string
- title: PVA Local Data and AI Boundary Pass
- product: Patient Visit Advocate
- purpose: Convert the approved patient-data-ai-contract into implementation-ready data and model boundaries: explicit state machine, field-level entity specs, local storage recommendation, AI boundary options, hard blockers before server-side PHI, and free-to-paid transition rules. This is a focused pass artifact — no code, no migrations.
- pass type: delta
- created at: 2026-05-08
- created by: vikram
- ai boundary: output_contract: object, local_prototype_options: object, recommended_prototype_path: string, ai_agent_constraints_from_architecture: object
- artifact type: local-data-ai-boundary-pass
- data entities: 6 items
- open decisions: 4 items
- schema version: 1.0
Machine-readable source fields
PVA-SLICE-02
Patient Data + AI Contract
draft
PVA Local Data and AI Boundary Pass
Patient Visit Advocate
Convert the approved patient-data-ai-contract into implementation-ready data and model boundaries: explicit state machine, field-level entity specs, local storage recommendation, AI boundary options, hard blockers before server-side PHI, and free-to-paid transition rules. This is a focused pass artifact — no code, no migrations.
delta
2026-05-08
vikram
- StructuredCaptureField records with source and confidence tags
- Visit brief stub with uncertainty markers
- Question plan items framed as clinician discussion questions
- Safety flags isolated in EscalationEvent, not mixed into summary text
- model_version and generated_at provenance on any AI-generated artifact
- Diagnosis or differential diagnosis as fact
- Treatment instruction or medication recommendation
- Dosage recommendation
- Emergency triage specificity beyond approved escalation copy
- Any field labeled 'diagnosis', 'treatment', or 'recommendation' without explicit clinician-framing
| option | phi risk | tradeoff | description | recommended for | blocker |
|---|---|---|---|---|---|
| A — Fully Manual / Stubbed | None — no model call. | Lower fidelity for testing value prop, but safest for prototype. Validates the form factor. | No AI call. Structured fields are entered by the user directly. VisitBrief and QuestionPlan are template-based stubs. | First 5–10 user tests. | |
| B — Browser-Local Model (e.g. WebLLM / Ollama local) | Low — no server transmission. Model provenance and output quality must be verified. | Feasibility depends on device capability and model size. Not guaranteed on all phones. | Small model runs on device. RawCapture text is processed locally. No text leaves the device. | Model selection and output quality review required before patient testing. | |
| C — Controlled Cloud Model with Synthetic Data Only | None if strictly synthetic. Must enforce no-real-PHI rule at call site. | Good for validating generation quality without PHI risk. Must not drift to real data. | Cloud model (e.g. Claude API) called with synthetic/anonymized intake text only. No real patient text. | Demo and internal quality testing before real-user prototype. | |
| D — Cloud Model with Approved Consent Path | High — all server PHI blockers (SPB-001 through SPB-007) must be cleared. | Full product experience but blocked until legal, data contract, and retention decisions complete. | Real patient text sent to cloud model. Requires full server-side PHI contract. |
Option A (manual/stubbed) for initial prototype. Option C (synthetic cloud) for internal generation quality testing. Option D only after all server PHI blockers resolved.
- intake-agent: No diagnosis, no treatment recommendations. Ask adaptive questions, extract structured fields from messy input.
- clinical-guardrail-layer: Classify seriousness signals conservatively. Never produce diagnosis categories as facts.
- question-generator: Questions framed for clinician discussion only. Never clinical directives.
- translator: Uncertainty preserved. No simplification that loses important qualifiers.
- memory-writer: User-corrected facts only. Raw chat is not primary memory.
local-data-ai-boundary-pass
| name | fields | purpose | storage scope | user controls | analytics rule |
|---|---|---|---|---|---|
| LocalVisitDraft | - local_id: name: string, type: string, notes: string, required: boolean - state: name: string, type: string, notes: string, required: boolean - visit_label: name: string, type: string, notes: string, required: boolean - created_at: name: string, type: string, notes: string, required: boolean - last_opened_at: name: string, type: string, notes: string, required: boolean - expires_at: name: string, type: string, notes: string, required: boolean - deleted_at: name: string, type: string, notes: string, required: boolean - server_visit_id: name: string, type: string, notes: string, required: boole | Anonymous on-device visit prep container before any account creation or server sync. | local-only | - delete - export - view expiry date - extend expiry once | Only state transitions and funnel counters may be reported. No visit_label, no health text. |
| RawCapture | - capture_id: name: string, type: string, notes: string, required: boolean - local_draft_ref: name: string, type: string, notes: string, required: boolean - capture_type: name: string, type: string, required: boolean - text: name: string, type: string, notes: string, required: boolean - created_at: name: string, type: string, required: boolean - retention_policy: name: string, type: string, notes: string, required: boolean - local_only: name: string, type: string, notes: string, default: boolean, required: boolean | Original typed or voice-transcribed user input, local-first with explicit retention tagging. | local-only by default | ||
| StructuredCaptureField | - field_id: name: string, type: string, required: boolean - local_draft_ref: name: string, type: string, required: boolean - section: name: string, type: string, required: boolean - label: name: string, type: string, notes: string, required: boolean - value: name: string, type: string, notes: string, required: boolean - source: name: string, type: string, required: boolean - model_confidence: name: string, type: string, notes: string, required: boolean - user_corrected: name: string, type: string, default: boolean, required: boolean - user_confirmed_at: name: string, type: string, notes: strin | Field-level extracted or user-entered structure from RawCapture, with model confidence and user correction state. | local-only by default; server-syncable post account save if server PHI blockers cleared | ||
| EscalationEvent | - event_id: name: string, type: string, required: boolean - local_draft_ref: name: string, type: string, required: boolean - trigger_category: name: string, type: string, notes: string, required: boolean - copy_version: name: string, type: string, notes: string, required: boolean - acknowledged_at: name: string, type: string, notes: string, required: boolean - stored_scope: name: string, type: string, notes: string, default: string, required: boolean | Record that serious-symptom safety copy was shown and acknowledged. Separates safety signal from health-text analytics. | local-only; never synced to analytics or third-party systems | trigger_category counter (no text) may be reported as a funnel safety metric only after server PHI blockers cleared and only as aggregate count. | |
| QuickVisitNote | - note_id: name: string, type: string, required: boolean - local_draft_ref: name: string, type: string, required: boolean - question_ref: name: string, type: string, notes: string, required: boolean - note_text: name: string, type: string, notes: string, required: boolean - note_type: name: string, type: string, required: boolean - question_status: name: string, type: string, notes: string, required: boolean - created_at: name: string, type: string, required: boolean - local_only_until_saved: name: string, type: string, notes: string, default: boolean, required: boolean | In-visit or immediate post-visit note tied to question status or debrief. Supports in-visit quick note mode and post-visit capture. | local-only until user opts into account save | ||
| ExportArtifact | - export_id: name: string, type: string, required: boolean - local_draft_ref: name: string, type: string, required: boolean - format: name: string, type: string, required: boolean - sections_included: name: string, type: string, notes: string, required: boolean - created_at: name: string, type: string, required: boolean - user_confirmed_sensitive_share: name: string, type: string, notes: string, required: boolean - destination: name: string, type: string, notes: string, required: boolean | Metadata record of a local export/share package. Tracks what was shared and requires explicit user acknowledgement before generation. | local-only metadata; exported file is user-managed | export format and sections_included count only may be reported. No health text, no visit label. |
| id | owner | impact | decision |
|---|---|---|---|
| OD-001 | Justin / Product | Determines whether any model infrastructure is needed for SLICE-01 testing. | Which AI option (A/B/C) is used for the first prototype build? |
| OD-002 | Justin / Product | If any free server persistence: all SPB blockers apply to free tier. | Does the free app include a limited saved-visit trial (e.g. 3 visits), or is free always local-only? |
| OD-003 | Content / Legal | SPB-005 blocks all patient-facing testing until resolved. | What is the approved escalation copy version (ESC-V1 token and exact copy text)? |
| OD-004 | Justin / Legal | SPB-003 blocker. No real PHI to cloud until resolved. | Which server-side model provider and DPA are selected for Option D? |
1.0
| id | role | uuid |
|---|---|---|
| patient-data-ai-contract/PVA-SLICE-02 | primary contract to expand | 1d0623fa-7b89-46d2-ab35-4b5223f17507 |
| architecture/MVP-01 | approved AI agent boundaries and generation pipeline | 9783e2c4-7623-4324-8aaa-86ee7dd77733 |
| local-pocket-prototype-spec/PVA-SLICE-01 | offline behavior, expiry, required screens | ae4aafaa-7ac7-4054-9b0a-fa443a7c8d94 |
| trust-boundary-charter/PVA-SLICE-00 | hard rules TB-001 through TB-008 | 78ca477c-cd9c-4ba8-84ed-db0944e88702 |
| revised-decomposition-plan/PVA-AUTOPILOT-01 | routing and slice exit conditions | 17a8249c-f8f0-42e5-aef1-1c9dd7e0c784 |
M-01 Visit Data Model and Architecture MVP-01 define the full server-side entity set and AI workflow. This pass does NOT modify those artifacts. It adds six local-prototype entities not present in M-01, specifies their state machine and field contracts, defines local-only storage, and draws the lines AI processing must not cross before server-side PHI is approved.
- LocalVisitDraft — anonymous on-device container with explicit state machine
- RawCapture — original user input with retention tagging
- StructuredCaptureField — field-level extraction with confidence and correction state
- EscalationEvent — record of serious-symptom copy acknowledgement
- QuickVisitNote — in-visit and immediate post-visit note keyed to question status
- ExportArtifact — local export package metadata with sensitive-share acknowledgement
- PatientProfile
- Visit
- IntakeSummary
- VisitBrief
- QuestionPlan
- PostVisitDebrief
- PatientMemoryItem
- CaregiverAccess
- LegalAcknowledgement
- No diagnosis or differential diagnosis
- No treatment or medication recommendation
- AI-first orchestrated workflow with structured artifacts
- Generated memory not reused in prompts until user-confirmed
- Analytics must never include health text, names, question text, brief or debrief content
Single-visit prep loop: messy intake, editable structure review, visit brief, question plan, in-visit quick notes, post-visit debrief capture, local export, draft recovery and delete.
Local device only. No server-side persistence.
30 days default, 7-day grace on expiry. User can extend once.
Options A, B, or C only (no real PHI to server). Option D requires all SPB blockers resolved.
Persistent saved history, cross-visit memory search, unresolved question continuity, reusable user-confirmed memory.
- LocalVisitDraft
- RawCapture
- StructuredCaptureField
- EscalationEvent
- QuickVisitNote
- ExportArtifact
State transition counters, funnel events, export format counts. No health text, visit labels, or question text.
Persistent PatientMemoryItem (M-01), saved Visit records, longitudinal QuestionPlan continuity, searchable history, cross-visit ExportArtifact generation.
Server-side M-01 entities via approved account sync path.
Generated memory (PatientMemoryItem) must not be reused in AI prompts until user explicitly confirms or edits. Architecture MVP-01 memory-writer agent boundary applies.
Option D after all SPB blockers cleared.
Do not punish free user immediately after trust is earned. Debrief capture is free. Saved/searchable longitudinal debrief memory is the paywall. Trust Boundary Charter caution rule applies.
User opts into account save. LocalVisitDraft.server_visit_id is populated. Local records may be migrated to server entities following approved sync path.
A limited free account tier may be offered (e.g. 3 saved visits) as a trial hook, but this is an open decision (OD-002).
If free account includes any server-side health text storage, all SPB blockers apply to the free tier.
Must be resolved before account/save flow is implemented. Default assumption for this pass: free = local-only.
Multiple PatientProfile records, CaregiverAccess grants, delegated prep and follow-up, family memory continuity.
Not in first prototype or MVP. Deferred to SLICE-04 or later per revised-decomposition-plan.
Requires CaregiverAccess (M-01) and multi-profile PatientProfile support. No new schema defined here.
- Structured relational storage supports the state machine, foreign key relationships between draft→capture→fields→notes, and expiry queries.
- AsyncStorage is insufficient for relational queries across entities; use for non-relational user preferences only (e.g. onboarding flags, theme).
- IndexedDB (Dexie) is viable for web/PWA; SQLite preferred for native mobile for better query performance and data integrity.
- Local encryption: use Expo SecureStore or SQLCipher (SQLite) for the database file at rest. Key derived from device secure enclave or user-provided PIN. No cloud key storage in prototype.
SQLite via Expo SQLite or React Native SQLite (native mobile) / IndexedDB with Dexie.js (web/PWA)
Required before any patient-facing test with real health text. Encrypt the local DB file. Key in device secure enclave.
No health text leaves device in local prototype. If network call required for AI, use TLS 1.2+ minimum.
Store only: key_created_at, key_version, enclave_type. Never store the key itself in app storage.
On app launch, query all LocalVisitDraft where expires_at < now() and state != draft_deleted. Transition to draft_expired, show recovery prompt.
Child records first (RawCapture, StructuredCaptureField, EscalationEvent, QuickVisitNote, ExportArtifact), then LocalVisitDraft. Never partial-delete a draft.
7 days from expires_at. After grace period, delete all child records before deleting draft.
For the first local-only prototype, a single SQLite database without encryption is acceptable IF AND ONLY IF synthetic/demo data is used. Real patient text requires encryption before any testing.
- Resolve OD-001 (AI option for prototype) before SLICE-04 UX Build Gate dispatches.
- Resolve OD-003 (escalation copy version) before any patient-facing test regardless of AI option.
- This artifact feeds SLICE-04 (Pocket UX Build Gate): screen inventory and state maps should reference LocalVisitDraft state machine.
- This artifact feeds SLICE-05 (Patient-Facing MVP Build): all SPB blockers must be resolved before Option D AI and server-side PHI entity persistence.
- Do not dispatch implementation tasks from this pass. This is a boundary and decision artifact only.
| id | blocks | blocker | required artifact |
|---|---|---|---|
| SPB-001 | - Option D AI - server-side M-01 entity persistence with real health text | Consent version and UI must be finalized and approved before any real patient text is sent to a server model. | Approved consent flow spec with exact copy text. |
| SPB-002 | - Option D AI - RawCapture local_only = false | Retention rule must be defined: how long is health text stored server-side, and what triggers deletion? | Approved data retention and deletion policy. |
| SPB-003 | - Option D AI | Model provider and data processing agreement (DPA) must be selected and approved. | Signed or reviewed DPA with model vendor. |
| SPB-004 | - Option D AI | Server-side logging policy must be defined: what is logged, for how long, and under what conditions deleted. | Approved server logging spec covering model request/response fields. |
| SPB-005 | - All options for patient-facing testing - EscalationEvent.copy_version field assignment | Escalation copy version must be finalized and approved before any patient-facing intake test (prototype or MVP). | Approved escalation copy with version token (ESC-V1 or equivalent). Applies to ALL AI options for patient-facing testing. |
| SPB-006 | - server-side M-01 entity persistence | Server-side encryption posture (at rest, in transit, key management) must be approved before any server-side PHI storage. | Approved security posture spec, consistent with Trust Boundary Charter TB-008. |
| SPB-007 | - public beta - any production release | Deletion and export paths must be implemented and tested before public beta. User must be able to delete all server-stored health content. | Approved deletion/export implementation spec. |
LocalVisitDraft
| id | label | description | allowed transitions |
|---|---|---|---|
| draft_new | New | Draft created; no content yet. Created by Fast Visit Start screen. | - draft_capturing - draft_deleted |
| draft_capturing | Capturing | User is entering raw intake via text. RawCapture records attach. | - draft_reviewing - draft_deleted |
| draft_reviewing | Reviewing | StructuredCaptureField records generated or user-entered; user is editing. EscalationEvent may fire here if serious signals detected. | - draft_briefed - draft_capturing - draft_deleted |
| draft_briefed | Briefed | VisitBrief and QuestionPlan stubs exist locally. User may proceed to visit. | - draft_in_visit - draft_reviewing - draft_exported - draft_deleted |
| draft_in_visit | In Visit | User in appointment; QuickVisitNote records attach, question items marked answered/open. | - draft_debriefing - draft_briefed - draft_exported - draft_deleted |
| draft_debriefing | Debriefing | Post-visit quick capture; QuickVisitNote or debrief text entered. | - draft_complete - draft_in_visit - draft_exported - draft_deleted |
| draft_complete | Complete | Full single-visit loop done. Local only until user opts into account/save. | - draft_exported - draft_deleted |
| draft_exported | Exported | ExportArtifact record created; user acknowledged sensitive content. Can return to prior workflow states. | - draft_complete - draft_deleted |
| draft_expired | Expired | Past retention expiry. Soft-deleted; show recovery prompt on reopen during grace period. | - draft_deleted |
| draft_deleted | Deleted | User-deleted or purged after expiry grace period. All local records wiped. |
device-local only (AsyncStorage / SQLite; see local_storage_recommendation)
local_id — UUID generated on-device; no server assignment until account sync
On reopen after expiry, show draft recovery prompt before starting a new visit. After grace period, purge all associated records. User can explicitly extend or delete.
local-pocket-prototype-spec/PVA-SLICE-01 offline_behavior.expiry + patient-data-ai-contract hard_open_questions[0]
30
30
7
30
On app reopen, check for any draft not in draft_deleted state. If found, present recovery screen before offering new visit start.