Skip to content

Loop #1 External Integrations Model

Mapping External Systems to Signal / Output / Outcome

Design Document v1.0 — September 4, 2026 Last 1 Enterprises · last1.app · last1.org

Companion to LOOP1_PROGRAM_TEMPLATE_MODEL.md and LOOP1_COORDINATION_ARCHITECTURE.md. This document captures the general integration pattern for connecting external program systems to the coordination loop. RecruitCRM is the first instance; the pattern applies to other ATSs, program-tracking systems, and (on a separate track) health-side EHR/VA APIs.

Status: deferred design capture — not built in I1a. Implementation follows template model I1b+ and integration increments gated separately.


0. Purpose and scope

External systems hold data the deliverer already uses day to day. Last1 does not replace those systems. Integrations mirror external events into the loop's typed event model as signals or org-side output attestations, never as outcomes.

What integrations do:

  • Ingest external stage transitions, status changes, and structured facts (read-only from the external system in v1).
  • Map them to template event slugs via versioned integration_* mapping tables.
  • Emit append-only ledger events with provenance (source, external_ref, structural metadata only).

What integrations do not do:

  • Write back to the external system of record (v1 is receive-only).
  • Close an outcome from external data alone (outcomes require coordination_loop + full V_req).
  • Substitute for recipient confirmation on beneficiary-facing outputs (Last1 two-source fork rule).

Health-side integrations (VA FHIR, provider EHR) are out of scope for this Loop #1 employment document. The same pattern applies later with different event classes, Part 2 constraints, and verifier sets — but that is a separate design pass, not this wedge.


1. The three event kinds (integration-facing)

Every external event maps to exactly one template event kind. The template fixes the kind; the integration cannot promote an output to an outcome.

Kind Meaning Closure engine Integration role
signal Activity observed, no beneficiary-facing close signal_only Primary ingest target: pipeline entered, stage advanced, document uploaded in external ATS
output Beneficiary-facing milestone the org claims happened milestone_attestation Org-side leg only: integration may emit deliverer_attested (or equivalent org attestation). Recipient must still confirm in Last1.
outcome Life change outside org sole control coordination_loop Integration may enrich (e.g. placement date from ATS) but never closes. Close = coordination loop + independent verifier.

1.1 Mapping pipeline (general)

External system event
  → adapter (poll / webhook / manual import)
  → normalize to IntegrationEvent { system, entityRef, stageOrEventCode, occurredAt, metadata }
  → lookup integration_event_mappings (program + template + external code → template_event_slug)
  → resolve template event kind from program_coordination_events (or template at ingest time)
  → branch:
       signal  → append coordination ledger signal (or signal-only row; no close)
       output  → append org/deliverer attestation on program_coordination_output_attestation_events
                 (recipient confirmation still required in Last1)
       outcome → reject ingest-as-close; optionally attach as non-closing enrichment metadata
                 on an open coordination_loop

Mappings are versioned per program instance and tied to the instantiated template slug. When WIN's ED supplies real RecruitCRM stage names, those replace MOCK mappings; the template event slugs stay fixed.

1.2 Side-of-house rule (load-bearing)

Integrations attach to one side of the program:

Side Typical external system Maps to
Program / output track WIN's internal training tracker, LMS, certification registry, legacy milestone scaffold Outputs (training complete, cert achieved, tools issued) — org attestation leg; often manual or a future WIN-specific integration
Placement / outcome track RecruitCRM, other ATS, employer HRIS feed Signals en route + outcome enrichment only; independent close stays on coordination loop

RecruitCRM naturally sits on the placement / outcome side. WIN's training milestones do not live in RecruitCRM; they live in WIN's program tracking. Do not force RecruitCRM to stand in for training outputs.


2. §3.13 independence — the RecruitCRM seam

SSRN §3.13 requires verifiers in V_req to be structurally independent: distinct incentives, no shared control. Failure modes include financial dependence, relational dependence, and common control.

For job placement, V_req = {deliverer (WIN), recipient (veteran), independent (hiring employer)}.

2.1 The gotcha

RecruitCRM is WIN's operational tool. A hiring-manager confirmation routed through RecruitCRM (e.g. "HM confirmed placement" stage set by WIN staff, or HM clicks a link hosted inside WIN's RecruitCRM workflow) can collapse the independent verifier into WIN's control surface:

  • WIN controls RecruitCRM pipeline stages and who can advance them.
  • An HM "confirmation" recorded only as a RecruitCRM stage transition is, structurally, deliverer-channel data, not independent attestation.
  • That satisfies neither §3.13 independence nor the coordination loop's independent role.

