iter design-ledger-formal-links.1 (DONE 5/5): clause-5 hard gate + 7 prose-ref conversions + 2 disposition-(b) homeless removals + honesty-rule positive-half (whole milestone in one iter)
Positive-half completion of the DESIGN.md -> design/ split: design/
body cross-references are now formal, file-relative Markdown links
into the durable tier (design/ or source), and a new in-tree hard
gate (design_index_pin.rs clause-5,
design_body_links_are_durable_and_resolve) walks every
design/contracts/*.md + design/models/*.md, strips fenced code
(strip_fences toggles on ```/~~~ lines so a ]( inside a fence is not
treated as a link), extracts every ](path), and asserts the target
resolves file-relative to a real file under design/-or-crates/-or-
runtime/; never docs/, never an in-file #anchor.
RED-first via identity-stubbed strip_fences (four embedded synthetic
vectors -- first one FAILS); replacing the stub with the real
toggle-on-fence impl turns the test GREEN. clause-5 composes with
clause-3 into the complete invariant the milestone establishes:
every contract cross-reference is EITHER a resolving durable
file-link OR clause-3-forbidden decision-record prose.
Conversions (recon-and-corpus-verified closed set):
Task 2 (7 prose refs, 8 link tokens):
float-semantics.md:69 Prelude classes -> [..](typeclasses.md)
float-semantics.md:100 bare-path -> [Str ABI](str-abi.md)
embedding-abi.md:45 "Frozen value layout" -> [..](frozen-value-layout.md) (drop stale "below")
memory-model.md:44 Data model -> [..](data-model.md)
memory-model.md:105-106 Method dispatch -> [..](typeclasses.md) (drop stale "below"; the target heading lives in typeclasses.md:227, not in this file)
scope-boundaries.md:48 Str ABI -> [..](str-abi.md)
scope-boundaries.md:88 mixed split: ailang-core::desugar -> source link + Pipeline -> ../models/pipeline.md (drop stale "above")
Task 3 (2 disposition-(b) homeless removals):
pipeline.md:60-61 (see docs/PROSE_ROUNDTRIP.md) pointer removed, CLI prose preserved
authoring-surface.md:178-181 cross-tier pointer clause removed, ail merge-prose sentence preserved
Task 4: honesty-rule.md positive-half paragraph inserted between L14 and the existing L15-blank-L16; both docs_honesty_pin.rs-pinned phrases byte-identical at L14/L19 (now shifted to L19 -> L25 by the +6 lines).
Out of scope, preserved (asserted independently): every intra-file
"above/below"; embedding-abi.md:51 "frozen value layout below
specifies" (no quoted title, no (see) form); data-model.md
38/66/79/206/226 (in-fence ```jsonc schema annotations -- the inline
analog of the nominal-mention carve-out). INDEX.md and the
decision-records journal byte-unchanged; clauses 1-4 of
design_index_pin.rs source byte-unchanged (the only `-` lines in
the diff are the two-line //! header rewrite Task 1 Step 5 itself
delivers).
Boss-verified independently (not on agent report alone):
cargo test --workspace 647 passed / 0 failed
(+1 vs pre-milestone 646:
the new clause-5)
cargo test --test design_index_pin 5 / 5 passed
cargo test --test docs_honesty_pin 5 / 5 passed (additive
paragraph is pin-safe)
grep ](.../docs/.../) under design/ zero
grep ](#) under design/ zero
](-link count under design/ 8 (closed convert-set)
git diff --quiet design/INDEX.md ok
git diff --quiet decision-records ok
embedding-abi.md:48 pinned phrase byte-identical
One Concerns item: Task-5 Step-7's plan-predicted "`-` line count = 1"
was actually 2 because Task 1 Step 5 rewrote the //! header 5 -> 8
lines (removing the original L4 + L5, not just L5). Planner self-
review-item-8 miss on my part -- a verification-arithmetic error in
the plan, NOT an implementation defect. The substantive assertion
(clauses 1-4 source byte-unchanged) is fully satisfied; the
implementer correctly flagged it and proceeded. The plan stands as
written; the assertion's `1` should have been `2`. Lesson noted for
future header-rewrite tasks.
Spec: docs/specs/2026-05-19-design-ledger-formal-links.md
(grounding-check PASS x3 across two corpus-grounded amendments --
clause-6 + cross-ref definition; clause-5 fence-skip + closed
convert-set enumeration).
Next: mandatory milestone-close audit (no fieldtest -- zero
authoring-surface change, reasoned exclusion).
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"iter_id": "design-ledger-formal-links.1",
|
||||
"date": "2026-05-19",
|
||||
"mode": "standard",
|
||||
"outcome": "DONE",
|
||||
"tasks_total": 5,
|
||||
"tasks_completed": 5,
|
||||
"reloops_per_task": { "1": 0, "2": 0, "3": 0, "4": 0, "5": 0 },
|
||||
"review_loops_spec": 0,
|
||||
"review_loops_quality": 0,
|
||||
"blocked_reason": null
|
||||
}
|
||||
@@ -1,8 +1,11 @@
|
||||
//! Structural pin for the design/ ledger. Sibling of
|
||||
//! docs_honesty_pin.rs. Fails RED the instant the design/ split
|
||||
//! re-conflates contract + rationale + narrative, an INDEX row
|
||||
//! dangles, a contract loses its ratifying test, or docs/DESIGN.md
|
||||
//! is resurrected. Spec: docs/specs/2026-05-19-design-md-rolesplit.md.
|
||||
//! dangles, a contract loses its ratifying test, docs/DESIGN.md is
|
||||
//! resurrected, or a design/ body cross-link fails to resolve into
|
||||
//! the durable tier (clause-5; spec
|
||||
//! docs/specs/2026-05-19-design-ledger-formal-links.md). Spec for
|
||||
//! the split: docs/specs/2026-05-19-design-md-rolesplit.md.
|
||||
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
@@ -250,3 +253,118 @@ fn contracts_carry_no_decision_record_prose() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn design_body_links_are_durable_and_resolve() {
|
||||
// clause 5 — every inline Markdown link in design/ body prose
|
||||
// (contracts/ + models/, NOT INDEX.md — the spine is the
|
||||
// structured registry tier resolved by clause-1, commitment 4)
|
||||
// resolves, relative to its CONTAINING file, to an existing
|
||||
// file under design/ or source (crates/** | runtime/**); never
|
||||
// under docs/; never an in-file #anchor. Fenced code blocks are
|
||||
// not scanned (a `](` inside ``` is literal text, not a link).
|
||||
// Composes with clause-3: a surviving cross-reference is a
|
||||
// resolving durable file-link or it is clause-3-forbidden
|
||||
// decision-record prose.
|
||||
|
||||
// Fenced code (``` … ``` / ~~~ … ~~~) is literal text, not
|
||||
// Markdown — a `](` inside a fence is NOT a navigable link on
|
||||
// any renderer. Strip fenced regions before scanning (gate
|
||||
// correctness: prevents false extraction of code-example byte
|
||||
// sequences and of non-rendering in-fence links).
|
||||
fn strip_fences(md: &str) -> String {
|
||||
let mut out = String::new();
|
||||
let mut in_fence = false;
|
||||
for line in md.lines() {
|
||||
let t = line.trim_start();
|
||||
if t.starts_with("```") || t.starts_with("~~~") {
|
||||
in_fence = !in_fence;
|
||||
continue; // drop the fence marker line itself
|
||||
}
|
||||
if !in_fence {
|
||||
out.push_str(line);
|
||||
out.push('\n');
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
// link target := first capture of \]\(([^)]+)\)
|
||||
fn targets(md: &str) -> Vec<String> {
|
||||
let mut out = Vec::new();
|
||||
let b = md.as_bytes();
|
||||
let mut i = 0;
|
||||
while i + 1 < b.len() {
|
||||
if b[i] == b']' && b[i + 1] == b'(' {
|
||||
if let Some(end) = md[i + 2..].find(')') {
|
||||
out.push(md[i + 2..i + 2 + end].trim().to_string());
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
fn is_durable(repo_rel: &str) -> bool {
|
||||
repo_rel.starts_with("design/")
|
||||
|| repo_rel.starts_with("crates/")
|
||||
|| repo_rel.starts_with("runtime/")
|
||||
}
|
||||
|
||||
// RED-first synthetic vectors (proves the gate bites before it
|
||||
// is pointed at the live tree).
|
||||
{
|
||||
let t = targets("see [x](../docs/specs/foo.md) and [y](#sec) and [z](./gone.md)");
|
||||
assert_eq!(t, vec!["../docs/specs/foo.md", "#sec", "./gone.md"]);
|
||||
assert!(!is_durable("docs/specs/foo.md")); // durable-tier reject
|
||||
assert!("#sec".starts_with('#')); // in-file anchor reject
|
||||
// fenced code is not a link surface (gate correctness)
|
||||
assert!(targets(&strip_fences("```\nsee [E](e.md)\n```\n")).is_empty());
|
||||
assert_eq!(targets(&strip_fences("[k](k.md)\n```\n[n](n.md)\n```")), vec!["k.md"]);
|
||||
}
|
||||
|
||||
let bases = ["design/contracts", "design/models"];
|
||||
for base in bases {
|
||||
let dir = root().join(base);
|
||||
for entry in fs::read_dir(&dir).expect("design/ subdir exists") {
|
||||
let p = entry.unwrap().path();
|
||||
if p.extension().and_then(|e| e.to_str()) != Some("md") {
|
||||
continue;
|
||||
}
|
||||
let raw = fs::read_to_string(&p).unwrap();
|
||||
let fname = format!("{base}/{}", p.file_name().unwrap().to_string_lossy());
|
||||
for tgt in targets(&strip_fences(&raw)) {
|
||||
if tgt.starts_with("http://")
|
||||
|| tgt.starts_with("https://")
|
||||
|| tgt.starts_with("mailto:")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let file_part = tgt.split('#').next().unwrap_or(&tgt);
|
||||
assert!(
|
||||
!file_part.is_empty(),
|
||||
"clause-5: in-file #anchor link {tgt:?} in {fname:?} — \
|
||||
commitment 1 forbids fragments; split the file"
|
||||
);
|
||||
let resolved = p.parent().unwrap().join(file_part);
|
||||
let canon = resolved
|
||||
.canonicalize()
|
||||
.unwrap_or_else(|e| panic!(
|
||||
"clause-5: link {tgt:?} in {fname:?} does not resolve: {e}"
|
||||
));
|
||||
let repo_rel = canon
|
||||
.strip_prefix(root().canonicalize().unwrap())
|
||||
.unwrap_or(&canon)
|
||||
.to_string_lossy()
|
||||
.replace('\\', "/");
|
||||
assert!(
|
||||
is_durable(&repo_rel),
|
||||
"clause-5: link {tgt:?} in {fname:?} targets the \
|
||||
non-durable tier ({repo_rel:?}); commitment 2 \
|
||||
permits design/ + crates/ + runtime/ only"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ exact. The swarm artefact is data-race-free, sanitiser-verified.
|
||||
The staticlib swarm artefact is **RC-only**:
|
||||
`ail build --emit=staticlib` rejects `--alloc=gc`/`--alloc=bump`
|
||||
(the shared Boehm collector is not swarm-safe). The value/record
|
||||
layout is **frozen as of M3** (see "Frozen value layout" below); the
|
||||
layout is **frozen as of M3** (see [Frozen value layout](frozen-value-layout.md)); the
|
||||
ctx-threaded C signature is the M2 shape.
|
||||
|
||||
Export parameters are written **bare**: a scalar type carries no
|
||||
|
||||
@@ -66,7 +66,7 @@ no `f32` variant. The runtime / codegen contract:
|
||||
|
||||
The same libc-`%g` rendering applies to `show 1.5` / `show nan` /
|
||||
`show inf` via `instance Show Float` (which calls `float_to_str`
|
||||
internally — see §"Prelude (built-in) classes" for the Show ship).
|
||||
internally — see [Prelude (built-in) classes](typeclasses.md) for the Show ship).
|
||||
The NaN-spelling caveat above is observable via `do print x` for
|
||||
Float-typed `x`; the rendering is libc-version-dependent and
|
||||
target-libc-specific. AILang does NOT canonicalise Float textual
|
||||
@@ -97,7 +97,7 @@ LLM-author wants. Use ordering operators (`<`, `>`, ...) and
|
||||
|
||||
`float_to_str` (Float → Str) and `int_to_str` (Int → Str) are
|
||||
fully wired through checker, codegen, and runtime. Both allocate
|
||||
a fresh heap-Str slab at the call site (see design/contracts/str-abi.md
|
||||
a fresh heap-Str slab at the call site (see [Str ABI](str-abi.md)
|
||||
for the dual realisation) and carry `ret_mode: Own` so the let-binder
|
||||
for the call result is RC-tracked and the slab is freed at scope
|
||||
close.
|
||||
|
||||
@@ -13,6 +13,12 @@ Two things never belong in a contract or model file:
|
||||
Decision-records are journal content, not ledger content; this is
|
||||
the honesty rule it holds itself to.
|
||||
|
||||
A cross-reference that does belong stays: it is a formal,
|
||||
file-relative Markdown link into the durable tier (`design/` or
|
||||
source), enforced by `design_index_pin.rs` clause-5. A reference
|
||||
that cannot be expressed as such a link is, by that fact, the
|
||||
history-or-rationale prose the rule above removes.
|
||||
|
||||
The single legitimate exception is a present-tense reserved or
|
||||
deliberately-excluded claim that is explicitly and correctly
|
||||
labelled. The discriminator is not whether a sentence mentions past
|
||||
|
||||
@@ -41,7 +41,7 @@ The form-A surface for fn signatures gains mode wrappers:
|
||||
|
||||
Internally, this is *not* a new `Type` variant. Modes are
|
||||
metadata on `Type::Fn` — `paramModes` and `retMode` fields run
|
||||
parallel to `params` and `ret` (see §"Data model" for the JSON
|
||||
parallel to `params` and `ret` (see [Data model](data-model.md) for the JSON
|
||||
schema). The substantive reasons for per-position metadata over a
|
||||
`Type::Borrow` / `Type::Own` variant approach:
|
||||
|
||||
@@ -102,8 +102,8 @@ Three schema fields carry class references in this form:
|
||||
`ClassDef.name` itself stays bare (defining-site context, like
|
||||
`TypeDef.name`).
|
||||
|
||||
Method dispatch is type-driven post-mq.3 (see §"Method dispatch"
|
||||
below): synth resolves a `Term::Var { name: "show" }` by consulting
|
||||
Method dispatch is type-driven post-mq.3 (see [Method dispatch](typeclasses.md)):
|
||||
synth resolves a `Term::Var { name: "show" }` by consulting
|
||||
the workspace's method-to-candidate-class index, filtering by
|
||||
argument type (concrete) or by declared constraint (rigid-var), and
|
||||
routing the residual through the registry at fn-body-end discharge.
|
||||
|
||||
@@ -45,7 +45,7 @@ What **is** supported (and used as the smoke test for the pipeline):
|
||||
`float_to_int_truncate : (Float) -> Int` (saturating, NaN → 0),
|
||||
`float_to_str : (Float) -> Str`,
|
||||
`int_to_str : (Int) -> Str` (both allocate a heap-Str slab at
|
||||
call time and return it with `ret_mode: Own`; see "Str ABI" for
|
||||
call time and return it with `ret_mode: Own`; see [Str ABI](str-abi.md) for
|
||||
the dual heap-/static-Str realisation); inspection
|
||||
`is_nan : (Float) -> Bool` (LLVM
|
||||
`fcmp uno`); Float bit-pattern constants `nan : Float`,
|
||||
@@ -85,7 +85,7 @@ What **is** supported (and used as the smoke test for the pipeline):
|
||||
another `Ctor`, or a literal. The desugar pass flattens
|
||||
nested Ctor patterns into a chain of let + match and rewrites every
|
||||
`Pattern::Lit` (top-level or sub-) to a `Term::If` on `==` before
|
||||
typecheck/codegen — see `ailang-core::desugar` and Pipeline above.
|
||||
typecheck/codegen — see [desugar](../../crates/ailang-core/src/desugar.rs) and [Pipeline](../models/pipeline.md).
|
||||
- Literal patterns at top level and inside Ctor sub-patterns (via desugar).
|
||||
`(pat-lit 0)` and `(pat-ctor Cons (pat-lit 0) _)` both
|
||||
parse and lower; the rewrite is to `Term::If { cond = (== sv lit) }`,
|
||||
|
||||
@@ -177,8 +177,8 @@ human readers. Form (B) inverts the trade-offs:
|
||||
Critically, **form (B) has no parser**. Form (A) is round-trippable
|
||||
by construction (Decision 6 constraint 2); form (B) deliberately is
|
||||
not. Re-integrating prose edits requires an external LLM mediator,
|
||||
not a compiler pass — see `docs/PROSE_ROUNDTRIP.md` for the
|
||||
six-step cycle and the prompt template `ail merge-prose` composes.
|
||||
not a compiler pass — the prompt template `ail merge-prose`
|
||||
composes the six-step cycle.
|
||||
|
||||
Form (B) does not weaken any Decision 6 invariant:
|
||||
|
||||
|
||||
@@ -58,7 +58,6 @@ ail parse <module.ail> — form-A text → canonical JSON-AST
|
||||
ail prose <module.ail.json> — JSON-AST → form-B (lossy human prose, no parser)
|
||||
ail merge-prose <m.ail.json> <m.prose.txt>
|
||||
— compose the LLM-mediator prompt for the prose round-trip
|
||||
(see docs/PROSE_ROUNDTRIP.md)
|
||||
ail deps <module.ail.json> — list cross-module references
|
||||
ail diff <a.ail.json> <b.ail.json> — content-addressed def-level diff
|
||||
ail workspace <entry.ail.json> — list all modules transitively reachable from entry
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
# iter design-ledger-formal-links.1 — formal cross-links + hard-gate clause-5
|
||||
|
||||
**Date:** 2026-05-19
|
||||
**Started from:** 36599be
|
||||
**Status:** DONE
|
||||
**Tasks completed:** 5 of 5
|
||||
|
||||
## Summary
|
||||
|
||||
Positive-half completion of the DESIGN.md → design/ split: `design/`
|
||||
body cross-references are now formal, file-relative Markdown links
|
||||
into the durable tier (`design/` or source), and a new in-tree hard
|
||||
gate (`design_index_pin.rs` clause-5,
|
||||
`design_body_links_are_durable_and_resolve`) walks every
|
||||
`design/contracts/*.md` + `design/models/*.md`, strips fenced code,
|
||||
extracts every `](path)`, and asserts the target resolves
|
||||
file-relative to a real file under `design/`-or-`crates/`-or-
|
||||
`runtime/` — never `docs/`, never an in-file `#anchor`. RED-first was
|
||||
established via four embedded synthetic-vector asserts on an
|
||||
identity-stubbed `strip_fences`; replacing the stub with the real
|
||||
toggle-on-fence impl turns the test GREEN. Seven prose cross-refs
|
||||
were converted to `[label](path)` links (8 link tokens total — the
|
||||
mixed-referent `scope-boundaries.md:88` split carries two), the two
|
||||
homeless `(see docs/PROSE_ROUNDTRIP.md)` pointers were resolved via
|
||||
clause-6 disposition (b) (pointer removed, surrounding behavioural
|
||||
prose preserved), and a pin-safe positive-half paragraph was inserted
|
||||
into `honesty-rule.md` after the existing clause-3 paragraph,
|
||||
explicitly naming `design_index_pin.rs` clause-5 as the gate and
|
||||
keeping both `docs_honesty_pin.rs`-pinned phrases byte-identical.
|
||||
`design/INDEX.md` and the decision-records journal are byte-unchanged
|
||||
(commitment 4 / Acceptance 5). Whole-workspace tests: **647 passed /
|
||||
0 failed** (+1 from the pre-milestone 646: the new clause-5).
|
||||
|
||||
**Composition-invariant assertion** (Acceptance 5; spec
|
||||
testing-strategy §Composition with clause-3): on the post-milestone
|
||||
tree, for every `design/contracts/*.md`, clause-3 GREEN ∧ clause-5
|
||||
GREEN — independently verified by running both tests in the same
|
||||
suite. Every cross-reference in a contract is therefore either a
|
||||
resolving durable file-link **or** it is gone (clause-3 would
|
||||
otherwise have rejected it as decision-record prose). The two
|
||||
clauses now form the complete invariant the split promised.
|
||||
|
||||
## Per-task notes
|
||||
|
||||
- iter design-ledger-formal-links.1.1: clause-5 hard gate added to
|
||||
`crates/ailang-core/tests/design_index_pin.rs` (RED-first via
|
||||
identity-stubbed `strip_fences`; GREEN after real toggle-on-fence
|
||||
impl; `//!` header extended one sentence; 5/5 tests pass).
|
||||
- iter design-ledger-formal-links.1.2: seven prose cross-refs
|
||||
converted to file-relative `[label](path)` Markdown links
|
||||
(`float-semantics.md:69, :100`; `embedding-abi.md:45`;
|
||||
`memory-model.md:44, :105-106`; `scope-boundaries.md:48, :88` —
|
||||
the last splits into two links, source-link + cross-models link).
|
||||
- iter design-ledger-formal-links.1.3: clause-6 disposition (b)
|
||||
applied to the two homeless `(see docs/PROSE_ROUNDTRIP.md)`
|
||||
pointers (`pipeline.md:60-61`, `authoring-surface.md:178-181`) —
|
||||
pointer removed, present-tense behavioural prose about
|
||||
`ail merge-prose` and the six-step cycle preserved.
|
||||
- iter design-ledger-formal-links.1.4: positive-half paragraph
|
||||
inserted into `honesty-rule.md` between lines 14 and 15 — names
|
||||
formal links into the durable tier as the surviving
|
||||
cross-reference form and `design_index_pin.rs` clause-5 as the
|
||||
gate. Pin-safe (both `docs_honesty_pin.rs`-pinned phrases stay
|
||||
byte-identical, no clause-3 PHRASE or Sweep-1 anchor introduced).
|
||||
- iter design-ledger-formal-links.1.5: whole-workspace gate +
|
||||
acceptance-criteria spot-checks (zero `docs/`-targeting links,
|
||||
zero `#fragment` links, exactly 8 `](path)` tokens introduced, 5
|
||||
in-fence refs untouched, INDEX + decision-records journal
|
||||
byte-unchanged).
|
||||
|
||||
## Concerns
|
||||
|
||||
- Task 5 Step 7 planner predicted-count discrepancy: the plan
|
||||
expected exactly **1** removed line in the test-file diff
|
||||
(interpreting Step 5's `//!` header replacement as a single-line
|
||||
edit), but the actual diff shows **2** removed lines because Step
|
||||
5's verbatim before→after rewords lines 4 *and* 5 of the original
|
||||
`//!` block (5-line block → 8-line block). Clauses 1–4 source
|
||||
content (line range 7+ of the file) is byte-unchanged, which is
|
||||
the load-bearing Acceptance 1; the 2-vs-1 mismatch is purely in
|
||||
the planner's predicted byte-count of the `//!` header rewording
|
||||
it itself mandated. Plan-pseudo-vs-reality class (cf.
|
||||
feedback_plan_pseudo_vs_reality), Step-5 verbatim taking precedence
|
||||
over Step-7 predicted-count.
|
||||
|
||||
## Known debt
|
||||
|
||||
- (none — the milestone closes the positive-half side of the
|
||||
contract/decision-record split; the spec's named acceptance set is
|
||||
exhaustive and closed; intra-file directional prose remains
|
||||
explicitly out of scope, with file-split as the documented future
|
||||
remedy under commitment 1 if a file ever grows enough that
|
||||
"above"/"below" loses clarity).
|
||||
|
||||
## Files touched
|
||||
|
||||
- `crates/ailang-core/tests/design_index_pin.rs` (header + appended
|
||||
clause-5)
|
||||
- `design/contracts/float-semantics.md` (lines 69, 100)
|
||||
- `design/contracts/embedding-abi.md` (line 45)
|
||||
- `design/contracts/memory-model.md` (lines 44, 105-106)
|
||||
- `design/contracts/scope-boundaries.md` (lines 48, 88)
|
||||
- `design/contracts/honesty-rule.md` (new paragraph after L14)
|
||||
- `design/models/pipeline.md` (drop line 61)
|
||||
- `design/models/authoring-surface.md` (lines 178-181 reworded)
|
||||
|
||||
## Stats
|
||||
|
||||
`bench/orchestrator-stats/2026-05-19-iter-design-ledger-formal-links.1.json`
|
||||
@@ -118,3 +118,4 @@
|
||||
- 2026-05-19 — design-decision-records (migration): relitigation-guard archive — every why/rejected/does-not-do/rollback/empirical ### moved out of the former docs/DESIGN.md by the design-md-rolesplit milestone. Companion to spec 2026-05-19-design-md-rolesplit. → 2026-05-19-design-decision-records.md
|
||||
- 2026-05-19 — audit design-md-rolesplit (milestone close): DRIFT (one tidy iteration) + bench causally-exonerated (baseline pristine). Architect drift_found, relocation byte-faithful (MIXED Decisions / dual-link / source-link / rewritten honesty-rule all match the spec Appendix vs deeffb1; build-atomicity holds; design_index_pin 4/4; honesty-rule.md correct + pins retargeted; agent contracts coherent) — one [medium] spirit-finding: faithfully-migrated decision-record/history prose in design/contracts/{typeclasses,str-abi,scope-boundaries}.md DODGES the 6 literal clause-3 markers (case+wording variance) but IS the relitigation content the split's spirit sends to journals; plus [low] float-semantics.md stale-direction "see Str ABI below". Both routed items adjudicated strippable-doc-archaeology-to-TIDY-not-ratify (the str-abi.md:23 advisory Sweep-1 exit-1 correctly diagnoses real pre-existing history residue, byte-identical DESIGN.md@deeffb1:2062-2065, faithfully migrated — not split-introduced). Bencher: NO-ratify, causally-exonerated DECISIVE on byte-evidence — emitted IR AND final -O2 binaries byte-identical 176821c vs pre-milestone dd5b183 for all 6 check.py firings (sha256+cmp), all ~11 changed code/runtime files audited comment/docstring/diagnostic-string-only, zero IR-path change; the firings are tracked-P2 (*.bump_s staleness, *_at_rc.max_us -n5 tail jitter, *.gc_s Boehm-scan variance — NOT the M5 gc_rss trio); compile_check 24/24 + cross_lang 25/25 pristine corroborate; baseline untouched (identical to M2/M3/M5). Resolution: one tidy iter design-md-rolesplit.tidy — (1) move the history prose to the decision-record journal, (2) fix the stale "below", (3) re-scope architect_sweeps honesty sweeps to design/contracts only (models/ is the explicitly-narrative tier — scanning it for history-anchors is a post-split category error), (4) widen design_index_pin.rs clause-3 to SUBSUME Sweep-1's history-anchor regex over contracts/ (invariant: clause-3 GREEN ⟹ Sweep-1 clean in contracts/ — the hard gate enforces the spirit, closing the literal-marker dodge permanently). No fieldtest (zero authoring-surface change). Milestone closes after the tidy lands Boss-verified. → 2026-05-19-audit-design-md-rolesplit.md
|
||||
- 2026-05-19 — iter design-md-rolesplit.tidy (DONE 7/7): resolves the milestone-close audit DRIFT (2ba5e16). Gate-first TDD: widened design_index_pin.rs clause-3 to a hand-rolled FAITHFUL Sweep-1 superset — case-sensitive digit-anchored Sweep-1 line anchors (confirmed ZERO across all contracts) + Sweep-1's `^[^/]*` path-EXCLUDED date_anchor (so docs/specs/2026-.. citations are not flagged) + the audit-named decision-record PHRASES (case-insensitive, closing the capital-variance dodge); NO regex dep, the blanket case-insensitive iter-detector REJECTED as unworkable (it conflated the memory-model rule-names "Iter A/B" + ordinary "pre-existing/pre-set/pre-Boehm" with provenance). Sentence-level strip of the faithfully-migrated history/decision-record prose out of 5 contract files (typeclasses/str-abi/scope-boundaries — the audit's spot-check — PLUS roundtrip-invariant.md:73 + data-model.md:149,161, the 2 the exhaustive plan-time scan found the spot-check missed) into docs/journals/2026-05-19-design-decision-records.md, each removed sentence replaced by its present-tense contract equivalent; float-semantics.md stale `(see "Str ABI" below)` → `(see design/contracts/str-abi.md)`; architect_sweeps.sh honesty sweeps re-scoped design/contracts+design/models → design/contracts only (models/ is the explicitly-narrative tier; scanning it for history-anchors is a post-split category error) + skills/audit/agents/ailang-architect.md lockstep. Invariant established: clause-3 GREEN ⟹ Sweep-1 finds nothing in contracts/. The prior dispatch correctly BLOCKED on a real plan defect (iso_date lacked Sweep-1's path-exclusion → over-fired on legit spec-path citations); per the "two+ defects in one iteration ⇒ fix the upstream artifact, not a third patch" discipline the audit Resolution mechanism+scope were corrected in lockstep (f2cdd67) before re-dispatch. Three docs_honesty_pin pinned-byte runs survived contiguous (str-abi.md:19, typeclasses.md:297, scope-boundaries.md:8 — shifted from :9 by the authorized :5-6 collapse, content byte-untouched). Boss-verified independently: cargo test --workspace 646/0, design_index_pin 4/4 (clause-3 RED→GREEN), architect_sweeps.sh exit 0 "All five sweeps clean" (acceptance criterion 9 met), acceptance grep CLEAN, 3 pins each exactly 1 contiguous match. Zero spec/quality re-loops. This is the FINAL design-md-rolesplit iteration — the milestone (DESIGN.md → design/ ledger role-split) is now functionally complete, audited, drift-resolved, and the in-code hard gate enforces the honesty spirit. → 2026-05-19-iter-design-md-rolesplit.tidy.md
|
||||
- 2026-05-19 — iter design-ledger-formal-links.1 (DONE 5/5, whole milestone): positive-half completion of the DESIGN.md → design/ split — design/ body cross-references are now formal, file-relative Markdown links `[label](path)` into the durable tier (design/ + crates/** + runtime/**), and a new in-tree hard gate `design_index_pin.rs` **clause-5** (`design_body_links_are_durable_and_resolve`) walks every design/contracts/*.md + design/models/*.md, strips fenced code (`strip_fences` toggles on ```/~~~), extracts every `](path)`, and asserts it resolves file-relative to a real durable file — never docs/, never an in-file #anchor. RED-first via identity-stubbed strip_fences (four embedded synthetic vectors — first FAILS) → real toggle-on-fence impl → GREEN. **clause-5 ∘ clause-3 = complete invariant** the milestone delivers: every contract cross-reference is either a resolving durable file-link OR clause-3-forbidden decision-record prose. Convert-set (recon-and-corpus-verified, closed): 7 prose refs / 8 link tokens — float-semantics:69/100, embedding-abi:45, memory-model:44/105 (the genuine cross-file stale-direction wart: "Method dispatch below" but the heading lives in typeclasses.md:227, not memory-model.md), scope-boundaries:48/88 (mixed-referent split: `ailang-core::desugar` → source link + Pipeline → ../models/pipeline.md). Disposition-(b) on the 2 PROSE_ROUNDTRIP homeless pointers (pipeline.md:61, authoring-surface.md:180) — pointer removed, ail merge-prose behavioural prose preserved (recon proved roundtrip-invariant.md does NOT carry the merge-prose-cycle content; the prior clause-6 sample's "(a) retarget" was thus wrong, corrected in spec amendment 1 to the three-disposition rule). honesty-rule.md positive-half paragraph inserted pin-safe between L14 and L16; both `docs_honesty_pin.rs` phrases byte-identical. Spec went through TWO corpus-grounded amendments before plan-write (grounding-check PASS ×3): (1) recon-driven — clause-6 incomplete + missing navigational/nominal cross-reference definition + OQ2/OQ3 byte-policies; (2) plan-time-corpus-driven — clause-5 fence-skip + the in-fence schema-annotation carve-out (data-model.md 38/66/79/206/226 are inside ```jsonc fences 30–87 + 203–228, where Markdown links are literal text on every renderer; the inline analog of the nominal-mention carve-out — schema-example documentation, not browsable cross-references). Per the "two+ surfaced ⇒ ground properly once, don't iter-patch" discipline, amendment 2 was the definitive corpus-grounded pass (every convert-set ref's prose-vs-fence status + exact bytes personally verified before amending), not a fourth patch returning later. INDEX-spine sub-fork resolved by user MC during brainstorm Step 2: spine stays repo-root-relative (registry tier is structurally invariant — move-fragility absent), clause-1 byte-unchanged; body uses file-relative (the converged-design path-form decision). Boss-verified independently: `cargo test --workspace` 647/0 (+1: clause-5), `design_index_pin` 5/5, `docs_honesty_pin` 5/5, design/INDEX.md + decision-records journal byte-unchanged, clauses 1–4 source byte-unchanged (the 2 `-` lines are the two-line //! header rewrite Task 1 Step 5 itself delivers — clauses are #[test] fns, untouched), 0 docs/ link targets, 0 #fragments, 8 `](` link tokens (= the closed convert-set), embedding-abi.md:48 docs_honesty_pin pinned phrase byte-identical. One Concerns item: Task-5 Step-7 plan-predicted `-`-line count was 1, actual 2 — planner self-review-item-8 arithmetic miss on the //! header rewrite (Steps 5 + 7 inconsistent within Task 1+5 about how many lines the header rewrite removes); harmless (substantive assertion *clauses 1–4 source unchanged* fully holds), recorded as lesson. Next: mandatory milestone-close audit; no fieldtest (zero authoring-surface change — reasoned exclusion). → 2026-05-19-iter-design-ledger-formal-links.1.md
|
||||
|
||||
Reference in New Issue
Block a user