plan+audit: design-md-rolesplit.tidy re-derived on planning-time evidence (mechanism + scope corrected)

The tidy's gate-first Task 1 RED-verification + Boss independent
verification surfaced two defects in the audit Resolution as first
written — caught exactly where the planner->Boss loop is designed to,
before any contract byte moved. Per the 'two+ defects in one
iteration => fix the upstream artifact, do not patch a third time'
discipline, the audit Resolution is corrected in lockstep with the
plan re-derivation:

- Mechanism (Resolution-4): the 'case-insensitive iter-code regex'
  clause-3 design is REJECTED as unworkable — a blanket
  iter/milestone detector conflates the memory-model rule-names
  'Iter A'/'Iter B' and ordinary words 'pre-existing'/'pre-set'/
  'pre-Boehm' with provenance, over-firing on legit present-tense
  contract prose (4 no-strip files). Replaced by a FAITHFUL Sweep-1
  superset: case-sensitive digit-anchored Sweep-1 line anchors
  (confirmed ZERO across all contracts) + Sweep-1's ^[^/]*
  path-excluded date (so docs/specs/2026-.. citations are not
  flagged — repairs the iso_date over-fire the implement
  orchestrator correctly BLOCKED on) + the audit-named
  decision-record phrases (case-insensitive). No regex dep. The
  load-bearing invariant (clause-3 GREEN => Sweep-1 clean) is
  preserved; it never required the blanket detector.
