§02 · Compile

ROE → MissionArtifact

How prose Rules of Engagement become a typed, paragraph-traced, commander-signed binary.
Reads after
§01 The compile-and-execute model
Reads before
§03 MissionArtifact → decision
Key claim
The compile path is the only place a language model touches Lincoln's data flow. The deterministic gates downstream are what make the choice safe.

The compile path takes free-form ROE prose and produces a Zod-typed, paragraph-traced, Ed25519-signed MissionArtifact. A language model reads the prose; an allowlist filters what the model is allowed to authorize; an operator validates the parsed result against the source; the commander signs the canonical-JSON of the final artifact. The signed binary is then the only artifact that crosses into execute time. Everything that fires at execute time can be traced to a paragraph in this binary, and from there to the prose the commander signed.

§1What the source program looks like

ROE is not one document. In the field it is a stack: an OPORD with engagement annexes, an ROE card distilled for the operator, weapons-control schedules, coalition coordination overlays, and an issuing authority's signed cover. Sometimes a hand-marked map. Sometimes a photo of a card on a clipboard. The compile path has to accept all of these and produce one thing.

The compile path expects prose paragraphs, numbered, in conventional ROE structure: Paragraph 1 mission window, Paragraph 2 geographic boundaries, Paragraph 3 positive identification criteria, Paragraph 4 engagement authority by class and zone, Paragraph 6 coalition coordination, Paragraph 7 escalation, Paragraph 8 prohibitions. The numbering matches how staff already write ROE, and every rule the artifact emits cites back to its source paragraph.

§2The compile pipeline

SOURCE ROE prose OPORD annexes brief photo paragraph-numbered FRONTEND · LM @interpretation gpt-4o-mini text gpt-4o vision prose → candidate fields ALLOWLIST GATE deterministic rejects unknown rule kinds + classes refuse, do not extend VALIDATE side-by-side UI prose vs. parsed commander corrects human-in-the-loop SIGN canonical JSON + Ed25519 SIGNED MISSIONARTIFACT artifact_id · mission_id · effective parsed_roe { PID, authority, zones, temporal, escalation, prohibited } commander signature over canonical JSON runtime boot: verify signature, refuse to start on mismatch → execute time
Figure 1. Five stages, three of them deterministic. The frontend (LM) does the natural-language work; the allowlist refuses anything outside its grammar; the operator validates against the source prose; the commander signs the canonical-JSON and only then is the artifact admissible at execute time.

§3Stage by stage

Stage 1 — Source intake

The intake surface accepts text (pasted ROE), image (photo of a card or briefing slide), and structured uploads (an existing JSON ROE from a prior mission). Image inputs run through gpt-4o vision for OCR and structure extraction; text inputs go directly to gpt-4o-mini. The intake layer adds no semantics — it normalizes the source into a single “ROE document” shape that the frontend can consume.

Stage 2 — Frontend (language model)

@lincoln/interpretation contains the only language-model code in the compile path. The model is given the source ROE plus a strict schema and asked to produce candidate values for each field of the artifact: PID criteria, engagement authority entries, geographic boundary polygons, temporal conditions, escalation procedures, prohibited actions. Each candidate carries a paragraph_ref sourced from the model's reading of the prose.

The model performs translation: it interprets what the prose says and produces candidate fields. The downstream gates verify those candidates. The cache layer (cache.ts) memoizes the model's output across runs of the same input.

Stage 3 — Allowlist gate (deterministic)

The model's output runs straight into @lincoln/interpretation/allowlist, a hardcoded gate that rejects anything outside a tight grammar:

Allowlist responsibilities The allowlist refuses artifacts that contain engagement classes outside the engine's evaluator catalog or default-on-timeout behavior other than BLOCK. It runs as deterministic code at compile time and operates independently of model output quality.

Stage 4 — Operator validation

The parsed-and-allowlisted artifact is rendered alongside the source ROE for a commander or staff officer to review. Each field shows its paragraph_ref; clicking the field highlights the corresponding span in the source prose. The operator can edit any field — this is the moment when human judgment about the meaning of the prose lives. The model produced a hypothesis; the staff officer ratifies, corrects, or rejects it.

The validation step is also where pre-mission staffing happens. JAG can review for legal compliance. The S3 can verify zone polygons against the operations overlay. The fires officer can confirm engagement authority allocations. None of these reviewers is being asked to read the model's prompt or its raw output — they are looking at a typed artifact and the source prose, side by side, with the model's role no more visible than a syntax highlighter's.

Stage 5 — Commander signature

On approve, the artifact is canonicalized — keys lex-sorted recursively, no NaN / Infinity, no fractional whitespace — hashed (SHA-256), and signed with the issuing-node Ed25519 private key. The signature is bound to the commander's identity through the issuing authority's certificate; in production this would chain to an organizational PKI. The signed artifact is the only thing that crosses into execute time.

§4The compiled binary, structurally

