832375f2ac
All 176 files in the four accumulating directories now use a zero-padded 4-digit counter prefix that reflects creation order (`NNNN-slug.md`). The counter is assigned per directory in strict git-log creation order; ties broken alphabetically by original name. The old `YYYY-MM-DD-` prefix on docs/specs/ and docs/plans/ files is dropped — the date is recoverable from git log and the counter carries the ordering. A file's counter is stable for the life of the file: never reassigned, never reused, never compacted. Deleted files retire their counter; subsequent files do not fill the gap. This is the property that lets cross-references stay literal — refs use the full filename including the counter (`design/contracts/0007-honesty-rule.md`) so they grep cleanly and resolve directly without a glob step. 313 cross-references updated across .md/.rs/.toml/.c/.json files (test pins, include_str! paths, design-INDEX entries, baseline notes, runtime C comments, inter-contract markdown links incl. bare basename and `../models/foo.md` forms). CLAUDE.md gets a new "File-naming convention" section spelling out the rule and rationale. skills/brainstorm/SKILL.md and skills/planner/SKILL.md updated so new spec/plan creation produces counter-prefixed names from the start. The full test suite (cargo test --workspace) passes.
352 lines
15 KiB
Markdown
352 lines
15 KiB
Markdown
# Architect Iron-Law Extension — Implementation Plan
|
|
|
|
> **Parent:** `docs/roadmap.md` P2 todo "Architect-iron-law standing-grep
|
|
> extension" (no per-iteration spec — this is a tooling-discipline
|
|
> extension, not a milestone).
|
|
>
|
|
> **Context:** JOURNAL 2026-05-10 "Milestone close: design-md-consolidation"
|
|
> (the four sweep regexes); JOURNAL 2026-05-10 "Fieldtest close:
|
|
> Floats milestone" (the lockstep failure-mode that B1 surfaced).
|
|
>
|
|
> **For agentic workers:** REQUIRED SUB-SKILL: use `skills/implement`
|
|
> to run this plan. Steps use `- [ ]` checkboxes for tracking.
|
|
|
|
**Goal:** Extend `ailang-architect`'s drift review with two standing
|
|
checks so DESIGN.md cannot silently regrow history anchors, and so
|
|
new typecheck-reject / `lower_app` arms cannot ship without their
|
|
cross-file companion update.
|
|
|
|
**Architecture:** A new helper script `bench/architect_sweeps.sh`
|
|
runs the four sweep regexes from the design-md-consolidation
|
|
milestone against `docs/DESIGN.md` and prints any matched lines.
|
|
The architect agent's standing reading list and "What you check"
|
|
section are extended with two new bullets: one that invokes the
|
|
sweep script, one that walks the two known cross-file lockstep
|
|
pairings (`Pattern::Lit::*` rejects ↔ `pre_desugar_validation.rs`,
|
|
and `lower_app` arms ↔ `is_static_callee`). No production code
|
|
changes; this is process-tooling only.
|
|
|
|
**Tech Stack:** bash, markdown.
|
|
|
|
**Files this plan creates or modifies:**
|
|
|
|
- Create: `bench/architect_sweeps.sh` — runs the four design-md-
|
|
consolidation sweep regexes against `docs/DESIGN.md`. Exit 0 if
|
|
all sweeps are clean, 1 if any anchor is found. Output is the
|
|
matched lines, prefixed by sweep name.
|
|
- Modify: `skills/audit/agents/ailang-architect.md` — adds two new
|
|
bullets to "What you check" (DESIGN.md history-anchor regrowth +
|
|
Lockstep invariants across files), and inserts a Step 2.5 in "The
|
|
Process" that runs the sweep script.
|
|
- Modify: `docs/JOURNAL.md` — append a closing entry under today's
|
|
date.
|
|
- Modify: `docs/roadmap.md` — strike the "Architect-iron-law
|
|
standing-grep extension" P2 todo (entry done).
|
|
|
|
---
|
|
|
|
## Task 1: Helper script `bench/architect_sweeps.sh`
|
|
|
|
**Files:**
|
|
- Create: `bench/architect_sweeps.sh`
|
|
- Test: manual invocation against current `docs/DESIGN.md`
|
|
|
|
- [ ] **Step 1: Write the script**
|
|
|
|
Create `bench/architect_sweeps.sh` with the following exact contents:
|
|
|
|
```bash
|
|
#!/usr/bin/env bash
|
|
# bench/architect_sweeps.sh
|
|
#
|
|
# Run the four design-md-consolidation sweep-invariant greps against
|
|
# docs/DESIGN.md. Output: matched lines, prefixed by sweep name. Exit 0
|
|
# if all four sweeps are clean, 1 if any anchor was found.
|
|
#
|
|
# Companion to skills/audit/agents/ailang-architect.md "What you check
|
|
# / DESIGN.md history-anchor regrowth". See JOURNAL 2026-05-10
|
|
# ("Milestone close: design-md-consolidation") for the rationale of
|
|
# each sweep regex; the regexes here are copied verbatim from JOURNAL
|
|
# entries 12487 (Sweep 1), 12619 (Sweep 2), 12718-12720 (Sweep 3),
|
|
# and 12840 (Sweep 4).
|
|
#
|
|
# A non-zero exit is advisory, not authoritative: the architect agent
|
|
# reviews each match and decides whether it is a legitimate quote
|
|
# (e.g. a JOURNAL citation inside a block-quote) or fresh drift.
|
|
|
|
set -u
|
|
DESIGN="docs/DESIGN.md"
|
|
HITS=0
|
|
|
|
if [[ ! -f "$DESIGN" ]]; then
|
|
echo "architect_sweeps: $DESIGN not found (run from repo root)" >&2
|
|
exit 2
|
|
fi
|
|
|
|
run_sweep() {
|
|
local name="$1"
|
|
local pattern="$2"
|
|
local matches
|
|
matches=$(grep -nE "$pattern" "$DESIGN" || true)
|
|
if [[ -n "$matches" ]]; then
|
|
echo "=== Sweep: $name ==="
|
|
echo "$matches"
|
|
echo
|
|
HITS=1
|
|
fi
|
|
}
|
|
|
|
run_sweep "1 (history anchors)" \
|
|
'Iter [0-9]+[a-z]?(\.[0-9]+)?|Family [0-9]+|^[^/]*2026-[0-9]{2}-[0-9]{2}|\*\*Status: |pre-[0-9]+[a-z]?|[0-9]+[a-z]? sketch|21\.g'
|
|
|
|
run_sweep "2 (REVERTED + migration)" \
|
|
'REVERTED|preserved for the audit trail|Migration plan|[Oo]riginally framed|original rationale|empirically-grounded version|A future (iter|iteration|milestone|Prelude) may|A future iter that|a (later|future) iter(ation)? \(deferred\)|Concrete design deferred'
|
|
|
|
run_sweep "3 (schema SoT)" \
|
|
'^\s*(struct |enum |pub (struct|enum|fn))|whenever the two disagree|ast\.rs is the source of truth'
|
|
|
|
run_sweep "4 (workflow + stale cross-references)" \
|
|
'agents/README\.md|ailang-docwriter|Recently lifted|see the JOURNAL queue|later the same day|Sharpened later|closure conversion in JOURNAL'
|
|
|
|
if [[ $HITS -eq 0 ]]; then
|
|
echo "All four sweeps clean."
|
|
fi
|
|
exit $HITS
|
|
```
|
|
|
|
- [ ] **Step 2: Make it executable**
|
|
|
|
Run: `chmod +x bench/architect_sweeps.sh`
|
|
Expected: no output, exit 0.
|
|
|
|
- [ ] **Step 3: Run against current DESIGN.md, expect clean**
|
|
|
|
Run: `bash bench/architect_sweeps.sh`
|
|
Expected: stdout = `All four sweeps clean.`, exit code 0.
|
|
|
|
If any sweep matches, the script implementation is wrong (the
|
|
design-md-consolidation milestone closed all four sweeps as clean
|
|
on 2026-05-10; today's DESIGN.md is the post-close baseline). Diff
|
|
the regex against the JOURNAL-recorded one character-by-character.
|
|
|
|
- [ ] **Step 4: Commit**
|
|
|
|
```bash
|
|
git add bench/architect_sweeps.sh
|
|
git commit -m "iter architect-iron-law.1: bench/architect_sweeps.sh runs the four design-md-consolidation sweeps against DESIGN.md"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 2: Extend `ailang-architect` agent prose
|
|
|
|
**Files:**
|
|
- Modify: `skills/audit/agents/ailang-architect.md`
|
|
|
|
- [ ] **Step 1: Add "DESIGN.md history-anchor regrowth" bullet to "What you check"**
|
|
|
|
In `skills/audit/agents/ailang-architect.md`, locate the "What you
|
|
check" section (currently has bullets: Drift against DESIGN.md, Drift
|
|
against the milestone spec, Growing debt, Consistency across crates,
|
|
Test coverage, Scaling break points, JOURNAL truthfulness).
|
|
|
|
Insert a new bullet immediately AFTER the "JOURNAL truthfulness"
|
|
bullet (i.e. as the last bullet in the list):
|
|
|
|
```markdown
|
|
- **DESIGN.md history-anchor regrowth.** Run
|
|
`bash bench/architect_sweeps.sh` from the repo root. Exit 0 = clean.
|
|
Exit 1 = at least one of the four sweeps from the
|
|
design-md-consolidation milestone (2026-05-10) matched. Review each
|
|
match: a legitimate quote (e.g. a JOURNAL citation inside a block-
|
|
quote) is fine; a fresh history anchor / REVERTED narrative /
|
|
workflow detail / stale cross-reference is drift to flag.
|
|
- **Lockstep invariants across files.** Two known cross-file pairings
|
|
must move together; a new arm in one without the matching update in
|
|
the other ships silently broken (B1 in the Floats fieldtest is the
|
|
canonical example). On every milestone-close, walk these pairs:
|
|
|
|
| Pair | Failure mode |
|
|
|---|---|
|
|
| `Pattern::Lit::*` typecheck rejects in `crates/ailang-check/src/lib.rs` ↔ pre-desugar walkers in `crates/ailang-check/src/pre_desugar_validation.rs` | A reject arm placed AFTER `desugar_module` in the call chain is unreachable through the public `check` API if the desugar pass rewrites that pattern shape first (e.g. `desugar::build_eq` rewrites `Pattern::Lit::Float` into `(== scrut lit)` before typecheck runs). New rejects on a `Pattern::Lit::*` shape MUST live in `pre_desugar_validation.rs`, or be paired with a written guarantee that no desugar pass eats the shape. |
|
|
| `lower_app` arms in `crates/ailang-codegen/src/lib.rs::lower_app` (line ~1749) ↔ name recognition in `crates/ailang-codegen/src/lib.rs::is_static_callee` (line ~2189) | A name lowered by a direct `lower_app` arm but unrecognised by `is_static_callee` falls through to the indirect-call path with `UnknownVar` (`UnknownVar` panic in worst case). Every new builtin lowering arm in `lower_app` must have a matching `is_static_callee` entry. |
|
|
|
|
Walk procedure: for each milestone-scope commit-range arm landed in
|
|
these files (use `git diff <prev-close>..HEAD --` on each file in
|
|
the pair), open both files in the pair and confirm the matching
|
|
update is present. Flag any unpaired arm as drift.
|
|
```
|
|
|
|
- [ ] **Step 2: Add Step 2.5 to "The Process"**
|
|
|
|
In `skills/audit/agents/ailang-architect.md`, locate "The Process"
|
|
section. Steps are currently numbered 1 through 6.
|
|
|
|
Replace Step 2 + the current Step 3 with Step 2 + Step 2.5 + Step 3
|
|
(renumbering nothing else). The current Step 2 reads:
|
|
|
|
```markdown
|
|
2. `git log --oneline -30` and `git diff <prev-milestone-close>..HEAD` for
|
|
the factual diff.
|
|
```
|
|
|
|
Replace it with:
|
|
|
|
```markdown
|
|
2. `git log --oneline -30` and `git diff <prev-milestone-close>..HEAD` for
|
|
the factual diff.
|
|
2.5. Run `bash bench/architect_sweeps.sh` from the repo root. If exit
|
|
code is 1, treat each matched line as a drift-suspicion to verify.
|
|
If exit code is 2, the script could not find DESIGN.md — fix the
|
|
working directory and re-run before continuing.
|
|
```
|
|
|
|
- [ ] **Step 3: Self-check by re-reading the modified agent file**
|
|
|
|
Read `skills/audit/agents/ailang-architect.md` end-to-end. Verify:
|
|
- The two new bullets appear at the end of "What you check".
|
|
- Step 2.5 appears between Step 2 and Step 3 in "The Process".
|
|
- File path references resolve: `crates/ailang-check/src/lib.rs`,
|
|
`crates/ailang-check/src/pre_desugar_validation.rs`,
|
|
`crates/ailang-codegen/src/lib.rs`, `bench/architect_sweeps.sh`
|
|
all exist.
|
|
|
|
- [ ] **Step 4: Commit**
|
|
|
|
```bash
|
|
git add skills/audit/agents/ailang-architect.md
|
|
git commit -m "iter architect-iron-law.2: extend ailang-architect with sweep-script invocation + lockstep-checklist for two known cross-file pairings"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 3: JOURNAL entry + roadmap close-out
|
|
|
|
**Files:**
|
|
- Modify: `docs/JOURNAL.md`
|
|
- Modify: `docs/roadmap.md`
|
|
|
|
- [ ] **Step 1: Append JOURNAL entry**
|
|
|
|
Append the following block at the end of `docs/JOURNAL.md`:
|
|
|
|
```markdown
|
|
## 2026-05-10 — Architect iron-law extension: sweep script + lockstep-checklist
|
|
|
|
`ailang-architect`'s drift-review iron law extended with two
|
|
standing checks, both motivated by failure modes that shipped in
|
|
the closing milestones of the typeclass-and-floats arc:
|
|
|
|
1. **DESIGN.md history-anchor regrowth.** The four sweep regexes
|
|
from the design-md-consolidation milestone (history anchors,
|
|
REVERTED + migration, schema SoT, workflow + stale cross-
|
|
references) are now packaged as `bench/architect_sweeps.sh` and
|
|
run as Step 2.5 of the architect's process. Today's DESIGN.md
|
|
is clean against all four; the script's job is to keep it that
|
|
way against future commits. Non-zero exit is advisory: the
|
|
architect reads each match and decides legitimate-quote vs. fresh
|
|
drift.
|
|
2. **Lockstep invariants across files.** Two cross-file pairings
|
|
are pinned in the agent's "What you check" section as standing
|
|
walks: `Pattern::Lit::*` typecheck-rejects ↔
|
|
`pre_desugar_validation.rs` walkers (the B1 lockstep — the
|
|
typecheck reject is unreachable through `check_module` if a
|
|
desugar pass rewrites the shape first), and `lower_app` arms ↔
|
|
`is_static_callee` recognition (the iter-4.2 / 4.4 lockstep —
|
|
a direct lowering arm without `is_static_callee` recognition
|
|
falls through to indirect-call with `UnknownVar`). For each
|
|
milestone-scope commit-range arm landed in these files, the
|
|
architect now opens both files in the pair.
|
|
|
|
Both pairings are real, both shipped silently broken at least once,
|
|
and both were caught only by post-hoc means (B1 by fieldtest, the
|
|
iter-4 ones by mid-iter implementer review). The architect was the
|
|
right role to catch them prospectively; the standing checklist is
|
|
how that role catches them in future.
|
|
|
|
Per-task commits:
|
|
|
|
- `<hash 1>` iter architect-iron-law.1: bench/architect_sweeps.sh runs the four design-md-consolidation sweeps against DESIGN.md
|
|
- `<hash 2>` iter architect-iron-law.2: extend ailang-architect with sweep-script invocation + lockstep-checklist for two known cross-file pairings
|
|
|
|
The roadmap entry "Architect-iron-law standing-grep extension"
|
|
under P2 is closed by this iteration. Future lockstep pairings, as
|
|
they surface in JOURNAL entries, can extend the table inline
|
|
without further iteration ceremony.
|
|
```
|
|
|
|
(The hashes will be filled in when the actual commits are made; the
|
|
commit-creating step in this task patches them in.)
|
|
|
|
- [ ] **Step 2: Resolve commit-hash placeholders**
|
|
|
|
After Tasks 1 and 2 have been committed, get the two short hashes:
|
|
|
|
Run: `git log --oneline -5 | head -3`
|
|
Expected: top three lines start with the two iter-1/iter-2 commits
|
|
plus the previous (Floats) commit.
|
|
|
|
Edit `docs/JOURNAL.md` — replace `<hash 1>` and `<hash 2>` with the
|
|
short SHA from the corresponding commits. The Task 1 commit is
|
|
"iter architect-iron-law.1:..." and Task 2 is "...iron-law.2:...".
|
|
|
|
- [ ] **Step 3: Strike the roadmap entry**
|
|
|
|
In `docs/roadmap.md`, locate the bullet:
|
|
|
|
```markdown
|
|
- [ ] **\[todo\]** Architect-iron-law standing-grep extension —
|
|
the architect agent's drift review should run the four sweep
|
|
invariant greps on every milestone-close so DESIGN.md cannot
|
|
silently regrow history anchors / REVERTED narratives /
|
|
workflow detail / stale cross-references. Path-anchored
|
|
exceptions (`docs/specs/2026-05-09-*`) need an allowlist.
|
|
Same extension should add the **lockstep-checklist** the
|
|
Floats fieldtest exposed: for every new typecheck reject arm
|
|
on a pattern shape, verify the corresponding desugar pass does
|
|
not eat that shape first; for every new lowering arm in
|
|
`lower_app`, verify `is_static_callee` recognises it. Both
|
|
shipped silently-broken in the Floats milestone (B1 and the
|
|
iter-4.2/4.4 pull-forwards) and the architect missed them.
|
|
- context: JOURNAL 2026-05-10 ("Milestone close:
|
|
design-md-consolidation"); 2026-05-10 ("Fieldtest close:
|
|
Floats milestone") — B1 + architect-checklist follow-up.
|
|
```
|
|
|
|
Delete it entirely. (Done entries are deleted from the roadmap once
|
|
they are no longer interesting context; the JOURNAL entry above
|
|
preserves the rationale.)
|
|
|
|
- [ ] **Step 4: Verify the script still runs clean after agent-prose changes**
|
|
|
|
Run: `bash bench/architect_sweeps.sh`
|
|
Expected: `All four sweeps clean.`, exit 0. (Sanity — Tasks 2 and 3
|
|
should not have touched DESIGN.md.)
|
|
|
|
- [ ] **Step 5: Commit**
|
|
|
|
```bash
|
|
git add docs/JOURNAL.md docs/roadmap.md
|
|
git commit -m "iter architect-iron-law.3: JOURNAL entry + close roadmap todo"
|
|
```
|
|
|
|
---
|
|
|
|
## Self-review checklist
|
|
|
|
1. **Spec coverage:** the roadmap entry has two halves (standing
|
|
greps + lockstep checklist); Task 1 covers the script that
|
|
embodies the greps, Task 2 covers the agent-prose for both halves,
|
|
Task 3 covers the JOURNAL + roadmap closure. All covered. ✓
|
|
2. **Placeholder scan:** `<hash 1>` / `<hash 2>` are placeholders
|
|
resolved in Task 3 Step 2 by the implementer reading actual git
|
|
output. No "TBD", no "TODO", no "implement later", no "similar to
|
|
Task N". ✓
|
|
3. **Type / path consistency:** `bench/architect_sweeps.sh` is the
|
|
same path in script, agent file, and JOURNAL. `lower_app` /
|
|
`is_static_callee` line numbers match the verified `grep` output
|
|
from this conversation (1749 / 2189). `pre_desugar_validation.rs`
|
|
exists. ✓
|
|
4. **Step granularity:** each step is a single file-edit-or-command,
|
|
2-5 minutes. ✓
|