test-intergraion.sh can never be ran automatically #232
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/232-test-intergraion-sh-can-never-be-ran-automatic"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
test-intergraion.sh can never be ran automatically
Along the way:
Stringmodule const could not be READfn main's parameter is an arity fault, not a lowering oneList<Char>could not be rebuilt into aStringinitis constant folding, and the arrow only runs one wayTouches 99 files:
CLAUDE.md,docs/01-laws.md,docs/03-types.md,docs/05-control.md,docs/08-errors.md,docs/10-effects.mdand 93 more.Split. The decision in
process_exit_codeis a pure function now, with its own tests insrc/rust/crates/ck_driver/src/lib.rs.It can borrow. The clone of
insertwas left over from before the lifetime was threaded throughsrc/rust/crates/ck_resolve/src/const_values.rs, and it is gone.It said what I assumed. Reworded in
src/rust/crates/ck_driver/src/run_cmd.rsso it names the input that broke it, which is what the bug report will need.Updated. The point about
src/rust/crates/ck_driver/src/lib.rsturned out to be a real bug, so thank you.Mostly there, but the question on
src/rust/crates/ck_driver/src/lib.rsneeds an answer before this lands.@ -1154,3 +601,3 @@/// Map a program's `i32` exit code onto the process's `u8` exit status (the OS/// only carries the low byte).fn process_exit_code(code: i32) -> ExitCode {pub(crate) fn process_exit_code(code: i32) -> ExitCode {process_exit_codereads, decides and writes in one function. The deciding part is the piece I would want to test on its own. Worth splitting?@ -0,0 +273,4 @@/// 2026-07-18).#[test]fn opt_flag_defaults_to_speed() {let parsed = parse_run_args(&argv(&["main.ck"])).expect("bare path parses");The expect message on
parsedis the only thing a user sees if this fires. Does it say what they should do, or only what we assumed?, at src/rust/crates/ck_driver/src/run_cmd.rs:276.@ -155,3 +163,3 @@});visiting.remove(&id);memo.insert(id, result);memo.insert(id, result.clone());insertis cloned on what looks like a hot path. Is the ownership forced here, or can this borrow?, at src/rust/crates/ck_resolve/src/const_values.rs:165.Looked through
src/rust/crates/ck_driver/src/lib.rsas well. Fine by me.Good. The second pass on
src/rust/crates/ck_driver/src/lib.rsis what I hoped for.`ck_driver/src/lib.rs` was 1323 lines against `MAX_FILE_LOC` 862 — the one `architectural-rule R3` violation in the workspace, standing long enough that `test-integration.sh` carried it on `KNOWN_RED` so the sweep could be read at all. The ask was to raise the cap. Raising it is global: 27 files already sit between 700 and 862, six within 22 lines of it, and `ck_types/src/diag.rs` at 856 is the file that went to 911 last week and was caught by exactly this cap (d991f0e5). A 1323 cap would have let that through and handed the other 26 files 461 lines of slack to park in. `CRATE_FILE_LOC_CAPS` could not soften it either — R3 asserts every per-crate entry is `<= MAX_FILE_LOC`, deliberately, so a per-crate cap can only tighten. So the file splits instead and the cap does not move. Two modules, cut along what the verbs actually share rather than by line count: outcome.rs 321 the `outcome` verb, `OutcomeArgs` + parser, and the three observers that classify where a compile stopped run_cmd.rs 335 `run` and `test` — both consume `RunArgs` — with the parser, its seven tests, and the `--mem` arena report lib.rs 695 dispatch, the `check`/`serve`/`stop` shells, shared helpers `test_cmd` moved in with `run_cmd` rather than staying at the root: it consumes `RunArgs` and `print_mem_report`, so leaving it behind meant widening two more helpers to `pub(crate)` for it to reach back across the boundary. Four things are `pub(crate)` now (`USAGE`, `resolve_stdlib`, `resolve_arg_path`, `process_exit_code`); nothing became `pub`. Pure movement — no behaviour change. `MAX_FILE_LOC` DOES NOT ratchet down, and that is a miss worth naming rather than leaving implied: 862 is already tight against `ck_lex/src/syntax_kind.rs` at exactly 862. This commit earns the allow-list entry's deletion, not a threshold move. `syntax_kind.rs` is what the cap descends past next. The `KNOWN_RED` emptying and the phantom-entry guard it needed landed separately in 8b2dc22c, with the owner's standing refusal to run that script automatically. Verified: four legs ALL GREEN; the integration sweep 252 passed / 0 known-red / 1 ignored (`corpus_inspect`, an opt-in printer, not an assertion) — 252 rather than 251 because R3 crossed from failed to passed; `clippy --workspace --all-targets` 0 warnings; `cargo fmt --all --check` clean; `--test architecture` 39/39.`corpus_inspect` carried `#[ignore = "opt-in via scripts/test.sh --corpus"]`. That driver was deleted with the old gate in `fc744ca6`, when `test.sh` became the four-leg sequencer — so for the last week the reason has been sending its reader to a flag their checkout does not have, in the one place a reader looks when a test will not run. `CLAUDE.md` §6 names this defect for `docs/`; it is the same defect in a doc comment, and worse there, because the ignore string is what `cargo test` prints back at you. Nothing in `scripts/` sets `CK_CORPUS_FILTER` any more — the only three references left in the tree are inside this file, where the test reads its own env var and documented its own dead flag. So the doc comment now carries the whole invocation: CK_CORPUS_FILTER=types/Roles.ck cargo test -p ck_driver --test corpus -- \ --ignored --nocapture corpus_inspect and the reason says why the test is ignored — it PRINTS rather than asserts, so running it in a gate adds noise, not coverage — rather than naming a way to run it that does not work. `tests/corpus/types/Roles.ck` is a real file; citing a path that does not exist is the defect being fixed, not a way to fix it. The gate twin is linked by its real name, `corpus_apps_match_their_trap_md`. The first draft of this comment called it `corpus_reconcile`, which is what the prose describes it as doing and not what it is called — a broken intra-doc link introduced while fixing a broken citation. No behaviour change: the test is `#[ignore]`d before and after, and its body is untouched. R3 covers `tests/` as well as `src/`; corpus.rs is 470 against 862. Verified: `cargo check -p ck_driver --test corpus` clean, `clippy` on that target 0 warnings, `cargo fmt --all --check` clean. The integration sweep was NOT run (owner, 8b2dc22c).Stringmodule const could not be READ 648ed1e337The cell had diagnosed the const FOLDER as having no answer for a two-word value. The truth was narrower and duller: the fold's literal reader admitted a closed set of token kinds — `IntLit`, `TrueKw`, `FalseKw` — and `StringLit` was simply not in it. So the value never reached the interner's registry, and every reference read absence as "not a compile-time value" and refused with `lower: ConstUnfoldable`. The immediate was never missing: `ConstVal::Str` is what a `String` LITERAL in a body has always lowered to. One value form crosses one registry, and there is still exactly ONE module-const evaluator. `ck_resolve::const_values::read_literal` admits `StringLit` and decodes it through `ck_hir::decode_str_literal` — the same escape table the lexer, the checker's measure and `ck_lower::read_str` already share, so the bytes the registry carries are the bytes codegen emits. `ConstScalar` gains `Str(Box<str>)` and loses `Copy`; the driver's `DeclaredShape::Str` admits it; `lower_const_ref`'s existing non-scalar arm carries it the rest of the way untouched. Width did not move and is still the type stage's: `const t: String<2> = "abcdef"` is E0702 at check time and never reaches the fold (measured), so a second width law in `admit` could only have converted that diagnostic into a silent refusal. `String` is recognized by its canonical `TypeId` — scope first, then the project-global nominal roster, since an app module imports nothing — never by a `== "String"` name probe, which is rule V6 and which the first cut of this change violated. Two catch-alls went with it, both of the shape that caused the bug: `admit`'s `_` arm (a value form with no pair now fails to compile instead of silently refusing every reference) and `read_literal`'s `_ => Bool(false)` (a widened token guard can no longer fold a new literal to `false`). `capability.rs` sat at exactly `MAX_FILE_LOC` (862), so the provenance the fix workflow requires was a guaranteed R3 violation for this cell and every next one. Split on the `tests/architecture/{main,caps}.rs` precedent: `main.rs` is the harness, `ledger.rs` is the three ratchets and their history. The cap did not move. `test-capability.sh` repoints `LEDGER_SRC` and its `sed` now tolerates the `pub(crate)` prefix — it refused loudly when it could not read the ratchet, which is the gate working. Moved: `a_module_const_string_does_not_fold` -> `module_const_string_is_read`, `lower: ConstUnfoldable` -> `runs: 42`; `BROKEN_CELL_COUNT` 45 -> 44; three `ck_resolve` unit tests (one of which had pinned this very defect as correct behaviour); plan.md's §1 ledger row and §4c, which read 42 BROKEN and 442 cells against source values of 45 and 464 — stale prose, corrected to the source rather than decremented from a wrong number. Not moved: `tag::String` on a const reference is still E0301, because resolution does not treat a module const as a value head. It was a separate defect wearing this one's clothes; the rewritten cell says so. Gates: ./scripts/test.sh ALL GREEN (4 legs — unit, corpus 107 apps, capability 464 cells, docs 40 expectations). cargo test --workspace --tests 1637 passed, 0 failed. cargo fmt --check clean. cargo clippy --workspace --all-targets -D warnings: 0 warnings, 0 errors. architecture 39 passed, 0 failed.fn main's parameter is an arity fault, not a lowering one caa4e47085The wrong reasoning was mine before it was the cell's, and it is the cheap one: the grammar admits `effect_decl = 'effect' <name> '{' <members: effect_member{0,64}> '}'`, so a blockless effect PARSES, and I read that as the block being optional. A grammar bounds what parses. It never claimed to bound what is well-formed. The rule was already written down one accessor away — `ck_syntax::EffectDecl::test_block`: "every effect *must* declare one … enforcing the rule is a resolver-stage concern, not the parser's." The cell was pinning a promise the tree made and no pass kept. The mechanism. `collect_project_effects` walks every `effect Name { … }` in the build closure and already refuses one property of the declaration — E0501, the name declared twice. Completeness is the same kind of fact: knowable from the declaration alone, and it must hold before any call site resolves, for the same supply-chain reason E0501 is front-loaded. So the walk reads `decl.test_block()` and a `None` is **E0510**, anchored at the effect's own name. The effect still REGISTERS when the block is missing: the declaration is incomplete, not absent, and refusing to register it would bury one defect at the declaration under an unknown-op cascade at every use. The check is on PRESENCE, by ruling. A mock's operations mirror the effect's — same names, same signatures, bodies free to be empty — but that shape is not machine-checked, so an empty `test {}` satisfies E0510. A marker effect with no operations owes the block too: one law, no carve-out for the degenerate arity, and `EffectDecl::operations` already calls `effect Alloc<Ctx> { test { … } }` the canonical marker shape. What the stdlib cost, and what it taught. `Panic`, `Assert` and `Verdict` had no mock and now carry one. `-> Nothing` accepts an empty body, so `Panic::raise` — the operation that looked unmockable, since a mock returning `Nothing` would have to diverge — was not. Its OVERLOAD is the real find: an effect body is the one place CkLang allows an operation-name overload (`collect_ops` says so and collects both), but a `test { }` block's members share one flat scope, so the second `raise` is E0305. `Panic.ck` carries the arity-2 mirror and says why, and the gap is pinned rather than papered over. Ledgers. `BROKEN_CELL_COUNT` 43 -> 42 for the fix, then 42 -> 43 for the cell that fix uncovered — `an_effect_mock_cannot_mirror_an_overload`, BROKEN, which does not block E0510 and so stays a cell by the demand-driven rule. `CELL_COUNT` 464 -> 465. Net: one closed, one opened, the queue the same length, which is the honest reading. `plan.md` §1 and §4c follow. What else moved. 31 mirrored blocks across the capability, resolve, types, lex and parser fixtures and the ck_resolve unit fixtures; four `# trap` coordinates re-anchored for the lines those blocks inserted; conformance goldens re-blessed. The book stated the block was "optional" (`docs/10-effects.md`) and that an effect "may" declare a mock (`docs/12-testing.md`) — both false the day `EffectDecl::test_block` was written, both corrected, and 10-effects now carries E0510 as a DELIVERED claim. `EffectDecl::test_block`'s own doc no longer promises an enforcement that exists. Gates. `./scripts/test.sh` ALL GREEN — unit 1382 passed / 0 ignored, corpus 107 apps, capability 465 cells, docs 40 expectations held / 0 failed. `cargo test --workspace --tests --no-fail-fast`: 1639 passed, 0 failed, 1 ignored. `cargo fmt --all -- --check`: 0. `cargo clippy --workspace --all-targets -- -D warnings`: 0 warnings, 0 errors.`tests/parser/effect/marker_with_generics` had been rewritten to `effect Alloc<Ctx> { test {} }` so it would stay clean under E0510. That traded away the thing the fixture existed for — the bare `effect Alloc<Ctx> {}` parse, a marker effect with an empty body and a generic binder — to keep a diagnostics section quiet. The owner's call is to keep the bare parse. So the fixture states both halves instead. The source is `effect Alloc<Ctx> {}` again, the CST golden pins the empty-bodied `EffectDecl` with its `GenericParams`, and the diagnostics section carries the E0510 that shape now earns, trapped as `E0510: 3, 8` so the untrapped ratchet does not absorb it (91 -> 87, back at the cap, unchanged). One page now says that the marker shape parses clean and is refused after it parses — which is the split between what a grammar bounds and what a resolver decides, written where both are visible. Also corrects two claims that were false when they landed one commit ago. Both the ledger paragraph and `plan.md` §4c said `tests/lex` and `tests/parser` kept their blockless effects because "those stages do not run this pass". They do: every `.cktest` runs the whole pipeline and reconciles diagnostics, `# expected: cst` fixtures included, which is why those two trees needed blocks at all. The corrected count is 31 mirrored blocks across the fixture trees — 12 capability, 5 resolve, 12 types, 1 lex, 1 parser — beside the 3 in the stdlib. Gates. `./scripts/test.sh` ALL GREEN — unit 1382 passed / 0 ignored, corpus 107 apps, capability 465 cells, docs 40 expectations held / 0 failed. `cargo test --workspace --tests --no-fail-fast`: 1639 passed, 0 failed, 1 ignored. `cargo fmt --all -- --check`: 0. `cargo clippy --workspace --all-targets -- -D warnings`: 0 warnings, 0 errors.List<Char>could not be rebuilt into aStringec2f3321c7initis constant folding, and the arrow only runs one way 8b4a2a9077