---
title: "SEVIS Readiness Criteria"
slug: sevis-readiness
section: Rules & Compliance
status: stable
description: "Completeness requirements and compliance gate for SEVIS pool entry and DS-2019 submission"
last-updated: 2026-10-07
---

# SEVIS Readiness Criteria

Completeness requirements and compliance gate for SEVIS pool entry and DS-2019 submission

## Overview

Before an applicant can enter the SEVIS pool and have a DS-2019 issued, Globus enforces a layered readiness gate. A certificate-health precondition confirms the SEVIS infrastructure is reachable, and a two-layer gate then evaluates every applicant: a global `ready_for_sevis` gate that applies regardless of program, and program-level add-on gates that stack on top of it. All gate outcomes are computed by the sevisComplianceService.ts and enforced by the Rules Engine via ruleEnforcement.ts.

## Two-Layer Gate Architecture

The SEVIS readiness gate architecture governs SEVIS pool entry for every applicant (Aug 11 2026 release capsule). It combines a certificate-health precondition with two stacked gate layers: a global gate every applicant must satisfy, and program-specific add-on gates.

### Certificate Health

The SEVIS certificate health check verifies that the sponsor's SEVIS credentials are valid and that the target SEVIS environment (production or test) is reachable. If the certificate is expired, revoked, or the environment is unreachable, the gate is closed for all applicants regardless of their individual compliance status. This check is performed by the sevisComplianceService.ts before any individual applicant evaluation.

Exactly one certificate is active per SEVIS environment. Uploading or activating a certificate atomically deactivates the previous active certificate for that environment (serialized by a per-environment lock), and credential, health, preflight, and submission checks ignore inactive certificate history.

### Global ready_for_sevis Gate

The global `ready_for_sevis` gate enforces thirteen dependency rules that every applicant must satisfy to enter the SEVIS pool, regardless of program. It is **fail-closed** — the gate stays closed until every rule passes. Applicants who fail route to the sevis-readiness-blocked workbench queue.

| Rule | Requirement |
| --- | --- |
| Minimum age | Applicant meets the minimum age at program start |
| Minimum age at employment start | Camp-family programs only (the fact comes from the Camp Contract step, so it is absent elsewhere and the rule stays dormant). Applicant is 18+ on the Camp Contract employment start date (rule `eligibility.minimum_age_employment_start.j1_camp_programs`, `ageAtEmploymentStart >= 18`). A mandatory, PASS_OR_APPROVED_REVIEW dependency of `ready_for_sevis` only: it has no bundle binding and does not block Market Ready or Placement Ready. A shortfall routes to Compliance Review Required (`MINIMUM_AGE_NOT_MET`, hold for review) and can't be waived by override. If the contract start date is absent or cannot be read, the gate reports a missing-prerequisite blocker (Employment Contract Start Date) instead of an age failure. |
| Intake complete | The application / Intake phase of the applicant's pinned published workflow is complete (the `workflowIntakeComplete` fact, resolved only by the authoritative step-completion service). If the workflow's Intake step count cannot be established the fact is absent and the rule fails closed. The legacy structural `application` track blocker (`track:application`) is no longer emitted alongside it, so only this rule blocker is shown. |
| T&C acceptance | Terms & Conditions accepted |
| Passport uploaded | A passport document has been uploaded |
| Passport not expired | Passport is valid and not expired |
| Passport OCR clear | Passport OCR completed without error |
| Passport identity confirmed | Passport identity data confirmed |
| Criminal background check clear | A criminal-background upload is present and the criminal-background assessment is clear (or an approved manual review) |
| Camp Counselor placement duration | The applicant's current Camp Counselor placement fits within four calendar months (rule `j1.camp_counselor.max_program_months`); non-Camp applications pass as not applicable. See the Camp Program Rules page. |
| Passport citizenship resolved | Passport citizenship resolved (pass or approved review) |
| Duplicate passport detection | No unresolved duplicate-passport match (pass or approved review) |

Failure of any single rule holds the applicant out of the SEVIS pool and routes them to the sevis-readiness-blocked workbench queue.

