Skip to content

Session state — 2026-07-16

Purpose: Committed handoff so work can resume cold (Monday, new agent, or Ryan with no chat memory).
Scope: What changed on 2026-07-15/16, current environment truth, gates, parallel tracks, planned work, open items, accepted limitations.

Do not infer from this doc: Start RLS batch 2 implementation, reopen Gate 0.5 A1, or rewrite closed gate docs (D11, D12).


1. What changed today (by repo and commit)

last.vet-api (main)

Commit What it actually did
5b1eaaf Inbox OTP harness: Fixed Gmail IMAP parsing (untagged SEARCH/FETCH + literals); pre-open UID baseline to ignore stale OTPs; default E2E recipient e2e-harness@last1.enterprises.
005bc4e OTP logging teardown: Removed SECURE_LINK_E2E_LOG_OTP from Terraform, SM lastvet-prod/app, API code, and CloudWatch harness fallback. Parallel-track E2E run log. Prod task def :7.
da11726 Migration pre-flight: migrate.js --list-pending, --expect; prod run-ecs-db-setup.sh lists pending then requires explicit expect set. Security posture doc committed.
1b046a8 Prod boot DDL gate: ensureCoreSchema skipped when APP_ENV=production. RLS batch 2 plan doc (RLS_BATCH2_PLAN.md).

Earlier context (same sprint, pre–Jul-16 session tail):

Commit What it actually did
790e188 P0.7 Phase B API: fhir_sync_manifest migration 050, sync gate, provider manifest alerts backend.
228ddef VA production cutover runbook; Railway prod teardown recorded.
0960c65 / dd69928 Gate 0 A1 re-earned on AWS prod (scripted + human TestFlight).

last.vet-provider (main)

Commit What it actually did
b6ebe1b Phase B: FHIR sync manifest warning UI on provider Record view.

last.vet-ios (local — not shipped)

Hardened client code exists locally (P0.1–7, Phase B: FHIRSyncPlanner, sync gate, ROI informed consent). Not on TestFlight as of this doc. Parallel-track human leg blocked on Ryan shipping a build.


2. Current environment truth

Fact State
Production API AWS ECS lastvet-prod-cluster / lastvet-prod-api, RDS lastvet-prod-postgres, api.last.vet
Staging API AWS ECS lastvet-staging-*, api-staging.last.vet
Railway prod Gone (2026-07-15). pg_dump: backups/railway-lastvet-prod-2026-07-15.dump (gitignored, local only).
Railway staging May still exist as rollback net per DEV_STAGING.md — clients must use api-staging.last.vet, not .railway.app.
Prod auto-migrate No. aws-start.sh skips when APP_ENV=production. Migrations only via run-ecs-db-setup.sh prod 'file1,file2'.
Prod boot DDL No. ensureCoreSchema skipped when APP_ENV=production (verified in CloudWatch: production_skipping_boot_schema, no schema_ready).
Prod OTP logging No. Inbox-only harness (e2e-harness@last1.enterprises + Bitwarden E2E_OTP_IMAP_*).
Real veteran PHI None in any environment. All data synthetic / VA sandbox.
VA production Lighthouse access Not approved. Case #00015000 in review.

3. Gate 0.5 and Gate 0

Item Status
Gate 0.5 engineering exit ✅ Complete (A–C + B7). See docs/runbooks/gate-0.5/GATE_0.5_STATUS.md.
Gate 0 earned On D11 + D12 alone (Ryan-owned). D11 closed 2026-07-16; D12 filled 2026-07-16.
D11 CLOSEDlastvet-gates/gates/GATE_1_TRACTION_THRESHOLD.md; pointer at docs/planning/GATE_1_THRESHOLD.md.
D12 docs/compliance/VA_PRODUCTION_ACCESS_TRACKER.mdRyan's. Do not edit.
A1 Closed. E2E_RUN_LOG_2026-07-15.md. Parallel track does not reopen A1.

4. VA production readiness — parallel track

Not Gate 0.5 exit criteria. Required before Gate 1 production pilot, not before Gate 0 declaration.

