Skip to content

IMM-03 · Eligibility and operator review

SOP: SOP_Immigration_Applications.md §5 / §8 Steps 4–5Actors: System (worker) then IMM Operator (admin@spade.local in dev). Pre-state: The client submitted their form (IMM-02); the run resumed to RUNNING. Post-state: Applicant screened (KycCase + ScreeningResult); eligibility evaluated against the SG IMM pack; MOM pack assembled; tier-4 IMM.SUBMIT_APPLICATION proposed → run AWAITING_REVIEW. (Or FAILED if eligibility BLOCKED.)

0. Prerequisites

  • A resumed IMM run that has passed collectDocuments. The threshold for the pass type is read from Jurisdiction.config.immThresholds[passType] (fallback 5000 SGD) — see IMM-05 §config and SOP §5.2.

1. Steps (worker-driven)

On resume the workflow runs steps 3–7:

  1. collectDocuments — derives completeness from the uploaded KycDocument slots vs the form definition's requiredDocs.
  2. screen — runs the screening adapter and persists a KycCase (purpose = ONBOARDING, status = SCREENING, source_run_id = <runId>) + a ScreeningResult. Idempotent per run + party.
  3. evalEligibility (RULE) — evaluates SG_IMM_PACK against the facts: monthly salary vs the injected per-pass-type threshold, documents complete, screening not CONFIRMED_MATCH, employer LIVE. Throws → run FAILED on any BLOCK.
  4. assembleApplication — builds the assisted MOM pack (mappedFields + an HTML artifact, base64 in the step output).
  5. submit — proposes the tier-4 IMM.SUBMIT_APPLICATION action; the orchestrator routes the run to AWAITING_REVIEW.

2. Operator review

2.1 Open the application detail

Navigate to /dashboard/imm/applications/<runId>. The page calls GET /ops/imm/applications/:runId, returning tabs:

  • details — run status, pass type, applicant, employer.
  • eligibilityevaluated, passed, salaryThresholdSgd, packVersion, warnings, blockers (the evalEligibility step's escalationReason when blocked).
  • documents — the collected KycDocument rows (docType, fileId, verification status).
  • review — the tier-4 review task (riskTier 4, routing, SLA, awaitingDecision).
  • submission / renewal — populated after the gate (see IMM-04, IMM-05).

2.2 Inspect the assembled pack

The detail response includes pack.mappedFields + pack.artifact (contentType, fileName, sizeBytes) so the operator can read exactly what to key into EP Online / WPOL. Once the application is filed and applied, the stored PDF/HTML is downloadable via GET /ops/imm/applications/:runId/pack (presigned S3 URL, 10-min TTL).

3. Verification

Database

sql
SELECT name, step_type, escalation_reason FROM agent_steps
  WHERE run_id = '<runId>' ORDER BY seq;
-- expect classify, collectApplicationForm, collectDocuments, screen, evalEligibility, assembleApplication, submit

SELECT purpose, status FROM kyc_cases WHERE source_run_id = '<runId>';
-- expect purpose = 'ONBOARDING'

SELECT provider, outcome FROM screening_results sr
  JOIN kyc_cases kc ON kc.id = sr.kyc_case_id WHERE kc.source_run_id = '<runId>';

SELECT status FROM agent_runs WHERE id = '<runId>';
-- expect 'AWAITING_REVIEW' (or 'FAILED' if a BLOCK rule fired)

API

  • GET /ops/imm/applications lists the run; eligibility.passed = true and review.awaitingDecision = true when at the gate.

4. Negative & edge cases

  • Salary below thresholdSG.IMM.SALARY_THRESHOLD BLOCKS; run FAILED; detail eligibility.passed = false with the blocker reason.
  • Missing documentSG.IMM.DOCUMENTS_PRESENT BLOCKS (should not happen if IMM-02 submit validation ran, but the rule is the backstop).
  • Confirmed screening matchSG.IMM.SCREENING_CLEARED BLOCKS.
  • Employer not LIVESG.IMM.EMPLOYER_ELIGIBLE BLOCKS.
  • A FAILED run can be re-driven (FAILED → RUNNING) after the blocker is resolved.

Next

Proceed to IMM-04 · Tier-4 submission and acknowledgement.

Internal use only — BreezyCorp