What ends up on disk after a successful compile (excerpted from the demo's 06_signed_mission_artifact.json):

{
  "artifact_id": "ALPHA-2026-0502-ARTIFACT-001",
  "mission_id":  "ALPHA-2026-0502",
  "schema_version": "lincoln.mission_artifact.v1",
  "effective": { "start_iso": "...", "end_iso": "..." },
  "issuing_authority": {
    "rank": "LTC", "name": "J. Hayes",
    "unit": "6-56 ADA", "callsign": "WARHORSE 6"
  },
  "parsed_roe": {
    "positive_identification_criteria": {
      "required_confirmations": 2,
      "criteria": [
        { "id": "PID-RF",     "source": "rf",           "confidence_floor": 0.80, "paragraph_ref": "Para 3.a" },
        { "id": "PID-EOIR",   "source": "eo_ir",        "confidence_floor": 0.75, "paragraph_ref": "Para 3.b" },
        { "id": "PID-ORIGIN", "source": "intelligence", "confidence_floor": 0.70, "paragraph_ref": "Para 3.c" },
        { "id": "PID-PROFILE","source": "radar",        "confidence_floor": 0.75, "paragraph_ref": "Para 3.d" }
      ]
    },
    "engagement_authority": [
      { "threat_class": "group_1", "zone_id": "ZONE-EZ-EAST",
        "authority_level": "crew",            "weapons_control_status": "tight",
        "paragraph_ref": "Para 4.a" },
      { "threat_class": "group_2", "zone_id": "ZONE-EZ-EAST",
        "authority_level": "battle_captain",  "weapons_control_status": "tight",
        "paragraph_ref": "Para 4.b" },
      { "threat_class": "unknown",
        "authority_level": "higher_echelon",  "weapons_control_status": "tight",
        "paragraph_ref": "Para 4.c" }
    ],
    "geographic_boundaries": [
      { "id": "ZONE-EZ-EAST",      "kind": "engagement_zone",     "polygon_wgs84": [...], "paragraph_ref": "Para 2"   },
      { "id": "ZONE-CC-CORRIDOR",  "kind": "coalition_corridor",  "polygon_wgs84": [...], "paragraph_ref": "Para 6"   },
      { "id": "ZONE-NFA-FOB",      "kind": "no_fire_area",        "polygon_wgs84": [...], "paragraph_ref": "Para 8.a" }
    ],
    "escalation_procedures": [
      { "trigger": "threat_class == group_2 AND no_battle_captain_approval",
        "escalate_to": "battle_captain", "timeout_sec": 20,
        "default_on_timeout": "BLOCK",  "paragraph_ref": "Para 4.b / Para 7.a" },
      { "trigger": "intercept_geometry_intersects_corridor AND coalition_corridor_active",
        "escalate_to": "higher_echelon", "timeout_sec": 30,
        "default_on_timeout": "BLOCK",  "paragraph_ref": "Para 4.c / Para 6.a" }
    ],
    "prohibited_actions": [
      { "id": "PROHIB-CORRIDOR",   "paragraph_ref": "Para 8.a", "description": "..." },
      { "id": "PROHIB-OUTSIDE-EZ", "paragraph_ref": "Para 8.b", "description": "..." },
      { "id": "PROHIB-WCS-HOLD",   "paragraph_ref": "Para 8.c", "description": "..." },
      { "id": "PROHIB-NO-PID",     "paragraph_ref": "Para 8.d", "description": "..." }
    ]
  },
  "node_signature": "ed25519:..."
}

Every rule carries a paragraph_ref. The artifact functions as its own debug info: a decision firing at execute time cites the source paragraph through the artifact, and the staff officer locates that paragraph in the original prose.

Rule IDs (PROHIB-NFA, PROHIB-NO-PID, etc.) name evaluators in @lincoln/policy-engine/hard_blocks.ts. The artifact's prohibition list is a parameter set for those evaluators; the rule ID binds the artifact's description to the engine's evaluator. The allowlist refuses any rule ID the engine cannot evaluate.

§5Where the language model lives

PropertyFrontend (LM)Allowlist gateValidation UISigning
DeterministicNoYesYes (UI)Yes
Auditable inputSource ROEModel outputAllowlisted artifactValidated artifact
Auditable outputCandidate fieldsAccepted-or-refusedEdits + approvalSignature
Human in pathNoNoYes (operator)Yes (commander)
Failure modeWrong field valuesRefuses outputOperator catchesBoot rejects mismatch
Recoverable?Yes — re-runYes — re-promptYes — editYes — re-sign

Each LM error has a corresponding downstream gate. autonomous as an authority level is refused by the allowlist. A polygon with the wrong altitude band is caught by the operator comparing parsed result to source prose. An unknown rule ID is refused by the allowlist. Errors that reach the commander are caught at signature; an unsigned or mis-signed artifact does not boot.

§6How a commander uses this in practice

The commander does not see prompts. The commander does not see model outputs. The commander sees:

  1. The ROE document they wrote or were issued, in its original form, on the left half of the screen.
  2. A typed mission artifact on the right half, with each field showing which paragraph it came from.
  3. An edit action on each field, and a regenerate action on each section if the parse looks wrong.
  4. An approve and sign action, gated by biometric, that produces the signed binary.

The mental model is “sign the contract” — the commander reviews the contract, edits anything they disagree with, signs when satisfied. The model is plumbing they don't have to think about, and the allowlist gate is a backstop they don't have to know exists. What they sign is what executes; what executes is what the audit chain proves; what the audit chain proves is what they reviewed.

§7Limitations

Three constraints to note.