{
  "$schema": "https://govschema.org/spec/v0.3/govschema.schema.json",
  "govschemaVersion": "0.3.0",
  "id": "rw/dgie/visa-application",
  "version": "1.0.0",
  "title": "Rwanda Visa Application (Directorate General of Immigration and Emigration)",
  "description": "Apply for a Rwandan entry visa (transit, tourist/visitor's, resident, or permanent) through the Directorate General of Immigration and Emigration (DGIE)'s standard \"VISA APPLICATION\" specimen used at Rwandan diplomatic missions abroad, resolving Rwanda's previously open, unresolved Visa candidate (GOV-2526's backlog item) and opening Rwanda's Visa vertical (2 of 6, alongside DMV). The specimen is a genuine, unauthenticated, directly downloadable PDF confirmed byte-identical across two independent Rwandan-embassy mirrors (in the UK and the USA); migration.gov.rw's own visitors-visa guidance confirms \"the office of a diplomatic mission of Rwanda in the applicant's country of residence\" as a current visa-issuance channel alongside the IremboGov online portal, border posts, and the DGIE office itself. Unlike rw/rra's Motor Vehicle Registration Form, this specimen carries **0 AcroForm widgets** — a flat, print-and-hand-fill form (the same pattern already established by pe/sunat, uy/dgi, and ke/brs in this registry), completed by hand, signed, and submitted in person or by mail with a coloured photo and supporting documents. It carries 27 numbered items across 2 pages, covering identity and passport particulars, parents' and (conditionally) spouse's particulars, prior travel history, the host/purpose of travel, and a bounded, printed 4-slot repeating group for accompanying children. This schema models 48 `fields[]` entries derived from those 27 numbered items (several numbered items print two or more side-by-side blanks, e.g. item 6 \"Place of Birth\" splits into District/Country, and item 27's children table is flattened to 4 numbered child slots per this registry's established bounded-repeating-group convention) plus the printed \"Done at / on\" signing block, and 2 `documents[]` entries (the coloured photo requirement and the printed certification statement). GovSchema is independent and is not affiliated with, endorsed by, or operated by the Government of Rwanda or its Directorate General of Immigration and Emigration.",
  "status": "draft",
  "jurisdiction": {
    "country": "RW",
    "level": "national"
  },
  "authority": {
    "name": "Directorate General of Immigration and Emigration",
    "abbreviation": "DGIE",
    "url": "https://www.migration.gov.rw"
  },
  "process": {
    "type": "application",
    "language": "en"
  },
  "source": {
    "url": "https://www.rwandainuk.gov.rw/fileadmin/user_upload/UK_user_upload/Documents/visa_permit_application_form_pdf.pdf",
    "retrievedAt": "2026-07-12",
    "documentRef": "\"VISA APPLICATION\" (Directorate General of Immigration and Emigration, under the National Intelligence and Security Service), 2-page flat (0 AcroForm widgets) PDF, confirmed byte-identical to the Rwandan Embassy in the USA's own mirror."
  },
  "verification": {
    "method": "manual-source-review-v1",
    "lastVerifiedAt": "2026-07-12",
    "verifiedBy": "GovSchema Engineering (Standards Engineer)",
    "nextReviewBy": "2027-01-12",
    "notes": "GovSchema Standard Research cycle GOV-2544, resolving GOV-2526's disclosed open Visa candidate. Independently re-fetched both cited mirrors directly (rwandainuk.gov.rw: HTTP 200, application/pdf, 233,226 bytes, Last-Modified 2021-03-22; rwandainusa.gov.rw: HTTP 200, application/pdf, 233,226 bytes, Last-Modified 2024-09-03) and confirmed both match the issue's cited sha256 (01ffbc05db088ece045c25867f791892dc3b9eed808b1445867f3d29946378c0) exactly, and are identical to each other byte-for-byte despite the two mirrors' differing Last-Modified headers — corroborating the issue's byte-identity claim independently rather than trusting it, and the newer USA-mirror Last-Modified date as a signal of ongoing maintenance. Re-fetched migration.gov.rw/visa/visitors-visa/ directly and confirmed its own printed text names \"the office of a diplomatic mission of Rwanda in the applicant's country of residence\" as a current issuance channel for the Holiday/Tourist (V1), Job Search (V4), and Business Survey (V6) visa categories. pdfjs-dist (legacy build, v3) getAnnotations() confirms 0 Widget annotations on both of the specimen's 2 pages, and getTextContent() (position-sorted by transform x/y) was used to read the form's full printed text and correlate every numbered item and its blank(s) directly, with no digital field names available to cross-check against (a flat form, unlike rw/rra). All 27 numbered items were accounted for exactly once. 48 fields[] entries were derived: 46 from splitting several numbered items into their printed side-by-side blanks (item 6 Place of Birth -> district/country; item 14 -> profession/occupation; items 16-17 -> father's/mother's name and nationality; items 20-22 -> a 5-field spouse block gated by requiredWhen against maritalStatus=married, matching this registry's ph/bi, ph/dfa, ph/lto, and us/uscis precedent for spouse-conditional fields; item 27's printed 2x2 children table -> 4 flattened child1-4 name/gender/dateOfBirth slots, matching fi/migri's established bounded-repeating-group convention) plus 2 fields for the header's visa-type/length-of-stay line (modelled as free text since the printed line has no tick-box instruction and its category boundaries -- \"Transit / Tourist / Visitor's-Resident - Permanent\" -- are ambiguous, rather than inventing an enum) and 2 for the printed \"Done at, ___ on ___\" signing-place/date block. 2 documents[] entries capture the printed \"COLOURED PHOTO\" box (supporting-evidence, matching pe/cancilleria/solicitud-visa-dgc-005's convention for a visa-form photo requirement) and the printed \"I hereby certify that all information is complete and correct\" statement beside the unwidgeted signature line (attestation, matching this registry's existing wet-ink-certification convention). The final printed section (\"Do not write below this line, for official use only\") is excluded as an office-only block. Conformance run: 2 valid mock scenarios (0 errors each) and 3 mutation-control fixtures (exactly 1 error each) using a disposable validate_instance.mjs script (not committed) implementing this schema's own required/requiredWhen grammar plus ajv for the static JSON Schema subset -- see VERIFICATION.md for the full write-up."
  },
  "maturity": {
    "level": "structural-reference",
    "criteria": {
      "structuralReference": true,
      "verifiedSchema": false,
      "agentReadySchema": false,
      "executionTestedSchema": false
    },
    "method": "maturity-self-assessment-v1",
    "assertedBy": "GovSchema Engineering (Standards Engineer)",
    "assertedAt": "2026-07-12"
  },
  "license": "CC-BY-4.0",
  "fields": [
    {
      "name": "visaTypeApplied",
      "label": "Visa applied for",
      "type": "string",
      "required": true,
      "description": "The category of visa applied for. The form prints \"Visa applied for: Transit / Tourist / Visitor's-Resident – Permanent\" as a single header line with one blank and no tick-box instruction (unlike, e.g., item 4's Gender or item 19's Marital Status, both of which print an explicit \"put a tick (√) in the relevant box\" instruction) and no enumerated boundary between \"Visitor's\", \"Resident\", and \"Permanent\" is legible from the printed punctuation alone, so this is modelled as free text quoting the applicant's own choice rather than an invented enum.",
      "sourceRef": "Page 1 header: \"Visa applied for: Transit / Tourist / Visitor's-Resident – Permanent\"",
      "validation": { "maxLength": 100 }
    },
    {
      "name": "lengthOfStay",
      "label": "Length of stay",
      "type": "string",
      "required": true,
      "sourceRef": "Page 1 header: \"Length of stay:\"",
      "validation": { "maxLength": 50 }
    },
    {
      "name": "givenNames",
      "label": "Given name(s)",
      "type": "string",
      "required": true,
      "classification": "pii",
      "description": "As shown in the applicant's passport.",
      "sourceRef": "Item 1: \"Given name(s) (As shown in your passport)\"",
      "validation": { "maxLength": 150 }
    },
    {
      "name": "familyNames",
      "label": "Family name(s)",
      "type": "string",
      "required": true,
      "classification": "pii",
      "description": "As shown in the applicant's passport.",
      "sourceRef": "Item 2: \"Family name(s) (As shown in your passport)\"",
      "validation": { "maxLength": 150 }
    },
    {
      "name": "otherNames",
      "label": "Other name(s)",
      "type": "string",
      "required": false,
      "classification": "pii",
      "description": "Including other names the applicant is or has been known by. Not required: an applicant with no other names has nothing to declare here and the form provides no separate \"none\" checkbox.",
      "sourceRef": "Item 3: \"Other name(s) (including other names You are known by and/or other names that you have been known by)\"",
      "validation": { "maxLength": 200 }
    },
    {
      "name": "gender",
      "label": "Gender",
      "type": "enum",
      "required": true,
      "classification": "pii",
      "description": "The form's own two-option tick-box pair (no third option is printed).",
      "sourceRef": "Item 4: \"Gender: put a tick (√) in the relevant box\" — \"Male\" / \"Female\"",
      "validation": { "enum": ["male", "female"] }
    },
    {
      "name": "dateOfBirth",
      "label": "Date of Birth",
      "type": "date",
      "required": true,
      "classification": "sensitive-pii",
      "sourceRef": "Item 5: \"Date of Birth\" (Day / Month / Year)"
    },
    {
      "name": "placeOfBirthDistrict",
      "label": "Place of Birth: District",
      "type": "string",
      "required": true,
      "classification": "pii",
      "description": "Printed as one of two blanks under item 6 (District and Country); modelled as its own field since the two are visually and semantically distinct.",
      "sourceRef": "Item 6: \"Place of Birth\" — \"District\"",
      "validation": { "maxLength": 100 }
    },
    {
      "name": "placeOfBirthCountry",
      "label": "Place of Birth: Country",
      "type": "string",
      "required": true,
      "classification": "pii",
      "sourceRef": "Item 6: \"Place of Birth\" — \"Country\"",
      "validation": { "maxLength": 100 }
    },
    {
      "name": "nationalityOfBirth",
      "label": "Nationality of Birth",
      "type": "string",
      "required": true,
      "classification": "pii",
      "sourceRef": "Item 7: \"Nationality of Birth\"",
      "validation": { "maxLength": 100 }
    },
    {
      "name": "emailContact",
      "label": "E-mail contact",
      "type": "string",
      "required": true,
      "classification": "pii",
      "sourceRef": "Item 8: \"E-mail contact\"",
      "validation": { "pattern": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$", "maxLength": 150 }
    },
    {
      "name": "localTelephoneContact",
      "label": "Local Telephone contact",
      "type": "string",
      "required": true,
      "classification": "pii",
      "sourceRef": "Item 9: \"Local Telephone contact\"",
      "validation": { "maxLength": 30 }
    },
    {
      "name": "passportNumber",
      "label": "Passport No",
      "type": "string",
      "required": true,
      "classification": "sensitive-pii",
      "sourceRef": "Item 10: \"Passport No\"",
      "validation": { "maxLength": 30 }
    },
    {
      "name": "passportNationality",
      "label": "Nationality of passport",
      "type": "string",
      "required": true,
      "classification": "pii",
      "sourceRef": "Item 11: \"Nationality of passport\"",
      "validation": { "maxLength": 100 }
    },
    {
      "name": "passportIssueDate",
      "label": "Date of Issue of passport",
      "type": "date",
      "required": true,
      "classification": "sensitive-pii",
      "sourceRef": "Item 12: \"Date of Issue of passport\" (Day / Month / Year)"
    },
    {
      "name": "passportExpiryDate",
      "label": "Expiry date of passport",
      "type": "date",
      "required": true,
      "classification": "sensitive-pii",
      "sourceRef": "Item 13: \"Expiry date of passport\" (Day / Month / Year)"
    },
    {
      "name": "profession",
      "label": "Profession",
      "type": "string",
      "required": true,
      "description": "Printed as one of two blanks on item 14's row (Profession and Occupation); modelled as separate fields since the form prints two distinct labels rather than one combined term.",
      "sourceRef": "Item 14: \"Profession\"",
      "validation": { "maxLength": 100 }
    },
    {
      "name": "occupation",
      "label": "Occupation",
      "type": "string",
      "required": true,
      "sourceRef": "Item 14: \"Occupation\"",
      "validation": { "maxLength": 100 }
    },
    {
      "name": "employer",
      "label": "Employer",
      "type": "string",
      "required": true,
      "sourceRef": "Item 15: \"Employer\"",
      "validation": { "maxLength": 150 }
    },
    {
      "name": "fatherName",
      "label": "Father's name",
      "type": "string",
      "required": true,
      "classification": "pii",
      "description": "Printed as one of two blanks on item 16's row (father's and mother's name).",
      "sourceRef": "Item 16: \"Father's name\"",
      "validation": { "maxLength": 150 }
    },
    {
      "name": "motherName",
      "label": "Mother's name",
      "type": "string",
      "required": true,
      "classification": "pii",
      "sourceRef": "Item 16: \"mother' name\"",
      "validation": { "maxLength": 150 }
    },
    {
      "name": "fatherNationality",
      "label": "Father's nationality",
      "type": "string",
      "required": true,
      "classification": "pii",
      "description": "Printed as one of two blanks on item 17's row (father's and mother's nationality).",
      "sourceRef": "Item 17: \"Father's nationality\"",
      "validation": { "maxLength": 100 }
    },
    {
      "name": "motherNationality",
      "label": "Mother's nationality",
      "type": "string",
      "required": true,
      "classification": "pii",
      "sourceRef": "Item 17: \"mother's nationality\"",
      "validation": { "maxLength": 100 }
    },
    {
      "name": "parentsAddress",
      "label": "Parent's address",
      "type": "string",
      "required": true,
      "classification": "pii",
      "sourceRef": "Item 18: \"Parent's address\"",
      "validation": { "maxLength": 200 }
    },
    {
      "name": "maritalStatus",
      "label": "Marital Status",
      "type": "enum",
      "required": true,
      "classification": "pii",
      "sourceRef": "Item 19: \"Marital Status: put a tick (√) in the relevant box\" — \"Married\" / \"Widowed\" / \"Divorced\" / \"Never Married/single\"",
      "validation": {
        "enum": ["married", "widowed", "divorced", "never_married_single"]
      }
    },
    {
      "name": "spouseName",
      "label": "Name of spouse",
      "type": "string",
      "required": false,
      "classification": "pii",
      "description": "Not required for an unmarried, widowed, or divorced applicant; gated on maritalStatus. Printed as one of two blanks on item 20's row (spouse's name and nationality).",
      "sourceRef": "Item 20: \"Name of spouse\"",
      "requiredWhen": { "field": "maritalStatus", "equals": "married" },
      "validation": { "maxLength": 150 }
    },
    {
      "name": "spouseNationality",
      "label": "Spouse's nationality",
      "type": "string",
      "required": false,
      "classification": "pii",
      "sourceRef": "Item 20: \"Spouse's nationality\"",
      "requiredWhen": { "field": "maritalStatus", "equals": "married" },
      "validation": { "maxLength": 100 }
    },
    {
      "name": "spouseBirthPlace",
      "label": "Spouse born at",
      "type": "string",
      "required": false,
      "classification": "pii",
      "description": "The place the spouse was born, continuing item 20's spouse block onto item 21's row (\"Born at ___ on [date]\").",
      "sourceRef": "Item 21: \"Born at ;\"",
      "requiredWhen": { "field": "maritalStatus", "equals": "married" },
      "validation": { "maxLength": 100 }
    },
    {
      "name": "spouseBirthDate",
      "label": "Spouse's date of birth",
      "type": "date",
      "required": false,
      "classification": "sensitive-pii",
      "sourceRef": "Item 21: \"on\" (Day / Month / Year)",
      "requiredWhen": { "field": "maritalStatus", "equals": "married" }
    },
    {
      "name": "spousePresentAddress",
      "label": "Present address of spouse",
      "type": "string",
      "required": false,
      "classification": "pii",
      "sourceRef": "Item 22: \"Present address of spouse\"",
      "requiredWhen": { "field": "maritalStatus", "equals": "married" },
      "validation": { "maxLength": 200 }
    },
    {
      "name": "priorVisitsRwanda",
      "label": "Former visits or stay in Rwanda, and time of stay",
      "type": "string",
      "required": false,
      "description": "Not required: a first-time applicant genuinely has none to declare, and the form provides no separate \"none\" checkbox, matching this registry's uy/mrree precedent for an analogous \"previous visits\" question.",
      "sourceRef": "Item 23: \"Former visits or stay in Rwanda, and time of stay\"",
      "validation": { "maxLength": 400 }
    },
    {
      "name": "priorStaysAfrica",
      "label": "Former stays in Africa, places, and dates",
      "type": "string",
      "required": false,
      "description": "Not required, for the same reason as priorVisitsRwanda.",
      "sourceRef": "Item 24: \"Former stays in Africa, places, and dates\"",
      "validation": { "maxLength": 400 }
    },
    {
      "name": "reasonForVisaApplication",
      "label": "Reason for visa application",
      "type": "string",
      "required": true,
      "sourceRef": "Item 25: \"Reason for visa application\"",
      "validation": { "maxLength": 400 }
    },
    {
      "name": "personsToBeVisitedAndAddress",
      "label": "Proposed persons to be visited and their address",
      "type": "string",
      "required": true,
      "description": "The named host(s) or contact(s) in Rwanda and their address; may cite a hotel or tour operator for an applicant with no personal host, consistent with this registry's uy/mrree \"referenciaUruguay\" precedent for an analogous in-country-reference field.",
      "sourceRef": "Item 26: \"Proposed persons to be visited and their address:\"",
      "validation": { "maxLength": 300 }
    },
    {
      "name": "child1Name",
      "label": "Accompanying child 1: Name",
      "type": "string",
      "required": false,
      "classification": "pii",
      "description": "Item 27 (\"Persons accompanying (children)\") prints a bounded 2x2 table (4 numbered slots: 1-4), not an open-ended list; flattened here to child1..child4, matching this registry's fi/migri bounded-repeating-group convention. Not required: an applicant with no accompanying children leaves the whole table blank.",
      "sourceRef": "Item 27, slot 1: \"1. Name\"",
      "validation": { "maxLength": 150 }
    },
    {
      "name": "child1Gender",
      "label": "Accompanying child 1: Gender",
      "type": "enum",
      "required": false,
      "description": "Expected to be filled in whenever child1Name is filled in, but not machine-gated with requiredWhen: child1Name is itself optional and absent (not empty-string) when unused, and comparing an absent sibling field against a sentinel value risks the same misfire class this registry has already hit and fixed elsewhere (see e.g. gov1121-nl-denhaag-voter-registration-abroad's symmetric judgment call).",
      "sourceRef": "Item 27, slot 1: \"Gender: put a tick (√) in the relevant box\" — \"Male\" / \"Female\"",
      "validation": { "enum": ["male", "female"] }
    },
    {
      "name": "child1DateOfBirth",
      "label": "Accompanying child 1: Date of birth",
      "type": "date",
      "required": false,
      "classification": "sensitive-pii",
      "description": "Expected to be filled in whenever child1Name is filled in; not machine-gated, for the same reason as child1Gender.",
      "sourceRef": "Item 27, slot 1: \"Date of birth:\" (Day / Month / Year)"
    },
    {
      "name": "child2Name",
      "label": "Accompanying child 2: Name",
      "type": "string",
      "required": false,
      "classification": "pii",
      "sourceRef": "Item 27, slot 2: \"2. Name\"",
      "validation": { "maxLength": 150 }
    },
    {
      "name": "child2Gender",
      "label": "Accompanying child 2: Gender",
      "type": "enum",
      "required": false,
      "description": "Expected to be filled in whenever child2Name is filled in; not machine-gated, for the same reason as child1Gender.",
      "sourceRef": "Item 27, slot 2: \"Gender: put a tick (√) in the relevant box\" — \"Male\" / \"Female\"",
      "validation": { "enum": ["male", "female"] }
    },
    {
      "name": "child2DateOfBirth",
      "label": "Accompanying child 2: Date of birth",
      "type": "date",
      "required": false,
      "classification": "sensitive-pii",
      "description": "Expected to be filled in whenever child2Name is filled in; not machine-gated, for the same reason as child1Gender.",
      "sourceRef": "Item 27, slot 2: \"Date of birth:\" (Day / Month / Year)"
    },
    {
      "name": "child3Name",
      "label": "Accompanying child 3: Name",
      "type": "string",
      "required": false,
      "classification": "pii",
      "sourceRef": "Item 27, slot 3: \"3. Name\"",
      "validation": { "maxLength": 150 }
    },
    {
      "name": "child3Gender",
      "label": "Accompanying child 3: Gender",
      "type": "enum",
      "required": false,
      "description": "Expected to be filled in whenever child3Name is filled in; not machine-gated, for the same reason as child1Gender.",
      "sourceRef": "Item 27, slot 3: \"Gender: Male\" / \"Female\"",
      "validation": { "enum": ["male", "female"] }
    },
    {
      "name": "child3DateOfBirth",
      "label": "Accompanying child 3: Date of birth",
      "type": "date",
      "required": false,
      "classification": "sensitive-pii",
      "description": "Expected to be filled in whenever child3Name is filled in; not machine-gated, for the same reason as child1Gender.",
      "sourceRef": "Item 27, slot 3: \"Date of birth:\" (Day / Month / Year)"
    },
    {
      "name": "child4Name",
      "label": "Accompanying child 4: Name",
      "type": "string",
      "required": false,
      "classification": "pii",
      "sourceRef": "Item 27, slot 4: \"4. Name\"",
      "validation": { "maxLength": 150 }
    },
    {
      "name": "child4Gender",
      "label": "Accompanying child 4: Gender",
      "type": "enum",
      "required": false,
      "description": "Expected to be filled in whenever child4Name is filled in; not machine-gated, for the same reason as child1Gender.",
      "sourceRef": "Item 27, slot 4: \"Gender: Male\" / \"Female\"",
      "validation": { "enum": ["male", "female"] }
    },
    {
      "name": "child4DateOfBirth",
      "label": "Accompanying child 4: Date of birth",
      "type": "date",
      "required": false,
      "classification": "sensitive-pii",
      "description": "Expected to be filled in whenever child4Name is filled in; not machine-gated, for the same reason as child1Gender.",
      "sourceRef": "Item 27, slot 4: \"Date of birth\" (Day / Month / Year)"
    },
    {
      "name": "signingPlace",
      "label": "Done at",
      "type": "string",
      "required": true,
      "sourceRef": "Page 2: \"Done at, ___ on ___\" — place",
      "validation": { "maxLength": 100 }
    },
    {
      "name": "signingDate",
      "label": "Signing date",
      "type": "date",
      "required": true,
      "sourceRef": "Page 2: \"Done at, ___ on ___\" — date (Day / Month / Year)"
    }
  ],
  "documents": [
    {
      "id": "applicantPhoto",
      "label": "Coloured photo",
      "category": "supporting-evidence",
      "required": true,
      "belongsTo": "applicant",
      "constraints": {
        "mediaTypes": ["image/jpeg", "image/png"]
      },
      "sourceRef": "Page 1, right margin: \"COLOURED PHOTO\""
    },
    {
      "id": "applicationCertification",
      "label": "Certification that all information is complete and correct",
      "category": "attestation",
      "required": true,
      "belongsTo": "applicant",
      "statement": "I hereby certify that all information is complete and correct",
      "sourceRef": "Page 2, beside the (unwidgeted) signature line: \"I hereby certify that all information is complete and correct\""
    }
  ]
}
