For engineers

How an engagement actually runs

Written for the engineers who will operate this, not for the people who sign the contract. If you are evaluating us, this is the page to send to your platform team.

Getting started

An engagement begins read-only. We take source and, where available, captured input and output from the running system. Nothing is written back to your estate at any point.

# 1 — build a typed graph of the estate
lightyr graph build --source ./estate --out knowledge/graph.json

# 2 — measure what your existing corpus actually reaches
lightyr coverage report --program CBTRN02C --corpus ./captured

# 3 — run one bounded proof cell end to end
lightyr factory run --work-order work-orders/intcalc.json

Step 2 is usually the one that changes the conversation. It answers a question nobody has asked before: how much of this program's decision surface has any test you own ever exercised.

Work orders

A work order is a contract, not a prompt. It declares the paths an agent may touch, the slice of the graph it may read, the gates that must pass, and the timeouts. Scope is a precondition — an agent cannot widen it at run time.

{
  "id": "intcalc-repair",
  "allowed_paths": ["src/interest/**"],
  "graph_scope": ["CBACT04C", "TCATBAL"],
  "gates": [
    { "id": "unit",    "expose_output_to_builder": true  },
    { "id": "holdout", "expose_output_to_builder": false }
  ]
}

expose_output_to_builder defaults to false and must be a real JSON boolean — a quoted "false" is rejected rather than coerced, because in Python it would evaluate as true and silently open the holdout boundary.

Verdicts and exit codes

Three verdicts, and the third is the one most tools do not have.

VerdictExitMeaning
faithful0Every compared field matched under the equivalence policy.
failed1A real divergence, classified by cause and located by field.
indeterminate2Nothing was verified. An operator error, never routed back to a builder as a defect.

The separation of 1 and 2 matters operationally. A failed run means the candidate is wrong. An indeterminate run means the harness could not tell, which is a configuration problem and must not be handed to an agent as "your code is broken."

Accepted differences

Some differences are genuinely meaningless — a run timestamp, a padding convention. Each permitted one is a controlled entry with a written reason, a named owner, and a review date. The validator fails closed on a missing owner, an expired review, an undocumented rule, or a rule whose text no longer matches the code.

lightyr validate-normalizations --ledger spec/normalizations.json

# NORMALIZATION_REVIEW_EXPIRED:fixed-width-padding:2026-02-22
# NORMALIZATION_GOVERNANCE_MISSING:decimal-canonical:owner
# NORMALIZATION_RUNTIME_MISMATCH:copybook-filler:behavior

Prefer a shape-preserving normalization over an outright ignore. Ignoring a timestamp lets a candidate that never writes one pass; collapsing its digits still asserts format, length and punctuation.

Evidence classes

Every artifact carries a class, and the class governs what may be claimed from it.

ClassSourceCan close an equivalence gate
simulatedSynthetic replay of the machineryno
local_observedReal execution, local environmentno
recordedReplay of a prior captureno
zos_observedCaptured from the authorised baselineyes

Replaying a live capture yields recorded, never live. Weak evidence cannot be promoted by round-tripping it through a mechanism, and that demotion is enforced in code rather than convention.

Coverage

We measure arc coverage, not statement coverage. A corpus can execute every line of a validation paragraph and never once take the reject branch — and reject branches are where modernization defects survive to go-live.

Arcs are classified into three populations with three different owners, because blending them produces a number that sends teams to chase the wrong work:

PopulationOwnerAcceptance
Businessthe harnessoutput matches legacy under the policy
ResilienceNFR suitefails safe, no partial commit, alert raised
Infrastructureout of scopedocumented, so it is not re-raised

Fidelity coverage is reported over business arcs only. Where the corpus misses one, we generate the input that reaches it — then run it through the legacy system first, because a synthetic case whose expected output a human decided is not evidence.

CLI reference

lightyr graph build         # typed estate graph from source
lightyr graph capabilities  # technology readiness and gate status
lightyr coverage report     # arc coverage for a program
lightyr coverage close-gaps # synthesize inputs for unreached arcs
lightyr compare             # differential run, emits a receipt
lightyr validate-normalizations
lightyr factory run         # one bounded work cell
lightyr portfolio-plan      # schedule non-conflicting cells
lightyr audit verify        # replay the hash-chained ledger

CI integration

The Verdict Engine is designed to be a gate, so exit codes route directly. Treat 2 as a pipeline error rather than a test failure — it means the run proved nothing.

- name: Differential verification
  run: |
    lightyr compare --expected ref/ --actual out/ --report r.json
    # 0 faithful · 1 divergent · 2 indeterminate

- name: Reject runs that mutate tracked evidence
  run: git diff --exit-code

That second step is worth copying whatever tooling you use. It asserts that a verification run is side-effect free, so a suite can never quietly rewrite the evidence it is checking against.

The evidence record

Every capability ships with a published record: what it delivered, what evidence supports it, and — the part that matters — what it explicitly does not claim. Generated from the repository, so the record cannot drift from the code.

lightyr milestones build     # regenerate the record from source
lightyr milestones verify    # catalog, hashes and boundaries
lightyr receipt-claims       # reject literal promotion anywhere in the tree
lightyr scripts              # every entry point owned, roled and twinned

Each boundary statement is deliberately unflattering. One records that ASE catalog, rows, replication and transactions are fixtures rather than live observations. If you are evaluating us, read the boundaries before the deliverables.

No documentation sections match that filter.

Trust

Built for organisations that cannot take a risk on us

We are asking a regulated business to let software work unattended on its most sensitive code. Everything here assumes you will not take that on trust after a demo.

Read-only by default

Collection is read-only. Live capture carries operator attestation and verified TLS with certificate and hostname validation, and writes nothing back to your estate.

Evidence cannot be laundered

Simulated evidence cannot satisfy an equivalence claim. Replaying a live capture yields recorded, never live — weak evidence cannot be promoted by round-tripping it.

Nothing runs loose

Checks run in a digest-pinned container with a read-only host bind. Work orders are signed, expiring, and replay-safe. Agent identities are short-lived and action-scoped.

Every step is on the record

Every event binds actor, action, subject, policy decision and evidence receipt to an exact graph identity. A reviewer can replay the evidence behind any release decision.

Your data stays yours

Comparison output contains real record values by design — that is what makes it evidence. Classification, access control and retention on run directories are agreed before the first capture, not after.

No borrowed code in the core

The verification core has zero external runtime dependencies. For a tool whose product is evidence, the dependency tree is part of what your auditor has to trust.

What the record shows

Four questions, answered without the original engineers

What changed, exactly?brokered patch + workspace hash
What proved it?gate result + output digest
What was the agent told?redacted diagnosis envelope
Can we replay it?content-addressed run receipt

Replayable next quarter, by someone who was not in the room when it ran.

Not finding it

These docs describe the shape. Your estate decides the detail.

Copybook dialects, screen conventions and clock injection all differ by site. Send us a program and we will tell you what the harness would need.

Ask an engineer