2.2 Resolution: per-integration independence class

Each integration adapter declares an independence class for every mapping it can emit:

Class Meaning May close outcome? Example
signal_only External fact enriches coherence; not a verifier attestation No RecruitCRM stage "Interview scheduled"
deliverer_channel Org-controlled channel; counts as deliverer-side evidence at most No RecruitCRM stage "Placed" set by WIN coordinator
independent_direct Independent party acts outside deliverer's UI, domain-verified Yes (independent leg only) HM opens domain-verified magic link (gate: domain_verified_magic_link), attests on employer domain
independent_disclosed_partial Third party present but residual entanglement Yes, with disclosure recorded per §3.13 HM sourced through WIN but attests on own corporate email with disclosed relationship

Rule: RecruitCRM ingest defaults to signal_only or deliverer_channel. It must never map directly to independent close.

The already-built independent path preserves §3.13:

  • Coordination loop stores hiring_manager_email + derived hiring_manager_domain.
  • issue-hm-token sends a single-use magic link bound to that domain.
  • HM attests via /api/coordination-loops/independent/attest (no WIN session required).
  • Token gate: domain_verified_magic_link — attester email must match employer domain.

RecruitCRM may mirror placement facts (signal) and pre-fill HM email for loop open, but the independent attestation stays on the direct magic-link path unless a future integration earns independent_direct or independent_disclosed_partial through an explicit per-integration review.

2.3 Decision checklist (every new integration)

Before shipping an adapter mapping:

  1. Which template event slug does this external code map to?
  2. What is the template event_kind (signal / output / outcome)?
  3. If output: does ingest only cover deliverer leg? (Must — recipient confirms in Last1.)
  4. If outcome-related: does ingest attempt to close? (Must fail closed — use coordination loop.)
  5. What independence class does this mapping carry?
  6. If anything touches independent: does the external party act outside deliverer control on the attestation UX?
  7. Residual entanglement documented on the verified outcome record?

3. RecruitCRM — first integration instance

RecruitCRM is the reference implementation of §1–§2 for WIN workforce placement.

3.1 Division of responsibility

System Role
RecruitCRM WIN's ATS / pipeline system of record for recruiting
last1.app Outcomes + participant confirmation + verified close ledger
Program template Fixes which events are signals, outputs, outcomes
Coordination loop Closes job_placement outcome (V_req = 3)

Existing scaffold (not yet live-ingest on prod): last1.app/docs/integrations/recruit-crm-win.md, integration_stage_mappings, mock adapter, stageTransitionHandler → legacy milestone_attestation_events.

Migration path: new ingest should target program_coordination_* tables and template event slugs, not legacy MOCK milestones — once I1b wires template events to UI/ledger.

3.2 RecruitCRM stage → template event (illustrative)

Real stage names come from WIN ED. Illustrative mapping intent:

RecruitCRM stage (example) Template slug Kind Independence class
New applicant / pipeline entered pipeline-entered signal signal_only
Enrolled with WIN enrollment-confirmed output deliverer_channel (org leg only; veteran confirms in Last1)
Training complete (if ever in CRM) — do not map Training outputs belong to WIN program tracker, not CRM
Offer / hired (CRM fact) — signal → loop enrichment deliverer_channel — not independent close
— job-placement-verified outcome independent_direct via magic link only

3.3 Ingest modes (deferred)

Mode Status Notes
Mock adapter Dev/staging POST /api/integrations/recruit-crm/mock/advance
Webhook Blocked on plan tier Business/Enterprise API
Poll Blocked 60 req/min; needs live mappings

All modes: read-only from RecruitCRM, append-only into Last1, no PHI in metadata (structural ids/stages only — same hygiene as trust ledger).


4. General pattern for future integrations

4.1 ATS / CRM (Greenhouse, Lever, etc.)

Same as RecruitCRM: placement-side signals + outcome enrichment; independent close on magic link or future disclosed-partial review. One integration_connections row per org per vendor; mappings per program instance.

4.2 Program / LMS / certification bodies (output track)

Maps to output template events. Typical pattern:

  • External system certifies completion → ingest emits deliverer attestation only.
  • Veteran confirms receipt in Last1 (recipient_confirmed).
  • Optional: cert body as additional signal (not substitute for recipient on beneficiary-facing outputs).

Independence: cert body may be independent_disclosed_partial for credential existence signals, not for "veteran benefited" outcomes unless template explicitly defines a separate outcome class (future, gated).

4.3 Health / EHR / VA (horizon — separate pass)