- Scope (Resolution-1): the architect's [medium] was a 3-file
  spot-check; the exhaustive scan found roundtrip-invariant.md:73
  ('at iter form-a.1') and data-model.md:149,161 ('loop-recur iter
  1:') also carry lowercase provenance. True strip set = 5 files;
  plan Task 5b adds the 2 (spirit-cleanup, not gate-blocking).

Plan self-review 8/8 re-run; clause-3 = hand-rolled faithful Sweep-1
superset, no regex dep, no blanket iter detector.
This commit is contained in:
2026-05-19 13:36:14 +02:00
parent 4f61a7aa4f
commit f2cdd67e69
2 changed files with 232 additions and 87 deletions
@@ -83,13 +83,21 @@ milestone.
iteration** `design-md-rolesplit.tidy`. Orchestrator-decided
scope (the architect named the gap; the clause-3-widening
decision is mine):
1. Move the decision-record/history prose out of
`design/contracts/{typeclasses,str-abi,scope-boundaries}.md`
into `docs/journals/2026-05-19-design-decision-records.md`
(append — same milestone's relitigation archive). Each removed
history sentence is replaced by its present-tense contract
equivalent (e.g. the builtin *signature* is the contract; the
`(iter …)` stamp is journal metadata).
1. Move the decision-record/history prose out of the affected
contract files into
`docs/journals/2026-05-19-design-decision-records.md` (append —
same milestone's relitigation archive). Each removed history
sentence is replaced by its present-tense contract equivalent
(the builtin *signature* is the contract; the `(iter …)` stamp
is journal metadata). **Scope corrected on planning-time
evidence (see amendment below):** the architect's `[medium]`
was a 3-file spot-check
(`typeclasses`/`str-abi`/`scope-boundaries`); the exhaustive
plan-recon + Boss verification scan found two more contract
files carrying lowercase `iter <code>` provenance the
spot-check missed — `roundtrip-invariant.md:73` ("at iter
form-a.1") and `data-model.md:149,161` ("loop-recur iter 1:").
The true strip set is **5 contract files**.
2. Fix `float-semantics.md` stale-direction cross-ref →
`(see design/contracts/str-abi.md)`.
3. **Re-scope the `architect_sweeps.sh` honesty sweeps from
@@ -102,19 +110,60 @@ milestone.
`ailang-architect.md` + any sweep-scope doc in lockstep.
4. **Widen `design_index_pin.rs` clause-3** so, over the
`design/contracts/` scope, it *subsumes* `architect_sweeps.sh`
Sweep-1's history-anchor regex (case-insensitive; iter-code
and ISO-date regexes; "earlier draft", "amends the above",
"was retired", "deliberately deferred", "new-baseline
decision", "milestone NN"). Invariant established:
Sweep-1's history-anchor regex. Invariant established:
**clause-3 GREEN ⟹ Sweep-1 finds nothing in `contracts/`**
the in-code hard gate enforces the spirit; the advisory can
then only legitimately fire on `models/` (now out of its
scope). This permanently closes the spirit-vs-letter gap the
literal 6-marker list left open.
5. Exit state: `architect_sweeps.sh` exit 0; widened
`design_index_pin.rs` clause-3 GREEN; whole `cargo test
--workspace` GREEN; the decision-record journal grows; no new
contract carries history residue.
the in-code hard gate enforces the spirit; the advisory then
only legitimately fires on `models/` (out of its scope after
point 3). This permanently closes the spirit-vs-letter gap the
literal 6-marker list left open. **Mechanism corrected on
planning-time evidence (see amendment below):** the original
"case-insensitive iter-code regex" sketch is *unworkable* and
is rejected — a blanket case-insensitive `iter`/`milestone`
detector conflates the memory-model rule-names "Iter A"/"Iter
B" and the ordinary words "pre-existing"/"pre-set"/"pre-Boehm"
with provenance, over-firing on legitimate present-tense
contract prose. The workable design: clause-3 = a **faithful
reproduction** of Sweep-1's actual alternatives
(case-*sensitive*, digit-anchored — confirmed ZERO across all
contracts) + Sweep-1's `^[^/]*` **path-excluded** date
(so `docs/specs/2026-…` citations are not flagged) + the
audit-named decision-record **phrases** (case-insensitive — the
deliberate widening that closes the capital-variance dodge).
The lowercase `(iter <code>)` provenance is removed by the
strip tasks (point 1), not by a fragile hard-gate regex; the
invariant holds without the rejected detector.
5. Exit state: `architect_sweeps.sh` exit 0; the widened
(faithful-superset) `design_index_pin.rs` clause-3 GREEN; whole
`cargo test --workspace` GREEN; the decision-record journal
grows; no contract carries history residue.
### Resolution amendment (2026-05-19, planning-time evidence)
The tidy plan's gate-first Task 1 (RED-verification) + Boss
independent verification surfaced two defects in this Resolution as
first written — caught exactly where the planner→Boss loop is
designed to catch them, before any contract byte moved:
- **Mechanism (point 4):** "case-insensitive iter-code regex" is
unworkable (conflates rule-names + ordinary words with
provenance). Replaced by the faithful-Sweep-1 + path-excluded-date
+ phrases design above. The load-bearing invariant (clause-3 ⟹
Sweep-1 clean) is *preserved* — it never required the blanket
detector; faithful-Sweep-1 + phrases suffices and faithful-Sweep-1
is confirmed already ZERO across every contract.
- **Scope (point 1):** the `[medium]` was a 3-file spot-check; the
exhaustive scan found `roundtrip-invariant.md` + `data-model.md`
also carry lowercase provenance. The strip set is 5 files (the
plan's Task 5b covers the 2 additions; they are spirit-cleanup,
not gate-blocking — neither Sweep-1 nor the corrected clause-3
trips on lowercase `iter form-a.1`, so the invariant/gate close
regardless; stripping them is the audit's *spirit* fully honored).
This amendment is the upstream-artifact correction the discipline
mandates over patching the plan a third time (the "two+ defects in
one iteration ⇒ the upstream artifact is wrong" rule). The plan
`docs/plans/design-md-rolesplit.tidy.md` is re-derived consistently
with it.
Milestone closes after the tidy iteration lands Boss-verified.
No fieldtest (zero authoring-surface change — the only author-facing
+161 -65
View File
@@ -61,60 +61,92 @@ loop) with this. The other 3 clauses + helpers (`root` :10-12,
```rust
#[test]
fn contracts_carry_no_decision_record_prose() {
// clause 3 — the conflation tripwire, widened (design-md-rolesplit.tidy)
// to a PROVABLE SUPERSET of bench/architect_sweeps.sh Sweep-1's
// history-anchor regex over the design/contracts/ scope.
// clause 3 — the conflation tripwire, widened (design-md-rolesplit.tidy,
// audit Resolution-4) to a FAITHFUL SUPERSET of
// bench/architect_sweeps.sh Sweep-1's history-anchor regex over the
// design/contracts/ scope, PLUS the audit-named decision-record
// phrases (the deliberate widening that closes the case-variance
// dodge the 6 literal markers left open).
//
// Invariant established by this milestone: clause-3 GREEN ⟹
// Sweep-1 finds nothing in design/contracts/.
// Invariant: clause-3 GREEN ⟹ Sweep-1 finds nothing in design/contracts/.
//
// Subsumption proof (each Sweep-1 alternative ⊆ a check below):
// Sweep-1 = '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'
// - "Iter <n>" / "Family <n>" / "21.g" / "<n> sketch"
// ⊆ iter_code_token() (any "iter"/"family"/"milestone"
// token followed by a code, case-insensitive)
// - "2026-NN-NN" ⊆ iso_date() (any 20NN-NN-NN)
// - "**Status: " / "pre-<n>" ⊆ PHRASES (literal, ci)
// Broader than Sweep-1 by construction; never narrower.
// Faithfulness, per Sweep-1 alternative:
// - Iter / Family / pre- / <n> sketch / 21.g / **Status:
// → sweep1_line_anchor() reproduces each verbatim,
// case-SENSITIVE (grep -E, no -i) — exactly Sweep-1 here,
// never narrower.
// - ^[^/]*2026-NN-NN → date_anchor() reproduces Sweep-1's
// ^[^/]* PATH-EXCLUSION (only the line prefix before the
// first '/' is scanned) and generalises 2026→20NN
// (⊇ Sweep-1, never narrower). A `docs/specs/2026-..`
// citation has '/' before the date ⇒ NOT flagged — faithful
// to Sweep-1, no over-fire on legit present-tense spec
// cross-refs (the iter-.1 plan defect this repairs).
// - PHRASES: literal decision-record idioms (case-insensitive) —
// the deliberate widening that closes the capital-variance
// dodge ("An earlier draft" vs "an earlier draft").
//
// A blanket case-insensitive iter/milestone detector was evaluated
// and REJECTED (audit Resolution-4 corrected): it conflates the
// memory-model rule-names "Iter A"/"Iter B", and ordinary words
// "pre-existing"/"pre-set"/"pre-Boehm"/"pre-tail-call", with
// provenance stamps — unworkable. faithful-Sweep-1 (the capital-I,
// digit-anchored form) already excludes those by construction and
// is confirmed ZERO across every contract file; lowercase
// `(iter <code>)` provenance is removed by the strip tasks, not by
// a fragile hard-gate regex. The load-bearing invariant
// (clause-3 GREEN ⟹ Sweep-1 clean in contracts/) holds with
// sweep1_line_anchor + date_anchor + PHRASES alone.
let dir = root().join("design/contracts");
// case-insensitive literal decision-record / history phrases
const PHRASES: &[&str] = &[
"we rejected", "an earlier draft", "earlier draft committed",
"why not other", "was retired", "were retired", "rollback plan",
"previously all", "deliberately deferred", "new-baseline decision",
"amends the above", "out of scope per", "**status:", "sketch",
"amends the above", "out of scope per",
"the journal records when", "unchanged from the original draft",
];
// a token that looks like an iter / milestone / family provenance code:
// a keyword followed (within 2 words) by an alnum/dot code or a digit.
fn iter_code_token(low: &str) -> Option<String> {
for kw in ["iter ", "milestone ", "family ", "axis-", "pre-"] {
// Sweep-1's non-date alternatives, hand-rolled verbatim, case-SENSITIVE
// (grep -E without -i), on the raw physical line.
fn sweep1_line_anchor(line: &str) -> Option<&'static str> {
let kw_digit = |kw: &str| -> bool {
let mut from = 0;
while let Some(i) = low[from..].find(kw) {
while let Some(i) = line[from..].find(kw) {
let p = from + i + kw.len();
let tail: String = low[p..].chars().take(12).collect();
// "iter 24.1", "iter str-concat,", "milestone 22",
// "family 18", "axis-7", "pre-22a"
if tail.chars().next().map_or(false, |c| {
c.is_ascii_alphanumeric()
}) && tail.chars().take(3).any(|c| {
c.is_ascii_digit() || c == '-' || c == '.'
}) {
return Some(format!("{kw}{tail}"));
if line[p..].chars().next().map_or(false, |c| c.is_ascii_digit()) {
return true;
}
from = p;
}
false
};
if kw_digit("Iter ") { return Some("Iter <n>"); }
if kw_digit("Family ") { return Some("Family <n>"); }
if kw_digit("pre-") { return Some("pre-<n>"); }
if line.contains("**Status: ") { return Some("**Status:"); }
if line.contains("21.g") { return Some("21.g"); }
if let Some(s) = line.find(" sketch") {
let pre = line[..s].as_bytes();
if pre.last().map_or(false, u8::is_ascii_alphanumeric)
&& pre.iter().rev()
.take_while(|c| c.is_ascii_alphanumeric())
.any(u8::is_ascii_digit)
{
return Some("<n> sketch");
}
}
None
}
// an ISO-8601-ish date: 20NN-NN-NN
fn iso_date(b: &[u8]) -> Option<String> {
for w in b.windows(10) {
// Sweep-1's `^[^/]*2026-NN-NN`, generalised to 20NN-NN-NN,
// PATH-EXCLUDED: scan only the line prefix BEFORE the first '/'.
fn date_anchor(line: &str) -> Option<String> {
let prefix = line.split('/').next().unwrap_or(line).as_bytes();
for w in prefix.windows(10) {
if w[0] == b'2' && w[1] == b'0'
&& w[2].is_ascii_digit() && w[3].is_ascii_digit()
&& w[4] == b'-' && w[5].is_ascii_digit() && w[6].is_ascii_digit()
@@ -132,24 +164,22 @@ fn contracts_carry_no_decision_record_prose() {
continue;
}
let raw = fs::read_to_string(&p).unwrap();
let fname = p.file_name().unwrap().to_string_lossy().into_owned();
let low = norm(&raw).to_lowercase();
for ph in PHRASES {
assert!(
!low.contains(ph),
"clause-3: history/decision-record phrase {:?} in contract {:?}",
ph, p.file_name().unwrap()
"clause-3: history phrase {ph:?} in contract {fname:?}"
);
}
assert!(
iter_code_token(&low).is_none(),
"clause-3: iter/milestone provenance code {:?} in contract {:?}",
iter_code_token(&low).unwrap(), p.file_name().unwrap()
);
assert!(
iso_date(raw.as_bytes()).is_none(),
"clause-3: ISO date {:?} in contract {:?} (history anchor)",
iso_date(raw.as_bytes()).unwrap(), p.file_name().unwrap()
);
for line in raw.lines() {
if let Some(a) = sweep1_line_anchor(line) {
panic!("clause-3: Sweep-1 anchor {a:?} in contract {fname:?}: {line:?}");
}
if let Some(d) = date_anchor(line) {
panic!("clause-3: history date {d:?} in contract {fname:?}: {line:?}");
}
}
}
}
```
@@ -157,11 +187,12 @@ fn contracts_carry_no_decision_record_prose() {
- [ ] **Step 2: Verify clause-3 is now RED against the un-stripped tree**
Run: `cargo test -p ailang-core --test design_index_pin contracts_carry_no_decision_record_prose 2>&1 | tail -8`
Expected: **FAIL** the assertion fires on the still-present history
prose (e.g. `clause-3: ISO date "2026-05-13" in contract "str-abi.md"`
or `iter/milestone provenance code "iter 24.1…"`). This is the
required RED: the widened gate correctly catches what the 6 literal
markers missed.
Expected: **FAIL** — fires on still-present history prose: a PHRASES
hit (e.g. `clause-3: history phrase "deliberately deferred" in
contract "str-abi.md"`) and/or the path-excluded date
(`clause-3: history date "2026-05-13" in contract "str-abi.md"`).
This is the required RED: the widened gate catches what the 6
literal case-sensitive markers missed (the capital-variance dodge).
- [ ] **Step 3: Verify the other 3 clauses + build still GREEN**
@@ -324,6 +355,57 @@ Expected: `CLEAN: stale below gone`. Run
---
## Task 5b: residual lowercase provenance stamps (exhaustive-scan additions)
> The audit's `[medium]` finding was a 3-file spot-check. The
> planning-time exhaustive scan found two more contract files
> carrying lowercase `iter <code>` provenance the audit missed
> (audit Resolution corrected in the same iter). These are spirit
> cleanup — faithful-Sweep-1/clause-3 do NOT trip on them (lowercase,
> no digit-anchored capital `Iter`), so they are not gate-blocking,
> but a contract carrying "iter form-a.1" is exactly the residue this
> milestone exists to remove. Strip + journal-note for completeness.
**Files:**
- Modify: `design/contracts/roundtrip-invariant.md:73`
- Modify: `design/contracts/data-model.md:149,161`
- Modify: `docs/journals/2026-05-19-design-decision-records.md` (append under the tidy section)
- [ ] **Step 1: Append the provenance to the journal**
```markdown
### roundtrip-invariant.md / data-model.md — corpus + loop-recur provenance
The Form-A round-trip corpus was flipped from `.ail.json` to `.ail`
at iter form-a.1. The `loop`/`recur` schema entries were added at
loop-recur iter 1 (strictly additive; pre-existing fixtures hash
bit-identically). Provenance only — the present-tense schema/contract
is the entry shapes themselves.
```
- [ ] **Step 2: Strip the stamps, keep the present-tense contract**
- `roundtrip-invariant.md:73` `… in at least one `.ail` fixture (corpus flipped from `.ail.json` to `.ail` at iter form-a.1). New AST` → drop the parenthetical: `… in at least one `.ail` fixture. New AST` (the invariant is "every variant appears in ≥1 `.ail` fixture"; the flip provenance is journal-class).
- `data-model.md:149` `// loop-recur iter 1: strict iteration block. `binders` declares``// loop: strict iteration block. `binders` declares` (drop `-recur iter 1:` → the schema-comment names the construct, not the iter).
- `data-model.md:161` `// loop-recur iter 1: re-enter the lexically innermost enclosing``// recur: re-enter the lexically innermost enclosing` (this entry is the `recur` schema — name it `recur`, drop the iter stamp).
- Leave `data-model.md:154` `pre-existing fixtures hash bit-identically` untouched — "pre-existing" is an ordinary present-tense word, NOT provenance (faithful-Sweep-1's `pre-[0-9]` does not match it; confirmed).
- [ ] **Step 3: Verify no lowercase `iter <code>` provenance remains in contracts**
Run: `grep -rnoE 'iter [a-z0-9][-a-z0-9.]*[0-9]' design/contracts/ | grep -ivE 'iteration|iterat' || echo "CLEAN: no iter-code provenance"`
Expected: `CLEAN: no iter-code provenance` (the `(iter 24.1)` /
`iter str-concat` / `iter form-a.1` / `loop-recur iter 1` stamps all
removed by Tasks 3 + 5b; `iteration`-word usages excluded). Run
`cargo test -p ailang-core --test design_schema_drift 2>&1 | grep 'test result:'`
then `cargo test -p ailang-surface --test round_trip 2>&1 | grep 'test result:'`
Expected: both PASS — `design_schema_drift` anchors on the JSON
`"t": "loop"` / `"t": "recur"` schema tokens (untouched; only the
prose comment changed), and the round-trip corpus is
content-unchanged.
---
## Task 6: re-scope `architect_sweeps.sh` honesty sweeps + lockstep doc
**Files:**
@@ -358,7 +440,7 @@ change.
- [ ] **Step 3: Verify the sweep now scans contracts only**
Run: `bash bench/architect_sweeps.sh; echo "exit=$?"`
Expected: at this point Tasks 25 have stripped the contract
Expected: at this point Tasks 25b have stripped the contract
history, so **`exit=0`** and `All five sweeps clean.` (If exit 1
with a `design/contracts/...` match, a history span was missed —
fix it; if the match is `design/models/...` the glob narrowing
@@ -397,11 +479,18 @@ Expected: `CLEAN` (no live-ref regression from the tidy edits).
## Self-review (planner Step 5)
1. **Spec/Resolution coverage:** Task 1 = Resolution-4 (clause-3
widen); Tasks 24 = Resolution-1 (history → journal, 3 files);
Task 5 = Resolution-2 (stale "below"); Task 6 = Resolution-3
(sweep re-scope + lockstep); Task 7 = Resolution-5 exit state.
All 5 points covered. ✓
1. **Spec/Resolution coverage:** Task 1 = Resolution-4 (clause-3 =
faithful-Sweep-1 + path-excluded-date + PHRASES; the
case-insensitive-iter-detector mechanism was found unworkable and
is corrected in the audit Resolution + this plan — it conflated
the "Iter A/B" rule-names and "pre-existing"/"pre-set" with
provenance); Tasks 24 = Resolution-1 (history → journal, the 3
audit-named files); Task 5 = Resolution-2 (stale "below"); Task
5b = Resolution-1 scope correction (the planning-time exhaustive
scan found 2 more contract files with lowercase provenance the
audit's 3-file spot-check missed); Task 6 = Resolution-3 (sweep
re-scope + lockstep); Task 7 = Resolution-5 exit state. All
points covered, scope corrected on evidence. ✓
2. **Placeholder scan:** no TBD/TODO/"similar to". Every strip names
the exact recon line + verbatim before→after text. ✓
3. **Type/path consistency:** `design/contracts/str-abi.md`,
@@ -428,16 +517,23 @@ Expected: `CLEAN` (no live-ref regression from the tidy edits).
no gate depends on a later task's code. Build green throughout
(test compiles; only its runtime assertion is RED until the
strip lands). ✓
8. **Verification filter strings resolve:** `--test
8. **Verification filter strings resolve:** `-p ailang-core --test
design_index_pin` / `design_schema_drift` / `docs_honesty_pin` /
`effect_doc_honesty_pin` / `eq_float_noinstance` /
`show_no_instance_e2e` all exist (iter .1 created/retargeted
them). The clause-3 filter
`contracts_carry_no_decision_record_prose` is the exact fn name.
Task 7 Step 3 uses the **unfiltered** `cargo test --workspace`
with a numeric `failed=0` + `passed≥646` assertion (cannot
masquerade as "nothing ran"). The `grep`/`bash architect_sweeps`
gates have explicit `CLEAN`/`exit=0` sentinels. ✓
`effect_doc_honesty_pin`, `-p ail --test eq_float_noinstance` /
`show_no_instance_e2e`, and `-p ailang-surface --test round_trip`
(Task 5b — corrected to its real crate `ailang-surface`, not
`ail`) all exist (iter .1 created/retargeted them). The clause-3
filter `contracts_carry_no_decision_record_prose` is the exact fn
name. Task 7 Step 3 uses the **unfiltered** `cargo test
--workspace` with a numeric `failed=0` + `passed≥646` assertion
(cannot masquerade as "nothing ran"). The `grep`/`bash
architect_sweeps` gates have explicit `CLEAN`/`exit=0` sentinels;
Task 5b Step 3's `grep … || echo "CLEAN…"` likewise. ✓
Plan is placeholder-free; the widened clause-3 is a hand-rolled
provable Sweep-1 superset (no `regex` dep). Hand off to `implement`.
Plan is placeholder-free; clause-3 is a hand-rolled **faithful**
Sweep-1 superset — faithful-Sweep-1 line anchors (case-sensitive,
digit-anchored — confirmed ZERO across all contracts) + Sweep-1's
path-excluded date + the audit-named decision-record phrases; **no
`regex` dep, no blanket iter detector** (the rejected mechanism).
The audit Resolution-4 is corrected in lockstep. Hand off to
`implement`.