A genuine minimum-age failure is also routed to the Eligibility Blocked queue with reason `MINIMUM_AGE_NOT_MET` (the minimum-age rule's fail action carries the `eligibility_documents` readiness dimension, which is the marker that routes a blocking action to a queue). An applicant with no date of birth is not an age failure: that result stays "Awaiting evidence" and opens no breach. Migration `20271115000001_backfill_minimum_age_open_breaches` opens the Blocked-queue breach rows for applications already evaluated as genuinely under age (latest record for the rule is a raw `fail`); applicants awaiting a date of birth are deliberately excluded. ADR 0004 records the contract behind this routing: the readiness dimension on a fail action is the routing marker, so `BLOCK` and other fail verbs route too, without changing their severity or gating, and a "fail" that is only a fail-closed rewrite of missing data never opens a breach.

### Program-Level Add-On Gates

Program-level add-on gates stack on top of the global `ready_for_sevis` gate to enforce program-specific requirements. An applicant must clear both the global gate and any applicable program add-on gate.

- **Teach USA** — gate is live and unblocked.
- **Intern / Trainee** — gates are scaffolded and will activate when their SEVIS configuration is published.
- **Summer Work Travel — Camp (Wild Packs)** — the `ready_for_sevis.swt_camp_wildpacks` add-on (scoped to the `summer_work_travel_wildpacks` program, seed `sevis-add-on-gates-v5`) additionally requires six SWT rules to pass: current student status verified, academic calendar verified, vacation window verified, Camp Contract start within the eligible window, Camp Contract end within the eligible window, and work period within four months. At the SEVIS chokepoint each of the six is resolved from fresh, application-scoped facts rather than a stored failure, and passes only on an explicit true verification fact, so a completed evidence review or a changed vacation or Camp Contract date cannot leave readiness reading a stale failure. Missing or incomplete Camp Contract dates, or unavailable DOS/vacation evidence, are held as awaiting evidence; a fully derived empty overlap between the declared vacation and the DOS travel window, a contract start before the permitted window, or a contract end after it is a blocking failure. The Applicant Profile compliance details show the evidence for these rules: the permitted SWT window, the Camp Contract window, and separate start and end outcomes.

### Camp Counselor (Wildpacks) Add-On Gate

> **Superseded — Eligibility Engine now live**
>
> The legacy Cat 1/2/3 auto-derivation and staff-set eligibility path have been **fully retired**. The Camp eligibility gate now depends on the Eligibility Engine's sponsor determination (live on development, designed under ADR 0003). See the Eligibility Engine & Compliance Tab page for the full model.

Camp Counselor applicants (Wildpacks) stack the eligibility gate on top of the global gate:

| Rule | Condition |
| --- | --- |
| CAMP-001 Eligibility approved | The applicant has an **approved and currently valid** sponsor determination from the Eligibility Engine — engine-assembled path evaluation, human approval. Fails closed if the fact is missing or unreadable. |

The former standalone evidence checks are subsumed by the engine's qualifying paths, each requiring uploaded and staff-verified evidence.

### Camp Eligibility Decision Model

The engine evaluates a universal minimum-age requirement (18+, fail-closed) plus four qualifying paths — post-secondary student, youth worker, teacher, special skills (always manual review) — from applicant facts and staff-verified evidence. Evaluation is automatic and event-driven; a compliance officer issues the approve/reject/revoke determination, and validity is continuously protected: if underlying facts or evidence later change, the determination automatically moves to **Reassessment required** rather than silently relying on a stale approval.

> **Staff determination control**
>
> Approve / reject / revoke actions live on the applicant profile's Compliance tab and require the `eligibility.approve` permission (session login only). Staff no longer set an eligibility path directly; preserved legacy approvals from the old model are never re-opened automatically.

## Ready Pool and Batch Admission

One canonical readiness verdict drives the Ready Pool, batch admission, and the final submission check. An applicant is selectable only when the live verdict is ready; general readiness labels and the legacy pool flag are advisory and never grant eligibility.

- SEVIS batches are scoped to one program and one operational cycle. The batch cycle picker lists only cycles in `open`, `active`, or `closing` status for the selected program.
- When creating a batch from the Ready Pool, the draft is created first and the selected applicants are then added through the canonical eligibility check (`POST /api/sevis/batches/:batchId/add-items`). Each rejected applicant is reported with a reason — not found, already in batch, already issued, program mismatch, cycle mismatch, or not ready (with the structured blockers). A zero-item draft is never presented as a successful admission.
- Production submission to SEVIS stays fail-closed unless the `SEVIS_ALLOW_PRODUCTION_SUBMIT` flag is explicitly enabled. A refused submission returns `403` with top-level `error.code` `SEVIS_SUBMISSION_BLOCKED` and the discriminator in `error.details.code`: `SEVIS_PRODUCTION_SUBMIT_DISABLED` (production without the flag), `SEVIS_ENVIRONMENT_CONFLICT` (the active sponsor certificate's environment disagrees with `SEVIS_ENVIRONMENT`) or `SEVIS_GATEWAY_ENDPOINT_MISMATCH` (a configured upload or download endpoint does not belong to the resolved environment, or targets the production gateway from a non-production environment). `details` also carries `environment` and `requiredFlag`.
- Issuance guards fail with `SEVIS_NOT_READY` (`422`) when any pre-SEVIS track blocker is present, and with `SEVIS_COMPLIANCE_BLOCKED` (`403`) when only compliance or passport blockers remain. The compliance message lists the blocker reasons; when an approved override exists but immutable requirements still block, the message says the override cannot bypass them and `details` adds `overrideId` and `immutableBlockerKeys` next to `applicationId` and `blockers`. `PATCH /api/applications/:id` returns these when it sets `isInSevisPool` to true, and SEVIS batch creation and send return the same two codes (with `details.rejected`) when candidates fail readiness revalidation; batch confirm returns only `SEVIS_NOT_READY`.
- The mandatory J-1 phase-gate governance bundle (`j1-phase-gate-governance`) carries a system-managed global J-1 scope so its rules, including criminal-background upload presence, enter live evaluation; without that scope those dependencies would fail closed as not evaluated.

## Surface Area

The gate outcomes and camp eligibility path surface across these areas (Aug 11 2026 release capsule):

- Applicant profile compliance tab
- SEVIS-readiness-blocked queue
- Command Center Readiness tab
- Executive Overview gate aggregation
- `POST /api/sevis/compliance/check`

**SEVIS reconciliation report.** `GET /api/reports/sevis-reconciliation` (permission `reporting.view`, clamped to the caller's brand, program and season scope; query `brandId`, `programId`, `seasonId`, `from`, `to` and `format` for an export) compares the SEVIS status held here with the local application status for participants that have a SEVIS record. The JSON response carries `summary`, `exceptions`, `noShow`, `disposition`, `stalenessThresholdDays` and `scopeEmpty`. An exception is `locally_ended_still_active_in_sevis`, `terminated_in_sevis_no_local_disposition`, `reported_no_show_not_in_sevis` (discrepancies) or `status_not_confirmed` (unverified: the SEVIS status was not re-confirmed within the staleness threshold, or never). `GET /api/reports/sevis-reconciliation/exceptions/:exceptionKey` (same permission and scope clamps) is the drill-down: it re-runs the scoped read and returns the `exception` metadata (label, meaning, action, kind), the `window`, the participants with that exception (identity included) capped at 500 with `limit` and `total`, and `scopeEmpty`. An unknown `exceptionKey` returns a 400 validation error. The report only identifies discrepancies; any corrective SEVIS transaction stays a human decision.

## 100% Completeness Policy

> **Zero-Tolerance Completeness**
>
> The SEVIS pool entry gate enforces a 100% completeness policy. There is no partial-pass threshold — every required global `ready_for_sevis` rule and every applicable program add-on rule must pass. This is a regulatory requirement, not a configurable threshold.

The 100% policy is implemented by the Rules Engine's resolveReadiness() function, which aggregates all rule outcomes for the global gate and any program add-on gate and returns blocked if any single rule fails. The gate will not open until all rules pass.

## Stored Verdicts, Fingerprints & Invalidation

Shipped Sep 2026. Readiness outcomes shown on the Applicant Profile and used to build the Ready Pool are **stored projection rows**, not live evaluations — screen loads never run the full readiness evaluator. To keep stored verdicts honest after configuration changes:

- **Every verdict carries a PII-free fingerprint** of the evaluator release, the application's program and operational cycle, the applicable pre-SEVIS tracks, the published baseline and program add-on gate versions, and the pool override context used during evaluation. A row with no fingerprint, a malformed fingerprint, or an older evaluator version is treated exactly like a missing verdict: it displays as **Awaiting Evidence** (staff wording: *Checking readiness*), never Ready, and cannot be selected or counted as eligible.
- **Configuration changes invalidate before they commit.** Publishing a SEVIS gate change, changing a gate's scope, changing a program's applicable tracks, or reassigning an application's program or operational cycle transactionally invalidates the affected stored rows inside the same transaction as the change. Global configuration changes also advance a persisted generation; each evaluation captures the generation before loading the rules catalogue and its persistence is refused if the generation moved while it ran, and readers reject rows from an older generation. An evaluation that started from a stale cached catalogue therefore cannot restore obsolete readiness after invalidation.
- **Data changes invalidate the affected application.** Mutations that can flip a blocker tombstone that application's stored verdict synchronously. When lifecycle reconciliation persists a changed pre-SEVIS track state, the verdict is tombstoned in the same transaction as the application update (both roll back together; an unchanged reconciliation invalidates nothing). SWT evidence decisions (for example vacation dates submitted, updated or verified) invalidate that application's verdict before queueing the targeted rule re-evaluation, so a closed blocker cannot linger while the asynchronous evaluation catches up.
- **The background sweeper rebuilds.** Missing, invalidated, expired, malformed-fingerprint, obsolete-evaluator and obsolete-generation rows are prioritised and rebuilt outside the request path. Readers only select; they never evaluate.
- **Freshness and expiry.** A stored verdict older than six hours is presented as stale (the sweeper re-verifies after four hours); the Applicant Profile then shows *Rechecking readiness* rather than Ready. A verdict computed under a readiness override is withheld once that override's expiry passes.
- **The Applicant Profile and the Ready Pool agree.** The profile's SEVIS card reads the same persisted full-readiness verdict as the Ready Pool; the operational gate detail only explains prerequisites and can no longer promote the applicant to Ready on its own. The profile's SEVIS readiness card renders the complete verdict: every unique structural blocker (workflow track, missing field) and every rule blocker is listed, deduplicated on rule key (with a composite-key fallback when a blocker has none), with linked incomplete workflow steps and an "Evaluated <date/time>" line taken from the verdict's evaluation time. The earlier behavior of showing only structural blockers plus a count of additional compliance rules is gone.
- **Filters and badges cannot disagree.** Ready Pool filtering matches on the same persisted row each application is rendered from; `awaiting` is exactly the set with no usable verdict. Rows are ordered by application `updatedAt` descending with an id tie-break, so an application cannot appear on two pages or on none.
- **Ready Pool cards and labels.** The four summary cards mean different things: *Confirmed gate pass* counts applications whose readiness is confirmed passing right now (a floor, not a total, while any verdicts are still being evaluated), *In Ready Pool* counts applications admitted for SEVIS processing, *DS-2019 issued* counts completed issuance, and *Waitlisted* counts applications awaiting program capacity. A pending or stale verdict is never treated as gate-ready and is never selectable for a batch: the row shows *Checking readiness* (no verdict yet) or *Rechecking readiness* with *Previously ready / not ready · rechecking*. Otherwise rows show *Ready for SEVIS* or *Not ready for SEVIS processing*. The readiness filter options are All applicants, Ready for batching, Processing incomplete, Checks need attention, and Still checking, with a one-line help text under the filter.
- **Backing tables.** `sevis_readiness_projection_config` is a single-row table (`id` fixed at 1, `generation`, `updated_at`) holding the configuration generation described above; each stored verdict records the generation it was computed under. `sevis_readiness_verdict_transitions` is an append-only history written when a stored verdict changes materially: the application, `from_ready` and `to_ready`, the full `from_verdict` and `to_verdict`, `change_kind`, the fingerprint and generation, and `changed_at`. `change_kind` is `initial` (first recorded verdict), `regression` (ready to not ready), `restored` (not ready to ready) or `changed`. The Ready Pool query returns each application's latest transition.

## Override and Audit Trail

A staff member with the `sevis.override.manage` RBAC permission (Super Admin, Compliance Manager, Compliance Officer) manages SEVIS readiness overrides. New broad overrides are retired: `POST /api/applications/:id/sevis-readiness-overrides` (still gated by the permission and entity scope, and answering 404 first for an unknown application) always ends in a 409 `LEGACY_SEVIS_OVERRIDE_RETIRED`, directing staff to request a governed Compliance override for the specific failed rule instead. Existing overrides are grandfathered until they expire or are revoked, and the same permission governs revoking, shortening the expiry of, reading the audit history of, and relying on one. An override is recorded per application and operation scope (`pool`, `add`, `confirm`, `send`; authority on one scope never covers another) with the waived blocker keys, a justification (minimum 20 characters), its expiry and an audit row. It is bound to the application's program and operational cycle (a material change makes it ineffective) and fails closed on expiry. Overrides were applied in one action by one authorized person with no second approver, with a 24-hour default life (`SEVIS_OVERRIDE_DEFAULT_EXPIRY_HOURS`) and a hard ceiling of 168 hours (7 days) measured from the moment the override was applied; that ceiling still bounds any expiry edit.

Some requirements can never be overridden: a terminal journey position (withdrawn, rejected, completed, cancelled, alumni), host site address state or postal-code defects, the minimum identity and contact set (first name, surname, contact phone, email, date of birth), and any minimum-age determination. Overrides are surfaced on the applicant's compliance timeline and are visible to compliance reviewers.

Every override route requires `sevis.override.manage` plus entity scope over the application's program, season, brand and partner organization.

| Route | Purpose | Contract |
| --- | --- | --- |
| `GET /api/applications/:id/sevis-readiness-overrides` | List the application's overrides | Optional `scope`, `status` (`pending`, `active`, `rejected`, `revoked`, `expired`; `pending` and `rejected` are legacy states) and `limit` (1 to 100). `includeBaseline=true` adds the no-override baseline: evaluation time, bypassable and non-bypassable blockers, and the scopes currently covered. |
| `GET /api/applications/:id/sevis-readiness-overrides/active` | Active override for one scope | `scope` is required. Returns `{ override, active }`. |
| `POST /api/applications/:id/sevis-readiness-overrides` | Apply (retired) | Once the permission, application and scope checks pass, always 409 `LEGACY_SEVIS_OVERRIDE_RETIRED`. |
| `POST /api/sevis-readiness-overrides/:overrideId/revoke` | Revoke one scope's override | Body is `reasonCode` only, one of `no_longer_needed`, `risk_identified`, `issued_in_error`, `superseded` or `other`; free text is rejected. |
| `PATCH /api/sevis-readiness-overrides/:overrideId/expiry` | Change the expiry | Body `expiresAt` plus `reasonCode` (`batch_rescheduled`, `remediation_delayed`, `administrative_correction` or `other`). Shorten only: a later expiry is 409 `LEGACY_SEVIS_OVERRIDE_EXTENSION_RETIRED`. The new expiry must be in the future and within 168 hours of when the override was applied (400 otherwise). |
| `GET /api/sevis-readiness-overrides/:overrideId/audit` | Audit trail | The append-only override audit events merged with the used and denied usage entries, oldest first. |

The audit events come from `sevis_readiness_override_audit`, one row per lifecycle event of an override: `override_id` (deletion of an override with events is restricted), `event_type` (`applied`, `expiry_changed`, `revoked`, `expired`, plus the retired `requested`, `approved` and `rejected`, kept so older rows still resolve), `actor_user_id` (null for system expiry), `status_snapshot`, `occurred_at` and a `metadata` object limited to the blocker keys, the justification length, the old and new expiry and a bounded `reasonCode`. The justification text stays on the override row and is never copied into the audit.