Deferred for Loop #1 employment wedge. Pattern sketch only:

  • VA FHIR / provider EHR → signals on care-coordination templates (Gate 1+ LastVet), not employment outcomes.
  • Part 2 + two-data-plane: transient VA plane, no server-side PHI in integration metadata.
  • Verifier sets differ (V_req = 2 for some coordination outcomes per Appendix A.3).
  • Do not reuse RecruitCRM adapters or employment mappings.

4.4 Adapter interface (implementation-neutral)

Each adapter implements:

type IntegrationIndependenceClass =
  | "signal_only"
  | "deliverer_channel"
  | "independent_direct"
  | "independent_disclosed_partial";

type NormalizedIntegrationEvent = {
  connectionId: string;
  externalEntityRef: string;
  externalEventCode: string;
  occurredAt: string;
  metadata: Record<string, string | number | boolean | null>; // structural only
};

type IntegrationAdapter = {
  vendor: string;
  pull(): Promise<NormalizedIntegrationEvent[]>;
  handleWebhook(payload: unknown): Promise<NormalizedIntegrationEvent | null>;
};

Central integrationIngestService resolves mappings, checks independence class, and dispatches to signal append or output org-attestation — hard-rejects outcome close attempts with OUTCOME_REQUIRES_COORDINATION_LOOP.


5. Relationship to program template model

Layer Document
What events exist and their kind LOOP1_PROGRAM_TEMPLATE_MODEL.md
How loops close outcomes LOOP1_COORDINATION_ARCHITECTURE.md
How external systems feed events This document

Template slugs are stable. Integration mappings are per org, per program instance, versioned when ED changes stage names. Template immutability (I1a) prevents an org from retyping an output as an outcome at ingest time.


6. Disability rating increase verifier (VetClaims wedge)

Disability rating increase is a second three-party outcome class (disability_rating_increase) with a different independent verifier than job placement.

6.1 Method A — document_review (interim, built now)

  • Independent party: not an employer. Verification is a Benefit Summary Letter uploaded by the veteran after recipient confirmation.
  • Gate: document_review on the independent attestation (ledger payload includes review_id_ref; attestation slot remains hire_confirmed for engine compatibility).
  • Flow: veteran uploads PDF/image → org admin reviews in Org Settings → approve records independent attestation → Λ may reach verified.
  • Loop private refs: independent_verifier_method: document_review, document_type: benefit_summary_letter.
  • Placeholder HM binding: document-review@loop.last1.internal / loop.last1.internal (structural slot only; no magic link).

This is intentionally interim: human review of a veteran-directed document, not VA system-of-record access.

6.2 Method B — VA API (deferred)

When production VA Lighthouse access is granted (Benefit Summary / rating facts via consented API), the independent leg may shift to API-backed verification with the same outcome class and V_req=3. Method A remains valid for orgs without API credentials or as fallback. Design pass required before build; not Phase 1 LastVet scope in this employment-focused doc, but the coordination loop pattern is identical.


7. Build increments (integration track — all deferred)

  1. I1b — Template events wired to UI + ledger (prerequisite for any integration to matter to veterans).
  2. Integration core — integration_connections, integration_event_mappings, integrationIngestService, independence class column.
  3. RecruitCRM live — ED stage taxonomy → mappings; poll or webhook; signal + deliverer_channel only.
  4. RecruitCRM → loop enrichment — Pre-fill HM email on loop open from CRM fact (still magic-link close).
  5. Second vendor — Prove pattern generalizes (another ATS or WIN LMS for output track).

RadioCheck, public anchor, and template marketplace remain separate tracks per LOOP1_PROGRAM_TEMPLATE_MODEL.md §4–§6.


8. Summary

  • External systems map into signal / output / outcome — they do not define those kinds; the template does.
  • RecruitCRM sits on the placement side; WIN training outputs stay on WIN's program side.
  • §3.13 forbids treating RecruitCRM HM confirmation as independent verification; the domain-verified magic link is the independent path already built.
  • Disability rating increase uses Method A document_review (Benefit Summary Letter + human review) until VA API verification (Method B) is papered and built.
  • Every integration mapping carries an independence class; outcome close stays on the coordination loop.
  • RecruitCRM is instance #1; the adapter shape generalizes to other ATSs and program systems; health integrations are a separate, later pass.

Document maintained by: Ryan Curry, Founder, Last 1 Enterprises Companion to: LOOP1_PROGRAM_TEMPLATE_MODEL.md, LOOP1_COORDINATION_ARCHITECTURE.md, last1.app/docs/integrations/recruit-crm-win.md, SSRN §3.13