Item Status
P0.1–7 + Phase B API ✅ Shipped prod (790e188 + prior P0 commits)
P0.1–7 + Phase B provider ✅ Shipped (b6ebe1b)
P0.1–7 + Phase B iOS ✅ TestFlight human E2E 2026-07-21
Inbox OTP harness ✅ Prod proven 2026-07-16
OTP logging teardown ✅ 2026-07-16
Migration pre-flight ✅ Built 2026-07-16
Prod boot DDL gate ✅ 2026-07-16
Scripted E2E on hardened API E2E_RUN_LOG_2026-07-16_VA_PARALLEL_TRACK.md
Human E2E on hardened iOS E2E_RUN_LOG_2026-07-21_VA_PARALLEL_TRACK_HUMAN.md

Exit criterion: Fresh scripted + human E2E on hardened code on AWS. Both legs complete (2026-07-21). Parallel track exited.


5. Planned — not built (decide before starting)

5.1 Staging should rehearse prod (schema path)

Problem: Prod no longer runs ensureCoreSchema or boot migrations. Staging still does both (APP_ENV=staging → boot DDL runs; RUN_MIGRATIONS_ON_BOOT=true → boot migrate without --expect). Staging schema_migrations can lie the same way prod's did until 2026-07-16. Batch 2's safety story is "staging proof before prod" — if staging gets schema differently, that claim is weaker.

Proposed end state:

Environment ensureCoreSchema Migrations
Local / dev ✅ On boot (fast iteration, empty DB recovery) Optional local migrate.js
Staging ❌ Off (same gate as prod) Same as prod: run-ecs-db-setup.sh staging lists pending; apply via explicit one-off; use --expect when rehearsing prod discipline
Production ❌ Off (shipped) run-ecs-db-setup.sh prod '049_….sql,050_….sql' only

Implementation sketch (when approved):

  1. Change src/index.ts gate: skip ensureCoreSchema when APP_ENV is production or staging.
  2. Remove or set RUN_MIGRATIONS_ON_BOOT=false in Secrets Manager lastvet-staging/app.
  3. Update docs/deployment/DEV_STAGING.md — staging deploy checklist becomes: push image → list pending → apply with expect (or staging-apply-all-pending if you deliberately relax expect on staging only).
  4. One-time: reconcile staging schema_migrations vs actual schema (list pending; apply any gap).

What breaks if we gate staging:

Dependency Impact
RUN_MIGRATIONS_ON_BOOT=true (documented in DEV_STAGING.md) Stops working. New migrations no longer apply on ECS rollout alone. Ops must run run-ecs-db-setup.sh staging after deploy when image contains new migration files.
Boot DDL healing ledger drift Stops. If pending migration not applied, app may fail on missing column — same as prod now. That's the point: failures surface in staging first.
Deploy-only workflow (push image, force rollout, done) Broken for schema changes. Becomes: push image → migrate one-off → rollout (mirror prod order).
Fresh empty staging RDS Requires post-apply-db.sh staging + full migration chain; no boot self-heal.
Local dev Unchanged if APP_ENV/NODE_ENV is development.

What does NOT break:

Item Why
Runtime API on existing staging DB Schema already present; gate only affects boot path for new/changed DDL.
ConsentEngine.ensureMinimalSchema() Separate legacy path: runs on lastvet_app pool only after 42P01 (missing table). Not owner boot DDL. Rare on staging with populated DB; dev/test concern.
RLS / lastvet_app Unaffected.

Objection to keeping boot DDL on staging:

There is no rehearsal value — it masks the same ledger drift that burned us on prod (049 behind 050). Migrations are a verified superset at column/index level; pre-flight --list-pending exposes drift. Keeping boot DDL on staging optimizes convenience over fidelity.

Decision deadline: Before RLS batch 2 step 1b (consent RLS migration). Step 1a (context refactor) can proceed on staging as-is, but 1b staging proof is not credible until staging matches prod schema authority.

Status:Plan only — not implemented.


5.2 RLS batch 2

Doc: docs/api/RLS_BATCH2_PLAN.md
Not Gate 0.5. Required before real veteran data, not before Gate 0.

Phase Scope
1a — Refactor Wire applyRequestDbContext through consent paths (consent/engine.ts + part2.ts, roi-sign.service.ts, provider routes, etc.). No RLS, no migration. Staging proof.
1b — Migration RLS + FORCE on part2_consents, consent_grants. Only after 1a + staging rehearsal decision.
2 — Credentials/tokens secure_access_*, oauth_*
3 — Remaining data consent_audit_log, connection_requests, preferences, etc.

