| name | verifiable-compiler |
| description | Use when the user wants Codex to build or make sustained progress on an end-to-end formally verified compiler in Lean. |
Verifiable Compiler
Use this skill for Lean-first verified compiler work. The primary artifacts are
Lean definitions, compiler functions, semantics, relations, and checked
theorems. Tests, fixtures, docs, and external tools are support
evidence only.
The default shape is: start near
the target, add one semantic abstraction layer at a time, prove the adjacent
lowering completely for the source language in scope, then move up.
Start Or Resume
- Inspect local state before planning:
git status --short (if this is not a git repo, initialize with a commit);
lakefile.lean, lean-toolchain, root modules, theorem files, tests, and
recent build scripts;
ROADMAP.md and PROGRESS_LOG.md, if present.
- Call
get_goal. If no active goal exists, create one whose objective
matches the user's concrete request in this turn. For sustained build
requests, include the requested compiler scope and the end-to-end theorem
standard. For narrower work, keep the objective scoped to that audit,
proof-debugging, refactor, architecture review, skill edit, or pass-specific
task.
- When starting or resuming sustained verified-compiler work, say explicitly
that this workflow is using
$verifiable-compiler, and remind the user
that future continuation requests should mention $verifiable-compiler.
Do this at start/resume or handoff, not in every status update.
- Use exactly two project docs by default:
ROADMAP.md: sparse checklist and current public spine.
PROGRESS_LOG.md: flat timestamped log of proofs, tests, bottlenecks,
architecture risks, deletions, and status.
- Every time the agent restarts from conversation compaction, append a short
timestamped
PROGRESS_LOG.md entry before continuing, including for narrow
follow-up tasks. Name it as a compaction resume, summarize the current
objective/checkpoint in one sentence, and keep it concise.
- Do not create feature matrices, trust ledgers, design histories, or incident
reports unless the user asks. If legacy docs exist, read them as context but
do not keep adding synchronized truth there.
Git Checkpoints
- Commit verified checkpoints as you go. After a meaningful theorem, boundary
cleanup, refactor, or audit passes its relevant build/axiom checks, create a
focused git commit before starting the next substantial proof thread.
- Keep commits honest: include only project files that belong to the verified
checkpoint, and mention the Lean build or axiom audit that passed. Do not
commit huge build logs, scratch outputs, or unrelated generated clutter.
- If the user says all current work belongs to the agent, treat the dirty tree
as owned work for staging purposes, while still keeping commits coherent and
avoiding accidental inclusion of temporary logs or secrets.
For a broad build request, the goal is not complete until concrete Lean theorem
statements connect every source-language feature in scope to the declared target
interpreter. Do not silently reinterpret a request for a source language as a
request for a convenient accepted fragment.
For any active goal that asks to complete a layer or compiler pass, do not stop
while the public theorem still takes compiler-generated evidence as an
unproved input. Treat these as blockers, not residual assumptions: generated
layout records, compilation certificates, replay certificates, whole-program
call or callee-preservation obligations, return-layout obligations, generated
label/token uniqueness tables, and proof-carrying emitted-code segments. It is
acceptable to expose fundamental semantic or resource premises such as source
acceptedness, input run/evaluation, initial-state relation, fuel/gas bounds, or
explicit code-size/no-overflow bounds, but any compiler artifact that can be
computed from the source program must either be constructed by a checked Lean
theorem or remain an explicitly unfinished goal.
Theorem-Truth Checks
Before major proof grinding, check whether the theorem is true as quantified.
Try to find small counterexamples involving arbitrary target PC, fuel-zero
states, stack height, static-context restrictions, gas observations, external
calls, revert/error outcomes, and unsupported source constructs.
If a target fact is only true for traces produced by accepted source programs,
state it over those actual traces or derive it from source-facing premises. Do
not keep a globally quantified target premise just because it is convenient for
the proof.
When a theorem is false or overbroad, fix the statement before adding wrappers,
compatibility lemmas, or local heartbeats. Record the correction in
PROGRESS_LOG.md as theorem-boundary, deletion, or architecture-risk.
Once the project freezes its public specification — hash-pinned theorem
statements, a frozen-closure checker, or a challenge/scoring regime that
measures rewrites against a fixed theorem — this workflow changes mode. A
frozen statement is an immutable interface: do not restate, weaken, or
"improve" it, even when the boundary looks fixable; rewrites and
optimizations must reprove the exact frozen statement. If a frozen statement
turns out to be false or overbroad, that is a project-level incident — report
it and get an explicit unfreeze decision from the user instead of editing
around it. Run the project's freeze gates (hash and closure checks) alongside
the usual build and axiom audits before calling any change complete.
No Unproven Compiler Paths
Do not introduce, wire in, or commit an unproven path that emits compiler output
or deployable bytecode. This includes paths named unchecked, unsafe,
artifact-only, benchmark-only, fallback, fast path, or executable shortcut.
If such a path is used by the compiler, bytecode/artifact generation, bridge
runner, benchmark harness, or user-facing validation, it must either be the
checked theorem path or have a Lean theorem proving equality/refinement to the
checked theorem path, with an axiom audit showing only standard Lean axioms.
Executable variants are allowed only when a checked equality/refinement
theorem connects them to the proof-facing definition, and all
callers that emit bytecode can be transported back to the public preservation
theorem through checked lemmas. Existing unproven output paths are blockers to
remove, prove equivalent/refining, or quarantine as non-compiler diagnostics;
do not commit new work that relies on them.
Core Strategy
Build a target-up semantic tower, one complete layer at a time:
- Choose or define the declared target interpreter and observation model.
- Define the lowest useful layer above that target.
- Add exactly one real semantic abstraction in the next higher layer.
- Give that layer syntax, semantics, wellformedness/acceptance, a relation to
the lower layer, compiler/lowering, and preservation theorem. You can add slices
to that layer one at a time, but the layer needs to be feature-complete,
not a toy version of the language, before moving on. Its feature set should
cover the whole abstraction that belongs at that layer and, as far as possible
before higher abstractions exist, match how that feature works in the source
language being targeted.
The semantics must be an independent interpreter or evaluation relation over
that layer's own syntax. Defining the layer's run/eval as "lower/compile this
program, then run the lower layer" is not a valid source semantics, except for
an explicitly named transparent adapter boundary with no new source constructs
and a recorded audit note.
The semantics must also abstract the feature this layer introduces. Do not
define a new source construct by exposing the lower representation it is meant
to hide. For example, a locals/frame layer should have a named-environment
source semantics; stack slots, layout depths, swaps, pops, or frame encodings
belong in that layer's compiler/lowering relation and proof, not in the
source interpreter used by higher layers.
- Compose the new theorem into the public spine.
- Run a brief theorem-boundary checkpoint before moving on.
- Only then add the next layer.
Example of good abstraction steps include labels over byte offsets, structured control over
jumps, locals/frames over stack slots, expressions over primitive stack code,
functions over entry labels, or objects/modules over flat functions.
Bad layers are story-shaped features (let-if-assign-return), parser fixtures,
one-off combinations (if inside for), or helper representations with no
independent semantic contract.
Before implementing a broad layer, run this checklist. This is a thinking
checkpoint, not a request to create new documents:
- Grammar frozen: every construct in scope is named, and every tempting
construct out of scope is explicitly excluded.
- Prior art checked: inspect the existing lower layer, adjacent completed
layers, and any sibling worktree or earlier implementation the user points to
before inventing a new proof route. Reuse proven theorem shapes when they
fit; record why they do not if you diverge.
- Semantics frozen: outcomes, errors, effects, divergence/fuel behavior, and
observable state are clear for the accepted subset.
- Theorem-truth checked: known counterexample shapes such as arbitrary PC,
fuel-zero target states, stack/resource exhaustion, static context, gas
observability, and external effects have been ruled out or reflected in the
theorem boundary.
- Interpreter independence checked:
run/Eval is not merely lower-layer
execution after compiling/elaborating the source; any exception is an explicit
transparent adapter boundary, not a completed compiler layer.
- Abstraction boundary checked: the layer's source semantics hides the lower
representation that its new feature abstracts. Any proof terms, layouts,
slots, continuations, frame encodings, return tokens, cleanup code, or other
lower-level machinery needed to implement the feature live in the compiler
and preservation proof, not in the source interpreter or the interface used by
higher layers.
- Lower capabilities pass through: the layer does not silently shrink the
already-verified lower language surface.
- Accepted restrictions classified: every nontrivial
Accepted/WF predicate
is checked against the requested scope. An explicit predicate name is not by
itself a justification; if it excludes lower-layer behavior because the proof
route or representation is unfinished, keep the layer incomplete unless the
user explicitly narrowed the language.
- Public theorem sketched: adjacent theorem and composed theorem have the right
shape before helper proofs begin.
- Proof interface sketched: layout, freshness, state relation, continuation,
resource, or environment assumptions are bundled when they are conceptually
one invariant.
- External/resource boundary classified: gas, fuel, code size, stack depth,
static-context restrictions, storage/account state, and external responses
are either modeled by source semantics, rejected by acceptance, or exposed as
explicit source-facing premises.
- Temporary scaffolds named: replay/certificate/helper routes have a planned
replacement theorem or are kept private.
- Public certificate boundary checked: if a theorem still takes a compiler
certificate, layout witness, replay witness, proof-carrying emitted-code
segment, or generated-label table as an input, do not call the pass complete
unless that certificate is itself generated by a checked compiler theorem or
the user explicitly accepted it as a trusted input format.
Source-Language Completeness
When the user asks for a verified compiler for a named source language or layer,
the default obligation is the complete semantics of that source language layer.
Accepted/WF may reject malformed, ill-scoped, ill-typed, or otherwise
semantically invalid programs, but it must not reject implemented source
constructs merely because they are proof-inconvenient unless the user explicitly
approved a fragment.
Before marking such a goal complete:
- Inventory the source grammar against the source semantics and compiler.
- For every construct, record one status: supported and covered by the theorem;
semantically invalid and rejected by WF/Accepted; or explicitly out of scope
by user-approved fragment boundary. Apply the same classification to every
Accepted/WF field, not only to syntax constructors.
- If the source is a named external or imported language, name the exact
reference semantics being targeted and require a checked theorem from that
semantics to the compiler source semantics; elaboration through the compiler
is not enough by itself.
- Confirm the source semantics is an independent interpreter or evaluation
relation over the source syntax. If
run/Eval delegates through compile,
lower, elaborate, toLower?, or similar, the layer is incomplete until
it has its own semantics and a checked equivalence/preservation theorem, or
the user explicitly accepts it as a transparent adapter boundary.
- Check that supported constructs include all outcomes their source semantics
admits, including errors, halts, resource failures, divergence/fuel behavior,
traces, and external observations claimed by the theorem.
- Confirm theorem statements quantify over the real source semantics, not only
over a compiler-success witness or replay certificate.
- If any source construct is missing semantics or theorem coverage, keep
working or report a blocker; do not call the compiler fully verified.
Add this source-language audit as its own audit entry in PROGRESS_LOG.md at
major layer boundaries and before declaring an end-to-end theorem complete.
Share source and target components where this reduces real proof burden:
values, arithmetic, memory/storage models, errors, traces, environments, and
external state. Do not share away the compiler obligation. Source and target
control semantics, layout, resource assumptions, and observations must remain
explicit.
It is valid for shared primitive operations to pass through the same semantics
across many layers when they are not the abstraction being introduced by that
layer. For example, arithmetic, hashing, memory/storage operations, and
explicitly shared external effects may reuse the same primitive meaning all the
way up to the source language. That exception does not apply to a feature whose
purpose is to hide a lower representation: locals should hide stack slots,
structured control should hide jump encodings, functions should hide
return-token/frame conventions, and so on.
Boundary Checkpoints
At major semantic pass boundaries, pause briefly before moving upward:
- Name the adjacent preservation theorem and the composed public spine theorem.
- Confirm syntax, semantics, acceptance/WF, lowering, relation, and
observation/outcome model exist for the accepted feature set.
- Check for silent narrowing:
Accepted/WF predicates must not exclude
supported behavior only because the proof route is unfinished.
- Check for theorem-boundary leaks: public theorem statements should not expose
lower representation details, generated certificates, replay witnesses, or
stale compatibility routes unless those are explicitly trusted inputs.
- Run the narrowest meaningful build, and
#print axioms or the local
equivalent for public theorem(s) when practical.
- Record one concise
audit entry in PROGRESS_LOG.md with theorem names,
command run, axiom result, and any remaining assumptions or unsupported
behavior.
If the checkpoint finds a shortcut, stale public route, or accepted feature
outside theorem coverage, fix it, explicitly narrow the layer with the user, or
report the blocker.
External Effects And Resources
For external effects such as calls, chain state, storage, balances, precompiles,
or environment responses, default to an open request/response protocol at the
compiler theorem boundary. Concrete world simulation is useful only when the
theorem is explicitly about that world model.
For resource-sensitive behavior such as gas, fuel, stack limits, code-size
limits, static context, memory growth, or no-overflow obligations, prefer
source-facing premises and actual-trace lemmas. A target-side runtime fact is
acceptable only when it is derived from the accepted source run, the checked
compiler output, and explicitly named resource bounds.
If a source primitive observes target resource state directly, either include
that observation in the source semantics and prove it end to end, or reject the
primitive in the accepted language. Do not patch it with future-answer or replay
oracles in the main public theorem.
Preservation Shape
The main public theorem for an adjacent pass is a same-observation theorem.
Replay certificates, traces, and local simulations are proof machinery; they
should not be the public theorem boundary once the layer is stable.
Use this shape, adapted to local names:
theorem compile_sound
(hWF : Hi.WF program)
(hCompile : Hi.compile program = lower)
(hEval : Hi.Eval program initial obs)
(hRel : StateRel initial lowerInitial) :
Exists fun lowerObs =>
And (Lo.Eval lower lowerInitial lowerObs) (ObsRel obs lowerObs) := by
...
When both semantics are executable and deterministic, this may be an equality
theorem over run; when the layer erases representation details, use ObsRel.
The important claim is that the lower semantics has the same observable program
result, not merely that some hand-written replay witness exists.
Prefer strengthened, compositional theorem statements from the beginning.
Lean theorem boundaries matter. If witness data is derived from a Prop
relation such as a source run, evaluation derivation, or preservation theorem,
the public result should usually expose ∃ or Nonempty evidence. Do not make
the public route depend on returning an arbitrary structure in Type unless
that structure is produced by computation or is passed in as explicit data.
For expression-like code generation, use an arbitrary continuation/suffix:
theorem compile_correct_aux (e : Expr) (k : Code) (s : Stack) :
run (compile e ++ k) s = run k (eval e :: s) := by
induction e generalizing k s with
| ... => ...
For statement/control layers, generalize this idea. Use whichever local shape
matches the layer:
- arbitrary code suffix;
- continuation or defunctionalized continuation;
- evaluation/control context;
- entry/destination labels;
- layout and no-wrap assumptions;
- state relation at an exact target PC, such as
RelAt;
- outcome relation for normal return, halt, revert, throw, break/continue, or
other abrupt exits.
The public proof route should be structural: sequence, context, branch, loop,
call, frame/layout, and outcome lemmas compose into the same-observation theorem.
If theorem names start encoding whole programs or feature combinations, stop and
replace them with generic recursive/compositional theorems.
If a proof is becoming a long run of nearly identical constructors or opcodes,
pause before continuing. Look for a semantic-family classifier, pass-through
lemma, source syntax traversal, or relation-preservation theorem that proves the
common case once and leaves only genuinely distinct cases as wrappers.
If several consecutive changes add wrappers, adapters, callbacks, bridge
aliases, or compatibility routes without shrinking the public assumptions, stop
and inspect the theorem boundary. Usually the right next patch is deletion or
restatement, not another adapter.
After a few helper lemmas for a new construct, inspect the next theorem
statement. If it needs many independent PC, label, freshness, layout, resource,
or environment premises, introduce a small structure or relation that names that
interface. Long premise lists are usually missing abstraction, not proof
progress.
Wherever feasible, derive full preservation proofs from accepted source runs;
treat assumed replay/certificate witnesses as temporary scaffolding, not the
public theorem boundary.
Compiler-generated evidence is not a fundamental assumption. Before declaring a
layer done, try to prove a checked constructor for every public certificate:
layout, freshness, label resolution, call-site table inclusion, PC-fit, typed
continuation boundary, and compiler-output equality. If construction is not yet
proved, the layer is not complete; log the missing constructor and keep working
or explicitly report the blocker.
Do not hide unfinished compiler evidence inside source acceptance. Accepted
may bundle source wellformedness, source semantic safety, checked resource
limits, or user-approved trusted-input contracts, but it must not contain a
compiler-generated layout, replay witness, call-site table, label-resolution
proof, procedure-body preservation proof, or semantic call oracle unless the
skill user explicitly chose proof-carrying source input as the trusted source
format. If a preservation theorem needs such evidence, either generate it with
a checked compiler theorem or keep the layer incomplete.
For recursive source features such as procedure calls, function calls,
recursive loops expressed through fuel, or mutually recursive declarations, the
default discharge route is induction on source fuel or on the relational
evaluation derivation. Do not replace this with an assumed "all callees
preserve" oracle. If a temporary all-callee/call obligation is introduced, keep
it private, give it a fuel-bounded replacement plan immediately, and do not
report the layer complete until the public theorem derives it.
Avoid brittle fusion lemmas. A lemma about if inside loop, switch inside
for, or assignment plus branch plus return is not a milestone unless it is a
private stepping stone being replaced immediately by generic seq/if/switch
loop/outcome composition. If a fused lemma remains useful, log it as a
shortcut or architecture-risk and keep it out of the public spine.
CPS is a tool, not a mandate. Raw higher-order continuations can make Lean
terms huge. Prefer a small continuation/context interface that keeps compiled
programs folded and lets induction hypotheses apply under arbitrary suffixes.
Accepted Subsets
Full preservation means full semantics for the accepted subset, but an accepted
subset is allowed only when the user requested a fragment or when the source
language definition itself is intentionally smaller than its parser or host AST.
If the user asks for a compiler for the whole source language, the accepted
subset must be source-complete except for malformed or semantically invalid
programs.
Do prove all relevant outcomes of accepted programs: success, errors, halts,
resource failures, traces, divergence/fuel behavior, and external observations
that the theorem claims to model.
Do not prove only the terminating happy path unless the theorem name and
accepted checker explicitly say that is the claim. Unsupported behavior should
be rejected by Accepted/WF, guarded by explicit theorem assumptions, or
called executable-only.
Keep these notions separate:
- parser/decoder success;
- semantic acceptance or wellformedness;
- compiler success;
- certificate checking;
- target execution success.
Accepted input must not mean "the compiler returned some." Compiler-success
theorems are useful, but they are weaker than accepted-input theorems.
Lean Blowup Rules
Treat timeouts and heartbeat explosions as architecture feedback, not merely
tactic problems.
Do not let Lean normalize whole compiled programs as a proof strategy.
Context Hygiene
Preserve context for theorem state, not logs or repo tours:
- Before every read, search, or build, name the narrow question it should
answer; avoid fresh "getting bearings" sweeps after a handoff identifies the
next target.
- Keep build output out of context: redirect noisy
lake build logs to /tmp
and inspect only error: lines plus the smallest needed neighborhood.
- Scope searches tightly. Prefer module-specific
rg, rg -n -m,
rg --files, git diff --stat, and short line windows; broad repo-wide
rg, full diffs, generated-file searches, and wide sed ranges are last
resorts.
- On resume, trust the latest handoff/progress log unless a specific line must
be checked.
- After any large tool output, retain only theorem names, file/line pointers,
failing goals, and the concrete next patch.
Prefer:
- structural lemmas over syntax/control contexts;
- one-step semantic interface lemmas;
- semantic classifiers for large opcode/operator families;
- small public wrapper theorems around imported or recursive definitions;
- explicit state/layout relations instead of massive record equalities;
- named intermediate definitions to share structure;
simp only [...] with local simp sets;
- controlled unfolding of one definition at a time;
- narrow module builds:
lake build Module.Name or lake env lean path/File.lean.
- recursive theorem families whose structurally decreasing syntax argument comes
early in the argument list, with
termination_by added before the proof grows.
Avoid:
- broad
simp_all over compiler and interpreter definitions;
- unfolding imported dispatchers across many constructors;
- one theorem that case-splits over a large instruction set and tries many
first | change ... branches;
- exposing large recursive compiler definitions as global simp rules;
- proof terms that inline every compiled instruction or generated label;
- broad imports in theorem files;
- adding local heartbeats before checking whether the theorem/interface shape is
wrong.
- continuing a proof whose statement has become a page of plumbing. Bundle the
invariant and prove the compiler supplies it.
When widening primitive operations, classify by semantic family or require a
small proof-carrying/accepted primitive interface. Prove PC/resource/state
insensitivity once per family, then use a one-line wrapper per constructor. Do
not ask Lean to rediscover the same dispatcher facts for every opcode.
Primitive Classifiers
For large primitive or opcode surfaces, introduce a small semantic-family API
before broadening the source layer. This API should be a proof boundary, not a
second unverified semantics.
Documentation And Logs
Code and theorem statements are the source of truth. Before reporting status,
inspect the actual theorem names, statements, public imports, and build output.
ROADMAP.md should stay sparse:
# Roadmap
## Public Spine
Accepted AST -> LayerA -> LayerB -> Target interpreter
## Next Layer
- [ ] Interface: syntax, semantics, WF, relation
- [ ] Theorem-truth check and external/resource boundary
- [ ] Complete source-faithful feature set for this layer
- [ ] Lowering function
- [ ] Adjacent same-observation theorem
- [ ] Composed public theorem
- [ ] Boundary checkpoint
PROGRESS_LOG.md is append-only and flat:
- 2026-05-12 18:17:26 - proof - proved `CompilerPreservation.block` and `compile_whole_program_sound_of_run`; command `lake build`; result green.
- 2026-05-12 18:20:00 - architecture-risk - primitive widening proof unfolds full opcode dispatcher; replace with semantic family interface before adding more ops.
Use tags such as proof, test, audit, bottleneck,
theorem-boundary, architecture-risk, shortcut, consolidation,
deletion, and incident. For risks and shortcuts, name the artifact, why it
is risky, and the generic theorem/interface that should replace it.
Keep logs current, not just append-heavy. When a bottleneck, shortcut, or risk
is resolved or superseded, add a short entry saying so and name the replacing
theorem or interface. Do not leave stale warnings that still read as active.
Git Preservation
Use git to preserve meaningful theorem-bearing states. Commit only coherent
milestones, preferably green:
- initial Lean package setup;
- first target-reaching theorem;
- new public layer or theorem boundary;
- accepted-language/theorem-boundary change;
- byte encoder or real-machine bridge;
- deletion of obsolete fixture/story routes;
- audited stable proof milestone.
Never revert user changes. Before pausing or finishing substantial work, run
git status --short and make the handoff state clear.
Anti-Patterns
Stop and repair the architecture if any of these appear:
- full high-level language first, proofs later;
- theorem ends at an IR while the claim says end-to-end;
- special theorems for
if inside loop or other combinations;
- fused feature lemmas become public proof routes instead of temporary private
scaffolding;
- parser helper recognizes a whole story instead of independent constructs;
- semantic classifier or helper interpreter used as if it were the real target
without an equality/refinement theorem;
- source semantics changed to match a compiler bug;
- broad public imports retain obsolete compiler routes;
- concrete external-world simulation is used where an open protocol is the real
theorem boundary;
- observed target resources such as gas are patched by replay/future-answer
oracles instead of source semantics, acceptance rejection, or explicit
source-facing premises;
- wrapper, adapter, callback, or compatibility-route churn continues without
reducing public assumptions;
- proof relies on
sorry, admit, new axiom, unsafe, partial, or
proof-critical external assumptions without excluding them from the claim;
- tests or external review are treated as verification;
- Lean timeout is answered by adding more feature code.
Completion Gate
Do not call the compiler verified because tests pass, the compiler runs, or a
scaffold theorem exists.
Before reporting a verified milestone:
- Inspect the accepted compiler path.
- Name the exact top theorem(s).
- Run the narrowest meaningful build command, and full build when practical.
- Run
#print axioms or the local equivalent on public top theorem(s) when
practical.
- Scan for
sorry, admit, axiom, unsafe, and partial.
- Check public imports for obsolete fixture/story/legacy routes.
- Check public theorem arguments for compiler-generated certificates or layout
evidence. They must be discharged by checked constructors, be private helper
inputs, or be explicitly named as trusted external inputs approved by the
user. Otherwise keep working.
- Inspect
Accepted/WF records used by the public theorem. They must not
smuggle in compiler-output equality, label layout, replay certificates,
call/return layout, generated-token uniqueness, or semantic preservation
oracles. They also must not exclude lower-layer capabilities merely because
the representation or proof is unfinished. If they do, split those fields out
and discharge them, explicitly narrow the requested source language with the
user, or keep the milestone incomplete.
- Check that resource and external-effect premises are source-facing or
actual-trace-derived, not globally quantified target facts.
- State remaining assumptions and unsupported features plainly.
The goal is complete only when every source-language feature in the requested
scope has a checked path from trusted input or AST through acceptance,
semantics, compiler/lowering, target interpreter, and theorem. If a fragment was
explicitly requested, say so in the theorem names or surrounding API and audit
the fragment boundary. Otherwise report the current work as a theorem-bearing
milestone and keep working on the missing source semantics.
References
Load only when useful:
references/verified-compiler-patterns.md: theorem-boundary patterns and
classic verified-compiler references.
references/process-lessons.md: earlier process failures to avoid.