title: "USI Module — Contract" doc_id: usi-module-01-contract status: RATIFIED 2026-07-08 (Tim) — records the 2026-07-07 ruling (USI as a swappable module — format-validation now, registry-verification later, behind a stable contract) as a design contract, plus the 2026-07-08 ratification of the three-grade assurance ladder (§3) over a two-grade collapse. Bind-at-build items (§8) are deferred, not blocking. Not a spec re-open: llnd-02 §2.3/§11.5 and rpl-02 already scope USI exactly this way; this doc is the shared vehicle both cite. Files via a single docs-only brief (the RPL-02/LLND-02 filing pattern). Filed ≠ build authority. layer: design contract (connector-class infrastructure — not a launcher tile; sits with SMS Connect / LMS Connector in kind) pairs_with: usi-registry-ext-api (the EXT-API reference this contract's impl (b) binds behind) consumed_by: intake-pipeline-01-model §4 (candidate USI capture — RPL + LLND intakes) · llnd-02-spec §2.3 (optional USI capture) · rpl-02-spec (USI at intake; Verify day-two) · T4 onboarding (USI capture within the onboarding transaction's capture step) authority_instruments: - Student Identifiers Act 2014 — the meaning of student_identifier (USI) authored: 2026-07-08 NYC — RTOpacks-side Claude ratified: 2026-07-08 (Tim) — the three-grade assurance ladder (§3) confirmed over a two-grade collapse
USI Module — Contract¶
1. The ruling this records¶
Tim, 2026-07-07: build USI as a swappable module — implementation (a) format-validation now, replaced by (b) registry-verification later, behind a stable contract; consumed by LLND and RPL intake and T4 onboarding. USI is infrastructure, not a launcher tile — connector class.
The canon this expresses: interface-as-revelation / looked-through-not-at. Callers see one contract forever; what stands behind it upgrades without any caller changing.
2. The contract¶
One operation, async and server-mediated from day one:
- Async always. Impl (a) is a local calculation that could return synchronously — the contract still awaits. The a→b swap replaces a library call with a credentialed registry round-trip; an async contract makes that swap invisible to every caller.
- Server-mediated always. Impl (b) is a credentialed registry call that MUST be server-side (credentials never client-side — credential policy). Routing (a) through the same server boundary from day one means the swap is a service-implementation change, not a call-path change. Client surfaces MAY hint format problems for UX (length, character set) but a client-side hint is never a recorded result — only the module's server-side answer is.
- The USI value itself rides the existing handling canon (rpl-01 §4 / intake-pipeline §4 / usi-registry-ext-api §2): Act-defined meaning, never free text, never in a URL, filename, or outbound message body. The contract's transport must honour this — the USI travels in request bodies over the same-origin BFF path, never in query strings.
3. The result — assurance grade is the load-bearing field¶
{
outcome: "pass" | "fail" | "unavailable",
assurance_grade: "format_structural" | "format_checked" | "registry_verified",
checked_at: timestamp,
detail: { ... grade-specific; never echoes the full USI back }
}
Consumers record the grade they got. This is the LLND conducted/external honesty pattern applied
to identity: a result recorded at format_structural today is never silently read as
registry-confirmed later. Any surface that displays or exports a USI status displays the grade it
holds. Upgrading a stored grade requires a fresh usi.check under the higher-grade implementation —
grades move by re-check, never by reinterpretation.
Three grades, not two (ratified 2026-07-08, Tim) — because impl (a) itself has two honest levels:
| Grade | What it asserts | Available |
|---|---|---|
format_structural |
10 characters, permitted alphanumeric set (per the published exclusions) | Now — public-source rules (usi-registry-ext-api §"launch boundary") |
format_checked |
Structural + the published check-character validation passes | When the TSC pins the algorithm — the authoritative format rules live in the Technical Services Contract (kit chain), and we implement from the authoritative source, not from circulating reproductions (the LAW-CORPUS-SOURCE-VERIFICATION posture applied to a technical spec) |
registry_verified |
The registry's Verify USI operation confirms the USI matches the student's identity details | Impl (b) — day-two, gated per §5 |
unavailable exists for impl (b) honesty: a registry outage returns unavailable at the attempted
grade — it never silently degrades to a format answer presented as verification.
4. Implementation (a) — launch¶
A server-side validation library behind the contract. format_structural at first commissioning;
format_checked lands as a drop-in the day the TSC's algorithm is pinned (a grade-field change and a
calculation, no contract change, no caller change). No external call, no credential, no EXT-API gate —
nothing leaves the account boundary.
5. Implementation (b) — the swap¶
The registry Verify USI operation, server-side only. Enabling triggers, all standing:
- EXT-API RULE — usi-registry-ext-api must pass its v2 (every [KIT-PENDING] resolved) before any registry integration deploys.
- The kit chain — myID (Standard strength, name-match on ABN 59 168 872 535) → RAM → DPO Kit → USI Developer Kit. AU/myID-gated, Tim-side.
- Credential policy — machine credentials (M2M / device keys per the kit) held server-side only, sourced per the fleet credential pipeline; never client-side, never in code.
- The USI relationship is RTOpacks-side (Pty Ltd) — the registry sees the Australian entity.
The swap itself: the module's implementation changes from library to credentialed service call; the
contract, the call sites, and the result shape do not change. Results begin carrying
registry_verified; previously stored lower-grade results keep their recorded grade until re-checked.
6. Consumers and their postures¶
| Consumer | When it calls | Grade sufficiency at launch |
|---|---|---|
| Intake pipeline (RPL + LLND candidate capture) | USI optionally captured at intake (llnd-02 §2.3; USI optional at the LLND stage) | Format grade suffices — enrolment-time USI obligations are the SMS's business, not the review's |
| T4 onboarding | USI capture within the onboarding transaction's capture step, reviewed/approved like any other section | Format grade suffices at launch; the recorded grade travels with the onboarding record |
| Day-two surfaces (Verify-backed flows, create-on-behalf per the ext-api ruling) | Post-swap | Require registry_verified; must check the grade, not just the outcome |
The guided self-create no-USI path (usi-registry-ext-api §"Create USI" ruling) is unchanged by this contract — a candidate without a USI is never stranded and never blocked on this module.
7. Non-goals¶
- Not a launcher tile. No user-facing surface of its own; it reveals itself inside the surfaces that consume it.
- Not an identity store. The module validates and verifies; custody of the USI value stays with the consuming record (candidate store / onboarding record) under the existing handling canon.
- Not a gate at launch. No launch flow hard-blocks on a USI check outcome — the honest-grade record is the deliverable, not a barrier.
8. Bind-at-build¶
- Where the module physically lives (in-worker library vs internal service worker) — either satisfies "server-mediated"; bind against the live worker topology at build, named per cloudflare-naming-canon and verified against cloudflare-resource-inventory.
- The
detailshape per grade — bind when the first consumer builds. - The TSC check-character algorithm — pin at kit receipt (the
format_checkedenabler); cite the TSC version in the module's config, mirroring the framework-version-pinning pattern (llnd-02 §4.4).
The USI module contract. One async server-mediated operation, three honest assurance grades, one swap path from local format validation to registry verification that no caller ever sees. Records the 2026-07-07 ruling; consumed by both regulated tiles' intakes and T4 onboarding; changes nothing in the ratified specs it serves.