8301ca3ee89dae7574381cf3285991215180addd
571 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8301ca3ee8 |
spec: intrinsic-bodies — correct .2 count + bijection split (refs #9)
Forward-fix on |
||
|
|
ce0374ac0c |
plan: intrinsic-bodies.1-mechanism — 8-task Term::Intrinsic cross-crate landing (refs #9)
Decomposes intrinsic-bodies.1 (parent spec docs/specs/0055-intrinsic-bodies.md
§ Architecture points 1-5) into 8 tasks plus a final gate:
Task 1 — Term::Intrinsic unit variant in ast.rs + the in-core
exhaustive-match arms (canonical/hash/visit/pretty), enumerated by
cargo build -p ailang-core (no-wildcard matches break until armed).
Task 2 — surface parse + print: (intrinsic) as a fn body-slot clause
and a lambda positional body, mapped to/from Term::Intrinsic;
round-trip rides the examples/ corpus gate.
Task 3 — cross-crate walker sweep (check + codegen + prose): leaf
arms at the sites that match Term::New today, enumerated by
cargo build --workspace. The two MEANINGFUL arms (codegen lower_term,
checker body-check) are bridged with a temp unreachable! so the gate
is green, then replaced by Tasks 4-5 — no deferred-caller across a
0-error gate.
Task 4 — checker: env.current_module_kernel_tier flag, signature-only
body check for an intrinsic body, intrinsic-outside-kernel-tier
reject (CheckError variant + code() arm). Reject test is subprocess
`ail check --json` on a temp file, modelled exactly on the verified
check_json_unbound_var pattern.
Task 5 — codegen: a Term::Intrinsic body routes through
intercepts::lookup; never reaches lower_term; lower_term's
Term::Intrinsic arm is a codegen-internal error.
Task 6 — `answer` intercept (ret i64 42) + the answer intrinsic in
STUB_AIL + examples/kernel_intrinsic_smoke.ail so the
schema_coverage corpus observes Term::Intrinsic (avoids the
Term::New-in-match-but-not-in-corpus gap).
Task 7 — E2E ratifier examples/kernel_answer.ail (calls
kernel_stub.answer, prints 42); build_and_run("kernel_answer.ail")
asserts stdout 42.
Task 8 — design/contracts/0002-data-model.md gains the
{ "t": "intrinsic" } Term entry; design_schema_drift mirror stays
green.
Three plan-time corrections after plan-recon + harness verification:
1. The reject test was first drafted against an invented ailang_check
API (Workspace::single_with_prelude / check_workspace). Verified
against e2e.rs:1236 that the established reject pattern is
subprocess `ail check --json` + exit-1 + JSON code assertion;
rewrote on a temp file.
2. build_and_run takes the fixture filename WITH .ail extension
(verified e2e.rs:13-38, existing calls build_and_run("sum.ail")) —
the ratifier call is build_and_run("kernel_answer.ail").
3. kernel_intrinsic_smoke.ail carries an intrinsic with no registered
intercept; confirmed no gate builds it (compile_check.py uses a
curated list, no test builds all examples/*.ail) — it rides only
the parse-level round-trip + schema-coverage gates, never a build.
Scope guard: .1 does NOT migrate prelude dummies, does NOT upgrade the
registry pin to a bijection, does NOT remove the dead body-lowering
path — all .2. Hashes stay stable in .1 (Term::Intrinsic is additive;
no existing fixture carries it).
Test trajectory: 667 (post-raw-buf.1) → ~669 (+intrinsic_in_user_module_is_rejected,
+answer_intrinsic_builds_and_runs_printing_42; corpus/round-trip
fixtures ride existing dynamic gates).
Handoff target: skills/implement on docs/plans/0106-intrinsic-bodies.1-mechanism.md
|
||
|
|
5b66de77ac |
spec: intrinsic-bodies — revise AST repr to Term::Intrinsic leaf (refs #9)
Forward-fix on
|
||
|
|
c42034b38d |
spec: intrinsic-bodies — (intrinsic) Form-A body marker (refs #9)
New milestone, triggered by the raw-buf.2 BLOCKED chain (the .2 work was discarded; spec |
||
|
|
647121cb8f |
plan: raw-buf.2-kernel-manifest — 7-task crate-rename + RawBuf submodule + checker-side surface (refs #7)
Decomposes raw-buf.2 (parent spec docs/specs/0054-raw-buf.md
§ Architecture point 2, § Components row 2, § Testing strategy
"raw-buf.2") into 7 atomic tasks:
Task 1 — crate rename + reshape: crates/ailang-kernel-stub/ →
crates/ailang-kernel/, restructured as a family-crate with
src/kernel_stub/{mod.rs,source.ail}; 13 steps covering 8
compile-checked rename sites plus design/INDEX.md + CLAUDE.md
path updates.
Task 2 — add raw_buf submodule: src/raw_buf/{mod.rs,source.ail}
with the spec's Form-A source (4 fns + 1 TypeDef with
param-in (a Int Float Bool)); RAW_BUF_AIL re-export.
Task 3 — wire raw_buf into ailang-surface: parse_raw_buf fn,
re-export at lib.rs:39, workspace injection alongside the
existing kernel_stub block, workspace_pin count bump 4→5.
Task 4 — round-trip test raw_buf_module_round_trips, verbatim
structural clone of kernel_stub_module_round_trips.
Task 5 — E2E raw_buf_check_e2e: (con RawBuf (con Int)) consumer
checks clean.
Task 6 — E2E raw_buf_param_in_reject_e2e: (con RawBuf (con Str))
consumer rejected at check with param-not-in-restricted-set.
Task 7 — E2E raw_buf_build_intercept_missing_e2e: (new RawBuf …)
consumer accepted at check, rejected at build with the
existing Term::New deferral message.
Three substantive plan-time decisions resolving plan-recon's
open questions:
1. The intercept-not-registered diagnostic is NOT introduced.
The spec hedged ("intercept-not-registered: new__RawBuf__Int
(or the existing Term::New-deferral diagnostic)") between
shipping a fresh diagnostic and reusing the existing deferral
at crates/ailang-codegen/src/lib.rs:2075-2078. Plan picks
reuse: the deferral already names "milestone raw-buf" and is
self-describing; a new diagnostic would exist for ~1 iter
(raw-buf.2 → raw-buf.3) before going away — disposable infra.
Task 7's test asserts on the substring "Term::New requires
the type's" which is stable in the existing message.
2. In-tree references to crates/ailang-kernel-stub/ AFTER the
rename — split-scope between raw-buf.2 and raw-buf.3.
The path changes in raw-buf.2 (the crate moves now), so
path-references in design/INDEX.md:112 and the CLAUDE.md
Code-layout table get updated in Task 1 Steps 10-11. The
retire-language (stub as "ratifying fixture for kernel-
extension-mechanics" → "retired by raw-buf") stays for
raw-buf.3 close, per spec § Components row 3.
3. parse_raw_buf gets a mirror re-export at ailang-surface/
src/lib.rs:39 alongside parse_kernel_stub. Recon's natural
reading; load-bearing because the new round-trip test calls
ailang_surface::parse_raw_buf() directly.
Plan honours the project's compile-gate discipline. Task 1's
13 steps thread all 8 rename sites inside the same task —
no deferred caller across the build gate. Task 3 bundles the
workspace_pin count bump with the loader injection that drives
it; the assertion goes 4→5 in the same task that makes it true.
Test-count trajectory: 667 (post-raw-buf.1 baseline) → 667
(Tasks 1, 2, 3 — refactor + wiring, no new test) → 668 (Task 4
round-trip) → 669 (Task 5 check E2E) → 670 (Task 6 reject E2E)
→ 671 (Task 7 deferral E2E).
Handoff target: skills/implement on docs/plans/0105-raw-buf.2-kernel-manifest.md
|
||
|
|
d1612d5463 |
plan: raw-buf.1-intercept-registry — 5-task atomic codegen-registry refactor (refs #7)
Decomposes raw-buf.1 (parent spec docs/specs/0054-raw-buf.md
§ Architecture point 1, § Components row 1) into 5 tasks:
Task 1 — intercepts module skeleton (3 steps)
Task 2 — populate the table: 18 emit fns + visibility bumps (9 steps)
Task 3 — rewire the dispatch site to a thin shim (3 steps)
Task 4 — fold wants_alwaysinline into the registry (4 steps)
Task 5 — registry_contains_all_legacy_arms pin test (3 steps)
Three substantive decisions made at plan time beyond what the spec
dictates, surfaced by the plan-recon report:
1. The match arm count is 18, not the ~8 the spec sentence hand-listed
(eq__Str, compare__Int|Bool|Str, float_*). Five additional arms
(eq__Int, eq__Bool, eq__Unit, plus the lt|le|gt|ge|ne__Int
direct-icmp family) shipped after the spec sentence was written.
All 18 are absorbed by the registry; the pin test enumerates all 18.
2. The `intercept_emit_wants_alwaysinline` predicate at lib.rs:1172 is
a separate hardcoded name-list that mirrors the dispatch arms.
This is a silent-drift class (regression seen earlier in the cycle
on compare__Int perf at +29-47% when the lists diverged). The plan
folds wants_alwaysinline into the Intercept entry as a per-row bool
and rewrites the predicate to consult the registry — one source of
truth instead of two.
3. The wrapper fn `try_emit_primitive_instance_body` survives as a
thin shim (`match intercepts::lookup(name) { Some(i) => ..., None
=> Ok(false) }`) rather than being deleted. Trade-off: a 6-line
wrapper vs. a 14-file comment-ref churn. The wrapper wins —
landmark name preserved, all in-source doc comments stay valid.
Plan honours the project's compile-gate discipline: fn signatures
stay stable throughout (only bodies change), no caller-threading is
deferred across a build gate. Visibility bumps in Task 2
(pub(crate) on three Emitter fields and four helper methods) are
additive and do not change any caller's signature.
Verification commands in each Run step name actual test fns the
plan-recon confirmed exist at specific lines; no filter-zero-match
risk. Pre-flight workspace baseline: 668 tests; post-iter:
669 (the new pin).
Handoff target: skills/implement on docs/plans/0104-raw-buf.1-intercept-registry.md
|
||
|
|
4ad003d21f |
spec: raw-buf — 3-iter base-extension milestone (refs #7)
First new milestone after kernel-extension-mechanics close.
RawBuf is the canonical kernel-tier *base* extension: mutable,
indexed, bounded-size flat buffer of primitive elements
({Int, Float, Bool}, restricted via prep.3's param-in). It
unblocks two downstream needs already in the backlog:
- series milestone #8 — library-tier ring buffer wrapping RawBuf.
- Embedding-ABI batch-FFI (subsumes closed #2) — the M5
friction-harvest measured per-tick FFI at ~206 ns/tick on
real EURUSD volume; RawBuf is the contiguous-slice primitive
that amortises that per-tick cost.
The milestone also fulfils the whitepaper § "Plugin contract"
commitment: the migration of the hardcoded
try_emit_primitive_instance_body into a registry is triggered
by the first real base extension shipping.
Decomposition (R — registry-first refactor, 3 iters):
raw-buf.1 — Intercept registry refactor. Lift the existing
hard-coded match (eq__Str, compare__Int|Bool|Str, float_*) into
a registry table. Zero behavioural change; ratified by the
existing E2E suite (eq_primitives_smoke / compare_primitives_smoke
in e2e.rs, float_compare_smoke, eq_ord_polymorphic). Pure
refactor — the cleanest possible bisection target.
raw-buf.2 — RawBuf kernel-tier manifest + checker side. Rename
crates/ailang-kernel-stub/ → crates/ailang-kernel/ and reshape
as a family-crate (src/{kernel_stub,raw_buf}/{mod.rs,source.ail});
public surface preserved via re-exports. Consumer code with
(con RawBuf (con Int)) passes ail check; ail build fails with
intercept-not-registered — that diagnostic IS the ratification.
raw-buf.3 — RawBuf codegen intercepts + Term::New desugar +
stub retirement. Register 12 element-type-specialised entries
(4 ops × {Int,Float,Bool}); lower via @ailang_rc_alloc +
getelementptr + load/store. Desugar (new T args) →
(app T.new args) so Term::New is eliminated before codegen
(completes the prep.2 deferral). Retire the kernel_stub
submodule + the round-trip test at design_schema_drift.rs:743;
ailang-kernel crate stays as the family-crate for future
series/matrix/… modules.
Ordering rationale: raw-buf.1 ships zero behavioural change so
its failure mode is "existing tests break" — cleanest bisection.
raw-buf.2 ships the checker-visible surface on an unchanged
codegen substrate, so its failure mode is checker-isolated.
raw-buf.3 lands codegen on a registry that has already absorbed
every legacy intercept, so the RawBuf entries do not co-mingle
with a registry move.
Kernel-tier crate organisation: rejected pro-modul-crate
(crates/ailang-series/, crates/ailang-matrix/, ...) for sublinear
scaling and onboarding locality; rejected sub-Cargo-crates under
crates/ailang-kernel/ (C1) for Cargo-boilerplate overhead with no
real consumer benefit at AILang's scale. C2 (one family-crate,
sub-folders per module, lib.rs re-exports) keeps Cargo dep
surface flat (ailang-surface needs one dep, not N) and stub
retirement is a submodule delete + re-export drop.
Out of scope: bounds checks (caller checks via RawBuf.size per
whitepaper — UB-on-overflow is the contract), RawBuf.fill /
.copy / .iter (deferred until series or Embedding-ABI concretely
asks), record element types (SoA — Forward Axis).
Grounding-check PASS on 10 load-bearing assumptions about
current code state (intercept dispatch site, existing E2E
ratifiers, ailang-kernel-stub crate layout, parse_kernel_stub
location).
Brainstorm → planner handoff: first iteration scope is raw-buf.1
(§ Architecture point 1, § Components row 1).
|
||
|
|
aa49a56d5a |
fieldtest: kernel-extension-mechanics — 6 examples, 9 findings (3 bugs, 1 friction, 1 spec_gap, 4 working)
Post-audit fieldtest for the kernel-extension-mechanics milestone. Fieldtester wrote 6 .ail consumer programs against the public interface only (design ledger + spec + ail CLI; no source crate reads), one per axis with two for the param-in pair (accept + reject). All artefacts in examples/fieldtest/ + the spec. **Working (4):** F5 NewTypeNotConstructible diagnostic is precise (names the home module + missing def in one sentence). F6 Term::New codegen-deferral diagnostic explicitly names the raw-buf milestone where support lands. F7 param-in accept-path is end-to-end (check + build + run prints 17). F8 ParamNotInRestrictedSet names type-arg + var + TypeDef. **Bugs (3, action: debug):** - F1 (axis 1) — Same-module type-scoped call `(app Type.member …)` rejected with phantom-qualified `expected <this>.T, got T`. Bare `(app member …)` from inside Type's home module works. Spec's "Canonical form decision" promises type-scoped works uniformly; the resolver appears to disagree with the workspace pre-pass on whether `<this-module>.T` equals bare `T`. Repro: examples/fieldtest/kem_2b_min_repro.ail. - F3 (axis 3) — Kernel-tier auto-import scopes the name but does not register the module as a resolvable qualifier prefix. Per the pre-pass, a bare `StubT` in a type slot is qualified to `kernel_stub.StubT`; the resolver then rejects `kernel_stub` as unknown. Asymmetric: prelude's free fns work (per prelude_free_fns.rs), but the stub's TypeDef is effectively unreachable from any consumer. Repro: examples/fieldtest/kem_3_stub_consumer.ail. - F4 (axis 3, spec/ship coherence) — The spec's prep.3 worked- consumer relies on `(new StubT 42)`, but the shipped STUB_AIL has only a TypeDef + ctor — the `(fn new ...)` the spec designed is missing from the implementation. The diagnostic the resolver does emit on the consumer (F5) is precise; the bug is the absent def itself. Resolution: re-add the `new` to STUB_AIL (the spec's design), refresh the drift pin. **Friction (1, action: plan-or-defer):** - F2 — Loader's sibling-only module resolution forces symlinks for any cross-module fixture sitting outside the canonical `examples/` directory. The kem_1 example required local symlinks for std_list.ail + std_maybe.ail. Secondary: the diagnostic message names only the .ail.json path even though .ail also resolves — actively misleading. Recommended: small tidy iter for loader workspace-search-path + diagnostic clarity. **Spec-gap (1, action: ratify):** - F9 — `design/models/0007-kernel-extensions.md:80` uses `unit` as a value literal of type Unit; the checker treats it as a Term::Var lookup and emits [unbound-var]. Either ratify `unit` as the canonical Unit-value literal in the language, or tighten the design model to use the existing idiom. The current model/ surface disagreement is a small but real LLM-author trap. **Symlinks committed** as evidence of the F2 workaround: examples/fieldtest/std_list.ail and std_maybe.ail are symlinks into ../. They are the fingerprint of the friction — removing them silently would erase the evidence. Per Iron Law, fieldtester did not work around bugs — they were all surfaced and recorded. The kem_2b_min_repro.ail fixture exists specifically because F1 surfaced mid-drafting and got minimised; kem_3_stub_consumer.ail also stays as the F3 RED-side fixture. Triage (next-step routing for /boss): F4 → small inline fix (add (fn new ...) to STUB_AIL + drift refresh) F9 → small inline ratify (whitepaper edit) F2 → backlog issue, deferred (single tidy iter someday) F1, F3 → debug skill dispatches, then implement mini-mode F5-F8 → carry-on, recorded as wins |
||
|
|
3b4fb42771 |
plan: prep.3-kernel-tier-modules — 9-task schema + surface + workspace + diagnostic + stub crate (refs #33)
Terminal iteration of the kernel-extension-mechanics milestone.
Carves the spec's § Iteration prep.3 into nine bite-sized tasks:
1. Module.kernel field + ~130-site struct-literal sweep + drift
round-trip + data-model anchor.
2. TypeDef.param_in field + ~30-site sweep + drift round-trip +
anchor (BTreeMap<String, BTreeSet<String>>, kebab-cased
`param-in`, skip-if-empty for hash stability).
3. Form-A (kernel) module-header attribute — parse + print +
round-trip.
4. Form-A (param-in (a Int Float) (b Str)) TypeDef attribute —
one outer clause, multiple inner var-lists (OQ1 decision).
5. Prelude becomes kernel-tier + loader generalisation: the
hardcoded `&["prelude"]` literal at loader.rs:108 migrates to
a `modules.values().filter(|m| m.kernel)` derivation;
ReservedModuleName diagnostic repurposed; CLI mapping +
hash-pin refresh in lockstep.
6. New crate `crates/ailang-kernel-stub/` — programmatic stub
module via parse_kernel_stub() mirroring parse_prelude
(OQ2 decision); wired into the loader; basic stub round-trip
drift test ratifies the end-to-end mechanism.
7. CheckError::ParamNotInRestrictedSet variant + code() + ctx() +
enforcement in check_type_well_formed's Type::Con arm +
in-source RED/GREEN tests.
8. New workspace_kernel.rs integration tests — auto-import without
explicit (import …), two kernel-tier modules co-load,
explicit-import-overrides-auto-import precedence.
9. design/INDEX.md + design/models/0007-kernel-extensions.md
STATUS + forward→present transitions for the now-shipped
mechanisms.
The four open questions raised by plan-recon are resolved up front
in the "Open-question decisions" block so no task carries a TBD.
ReservedModuleName variant shape stays `{ name: String }` (OQ3);
workspace.rs:2655 stays a test-site literal (OQ4).
The Module struct-literal sweep is the largest single mechanical
edit (~130 sites; the additive #[serde(default)] covers JSON
deserialise paths, only Rust struct literals break) — handled as
a compiler-driven sweep inside Task 1, with the workspace-build
gate validating no caller is deferred. TypeDef has ~30 sites.
Compile-gate-vs-deferred-caller and pin/replacement-substring
contiguity rules from planner self-review Step 5 are scrubbed:
no signature change defers a caller past its own compile gate,
no verbatim text edit pairs with a soft-wrappable presence pin.
Recon report received DONE_WITH_CONCERNS — concerns were the
four OQs, all decided in this plan.
|
||
|
|
70e6fcd5c0 |
plan: prep.2 Term::New construct — 4-task atomic AST + surface + checker + drift (refs #32)
Second iteration of the kernel-extension-mechanics milestone. The
plan ships the `new` Form-A keyword + Term::New AST variant + NewArg
enum + checker elaboration + two diagnostics, plus the schema-drift
pin and the data-model.md / form_a.md anchor additions.
Decomposition:
- Task 1 (large mechanical): AST variant declaration + workspace-wide
compile-forced arms across 24 files (44+ exhaustive Term-match
sites). Six arm patterns inlined; per-site table assigns one
pattern per site. Includes the prep.1 pre-pass partner — the
`qualify_workspace_term` arm that rewrites bare Term::New.type_name
to qualified form, mirroring the existing Term::Ctor arm. Synth
gets a Pattern-E stub here; Task 3 replaces with real logic.
- Task 2: Form-A lex/parse/print + round-trip fixture. New
`parse_new` method with Type-vs-Term arg disambiguation by
syntactic form (head keyword = Type-production heads
`con`/`fn-type`/`borrow`/`own` → NewArg::Type; else NewArg::Value).
- Task 3: Checker synth real-logic + 2 new CheckError variants
(NewTypeNotConstructible, NewArgKindMismatch) + 3 RED-first
in-source tests covering the spec's worked example, the missing-
`new`-def case, and the kind-mismatch case.
- Task 4: Schema-drift pin (term_new_round_trips +
term_new_type_arg_round_trips) + spec_drift exemplar + form_a.md
keyword cheatsheet + design/contracts/0002-data-model.md JSON-tag
block.
Spec is already correct on prep.2 scope; the recon surfaced one
design decision the plan resolves inline: NewArg uses
`#[serde(tag = "kind", content = "value", rename_all = "lowercase")]`
to land the spec's exact JSON byte shape. Codegen remains explicitly
out of scope per the milestone spec; Task 1's codegen sites get
Pattern-D error-arms ("Term::New requires desugar first; codegen
support lands in the raw-buf milestone").
Forward-reference: Task 1's Pattern-C arm in `qualify_workspace_term`
extends prep.1's workspace-wide normalisation pre-pass — Term::New
joins Term::Ctor and Type::Con as a type_name-bearing site that
gets bare→qualified normalised before the checker sees it.
|
||
|
|
b586999e81 |
iter prep.1-type-scoped-namespacing (DONE 5/5): TypeDef-first resolution + workspace pre-pass — closes #31
First iteration of the kernel-extension-mechanics milestone. Ships
the type-scoped `<TypeName>.<member>` resolution path as the
canonical form for type-associated operations, narrows the
`BareCrossModuleTypeRef` / `BadCrossModuleTypeRef` diagnostics from
"bare = strictly local" to "bare = in-scope by any path", migrates
12 std-library example fixtures, and introduces a workspace-wide
normalisation pre-pass `prepare_workspace_for_check` shared between
`check_workspace` and `monomorphise_workspace`.
Architectural discovery during implementation: the plan covered the
`Term::Var` dot-qualified resolver layer plus the workspace
validator's bare-name acceptance, but the migration of bare-form
fixtures exposed five sites where bare vs. qualified type-names
needed symmetric treatment — `Term::Ctor` resolution, `Type::Con`
well-formedness, mono's poly-free-fn name/constraint-count
enumeration, codegen's `lookup_ctor_by_type` bare-name path, and
the upstream desugar-then-qualify composition. Rather than
scattering TypeDef-first ladders across each site, the implementer
centralised the work into one pre-pass that walks every consumer
module's `Type::Con.name` and `Term::Ctor.type_name`, rewriting
bare cross-module references to their qualified `<home>.<Type>`
form. This is symmetric to the pre-existing `qualify_local_types`
(owner-side); the new pre-pass is the consumer-side mirror.
Downstream passes see qualified Types regardless of authoring form.
The TypeDef-first ladder still lives in `synth`'s `Term::Var` arm
because `<TypeName>.<member>` is term-position-only — `Maybe.from_maybe`
is a Var, not a Type expression, and the pre-pass does not rewrite
Var names.
Alternatives considered:
(a) Add TypeDef-first ladder at every resolution site separately
(the plan's implicit assumption). Rejected: O(N) extension
sites, each carrying the same workspace-walking logic; the
pre-pass version is O(1) — one pass, every downstream consumer
benefits.
(b) BLOCKED + spec re-brainstorm. Rejected: the architecture
extension is consistent with prep.1's thesis (bare type-name
resolves to the workspace-wide TypeDef) and forward-compatible
with prep.2 (Term::New.type_name falls under the same rewrite)
and prep.3 (kernel-tier TypeDefs enter the workspace map
automatically). No design regression to bounce back over.
Spec updated to document the realisation mechanism honestly: the
"Realisation mechanism — workspace pre-pass" subsection clarifies
that the resolver-level semantics described in "Implementation
shape" are the user-facing contract, and the actual code path is
the pre-pass.
Verification:
- `cargo test --workspace`: ALL GREEN. 87 e2e + every crate's unit
+ integration tests pass with no regressions.
- Three NEW in-source tests pin Task 1's resolver paths:
`type_scoped_member_resolves`, `type_scoped_member_not_found`,
`type_scoped_receiver_not_a_type`.
- One NEW workspace test pins the narrowed validator:
`ct1_validator_accepts_bare_with_explicit_import`.
- One renamed-and-flipped existing test:
`ct1_validator_rejects_bare_xmod_with_import_candidate` →
`ct1_validator_accepts_bare_xmod_with_import_candidate` (the
bare-with-import path is now ACCEPTED).
- One NEW companion test for the workspace-wide ctor lookup:
`ct2_term_ctor_bare_cross_module_via_workspace_resolves`.
- Two pre-existing tests' assertions updated for the new error
wording: `ct1_check_cli::check_human_mode_emits_actionable_message_to_stderr`
and `crates/ailang-check/tests/workspace.rs::unknown_module_prefix_is_reported`.
- 12 migrated `.ail` fixtures verified via the existing e2e
suite (each fixture is the test runner's target for an existing
`build_and_run` assertion).
- Negative fixture `ct_2_bare_cross_module.ail` semantically
preserved: dropped its `(import std_maybe)` so bare `Maybe` is
out-of-scope under the narrowed rule and still fires
`BareCrossModuleTypeRef`.
Concerns:
- The pre-pass introduces a new architectural layer (consumer-side
qualification) that the spec did not originally anticipate. Spec
amendment in this commit documents the layer. Future iterations
reference `prepare_workspace_for_check` as established
infrastructure.
- `examples/test_ct1_bare_xmod_rejected.ail.json` switched its
offending name from bare `Ordering` (which under the prep.1
semantics may now resolve via implicit prelude) to a still-
unresolvable `Mystery_Type`. The CLI test's intent (assert that
a human-mode `ail check` exits non-zero on a still-RED case) is
preserved.
Milestone status: kernel-extension-mechanics (Gitea #6) advances
1/3 iters. Next: prep.2 (`Term::New` construct) issue #32.
|
||
|
|
46c9aabf00 |
plan: prep.1 type-scoped namespacing — 5-task atomic resolver + 12-fixture migration (refs #31)
The plan covers the first iteration of the kernel-extension-mechanics
milestone: type-scoped `<TypeName>.<member>` resolution in
`ailang-check`, narrowed `BareCrossModuleTypeRef` /
`BadCrossModuleTypeRef` diagnostics in `ailang-core::workspace`,
two new `CheckError` variants, CLI diagnostic-message rewording,
and atomic rewrite of 12 `.ail` example fixtures from `std_X.Y` to
the type-scoped form. Five tasks, each unit-of-review.
Includes a spec correction (same commit because plan recon
surfaced it): the prep.1 Blast Radius previously claimed
`hash_pin.rs` + `prelude_module_hash_pin.rs` refreshes and a
`design_schema_drift.rs` pin addition. Plan-recon walked every
test crate (per the schema-camelcase-fix hash-pin-blast-radius
lesson) and found:
* neither hash-pin file pins any fixture in prep.1's migration
set — refresh is empty;
* type-scoped resolution is a checker-only change (no new JSON
tags, no AST shape change) — the drift pin belongs to prep.2
(`Term::New`) and prep.3 (`kernel: true` + `param-in`), not
prep.1.
Spec section 'Blast radius' and the 'Iteration scope' summary now
reflect the recon-cleared reality.
|
||
|
|
832375f2ac |
convention: counter-prefix file naming across docs/specs/, docs/plans/, design/contracts/, design/models/
All 176 files in the four accumulating directories now use a zero-padded 4-digit counter prefix that reflects creation order (`NNNN-slug.md`). The counter is assigned per directory in strict git-log creation order; ties broken alphabetically by original name. The old `YYYY-MM-DD-` prefix on docs/specs/ and docs/plans/ files is dropped — the date is recoverable from git log and the counter carries the ordering. A file's counter is stable for the life of the file: never reassigned, never reused, never compacted. Deleted files retire their counter; subsequent files do not fill the gap. This is the property that lets cross-references stay literal — refs use the full filename including the counter (`design/contracts/0007-honesty-rule.md`) so they grep cleanly and resolve directly without a glob step. 313 cross-references updated across .md/.rs/.toml/.c/.json files (test pins, include_str! paths, design-INDEX entries, baseline notes, runtime C comments, inter-contract markdown links incl. bare basename and `../models/foo.md` forms). CLAUDE.md gets a new "File-naming convention" section spelling out the rule and rationale. skills/brainstorm/SKILL.md and skills/planner/SKILL.md updated so new spec/plan creation produces counter-prefixed names from the start. The full test suite (cargo test --workspace) passes. |
||
|
|
7b8596cef0 |
spec: kernel-extension-mechanics — three-iter prep milestone
docs/specs/2026-05-28-kernel-extension-mechanics.md: per-milestone implementation container for the four language-level mechanisms described in design/models/kernel-extensions.md. Three iterations, each independently shippable: - prep.1 — Type-scoped namespacing. Resolver change so `<TypeName>.<member>` resolves to the type's home module. Migrates ~14 std-library example fixtures from `std_X.Y`-style cross-module references to type-scoped form. Hash pins refreshed in lockstep (ailang-core + ailang-surface — full blast-radius walk, per the hash-pin-audit lesson from schema-camelcase-fix). - prep.2 — Term::New. New AST variant and Form-A keyword `(new T args...)`, calls the `new` def in T's home module. Uses prep.1's resolution. - prep.3 — Kernel-tier modules + `param-in`. Schema flag `Module.kernel` + TypeDef `param-in` field. Workspace-load generalises the existing hardcoded prelude auto-injection (loader.rs:98-108 + workspace.rs:308-311, 467, 2655) into a flag-driven mechanism; prelude itself gains `kernel: true` as a code-path migration (consumer-observable behaviour unchanged — prelude_free_fns.rs regression test stays green). A new minimal ailang-kernel-stub crate ratifies the mechanism without domain content. Five new diagnostics across the three iters: TypeScopedMemberNotFound, TypeScopedReceiverNotAType, NewTypeNotConstructible, NewArgKindMismatch, ParamNotInRestrictedSet. BareCrossModuleTypeRef and BadCrossModuleTypeRef diagnostics repositioned (still "type name not resolvable" but with revised remediation pointers). Each iter's spec section carries explicit `## Canonical form decision`, `## Blast radius`, and `## Integration with existing mechanisms` subsections — the migration-policy discipline made visible per spec section. Grounding-check (two dispatches): first BLOCK on prelude auto-injection mis-framing (claimed it was a new mechanism; in fact prelude is hardcoded-auto-injected today), corrected inline; second PASS after the revised two-tier-architecture framing also landed. All load-bearing assumptions ratified by named tests in the working tree. Out of scope, named explicitly: the raw-buf milestone (#7), the series milestone (#8), record-element SoA support, LSP/MCP integration for `ail describe`, higher-kinded `param-in`, and primitive-instance intercept migration (deferred to #7 when there is a real second consumer for the registry). Refs Gitea milestone #6. |
||
|
|
90977663ff |
plan: schema-camelcase-fix — 4-task atomic schema-tag migration (refs #30)
Iteration plan derived from `docs/specs/2026-05-21-schema-camelcase-fix.md` (commit |
||
|
|
55ce6d0d70 |
spec: schema-camelcase-fix — expand scope to data-model.md + rustdoc layer (refs #30)
Spec amendment after plan-recon flagged four missed touch-points in the brainstorm grounding-check loop: 1. `design/contracts/data-model.md:142-147` — fenced JSON-block in the canonical data-model contract. The data-model contract IS the canonical-schema doc (INDEX.md row, ratifying test `tests/design_schema_drift.rs`); leaving it on camelCase after `ast.rs` ships kebab is a direct Honesty-Rule violation. 2. Three rustdoc strings in production source that describe the present-state schema vocabulary: `ast.rs:8`, `parse.rs:81`, `check/lib.rs:1707`. Each enumerates the rename targets in prose; left unchanged they would describe a state that no longer exists. 3. Better home for the new schema-shape pin: `design_schema_drift.rs` (not `schema_coverage.rs`). That file already operates as the data-model-contract ratifying test, already builds Term::Lam exemplars at L121-129, and uses `anchor_in_jsonc_block` to walk data-model.md fenced blocks — the proposed extension slots directly into the existing pin family. 4. Experiment-tree files (`experiments/2026-05-12-.../master/spec.md`, `rendered/*.md`, `runs/**`) carry old tags. Per Honesty-Rule analogy with docs/plans/* — these are frozen historical artefacts of the 2026-05-12 cross-model-authoring experiment and are NOT migrated. The experiment's `master/examples/*.ail.json` fixture IS migrated (live JSON the workspace loader can deserialise); surrounding prose is not. Plus an editorial fix: the fixture-occurrence count parenthetical corrected from "3" to "2" — each fixture has one `paramTypes` + one `retType`, one per line. Spec re-dispatched through `ailang-grounding-check` (Step 7.5 re-PASS). All 9 load-bearing claims ratified, with 2 negative-grep "no test pins this" ratifications openly flagged in the agent report as a Boss-override-eligible shape. Acceptance criteria renumbered to 7 (was 6). Touch-point count now: 2 serde-renames + 1 workspace.rs literal + 2 .ail.json fixtures + 1 data-model.md fenced block + 3 rustdoc strings = 9 files, all small edits. No hash-pin refresh required. |
||
|
|
7d086e69ce |
spec: schema-camelcase-fix — paramTypes/retType → param-types/ret-type (closes #30)
Brainstorm output. Single-iteration milestone: rename the two camelCase JSON tags on `Term::Lam` — the only camelCase outliers in the AST schema — to kebab-case, matching the convention every other compound-key tag (`reuse-as`, etc.) already follows. Scope is verified-tiny: ast.rs (2 serde-rename strings) + workspace.rs in-source test JSON-literal + 2 `.ail.json` fixtures. None of the five hash-pinned `.ail` modules contains a lambda, so the milestone refreshes zero hash pins. Form-A is untouched — the surface uses `(params (typed ...))` / `(ret ...)`, never the camelCase tags. Feature-acceptance gate: passes weakly-but-honestly. Clause 1 is indirect (schema-internal consistency reduces the LLM author's "compound-tag-is-kebab" generalisation failure rate); there is no empirical preference measurement for this axis. Clause 2 holds (one fewer special case to memorise). Clause 3 vacuous (no semantic surface touched). Grounding-check (Step 7.5) PASS: all four load-bearing claims ratified by currently-green tests — round_trip.rs (Form-A invariance), hash_pin.rs (no lambda in pinned modules), workspace.rs in-source ct1_validator test (exhaustive call-site list), design_schema_drift.rs (kebab convention pin). Not bundled with #27 (arith-rename) per the spec preamble: #27 carries its own four open brainstorm questions and is a separate milestone; each gets one re-pin wave with its own rationale, no churn savings from bundling. |
||
|
|
8d61599b8d |
doc: fix bare (class Eq) → (class prelude.Eq) in operator-routing-eq-ord spec north-star
Fieldtest (
|
||
|
|
505eb8484e |
fieldtest: operator-routing-eq-ord — 5 examples, 6 findings (4 working, 1 friction, 1 spec_gap)
Post-audit field test of the operator-routing-eq-ord milestone (closed via |
||
|
|
400ad7c067 |
plan: operator-routing-eq-ord.1 — atomic single-iter execution layout
Decomposes the operator-routing-eq-ord spec (
|
||
|
|
a68d7b6353 |
spec: operator-routing-eq-ord — drop comparator builtins, route through Eq/Ord
Resolves Gitea #1. Realises the "P2 follow-up" called out in examples/prelude.ail line 9. Approach A (single-iter atomic milestone): one cohesive cut across seven layers in one iter, plus the regenerated prelude module hash pin. Three design forks resolved with the user via brainstorm Q&A: (1) Operator-name surface: `==` `!=` `<` `<=` `>` `>=` die from the language. The LLM-author writes only the class-method names `eq` `ne` `lt` `le` `gt` `ge` `compare`. One mental model: AILang has class-dispatch, operators are not a separate concept. Option 2 (keep names as surface aliases) was rejected because it adds a second spelling for an identical operation — the redundancy the milestone is supposed to remove gets reintroduced syntactically. Option 3 (two-track: primitive Built-in for Int/Bool/Str/Unit, class for user-types) was rejected because the two-pathy state is precisely what this milestone exists to dismantle. (2) Float comparison surface: Float keeps comparison capability via six named prelude fns (`float_eq` `float_ne` `float_lt` `float_le` `float_gt` `float_ge`), no `Eq Float` / `Ord Float` instance. Motivation: all three feature-acceptance clauses simultaneously satisfied — clause 1 (LLM-natural via Library-Convention-Pattern like Python's `math.isclose` or Rust's `approx`-crates), clause 2 (within the polymorphic surface there is one path; Float is honestly stamped "non-polymorphic"), clause 3 (the NaN-comparison anti-pattern stays visible in code as `float_eq` rather than hiding behind `eq`). Option A (Float loses all comparison) was rejected as overstretch — workarounds via `is_nan` + arithmetic are more bug-prone than a named fn that emits the right fcmp directly. Option C (Eq Float with IEEE semantics) was rejected as clause-3 violation — it would reintroduce the silent NaN-comparison bug class that the existing Float-no-Eq/Ord design exists to prevent. (3) Codegen mechanism for primitive Eq/Ord instances: option β (always-call through dispatch, with `alwaysinline` attribute on intercept-emitted bodies as pre-emptive `-O0` mitigation, and option α — call-site intercept — held as the bench-gate fallback if measurements show real regression). Motivation: semantic honesty (class methods ARE calls, optimiser folds primitives uniformly at Int and User-Point alike), parity with `Show` (which is also full-call today with no intercept), smaller IR-shape contract for the existing pins. Under `-O2` the inliner deterministically collapses 2- instruction bodies; bench corpus runs `-O2`. Under `-O0` `alwaysinline` overrides the no-inline default, giving the same per-call IR shape as today. α was the initial-framed Recommendation but was scrutinised in user pushback ("spricht irgendwas FÜR β?") and after substantive re-balancing β came out coherent. Grounding-check (ailang-grounding-check) PASS on re-dispatch — 11 load-bearing assumptions ratified by: `crates/ail/tests/e2e.rs::eq_demo` + `::lit_pat_demo`, `crates/ail/tests/eq_ord_e2e.rs::eq_ord_polymorphic_runs_end_to_end` + `::eq_ord_user_adt_runs_end_to_end` + `::eq_ord_user_adt_eq_intbox_hash_stable`, `crates/ail/tests/eq_float_noinstance.rs::eq_at_float_fires_float_aware_noinstance`, `crates/ail/tests/prelude_free_fns.rs::ne_at_int_produces_mono_symbol` (+4 siblings), `crates/ailang-surface/tests/prelude_module_hash_pin.rs::prelude_parse_yields_canonical_hash`, plus in-source `#[cfg(test)] mod tests` ratifiers in `crates/ailang-check/src/lib.rs` (`eq_typechecks_at_int/bool/str/unit`, `mq2_env_method_to_candidate_classes_built`) and `crates/ailang-codegen/src/lib.rs` (`lower_eq_str_calls_strcmp_with_bytes_pointer`). The `alwaysinline` LLVM attribute is correctly classified as new feature-work commitment (no live occurrences today), not as a load-bearing assumption about present state. First grounding-check pass BLOCKED on one spec defect — the spec mischaracterised `crates/ailang-core/src/desugar.rs:2414` as "a separate desugar pass" when it is in fact a `#[cfg(test)] mod tests` AST-literal scaffold. Fixed inline: §Architecture and §Components/4 now enumerate only `build_eq` (desugar.rs:1099) as the sole production desugar site; `desugar.rs:2414`, `lib.rs:6092`, `lib.rs:6220` are framed as test-scaffold migrations alongside the production change, not as desugar-pass work. Re-dispatch PASS. Out of scope (tracked separately): - Deriving for Eq/Ord — `typeclasses.md:177` "No deriving" stands; instance bodies remain hand-written. - Parameterised-ADT instances (`instance Eq (List a)` etc.) — requires constraint-propagation infrastructure, belongs to Gitea #2 ("22c typeclass corpus expansion"). - Eq/Ord for the `Ordering` ADT itself — no use case; consumed via match, not compared. - `and` / `or` as Builtins — north-star fixture uses `(if … … false)` for short-circuit conjunction; separate concern. refs #1 |
||
|
|
ad0a8d8786 |
plan: boehm-retirement.1 — atomic single-iter execution layout
Decomposes the Boehm-retirement spec (
|
||
|
|
50dc478ca5 |
spec: boehm-retirement — drop the transitional Boehm GC path
Resolves Gitea #4. Approach A (atomic single iteration). Six layers in one cohesive cut: CLI `--alloc=gc` arm removed; codegen `AllocStrategy::Gc` variant deleted with the default flipped to `Rc`; libgc link branch removed; ~3 pure-differential e2e tests plus the `gc_stress.ail` fixture deleted; ~9 RC-feature tests that used GC-stdout as backstop lose only the differential assertion (absolute fixed-stdout pin retained); M2 staticlib alloc-guard drops its gc-arm (bump-arm preserved); design/models/rc-uniqueness excises the Boehm-parity-oracle narrative; pipeline.md drops the libgc pipeline-diagram arm; docs_honesty_pin flips from Boehm-present-tense anchor to four absence-pins against Boehm-zombie strings. Three design forks were resolved with the user via brainstorm Q&A: (1) bump survives as bench-floor — `AllocStrategy::Bump`, the `--alloc=bump` CLI flag, and `runtime/bump.c` all stay; the enum keeps two variants (Rc, Bump); the codegen negative-complement test retargets from `AllocStrategy::Gc` to `AllocStrategy::Bump`. Bump's standing role is the raw-alloc bench-floor for RC-overhead measurement, not a production target. (2) the ~12 RC-vs-GC differential e2e tests are NOT all deleted wholesale — pure-differential ones (test name literally `*_matches_gc_*` or `*_same_stdout_as_gc`) are deleted; the RC-feature tests with GC as backstop keep their absolute stdout pin (`assert_eq!(stdout_rc.trim(), "<n>")`) and only lose the differential assertion. This nuance was added at spec time on top of the user's "delete the differential pattern" answer, because the differential was incidental to tests like `rc_box_drop` / `rc_list_drop_borrow` that pin drop-fn correctness under RC and would lose unrelated coverage if deleted entirely. (3) the 1.3× RC-over-bump number is retained in design/models/rc-uniqueness.md but reframed as a bench-health regression gate (not a Boehm-retirement gate); the closure-chain ±15% wider band is preserved analogously. Grounding-check (ailang-grounding-check) PASS — 7 load-bearing assumptions ratified, all spec-named paths and line numbers verified (±2 lines), all proposed-for-removal strings present at the spec-named locations. Assumption #7 (codegen default currently Gc) is structurally self-evident: removing the variant forces the default onto a surviving one by construction. Out of scope, tracked separately: - Gitea #3 "Closure-pair slab / pool" — would tighten the closure-chain ±15% band; not blocked by retirement. - Any further `AllocStrategy::Bump` rework — still a single-variant bench instrument. refs #4 |
||
|
|
7d8b3a3c10 |
plan: nullary-app.1 — accept (app f) as canonical zero-arg call form
Resolves the design fork in Gitea #12 (the bounce-back from the 2026-05-20 /boss session). User accepted both half-decisions: (a) the surface form `(app f)` becomes the canonical nullary call shape, dropping the "expected at least one argument" parser guard in `parse_app_body`; (b) `Term::App.args` mirrors the *actual* serde attrs of `Term::Ctor.args` — `#[serde(default)]` for read-tolerance, no `skip_serializing_if`, so writes always emit `"args":[]`. The plan covers five small tasks: a RED→GREEN E2E (nullary user fn called as `(app greet)`), the four-line parser-guard removal, the one-attribute serde edit, and a doc-honesty fix on `design/contracts/data-model.md` — the current "args omitted when empty" comment on `Term::Ctor` is factually false relative to the code (verified by a serde probe at plan time) and gets rewritten to describe actual write/read behaviour while we are in the same jsonc block. `design/contracts/honesty-rule.md` enforcement folded into the same iter because leaving a stale comment behind in the block we're modifying would be the exact failure mode the rule names. Hash-impact verified at plan time: `grep -rn '"args":\[\]' examples/*.ail.json` returns zero matches, so the new `#[serde(default)]` on `App.args` is read-only behaviour change — write side is unchanged, no existing fixture hash mutates. The plan documents this explicitly under Task 3.2. Two prior fieldtest specs already supplied the LLM-natural shape evidence — `docs/specs/2026-05-15-fieldtest-mut-local.md` F3 (mut-local) and `docs/specs/2026-05-18-fieldtest-loop-recur.md` spec_gap (`run_forever`) — so the feature-acceptance gate in `design/contracts/feature-acceptance.md` is already passed; no brainstorm phase needed for this iter. refs #12 |
||
|
|
ddb50c3cb3 |
plan: bench-harness-recalibration.1 — drop 6 latency entries + recapture
One terminal iteration covering the whole spec. Four tasks, all on `bench/baseline.json`: - Task 1: pre-recapture JSON edit — drop `max_us` + `p99_9_us` × 3 latency arms (6 entries) and rewrite the `note` field forward- looking. The 6 entries must go before `--update-baseline` runs because `write_new_baseline` faithfully re-baselines anything left in the file (recon Open Q). The note rewrite is folded in here because `--update-baseline` preserves the existing note as- is, so any change has to happen before recapture (or as a separate post-recapture edit; one-edit is cleaner). - Task 2: `bench/check.py --update-baseline` regenerates every remaining `baseline` value from a fresh `bench/run.sh -n 5`, updating `captured` → 2026-05-20 and `captured_via`. - Task 3: acceptance §1 — fresh-HEAD replay → exit 0, 0 regressed, 57 metrics in summary (= pre-edit 63 minus the 6 drops). - Task 4: acceptance §2 — synthetic injection (halve `bench_list_sum.bump_s.baseline` via `jq`) → exit 1 + REGRESSION row on that metric, then restore via `jq` and confirm a final exit-0 replay. Recon adjudications: - Replay-source (recon Open Q1): fresh `bench/run.sh -n 5` for replay, not the same output that produced the recapture. Realistic acceptance scenario; with 10% throughput tolerance vs. ~1-2% measured run-to-run variance on the affected metrics (run-1 / run-2 reproduction data in spec body), there is ample margin. - Note rewrite (recon Open Q2): forward-looking — drop stale refs (JOURNAL workflow retired 8e586f4; the `*.max_us` tolerance convention is now moot since the metric is gone), replace with pointer to docs/specs/2026-05-20-bench-harness- recalibration.md + closed issues #15 / #16. Spec lives where the rationale lives; the note carries the gate-policy one-liner only. No Rust crate touched. `bench/check.py` / `bench/run.sh` / `bench/latency_harness.py` unmodified. Plan self-review (all 8 checklist items): clean. Step granularity checked; Task 3 collapsed from two `bench/check.py` runs to one (single 3-minute run captures both summary and exit code). Ready for handoff to `skills/implement`. |
||
|
|
a97aaebd45 |
spec: bench-harness-recalibration — degate max_us/p99_9, recapture baselines
One-iteration infra milestone closing Gitea #15 + #16. Two issues framed distinct symptoms; reproduction on 2026-05-20 HEAD via two back-to-back `bench/check.py -n 5` runs collapses them onto a single picture: - #15 ("*.bump_s stale") is wider than the issue framed. Drift reproduces deterministically on `bench_list_sum.bump_s` (+13.91% / +15.56%) AND on `bench_hof_pipeline.gc_s` (+10.60% / +10.94%) — not just the bump_s family. Drift correlates with memory pressure: `bench_tree_walk` and `bench_compute_collatz` are clean across both runs. - #16 ("*.max_us structural false-positive") has matured. The "vanishes on rerun" pattern the issue documented from 2026-05-16 / 2026-05-18 audits is gone: today `implicit_at_rc.max_us` reproduces at +47.20% / +49.42%, and `implicit_at_rc.p99_9_us` at +27.79% / +41.92%. Same arm only (`implicit @ rc`); the other two latency arms are clean. The metrics are now drift-elevated AND structurally jitter- prone — both reasons to retire them from the gate. Decision: one cohesive change, all in `bench/baseline.json`. Drop the six unreliable entries (`max_us` + `p99_9_us` × 3 latency arms), then `bench/check.py --update-baseline` from current HEAD to absorb the environmental drift in one honest cut. No code change to `check.py` / `run.sh` / `latency_harness.py` — the harness already iterates only entries present in `baseline.json`, so the schema mechanics work as-is. Alternatives considered and rejected: - Adding a `gated: bool` field per metric to keep `max_us` / `p99_9_us` measured-but-not-gated. Pure speculative infrastructure: today's pathology is drift, not jitter, and the diagnostic value of `max_us` in the `check.py` report is hypothetical (it's already in `run.sh` output upstream). User push-back ("was soll 1?") was correct. - Tolerance widening on the drifted metrics. Hides the drift under a wider band; a real +10% codegen regress would slip through. - `-n` raise for tail metrics. Doesn't address the structural problem (max-of-distribution is OS-jitter-dominated regardless of N); blows up bench wall time ~10x. - cpuset / `isolcpus=` pinning. Sysadmin-layer fix that doesn't survive CI move or a new dev machine. - Histogram-based latency methodology rework (Gitea #19). The proper long-term fix, but a separate brainstorm; this milestone is the stop-gap that buys back the noise floor in the meantime. Grounding-check (Step 7.5): PASS, trivial-spec path — no Rust compiler / checker / codegen / schema / runtime claims (all load-bearing claims are about the out-of-tree Python harness, and are covered by the spec's own replay-pass + synthetic-injection acceptance checks). |
||
|
|
93887aa03b |
workflow: replace docs/roadmap.md with Gitea issue backlog
The forward queue moves out of the in-tree markdown file and into Gitea issues at http://192.168.178.103:3000/Brummel/AILang/issues. Labels: kind:{milestone,feature,todo,idea} + prio:{p1,p2,p3} + state:in-progress. Big chunks live as Gitea milestones (containers) with full prose in the description; smaller items are standalone issues. Browse-and-filter scales constant against growing item count; the previous markdown file was 1059 lines, of which ~850 were already-closed-entry verlauf (the same failure class the JOURNAL cut removed). Sync-drift Code<>Tracker mitigation: Soft-convention `closes #N` / `refs #N` in commit bodies — Gitea auto-closes the issue on push. Captured in user-level CLAUDE.md (~/.claude/CLAUDE.md, not in this commit) as the durable rule; no hook enforcement. In-repo changes: - docs/roadmap.md deleted. - CLAUDE.md (project): Code-layout drops roadmap; /boss gating retargeted; Roles section rewritten with a new "Gitea issues" bullet (URL + tea-CLI snippet) and the closes-#N trailer note. - skills/boss/SKILL.md: 10 sites retargeted, plus Step 1 now prescribes `tea issues ls --labels prio:p1` as the queue read. - skills/brainstorm/SKILL.md: Step 7.5 no-override BLOCK now files a Gitea issue via `tea issues create` instead of appending a roadmap entry; spec deletion stays. - skills/audit/SKILL.md + ailang-architect.md: deferral requirement and debt-heuristic retargeted; forward-intent belongs in the Gitea backlog. - skills/fieldtest/SKILL.md, skills/docwriter/SKILL.md + ailang-docwriter.md: roadmap → backlog. - design/contracts/honesty-rule.md: forward intent lives in the Gitea backlog (pinned phrases unchanged). - design/INDEX.md: Docs bullet drops roadmap, adds the backlog URL. - crates/ailang-core/tests/docs_honesty_pin.rs: two assert messages retargeted (assertion bodies unchanged). - bench/architect_sweeps.sh: Sweep-4 TABU extended with `docs/roadmap\.md` so the deleted path cannot quietly regrow as a cross-reference in design/contracts/. Verification: - cargo build --workspace clean. - cargo test --workspace: 647 passed, 0 failed, 2 ignored. - bench/architect_sweeps.sh exit 0 (all five sweeps clean, incl. new TABU). - grep over the live tree (excluding docs/specs/, docs/plans/) shows zero residual docs/roadmap.md refs. Not touched: ~55 historical files under docs/specs/ and docs/plans/ that mention docs/roadmap.md. Snapshot-character, analogous to the JOURNAL-cut precedent — historical specs are not mass-edited just because a live file was retired; their mentions were correct at write time. |
||
|
|
54f0ced148 |
workflow: delete docs/journals/ and docs/journal-archive.md
Strict application of the "Future-Use, not Verlauf" criterion to the
two remaining journal artefacts:
- `docs/journals/` (110 files): the per-iter and audit journals from
2026-05-11 onward. Pure history; no live reader after the previous
sweep. Entire directory removed.
- `docs/journals/2026-05-19-design-decision-records.md`: the one file
that had live readers (`docs_honesty_pin.rs:108`, `parse.rs:80`,
`duplicate_ctor_pin.rs:8`, three roadmap.md mentions) and was framed
as a "relitigation guard". On re-examination its three asserted
pinned phrases ("Regions were considered and rejected", the
"demands annotations *because*" rationale, the prose-render
placeholder statement) are rationale-prose, not load-bearing
invariants — the test pinned itself, not a system property. Any
Decision that still holds lives in the code, `design/contracts/`,
or `design/models/`. Removed with the rest.
- `docs/journal-archive.md` (pre-2026-05-11 history): content-frozen
long-tail history with no live reader. Removed; if anyone ever
needs the pre-cutoff rationale they can `git log --before=2026-05-11
--grep=<keyword>`.
Live-file consequences:
- `docs_honesty_pin.rs` `design_md_present_tense_anchors_present`:
the three `records.*` assertions and the `read("docs/journals/…")`
are dropped; the contract/model anchor pins remain.
- `duplicate_ctor_pin.rs`: the "why-two-overlays rationale lives in
docs/journals/…" comment is replaced with the rationale inline.
- `parse.rs`: the "form-refinement rationale lives in docs/journals/…"
comment is dropped (the rule body already states the refinement).
- `roadmap.md`: the decision-records mention in the DESIGN.md →
design/ entry's body is dropped; the journal-archive.md `context:`
pointers across ~12 closed entries are either rephrased to point
at the relevant iter/audit (no path), or simplified to a one-line
comment when the iter name alone carries the story.
- `CLAUDE.md` Roles section: the `docs/journal-archive.md` slot is
removed; vocabulary note rephrased.
- `design/INDEX.md`: the Docs bullet drops `journal-archive.md`.
- `skills/README.md` bootstrap-rationale pointer rephrased.
`docs/specs/` and `docs/plans/` (per-milestone specs and per-iteration
plans) are unaffected — they remain the structured-design artefacts
they were before this sweep.
Workspace builds, full test suite green.
|
||
|
|
8e586f493f |
workflow: replace per-iter journal system with git log + BLOCKED.md
The per-iter journal under docs/journals/ duplicated the iter commit body's substance and accumulated as Verlauf-Doku with no Future-Use. Sweep across all live control documents: CLAUDE.md, the 7 SKILL.md files, the 11 agent files, design/INDEX.md and the contracts/models that referenced journals, docs/roadmap.md, and the handful of source comments + tests that pointed at journal files for rationale. Mechanism changes: - Standing-reading-lists in every agent now read `git log -N --format=full` for recent project state, never per-iter journal files. The architect reads `git log <prev-milestone-close>..HEAD --format=full` for audit scope. - implement-orchestrator no longer writes a journal file. DONE outcomes emit just code + stats; the end-report is the per-task summary the Boss uses to write the commit body. PARTIAL/BLOCKED outcomes emit BLOCKED.md at the repo root — uncommitted by convention, Boss removes on repair or discard. New iron-law line + four-rationalisation row + red-flag bullet codify it. - audit ratify mechanic: --update-baseline is now paired with an explicit ratify paragraph in the audit-close commit body, not a separate JOURNAL ratify entry. - design/contracts/honesty-rule.md: "history and rationale lives in docs/journals/" → "lives in git log (iter and audit commit bodies)". Pinned phrase preserved verbatim. - CLAUDE.md "Roles of …" section reframed: design/, git log, journal-archive.md (content-frozen), roadmap.md, specs/, plans/. No docs/journals/ slot anymore. - roadmap.md context-lines that pointed at per-iter journals are dropped where the spec/commit already carries the rationale, or rephrased to "shipped in the <iter> iter commit" / "docs/journal- archive.md (<date> entry)" for pre-2026-05-11 references. What stays (this commit): - docs/journals/ directory and contents are NOT touched. Removing the contents is a separate follow-up. - docs/journals/2026-05-19-design-decision-records.md still has live readers (docs_honesty_pin.rs Z 108 + parse.rs + duplicate_ctor_pin.rs + 3 roadmap mentions) — also follow-up. - docs/journal-archive.md still exists; its self-pointer header has been updated to drop the "see docs/journals/INDEX.md" mention. Workspace builds, full test suite green. |
||
|
|
55ad0fa37f |
workflow: drop docs/WhatsNew.md (Notify carries done-state on its own)
WhatsNew.md duplicated the Notify text into a file the only reader (the user) does not consult. Removed the file and trimmed every reference in the live control docs (CLAUDE.md, skills/boss, skills/implement). The editorial rules (no internals, telegram-pragmatic, factual) are preserved in skills/boss as notify-text discipline. Historical specs/plans/journals are not rewritten — they show the contemporaneous state. |
||
|
|
cca6e3959d |
audit + close: design-ledger-formal-links CLEAN milestone close (no drift, bench 0/0/0, no tidy)
Cleanest close pattern in recent project history. Architect: zero drift -- every commitment + invariant verified positively (clause-5 implements all 4 predicates incl. fence-skip, 8 link tokens match the closed convert-set exactly, disposition-(b) applied to the 2 homeless pointers, honesty-rule positive-half pin-safe, commitments 4/7 byte-unchanged, composition invariant clause-3 ∧ clause-5 GREEN simultaneously, out-of-scope set untouched incl. the 5 in-fence data-model annotations, no commitment-2 violation in any reading list, architect_sweeps clean). Bench: check.py exit 0 (63/0/0/63), compile_check exit 0 (24/0/0/24), cross_lang exit 0 (25/0/0/25); baseline pristine, no --update-baseline, no paired ratify. The two spec amendments (clause-6 + cross-ref definition; clause-5 fence-skip + closed convert-set enumeration) were the discipline working: planner-recon and plan-corpus-fetch surfaced gaps the brainstorm-sample missed; the spec was corpus-grounded *before* any byte moved (grounding-check PASS x3); implementation then ran clean 5/5 with one non-blocking concern (planner self-review-item-8 arithmetic miss on the //! header line count -- substantive assertion unaffected; recorded as lesson). No tidy iteration. No fieldtest -- zero authoring-surface change (no .ail, no language construct, no compiler/checker/codegen path) is the spec-stated reasoned exclusion, audit-confirmed. This commit ratifies the milestone close: - audit journal: docs/journals/2026-05-19-audit-design-ledger-formal-links.md - journals/INDEX.md: audit pointer appended - roadmap.md: [~] -> [x] CLOSED 2026-05-19 with full pipeline record - WhatsNew.md: user-facing done-state entry (verbatim with notify) Spec: docs/specs/2026-05-19-design-ledger-formal-links.md Plan: docs/plans/design-ledger-formal-links.1.md Iter journal: docs/journals/2026-05-19-iter-design-ledger-formal-links.1.md Pipeline: brainstorm (PASS x3) -> planner (recon + plan + self-review 8/8) -> implement (DONE 5/5, Boss-verified independently) -> audit (CLEAN, no tidy). |
||
|
|
8ad91e7f24 |
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).
|
||
|
|
36599bedd9 |
plan: design-ledger-formal-links.1 — clause-5 + 7 conversions + 2 disposition-(b) + honesty-rule positive-half
Single iteration covering the whole milestone (same shape as
rolesplit.1; spec is small, no build-atomicity issue — clause-5 is
isolated additive code, prose edits don't affect compilation).
Five tasks, each at task-level review granularity:
Task 1: clause-5 added to design_index_pin.rs RED-first via
identity-stubbed strip_fences (synthetic vector FAILS) →
correct toggle-on-fence impl (GREEN); module //!-header
extended to name clause-5. Test count 4 → 5.
Task 2: 7 prose-ref conversions to file-relative Markdown links
(float-semantics:69/100, embedding-abi:45, memory-model:44/
105, scope-boundaries:48/88 with the source+Pipeline split).
Exact verbatim before→after for every line. clause-5 stays
GREEN by construction (every introduced link resolves
durable).
Task 3: 2 disposition-(b) homeless-ref removals (pipeline:60-61
in-fence CLI block + authoring-surface:178-181 prose).
Pointer dropped, behavioural prose preserved.
Task 4: honesty-rule.md pin-safe positive-half paragraph between
L14 and the existing L15-blank (the two docs_honesty_pin
phrases at L14/L19 each stay verbatim on their physical
line; the additive insertion splits neither). The new
paragraph names design_index_pin.rs clause-5 by name
(nominal mention, not a link — consistent with the
existing 'Ratified by:' footer style and with §Scope).
Task 5: Whole-suite gate (646 → 647) + 5 grep+diff verifications
(no docs/ link, no #fragment, link count = 8, in-fence
schema-annotations intact, INDEX.md + decision-records
journal + clauses 1-4 byte-unchanged).
Self-review 8/8: spec coverage complete; zero placeholders; names
consistent; bite-sized; no commit steps; pin contiguity verified
(L14 + L19 stay verbatim on their physical lines, replacement body
shows L14 contiguous); no signature change ⇒ no compile-gate
ordering issue; every cargo-test filter substring is a real test
name + unfiltered runs have explicit count assertions.
|
||
|
|
42ff44adf6 |
spec: design-ledger-formal-links — corpus-grounded amendment (clause-5 fence-skip + closed enumeration)
Plan-time corpus verification surfaced a third distinct gap the brainstorm-sample missed: data-model.md:38/66/79/206/226 are 'see §"..."' annotations inside fenced jsonc code blocks (verified: fences at 30-87 and 203-228; the 5 refs fall inside), where a Markdown link is literal text — not a navigable link on any renderer. Per the "two+ surfaced ⇒ ground the spec properly once, don't iter-patch" discipline: amendment 2 is the definitive corpus-grounded pass, not a fourth-patch returning later. Every convert-set ref's prose-vs-fence status + exact bytes personally verified before amending. - clause-5 (Concrete a): adds a strip_fences helper toggling on triple-backtick / tilde lines; the per-file scan runs targets(&strip_fences(&raw)); the RED-first synthetic vector gains two fence-skip assertions (identity-stub of strip_fences ⇒ first assert fails ⇒ genuine RED). Contract grows from 3 to 4 predicates (+ fenced-code-not-scanned). - Scope section: third out-of-scope carve-out — a 'see §"..."' inside a fenced code block is schema-example documentation = the inline- annotation analog of the nominal-mention carve-out (a // comment in a code example is code documentation, not a 'go browse there' pointer). Clean extension of the converged navigational-vs-nominal principle. - Acceptance 3: convert-set CLOSED and exhaustive — 8 prose refs (float-semantics:69/100, embedding-abi:45, memory-model:44/105, scope-boundaries:48/88), 2 disposition-(b) homeless removals (pipeline:61, authoring-surface:180), 6 stay-prose (data-model in-fence x5, embedding-abi:51). Iter-provenance suffixes stripped on conversion. scope-boundaries:88 splits into a source link plus a Pipeline cross-file link. grounding-check third dispatch on the amended bytes: PASS, all 8 assumptions ratified (incl. corpus-state-verified A4-A7 per the rolesplit precedent for text-enumeration claims). |
||
|
|
b1a0364bf2 |
spec: design-ledger-formal-links — recon-driven amendment (clause-6 + cross-ref definition)
Planner Step-2 recon (ailang-plan-recon) surfaced two spec defects;
forward-fix amendment (
|
||
|
|
63b669fa8f |
spec: design-ledger-formal-links — formal cross-links in the design/ ledger
Positive completion of the DESIGN.md -> design/ split: informal prose cross-references become formal file-relative Markdown links, gated by a new RED-first design_index_pin.rs clause-5 (every design/ body link resolves into the durable tier or fails the build). INDEX spine stays repo-root-relative (registry tier, clause-1 unchanged). No authoring surface. Eight converged commitments + the user-decided INDEX sub-fork; grounding-check PASS 7/7. roadmap [~] in-flight. |
||
|
|
2ee408770e | roadmap: close DESIGN.md->design/ ([~]->[x]); WhatsNew: design-spec-restructure done-state | ||
|
|
f683f1aec8 |
iter design-md-rolesplit.tidy (DONE 7/7): resolve milestone-close audit drift
Gate-first TDD: widened design_index_pin.rs clause-3 to a hand-rolled
FAITHFUL Sweep-1 superset (case-sensitive digit-anchored line anchors
+ Sweep-1's ^[^/]* path-excluded date + the audit-named
decision-record phrases, case-insensitive); no regex dep; the blanket
iter-detector rejected as unworkable. Sentence-level strip of
faithfully-migrated history/decision-record prose out of 5 contract
files (the audit's 3 spot-checked + roundtrip-invariant.md +
data-model.md the exhaustive scan found) into the decision-record
journal, each replaced by its present-tense contract equivalent;
float-semantics.md stale 'see Str ABI below' -> str-abi.md;
architect_sweeps honesty sweeps re-scoped to design/contracts only
(models/ is the narrative tier) + ailang-architect.md lockstep.
Invariant: clause-3 GREEN => Sweep-1 clean in contracts/.
The prior dispatch correctly BLOCKED on a real plan defect (iso_date
lacked Sweep-1's path-exclusion, over-firing on legit
docs/specs/2026-.. citations); per the two+-defects-in-one-iteration
discipline the audit Resolution mechanism+scope were corrected
upstream in lockstep (
|
||
|
|
f2cdd67e69 |
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.
|
||
|
|
4f61a7aa4f |
plan: design-md-rolesplit.tidy — audit drift fix (history->journal, sweep re-scope, clause-3 widen)
7 tasks executing the audit Resolution's 5 points: (1) gate-first RED — widen design_index_pin.rs clause-3 to a hand-rolled PROVABLE SUPERSET of architect_sweeps Sweep-1 over design/contracts/ (no regex dep; subsumption proof inline), verify RED vs the un-stripped tree; (2-4) sentence-level strip the faithfully-migrated history/decision-record prose out of typeclasses.md / str-abi.md / scope-boundaries.md into the decision-record journal, per recon's per-sentence contract-residue map, each docs_honesty_pin pinned run guarded contiguous; (5) fix float-semantics.md stale 'see Str ABI below' -> str-abi.md; (6) re-scope architect_sweeps DESIGN_GLOB to design/contracts only (models/ is the narrative tier) + lockstep ailang-architect.md; (7) whole-tree GREEN gate (clause-3 RED->GREEN, 4/4, sweep exit 0, suite >=646/0, acceptance grep CLEAN). Self-review 8/8. |
||
|
|
2ba5e16806 |
audit design-md-rolesplit (milestone close): DRIFT (one tidy iter) + bench causally-exonerated (baseline pristine)
Architect: relocation byte-faithful; 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 but is the relitigation content the
split's spirit sends to journals; [low] float-semantics.md
stale-direction 'see Str ABI below'. Both routed items: 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 — faithfully migrated, not split-introduced).
Bencher: causally-exonerated, DECISIVE on byte-evidence — emitted IR
AND final -O2 binaries byte-identical
|
||
|
|
176821c2e7 |
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).
|
||
|
|
deeffb1872 |
plan: design-md-rolesplit.1 — the whole milestone, build-atomic by task ordering
9 tasks: (1) RED-first design_index_pin.rs 4-clause guard; (2) design/INDEX.md + 14 prose contracts; (3) 5 model whitepapers; (4) decision-record journal + INDEX pointer; (5) retarget the 3 doc-reading tests GREEN vs design/; (6) 2 diagnostics + 2 E2Es lockstep; (7) architect_sweeps.sh spine repoint; (8) ~12 agent lists + 5 SKILL bodies + CLAUDE.md + README + bucket-(e) comment xrefs + OQ7 cite deletion; (9) clean cut (git rm DESIGN.md) + whole-tree gate + acceptance grep. Build-atomicity by construction: include_str! retarget (Task 5) precedes DESIGN.md deletion (Task 9), data-model.md exists from Task 2 — every intermediate cargo build is green, no monster task. Self-review 8/8 (contiguity + compile-gate-ordering + filter-resolution scrubbed). |
||
|
|
314e5e4920 |
spec: design-md-rolesplit — Boss-adjudicated relocation appendix (planner recon resolution)
plan-recon surfaced 7 open questions (genuine Boss design judgement, not architectural forks). Adjudicated and folded into the spec as an authoritative placeholder-free Appendix relocation map (every ##/### of DESIGN.md -> exactly one destination): - design_index_pin.rs clause-2 widened to accept crates/**/src/*.rs in-source #[cfg(test)] mod tests as first-class ratifiers. - INDEX ratifier tokens resolved to recon-verified paths; memory-model -> uniqueness.rs (in-source), tail-calls -> lib.rs:5044 tail_call_in_non_tail_position_is_rejected (NOT loop_recur — different construct), env-construction path corrected to ailang-check/tests. - 3 ledger additions the 12-list under-counted: qualified-xref (source-link only), str-abi (prose+source; the one sanctioned sentence-level move, 2802 bold para), scope-boundaries (present-tense honesty-pinned). Net 15 contracts / 5 models / 1 decision-record journal. - OQ7: lib.rs:103 dangling 'Iter 13b' cite is deleted not retargeted (no forward target exists; a pointer would be fiction). grounding-check re-dispatched after the material edit: PASS, all 6 changed/new ratifiers resolve to named currently-green tests. |
||
|
|
a64b2ccb2a |
spec: design-md-rolesplit — DESIGN.md role-split into design/ contracts+models ledger
Role-split the 3020-line docs/DESIGN.md into design/contracts/ (the hot, test-linked invariant set), design/models/ (one whitepaper per model), and design/INDEX.md as the sole addressable spine; decision- records rehomed to docs/journals/. Clean cut (DESIGN.md deleted, no stub), ###-subsection relocation granularity, build-atomic landing (design_schema_drift.rs include_str! forces one commit), polymorphic INDEX links (code-SoT contracts point at source //!, no prose dup), typed-INDEX anti-regrowth pin (design_index_pin.rs). grounding-check PASS 13/13 after one re-dispatch (commitment-4 pin-status claim corrected: Decision-6 :242 audit-trail sentence is pinned by no test, retired to the decision-record journal, no successor pin by design). roadmap: DESIGN.md->design/ marked [~] in flight (spec landed). |
||
|
|
dd5b18378f |
docs: DESIGN.md §Embedding ABI — current-state honesty (no general-ABI claim)
The §"Embedding ABI" prose presented the M3 contract as "the embedding ABI" — a general boundary — and justified the layout freeze with "this is what codegen emits today". Both overclaim: - The accepted set (bare scalar | single-ctor all-scalar record) is the *whole* contract, narrow by construction. The host hand-constructs and hand-reads the box layout directly; there is no general value-marshalling layer. The text now says this plainly instead of framing the set as a subset of a wider ABI. - The freeze is reframed as the consequence of that direct layout exposure (the host is the contract surface), not as "frozen because that is what lower_ctor emits". - "MUST NOT move these offsets" is corrected to "for an exported type" — the prior wording overclaimed the freeze as binding every record layout; the commitment binds exported types and thereby constrains codegen repacking of exported records. Present-tense Ist-state mirror only: no lockstep/wire-contract design, no post-mortem, no aspirational "should become". Schema section untouched. Verified green: design_schema_drift (8), docs_honesty_pin (5), effect_doc_honesty_pin (4), embed_record_layout_pin (1), embed_staticlib_lowering (3). |
||
|
|
d160f2c977 |
roadmap: close Embedding ABI — M5 ([~]->[x]) — M1–M5 arc complete, audited+ratified+doc-honest; WhatsNew + P2 reframed
M5 done 2026-05-19: real backtest over real Pepperstone tick data
through the real external data-server into the shipped M3-frozen
kernel, across a per-thread-ctx thread swarm; symbol-fan (headline
existence proof) + time-shard (first actual proof of chunk-boundary
invisibility); globally leak-free, deterministic. Zero
language/compiler change; one runtime change (
|
||
|
|
70f2a318e0 |
iter embedding-abi-m5.tidy (DONE 3/3): milestone-close doc-honesty drift — pin-safe, doc/comment-only
Resolves the M5 milestone-close audit DRIFT (audit journal |
||
|
|
e81fb90d88 |
plan: embedding-abi-m5.tidy — milestone-close doc-honesty drift (pin-safe, doc/comment-only)
Resolves the M5 milestone-close audit DRIFT (audit journal |
||
|
|
28ab56af7e |
audit embedding-abi-m5: milestone close — RATIFY gc_rss trio (evidenced) + DRIFT (one doc-honesty tidy); P2 bench noise causally exonerated, baseline pristine for it
Architect: Invariant 1 PASS (zero data-server in any compiler
crate/runtime; ail-embed its own workspace root); M3 frozen-layout
SSOT unmoved (the lone rc.c change
|