Staging proof requirements: Cross-veteran consent negative test; multi-veteran health-record bypass regression. See plan doc.

Unblocks: 1a → engineering; 1b → 1a proven + staging schema rehearsal aligned with prod.


5.3 Pentest retest

After RLS batch 2 on staging; before first real veteran on prod. Shannon + ~1 day eng for staging deploy/fixtures. Not scheduled.


6. Parked

Item Why
P0.7 Phase C Point-in-time manifest on consent grants / secure-link sidecar. Hogan Lovells, not engineering.

7. Open on Ryan

Item Notes
D11 CLOSED (2026-07-16) — was Gate 1 threshold doc; canonical: lastvet-gates/gates/GATE_1_TRACTION_THRESHOLD.md.
D12 CLOSED (2026-07-16) — docs/compliance/VA_PRODUCTION_ACCESS_TRACKER.md filled.
TestFlight / parallel human E2E CLOSED 2026-07-21 — E2E_RUN_LOG_2026-07-21_VA_PARALLEL_TRACK_HUMAN.md.
Bitwarden E2E_OTP_IMAP_* + Google app password for e2e-harness@last1.enterprises — done.

8. Known limitations — accepted and tracked

Limitation Reasoning
app.bypass_rls on health records Provider multi-veteran reads need one query across consented veterans. Policy bypass is deliberate, code-controlled, documented in SECURITY_POSTURE_DATABASE_ACCESS.md. Staging must prove it still works after batch 2.
Consent engine without request context Not wired through applyRequestDbContext yet. App-layer SQL filters today; batch 2 step 1a fixes before RLS. Without 1a, RLS would fail closed and break consent flows.
Dual schema authority on staging (today) Prod fixed (boot DDL off). Staging still runs boot DDL + boot migrate — weak rehearsal. Tracked in §5.1; decide before 1b.
schema_migrations ledger can lag reality Was true when boot DDL created objects before migrate ran (049/privacy_notice_campaigns). Prod mitigated: boot DDL off + pre-flight. Staging mitigated when §5.1 ships.
13 veteran_id tables without RLS Batch 2 scoped; consent + credentials first. Documented in security posture doc.
ConsentEngine.ensureMinimalSchema Legacy dev recovery on app pool; not prod boot path. Separate from owner DDL issue.

9. Key doc index

Doc Use
docs/security/SECURITY_POSTURE_DATABASE_ACCESS.md RLS truth, Jul-12 sentence correction, shareable §8
docs/api/RLS_BATCH2_PLAN.md Batch 2 phases, 1a/1b split, staging proof
docs/runbooks/VA_PRODUCTION_CUTOVER_RUNBOOK.md Cutover, migration pre-flight, Appendix B inbox OTP
docs/runbooks/gate-0.5/GATE_0.5_STATUS.md Gate 0.5 checklist + parallel track
docs/runbooks/gate-0.5/E2E_RUN_LOG_2026-07-16_VA_PARALLEL_TRACK.md Parallel scripted pass (not A1)
docs/runbooks/gate-0.5/E2E_RUN_LOG_2026-07-21_VA_PARALLEL_TRACK_HUMAN.md Parallel human TestFlight pass; track exit
docs/runbooks/gate-0.5/E2E_RUN_LOG_2026-07-15.md A1 closed
docs/security/SECURITY_PENTEST_STATUS.md B7 note + posture link
docs/deployment/DEV_STAGING.md Staging ops (will need update when §5.1 ships)

10. Prod ops quick reference

# Deploy API (after code push)
./infra/scripts/deploy-api-image.sh prod
aws ecs update-service --cluster lastvet-prod-cluster --service lastvet-prod-api \
  --task-definition lastvet-prod-api:N --force-new-deployment

# Migrate (prod — list only first via script, then expect set)
./infra/scripts/run-ecs-db-setup.sh prod '050_fhir_sync_manifest.sql'

# Scripted E2E (Bitwarden E2E_OTP_IMAP_* + VETERAN_SESSION_EXCHANGE_SECRET)
API_BASE=https://api.last.vet/api ./scripts/e2e-roi-gate0-full.sh

Last updated: 2026-07-16 end of session. Do not start RLS batch 2 from this doc without explicit approval.