workflow(plan-recon): require compile-driven enumeration + existence table
Tightens `skills/planner/agents/ailang-plan-recon.md` against two recon-contract failure modes documented in Gitea #9: (a) For signature-change / enum-variant-add-remove / public-symbol- removal scopes, hand-listing of call sites or match arms has under-counted the blast radius four times across two milestones, each through a different site type (loop-recur.1 walker arms, loop-recur.2 cross-module synth callers, loop-recur.tidy implicit, remove-mut-var-assign.1 in-source `mod tests` fns + drift pin + `.ail.json` carve-outs + a non-enumerated E0599). The recon now MUST report a compile-driven enumeration (cargo check after a stub / exhaustive `git grep -nE` / `cargo expand`) as the authoritative code-site set; hand-listing is explicitly labelled "advisory". The compile-driven channel only covers compile-checked sites, so a separate sweep for drift pins, `.ail`/`.ail.json` fixtures, and design-doc references is required and reported under a "Non-compile-checked sites" section. (b) Every path the spec names is now `ls`-verified before propagation into the brief. An existence claim feeding a recon is itself load-bearing — one prior recon brief inherited an unverified "X does not exist" claim (form_a.md, remove-mut-var-assign.1) and was caught only at milestone-close audit. The new "Spec-named path existence table" is mandatory for every dispatch (regardless of scope class); entries marked "not exists" must carry the exact `ls` / `git ls-files` command run, and only verified-not-exists entries may feed "Anchors not yet present". Three new Common Rationalisations and three new Red Flags calibrate against the named failure modes. The "Compile-driven site set" / "Non-compile-checked sites" output sections may be omitted for iterations that do not involve a signature / variant / removal scope; the existence table is always required. No language change; no code change. Agent-definition discipline fix only. closes #9
This commit is contained in:
@@ -82,15 +82,56 @@ fix or write.
|
|||||||
- cross-references the iteration touches (especially the
|
- cross-references the iteration touches (especially the
|
||||||
lockstep-invariant pairs documented in `ailang-architect`'s
|
lockstep-invariant pairs documented in `ailang-architect`'s
|
||||||
reading list)
|
reading list)
|
||||||
5. For each path or symbol the spec implies must exist but does not
|
5. **Compile-driven enumeration (signature / variant / removal
|
||||||
|
scopes).** If `iteration_scope` involves any of:
|
||||||
|
- a signature change to a public function or trait method,
|
||||||
|
- adding or removing an enum variant,
|
||||||
|
- removing a public symbol, type, or module,
|
||||||
|
|
||||||
|
then a hand-listing of call sites or match arms has historically
|
||||||
|
under-counted the blast radius (loop-recur.1, loop-recur.2,
|
||||||
|
loop-recur.tidy, remove-mut-var-assign.1 — four failures across
|
||||||
|
two milestones, each through a different site type). For these
|
||||||
|
scopes the recon MUST report a compile-driven enumeration as the
|
||||||
|
authoritative code-site set, with any hand-list explicitly
|
||||||
|
labelled "advisory". Mechanics that count as compile-driven:
|
||||||
|
- `cargo check` after a temporary stub of the change (the
|
||||||
|
compiler enumerates every broken match arm / caller / impl);
|
||||||
|
- exhaustive `git grep -nE` of the symbol across the workspace,
|
||||||
|
reported as the literal command + line count;
|
||||||
|
- `cargo expand` over a representative crate when the change
|
||||||
|
touches macro-generated code.
|
||||||
|
|
||||||
|
The compile-driven channel only catches compile-checked sites.
|
||||||
|
Non-compile-checked sites — drift-pin tests, `.ail`/`.ail.json`
|
||||||
|
fixtures, design-doc references, prose mentions — need a
|
||||||
|
separate `git grep` sweep, reported alongside the compile-driven
|
||||||
|
set under "Non-compile-checked sites". The recon explicitly
|
||||||
|
names BOTH channels in the output; missing the second is the
|
||||||
|
exact failure mode item (a) in Gitea #9.
|
||||||
|
|
||||||
|
6. **Spec-named-path existence table.** Before recording anything
|
||||||
|
under "Anchors not yet present", `ls`-verify every path the spec
|
||||||
|
names. `git ls-files <path>` or `test -e <path>` is the
|
||||||
|
authoritative check; a Boss-time grep of a sibling directory is
|
||||||
|
not. An existence claim that feeds the recon is itself
|
||||||
|
load-bearing — historically a "path X does not exist" claim
|
||||||
|
propagated unverified into a recon brief once and was caught
|
||||||
|
only at milestone-close audit (remove-mut-var-assign.1,
|
||||||
|
form_a.md). Record every spec-named path with its verified
|
||||||
|
status in the existence table; an entry of "not exists" must
|
||||||
|
carry the exact `ls` / `git ls-files` command run.
|
||||||
|
7. For each path or symbol the spec implies must exist but does not
|
||||||
in the current tree, record it under "Anchors not yet present".
|
in the current tree, record it under "Anchors not yet present".
|
||||||
Absence is signal; do not invent.
|
Absence is signal; do not invent. The existence table from Step 6
|
||||||
6. Apply the priority filter: spec sections in `iteration_scope` get
|
is the input here — only entries marked "not exists" from a
|
||||||
|
verified check appear under "Anchors not yet present".
|
||||||
|
8. Apply the priority filter: spec sections in `iteration_scope` get
|
||||||
full coverage; sections out-of-scope get a one-line acknowledgement
|
full coverage; sections out-of-scope get a one-line acknowledgement
|
||||||
only.
|
only.
|
||||||
7. Compose the output block (≤1500 tokens) in the format below.
|
9. Compose the output block (≤1500 tokens) in the format below.
|
||||||
8. If anything is ambiguous, return `DONE_WITH_CONCERNS` (concern
|
10. If anything is ambiguous, return `DONE_WITH_CONCERNS` (concern
|
||||||
inline) or `NEEDS_CONTEXT` (cannot proceed without clarification).
|
inline) or `NEEDS_CONTEXT` (cannot proceed without clarification).
|
||||||
|
|
||||||
## Output format
|
## Output format
|
||||||
|
|
||||||
@@ -105,8 +146,25 @@ fix or write.
|
|||||||
- relevant function: `<fn name>` at `<path>:<line>`
|
- relevant function: `<fn name>` at `<path>:<line>`
|
||||||
- cross-reference: `<other path>:<line>` (lockstep partner)
|
- cross-reference: `<other path>:<line>` (lockstep partner)
|
||||||
|
|
||||||
|
### Compile-driven site set (signature / variant / removal scopes only)
|
||||||
|
- channel: `<cargo check after stub | git grep -nE '<pattern>' | cargo expand -p <crate>>`
|
||||||
|
- raw command output / line count: `<n sites>`
|
||||||
|
- enumerated paths + line numbers: `<path:line>` (one bullet per site)
|
||||||
|
- hand-list comparison (advisory): `<n sites listed by hand>` —
|
||||||
|
delta vs. compile-driven set, with the missed sites named.
|
||||||
|
|
||||||
|
### Non-compile-checked sites
|
||||||
|
- drift pins / `.ail` / `.ail.json` fixtures / design-doc references:
|
||||||
|
`<path>` — <one-line site description>
|
||||||
|
|
||||||
|
### Spec-named-path existence table
|
||||||
|
| Path the spec names | Verified by | Exists? | Handling task (file-map row) |
|
||||||
|
|---------------------|-------------|---------|------------------------------|
|
||||||
|
| `<path>` | `git ls-files <path>` / `test -e <path>` | yes / no | <where it lands in "Modify" or "Anchors not yet present"> |
|
||||||
|
|
||||||
### Anchors not yet present
|
### Anchors not yet present
|
||||||
- `<path>` — <what the spec implies must be added but does not exist today>
|
- `<path>` — <what the spec implies must be added but does not exist today>
|
||||||
|
(cross-references the existence-table entry whose status is "no")
|
||||||
|
|
||||||
## Cross-references
|
## Cross-references
|
||||||
|
|
||||||
@@ -123,6 +181,12 @@ Flag for Boss judgement; do not invent an answer.
|
|||||||
`DONE` | `DONE_WITH_CONCERNS` | `NEEDS_CONTEXT` | `BLOCKED` (one-line reason)
|
`DONE` | `DONE_WITH_CONCERNS` | `NEEDS_CONTEXT` | `BLOCKED` (one-line reason)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For iterations where `iteration_scope` does NOT involve a signature
|
||||||
|
change / variant addition or removal / public-symbol removal, the
|
||||||
|
"Compile-driven site set" and "Non-compile-checked sites" sections
|
||||||
|
MAY be omitted; the "Spec-named-path existence table" is always
|
||||||
|
required.
|
||||||
|
|
||||||
## Status protocol
|
## Status protocol
|
||||||
|
|
||||||
| Status | Meaning |
|
| Status | Meaning |
|
||||||
@@ -141,6 +205,9 @@ Flag for Boss judgement; do not invent an answer.
|
|||||||
| "Spec is ambiguous on point X, I'll pick the obvious reading" | Return `NEEDS_CONTEXT`. The Boss decides. |
|
| "Spec is ambiguous on point X, I'll pick the obvious reading" | Return `NEEDS_CONTEXT`. The Boss decides. |
|
||||||
| "Code search returns nothing for X, so X isn't in scope" | List X under "Anchors not yet present". Absence is signal. |
|
| "Code search returns nothing for X, so X isn't in scope" | List X under "Anchors not yet present". Absence is signal. |
|
||||||
| "Line numbers will shift before the plan executes, so I'll be vague" | The Boss needs the current line numbers to anchor the plan. Drift between recon and plan execution is the Boss's problem, not yours. |
|
| "Line numbers will shift before the plan executes, so I'll be vague" | The Boss needs the current line numbers to anchor the plan. Drift between recon and plan execution is the Boss's problem, not yours. |
|
||||||
|
| "Hand-listing every match arm of the enum gives me the site set — the compiler would say the same" | Four documented misses across two milestones say otherwise (loop-recur.1, loop-recur.2, loop-recur.tidy, remove-mut-var-assign.1 — each missed a different site type). For signature / variant / removal scopes, the compile-driven enumeration is authoritative; the hand-list is advisory. Run `cargo check` after a stub, report the broken site set verbatim. |
|
||||||
|
| "The spec says path X does not exist, so I don't need to verify it" | An existence claim feeding a recon is itself load-bearing. `git ls-files <X>` or `test -e <X>` is the authoritative check; a Boss-time grep of a sibling directory is not. Caught only at milestone-close audit once (form_a.md, remove-mut-var-assign.1) — the existence table makes this unmissable. |
|
||||||
|
| "Compile-driven enumeration covers everything that matters" | It covers compile-checked sites only. Drift pins, `.ail`/`.ail.json` fixtures, design-doc anchors, prose references — none of these break the build. Run a separate `git grep` sweep and report it under "Non-compile-checked sites". |
|
||||||
|
|
||||||
## Red Flags — STOP
|
## Red Flags — STOP
|
||||||
|
|
||||||
@@ -150,3 +217,6 @@ Flag for Boss judgement; do not invent an answer.
|
|||||||
- About to return a file-map without line ranges
|
- About to return a file-map without line ranges
|
||||||
- About to invent a line number you did not verify
|
- About to invent a line number you did not verify
|
||||||
- About to use `Bash` to write or edit anything
|
- About to use `Bash` to write or edit anything
|
||||||
|
- About to report a signature / variant / removal scope without a compile-driven enumeration channel
|
||||||
|
- About to propagate a spec-claimed "path X does not exist" into the brief without an `ls` / `git ls-files` verification
|
||||||
|
- About to return only the compile-driven set without sweeping for non-compile-checked sites (drift pins, fixtures, doc references)
|
||||||
|
|||||||
Reference in New Issue
Block a user