Skip to content

Loop #1 — Coordination Loop Build Plan (Implementation Map)

Status: Scope only — awaiting Ryan approval before any code
Date: 2026-09-02
Prerequisites: L0 verification closed · L1 entry (Last1 ID login + gate) closed
Authorizes: LOOP1_FIRST_BUILD_SPEC.md §8 (+ §3.1 governance)
Maps: LOOP1_COORDINATION_ARCHITECTURE.md → last1.app codebase
Companion: LOOP1_BUILD_PLAN.md §4 (sequenced phases); this doc is the under-the-hood map Ryan asked for.


0. One sentence (keystone)

Close one real WIN job placement as a three-party Verified Outcome (WIN + veteran via last1.id + hiring manager via Path A magic link), on a hash-chained PHI-free ledger in last1.app, with denominator tracked and a minimal read surface in last1.app + LastVet hub card.

Not tonight: no migrations, no routes, no UI. Review this plan first.


1. What exists today vs net-new

1.1 Three different "loop" systems (do not conflate)

System Repo / DB Purpose Relation to Loop #1
Gate 0 ROI loop last.vet-api · coordination_loops + loop_events (037_coordination_loop_ledger.sql) Mental-health consent → ROI delivered; PHI-free event emitter (loopEvents.ts) Separate product plane. Same English name, different schema/state enum. Do not extend for WIN placement.
Legacy WIN milestone attestation last1.app · milestone_attestation_events + milestoneAttestationService.ts Two-party org + member confirm on program milestones (POST /api/member/milestones/:id/confirm) Legacy mock / demo path. Stays unchanged. Loop #1 is a new SoR.
Loop #1 coordination engine last1.app · coordination_* tables (net-new) Three-party Λ state machine, hash chain, Path A HM close This build.

1.2 last1.app — extend vs net-new

