iter design-md-rolesplit.1 (DONE 9/9): DESIGN.md -> design/ ledger role-split
The 3020-line docs/DESIGN.md is replaced by the design/ ledger:
design/INDEX.md (sole addressable spine, typed Contracts+Models tables,
polymorphic links — prose file OR authoritative source //!), 14
design/contracts/*.md test-linked invariants + 3 source-link-only
contracts (mangling/env-construction/qualified-xref, no prose file —
code is SoT), 5 design/models/*.md whitepapers, and
docs/journals/2026-05-19-design-decision-records.md (the
relitigation-guard archive — every why/rejected/does-not-do/rollback/
empirical ### moved out at ###-granularity). Clean cut: git rm
docs/DESIGN.md, no stub.
RED-first crates/ailang-core/tests/design_index_pin.rs — the 4-clause
anti-regrowth spine (DESIGN.md-gone / every-INDEX-link-resolves /
every-contract-names-a-resolvable-ratifier /
contracts-carry-no-decision-record-prose) — demonstrably RED before,
GREEN after. Build-atomic by task ordering: design_schema_drift.rs's
include_str! (the only compile-time consumer) retargeted to
design/contracts/data-model.md BEFORE the deletion; its
## Data model/## Pipeline slicer dropped (a simplification the split
enables). 2 NoInstance diagnostics + 2 lockstep E2Es retargeted to
design/contracts/{float-semantics,typeclasses}.md. ~12 agent reading
lists + 5 SKILL bodies + CLAUDE.md + skills/README.md + ~25
code/C/.ail/spec comment xrefs retargeted; OQ7 dangling 'Iter 13b'
cite deleted (no forward target — a pointer would be fiction).
honesty-rule.md rewritten so the rule names the new home
(rationale->journals), resolving the recon-found internal
contradiction; the two docs_honesty_pin.rs:70,72 pinned phrases kept
verbatim+contiguous.
Boss-verified independently: cargo test --workspace 646 passed /
0 failed; design_index_pin 4/4; acceptance grep CLEAN of live
DESIGN.md refs (residuals = only the spec-mandated clause-4
deletion-enforcer). 2 DONE_WITH_CONCERNS routed to the mandatory
milestone-close audit: (a) str-abi.md:23 '(iter str-concat,
2026-05-13)' provenance stamp trips advisory architect_sweeps Sweep-1
— Boss-confirmed byte-identical to DESIGN.md@deeffb1:2062-2065, a
faithfully-migrated PRE-EXISTING anchor (regexes verbatim, only path
retargeted), NOT split-introduced — RATIFY-or-tidy at audit; (b) a
now stale-direction intra-prose 'see Str ABI below' cross-ref in
float-semantics.md — audit-adjudication candidate. Plan defect noted:
Task 9 Step 4's verbatim acceptance grep used a ^./ anchor not
matching the system's grep -rIn output; substance re-verified CLEAN.
Spec grounding-check PASS x2. Journals INDEX + decision-records
pointer appended (Boss-only).
This commit is contained in:
-3020
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,431 @@
|
||||
# Design decision-records — relitigation guard (migrated 2026-05-19)
|
||||
|
||||
Why-X-chosen / why-Y-rejected / deliberately-does-not-do / rollback
|
||||
/ empirical-addendum prose, migrated out of the former
|
||||
`docs/DESIGN.md` by the design-md-rolesplit milestone. A future
|
||||
brainstorm reads this so it does not re-propose a settled-and-
|
||||
rejected idea. Order preserved from the source. This file is
|
||||
append-only history; it is NOT a contract surface.
|
||||
|
||||
|
||||
## Decision 1: source = data, not text
|
||||
|
||||
A module is a JSON object with a fixed schema. There is no parser for
|
||||
free-form text. Typos in identifiers turn into hash-lookup errors that the
|
||||
compiler proposes a fix for directly.
|
||||
|
||||
A textual form exists (`.ail`, S-expression-like), but only as a
|
||||
bidirectional projection of the JSON form. It is intended for human reviews
|
||||
and diffs.
|
||||
|
||||
**Canonical format:** `.ail.json` with deterministic key order.
|
||||
|
||||
## Decision 2: content-addressed definitions
|
||||
|
||||
Every top-level definition has a `hash` value (BLAKE3 over canonical JSON
|
||||
without the `hash` field itself). References between definitions go primarily
|
||||
by name — names are for readability. The hash is the canonical identity.
|
||||
|
||||
Advantages:
|
||||
|
||||
- Refactoring by adding new defs, not by in-place change. Old versions stay
|
||||
callable until manually removed.
|
||||
- Caching of typecheck results and codegen per hash.
|
||||
- Diffs show exactly which def has changed.
|
||||
|
||||
## Decision 4: Hindley-Milner + optional refinements
|
||||
|
||||
MVP: HM with let-polymorphism. All types are inferable, but at the top level
|
||||
they must always be explicitly annotated (for local reasoning).
|
||||
|
||||
Later: refinement annotations that escalate to SMT. `(i: Int | i >= 0)`. They
|
||||
are reserved in the AST from the start, but in the MVP they are simply passed
|
||||
through as opaque strings.
|
||||
|
||||
## Decision 5: emit LLVM IR as text
|
||||
|
||||
Instead of `inkwell` or `llvm-sys`: AILang produces `.ll` files as strings
|
||||
and hands them to `clang` for linking.
|
||||
|
||||
Rationale:
|
||||
|
||||
- The LLVM IR text syntax is largely stable across versions.
|
||||
- No build dependency on a specific libllvm version.
|
||||
- Generated code is trivially inspectable, which makes debugging much easier.
|
||||
- An LLM can read the generated IR directly, which is harder with opaque
|
||||
library calls.
|
||||
|
||||
Trade-off: no inline optimisations through the LLVM API. We rely on
|
||||
`clang -O2` as the standard pipeline.
|
||||
|
||||
The rest of this section
|
||||
records the *why* of Decision 6 for the audit trail; the constraints
|
||||
listed below describe the surface as shipped.
|
||||
|
||||
## Why this is opening up
|
||||
|
||||
Early development authored everything as raw `*.ail.json`. That worked
|
||||
for 17 fixture files (each ≤ 60 LOC of JSON) but does not scale. Two
|
||||
breaking signals:
|
||||
|
||||
1. The token-economy cost of the JSON-AST is massive: a single integer
|
||||
literal `1` is encoded as `{"t":"lit","lit":{"kind":"int","value":1}}`
|
||||
— ~38 tokens of structural overhead per bit of semantics. For a stdlib
|
||||
in the 200–500 def range this displaces real attention budget.
|
||||
2. JSON-AST authoring exposes a class of errors (wrong field names,
|
||||
silently-accepted extra fields under `#[serde(default)]`,
|
||||
inconsistent ctor casing) that surface only at load time. The
|
||||
schema is correct-by-construction in storage but **error-prone in
|
||||
authoring**.
|
||||
|
||||
Decision 1 anticipated this: it says a textual form exists "as a
|
||||
bidirectional projection of the JSON form." The pretty-printer already
|
||||
emits S-expression-style text (see `crates/ailang-core/src/pretty.rs`).
|
||||
What is missing is the inverse direction — text → AST. Decision 6
|
||||
adds that inverse as **one** authoring projection alongside the
|
||||
existing pretty-printer; the JSON-AST remains the source of truth.
|
||||
|
||||
## First choice and rollback plan
|
||||
|
||||
**Try (A) first.** Reasoning: constraint 1 (formalizable) outweighs
|
||||
constraint readability. (A) has a 3-rule core grammar with one
|
||||
lexical disambiguation rule. (B) doubles the rule count and
|
||||
re-introduces a soft form of precedence (`->` inside `forall`).
|
||||
(C) is tempting because it is zero-design but the resulting spec is
|
||||
visibly heterogeneous, which is exactly what constraint 1 was meant
|
||||
to rule out.
|
||||
|
||||
If implementing (A) reveals that paren density actively hurts my
|
||||
authoring (measurable: I make more wrong-paren errors than the
|
||||
JSON-AST shape produced before), roll back and try (C). (B) stays
|
||||
on the shelf for a future iter only if both fail.
|
||||
|
||||
## Implementation outline
|
||||
|
||||
- `crates/ailang-surface` — new crate. **Strictly additive.** PEG
|
||||
parser produces existing `ailang-core::ast` types. No new AST
|
||||
nodes, no schema changes, no new hashable form. Pretty-printer
|
||||
for form (A) lives here too (the round-trip is the contract).
|
||||
- `ailang-check`, `ailang-codegen` are **not modified**. They
|
||||
continue to consume `ailang-core::ast::Module` values regardless
|
||||
of which projection produced them.
|
||||
- Round-trip test: for every `examples/*.ail.json`, parse the
|
||||
corresponding hand-written `*.ail`, canonicalise, and assert
|
||||
hash-equivalence to the original. Hash equivalence is the truth
|
||||
check; the surface ships only if every fixture round-trips
|
||||
identically.
|
||||
- CLI: `ail parse <file.ail> -o <file.ail.json>`. Symmetric to
|
||||
existing `ail render`. **`.ail.json` remains a first-class input**
|
||||
to every existing subcommand; the parser is a producer, not a
|
||||
gatekeeper.
|
||||
|
||||
**Both extensions accepted.** Every path-taking CLI subcommand
|
||||
accepts either `.ail` (Form A)
|
||||
or `.ail.json` (Form B) as input. For `.ail` paths the subcommand
|
||||
parses through `ailang_surface::parse` in-line and then proceeds
|
||||
with the same loaded `Module` value that `.ail.json` would have
|
||||
produced. `ail parse` remains the explicit converter — it does
|
||||
nothing the implicit dispatch in the other subcommands does not,
|
||||
but it is the supported way to materialise a stable `.ail.json`
|
||||
snapshot from a `.ail` source for diff / hash / cache purposes.
|
||||
- Stdlib (`std_list`, `std_maybe`, ...) authored in
|
||||
form (A) from day one **because that is the AI authoring
|
||||
projection**, not because JSON authoring is forbidden. The
|
||||
resulting `.ail.json` is what tests and downstream tools see.
|
||||
|
||||
## What this Decision deliberately does not do
|
||||
|
||||
- It does not change which form is canonical: the JSON-AST remains
|
||||
the hashable, content-addressed representation, and all hashing,
|
||||
content-addressing, and cross-module references flow through it
|
||||
unchanged. The authored form is Form A; the JSON-AST is
|
||||
materialised in-process by callers that need it. The two
|
||||
forms are byte-isomorphic by the round-trip invariant. Form (A)
|
||||
is one projection; the JSON-AST stays canonical.
|
||||
- It does not foreclose visual or graphical front-ends. The crate
|
||||
layout (`core` owns AST; `surface`/`visual`/... are siblings)
|
||||
reserves that lane.
|
||||
- It does not remove `.ail.json` as input. Every existing
|
||||
CLI subcommand (`check`, `render`, `describe`, `emit-ir`,
|
||||
`build`, `run`, `manifest`, `deps`, `diff`, `workspace`,
|
||||
`builtins`) keeps its current `.ail.json` interface.
|
||||
|
||||
## Form refinements during implementation
|
||||
|
||||
Two productions in the original sketch had to be widened
|
||||
during implementation to round-trip the existing AST faithfully.
|
||||
Captured here for the spec record:
|
||||
|
||||
1. **`lam-term` carries types and effects.** The AST's `Term::Lam`
|
||||
stores parallel `params`, `param_tys`, `ret_ty`, and `effects`
|
||||
fields. The original sketch had only names. The implemented form is
|
||||
|
||||
```
|
||||
lam-term ::= "(" "lam" "(" "params" typed-param* ")"
|
||||
"(" "ret" type ")"
|
||||
effects-clause? body-attr ")"
|
||||
typed-param ::= "(" "typed" ident type ")"
|
||||
```
|
||||
|
||||
This keeps the no-precedence / one-construct-per-token-list
|
||||
invariants and adds no new lexical rules.
|
||||
|
||||
2. **`import-clause` admits an optional alias.** The AST's
|
||||
`Import.alias` is `Option<String>`; the original sketch only
|
||||
supported the `None` case. The implemented form is
|
||||
|
||||
```
|
||||
import-clause ::= "(" "import" ident ("as" ident)? ")"
|
||||
```
|
||||
|
||||
`as` is a bare ident token in this position; no special lexical
|
||||
rule is needed.
|
||||
|
||||
Neither change extends the grammar's rule budget meaningfully:
|
||||
the 30-production ceiling of constraint 1 is intact (the parser
|
||||
implements ~28 named productions). All 17 `examples/*.ail.json`
|
||||
fixtures round-trip identically through `print → parse → canonical
|
||||
JSON`; the three hand-written `.ail` exhibits parse to canonical
|
||||
JSON identical to their corresponding `.ail.json` files.
|
||||
|
||||
3. **Tail-call surface.** Decision 8 ships two new
|
||||
productions, both positional analogues of their non-tail
|
||||
counterparts. Their result terms set `Term::App.tail = true` /
|
||||
`Term::Do.tail = true`; the typechecker's `verify_tail_positions`
|
||||
pass enforces that the marker is only used in tail position.
|
||||
|
||||
```
|
||||
tail-app-term ::= "(" "tail-app" term term+ ")"
|
||||
tail-do-term ::= "(" "tail-do" ident term* ")"
|
||||
```
|
||||
|
||||
Production count: ~30, still inside the 30-rule
|
||||
constraint-1 budget. No new lexical rule (`tail-app` / `tail-do`
|
||||
are bare ident tokens; no special casing).
|
||||
|
||||
## Empirical addendum — cross-model authoring measurement
|
||||
|
||||
Cross-model measurement against two foreign LLMs via IONOS,
|
||||
temperature=0, top_p=1, max-turns=5. Two blind cohorts on the same
|
||||
four MVP tasks (`t1_add_three`, `t2_length`, `t3_main_prints`,
|
||||
`t4_count_zeros`); each cohort sees only its own form's mini-spec.
|
||||
Subjects (both runs use the pipeline-error-formatting fix from ms.1
|
||||
so JSON-cohort feedback carries the full anyhow cause chain):
|
||||
|
||||
- `Qwen/Qwen3-Coder-Next` —
|
||||
`experiments/2026-05-12-cross-model-authoring/runs/2026-05-12-080864/`
|
||||
- `meta-llama/CodeLlama-13b-Instruct-hf` —
|
||||
`experiments/2026-05-12-cross-model-authoring/runs/2026-05-12-9197fd/`
|
||||
|
||||
| metric | Qwen / JSON | Qwen / AIL | CodeLlama / JSON | CodeLlama / AIL |
|
||||
|---|---|---|---|---|
|
||||
| reached green | 1/4 | 1/4 | 0/4 | 2/4 |
|
||||
| first-attempt green | 1/4 | 1/4 | 0/4 | 2/4 |
|
||||
| mean turns-to-green (green only) | 1.0 | 1.0 | — | 1.0 |
|
||||
| total prompt tokens | 182,378 | 110,575 | 116,015 | 93,017 |
|
||||
| total completion tokens | 14,972 | 3,474 | 2,711 | 2,234 |
|
||||
| top error class | check (×3) | parse (×3) | check (×2) | parse (×2) |
|
||||
|
||||
Both subjects show the same direction on every metric the table
|
||||
tracks. AIL is cheaper than JSON on prompt tokens (Qwen 61%,
|
||||
CodeLlama 80% of the JSON cohort's spend) and cheaper on completion
|
||||
tokens (Qwen 23%, CodeLlama 82%). AIL reached-green is greater than
|
||||
or equal to JSON reached-green for each subject (Qwen ties at 1/4;
|
||||
CodeLlama strictly dominates, 2/4 vs 0/4). The failure-class
|
||||
symmetry observed on the original Qwen baseline holds for both
|
||||
subjects: JSON cohorts fail at the typecheck stage, AIL cohorts at
|
||||
the parse stage — each form's front-of-pipeline check. Three of the
|
||||
four first-attempt-green cells observed across the two subjects are
|
||||
AIL (Qwen-AIL t3, CodeLlama-AIL t1, CodeLlama-AIL t3); the
|
||||
fourth is Qwen-JSON t3, the same task the original baseline already
|
||||
flagged as the JSON-form's only first-attempt success. Two CodeLlama
|
||||
JSON-cohort cells (`t2_length`, `t4_count_zeros`) terminated as
|
||||
`api_failure` on turn 1 with zero tokens consumed — a transient
|
||||
IONOS-side terminal error, not a model-output failure; CodeLlama
|
||||
JSON-cohort numbers therefore average over 2 informative cells, not
|
||||
4. The Qwen re-run also shifted by one cell against the cma.3
|
||||
baseline (AIL 2/4 → 1/4, JSON 1/4 → 1/4) despite identical
|
||||
temperature=0 inputs; this is IONOS-side state-of-day noise on a
|
||||
single deterministic re-run, not an effect of the ms.1
|
||||
feedback-formatting fix (which only changes JSON-cohort prompt
|
||||
content).
|
||||
|
||||
**Scope of this addendum:** two subjects, n=1 each, deterministic.
|
||||
This is a second data point pointing in the same direction as the
|
||||
first, not a verdict. The universal claim of this Decision (".ail
|
||||
is the AI authoring projection") would need ≥3 subjects with
|
||||
statistical robustness to ratify; both current points point the
|
||||
same way (AIL cohort cheaper and at-least-as-green) but neither
|
||||
the sample size nor the cross-call noise observed in the Qwen
|
||||
re-run is enough to close out the Decision.
|
||||
|
||||
## Why not other memory models
|
||||
|
||||
**Tracing GC.** Open-ended. Boehm's bench overhead is structurally on the allocate path (JOURNAL bench notes); tuning Boehm cannot move that
|
||||
needle. A precise tracing GC would need read/write barriers,
|
||||
root maps, generational machinery — months of work, with
|
||||
irreducible pause-time variability at the end. The user's
|
||||
framing was decisive: "Am GC kannst du ewig rumschrauben (und
|
||||
bekommst trotzdem auch in 100 Jahren keine berechnbare
|
||||
Performance)."
|
||||
|
||||
**Region inference (Tofte/Talpin / MLton-style).** Considered
|
||||
seriously; rejected. Regions tie lifetimes to dynamic scope —
|
||||
every value lives in some region, regions stack on entry/exit,
|
||||
deallocation is bulk-by-region. The reduction: a region is an
|
||||
explicit allocator with sugar plus a static check that nothing
|
||||
escapes its lifetime. The deeper problem: regions assume
|
||||
**stack-shaped lifetimes**. Real programs have non-stack-shaped
|
||||
lifetimes — caches, memo tables, registries, lookup structures
|
||||
whose lifetimes are not nested. Regions would either force these
|
||||
into a `letregion` at the top of `main` (everyone's allocator
|
||||
becomes the root region — useless), or require a region per
|
||||
cache variant (combinatorial). RC has no lifetime-shape
|
||||
assumption; it works for any DAG.
|
||||
|
||||
**Linear / ownership types as primary mechanism (Rust-style).**
|
||||
Considered as a general-purpose alternative; rejected as primary.
|
||||
Rust's borrow-checker is a great mechanism but requires the
|
||||
author to thread lifetimes through every signature and accept
|
||||
that some programs cannot be expressed without `unsafe`. For an
|
||||
LLM-targeted language with recursion + closures everywhere, that
|
||||
cost is too high — most of the source surface would be lifetime
|
||||
annotations rather than logic. AILang uses a *subset* of these
|
||||
ideas (mode annotations, linear consumption discipline)
|
||||
selectively, layered on top of RC, where the annotations buy
|
||||
concrete optimisations and never have to thread lifetimes
|
||||
through callees.
|
||||
|
||||
## Why advisory + suppress instead of inference
|
||||
|
||||
Three reasons, all anchored in Decision 10's framing:
|
||||
|
||||
1. **Annotation states intent; inference picks
|
||||
weakest-supporting.** These often coincide today but are
|
||||
conceptually different. The annotation captures what the
|
||||
author committed to (e.g. `(own T)` reserved for a planned
|
||||
mutation that hasn't landed); inference would silently
|
||||
relax it.
|
||||
2. **Annotation is a drift-bremse.** Body change that flips
|
||||
the inferred mode produces caller-side breakage at remote
|
||||
sites. Annotation enforces the local-conflict-error pattern
|
||||
instead.
|
||||
3. **Forcing function for LLM authoring.** Without mandatory
|
||||
annotation, the LLM never has to commit to ownership intent
|
||||
before writing the body. The advisory lint plus suppress
|
||||
lets us flag accidental over-strictness without weakening
|
||||
the contract.
|
||||
|
||||
The suppress mechanism with mandatory-reason mirrors Rust's
|
||||
`#[allow(...)]`-style escape hatch but sharpens it: the reason
|
||||
is required (not optional), and it becomes part of the contract
|
||||
the next reader sees. CLAUDE.md's "preserve correctness across
|
||||
development cycles" is what this directly serves.
|
||||
|
||||
## Adjacent extensions for mutability (out of Decision 10's scope)
|
||||
|
||||
If future workloads need mutable arrays, hash tables, or other
|
||||
inherently mutable primitives, the answer is **not** a tracing GC
|
||||
backstop. The answer is a separate ownership/linear extension
|
||||
that gates mutability behind static single-owner discipline. RC
|
||||
+ uniqueness is the universal floor; ownership extends it for
|
||||
specific high-performance primitives without rebreaking the
|
||||
acyclicity invariant.
|
||||
|
||||
## What this Decision deliberately does not do
|
||||
|
||||
- **Does not infer everything.** AILang demands annotations
|
||||
*because* the LLM author can produce them effortlessly. The
|
||||
compiler does inference *plus* verification of contracts.
|
||||
- **Does not require existing fixtures to migrate immediately.**
|
||||
`(con T)` is treated as `(own T)`. Existing JSON hashes
|
||||
stay bit-identical until the fixture is intentionally updated.
|
||||
- **Does not commit to atomic refcounts.** AILang is
|
||||
single-threaded; refcounts are non-atomic. The embedding ABI's
|
||||
per-thread `ailang_ctx_t` keeps this correct under a host swarm:
|
||||
each thread's allocations are private to its ctx, no RC cell
|
||||
crosses a thread, so non-atomic refcounts stay sound.
|
||||
- **Does not introduce regions.** Regions were considered and
|
||||
rejected; see "Why not other memory models" above.
|
||||
|
||||
## What the typeclass design explicitly does NOT support
|
||||
|
||||
Each of the following is rejected by either schema (parser cannot
|
||||
express the construct) or by an enumerated diagnostic. The
|
||||
combination of axis-1 (single-param, no FunDeps, no assoc) and
|
||||
axis-5 (kind `*` only) covers the space.
|
||||
|
||||
- **Multi-parameter classes** (`class Foo a b where ...`). Schema
|
||||
rejects: `ClassDef.param` is a string, not a list.
|
||||
- **Higher-kinded class params** (`class Functor f`). Rejected at
|
||||
workspace-load time: `BareCrossModuleTypeRef` from canonical-form
|
||||
validation fires before class-schema validation if any method
|
||||
body uses the param as a `Type::Con` head — bare non-primitive
|
||||
names must be declared as a `TypeDef` in the owning module, and
|
||||
a class param is not.
|
||||
- **Higher-rank polymorphism** (`forall a. (forall b. b -> b) -> a`).
|
||||
Already rejected at parse time per the typeclass-conversation
|
||||
rationale recorded in JOURNAL; constraint-bearing
|
||||
signatures inherit that prohibition.
|
||||
- **Existential / dyn dispatch** (`exists a. Show a => a`,
|
||||
heterogeneous lists like `[Show]`). Schema does not express
|
||||
existentials. The LLM-natural alternative is sum types.
|
||||
- **Associated types** (`class Container c where type Element c`).
|
||||
Schema does not express type-level methods.
|
||||
- **Functional dependencies** (`class Convert a b | a -> b`). Required
|
||||
only for multi-param classes; entails by axis 1.
|
||||
- **`deriving` / auto-derivation** (`data Foo = ... deriving (Eq)`).
|
||||
Future iteration, gated separately on Feature-acceptance.
|
||||
- **Numeric literal defaulting.** `1` does not auto-resolve to `Int`
|
||||
under an ambiguous `Num a` constraint. Bare polymorphic literals
|
||||
with multiple satisfying instances fire `NoInstance` with a hint
|
||||
to annotate. The LLM-author writes `1 : Int` or `1 : Float`.
|
||||
- **Orphan-with-warning mode.** Coherence is hard. `OrphanInstance`
|
||||
is always an error, never a warning. The corollary `--allow-orphans`
|
||||
flag is not provided.
|
||||
|
||||
## What this decision does NOT commit to
|
||||
|
||||
- **Operator routing.** `==`, `<`, etc. stay primitive in milestone
|
||||
22. Class-routing operators is a future-iteration option, not a
|
||||
Decision-11 commitment.
|
||||
- **Form-B (prose) projection of class/instance.** The prose
|
||||
renderer for the class/instance schema nodes is one-way (no
|
||||
parser by design); the render in
|
||||
`crates/ailang-prose/src/lib.rs` is a placeholder and
|
||||
informational only.
|
||||
- **Specific monomorphised-symbol naming format.** Milestone 22
|
||||
uses `<method>__<type-surface-name>` for primitive type targets
|
||||
(e.g. `show__Int`) and `<method>__<8-hex-prefix>` for compound
|
||||
types (where `<8-hex-prefix>` is the BLAKE3 hash of the canonical
|
||||
type bytes). The `__` separator was chosen over `#` and `@` for
|
||||
LLVM IR identifier legality.
|
||||
- **Mode annotations on class methods.** Class method signatures
|
||||
ARE full FnSigs and DO carry mode annotations per Decision 10;
|
||||
the convention is `borrow` for read-only methods. User-defined
|
||||
classes pick modes per method.
|
||||
- **Number of Prelude classes.** Milestone 22 ships zero (no
|
||||
Prelude). A future Prelude milestone gates class additions on
|
||||
the Feature-acceptance criterion at the time of proposal.
|
||||
|
||||
## Env construction — why two parallel overlays (rationale of the code-SoT §"Env construction")
|
||||
|
||||
Behaviour of the two-overlay check environment is code-authoritative
|
||||
(the `env-construction` ledger row is source-link only); only the
|
||||
*why* moves here so a future brainstorm does not re-propose
|
||||
collapsing the two maps:
|
||||
|
||||
The split is not a refactor wart. The two maps have distinct
|
||||
semantic roles: an owning data index, and a derived lookup
|
||||
accelerator over the same data. Collapsing them into one
|
||||
variant-keyed map (`Map<Name, EntryKind>`) would force every
|
||||
type-iterator and every ctor-lookup site to discriminate the variant
|
||||
tag, reversing the optimisation the reverse index exists to
|
||||
provide.
|
||||
|
||||
The mono-side overlay was narrowed to types-only at iter ct.3.2 because its
|
||||
consumer is the runtime ctor lookup, which became type-driven
|
||||
post-ct.2.2 — a different consumer story, hence a different
|
||||
overlay shape. The asymmetry between the check side and the mono
|
||||
side is by design and is pinned by
|
||||
`crates/ailang-check/tests/duplicate_ctor_pin.rs`.
|
||||
@@ -0,0 +1,91 @@
|
||||
# iter design-md-rolesplit.1 — DESIGN.md → design/ ledger role-split (whole milestone)
|
||||
|
||||
**Date:** 2026-05-19
|
||||
**Started from:** deeffb1872cd13a9fed2a0812d69e7273f49671b
|
||||
**Status:** DONE
|
||||
**Tasks completed:** 9 of 9
|
||||
|
||||
## Summary
|
||||
|
||||
The 3020-line `docs/DESIGN.md` is replaced by the `design/` ledger:
|
||||
`design/INDEX.md` (sole addressable spine, a typed Contracts+Models
|
||||
table), 14 `design/contracts/*.md` (test-linked invariants), 5
|
||||
`design/models/*.md` (onboarding whitepapers), plus
|
||||
`docs/journals/2026-05-19-design-decision-records.md` (the
|
||||
relitigation-guard archive of every why/rejected/does-not-do/rollback
|
||||
`###`). Content was sliced from DESIGN.md by the spec Appendix line
|
||||
ranges with a deterministic Python slicer (`/tmp/ail-iter/
|
||||
design-md-rolesplit.1/slice.py`, not committed) — byte-faithful
|
||||
except (a) heading-level re-level, (b) the rewritten
|
||||
`honesty-rule.md`, (c) the OQ7 cite deletion. The RED-first
|
||||
`design_index_pin.rs` anti-regrowth spine (4 clauses) was
|
||||
demonstrably RED before and is GREEN after. Every live `DESIGN.md`
|
||||
reference in code, scripts, agents, SKILL bodies, CLAUDE.md, README,
|
||||
runtime C, `.ail` fixtures, and `form_a.md` was retargeted to the
|
||||
Appendix destination (or to a code-SoT note for the source-link
|
||||
contracts). `docs/DESIGN.md` deleted via `git rm` (staged only).
|
||||
Build-atomic by task ordering; whole `cargo test --workspace` GREEN,
|
||||
zero failures.
|
||||
|
||||
## Per-task notes
|
||||
|
||||
- design-md-rolesplit.1.1: RED-first `crates/ailang-core/tests/design_index_pin.rs` — 4-clause structural pin written; verified RED (DESIGN.md present + design/ absent). Dropped one unused `Path` import (plan-verbatim code had an unused-import warning) — recorded as a concern.
|
||||
- design-md-rolesplit.1.2: `design/INDEX.md` (spec-verbatim 2-table ledger + "## Project framing" preamble absorbing DESIGN.md:6-18/19-55/83-92) + 14 `design/contracts/*.md` sliced from the Appendix ranges + the rewritten `honesty-rule.md` (two `docs_honesty_pin.rs:70,72` phrases each contiguous on one physical line). INDEX link cells made workspace-root-relative (`design/contracts/...`) so the authoritative pin resolves them.
|
||||
- design-md-rolesplit.1.3: 5 `design/models/*.md` sliced from the Appendix model-tagged ranges; `every_index_link_resolves` PASS for all 20 link rows.
|
||||
- design-md-rolesplit.1.4: `docs/journals/2026-05-19-design-decision-records.md` — every Appendix `D` range concatenated in source order + the genuine Env-construction "why" rationale (source-link sections' behaviour dropped as code-SoT). Acceptance-criterion-2 completeness verified programmatically: every one of 66 `##`/`###` headings mapped exactly once, no overlap (only uncovered lines are DESIGN.md's own `#`-preamble :1-5 and one blank separator :244). Journals-INDEX pointer line (Step 2) **deferred to Boss** — see Concerns.
|
||||
- design-md-rolesplit.1.5: retargeted `design_schema_drift.rs` (const `DESIGN_MD`→`DATA_MODEL` include_str! → data-model.md; deleted `data_model_section()` + `data_model_section_is_bounded()`; all anchor tests use `DATA_MODEL`), `docs_honesty_pin.rs` (per-test reads point at the design/ homes; three present-anchors found to live in the decision-records journal — read from there), `effect_doc_honesty_pin.rs:21` (normalised join of effects.md + scope-boundaries.md; added `norm()`). All three GREEN; build green with DESIGN.md still present.
|
||||
- design-md-rolesplit.1.6: retargeted the Float-branch (`design/contracts/float-semantics.md`) and Show-branch (`design/contracts/typeclasses.md`, contiguous across the `\`-continuation) diagnostics in `ailang-check/src/lib.rs` + the 2 lockstep E2E assertions + module rustdocs; both E2Es GREEN.
|
||||
- design-md-rolesplit.1.7: `bench/architect_sweeps.sh` repointed (`INDEX`/`DESIGN_GLOB`, recursive grep over design/contracts+models, regexes unchanged, exit-code contract preserved, exit-2 verified). Sweep-5 honesty-rule self-quote reworded; one pre-existing advisory Sweep-1 match remains (see Concerns).
|
||||
- design-md-rolesplit.1.8: retargeted buckets (b) 12 agent files, (c) 5 SKILL bodies + skills/README.md, (d) CLAUDE.md (layout table + the "Roles of …" section, current-state-mirror discipline preserved & re-homed), (e) ~25 code/C/.ail/spec comment xrefs to the Appendix destinations (source-link contracts → code-SoT/INDEX note); OQ7 "Iter 13b" cite deleted (behaviour stated directly, no pointer). Build green.
|
||||
- design-md-rolesplit.1.9: `git rm docs/DESIGN.md` (staged); workspace build green (build-atomicity proven — the only compile-time consumer was retargeted in Task 5); `cargo test --workspace` ALL GREEN incl. `design_index_pin`'s 4 clauses (RED→GREEN); acceptance grep CLEAN of live refs (residuals = the spec-mandated clause-4 pin only); architect_sweeps contract preserved.
|
||||
|
||||
## Concerns
|
||||
|
||||
- iter .1: dropped an unused `use std::path::Path` from the plan-verbatim `design_index_pin.rs` (it produced an unused-import warning). Minimal quality fix; the RED-first property is unchanged. Deviation from plan-verbatim text, recorded.
|
||||
- iter .2: **Plan/spec internal contradiction (repaired).** Task 1's clause-3 marker list (spec-verbatim) includes `"an earlier draft"`; Task 2 Step 4's plan-verbatim `honesty-rule.md` text quoted `"an earlier draft said"` as a *forbidden-pattern example*, which `contracts_carry_no_decision_record_prose` flags forever. The spec's own sample honesty-rule.md (spec §"Concrete code shapes") does NOT contain that phrase. Repaired by rewording honesty-rule.md's History bullet to name the category without the tripwire substring, preserving the two `docs_honesty_pin.rs:70,72` pinned phrases verbatim+contiguous. Spec-faithful to §Architecture-4 ("rewritten to resolve the internal contradiction").
|
||||
- iter .2: INDEX link cells changed from spec-verbatim `contracts/…` to workspace-root-relative `design/contracts/…` so the authoritative `design_index_pin.rs` (resolves `root().join(link)`) is GREEN. Ratifying-test column resolved to exact paths (`skills/brainstorm/SKILL.md`, `crates/ailang-surface/tests/round_trip.rs`) per spec lines 183-187 ("Boss-resolved to exact recon-verified paths"); the spec's short labels (`… Step 4`, `… round_trip.rs`) would not resolve under clause-2.
|
||||
- iter .7 / .9 (DONE_WITH_CONCERNS): `architect_sweeps.sh` exits **1**, not the plan-expected **0**. Sole match: `design/contracts/str-abi.md:23` `(iter str-concat, 2026-05-13)` — an API-origin date faithfully migrated verbatim inside the `### Heap-Str primitives` block (spec Architecture-2: `###` moves whole, no sentence-surgery; the pre-split sweep against DESIGN.md flagged the same line identically — NOT a split-introduced regression). The sweep is explicitly advisory; this is a milestone-close `audit` adjudication item, not a relocation defect. Faithful-migration over content-dodging (CLAUDE.md memory).
|
||||
|
||||
## Known debt
|
||||
|
||||
- `design/contracts/float-semantics.md` retains the cross-prose `(see "Str ABI" below for the dual realisation)` inside the `float_to_str`/`int_to_str` paragraph (DESIGN.md:2795-2800) — the Str ABI section moved to `str-abi.md`, so this internal "below" cross-ref is now stale-direction. Not strippable at relocation time (no task prescribes intra-prose cross-ref rewriting; the Appendix is heading-level). `str-abi.md` contract exists; the phrase still names a real contract. Audit-adjudication candidate.
|
||||
- `design/contracts/str-abi.md:23` iter-origin date stamp (the architect_sweeps Sweep-1 advisory match above) — audit adjudicates whether the iter/date origin annotations in the migrated `### Heap-Str primitives` API list are honest API-provenance or strippable history.
|
||||
|
||||
## Blocked detail
|
||||
|
||||
(none — DONE)
|
||||
|
||||
## Boss action required (NOT done by this agent — role + project rule)
|
||||
|
||||
- **Journals INDEX pointer (Task 4 Step 2):** the orchestrator role
|
||||
Red-Flags any edit to `docs/journals/INDEX.md`, and
|
||||
`skills/implement/SKILL.md` makes INDEX.md strictly Boss-only with
|
||||
no exception. The decision-record *file* is created (the
|
||||
substantive deliverable); the Boss appends, in the same commit,
|
||||
newest-last to `docs/journals/INDEX.md`:
|
||||
`- 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.`
|
||||
plus this iter's own pointer line per the standard Boss procedure.
|
||||
- **Acceptance-grep plan-defect:** Task 9 Step 4's verbatim grep
|
||||
filter `grep -vE '^\./docs/(...)'` uses a `^\./` anchor that does
|
||||
NOT match this system's `grep -rIn` path output (`docs/...`, no
|
||||
`./`), so the history-doc exclusion silently fails on the literal
|
||||
command. The spec-criterion-8-faithful filter (anchor `^(\./)?`,
|
||||
plus excluding `design_index_pin.rs` — the absence-enforcing
|
||||
clause-4 pin the spec's own sketch mandates) returns
|
||||
**CLEAN: zero live DESIGN.md references**. The 3 residual matches
|
||||
are all `crates/ailang-core/tests/design_index_pin.rs` (the
|
||||
spec-mandated `docs/DESIGN.md was resurrected` guard) — the
|
||||
deletion *enforcer*, categorically not a live content xref.
|
||||
|
||||
## Files touched
|
||||
|
||||
- New: `design/INDEX.md`, `design/contracts/{14 files}.md`, `design/models/{5 files}.md`, `crates/ailang-core/tests/design_index_pin.rs`, `docs/journals/2026-05-19-design-decision-records.md`
|
||||
- Deleted (staged): `docs/DESIGN.md`
|
||||
- Modified — tests: `design_schema_drift.rs`, `docs_honesty_pin.rs`, `effect_doc_honesty_pin.rs`, `eq_float_noinstance.rs`, `show_no_instance_e2e.rs`, `duplicate_ctor_pin.rs`, `codegen_import_map_fallback_pin.rs`, `polyfn_dot_qualified_branch_pin.rs`, `embed_record_layout_pin.rs`, `embed_staticlib_lowering.rs`, `eq_ord_e2e.rs`, `e2e.rs`, `round_trip.rs`
|
||||
- Modified — source: `ailang-check/src/lib.rs`, `ailang-codegen/src/{lib,drop,match_lower}.rs`, `ailang-core/src/ast.rs`, `ailang-surface/src/{lib,parse,print}.rs`, `ail/src/main.rs`, `ail-embed/src/lib.rs`, `ailang-core/specs/form_a.md`
|
||||
- Modified — runtime/fixtures: `runtime/{rc,str}.c`, `crates/ail/tests/embed/{record,tick}_roundtrip.c`, `examples/fieldtest/floats_{3,4}*.ail`
|
||||
- Modified — bench/skills/docs: `bench/architect_sweeps.sh`, `CLAUDE.md`, `skills/README.md`, 5 SKILL.md, 12 agent .md
|
||||
|
||||
## Stats
|
||||
|
||||
bench/orchestrator-stats/2026-05-19-iter-design-md-rolesplit.1.json
|
||||
@@ -114,3 +114,5 @@
|
||||
- 2026-05-19 — iter embedding-abi-m5.3 (DONE 3/3): final functional M5 iteration — the time-shard boundary-invisibility proof + friction harvest. One symbol (EURUSD), three disjoint contiguous single-month windows (2017-03/04/05), each folded on its own thread owning its own `Kernel` (`Ctx: !Send` ⇒ one-ctx-per-thread compile-time-enforced). Adds the purely-additive windowed adapter sibling `fold_window` (same `MidPriceStream`+`Kernel` path as `fold_symbol`, differs only by `stream_tick_windowed`), a new single-responsibility `[[bin]] timeshard_runner`, `chrono` as a **dev-dep** (the time-shard test derives `(y,m)→Unix-ms` bounds via data-server's own `NaiveDate…timestamp_millis()` precedent and passes raw ms to the bin, keeping the bin date-math-free and Invariant 1 untouched), and `tests/timeshard.rs` carrying the spec §3 strength-ordered assertions: (a) each shard's `(acc,n)` **bit-exact** vs a single-thread host fold of THAT EXACT window in data-server stream order — the first actual proof of the chunk/window-boundary-invisibility claim the entire M4 retirement rests on; (b) host-summed partials bit-exact by construction; (c) the whole-window [2017-03..2017-05] single-thread total within `REL_TOL=1e-6` only (cross-shard f64 re-association is host arithmetic, NOT a kernel property — asserting it bit-exact would be the bug; tolerance derived from the recursive-summation error bound with ~4 orders of safety, shown in the test). Plus the now-deterministic global leak-Σ (post-`dbd76e5`) and a journal-only friction-timing capture (no bench gate, no timing assertion — flake-free). RED was a genuine deterministic compile failure (declared-but-absent `[[bin]] timeshard_runner` source; surfaced as Cargo's missing-source error rather than the plan's predicted `env!` error — same root cause, same trigger, no false-green; recorded as a benign plan-text imprecision in Concerns). The shipped m5.2 symbol-fan path (`swarm_runner.rs`, `swarm.rs`) and m5.1 core stay byte-untouched and green. Boss-verified independently: **timeshard determinism 5/5** (consistent ~2.7s, no jitter); full ail-embed suite **0 failed AND 0 ignored** across all binaries (lib 2, swarm 2 — the m5.2 leak-proof stays un-ignored & green, the whole saga's resolution intact —, smoke 1, rt_archive 1, timeshard 1); isolated `embed_rc_global_stats_race` still green; AILang workspace `cargo metadata` data-server count 0; compiler-surface diff empty (zero diff to crates/ailang-*, crates/ail/, runtime/, examples/*.ail, root Cargo.toml, DESIGN.md). **Friction-harvest deliverable (P2 flat-array-decision input): host-per-tick-FFI ≈ 658 ms / 3 192 562 ticks ≈ ~206 ns/tick at real EURUSD volume.** M5's functional work is complete; the milestone closes next via the mandatory `audit` (which also handles the pre-existing `docs/DESIGN.md:2358-2360` "additive M4 concern" drift, explicitly out of m5.3 scope). → 2026-05-19-iter-embedding-abi-m5.3.md
|
||||
- 2026-05-19 — audit embedding-abi-m5 (milestone close): DRIFT (one doc-honesty tidy) + RATIFY (gc_rss trio, evidenced) + causally-exonerated pre-existing P2 bench noise. Architect: **Invariant 1 PASS** (zero data-server in any compiler crate/runtime; ail-embed its own workspace root; only "finance" hits are the M3 ABI export *symbol name* — ABI not data-server knowledge), M3 frozen-layout SSOT unmoved (the lone rc.c change `7bfa11e` touched only the global stats counters), rc.c header-comment honesty accurate; drift = `[medium]` DESIGN.md:2358-2360 stale "additive M4 concern" (PRE-EXISTING, M4 retired, correctly scoped out of M5) + `[medium]` DESIGN.md §"Embedding ABI" silent-drift (it asserts "no shared mutable runtime state … data-race-free" but the now-atomic global RC-stats fallback IS shared mutable state under concurrency — M5 is AILang's first concurrent consumer) + `[low]` rc.c:88 "two unconditional ++" imprecise — one tidy, same honesty axis, not split. Bencher (my pre-audit "gc_rss is allocator-orthogonal → environmental" hypothesis was **refuted by evidence** — the verification discipline working): the 3× `*.gc_rss_kb +32%` are GENUINE, DETERMINISTIC, M5-attributable — `7bfa11e`'s atomic split a branch in `ailang_rc_alloc` (reached by GC programs via `str.c` int→str at `print`), spilling `%r14/%rbx`; a stale interior list pointer in the new spill slot is conservatively retained by Boehm, pinning a ~32 MB dead spine (Boehm collection #12 freed PRE 32 MB vs HEAD 32 B); bisects exactly on the commit, IR byte-identical, `ail` sha256-identical; RC/bump RSS dead-stable. `bump_s`/`max_us` = pre-existing tracked-P2 (bump RC-orthogonal; max_us 1-sample tail-jitter, PRE often worse, +65→+104% swing between runs minutes apart — dispositively noise), NOT M5. Adjudication: **RATIFY** the gc_rss trio — language reason (Decision 9: Boehm is explicitly transitional; the cost is purely a Boehm conservative-scan false-retention artifact on the transitional allocator of a *correct, necessary, user-approved swarm-safety fix*, codegen-layout-fragile, RC path the committed model and unaffected; chasing it with an out-of-scope codegen change invests in the path being removed) — selective baseline re-anchor `bench/baseline.json` lines 14/44/64 ONLY (137448/137768/137636, bencher-confirmed steady-state; every other metric byte-pristine — a wholesale --update-baseline would have absorbed the P2 noise and broken the established-envelope discipline); re-run confirms the 3 now `ok` at ±0.3%. **NO-ratify / causally exonerated** for bump_s×2 + max_us×2 — baseline pristine, identical disposition to the M2/M3/prelude-decouple closes. Friction-harvest recorded (P2 input): host-per-tick-FFI ≈ ~206 ns/tick at real EURUSD volume. M5 closes after the doc-honesty tidy lands + Boss-verified. Ratify discipline honored: updated baseline JSON + this paired JOURNAL ratify entry committed together. → 2026-05-19-audit-embedding-abi-m5.md
|
||||
- 2026-05-19 — iter embedding-abi-m5.tidy (DONE 3/3): resolves the M5 milestone-close audit DRIFT (28ab56a). DOC/COMMENT-ONLY, recon-pin-verified, single cohesive commit (M2.tidy a80d495 / M3.tidy 63d7d60 precedent — pins are the coverage, no RED, no audit/fieldtest gate). `docs/DESIGN.md` edit-1 §"Free (host side)": dropped the retired-M4 forward-reference ("an additive M4 concern, not a contradiction of this freeze" — M4 retired 2026-05-18) → present-tense current fact (a boxed-field record is **not** an M3 embedding type, export-gate-rejected; the freeze covers exactly the all-scalar single-ctor record). edit-2 §"Embedding ABI": reconciled the now-inaccurate "(no shared mutable runtime state — … data-race-free, sanitiser-verified)" blanket with the real post-7bfa11e state — the per-allocation hot path (per-ctx counters + per-object refcount header) is non-atomic by design and never shared (`Ctx: !Send`, single-thread-per-ctx); the one datum a multi-threaded host shares is the global RC-stats fallback counter, atomic-relaxed so the swarm's leak accounting is exact; "data-race-free, sanitiser-verified" retained (still true). `runtime/rc.c:88` 18g.0-block comment-only: stale "two unconditional `++` operations" → accurate "one counter bump per alloc/free … relaxed atomic add on the global null-ctx fallback, a plain `++` on the per-ctx path" (consistent with the adjacent already-correct :93-106 atomic block + :45-55 Threading header). Boss-verified independently: all pins green (design_schema_drift 8/0, docs_honesty_pin 5/0, effect_doc_honesty_pin 4/0, embed_record_layout_pin 1/0) — the mechanical proof the edits moved no pinned/hashed byte; the adjacent separately-pinned bare-scalar sentence is byte-identical (shifted 2299→2305 by net-added lines; `docs_honesty_pin.rs:135` is a substring pin, passes); rc.c diff strictly comment-only (filter empty); `cargo build --workspace` Finished; git scope = only docs/DESIGN.md + runtime/rc.c + journal/stats. Clears the M5-audit doc-honesty debt; no new debt. This is the FINAL M5 iteration — M5 (the M1–M5 Embedding ABI arc) is now functionally complete, audited, ratified, and doc-honest. → 2026-05-19-iter-embedding-abi-m5.tidy.md
|
||||
- 2026-05-19 — iter design-md-rolesplit.1 (DONE 9/9, whole milestone): the 3020-line `docs/DESIGN.md` replaced by the `design/` ledger — `design/INDEX.md` (sole addressable spine, typed Contracts+Models tables, polymorphic links: prose file OR authoritative source `//!`), 14 `design/contracts/*.md` test-linked invariants + 3 source-link-only contracts (mangling/env-construction/qualified-xref, no prose file — code is SoT), 5 `design/models/*.md` onboarding whitepapers, and `docs/journals/2026-05-19-design-decision-records.md` (the relitigation-guard archive: every why/rejected/does-not-do/rollback/empirical `###` moved out at `###` granularity). Clean cut (`git rm docs/DESIGN.md`, no stub). RED-first `crates/ailang-core/tests/design_index_pin.rs` 4-clause anti-regrowth spine (DESIGN.md-gone / every-INDEX-link-resolves / every-contract-names-a-resolvable-ratifier / contracts-carry-no-decision-record-prose) demonstrably RED→GREEN. Build-atomic by task ordering (the only compile-time consumer, `design_schema_drift.rs` `include_str!`, retargeted to `design/contracts/data-model.md` BEFORE the deletion; the `## Data model`/`## Pipeline` slicer dropped — a simplification the split enables). 2 NoInstance diagnostics + their 2 lockstep E2Es retargeted to `design/contracts/{float-semantics,typeclasses}.md` (the contiguity-across-`\`-continuation hazard scrubbed). ~12 agent reading lists + 5 SKILL bodies + CLAUDE.md + skills/README.md + ~25 code/C/.ail/spec comment xrefs retargeted to the Appendix destinations; OQ7 dangling "Iter 13b" cite deleted (no forward target — a pointer would be fiction). honesty-rule.md rewritten so the rule names the new home (rationale→journals), resolving the recon-found internal contradiction; the two `docs_honesty_pin.rs:70,72` pinned phrases preserved verbatim+contiguous. Boss-verified independently: whole `cargo test --workspace` **646 passed / 0 failed**, `design_index_pin` 4/4, acceptance grep **CLEAN of live DESIGN.md refs** (residuals = only the spec-mandated clause-4 deletion-enforcer), honesty-rule repair carries no clause-3 marker. Spec grounding-check PASS ×2 (one re-dispatch after a corrected commitment-4 pin-status claim; one after the Boss-adjudicated relocation-appendix amendment resolving plan-recon's 7 open questions — ledger completed to 17 contract rows incl. the qualified-xref/str-abi/scope-boundaries additions the 12-list under-counted). 2 DONE_WITH_CONCERNS routed to the mandatory milestone-close `audit`: (a) `design/contracts/str-abi.md:23` `(iter str-concat, 2026-05-13)` API-provenance stamp trips advisory `architect_sweeps.sh` Sweep-1 — Boss-confirmed **byte-identical to DESIGN.md@deeffb1:2062-2065**, a faithfully-migrated PRE-EXISTING anchor (sweep regexes verbatim, only the path retargeted), NOT a split-introduced regression — RATIFY-or-tidy at audit; (b) the now stale-direction `(see "Str ABI" below)` intra-prose cross-ref in `float-semantics.md` (the Appendix is heading-level; no task prescribes intra-prose cross-ref rewrite) — audit-adjudication candidate. One plan defect recorded (Task 9 Step 4's verbatim acceptance grep used a `^\./` anchor not matching the system's `grep -rIn` output; substance independently re-verified CLEAN). → 2026-05-19-iter-design-md-rolesplit.1.md
|
||||
- 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
|
||||
|
||||
Reference in New Issue
Block a user