54f0ced148
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.
78 lines
2.6 KiB
Rust
78 lines
2.6 KiB
Rust
//! Pin for `CheckError::DuplicateCtor` — same-named ctors in two
|
|
//! different ADTs within one module. Ratifies the load-bearing
|
|
//! consumer of the per-module `env.ctor_index` rebuild in
|
|
//! `check_in_workspace`. Env construction is code-SoT (the
|
|
//! `env-construction` ledger row in design/INDEX.md is source-link
|
|
//! only). The two overlays — typecheck-side rebuild + mono-side
|
|
//! narrowed — are deliberately asymmetric: the typecheck-side
|
|
//! `ctor_index` half exists *for this very diagnostic*, while the
|
|
//! mono-side overlay is narrowed to types-only because the runtime
|
|
//! ctor lookup is type-driven. If the per-module rebuild is ever
|
|
//! removed without an equivalent replacement path, this test goes
|
|
//! red.
|
|
|
|
use ailang_check::check_workspace;
|
|
use ailang_core::ast::{Ctor, Def, Module, TypeDef};
|
|
use ailang_core::workspace::{Registry, Workspace};
|
|
use ailang_core::SCHEMA;
|
|
use std::collections::BTreeMap;
|
|
|
|
#[test]
|
|
fn duplicate_ctor_across_two_adts_in_one_module() {
|
|
let m = Module {
|
|
schema: SCHEMA.into(),
|
|
name: "M".into(),
|
|
imports: vec![],
|
|
defs: vec![
|
|
Def::Type(TypeDef {
|
|
name: "Cat".into(),
|
|
vars: vec![],
|
|
ctors: vec![Ctor {
|
|
name: "Twins".into(),
|
|
fields: vec![],
|
|
}],
|
|
doc: None,
|
|
drop_iterative: false,
|
|
}),
|
|
Def::Type(TypeDef {
|
|
name: "Dog".into(),
|
|
vars: vec![],
|
|
ctors: vec![Ctor {
|
|
name: "Twins".into(),
|
|
fields: vec![],
|
|
}],
|
|
doc: None,
|
|
drop_iterative: false,
|
|
}),
|
|
],
|
|
};
|
|
let mut modules = BTreeMap::new();
|
|
modules.insert(m.name.clone(), m.clone());
|
|
let ws = Workspace {
|
|
entry: m.name.clone(),
|
|
modules,
|
|
root_dir: std::path::PathBuf::from("."),
|
|
registry: Registry::default(),
|
|
};
|
|
|
|
let diags = check_workspace(&ws);
|
|
let dup = diags
|
|
.iter()
|
|
.find(|d| d.code == "duplicate-ctor")
|
|
.unwrap_or_else(|| {
|
|
panic!(
|
|
"expected at least one `duplicate-ctor` diagnostic, got: {diags:?}"
|
|
)
|
|
});
|
|
assert!(
|
|
dup.message.contains("Twins"),
|
|
"expected message to name the duplicate ctor `Twins`, got: {}",
|
|
dup.message
|
|
);
|
|
assert!(
|
|
dup.message.contains("Cat") && dup.message.contains("Dog"),
|
|
"expected message to name both ADTs `Cat` and `Dog`, got: {}",
|
|
dup.message
|
|
);
|
|
}
|