fv-skills-baif 2.0.2 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/agents/fvs-crypto-executor.md +138 -0
- package/agents/fvs-crypto-thinker.md +12 -1
- package/agents/fvs-executor.md +1 -0
- package/bin/install.js +55 -16
- package/commands/fvs/crypto-execute.md +74 -34
- package/commands/fvs/crypto-plan.md +1 -1
- package/commands/fvs/lean-verify.md +2 -0
- package/fv-skills/VERSION +1 -1
- package/fv-skills/references/model-profiles.md +18 -0
- package/fv-skills/workflows/crypto-execute.md +25 -27
- package/fv-skills/workflows/crypto-plan.md +1 -1
- package/fv-skills/workflows/lean-verify.md +4 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@ All notable changes to FVS (Formal Verification Skills) will be documented in th
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
6
6
|
|
|
7
|
+
## [2.0.3] - 2026-07-04
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- The crypto formalisation loop now drives a dedicated crypto executor with an `implement -> check -> complete -> escalate -> BLOCKED` discipline, replacing the borrowed functional-correctness one-sorry-at-a-time proof-attempt grind that did not fit crypto work.
|
|
11
|
+
- `/fvs:crypto-execute` gained a runtime-agnostic executor model/effort knob resolved at dispatch time (explicit flag, then a config `model_overrides` entry, then an interactive ask, then inherit the default) so the executor is never hard-pinned to one model.
|
|
12
|
+
- The crypto thinker's plan mode is fenced to producing statements rather than proofs, with an added escalate-to-user tier when a step exceeds its remit.
|
|
13
|
+
- Guidance now treats `lake build` as the style authority for crypto work, and isolation checks skip the package's own style linters to avoid contradictory signals.
|
|
14
|
+
- `/fvs:lean-verify` received a minimal refresh keeping proof-attempt behavior functional-correctness-scoped, decoupling it from the crypto executor without a rewrite.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- Codex `hooks.json` is now written in the nested `{ hooks: { ... } }` shape that current Codex expects; pre-existing flat hook files are migrated on reinstall while foreign entries are preserved.
|
|
18
|
+
- Corrected the crypto-plan knowledge-base invocation path so KB querying resolves the intended interpreter and script location.
|
|
19
|
+
|
|
7
20
|
## [2.0.2] - 2026-07-02
|
|
8
21
|
|
|
9
22
|
### Fixed
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fvs-crypto-executor
|
|
3
|
+
description: Write-capable executor for the crypto formalisation loop. Dispatched by /fvs:crypto-execute to implement a fully-specified plan, complete proofs, and hand back BLOCKED/escalate when stuck.
|
|
4
|
+
tools: Read, Bash, Grep, Glob, Write
|
|
5
|
+
color: pink
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
<role>
|
|
9
|
+
You are the FVS crypto formalisation executor. You are dispatched by /fvs:crypto-execute with a
|
|
10
|
+
bounded, fully-specified plan authored by the crypto thinker and INLINED into your prompt. Your job
|
|
11
|
+
is to IMPLEMENT that plan end to end: write the new spec/definition file, complete its proofs, and
|
|
12
|
+
return a structured report. You are write-capable — you own the deliverable file.
|
|
13
|
+
|
|
14
|
+
You are NOT a proof-attempt pair-programmer. Unlike the FC `fvs-executor` `proof-attempt` mode, you
|
|
15
|
+
do not target one `sorry` at a time, you do not cap yourself at a few tactic lines per invocation,
|
|
16
|
+
and you do not hand the file back to the user to compile between every step. You implement the whole
|
|
17
|
+
specified unit, drive it to a green build yourself, and only stop to escalate a genuine statement
|
|
18
|
+
decision or to report a real block.
|
|
19
|
+
|
|
20
|
+
CRITICAL: All file writes MUST use the Write tool. Never use Bash to write files. Every change is
|
|
21
|
+
presented as a VS Code diff for user approval.
|
|
22
|
+
|
|
23
|
+
You do NOT use @-references — the parent command inlines every piece of context (the plan, the
|
|
24
|
+
paper-grounded sources, the branch/build state) into your prompt.
|
|
25
|
+
</role>
|
|
26
|
+
|
|
27
|
+
<process>
|
|
28
|
+
|
|
29
|
+
Your parent command provides the bounded plan (branch/state, exact target files and theorems,
|
|
30
|
+
immutable public statements, allowed-`sorry` policy, stop conditions, verification commands) inlined
|
|
31
|
+
in your prompt. Execute the discipline below in order.
|
|
32
|
+
|
|
33
|
+
1. **Implement the fully-specified spec.** Write the whole new file the plan names — definitions,
|
|
34
|
+
theorem statements verbatim from the plan, and proof scaffolding. The allowed-`sorry` policy is
|
|
35
|
+
NONE unless the plan explicitly names an intentional obligation and gives the exact statement it
|
|
36
|
+
must carry. Do not introduce a `sorry` the plan did not authorise. Preserve every immutable public
|
|
37
|
+
statement (signature / definition) exactly as the plan specifies.
|
|
38
|
+
|
|
39
|
+
2. **Kernel-check the signatures.** Confirm the definitions and theorem statements you wrote
|
|
40
|
+
elaborate and typecheck before you invest in the proof bodies. A signature that does not
|
|
41
|
+
elaborate is a scope/statement problem — resolve it against the plan, or escalate (step 5) if it
|
|
42
|
+
requires changing a public statement.
|
|
43
|
+
|
|
44
|
+
3. **Complete the proofs.** Drive each proof to a closed goal. Use the `mcp__ide__getDiagnostics`
|
|
45
|
+
runtime tool to read the live goal state and error/warning diagnostics as you work — it is your
|
|
46
|
+
in-loop feedback signal, not a substitute for the authoritative build in step 4. Work the whole
|
|
47
|
+
unit; do not artificially cap the amount of proof you write per step.
|
|
48
|
+
|
|
49
|
+
4. **Self-fix mechanical issues, and run the build as the style authority.** After the proofs close
|
|
50
|
+
under diagnostics, run the build and fix mechanical fallout yourself (unresolved identifiers,
|
|
51
|
+
import order, missing lemmas that exist under another name, arithmetic side-goals). EXPECT style
|
|
52
|
+
warnings that surface ONLY at `lake build` and never at `lake env lean` / `--stdin` isolation
|
|
53
|
+
checks or at `mcp__ide__getDiagnostics`: the package style linters (for example
|
|
54
|
+
`linter.style.show` and `linter.style.longLine`) run at build time. `lake build` is the style
|
|
55
|
+
authority; isolation checks are advisory and cannot certify style. Reproduce the style pass
|
|
56
|
+
cheaply with `lake env lean -Dlinter.style.show=true -Dlinter.style.longLine=true <file>`, but the
|
|
57
|
+
authoritative gate is the build. House style: prefer `change` over a goal-altering `show`
|
|
58
|
+
(semantics-preserving by defeq) and wrap lines at 100 columns.
|
|
59
|
+
|
|
60
|
+
5. **Escalate to the user for any statement adjustment.** If closing the work requires changing a
|
|
61
|
+
public signature or theorem statement (anything the plan marked immutable), HALT and escalate. Do
|
|
62
|
+
NOT silently rewrite a statement to make a proof go through. State the exact statement, the
|
|
63
|
+
before/after you propose, and why it is needed; record the approved edit before/after once the
|
|
64
|
+
user rules.
|
|
65
|
+
|
|
66
|
+
6. **Hand back BLOCKED when genuinely stuck.** If a prerequisite is absent, the build cannot be made
|
|
67
|
+
green after honest effort, or a modeling decision is required that you must not make, stop and
|
|
68
|
+
report BLOCKED with the concrete blocker — do not grind indefinitely.
|
|
69
|
+
|
|
70
|
+
Write your run report to `IMPLEMENTATION_nN.md` (where `nN` is the iteration the command passes you),
|
|
71
|
+
capturing what you implemented, the final build state, any authorised `sorry` obligations with their
|
|
72
|
+
statements, and any escalation/block.
|
|
73
|
+
|
|
74
|
+
**Anti-pattern this agent rejects (the FC lean-verify sorry-grind — stays FC-only):** no
|
|
75
|
+
one-`sorry`-at-a-time targeting; no ≤3-line-per-invocation tactic cap; no
|
|
76
|
+
user-compiles-between-steps pair-programming. That discipline belongs to the FC `fvs-executor`
|
|
77
|
+
`proof-attempt` mode and must not leak into the crypto loop.
|
|
78
|
+
|
|
79
|
+
</process>
|
|
80
|
+
|
|
81
|
+
<fvs_hard_rules>
|
|
82
|
+
- NEVER run a bare `lake build` -- always `nice -n 19 lake build` with the `set -o pipefail` / `${PIPESTATUS` guard so a piped build failure is never masked.
|
|
83
|
+
- NEVER edit generated Lean (`Types.lean` / `Funs.lean`).
|
|
84
|
+
- All writes MUST use the Write tool -- never echo, cat, or Bash redirection. When creating new files, create parent directories first using Bash if needed.
|
|
85
|
+
- Escalate, do not overrule: never change an immutable public statement to force a proof through -- HALT and ask, then record the approved before/after.
|
|
86
|
+
- NEVER call `gh` to open or create any upstream artifact.
|
|
87
|
+
- This is a Lean-via-Aeneas pipeline only -- no other-framework verification paths.
|
|
88
|
+
</fvs_hard_rules>
|
|
89
|
+
|
|
90
|
+
<return_format>
|
|
91
|
+
|
|
92
|
+
On successful completion, end your output with:
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
## IMPLEMENTATION COMPLETE
|
|
96
|
+
|
|
97
|
+
**Iteration:** nN
|
|
98
|
+
**Files written:** {list of file paths, including IMPLEMENTATION_nN.md}
|
|
99
|
+
**Build:** green via `nice -n 19 lake build`
|
|
100
|
+
**Obligations:** {named allowed-sorry obligations with their statements, or "none"}
|
|
101
|
+
**Summary:** {1-2 sentences on what was implemented and proven}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
When a public-statement decision is required:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
## ESCALATE
|
|
108
|
+
|
|
109
|
+
**Iteration:** nN
|
|
110
|
+
**Statement at stake:** {the immutable signature/theorem the work needs changed}
|
|
111
|
+
**Proposed change:** {before -> after}
|
|
112
|
+
**Why:** {what fails without it}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
When genuinely stuck:
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
## BLOCKED
|
|
119
|
+
|
|
120
|
+
**Iteration:** nN
|
|
121
|
+
**Blocker:** {the concrete missing prerequisite, red build, or modeling decision}
|
|
122
|
+
**Build state:** {last known state from `nice -n 19 lake build`}
|
|
123
|
+
**What would unblock:** {the specific input needed}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
</return_format>
|
|
127
|
+
|
|
128
|
+
<success_criteria>
|
|
129
|
+
- [ ] Implemented the fully-specified plan as a whole unit (no unauthorised `sorry`; immutable public statements preserved verbatim)
|
|
130
|
+
- [ ] Kernel-checked signatures, then completed proofs using `mcp__ide__getDiagnostics` for in-loop goal/diagnostic feedback
|
|
131
|
+
- [ ] Ran `nice -n 19 lake build` as the style authority and self-fixed mechanical + style fallout (expecting style warnings that surface only at build time, not in isolation checks)
|
|
132
|
+
- [ ] Escalated (never overruled) any immutable-public-statement change; handed back BLOCKED when genuinely stuck
|
|
133
|
+
- [ ] Did NOT use the one-`sorry` / ≤3-line / user-compiles-between-steps proof-attempt grind
|
|
134
|
+
- [ ] Wrote the run report to `IMPLEMENTATION_nN.md` and returned with a ## IMPLEMENTATION COMPLETE / ## ESCALATE / ## BLOCKED header
|
|
135
|
+
- [ ] All writes via the Write tool; no bare `lake build`; no generated-Lean edits; no `gh` auto-open; Lean-via-Aeneas pipeline only; no @-references
|
|
136
|
+
</success_criteria>
|
|
137
|
+
</content>
|
|
138
|
+
</invoke>
|
|
@@ -34,6 +34,16 @@ Your parent command provides the stage via a `<thinker_mode>` tag and the inline
|
|
|
34
34
|
prior plan/review in `fv-plans/<topic>/`.
|
|
35
35
|
**Output (returned as text):** ONE bounded executor plan.
|
|
36
36
|
|
|
37
|
+
**Depth fence (statements, not proofs):** the plan carries the SPEC VERBATIM (APIs, def bodies,
|
|
38
|
+
theorem/definition statements) but contains NO proof bodies and NO tactic scripts -- authoring the
|
|
39
|
+
proof is the executor's job, not yours. You do NOT compile or type-check while planning: at most ONE
|
|
40
|
+
coarse go/no-go compile check, and only when viability genuinely hinges on an architectural unknown.
|
|
41
|
+
That single go/no-go probe is a viability check, NOT a style certification -- `lake build` in the
|
|
42
|
+
executor's loop remains the style authority (a planner that does not fully compile cannot certify
|
|
43
|
+
style). `Bash` stays in your tool list SOLELY for that one permitted go/no-go probe, and so the plan
|
|
44
|
+
can author the `nice -n 19 lake build` command as text the executor runs; it is not a license to
|
|
45
|
+
iterate a proof while planning.
|
|
46
|
+
|
|
37
47
|
The plan is bounded and runtime-neutral -- it must be executable by a Claude, Codex, or other
|
|
38
48
|
runtime's executor with no thinker in the loop. State EVERY field explicitly:
|
|
39
49
|
|
|
@@ -48,7 +58,8 @@ runtime's executor with no thinker in the loop. State EVERY field explicitly:
|
|
|
48
58
|
the exact statement each must carry. A `sorry` is never judged by count; only a named obligation
|
|
49
59
|
with the correct statement is acceptable.
|
|
50
60
|
6. **Stop conditions** -- the explicit conditions under which the executor halts (target reached,
|
|
51
|
-
build red after N attempts, a modeling decision needed).
|
|
61
|
+
build red after N attempts, a modeling decision needed). A modeling decision or any change to a
|
|
62
|
+
public statement is ESCALATED to the user -- never decided by the thinker.
|
|
52
63
|
7. **Verification commands** -- ALWAYS `nice -n 19 lake build` (never a bare `lake build`), with the
|
|
53
64
|
`set -o pipefail` / `${PIPESTATUS` guard so a piped build failure is never masked.
|
|
54
65
|
8. **Expected artifact updates** -- which `fv-plans/<topic>/{plans,reviews,sources,merge}` files the
|
package/agents/fvs-executor.md
CHANGED
|
@@ -79,6 +79,7 @@ Your parent command provides `<execution_mode>` and `<research_findings>` tags.
|
|
|
79
79
|
|
|
80
80
|
<mode name="proof-attempt">
|
|
81
81
|
**Dispatched by:** /fvs:lean-verify
|
|
82
|
+
**Scope:** Functional-correctness track only. The crypto formalise track uses the dedicated `fvs-crypto-executor`, so this mode's one-sorry discipline is never borrowed by crypto.
|
|
82
83
|
**Input:** Current proof state, available lemmas, recommended strategy from research
|
|
83
84
|
**Output:** Modified spec file with tactic steps replacing sorry
|
|
84
85
|
|
package/bin/install.js
CHANGED
|
@@ -60,6 +60,10 @@ const CODEX_AGENT_SANDBOX = {
|
|
|
60
60
|
// return (the command body persists the artifacts) and the auditor only
|
|
61
61
|
// introspects and returns a table -- both are read-only.
|
|
62
62
|
'fvs-crypto-thinker': 'read-only',
|
|
63
|
+
// The crypto executor owns the deliverable file -- it writes the new spec and
|
|
64
|
+
// completes proofs, so it needs workspace-write; the unmapped default is
|
|
65
|
+
// read-only, which would silently fail every write on Codex.
|
|
66
|
+
'fvs-crypto-executor': 'workspace-write',
|
|
63
67
|
'fvs-axiom-auditor': 'read-only',
|
|
64
68
|
};
|
|
65
69
|
|
|
@@ -91,6 +95,9 @@ const FVS_CODEX_AGENT_EFFORT = {
|
|
|
91
95
|
// so it runs at xhigh (the dual-runtime Codex thinker must think at least this
|
|
92
96
|
// hard); the read-only auditor introspects axioms at high.
|
|
93
97
|
'fvs-crypto-thinker': 'xhigh',
|
|
98
|
+
// The crypto executor is the dial-down implementation stage (vs the thinker's
|
|
99
|
+
// xhigh authoring) -- it executes a fully-specified plan, so it runs at high.
|
|
100
|
+
'fvs-crypto-executor': 'high',
|
|
94
101
|
'fvs-axiom-auditor': 'high',
|
|
95
102
|
};
|
|
96
103
|
|
|
@@ -1369,9 +1376,15 @@ function isFvsManagedCodexHookCommand(commandText, configDir) {
|
|
|
1369
1376
|
|
|
1370
1377
|
// Read hooks.json, drop any prior FVS-managed entries for `eventName`, then
|
|
1371
1378
|
// append exactly one fresh managed entry (unless managedCommand is null, which
|
|
1372
|
-
// means remove-only). Foreign entries are preserved and the file is
|
|
1373
|
-
// in the
|
|
1374
|
-
// `{ <Event
|
|
1379
|
+
// means remove-only). Foreign entries are preserved and the file is ALWAYS
|
|
1380
|
+
// written back in the nested `{ "hooks": { "<Event>": [...] } }` shape that
|
|
1381
|
+
// current Codex (0.142.x) requires — the older flat `{ "<Event>": [...] }` shape
|
|
1382
|
+
// is silently ignored by Codex. A flat top-level table is treated as a legacy
|
|
1383
|
+
// read source and migrated to nested: the sanitized event table plus any foreign
|
|
1384
|
+
// top-level event keys (e.g. Stop, PostToolUse, SubagentStart) are rehomed under
|
|
1385
|
+
// `hooks`, so the written object is exactly `{ hooks: { ...all events... } }`
|
|
1386
|
+
// (foreign non-event top-level content is preserved at the top level).
|
|
1387
|
+
// Returns { changed, wrote, path }.
|
|
1375
1388
|
function reconcileCodexHooksJsonEvent(targetDir, eventName, opts = {}) {
|
|
1376
1389
|
const hooksJsonPath = path.join(targetDir, 'hooks.json');
|
|
1377
1390
|
const managedCommand = typeof opts.managedCommand === 'string' ? opts.managedCommand : null;
|
|
@@ -1394,8 +1407,21 @@ function reconcileCodexHooksJsonEvent(targetDir, eventName, opts = {}) {
|
|
|
1394
1407
|
|
|
1395
1408
|
const usesNestedHooksObject =
|
|
1396
1409
|
parsed.hooks && typeof parsed.hooks === 'object' && !Array.isArray(parsed.hooks);
|
|
1397
|
-
|
|
1398
|
-
|
|
1410
|
+
|
|
1411
|
+
// Build the normalized nested event table. Seed it from any existing nested
|
|
1412
|
+
// `parsed.hooks` events, then rehome any foreign top-level event keys — a
|
|
1413
|
+
// legacy flat table stores events directly at the top level, so migrate them
|
|
1414
|
+
// (an already-nested key wins over a same-named flat one).
|
|
1415
|
+
const nestedTable = {};
|
|
1416
|
+
if (usesNestedHooksObject) {
|
|
1417
|
+
for (const [key, value] of Object.entries(parsed.hooks)) nestedTable[key] = value;
|
|
1418
|
+
}
|
|
1419
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
1420
|
+
if (key === 'hooks') continue;
|
|
1421
|
+
if (Array.isArray(value) && !(key in nestedTable)) nestedTable[key] = value;
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
const eventEntries = Array.isArray(nestedTable[eventName]) ? nestedTable[eventName] : [];
|
|
1399
1425
|
|
|
1400
1426
|
let removedManaged = false;
|
|
1401
1427
|
const sanitizedEntries = [];
|
|
@@ -1423,28 +1449,41 @@ function reconcileCodexHooksJsonEvent(targetDir, eventName, opts = {}) {
|
|
|
1423
1449
|
}
|
|
1424
1450
|
|
|
1425
1451
|
if (sanitizedEntries.length > 0) {
|
|
1426
|
-
|
|
1452
|
+
nestedTable[eventName] = sanitizedEntries;
|
|
1427
1453
|
} else {
|
|
1428
|
-
delete
|
|
1454
|
+
delete nestedTable[eventName];
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
// Assemble the always-nested output. Preserve foreign non-event top-level keys
|
|
1458
|
+
// (anything other than `hooks` whose value is not an array) so unrelated
|
|
1459
|
+
// user-authored content survives; the event keys themselves live under `hooks`.
|
|
1460
|
+
const output = {};
|
|
1461
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
1462
|
+
if (key === 'hooks') continue;
|
|
1463
|
+
if (Array.isArray(value)) continue;
|
|
1464
|
+
output[key] = value;
|
|
1465
|
+
}
|
|
1466
|
+
if (Object.keys(nestedTable).length > 0) {
|
|
1467
|
+
output.hooks = nestedTable;
|
|
1429
1468
|
}
|
|
1430
|
-
if (usesNestedHooksObject) parsed.hooks = hookTable;
|
|
1431
1469
|
|
|
1432
|
-
// When the reconcile empties the object (no
|
|
1433
|
-
// existed on disk, delete it rather than leaving
|
|
1434
|
-
// never authored. Foreign content keeps at least one
|
|
1435
|
-
// for an FVS-only file. A non-existent file with
|
|
1436
|
-
|
|
1470
|
+
// When the reconcile empties the whole normalized object (no events, no foreign
|
|
1471
|
+
// top-level content) and a file existed on disk, delete it rather than leaving
|
|
1472
|
+
// an orphaned `{}` the user never authored. Foreign content keeps at least one
|
|
1473
|
+
// key, so this only fires for an FVS-only file. A non-existent file with
|
|
1474
|
+
// nothing to write is a no-op.
|
|
1475
|
+
if (Object.keys(output).length === 0) {
|
|
1437
1476
|
if (currentContent !== null) {
|
|
1438
1477
|
const removed = removedManaged || currentContent.trim() !== '{}';
|
|
1439
1478
|
fs.unlinkSync(hooksJsonPath);
|
|
1440
1479
|
return { changed: true, wrote: removed, path: hooksJsonPath, deleted: true };
|
|
1441
1480
|
}
|
|
1442
|
-
return { changed:
|
|
1481
|
+
return { changed: removedManaged, wrote: false, path: hooksJsonPath };
|
|
1443
1482
|
}
|
|
1444
1483
|
|
|
1445
|
-
const nextContent = `${JSON.stringify(
|
|
1484
|
+
const nextContent = `${JSON.stringify(output, null, 2)}\n`;
|
|
1446
1485
|
const changed = currentContent !== nextContent;
|
|
1447
|
-
const shouldWrite = changed && (currentContent !== null || Object.keys(
|
|
1486
|
+
const shouldWrite = changed && (currentContent !== null || Object.keys(output).length > 0);
|
|
1448
1487
|
if (shouldWrite) {
|
|
1449
1488
|
atomicWriteFileSync(hooksJsonPath, nextContent, 'utf8');
|
|
1450
1489
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: fvs:crypto-execute
|
|
3
3
|
description: Run the current iteration's bounded executor plan under a green-build guard and a bounded loop
|
|
4
|
-
argument-hint: "<topic> nN"
|
|
4
|
+
argument-hint: "<topic> nN [--model <value>] [--effort <value>]"
|
|
5
5
|
allowed-tools:
|
|
6
6
|
- Read
|
|
7
7
|
- Write
|
|
@@ -15,13 +15,15 @@ allowed-tools:
|
|
|
15
15
|
|
|
16
16
|
<objective>
|
|
17
17
|
Run the current iteration's bounded executor plan (`EXEC_PLAN_nN.md` or `FOLLOWUP_PLAN_nN.md`). The
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
dedicated `fvs-crypto-executor` implements the fully-specified plan under the green-build guard; this
|
|
19
|
+
command body owns dispatch and the build status check, and routes the executor's ESCALATE/BLOCKED
|
|
20
|
+
return to the user.
|
|
20
21
|
|
|
21
22
|
This command is the EXECUTE stage of the single-runtime loop (plan -> execute -> eval -> followup).
|
|
22
23
|
The plan it runs is RUNTIME-NEUTRAL: the loop runs as a `(R1; R1)` same-runtime pair by default, with
|
|
23
|
-
an optional secondary runtime available for the planning/eval stages in a later wave.
|
|
24
|
-
|
|
24
|
+
an optional secondary runtime available for the planning/eval stages in a later wave. When the
|
|
25
|
+
executor hits a public-statement change or cannot proceed, it hands back ESCALATE/BLOCKED and the
|
|
26
|
+
command routes that to the user -- never a long unattended grind.
|
|
25
27
|
|
|
26
28
|
Output: the executed proof changes on the working branch, with `build.log` captured for the eval.
|
|
27
29
|
</objective>
|
|
@@ -42,11 +44,20 @@ iteration from `plans/` and runs it. The loop is restartable from its on-disk re
|
|
|
42
44
|
## Step 1: Resolve the topic slug + paths (path safety)
|
|
43
45
|
|
|
44
46
|
Resolve the topic into a slug (whitespace -> `-`, capitalization preserved, e.g.
|
|
45
|
-
`CKA from KEM` -> `CKA-from-KEM`). Treat the topic + iteration arg
|
|
46
|
-
shell metacharacters, QUOTE every path expansion, NEVER
|
|
47
|
+
`CKA from KEM` -> `CKA-from-KEM`). Treat the topic + iteration arg AND the new `--model` / `--effort`
|
|
48
|
+
flag values as UNTRUSTED: REJECT a slug with shell metacharacters, QUOTE every path expansion, NEVER
|
|
49
|
+
`eval` a path. The `--model` / `--effort` values are opaque, runtime-valid strings -- do NOT validate
|
|
50
|
+
them against any model taxonomy; reject only shell metacharacters (the same path-safety check).
|
|
47
51
|
|
|
48
52
|
```bash
|
|
49
|
-
TOPIC_RAW="
|
|
53
|
+
TOPIC_RAW=""; ITER=""; EXEC_MODEL=""; EXEC_EFFORT=""
|
|
54
|
+
while [ $# -gt 0 ]; do
|
|
55
|
+
case "$1" in
|
|
56
|
+
--model ) EXEC_MODEL="$2"; shift 2 ;;
|
|
57
|
+
--effort ) EXEC_EFFORT="$2"; shift 2 ;;
|
|
58
|
+
* ) if [ -z "$TOPIC_RAW" ]; then TOPIC_RAW="$1"; elif [ -z "$ITER" ]; then ITER="$1"; fi; shift ;;
|
|
59
|
+
esac
|
|
60
|
+
done
|
|
50
61
|
case "$TOPIC_RAW" in
|
|
51
62
|
*[';|&$`()<>'*]* ) echo "FVS >> ERROR: topic contains shell metacharacters" >&2; exit 1 ;;
|
|
52
63
|
*..*|*/* ) echo "FVS >> ERROR: topic contains '..' or '/' (path traversal); refusing" >&2; exit 1 ;;
|
|
@@ -55,6 +66,11 @@ case "$ITER" in
|
|
|
55
66
|
n[0-9]* ) : ;;
|
|
56
67
|
* ) echo "FVS >> ERROR: iteration must be of the form nN" >&2; exit 1 ;;
|
|
57
68
|
esac
|
|
69
|
+
for FLAGVAL in "$EXEC_MODEL" "$EXEC_EFFORT"; do
|
|
70
|
+
case "$FLAGVAL" in
|
|
71
|
+
*[';|&$`()<>'*]* ) echo "FVS >> ERROR: --model/--effort contains shell metacharacters" >&2; exit 1 ;;
|
|
72
|
+
esac
|
|
73
|
+
done
|
|
58
74
|
SLUG=$(printf '%s' "$TOPIC_RAW" | tr -s '[:space:]' '-')
|
|
59
75
|
ROOT=".formalising/fv-plans/$SLUG"
|
|
60
76
|
```
|
|
@@ -68,22 +84,48 @@ Read the bounded executor plan for this iteration -- `plans/EXEC_PLAN_nN.md`, or
|
|
|
68
84
|
the executor needs (it is runtime-neutral and bounded -- branch/state, exact targets, immutable public
|
|
69
85
|
statements, allowed-`sorry` policy, stop conditions, verification command).
|
|
70
86
|
|
|
71
|
-
## Step 3: Resolve the executor model + dispatch
|
|
87
|
+
## Step 3: Resolve the executor model + effort + dispatch
|
|
72
88
|
|
|
73
|
-
Resolve `$EXECUTOR_MODEL` for `fvs-executor`
|
|
74
|
-
|
|
89
|
+
Resolve `$EXECUTOR_MODEL` and `$EXECUTOR_EFFORT` for `fvs-crypto-executor` AT DISPATCH TIME -- never
|
|
90
|
+
pinned in the agent frontmatter. The resolved values are opaque, runtime-valid strings passed
|
|
91
|
+
STRAIGHT THROUGH to `Task(model=...)`; FVS keeps NO cross-provider model/effort taxonomy (an invalid
|
|
92
|
+
value is rejected by the runtime itself). Resolve with this ladder:
|
|
93
|
+
|
|
94
|
+
1. The per-run `--model` / `--effort` flags from Step 1, if present.
|
|
95
|
+
2. Else a top-level override in `.formalising/fvs-config.json`:
|
|
96
|
+
`model_overrides["fvs-crypto-executor"]`. Read it at the TOP-LEVEL `model_overrides` key the
|
|
97
|
+
model-profiles resolver actually consults -- NOT the template's nested `model.model_profile` (a
|
|
98
|
+
pre-existing shape mismatch, out of scope here; do not depend on the nested key).
|
|
99
|
+
3. Else, in an interactive run, ASK via `AskUserQuestion` which model + effort to use for the
|
|
100
|
+
execution subagent, offering "inherit / default" as a choice.
|
|
101
|
+
4. Else default `inherit` (works zero-config on every runtime).
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
CONFIG=$(cat .formalising/fvs-config.json 2>/dev/null || echo '{}')
|
|
105
|
+
# 1. flag -> 2. top-level model_overrides["fvs-crypto-executor"] -> 4. inherit
|
|
106
|
+
# (3. AskUserQuestion runs between 2 and 4 in an interactive run)
|
|
107
|
+
EXECUTOR_MODEL="${EXEC_MODEL:-$(printf '%s' "$CONFIG" | OVERRIDE_KEY='model_overrides["fvs-crypto-executor"]' read_top_level_override)}"
|
|
108
|
+
EXECUTOR_MODEL="${EXECUTOR_MODEL:-inherit}"
|
|
109
|
+
EXECUTOR_EFFORT="${EXEC_EFFORT:-inherit}"
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
On Codex the `model=` parameter is silently ignored and per-agent effort is FIXED at install time
|
|
113
|
+
(from `FVS_CODEX_AGENT_EFFORT`), so the per-run `--effort` flag is a Claude / OpenCode / Gemini
|
|
114
|
+
nicety; Codex users tune the crypto executor's effort via the agent `.toml` / reinstall.
|
|
115
|
+
|
|
116
|
+
`cat` the bounded plan and INLINE it into the prompt (references do not cross the Task boundary):
|
|
75
117
|
|
|
76
118
|
```
|
|
77
119
|
Task(
|
|
78
|
-
subagent_type="fvs-executor",
|
|
120
|
+
subagent_type="fvs-crypto-executor",
|
|
79
121
|
model="$EXECUTOR_MODEL",
|
|
80
122
|
description="Run bounded plan",
|
|
81
|
-
prompt="Execute
|
|
123
|
+
prompt="Execute the bounded crypto plan.
|
|
82
124
|
|
|
83
125
|
<bounded_plan>...the inlined EXEC_PLAN_nN.md / FOLLOWUP_PLAN_nN.md...</bounded_plan>
|
|
84
126
|
|
|
85
|
-
|
|
86
|
-
|
|
127
|
+
Implement the fully-specified plan; self-fix at the green build; ESCALATE for any public-statement
|
|
128
|
+
change and hand back BLOCKED if you cannot proceed. Return with ## IMPLEMENTATION COMPLETE"
|
|
87
129
|
)
|
|
88
130
|
```
|
|
89
131
|
|
|
@@ -98,23 +140,19 @@ nice -n 19 lake build 2>&1 | tee "$ROOT/build.log"
|
|
|
98
140
|
test ${PIPESTATUS[0]} -eq 0 || echo "FVS >> build red -- a proof did not close"
|
|
99
141
|
```
|
|
100
142
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|-------|---------|-----------|
|
|
107
|
-
| Per-step attempt-cap | `3` | Matches the FVS `lean-verify` per-sorry limit. |
|
|
108
|
-
| Cycle hard-cap | `~25` | On exhaustion, HALT with the transcript. |
|
|
109
|
-
| No-progress key | `sha256(target || goal-state)` | A same-key recurrence after a fix is known-stuck. |
|
|
143
|
+
`lake build` is the STYLE authority: `lake env lean` / `--stdin` isolation does NOT run the package
|
|
144
|
+
style linters (`linter.style.show`, `linter.style.longLine` from `weak.linter.mathlibStandardSet`),
|
|
145
|
+
so a style warning surfaces only here. Reproduce it cheaply and early with `lake env lean
|
|
146
|
+
-Dlinter.style.show=true -Dlinter.style.longLine=true <file>`. House style uses `change` (not a
|
|
147
|
+
goal-altering `show`) and wraps lines to <=100 columns.
|
|
110
148
|
|
|
111
|
-
|
|
112
|
-
PROGRESS_KEY=$(printf '%s' "$TARGET$GOAL" | sha256sum | cut -c1-16)
|
|
113
|
-
```
|
|
149
|
+
## Step 5: Route the executor's ESCALATE/BLOCKED return
|
|
114
150
|
|
|
115
|
-
|
|
151
|
+
The `fvs-crypto-executor` owns its own implement -> check -> complete -> escalate -> BLOCKED
|
|
152
|
+
discipline; this command does not re-drive a per-goal grind. When the executor returns ESCALATE (a
|
|
153
|
+
public-statement change is needed) or BLOCKED (it cannot proceed), HALT and redirect to the user via
|
|
116
154
|
`AskUserQuestion` (degrade to plain-text + WAIT on a secondary runtime that lacks it) -- a short
|
|
117
|
-
interactive redirect
|
|
155
|
+
interactive redirect beats a long unattended grind.
|
|
118
156
|
|
|
119
157
|
## Step 6: Run-end banner + next command
|
|
120
158
|
|
|
@@ -133,15 +171,17 @@ Plan: plans/{EXEC_PLAN | FOLLOWUP_PLAN}_{ITER}.md
|
|
|
133
171
|
</process>
|
|
134
172
|
|
|
135
173
|
<codex_skill_adapter>
|
|
136
|
-
On a secondary runtime, the
|
|
137
|
-
|
|
138
|
-
|
|
174
|
+
On a secondary runtime, both the Step 3 model/effort ask and the Step 5 ESCALATE/BLOCKED redirect
|
|
175
|
+
degrade to a plain-text question and WAIT for the user; each is fail-closed (never auto-picks a
|
|
176
|
+
default beyond the ladder's `inherit`, never writes an upstream artifact). The `Task(...)` dispatch
|
|
177
|
+
survives intact (the `model=` parameter is silently ignored on Codex, where per-agent effort is fixed
|
|
178
|
+
at install time, so the per-run `--effort` flag is a no-op there).
|
|
139
179
|
</codex_skill_adapter>
|
|
140
180
|
|
|
141
181
|
<success_criteria>
|
|
142
182
|
- [ ] Topic + iteration resolved; shell metacharacters rejected; every path quoted; no `eval`.
|
|
143
|
-
- [ ] The bounded plan (`EXEC_PLAN_nN.md` / `FOLLOWUP_PLAN_nN.md`) read and inlined; `fvs-executor` dispatched (`subagent_type="fvs-executor"`).
|
|
183
|
+
- [ ] The bounded plan (`EXEC_PLAN_nN.md` / `FOLLOWUP_PLAN_nN.md`) read and inlined; `fvs-crypto-executor` dispatched (`subagent_type="fvs-crypto-executor"`).
|
|
144
184
|
- [ ] The build runs under `set -o pipefail` + `${PIPESTATUS` reading the tool's real status; always `nice -n 19 lake build` (never a bare `lake build`).
|
|
145
|
-
- [ ]
|
|
185
|
+
- [ ] The executor's ESCALATE/BLOCKED return is routed to the user (short interactive redirect early, never a long unattended grind).
|
|
146
186
|
- [ ] No `gh` open/create; no generated-Lean write.
|
|
147
187
|
</success_criteria>
|
|
@@ -99,7 +99,7 @@ QHASH=$(printf '%s' "$QUESTION" | shasum -a 256 | cut -c1-16)
|
|
|
99
99
|
if [ -f "$ROOT/sources/$QHASH.json" ]; then
|
|
100
100
|
cat "$ROOT/sources/$QHASH.json" # cache hit -- re-read, do NOT re-query
|
|
101
101
|
else
|
|
102
|
-
|
|
102
|
+
.formalising/.kb-venv/bin/python ~/.claude/scripts/fvs-kb-query.py ask "$QUESTION" --notebook "$NOTEBOOK_ID" --json \
|
|
103
103
|
| tee "$ROOT/sources/$QHASH.json" # cache the answer for the next iteration
|
|
104
104
|
fi
|
|
105
105
|
```
|
|
@@ -14,6 +14,8 @@ allowed-tools:
|
|
|
14
14
|
<objective>
|
|
15
15
|
Orchestrate interactive proof development for a Lean specification using two-phase subagent dispatch (research -> iterative execute). Dispatches fvs-researcher to analyze sorry locations and recommend proof strategies, then iteratively dispatches fvs-executor to replace each sorry ONE AT A TIME with small tactic blocks.
|
|
16
16
|
|
|
17
|
+
This is a functional-correctness (FC) track command. Its `fvs-executor` `proof-attempt` mode is FC-only: the crypto formalise track drives its own dedicated executor, so the one-sorry pair-programming loop below is exclusive to this command and is not shared with or borrowed by any other track.
|
|
18
|
+
|
|
17
19
|
This is the most interactive command -- it feels like pair programming. The executor proposes a small tactic step, the user checks Lean compiles, and the cycle repeats. This is a locked user decision and must not be overridden.
|
|
18
20
|
|
|
19
21
|
Output: Spec file with sorry replaced by complete proof (VERIFIED) or clear report of where proof got stuck (STUCK).
|
package/fv-skills/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.0.
|
|
1
|
+
2.0.3
|
|
@@ -132,6 +132,24 @@ Task(
|
|
|
132
132
|
- **Invalid profile name:** Fall back to `quality` with a warning.
|
|
133
133
|
- **Empty overrides:** Ignored. Equivalent to no overrides.
|
|
134
134
|
|
|
135
|
+
## crypto-execute Model + Effort Knob
|
|
136
|
+
|
|
137
|
+
`/fvs:crypto-execute` resolves the model + effort for `fvs-crypto-executor` ABOVE the profile table,
|
|
138
|
+
at its own dispatch site (command Step 3) -- not from a `PROFILE_TABLE` row. The crypto executor is
|
|
139
|
+
intentionally NOT pinned, so there is deliberately **no `fvs-crypto-executor` row and no `opus`
|
|
140
|
+
value** in the table above. The resolution ladder is:
|
|
141
|
+
|
|
142
|
+
1. A per-run `--model` / `--effort` flag on the command.
|
|
143
|
+
2. Else a top-level override `model_overrides["fvs-crypto-executor"]` in `.formalising/fvs-config.json`
|
|
144
|
+
(read at the top-level `model_overrides` key this resolver consults, not the template's nested
|
|
145
|
+
`model.model_profile`).
|
|
146
|
+
3. Else an interactive `AskUserQuestion` offering "inherit / default".
|
|
147
|
+
4. Else the default `inherit`.
|
|
148
|
+
|
|
149
|
+
The resolved value is an opaque, runtime-valid string passed straight to `Task(model=...)`; FVS keeps
|
|
150
|
+
no cross-provider taxonomy. On Codex `model=` is ignored and per-agent effort is fixed at install
|
|
151
|
+
time, so the per-run `--effort` flag is a Claude / OpenCode / Gemini nicety.
|
|
152
|
+
|
|
135
153
|
## Two-Phase Dispatch
|
|
136
154
|
|
|
137
155
|
Each main command dispatches two subagents in sequence:
|
|
@@ -4,10 +4,10 @@ plan under a green-build guard and a bounded loop, so a failed proof triggers a
|
|
|
4
4
|
redirect early rather than a long unattended grind.
|
|
5
5
|
|
|
6
6
|
This workflow is the state machine for `/fvs:crypto-execute`. The command body resolves the topic +
|
|
7
|
-
iteration, reads the bounded plan from `plans/`, dispatches the
|
|
8
|
-
|
|
9
|
-
the loop runs as a `(R1; R1)` same-runtime pair by default, with an optional
|
|
10
|
-
the planning/eval stages in a later wave.
|
|
7
|
+
iteration, reads the bounded plan from `plans/`, dispatches the dedicated `fvs-crypto-executor`, and
|
|
8
|
+
owns the build-status check + routing the executor's ESCALATE/BLOCKED return to the user. The plan is
|
|
9
|
+
RUNTIME-NEUTRAL: the loop runs as a `(R1; R1)` same-runtime pair by default, with an optional
|
|
10
|
+
secondary runtime for the planning/eval stages in a later wave.
|
|
11
11
|
|
|
12
12
|
Hard invariants this workflow preserves:
|
|
13
13
|
- The build's exit status is read from the TOOL (`set -o pipefail` / `${PIPESTATUS`), never from the
|
|
@@ -38,19 +38,19 @@ allowed-`sorry` policy, stop conditions, verification command).
|
|
|
38
38
|
</step>
|
|
39
39
|
|
|
40
40
|
<step name="dispatch_executor">
|
|
41
|
-
## Step 3: Dispatch the executor
|
|
41
|
+
## Step 3: Dispatch the crypto executor
|
|
42
42
|
|
|
43
|
-
Resolve `$EXECUTOR_MODEL` via the model-profiles sequence, then dispatch the
|
|
44
|
-
INLINING the bounded plan:
|
|
43
|
+
Resolve `$EXECUTOR_MODEL` via the model-profiles sequence, then dispatch the dedicated crypto
|
|
44
|
+
executor, INLINING the bounded plan:
|
|
45
45
|
|
|
46
46
|
```
|
|
47
|
-
Task(subagent_type="fvs-executor", model="$EXECUTOR_MODEL",
|
|
47
|
+
Task(subagent_type="fvs-crypto-executor", model="$EXECUTOR_MODEL",
|
|
48
48
|
description="Run bounded plan",
|
|
49
|
-
prompt="Execute
|
|
49
|
+
prompt="Execute the bounded crypto plan. ...inlined bounded plan... Return with ## IMPLEMENTATION COMPLETE")
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
The `fvs-crypto-executor` owns its own implement -> check -> complete -> escalate -> BLOCKED
|
|
53
|
+
discipline; this workflow does not re-drive a per-goal grind.
|
|
54
54
|
</step>
|
|
55
55
|
|
|
56
56
|
<step name="green_build_guard">
|
|
@@ -64,23 +64,21 @@ set -o pipefail
|
|
|
64
64
|
nice -n 19 lake build 2>&1 | tee "$ROOT/build.log"
|
|
65
65
|
test ${PIPESTATUS[0]} -eq 0 || echo "build red -- a proof did not close"
|
|
66
66
|
```
|
|
67
|
-
</step>
|
|
68
|
-
|
|
69
|
-
<step name="loop_bounds">
|
|
70
|
-
## Step 5: Bounded loop -- caps + the no-progress rule
|
|
71
67
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
68
|
+
`lake build` is the STYLE authority: `lake env lean` / `--stdin` isolation does NOT run the package
|
|
69
|
+
style linters (`linter.style.show`, `linter.style.longLine` from `weak.linter.mathlibStandardSet`),
|
|
70
|
+
so a style warning surfaces only here. Reproduce it cheaply and early with `lake env lean
|
|
71
|
+
-Dlinter.style.show=true -Dlinter.style.longLine=true <file>`. House style uses `change` (not a
|
|
72
|
+
goal-altering `show`) and wraps lines to <=100 columns.
|
|
73
|
+
</step>
|
|
77
74
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
```
|
|
75
|
+
<step name="route_escalation">
|
|
76
|
+
## Step 5: Route the executor's ESCALATE/BLOCKED return
|
|
81
77
|
|
|
82
|
-
|
|
83
|
-
|
|
78
|
+
The `fvs-crypto-executor` owns escalation (implement -> check -> complete -> escalate -> BLOCKED);
|
|
79
|
+
this workflow does not enforce a per-goal attempt grind. When the executor returns ESCALATE (a
|
|
80
|
+
public-statement change is needed) or BLOCKED (it cannot proceed), HALT and redirect to the user (a
|
|
81
|
+
short interactive redirect beats a long unattended grind). On a secondary runtime that lacks an
|
|
84
82
|
interactive prompt, degrade to plain-text and WAIT (fail-closed).
|
|
85
83
|
</step>
|
|
86
84
|
|
|
@@ -88,8 +86,8 @@ interactive prompt, degrade to plain-text and WAIT (fail-closed).
|
|
|
88
86
|
|
|
89
87
|
<success_criteria>
|
|
90
88
|
- [ ] Topic + iteration resolved; shell metacharacters rejected; paths quoted; no `eval`.
|
|
91
|
-
- [ ] The bounded plan read and inlined; `fvs-executor` dispatched (`subagent_type="fvs-executor"`)
|
|
89
|
+
- [ ] The bounded plan read and inlined; `fvs-crypto-executor` dispatched (`subagent_type="fvs-crypto-executor"`).
|
|
92
90
|
- [ ] The build runs under `set -o pipefail` + `${PIPESTATUS` reading the tool's real status; always `nice -n 19 lake build` (never a bare `lake build`).
|
|
93
|
-
- [ ]
|
|
91
|
+
- [ ] The executor's ESCALATE/BLOCKED return is routed to the user (short interactive redirect early, never a long unattended grind).
|
|
94
92
|
- [ ] No generated-Lean write; no `gh` open/create.
|
|
95
93
|
</success_criteria>
|
|
@@ -58,7 +58,7 @@ QHASH=$(printf '%s' "$QUESTION" | shasum -a 256 | cut -c1-16)
|
|
|
58
58
|
if [ -f "$ROOT/sources/$QHASH.json" ]; then
|
|
59
59
|
cat "$ROOT/sources/$QHASH.json" # cache hit -- re-read, do NOT re-query
|
|
60
60
|
else
|
|
61
|
-
|
|
61
|
+
.formalising/.kb-venv/bin/python ~/.claude/scripts/fvs-kb-query.py ask "$QUESTION" --notebook "$NOTEBOOK_ID" --json \
|
|
62
62
|
| tee "$ROOT/sources/$QHASH.json" # cache the answer under sources/
|
|
63
63
|
fi
|
|
64
64
|
```
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
Orchestrate interactive proof development for a Lean specification using two-phase
|
|
3
3
|
subagent dispatch (research -> iterative execute).
|
|
4
4
|
|
|
5
|
+
This is a functional-correctness (FC) track workflow. The fvs-executor proof-attempt
|
|
6
|
+
mode it drives is FC-only -- the crypto formalise track uses its own dedicated executor,
|
|
7
|
+
so this one-sorry loop is exclusive to lean-verify and is not shared with any other track.
|
|
8
|
+
|
|
5
9
|
Dispatches fvs-researcher to analyze sorry locations and recommend proof strategies,
|
|
6
10
|
then iteratively dispatches fvs-executor to replace each sorry ONE AT A TIME with
|
|
7
11
|
small tactic blocks. The user checks Lean compiles between each step.
|
package/package.json
CHANGED