iter kernel-extension-mechanics.tidy: architect drift items — present-state + plugin-migration aftermath

Audit Step 3 fix path. Architect drift review at milestone close
surfaced 8 items (3 high, 4 medium, 1 low). Resolved 7 inline as
mechanical text rewrites + 2 source-rustdoc cleanups; the 1 low
(cycle-avoidance pattern documentation in design ledger) is
deferred — architect flagged it "Note, do not push" because the
pattern is implementation mechanism, not language semantics,
and is already documented in the load-bearing place
(`crates/ailang-kernel-stub/src/lib.rs //!`).

CLAUDE.md (2 sites):
  - Lead paragraph: "this file carries [...] in-tree skill system"
    → reframe to "this file carries [...] orchestrator discipline
    (the skill system itself lives in the ~/dev/skills/ plugin
    and is wired in via .claude/dev-cycle-profile.yml)".
  - Code-layout table: new row for `crates/ailang-kernel-stub/`
    documenting the zero-dep leaf design, the parse-hop location
    in `ailang-surface`, and the planned retirement at raw-buf
    landing.

design/INDEX.md (2 sites):
  - Project-ecosystem "Skills" bullet: in-tree `skills/` path +
    `skills/README.md` reference → `~/dev/skills/` plugin +
    in-tree per-project profile. Also added `docwriter` and
    `boss` to the enumerated skill list (8 in total) for
    completeness.
  - kernel-extensions row 111: added stub-retirement plan to the
    annotation so the spine names the future state, not just the
    in-tree reader of `lib.rs //!`.

design/models/0007-kernel-extensions.md (3 sites):
  - § "Migration policy" subsection: 4 bullets transitioned
    forward → present-state per honesty-rule. References to
    `loader.rs:98-108` / `workspace.rs:308-311, 467, 2655` as
    if hardcoded paths still existed → described as past state
    that has been replaced by the generic flag-filter. Codegen-
    intercept-migration bullet kept forward-looking because the
    `try_emit_primitive_instance_body` migration is *actually*
    still pending (deferred to Series milestone per spec
    § Out-of-scope).
  - § "Feature-acceptance argument": "the bounded push-only
    mutation surface — gated by the `Series` effect" — internal
    contradiction with three earlier statements that "Series
    carries no separate algebraic effect; mutation is mode-
    tracked, not effect-tracked". Re-framed to "gated by
    uniqueness mode-tracking on the owned `Series` value (not by
    an algebraic effect; see §"Coexistence" below)".
  - § "Coexistence" "Algebraic effects" bullet: "Reused
    unchanged. The `Series` effect is a new name" — same
    contradiction. Re-framed to "Not extended by Series.
    Mutation discipline lives in the uniqueness/mode system; the
    algebraic-effects set is unchanged".

Source rustdoc (2 sites):
  - `crates/ailang-core/tests/design_index_pin.rs:117` comment
    "skills/**/SKILL.md" → "any in-tree project-discipline
    document (e.g. CLAUDE.md)" — the allowlist comment now
    matches what the test actually does (no allowlist enforced
    in code; any existing path passes).
  - `crates/ailang-core/tests/design_schema_drift.rs:419`
    rustdoc: "RED until `skills/implement` mini-mode adds it"
    → "RED until the `implement` skill (mini-mode dispatch)
    adds it" — same skill, post-plugin-migration framing.

Architect items not addressed in this tidy:
  - 0007 § "The plugin contract (consolidated)" forward-intent
    reference to `try_emit_primitive_instance_body` migration —
    architect flagged as edge-case-acceptable per the explicit
    STATUS carve-out (the migration IS still pending). No
    change.
  - Cycle-avoidance pattern documentation (low): deferred per
    architect recommendation.