Area Path Today Loop #1 action
Verification gate consumer server/last1VerificationService.ts Reads veteran_verified from last1.id via internal API Extend — reject veteran attestation if not verified
Identity link server/last1IdentityService.ts Maps beneficiary ↔ last1.id subject Reuse — last1id_subject on loop row
Legacy attestation server/services/milestoneAttestationService.ts WIN two-party milestone events Do not touch
Accountability / outcomes server/accountabilityLoopService.ts Org outcome coverage, delivery metrics Parallel — may read denominator later; not SoR for Λ
Member progress UI client/src/pages/member/progress.tsx Milestone rows + confirm button (legacy) Extend — add placement-close panel from new API
Member routes server/routes.ts (~4782 milestone confirm) Legacy endpoints Add new /api/coordination-loops/* block; keep legacy
Schema shared/schema.ts milestoneAttestationEvents Drizzle Add coordination_* tables (migration + Drizzle)
Cross-org coordination migrations/20260217_cross_org_coordination.sql Beneficiary multi-org relationships Unrelated — do not overload
WIN ED demo scripts/seed-win-ed-demo.ts, win-walkthrough-help.mjs Seeds milestone attestation Replace walkthrough with coordination-loop E2E script (L1-7)

1.3 LastVet — read surface only (minimal)

Area Path Today Loop #1 action
L1 entry / verification OperatingSystemShellView.swift, AuthManager Last1 ID status card Done — not loop card
ROI Gate 0 loop ROIViewModel.swift, loopEvents API Opens MH coordination loop on consent Unchanged — different loop type
Loop #1 hub card none — Net-new (L1-6b) — thin client: GET last1.app member/coordination API or LastVet proxy; show Λ state + attest CTA

Pragmatic sequencing: close loop in last1.app first (WIN operates there); LastVet card is minimum beneficiary read + deep link to attest — not full dashboard.

1.4 last1.id — attestation gate (proven at L1 entry)

Capability Status
Sovereign session (Google OAuth, partner redirect) Proven — L1 entry E2E
veteran_verified credential Proven — L0
Veteran recipient attestation gate Reuse — session subject must match verifier_binding on token

No new last1.id product features for Loop #1 close beyond session validation on attest POST (handled in last1.app verifying JWT / internal identity lookup).


2. Module boundaries — coordination_* in last1.app

Decision (locked): New module namespace under server/services/coordination/ — separate system of record from milestoneAttestationService.

last1.app/
├── migrations/
│   └── YYYYMMDD_coordination_loop1.sql          # coordination_* tables
├── shared/schema.ts                             # Drizzle: coordinationLoops, ledger, tokens, stageSignals
├── server/services/coordination/
│   ├── coordinationLoopService.ts               # Λ transitions, loop CRUD, denominator
│   ├── coordinationLedgerService.ts             # Append-only hash chain, payload allowlists
│   ├── attestationTokenService.ts               # Mint/consume/revoke tokens; §3.1 HM gate
│   ├── coordinationAttestationService.ts        # Record attestations → ledger → applyTransition
│   ├── coordinationPayloadAllowlist.ts          # Zod per event_type (PHI-free)
│   └── __tests__/
│       ├── lambdaTransition.test.ts
│       └── hashChain.test.ts
├── server/routes/coordinationLoops.ts           # WIN + public HM routes (mount in routes.ts)
└── scripts/
    └── coordination-loop-e2e-staging.mjs        # ED walkthrough (L1-7)

Private record store (existing tables): beneficiaries, organizations, programs — hold veteran name, employer, role details. Ledger references them by opaque UUID only in allowlisted payload keys (beneficiary_ref, org_ref), never names/PII.


3. Data model — four tables

Naming: coordination_* prefix in last1.app Postgres (Supabase). Distinct from last.vet-api.coordination_loops.

3.1 coordination_loops

Column Type Notes
id uuid PK Opaque loop id (also ledger key)
organization_id uuid FK WIN org
program_id uuid FK WIN program (optional but useful for reporting)
beneficiary_id uuid FK Veteran in WIN pipeline
last1id_subject text Identity binding for recipient gate
outcome_class enum job_placement (Loop #1 only)
lambda_state enum open | partial | verified | contradicted | lapsed
hiring_manager_email text Domain-bound; reject public mail providers
hiring_manager_domain text Derived + WIN-vouched; used for Path A binding
private_refs jsonb Opaque refs to role/employer rows in private store (not in ledger payload)
opened_at timestamptz Λ_open
verified_at timestamptz Set on Λ_verified
terminal_at timestamptz Set on verified | contradicted | lapsed
attestation_bitmap smallint Optional cache: bits for

Denominator: every row with opened_at counts as attempted; terminal state from lambda_state.

3.2 coordination_ledger_events

Column Type Notes
id uuid Event id
loop_id uuid FK
seq bigint Monotonic per loop (unique with loop_id)
event_type enum loop_created | stage_signal | attestation | state_transition
payload jsonb PHI-free — zod allowlist per type
resulting_lambda enum Λ after this event
prev_event_hash text SHA-256 hex; genesis = zero hash
event_hash text SHA256(canonical_json(payload) ‖ prev_event_hash)
created_at timestamptz

Append-only: no UPDATE/DELETE on ledger rows; corrections = new events + optional revoked token status.

Payload examples (allowlisted keys only):

event_type Allowed payload keys
loop_created outcome_class, org_ref, beneficiary_ref
attestation verifier_role, expected_attestation, attestation_value, token_id_ref
state_transition from_lambda, to_lambda, reason
stage_signal stage, attested_by_role, occurred_at

3.3 attestation_tokens

Column Type Notes
id uuid
token_hash text Store hash only; raw token shown once at mint
loop_id uuid FK
verifier_role enum deliverer | recipient | independent
verifier_binding text win_org:{orgId} | last1id:{subject} | hm_email:{domain}
gate enum session | domain_verified_magic_link
expected_attestation enum placement_delivered | placement_confirmed | hire_confirmed
issued_at, expires_at timestamptz Governance-set windows
status enum issued | consumed | expired | revoked
single_use bool always true

3.4 coordination_stage_signals

Column Type Notes
id uuid
loop_id uuid FK
stage enum Loop #1: placement only (seven-stage enum reserved)
signal text e.g. stage_complete
attested_by_role enum deliverer | system
occurred_at timestamptz
ledger_event_id uuid FK Back-link to ledger row

Also emit matching stage_signal ledger event when placement stage recorded (parallel to attestation close).


4. Λ state machine

4.1 Committed vocabulary

Spec symbol DB value Meaning
Λ_open open Loop created; 0–3 attestations
Λ_partial partial 1–2 of {WIN, veteran, HM} recorded, no contradiction
Λ_verified verified All three present, no contradiction
Λ_contradicted contradicted Conflicting attestations → human review queue
Λ_lapsed lapsed Token/window expired before close

Do not invent: Λ_pending_*, Λ_draft, ordered sub-states.

4.2 Transition function (deterministic)

Pure function applyTransition(loop, attestationSet, now) — recompute from recorded attestations, not from order:

INPUT: set of recorded attestations {placement_delivered?, placement_confirmed?, hire_confirmed?}
       + any contradiction flags + expiry checks

IF any contradiction among recorded values     → contradicted
ELSE IF all three attestations present         → verified
ELSE IF any attestation present                → partial
ELSE IF open and any required token expired    → lapsed
ELSE                                           → open

Contradiction examples (first-class, not errors):

  • WIN placement_delivered + veteran placement_denied (if modeled) → contradicted
  • WIN says placed + HM hire_confirmed: false → contradicted

4.3 Token-issuance governance (spec §3.1) — veteran-first for HM contact

Attestation order: not fixed (WIN and veteran may attest in any order).

Token mint order (load-bearing business rule):

issue-hm-token MUST return 403 until placement_confirmed is on the ledger.

  • WIN may still record placement_delivered before or after veteran confirms.
  • Path B HM session (deferred) exempt from this mint rule only if session already exists — not built in Loop #1.

Implementation: attestationTokenService.canIssueHmToken(loopId) checks ledger for recipient attestation event before minting Path A link.


5. Three-party attestation — gates and paths

Verifier Role Gate Expected attestation Loop #1 path
WIN Deliverer last1.app org session (WIN admin) placement_delivered Session
Veteran Recipient last1.id session + L0 verified placement_confirmed Session (LastVet → last1.app API with identity)
Hiring manager Independent Path A: domain magic link hire_confirmed GET/POST /public/hm-attest/:token
HM Path B Independent last1.app hiring-org session hire_confirmed Deferred

5.1 Path A HM flow (DoD path)

  1. WIN creates loop with hiring_manager_email at verified employer domain (not gmail/yahoo/etc.).
  2. WIN vouches employer relationship (stored in private refs; ledger gets domain code only).
  3. After veteran placement_confirmed, WIN calls issue-hm-token.
  4. Email magic link → /public/hm-attest/:token (no account).
  5. Server validates: token unexpired, single-use, email domain matches verifier_binding.
  6. HM submits hire confirmation → ledger attestation → recompute Λ → verified if all three agree.

Trust chain (spec §1.1): WIN vouch + domain inbox control = independent third party, not "anyone with company email."

5.2 Veteran attestation in LastVet (L1-6b)

Options (pick at L1-1 design review — smallest path wins):

Option Flow
A (recommended) LastVet iOS opens last1.app member URL in ASWebAuthenticationSession; last1.app validates last1.id session
B LastVet API proxy to last1.app with veteran JWT + last1.id subject claim

Gate in all cases: last1VerificationService confirms veteran_verified for beneficiary's linked subject.


6. Hash-chained PHI-free ledger

6.1 Write path (single front door)

All ledger writes go through coordinationLedgerService.appendEvent():

  1. Load last event for loop_id → prev_event_hash
  2. Validate payload against allowlist
  3. Compute event_hash
  4. INSERT in transaction with attestation / loop state update
  5. Return chain head for optional future anchor

6.2 Two-layer boundary

Layer Location Contents In ledger?
Private store last1.app beneficiaries, org records, WIN CRM notes Names, DD-214 refs, employer, role title Never
Ledger coordination_ledger_events Opaque ids, enums, timestamps, verifier roles, attestation values Yes

Reference by opaque id only: loop_id, beneficiary_id as UUID in DB but payload uses beneficiary_ref key without name fields.

6.3 Verification tooling (L1-2)

Script scripts/verify-coordination-hash-chain.ts:

  • For each loop, walk seq ascending
  • Recompute hashes; fail on break
  • CI test on fixture loop

Public anchor (RFC 3161, last1.org log): explicitly deferred until first Λ_verified exists.


7. Denominator tracking

From day one (architecture §2.3, spec §6):

Metric Source
Attempted COUNT(*) FROM coordination_loops WHERE opened_at IS NOT NULL
Verified lambda_state = 'verified'
Lapsed lambda_state = 'lapsed'
Contradicted lambda_state = 'contradicted'
Rate verified / attempted (never placements-only)

L1-5 deliverable: GET /api/coordination-loops/denominator?organization_id= for WIN admin (minimal table; no fancy dashboard).

Ledger audit: sum of terminal state_transition events must match loop row counts.


8. Read surfaces — minimum for one close

8.1 last1.app (engine + detail)

Surface Path Loop #1 scope
WIN ops Org admin — create loop, deliverer attest, issue HM token In scope — minimal forms
Member progress /member/progress Extend — "Placement" panel: Λ badge, three checkmarks, link to confirm if pending
Member API GET /api/member/coordination-loop New — loop state + attestation status for logged-in beneficiary
HM public /public/hm-attest/:token In scope — single-page confirm
Full timeline / seven stages /member/timeline Out of scope — placement stage signal only

8.2 LastVet (hub — beneficiary-first)

Surface Loop #1 scope
Full coordination dashboard Out
Loop status card In (minimal) — Λ state, "Confirm placement" if veteran action pending, deep link
Gate 0 ROI card Unchanged — separate loop type

Card reads same API as member progress (proxy or direct last1.app fetch with veteran auth).


9. ED staging test path (real accounts, no bypass)

Step Actor Action Expected Λ
0 ED L0 + L1 entry already proven (verified last1.id) —
1 ED (WIN org admin) Enroll beneficiary linked to veteran's last1.id —
2 ED (WIN) POST /api/coordination-loops — veteran + employer domain email open
3 ED (WIN) POST .../attest/deliverer — placement_delivered partial
4 Veteran (real last1.id) POST .../attest/recipient — placement_confirmed partial
5 ED (WIN) POST .../issue-hm-token — must succeed after step 4 —
6 ED (HM inbox) Open magic link on employer domain test mailbox —
7 HM POST /public/hm-attest/:token — hire_confirmed verified
8 Any verify-coordination-hash-chain.ts PASS —
9 Any Denominator: 1 open, 1 verified —
10 Veteran /member/progress + LastVet card show closed placement read surface

Reject tests:

  • issue-hm-token before step 4 → 403
  • HM token to @gmail.com → 400
  • Expired token → 410 + loop → lapsed (after expiry job)

No LOOP1_ED_TEST_MODE. ED may use second real last1.id account for veteran step.


10. In scope vs deferred (§10.5 discipline)

10.1 IN first loop-close increment

  • [ ] coordination_* migrations + services + hash chain
  • [ ] Λ state machine (five states only)
  • [ ] WIN deliverer + veteran recipient attestations (session gates)
  • [ ] Path A HM magic link + §3.1 veteran-first token rule
  • [ ] Denominator query (attempted / verified / lapsed / contradicted)
  • [ ] Extend /member/progress placement panel
  • [ ] Minimal LastVet loop status card
  • [ ] Staging E2E script + ED sign-off

10.2 DEFERRED (named, not built)

Item Why deferred
RecruitCRM integration Scale after first manual close
Seven-stage timeline UI Enrich backward after keystone
veteran_verification, dd214_mos_validated, training_complete, etc. stage signals Only placement stage in Loop #1
Path B HM last1.app session Fast-follow after first Λ_verified
Hiring-org verified-hiring product Downstream SaaS on same attestation
Public anchor + open-source verifier + last1.org dashboard After first close
last1.org veteran-hiring standard (published) With showcase product
BH/MH care-coordination fork (V_req=2) Second fork
Meridian as matcher Fed by closed loops, not driver
Full LastVet coordination dashboard Hub card minimum only
Merge legacy outcome_events / milestone timeline Optional later
last.vet-api Gate 0 loop changes Unrelated plane

11. Build sequence (L1-1 → L1-7)

Phase Deliverable Repo Depends on
L1-1 Migration + Drizzle schema for four tables last1.app Plan approval
L1-2 coordinationLoopService + coordinationLedgerService + unit tests (Λ + hash chain) last1.app L1-1
L1-3 WIN routes: create loop, deliverer attest; veteran attest + L0 gate last1.app L1-2
L1-4 attestationTokenService + Path A public HM routes + §3.1 enforcement last1.app L1-3
L1-5 Denominator endpoint + WIN admin read (single table) last1.app L1-2
L1-6a GET /api/member/coordination-loop + /member/progress placement panel last1.app L1-3
L1-6b LastVet hub loop card (read + attest deep link) last.vet-ios (+ optional API proxy) L1-6a
L1-7 coordination-loop-e2e-staging.mjs + hash verifier in CI + ED checklist last1.app, lastvet-gates doc update L1-4, L1-6

Estimated effort: 5–7 dev days after approval.

L1 Definition of Done: spec §8 — one placement, three-party verified, hash chain valid, denominator correct, Path A only, real last1.id sessions.


12. API sketch (mount in routes.ts)

WIN (authenticated org)

POST   /api/coordination-loops
POST   /api/coordination-loops/:id/attest/deliverer
POST   /api/coordination-loops/:id/issue-hm-token      # 403 until veteran confirmed
POST   /api/coordination-loops/:id/revoke              # append-only correction
GET    /api/coordination-loops/:id                     # ops read
GET    /api/coordination-loops/denominator             # org scoped
GET    /api/member/coordination-loop
POST   /api/coordination-loops/:id/attest/recipient    # 403 if not veteran_verified

Hiring manager (public Path A)

GET    /public/hm-attest/:token
POST   /public/hm-attest/:token

Not in Loop #1: POST .../attest/independent (Path B).


13. Open items for Ryan (before build)

  1. Which veteran is loop #1 in production? WIN picks one at/near placement after staging proves the path.
  2. Veteran attest surface: last1.app web session vs LastVet-native form (§5.2 option A vs B).
  3. HM test mailbox: staging employer domain + inbox for Path A proof.
  4. WSGR — placement loop vs payment structure (unchanged from spec §9).
  5. Email delivery for HM magic link — confirm SendGrid path in last1.app prod (existing sendEmail).

14. Citation chain

Document Role
LOOP1_COORDINATION_ARCHITECTURE.md Layer model, Λ vocabulary, ledger integrity
LOOP1_FIRST_BUILD_SPEC.md Authorized increment, §3.1 HM token rule, §8 DoD
LOOP1_BUILD_PLAN.md Sequenced L0/L1 sub-plans
L1_ENTRY_CLOSEOUT_2026-09-02.md Login + gate closed
LOOP1_L0_DOD_REPORT.md L0 + L1-entry validation
This plan Implementation map onto last1.app

STOP — Ryan reviews this plan ("see what's under the hood"). No coordination-loop code until explicit approval for L1-1.