Tests green (664/0); workspace_pin module-count assertion picked
up from a844de3 carries through.
This commit is contained in:
2026-05-28 19:04:43 +02:00
parent de4399df37
commit 9d2e752f07
5 changed files with 52 additions and 41 deletions
+5 -2
View File
@@ -2,8 +2,10 @@ Inherits `~/.claude/CLAUDE.md` (chat language, IONOS security)
and `~/dev/CLAUDE.md` (cross-project dev rules: English in and `~/dev/CLAUDE.md` (cross-project dev rules: English in
repos, commit convention, issue-tracker vocabulary). This file repos, commit convention, issue-tracker vocabulary). This file
carries only AILang-specific decisions on top — the language carries only AILang-specific decisions on top — the language
identity, code layout, file-naming convention, in-tree skill identity, code layout, file-naming convention, the
system, project-calibrated orchestrator discipline, and the project-calibrated orchestrator discipline (the skill system
itself lives in the `~/dev/skills/` plugin and is wired into
this project via `.claude/dev-cycle-profile.yml`), and the
LLM-utility feature gate. LLM-utility feature gate.
## AILang — a language for LLM authors ## AILang — a language for LLM authors
@@ -47,6 +49,7 @@ it measurably improves correctness or removes redundancy.
| `crates/ailang-check/` | Type and uniqueness/mode analysis, lints, diagnostics | | `crates/ailang-check/` | Type and uniqueness/mode analysis, lints, diagnostics |
| `crates/ailang-codegen/` | LLVM-IR codegen — RC, drop, lambda lowering, match lowering, escape, synth, subst | | `crates/ailang-codegen/` | LLVM-IR codegen — RC, drop, lambda lowering, match lowering, escape, synth, subst |
| `crates/ailang-prose/` | Form-A ↔ Form-B prose projection | | `crates/ailang-prose/` | Form-A ↔ Form-B prose projection |
| `crates/ailang-kernel-stub/` | Zero-dependency leaf crate carrying only the Form-A source of the `kernel_stub` ratifying-fixture module (`pub const STUB_AIL: &str`). The parse hop (`parse_kernel_stub`) lives in `ailang-surface` to keep the crate-dependency graph acyclic. Injected into every workspace load alongside `prelude`; may be retired when the `raw-buf` milestone lands a real second kernel-tier consumer. |
| `runtime/` | C glue around the RC runtime | | `runtime/` | C glue around the RC runtime |
| `bench/` | Regression harnesses (`check.py`, `compile_check.py`, `cross_lang.py`) and the throughput-and-latency runner (`run.sh`); `bench/reference/` holds the hand-C corpus for cross-language ratios | | `bench/` | Regression harnesses (`check.py`, `compile_check.py`, `cross_lang.py`) and the throughput-and-latency runner (`run.sh`); `bench/reference/` holds the hand-C corpus for cross-language ratios |
| `examples/` | AILang fixtures used by tests and benches | | `examples/` | AILang fixtures used by tests and benches |
+1 -1
View File
@@ -114,7 +114,7 @@ fn every_contract_names_a_resolvable_ratifying_test() {
// clause 2 — ratifying-test token resolves to a real file under // clause 2 — ratifying-test token resolves to a real file under
// crates/**/tests, crates/**/src (in-source #[cfg(test)] mod // crates/**/tests, crates/**/src (in-source #[cfg(test)] mod
// tests are first-class ratifiers — spec OQ1/OQ2), bench/, or // tests are first-class ratifiers — spec OQ1/OQ2), bench/, or
// skills/**/SKILL.md. // any in-tree project-discipline document (e.g. CLAUDE.md).
let (contracts, _) = index_tables(); let (contracts, _) = index_tables();
for row in &contracts { for row in &contracts {
// columns: id | consumer/lifetime | ratifying-test | link // columns: id | consumer/lifetime | ratifying-test | link
@@ -416,8 +416,8 @@ fn design_md_anchors_every_parammode_variant() {
/// block must report PRESENT under the scoped helper. /// block must report PRESENT under the scoped helper.
/// ///
/// Gitea issue #10. The helper `anchor_in_jsonc_block` does not yet exist — /// Gitea issue #10. The helper `anchor_in_jsonc_block` does not yet exist —
/// this test is RED until `skills/implement` mini-mode adds it and re-routes /// this test is RED until the `implement` skill (mini-mode dispatch) adds it
/// the six existing call sites onto it. /// and re-routes the six existing call sites onto it.
#[test] #[test]
fn anchor_presence_check_is_scoped_to_jsonc_blocks() { fn anchor_presence_check_is_scoped_to_jsonc_blocks() {
// Anchor mentioned only in prose — the false-pass surface. The whole // Anchor mentioned only in prose — the false-pass surface. The whole
+7 -6
View File
@@ -46,12 +46,13 @@ evolving in lockstep with the language:
`merge-prose`, etc., preferably with `--json` for machine consumption. `merge-prose`, etc., preferably with `--json` for machine consumption.
- **Examples** (`examples/`): canonical `.ail.json` programs. They are - **Examples** (`examples/`): canonical `.ail.json` programs. They are
specification anchors, not demos — the E2E suite hangs off them. specification anchors, not demos — the E2E suite hangs off them.
- **Skills** (`skills/`): specialised disciplines - **Skills** (`~/dev/skills/` plugin, wired in via
`.claude/dev-cycle-profile.yml`): specialised disciplines
(`brainstorm`, `planner`, `implement`, `audit`, `debug`, (`brainstorm`, `planner`, `implement`, `audit`, `debug`,
`fieldtest`) plus the agent rosters they dispatch `fieldtest`, `docwriter`, `boss`) plus the agent rosters
(`skills/<name>/agents/`). They form the project's own they dispatch. They form the project's development
development methodology and are versioned with the codebase. methodology; the plugin is versioned separately, the
See `skills/README.md`. per-project profile is in-tree.
- **Design ledger** (`design/`): `design/INDEX.md` (this file — the - **Design ledger** (`design/`): `design/INDEX.md` (this file — the
sole addressable spine for canonical state), `design/contracts/` sole addressable spine for canonical state), `design/contracts/`
(test-linked invariants), `design/models/` (onboarding (test-linked invariants), `design/models/` (onboarding
@@ -108,4 +109,4 @@ is the default.
| authoring-surface | onboarding / evolves | design/models/0001-authoring-surface.md | | authoring-surface | onboarding / evolves | design/models/0001-authoring-surface.md |
| prose-projection | onboarding / evolves | design/models/0006-prose-projection.md | | prose-projection | onboarding / evolves | design/models/0006-prose-projection.md |
| pipeline | onboarding / evolves | design/models/0003-pipeline.md | | pipeline | onboarding / evolves | design/models/0003-pipeline.md |
| kernel-extensions | onboarding / evolves (mechanisms milestone closed 2026-05-28; raw-buf and series milestones pending) | design/models/0007-kernel-extensions.md | | kernel-extensions | onboarding / evolves (mechanisms milestone closed 2026-05-28; ratified end-to-end by the `ailang-kernel-stub` fixture, planned for retirement when raw-buf lands a real second consumer; raw-buf and series milestones pending) | design/models/0007-kernel-extensions.md |
+37 -30
View File
@@ -517,9 +517,11 @@ summary: LLM authors naturally reach for a bounded ring buffer
for streaming workloads (clause 1 — the SMA worked example for streaming workloads (clause 1 — the SMA worked example
above is the evidence); the type structurally eliminates a class above is the evidence); the type structurally eliminates a class
of off-by-one and warmup-handling bugs (clause 2); the bounded of off-by-one and warmup-handling bugs (clause 2); the bounded
push-only mutation surface — gated by the `Series` effect — does push-only mutation surface — gated by uniqueness mode-tracking
not reintroduce the iterated-mutable-state bug class that the on the owned `Series` value (not by an algebraic effect; see
`mut`/`var`/`assign` removal addressed (clause 3 — see §"Coexistence" below) — does not reintroduce the iterated-
mutable-state bug class that the `mut`/`var`/`assign` removal
addressed (clause 3 — see
`docs/specs/0052-kernel-extension-mechanics.md`'s clause-3 `docs/specs/0052-kernel-extension-mechanics.md`'s clause-3
discussion). discussion).
@@ -537,36 +539,41 @@ strictly better than an existing one for the use case it covers,
the existing one is retired or repositioned, not preserved the existing one is retired or repositioned, not preserved
in parallel for compatibility.** in parallel for compatibility.**
Concrete consequences for the prep milestone: Concrete state after the mechanisms milestone closed (2026-05-28):
- Type-scoped namespacing makes `<module>.<TypeOrFn>` non-canonical - Type-scoped namespacing makes `<module>.<TypeOrFn>` non-canonical
for type-associated operations. Existing examples and fixtures for type-associated operations. The example and fixture corpus
using `std_maybe.from_maybe`, `std_pair.from_pair`, etc., are has been rewritten from `std_maybe.from_maybe`,
rewritten to type-scoped form. Hash pins are refreshed in `std_pair.from_pair`, etc., to type-scoped form. The hash-pin
lockstep — each test crate (`crates/ailang-core/tests/hash_pin.rs`, blast-radius audit at prep.1 plan time enumerated the affected
`crates/ailang-surface/tests/prelude_module_hash_pin.rs`, and pin files; only `crates/ailang-surface/tests/prelude_module_hash_pin.rs`
any other hash-pin file the prep recon enumerates) is walked, needed refresh in this milestone (at prep.3, when prelude
per the "hash-pin blast-radius audit" practice. gained `(kernel)`).
- The existing `BareCrossModuleTypeRef` / - The pre-existing `BareCrossModuleTypeRef` /
`BadCrossModuleTypeRef` diagnostics are repurposed: what they `BadCrossModuleTypeRef` diagnostics are repurposed: what they
considered "bad" before (a bare type ref to a foreign module's considered "bad" before (a bare type ref to a foreign module's
type) becomes "bad" still, but the *correct* form is now type) is still bad when the type is not in scope, but the
type-scoped (when feasible) rather than module-qualified. *correct* form is now type-scoped (when feasible) rather than
module-qualified.
- The prelude module gains `kernel: true`. The hardcoded - The prelude module carries `kernel: true`. The previously
prelude-name paths in `crates/ailang-surface/src/loader.rs:98-108` hardcoded prelude-name paths in `crates/ailang-surface/src/loader.rs`
and `crates/ailang-core/src/workspace.rs:308-311, 467, 2655` (the `&["prelude"]` literal) and the matching reservation +
migrate to the generic flag-driven mechanism. Consumer- contract docs in `crates/ailang-core/src/workspace.rs` have
observable behaviour for prelude is unchanged (the 12 free been replaced by a generic `modules.values().filter(|m| m.kernel)`
fns remain callable bare); the code path no longer hardcodes derivation. Consumer-observable behaviour for prelude is
any module name as special. unchanged (the 12 free fns remain callable bare in every
consumer — `crates/ail/tests/prelude_free_fns.rs` is the
regression pin); the code path no longer hardcodes any module
name as special.
- Codegen intercepts: the existing `try_emit_primitive_instance_body` - Codegen intercepts: the pre-existing `try_emit_primitive_instance_body`
hardcoded list is migrated into the plugin registry as part hardcoded list is **not yet** migrated into a plugin registry
of the Series milestone when there is the first real that migration is deferred to the Series milestone, when there
external consumer, the mechanism graduates from "hardcoded is the first real external consumer and the mechanism can
for one case" to "registry for many cases". graduate from "hardcoded for one case" to "registry for many
cases". Single-consumer registries are premature mechanism.
The reason migration cost is not a decision driver: there is The reason migration cost is not a decision driver: there is
nothing to break externally, and rewrites inside the workspace nothing to break externally, and rewrites inside the workspace
@@ -589,10 +596,10 @@ here so the spec can quote the position:
via the instance) and a `Series.dump` free-fn def (accessed via the instance) and a `Series.dump` free-fn def (accessed
via type-scope). Both mechanisms remain. via type-scope). Both mechanisms remain.
- **Algebraic effects.** Reused unchanged. The `Series` effect - **Algebraic effects.** Not extended by Series. Mutation
is a new name in the flat effect-set; the `(do effect/op discipline lives in the uniqueness/mode system (see
args)` syntax is the existing one (`io/print_str` is the `(own Series)` in caller signatures); the algebraic-effects
precedent). set is unchanged.
- **RC + uniqueness.** Series values are RC-managed like any - **RC + uniqueness.** Series values are RC-managed like any
heap value; drop is via a kernel-supplied `@ailang_series_drop`. heap value; drop is via a kernel-supplied `@ailang_series_drop`.