Skip to content

fix(specs): make 62 specs that no backend accepted compile again (Closes #4793) - #4794

Merged
dmitrii-f-t27 merged 2 commits into
gHashTag:masterfrom
dmitrii-f-t27:fix/broken-specs-2026-09-24
Sep 24, 2026
Merged

dmitrii-f-t27 merged 2 commits into
gHashTag:masterfrom
dmitrii-f-t27:fix/broken-specs-2026-09-24

Conversation

@dmitrii-f-t27

Copy link
Copy Markdown
Collaborator

Closes #4793

The Queen board (t27.ai/queen → Specs) lists Broken 218. Re-measured on master a103752 with the explorer wasm and t27c built from that commit, 62 of them are real sources in this repository that fail in the parser, before any backend: Zig idioms (std.ArrayList, for (xs) |x|, try std.testing.expect, [_]T{...}), Rust idioms (let mut, Vec::new, format!, slices), the older t27 style (import x;, module X { ... } blocks, given ... when ... tests, }; after a struct) and typos. Five are the regressions of #4488. The rest of the 218 is not this PR: not-modules (#4541), fixtures broken on purpose, and 54 files in other repositories (tt-trinity-euler#99, trios#1680, turbobaby-user-bot#64, tt-trinity-gamma#230).

What changed. Syntax translated to t27, meaning kept: declarations, tests, invariants, benches, assertions and constants stay; where t27 has no direct form, the spec says so in a comment. Each batch was reviewed a second time against the original's declaration and assertion counts, and repaired where the review found a problem.

Verified locally on this branch

  • all 62: seven explorer targets OK (c, js, rust, ts, verilog, verilog_hir, zig) and t27c gen / gen-c / gen-rust / gen-verilog succeed; 61 have 0 discarded / 0 swallowed, specs/igla/coder/benchmark.t27 keeps 18 quantified invariants over unbounded domains (open decision 69% of the remaining discard is one construct the parser does not implement: quantified invariants #2774);
  • tools/ci/check_specs_still_parse.py --base upstream/master: all 62 "repaired", none stopped parsing;
  • tools/check_specs_generate.py: the 61 now-generating baseline entries are removed (54 ours, 7 fixed earlier on master); it still fails on 11 unbaselined specs/port/tools/* specs that fail the same way on master;
  • tools/check_duplicate_declarations.py: OK after lowering benchmark 13, adamw 11, file/operations 1 to zero;
  • seals: t27c seal --save for every changed spec (117 updated, 6 new); check_seal_currency goes from 542 current / 170 gen_hash=none / 574 stale on master to 661 / 66 / 565, check_seal_coverage from 655 to 626 stale;
  • check_withdrawn_live, check_specs_parse, check_duplicate_agreement, check_now_entry_shape OK; all 123 changed seal JSON files parse.

Unchanged on purpose: specs/test_framework/verilog_bench_harness.t27 and graph_drift_detection.t27 (open PRs #4565, #4536).

Per file (62)
File tests + invariants + benches What changed
bootstrap/src/codegen_python.t27 3 Unchanged in this round. module codegen_python { ... } became module codegen_python;. Its closing brace and two stray unbalanced } were removed. b"t27_" became "t27_". A Rust match node.kind { .. } became if/…
compiler/cli/git.t27 29 Parse blockers: the if-expression payload capture if (skill.?.issue) |id| id else "" -> if (skill.?.issue != null) skill.?.issue.? else ""; 6 x orelse "" -> if (x != null) x.? else ""; the unbalanced paren typo…
compiler/cli/spec.t27 22 (1) validate_tdd_compliance: the heap std.ArrayList (with defer deinit, append ... catch {}, toOwnedSlice() catch ...) is replaced by a new fixed-capacity struct `TddErrors { items: [MAX_TDD_ERRORS][]const u8, le…
compiler/codegen/testgen.t27 17 No code change in this round; the counts below are corrected. The module body is unchanged. Before the fix the file had discarded=8 and swallowed=962, and verilog_hir reported duplicate signals ast/opts/gen, all caused b…
compiler/codegen/verilog/fpga_emission.t27 45 Only the parts that stopped the parse were changed; the other 2300+ lines are untouched. (1) One Rust closure/iterator chain at the old line 2215, cg.output.lines().filter(|l| l.contains("get_ports {clk}")).count(), …
compiler/parser/parser.t27 17 Parse blockers: 2 empty string-list literals &[0][]const u8{} (Program.exports/imports) -> []; 1 Zig multi-object for for (source, 0..) |c, i| -> indexed while. Zig for-captures that parsed but mis-lower: `for (t…
compiler/runtime/commands.t27 47 Reviewer fix, line 35: [_][]u8{...} became const valid_kinds : [4]string = [_]string{...}. string is t27's single type name for []const u8, so the const qualifier is kept. The [4]string annotation is the type Z…
compiler/runtime/runtime.t27 15 Before: parsed, but verilog_hir failed (duplicate signal rt) and every test body was swallowed (bdd-block-fallback). Error unions: runtime_init/alloc_stack/alloc_heap !void -> void, and 2 try f(rt) -> f(rt). t2…
compiler/runtime/validation.t27 40 Parse blockers: 3 Zig \\ multi-line string literals -> single string literals (lines joined with \n, no trailing newline, as Zig does). The bench one had a literal \n inside a Zig multi-line string, where Zig applies…
compiler/skill/registry.t27 21 No code change in this round; exact counts added. (1) .tags = &[_][]const u8{} -> &[_][]u8{}. This was the hard parse error at 200:31. The same change is in the skill_metadata_priority_valid test. (2) All 21 blocks (…
contrib/backend/zig/legacy/main_zig_handwritten.t27 5 This file is quarantined handwritten Zig (tri.zig), so the changes are targeted translations. (1) 8 Zig multiline \\ strings are now ordinary literals with \n escapes. The text is byte-identical. (2) The AST namespace …
specs/account/auth.t27 38 Unchanged in this round. (1) return Ok(()); became return Ok(); (t27 has no unit value; this follows specs/shell/process.t27). (2) assert(result.unwrap() == ()) became result.unwrap();, with a comment. Comparing …
specs/account/schema.t27 12 No change this round. 6 tuple newtypes struct Name(str); became struct Name { value: str, }, with a comment. 8 constructor calls became Name { value = "..." }, and 5 .0 accesses became .value. 4 postfix optiona…
specs/compiler/parser.t27 10 No change in this round. Earlier change: 1 operator, and not self.check_peek(...) (line 1500), became and !self.check_peek(...), because t27 has no not keyword. 45 missing semicolons were added in the Tests section…
specs/config/load.t27 37 No code change in this round; the count is corrected. The file had 26 type references with a hyphenated module path (config-schema::ConfigError, config-schema::AgentConfig) on 14 lines. The type parser stops at the `…
specs/config/migrate.t27 46 Unchanged in this round. Parse error fixed: @ptrFrom([]u8{"version":1}) (x2) now passes the JSON text it stands for, @ptrFrom("{\"version\":1}"). 15 try std.testing.expect(c) became assert(c). 8 empty Zig slice l…
specs/depin/prove.t27 37 Reviewer's minor finding: I agree and fixed it. The parameters are by value now (node_id: [32]u8, w/x: [4]u8, a: [16][16]u8), so the & was removed at the four call sites that still passed addresses. These are `gf…
specs/enrichment/audio_overview.t27 7 (1) Seven body-less declarations pub fn f(...) -> T; (the parser has no extern or prototype form) now have empty bodies { } with a comment saying no body was written in the original. The backends emit their standard …
specs/enrichment/youtube_transcript.t27 20 Reviewer's major finding: I checked it and agree. "youtube.com/" is 12 characters, so @indexOf(..) + 11 points at the '/'. The reference implementations do the same: bootstrap/src/_enrich/mod.rs filters out empty segme…
specs/file/operations.t27 24 Unchanged in this round. It already parsed; the only failure was verilog_hir: 'duplicate port name: delete_result'. The file defined two functions named delete: delete(path, startLine, endLine), a line-range delete who…
specs/igla/coder/benchmark.t27 612 Before the edit the file already parsed. Six targets were OK; verilog_hir FAILED with 'duplicate port name: _result' x24; there were 24 discarded, 438 swallowed and 20 non-ASCII lines. Changes: (1) 13 competitor func…
specs/interop/gf_cross_language.t27 8 module X { ... } -> module X; and the closing brace was dropped. 3 import a::b; / import ffi::gf16::*; -> use ...;. 8 then a and b ... test clauses -> assert a and b ...;, with the same conjunctions kept. S…
specs/math/gf_competitive.t27 11 11 Rust assertion macros translated: assert_eq!(a, b) -> assert(a == b) (3 places) and assert!(x) -> assert(x) (8 places). Nothing else changed. .len() was kept; the compiler lowers it to .len.
specs/ml/optimizer/adamw.t27 82 Unchanged in this round. The file already parsed; only verilog_hir failed, because it holds two copies of the spec (the pre-B1 spec plus the appended Phase B1 block, which declares the same names again). (1) The 17 pre-B…
specs/neural/forward_pass.t27 47 Unchanged in this round. Rust dialect converted to t27, with an ASCII dialect-notes comment. 3 import x; became use x;. 3 pub type X = T; became pub const X = T;. About 30 borrowed parameter types changed: &T i…
specs/nn/phi_rope.t27 5 The whole file was a declarative algorithm phi_rope { module: ..., strand_i: {...}, ..., notes: |..., invariants: [...], tests: [...] } record with no t27 equivalent. It is rewritten as module PhiRope;. module/stran…
specs/nn/sacred_attention.t27 4 Changed in this round, per the major finding. I agreed and checked it: specs/nn/attention.t27 is unmodified at master (checkout mtime). Its line 4 and line 24 write d_k^(-phi^3), but lines 25-26 compute SACRED_SCALE = po…
specs/numeric/formats.t27 36 Unchanged in this round. The file already parsed. verilog_hir failed with duplicate signal names because the braceless benches leaked var result / const test_value to module scope, and .pos was swallowed. All 36 bl…
specs/numeric/goldenfloat_family.t27 43 No source change in this round. Only the report is corrected, as the reviewer asked. From round 1: 8 for (const XS) |x| became for (XS) |x|. 2 Rust Option<GoldenFloatFormat> return types became `?GoldenFloatFor…
specs/physics/formula_discovery.t27 8 Reviewer fix applied (major). The capacity is now const BASIS_MAX_POW: i32 = 6; and const BASIS_CAPACITY: u32 = 2197;, which is (2*6+1)^3. A comment says this matches the default --max-pow 6 of `formula chimera-sea…
specs/physics/p2_brain_physics.t27 12 Unchanged in this round. The 3 body-less declarations (stateInit, next, su2Entropy) got empty bodies { }, each with a comment that the original is signature-only. [LQGCSymbol; 8] became [8]LQGCSymbol. 3 braceless B…
specs/pins/parser.t27 6 This round, comments only. The NOTE at the top now says that test_error_handling and the error_recovery invariant hold, and that ast_consistency holds only vacuously. Its assert runs only when TEST_BASIC_INPUT parses, an…
specs/port/tools/_prereq.t27 4 Unchanged in this round. 10 println!("fmt {}", a, b) became multi-argument @print(.., "\n"), the form the passing port/tools specs use. use std::regex; moved to module level. 0o755 became 493, with a comment; i…
specs/port/tools/builtin_parity_table.t27 7 Unchanged in this round. (1) module specs.port.tools.builtin_parity_table -> module specs::port::tools::builtin_parity_table;. (2) The malformed [&][:]"a", "b"; -> ["a", "b"];. (3) 2 octal literals `stat.mode & 0…
specs/port/tools/check_damage_negatives.t27 7 No change in this round. From round 1: 2 Rust turbofish calls x.parse::<u32>() became x.parse_u32(), which was the parse error. 13 Rust assert!(cond, "msg") became assert(cond, "msg"). Before, they lowered as `as…
specs/port/tools/published_figures.t27 4 Unchanged this round. - row.2.len (the lexer reads 2. as a number) now binds row.2 to row_files first. - The nested closure fn walk is now a top-level walk(dir, paths: *[]string, lines: *[]string). - The raw …
specs/port/tools/wp18_gate_selfconsistent_selftest.t27 8 Unchanged in this round. (1) 5 import std.x.y; -> use std::x::y;. (2) JsonValue{ .Null = {} } -> JsonValue.Null. (3) The no-op _ = struct{}; in the documented stub _drop_stale_bytecode -> return;. (4) 2 Zig i…
specs/portable/relay_observer.t27 39 Unchanged this round. Syntax fixes only: - 3 ; header comment markers became //. - 2 }; after a struct became }. - A duplicated return type is fixed. - A block-valued return if became an if/else chain. - 8 brac…
specs/provider/adapters.t27 39 Two if-expressions (in adapter_config_create and get_endpoint) had block branches ending in X;. The parser only takes { X } as a branch value, so the 4 trailing semicolons inside those branches were dropped. Nothing …
specs/provider/schema.t27 38 Unchanged this round. The block-valued if (...) { "a"; } else { "b"; } became the if expression if (...) "a" else "b". 4 empty typed slices (&[_]Tool{}, &[_]ToolCall{}, 2x &[_]Message{}) became []. They sit i…
specs/runtime/execute.t27 49 No change this round. There are 4 fixes. (1) The fn-typed parameter resolve_fn: fn(TaskResult) void now uses the alias pub const ResolveFn = fn(TaskResult) void;, the same pattern as router.t27's Handler. (2) The 3 a…
specs/sandbox/health.t27 1 Unchanged in this round. pub trait HealthPoller { fn poll_sessions(&self) -> bool; } became pub const HealthPoller = struct { poll_sessions : fn(*HealthPoller) bool, };, following specs/server/sse.t27, and the doc co…
specs/sandbox/https_enforce.t27 10 The whole file was Rust, so it is a full rewrite with the same header, doc comments and section comments. Type changes: &[u8] -> []const u8; Option<&[u8]> -> ?[]const u8; b".." literals -> ".."; [&[u8;9];3] -> …
specs/sandbox/modules.t27 1 Reviewer fix: removed the bare use session_timeout; I added in round 1. It named no existing module, since the module is called sandbox.session_timeout, and it duplicated the existing use sandbox.session_timeout;. …
specs/sandbox/orphan_detection.t27 6 Unchanged in this round. It follows the conventions of the already-translated siblings https_enforce.t27 and health.t27. import x; became use x; (2). [u8; N] became [N]u8. Option<[u8;64]> became ?[64]u8. The st…
specs/sandbox/session_timeout.t27 6 Round 2, comments only; the code and assertions are unchanged. The note above the tests now states plainly that the created_at values are 1970 (2_000_000_000 ms = 1970-01-24, 4_000_000_000 ms = 1970-02-16). Against any c…
specs/server/provider.t27 10 The file was written without semicolons, and a bare expression statement (assert(...) in the tests) must end with ;. Semicolons were added to about 83 statements in fns and tests. Struct-literal returns now end with …
specs/server/router.t27 40 Round 2, reviewer finding accepted: route_match's for (router.routes) |route| is now for (0..router.routes.len) |ri| { const route = router.routes[ri]; ... }. The former @ptrFrom(*route) is now `best_match = &r…
specs/server/vm.t27 32 The parser has no switch statement with block-bodied arms (.x => { ... },); parse_switch_expr accepts only expression arms. Two such switches were rewritten as equivalent if/else-if chains: vm_step (19 arms, same order…
specs/shell/process.t27 20 Reviewer fix applied: specs/shell/schema.t27 now declares env: ?[]EnvVar, so the helper is now fn env_lookup(env: ?[]EnvVar, key: str) -> ?str. It starts with if (env == null) { return null; } and then loops over t…
specs/shell/schema.t27 24 (1) The map literal { "PATH": ..., "HOME": ... } that broke the parse became a [2]EnvVar array of name/value pairs. (2) The struct field type env: [str: str]? became env: ?[]EnvVar to match; the original type is …
specs/sync/index.t27 44 No change in this round. From round 1: 1 multi-object loop for (delta.operations, 0..) |op| became for (delta.operations) |op|, which was the parse error. The garbled query.limit.? MAX_INDEX_ENTRIES became `if …
specs/ternary/hybrid_arithmetic.t27 50 Reviewer fix, line 320: createUnpacked([_]i8{}, 0) became createUnpacked([]i8{}, 0), and the comment now says that t27c lowers an empty [_]T{} to a one-element { _ }. Unchanged from round 1: 2 }; after struct b…
specs/ternary/hybrid_bigint.t27 51 The whole file was Rust; this round did not change it. 3 import a::b; became use a::b;, keeping :: in the paths. 1 pub type Vec32 = ... became pub const. pub struct HybridBigInt, including its `Option<[MAX_TR…
specs/test_framework/core.t27 4 Reviewer fixes applied: (1) REPORT_CAP went from 8192 to 32768. A comment gives the worst case: a TAP report of MAX_RESULTS failing results with full-length name and message is 6 + 64 * 284 = 18182 bytes, so a full Resul…
specs/test_framework/property_test_template.t27 10 Round 2, comments only; the code is unchanged. (a) A DEPENDENCY paragraph in the header translation notes, plus a pointer at the import, says that Text, text_from, text_append_str, text_append_u32, text_append_text and f…
specs/test_framework/runner.t27 5 The original was pure Rust; it is translated throughout. This round the file was reconciled with the core.t27 now in the working tree (sha256 prefix 2c2d722efca0235f; that file passes check.mjs). - impl methods became fr…
specs/tools/registry.t27 33 Only the constructs that broke the parse were changed. (1) Empty map literal properties = {} became properties = [] with an inline comment (10 places, in non-comment code only). (2) The typo required: [] (a colon i…
specs/tools/schema.t27 27 Changed in this round, per the review. I agreed with the finding and checked it: ls specs/session fails, and SessionID/MessageID appear only in specs/tools/schema.t27 and specs/tools/registry.t27. (a) The external Sess…
specs/tri/collections/maybe.t27 14 The parameter grammar has no inline fn type, so 2 function-typed parameters use the aliases pub const MaybeBindFn = fn(T) Maybe(T); and pub const MaybeMapFn = fn(T) T;. 5 inline closures in tests became 4 named helpe…
specs/tri/graph/graph_bfs.t27 14 Reviewer fix: restored the original declared type, so the line is var adj_array : *[]usize = allocator.alloc([]usize, vertex_count);. The comment now says the annotation is kept as the original wrote it. I also withdra…
specs/tri/search/aho_corasick.t27 10 The only failure was Verilog: the local var pattern_array : [256][]const u8 (a 2-D array of slices, W469 not implemented). The comma-split pattern list is now stored as the source string plus start/end offsets. In ACAu…
Approximations and removals to check (169)
  • bootstrap/src/codegen_python.t27 (removed): Three closing braces: the old module block's own } and two stray unbalanced }. These are structural only; no declarations or tests were removed.
  • compiler/cli/git.t27: The orelse and if (opt) /v/ desugars are written literally. For the fields that Skill declares non-optional (issue, id, kind, artifacts), the original code was already type-inconsistent, so the Zig backend lowers != null on them as a string compare. The desugar is a faithful syntax translation; it does not fix the original's types.
  • compiler/cli/git.t27: Bench target: metadata lines are kept as comments.
  • compiler/cli/git.t27: The ten _ = git_commit; assert true; tests and the assert true invariants were already placeholders in the original. They were translated as they are, not strengthened. compiler/ is not covered by the assertionless-tests gate.
  • compiler/cli/spec.t27: validate_tdd_compliance returns a fixed-capacity TddErrors (items + len) instead of a heap-owned [][]const u8. Callers still read .len. The capacity of 1 matches the single violation the function can raise.
  • compiler/cli/spec.t27: std.mem.indexOf(u8, t, s) != null in 3 tests and 1 invariant became the explicit-loop helper contains(t, s).
  • compiler/cli/spec.t27: Bench target: metadata is kept as comments, because braced benches have no slot for it.
  • compiler/cli/spec.t27 (removed): defer errors.deinit(); in validate_tdd_compliance: it freed the heap ArrayList, and nothing is allocated any more. A comment in the function records this.
  • compiler/cli/spec.t27 (removed): The spec_commands. qualifier on references inside the tests and invariants (the same declarations, referenced directly).
  • compiler/codegen/testgen.t27: The invariant testgen_backend_switch uses [_][]u8{...} instead of [_][]const u8{...}, because the parser rejects const in an array-literal element type. The values are the same.
  • compiler/codegen/testgen.t27: This predates my edit: all 24 functions are methods inside pub const TestGen = struct {...} / StringBuilder. The compiler skips struct methods by design (W577, parse_struct_body) and does not count them as discarded or swallowed. So no generator logic reaches any backend, and the tests call methods that are never emitted. Moving them out as free functions would be a large rewrite, and some bodies are not valid in any dialect (for example if (x) /y/ and cond {). That is why the status is warn.
  • compiler/codegen/verilog/fpga_emission.t27: Closure lines().filter(/l/ ...).count() replaced with explicit-loop helpers count_lines_containing/range_contains. The count is the same as Rust's lines() for any needle that has no newline or CR in it.
  • compiler/codegen/verilog/fpga_emission.t27: The test reads the output bytes through cg.output.to_string(). That is the accessor the StringBuilder in the sibling compiler/codegen/verilog/codegen.t27 defines. This file never defines StringBuilder itself; its other tests call Rust-style .len() / .contains() on it.
  • compiler/codegen/verilog/fpga_emission.t27: The three bench bodies were metadata only. The bodies I added run exactly the operation each measure: line names, and the target lines are kept as comments. This is the one place where statements were added rather than translated.
  • compiler/parser/parser.t27: Bench target: > 10K lines/sec / target: < 1000 ns/line metadata lines are now comments; they were never executable.
  • compiler/parser/parser.t27: Invariant parser_tdd_contract_enforced was comments only in the original. It is kept as a brace block with those comments and no statements. Nothing was invented.
  • compiler/parser/parser.t27: Invariant parser_symbol_table_consistent has no assertion in the original either. Its // assert ... is still a comment.
  • compiler/parser/parser.t27: Observation, not changed: the Zig backend drops _ = parser.parse_program(); in fn parse (the local var parser shares its name with the module). The C backend and the AST keep it, so this is a codegen quirk.
  • compiler/runtime/commands.t27: Removed the 3 catch "" fallbacks because t27 has no error unions. They could never fire: a usize is at most 20 digits, which fits the 64-byte buffer, and "skill-" plus a usize is at most 26 bytes, which fits the 32-byte buffer.
  • compiler/runtime/commands.t27: Each of the 4 benches (spec_create_latency, spec_validate_latency, gen_spec_latency, skill_begin_latency) had its target: < Nms goal demoted to a comment such as // target: < 10ms. t27 has no syntax for a timing goal, so nothing checks it now. The measured call remains as the bench statement.
  • compiler/runtime/commands.t27: valid_kinds lowers to Verilog as 0 /* TODO: array literal [_]string not yet lowered to Verilog */. The Verilog backend cannot hold string arrays. It produced the same TODO for the round-1 [_][]u8 spelling, so this is not a regression.
  • compiler/runtime/commands.t27: In C, the empty tag list lowers to (uint8_t*[]){ 0 }, a compound literal with one NULL element, instead of a const char* array of length 0. That is how the C backend spells []string{}. It has the same shape as hybrid_arithmetic's []i8{} -> (int8_t[]){ 0 } with count 0.
  • compiler/runtime/runtime.t27: The error-union removal is behaviour-preserving: neither allocator has an error path ("assume allocation succeeds"). The function signatures no longer advertise possible failure. A comment explains this.
  • compiler/runtime/runtime.t27: In invariant thread_count_limit, const MAX_THREADS = triruntime.MAX_THREADS; became const max_threads = MAX_THREADS;. The local was renamed so that, without the module prefix, it does not shadow the constant it reads.
  • compiler/runtime/runtime.t27: Bench target: metadata lines are kept as comments.
  • compiler/runtime/validation.t27: Bench target: metadata lines are kept as comments. The benches' own elapsed-time asserts are kept.
  • compiler/runtime/validation.t27: Not changed: validate_generated_header still calls .len and indexes the result of std.mem.splitScalar, which is an iterator. That is a bug in the original, not a syntax issue.
  • compiler/skill/registry.t27: The empty tag list is &[_][]u8{} instead of &[_][]const u8{}. The value is the same (empty).
  • contrib/backend/zig/legacy/main_zig_handwritten.t27: Error-union success is tested with Zig's std.meta.isError instead of if (r) /_/ ... else /_/. Both original captures were _, so no value is lost. runGitDirect names the error with @errorName(exec_result). Real Zig needs the bare error, which only a capture or catch can extract, and t27 has neither. The comment is marked APPROXIMATION.
  • contrib/backend/zig/legacy/main_zig_handwritten.t27: FileNotFound handling compares the error union with == error.FileNotFound and then uses try. zig 0.15.2 accepts this.
  • contrib/backend/zig/legacy/main_zig_handwritten.t27: gitCommit keeps the original's literal Zig precedence: --all drops -m. The probable intent (both together) is left as a TODO rather than changed.
  • contrib/backend/zig/legacy/main_zig_handwritten.t27: []const u8 is written string inside ArrayList(...), array literals and []const string parameters. It is the same type in t27. But the Zig backend maps only a bare string / ?string to []const u8, so the generated Zig carries an undeclared string at those sites. [][]const u8 would lower cleanly, but it drops the outer const, and Zig would then reject passing argsAlloc's [][:0]u8 slices, so it was not used.
  • contrib/backend/zig/legacy/main_zig_handwritten.t27: The comptime qualifier was removed from printErrorFmt's fmt parameter (t27 has no comptime parameters).
  • contrib/backend/zig/legacy/main_zig_handwritten.t27: append(...) catch {} became _ = append(...).
  • contrib/backend/zig/legacy/main_zig_handwritten.t27: The GPA type is bound to a local const before it is initialized. The value is the same as the original.
  • contrib/backend/zig/legacy/main_zig_handwritten.t27: Known remaining issues, not fixed. All 24 defers are kept in the AST but no backend lowers them: Zig emits // NOT LOWERED (T43), C emits /* unsupported */, and Rust emits ();. The 14 printError arity mismatches are carried over from the original. Generated-Zig problems common to every spec: a duplicate const std import, error.X escaped as @"error".X, and !T return types dropped by the parser. The lexer has no \r escape (3 unchanged literals).
  • specs/account/auth.t27: The heterogeneous map [str: any] is modelled as an array of ConfigEntry. Each entry has a kind tag and one value field per kind (str, bool, i64, [str]); the unused fields hold zero values.
  • specs/account/auth.t27: AccountID("...") and .0 tuple-struct usage were kept to match the current specs/account/schema.t27. That file is not in this batch, still fails to parse, and declares struct AccountID(str);. If its translation turns tuple structs into { value }, auth.t27 must follow.
  • specs/account/auth.t27: Kept as written (not syntax problems): poll_function and poll_success/poll_expired build Login with fields that schema's Login does not declare (device_code, verification_uri, expires_at, poll_interval), and timestamp() is undefined.
  • specs/enrichment/audio_overview.t27: The 7 HTTP, file and orchestrator fns were declarations only (no body) in the original. They are left unimplemented (empty body plus comment), not given invented return values.
  • specs/enrichment/audio_overview.t27: invariant lang_code_valid: the forall over all strings is checked only over the finite set {"ru","en","fr","english"} (the codes the tests name), with a for i in 0..4 loop.
  • specs/enrichment/audio_overview.t27: invariant audio_files_have_duration: the forall over AudioFile is checked on one sample record. AudioFile has no content field (the original read file.content), so the content length is a separate local. With the sample values the check is true by construction.
  • specs/enrichment/audio_overview.t27: bench http_request_latency: the anonymous argument { language_code: "en" } is written as a full AudioOverviewRequest (notebook_id "nb123", language_code Lang.En, episode_focus "", source_ids null).
  • specs/enrichment/audio_overview.t27: Existing gap left unchanged: the tests and invariant call @langToCode, @langFromCode, @langFilename, @concat, @contains, which are not real t27 builtins. They parse and are emitted verbatim; I did not invent definitions for them.
  • specs/file/operations.t27: The 3-argument delete(path, startLine, endLine) is now delete_lines, because t27 cannot overload a name. The 1-argument delete(path) keeps the original name because delete_dir calls it. The renamed function's body was already empty in the original.
  • specs/igla/coder/benchmark.t27: None were sampled or approximated. Each of the 6 rewritten quantifiers is exhaustive: one had no binder; one reads only a bool field and both values are checked; four have a len()==0 premise that only the empty slice satisfies.
  • specs/igla/coder/benchmark.t27: I did NOT lower the 18 remaining quantified invariants, which are all of the discarded=18 and swallowed=315 (every swallowed token is bdd-block-fallback inside them). All quantify over unbounded or over-ceiling domains ([]BenchmarkResult, BenchmarkReport/CompetitorScore with f32 fields, f32, u32). compiler.rs and docs/now record that what forall means in codegen is the open language decision 69% of the remaining discard is one construct the parser does not implement: quantified invariants #2774, and turning them into finite samples would invent that meaning. Several are also false or ill-formed as written, so an honest sample would be a failing check and a passing one would have to be cherr
  • specs/igla/coder/benchmark.t27 (removed): One stray closing brace line (original line 4593) that closed no block. The parser was swallowing it as 'stray-brace'. A comment now marks the spot.
  • specs/igla/coder/benchmark.t27 (removed): Syntax only, no content lost: the bare 'forall' keyword line (no binder) in benchmark_trinity_self_train_estimate_bounded; the binder lines of the 5 other exactly rewritten quantifiers, whose original text is kept in 'Was:' comments; and the inline ':' after 'invariant trinity_phi_identity'.
  • specs/interop/gf_cross_language.t27: Glob imports ffi::gf16::* / ffi::gf32::* became use ffi::gf16; / use ffi::gf32; because t27 use has no glob form. The gf16_/gf32_ functions are still called unqualified, as before. The ffi modules do not exist in this checkout; unresolved use is accepted, like in many passing specs.
  • specs/ml/optimizer/adamw.t27: all_pairs(a, b, fn(a, b) b >= a) is read as an element-wise pairing (index i of both arrays) and written as an explicit loop. all_pairs is an undefined helper in the original, so the pairing is an interpretation.
  • specs/ml/optimizer/adamw.t27: get_effective_betas keeps the original TODO placeholder return DEFAULT_BETA1; (a single value for a triple return type). It was never implemented.
  • specs/ml/optimizer/adamw.t27: The pre-B1 duplicates were renamed rather than removed. Reviewers may prefer to retire the stale v1 copy, but that is outside a syntax translation.
  • specs/neural/forward_pass.t27: Vec/Vec are slices []T grown with .push, the same idiom specs/vsa/ops.t27 uses. t27 has no heap vector.
  • specs/neural/forward_pass.t27: Immutable Rust borrows (&T) are passed by value, because t27 has no reference types. None of those parameters is written to, so behaviour is unchanged.
  • specs/neural/forward_pass.t27: r as Trit with r in {-1,0,+1} became @as(Trit, @enumFromInt(r)), the corpus idiom. The parser accepts only scalar cast targets.
  • specs/nn/phi_rope.t27: Float[seq, dim] tensors are passed as flat row-major slices of length seq*dim, with seq as a parameter. t27 has no 2-D dynamic tensor type.
  • specs/nn/phi_rope.t27: backends: [rust, zig, c, verilog] is kept as the single string "rust,zig,c,verilog".
  • specs/nn/phi_rope.t27: The invariant bodies are an interpretation, because the original only names them. orthogonality_preserved asserts that each rotated pair keeps its squared length (tolerance 1e-6, on the sample x=[1,2,3,4], position 7). phi_decay_monotone asserts theta(i+1) < theta(i) for dim=81.
  • specs/nn/phi_rope.t27: The test pos=0 -> x_rotated == x gives no x, so the sample vector [1,2,3,4] (dim 4) is used.
  • specs/nn/phi_rope.t27: The dim=4 table [1.0, 0.886, 0.618, 0.486] is kept verbatim and compared with tolerance 0.001. By the spec's own formula, theta[1] = PHI^(-1/2) = 0.786, not 0.886. This assertion therefore fails if the test is ever run. It is flagged in a NOTE comment for the spec owner rather than silently corrected.
  • specs/nn/sacred_attention.t27: sacred_scale() was never defined in the original. It is now defined as head_dim^(-(1/PHI^3)) = 81^(-0.236068), about 0.3544, which is how the repo's unmodified specs/nn/attention.t27 computes the same 'd_k^(-phi^3)' notation (SACRED_SCALE, test attn_sacred_scaling_constant). The literal reading -(PHI^3) would give about 8.2e-9. A NOTE (review) comment in the file records both values. PHI = 1.6180339887498948.
  • specs/nn/sacred_attention.t27: The invariants scale_in_0_1 and n_heads_times_head_dim_eq_embed_dim were only named in the original. Each body asserts exactly what its name says.
  • specs/nn/sacred_attention.t27: The notes forward pass (Q,K,V = x@W..., softmax, @wo) is kept only as a comment. The record gives no weight matrices and no head split, so writing it as a function would mean inventing them.
  • specs/nn/sacred_attention.t27: backends: [rust, zig, c, verilog] became the string "rust,zig,c,verilog".
  • specs/numeric/formats.t27: Corrected count: the 6 function bodies (gf16_to_f32, f32_to_gf16, f32_to_ternary, ternary_to_f32, format_bytes, quantize_value) were already empty { } in the original and stay empty. The Zig backend emits @CompileError("not yet implemented") for them. The earlier report wrongly said 7.
  • specs/numeric/formats.t27: std.math.inf/nan(f32) and @setEvalBranchQuota were kept; the passing core specs gf16.t27 and tf3.t27 use the same spellings.
  • specs/numeric/goldenfloat_family.t27: Each of the 5 benches had a prose line measure: nanoseconds to f(x) that did nothing: it lowered to a NOT LOWERED empty statement. The call it names is now an executable bench statement _ = f(x);, and the prose stays as a comment.
  • specs/numeric/goldenfloat_family.t27: Each of the 5 benches had its target: < Nns goal (100ns and similar) demoted to a comment. t27 has no syntax for a timing goal, so nothing checks it now.
  • specs/physics/formula_discovery.t27: The label format!("phi^{}pi^{}e^{}", i, j, k) is stored as its three exponents (i, j, k), which fully determine it. t27 has no string formatting.
  • specs/physics/formula_discovery.t27: The heap Vec is now a fixed array of BASIS_CAPACITY = 2197 entries, enough for max_pow <= 6, the CLI default. Only a max_pow above 6 would lose patterns past capacity, and a comment in the code says so.
  • specs/physics/p2_brain_physics.t27: The state literals listed 11, 10 or 9 zeros for the 8-element symbols field; all now use 8 zeros (commented).
  • specs/physics/p2_brain_physics.t27: next(state, 0, 0, 0b00000000u8) passed 4 arguments to a 3-parameter function; the surplus zero was dropped (commented).
  • specs/physics/p2_brain_physics.t27: The function bodies stay empty because the original never wrote them; the Zig backend emits @CompileError("not yet implemented").
  • specs/physics/p2_brain_physics.t27: Invariant expressions were kept verbatim even where semantically dubious (f64 compared against gf16 from_f64(3.0), LQGCSymbol::NUM_VALUES on a u8 alias, Simulation.samples read off a type).
  • specs/pins/parser.t27: Kept on purpose, documented in the NOTE: the original logic cannot satisfy its own tests. scan_token calls advance() before number()/identifier(), so the first character is lost. parse_module consumes the signal/constraint keyword, and then parse_signal_decl/parse_constraint expect it again. parse_io_standard reads the name with expect_identifier while the test passes a string. 12_000_000 is not one number. So test_basic_parsing, test_io_standard_parsing and the parser_robustness invariant would fail if executed. test_error_handling and error_recovery hold. ast_consistency is vacuous (its as
  • specs/pins/parser.t27: self.consume_token(PinToken::RIGHT_BRACE)? does not type-check in Rust (consume_token takes no argument and returns Option). It is kept as a plain consume, with the argument and ? dropped.
  • specs/pins/parser.t27: lexer.tokenize()? inside a fn returning ParseError has no LexError-to-ParseError conversion in the original. A lex error is reported as a ParseError named after its LexErrorKind, at the lexer's position.
  • specs/pins/parser.t27: this.error(...) (a typo) is read as the parser itself. error() stores the error in p.err and returns false.
  • specs/pins/parser.t27: String payloads and AST strings are slices borrowed from the input, not owned copies. Input is read byte by byte (ASCII) instead of chars().nth.
  • specs/pins/parser.t27: Vec growth is bounded by MAX_TOKENS/MAX_SIGNALS/MAX_CONSTRAINTS. ParseError messages are capped at MSG_CAP=64 bytes.
  • specs/pins/parser.t27: {:?} of a token kind is its variant name via pin_token_name. number() accumulates digits directly; no digits or a value above the u32 range gives InvalidNumber, the same failure parse:: gave.
  • specs/pins/parser.t27: The prose invariants became concrete checks on the test inputs (details in the in-file comments). "valid references" defines no checkable rule and stays prose.
  • specs/pins/parser.t27: parser_last_string_value keeps the original placeholder body (returns "").
  • specs/pins/parser.t27 (removed): The record wrappers test: {...}, invariant: {...} and documentation: {...} were restructured into t27 tests, invariants and DOC_* constants. Every field's content is kept (descriptions and checks as comments, values as constants and asserts).
  • specs/port/tools/_prereq.t27: println! formatting has no t27 form. Each line prints the same pieces with @print and an explicit newline.
  • specs/port/tools/builtin_parity_table.t27: Octal 0o100 is written as hex 0x40. The value is the same.
  • specs/port/tools/published_figures.t27: walk receives its accumulators by pointer instead of capturing them.
  • specs/port/tools/published_figures.t27: FIGURES is referenced but never defined in the port. It exists only in tools/published_figures.py and was not added. The original's placeholder test bodies (true;) in code_lines/derive/main are kept as they were.
  • specs/port/tools/wp18_gate_selfconsistent_selftest.t27: JsonValue{ .Null = {} } is written as JsonValue.Null. This is the same payload-less union value.
  • specs/port/tools/wp18_gate_selfconsistent_selftest.t27: _ = struct{}; is written as return;. Both are no-ops in a body the original already documents as a stub.
  • specs/portable/relay_observer.t27: parse_websocket_message's copy loop into a storage-less buffer became const payload: []u8 = data[1..data.len];, which holds the same bytes. There is no heap for a real copy.
  • specs/runtime/execute.t27: Two identical no-op resolve literals now share one named fn, noop_resolve.
  • specs/sandbox/health.t27: t27 has no trait. The interface is a struct with a function-typed member (a vtable), and &self is an explicit *HealthPoller parameter. No method body was invented; the trait had none.
  • specs/sandbox/https_enforce.t27: Heap Vec result replaced by a caller-supplied fixed buffer (new const MAX_URL_LEN = 2048) and a returned length. Bytes past the buffer are not written; that bound replaces Vec growth.
  • specs/sandbox/https_enforce.t27: HttpsEnforcer.enforce returned Option<Vec>. It now returns ?usize, the length of the HTTPS URL written into a caller buffer (a new []u8 parameter).
  • specs/sandbox/https_enforce.t27: Trait -> struct with a function-typed field; &self becomes an explicit *HttpsEnforcer parameter.
  • specs/sandbox/https_enforce.t27: SEMANTIC FIX, flagged: the original should_redirect arm Some(proto) => proto == HTTPS_SCHEME would redirect exactly the https requests. That contradicts its own inline comment, doc rule 2, and the tests https_not_redirected / http_redirected_in_prod. It was translated as !bytes_eq(proto, HTTPS_SCHEME) to match them, and a NOTE comment in the code records this.
  • specs/sandbox/https_enforce.t27: LOCAL_HOSTNAMES was typed [&[u8; 9]; 3] although two of its entries are not 9 bytes; it is typed [3][]const u8 now, with a comment.
  • specs/sandbox/https_enforce.t27 (removed): use sandbox.https_enforce; inside the .test wrapper: a self-import that has no meaning once the tests are in the same module (noted in a comment).
  • specs/sandbox/https_enforce.t27 (removed): The .test { } wrapper itself: its contents (make_ctx and all 10 tests) were kept.
  • specs/sandbox/modules.t27: The re-export meaning of pub use session_timeout; is lost. t27 has no construct for it, and the round-1 plain use did not express it either: the Zig output only emitted a 'no references' note.
  • specs/sandbox/modules.t27: OPEN ITEM for the owner: the added invariant is vacuous (assert true), because this registry holds only imports and computes nothing. The repo treats cannot-fail test bodies as debt (tools/check_assertionless_spec_tests.py and its baseline). That script matches only test declarations, so it does not count this invariant, which has the same cannot-fail shape. Someone must decide whether a real check belongs here, or whether this spec should be exempt from L4.
  • specs/sandbox/modules.t27 (removed): The directive pub use session_timeout; is kept only as a comment. t27 has no re-export, and the module is already imported by use sandbox.session_timeout;. No function, type, constant or test was removed.
  • specs/sandbox/orphan_detection.t27: All 12 test timestamps were divided by 1000, with a NOTE in the file. The original values are microsecond-scale, while Timestamp.ms and current_time_ms are milliseconds. Read literally, the grace-period test's session is 10,000 minutes old, which contradicts its expected=false, its description and its "10 minutes ago" comment. After scaling, every test's inputs match its comments and its expected value. The reviewer checked the arithmetic (960,000 ms = 16 min, 600,000 ms = 10 min, threshold 900,000 ms). Maintainers should confirm the unit reading; the alternative is to keep the literal values
  • specs/sandbox/orphan_detection.t27: Short byte lists for the [32]u8/[64]u8 fields are zero-padded by bytes32/bytes64. The original literals would not type-check in Rust.
  • specs/sandbox/orphan_detection.t27: !id.is_empty() on a fixed [u8;64] is always true in Rust and is kept as id.len != 0, so any Some railway_id means not orphaned, exactly as in the original.
  • specs/sandbox/orphan_detection.t27: detect_orphaned_sessions writes at most out.len IDs (the buffer bound replaces Vec growth).
  • specs/sandbox/orphan_detection.t27: The enum's string values are no longer the variants' values; they come from session_status_str.
  • specs/sandbox/orphan_detection.t27 (removed): The generic pub enum Option<T> { Some(T), None } declaration was replaced by t27's built-in optional ?T, which is that type (t27 has no generic enums). Its doc comment is kept, with an explanatory comment in its place.
  • specs/sandbox/orphan_detection.t27 (removed): The self-import use sandbox.orphan_detection; inside the .test { } wrapper was dropped, because the tests now live in the module itself.
  • specs/sandbox/session_timeout.t27: The interface field takes Session by value instead of &Session: fn-typed field types are emitted as raw text, so *const Session would become *constSession.
  • specs/sandbox/session_timeout.t27: The enum's string values are expressed through session_status_str().
  • specs/sandbox/session_timeout.t27 (removed): The .test {} wrapper and its self-import use sandbox.session_timeout; were removed because the tests now live in the module itself. All 6 tests are kept. session_within_max_duration fails against a real clock, as the file now states; it was not weakened.
  • specs/shell/process.t27: t27 has no map literal and no map index operator. The env map in test process_options_with_env is now an array of EnvVar key/value pairs (the type specs/shell/schema.t27 now uses for ProcessOptions.env), and the optional lookup env?.[key] is now env_lookup(env, key). The helper takes ?[]EnvVar and returns null when env is null, so the ?. short-circuit is modelled. The assertion is unchanged.
  • specs/shell/schema.t27: t27 has no map type or map literal. ProcessOptions.env ([str: str]?) is carried as ?[]EnvVar (name/value pairs, using the spec's own EnvVar struct). The test's map literal is a 2-element EnvVar array.
  • specs/shell/schema.t27: Existing bug left unchanged: is_blacklisted compares against ShellType.Nu, but ShellType has no Nu member. Codegen accepts it; adding an enum member would change the spec's behaviour, so I did not.
  • specs/sync/index.t27: I read query.limit.? MAX_INDEX_ENTRIES as a garbled Zig query.limit orelse MAX_INDEX_ENTRIES and wrote it as an explicit null test and unwrap. That is an interpretation of broken source.
  • specs/sync/index.t27: 5 lines I did not edit use &[_]T{} (lines 143, 144, 289, 321, 564), and t27c lowers them to the invalid Zig &.{ _ }. This is the compiler's empty-[_]T{} defect that the reviewer found. I left these lines as written because the original parsed and the alternative spellings mis-lower too: in a typed var, []T{} becomes Zig .{}, and &.{} becomes C &{ }. It needs a compiler fix.
  • specs/ternary/hybrid_arithmetic.t27: The 11 functions had no bodies in the original and now have empty bodies. The Zig backend emits @compileError("not yet implemented") for them. No behaviour was invented.
  • specs/ternary/hybrid_arithmetic.t27: [_]i8{x} ** n lowers correctly to Zig .{x} ** n. In the 2 benches that pass such an array, the C backend emits a placeholder: /* repeat: { 1 } ** 32 */ {0}. That is a gap in the C backend, not in this source.
  • specs/ternary/hybrid_bigint.t27: The impl methods are now free functions (hybrid_zero, hybrid_add, ...), so the call syntax changed. They are not kept as methods inside the struct because t27c parses fns declared in a struct {} body and then silently drops them, with no discarded or swallowed count. specs/ternary/bigint.t27 has this problem today.
  • specs/ternary/hybrid_bigint.t27: add_simd's 2-D carry table [[Trit; SIMD_WIDTH]; SIMD_CHUNKS + 1] is stored flat, row-major, in [CARRY_SLOTS]Trit, where CARRY_SLOTS = (SIMD_CHUNKS + 1) * SIMD_WIDTH, and it is indexed as carries[c * SIMD_WIDTH + i]. gen-verilog rejects 2-D Trit arrays (W469). The values are identical.
  • specs/ternary/hybrid_bigint.t27: 3u32.pow(j as u32) is now pow3_u32(j as u32), an exact loop helper.
  • specs/ternary/hybrid_bigint.t27: The tuple array in the add_simd_matches_scalar test is now two parallel arrays, cases_a and cases_b.
  • specs/ternary/hybrid_bigint.t27: Plain-let bindings that the original then passed to &mut self methods are now var: neg1 in the negate tests, and zero in 'zero creates empty value'.
  • specs/test_framework/core.t27: Generics and function-typed parameters. for_all, metamorphic and differential cannot take functions in t27. The caller now applies the functions and passes the evaluated samples: PropertySamples, MetamorphicCase and DifferentialCase. T and R are fixed to f64. Counting, last-failure tracking, verdicts, tolerance tiers, delta rules, names and messages stay inside the functions.
  • specs/test_framework/core.t27: any fields (input, expected, actual) are f64. Every producer in the file passes a number.
  • specs/test_framework/core.t27: Fixed capacities where Rust would grow the collection: at most 64 cases or iterations per call (MAX_CASES) and 64 results per ResultList. Text past 128 bytes (names and messages) or 32768 bytes (reports; this covers the worst case of 18182) is dropped. for_all evaluates min(iterations, 64) samples, and when it caps it says " (capped at 64)" in its name and message.
  • specs/test_framework/core.t27: Float formatting: f64_to_text writes the integer part (clamped to u32), up to 6 fraction digits with trailing zeros trimmed, and inf, -inf or NaN. Rust would print the shortest round-trip decimal. {:?} of x and of last_failure uses the same formatter; last_failure is written as Some(v) or None.
  • specs/test_framework/core.t27: f64::INFINITY is F64_MAX * 2.0, which overflows to +inf under IEEE 754. f64::INF(a) is read as 'a is infinite' (f64_is_infinite: /x/ > F64_MAX).
  • specs/test_framework/core.t27: assert!(cond, "Test suite had {} failures", n) became assert(failed_count == 0). t27 assert has no message argument; the generated failure report still prints failed_count.
  • specs/test_framework/core.t27: The quantified invariants are now checked on concrete inputs. gate_pipeline_sequential is exhaustive over all 64 combinations. phi_squared_identity is checked at 1.618033988749895, where the residual is 0.0. gf16_roundtrip_preservation is checked only at 0.0, because the original GF16 encode/decode are placeholders (they return 0 and 0.0).
  • specs/test_framework/core.t27: println! with a format became two prints: print("TAP Output:") and then the report bytes. suite_results.clone() became a by-value copy.
  • specs/test_framework/core.t27: The original bodies of test_gf4_exhaustive, gf16_encode_f32 and gf16_decode_to_f32 were already placeholders. They are kept minimal: an empty list, 0 and 0.0.
  • specs/test_framework/property_test_template.t27: Cross-file dependency: the format! stand-ins use Text and the text_* / f64_to_text helpers from the campaign's rewrite of specs/test_framework/core.t27 (working-copy lines 63-169, another batch). They do not exist at master a103752. Ship this file in the same PR as that core.t27 rewrite, or after it. t27c does not resolve imports, so the checks pass either way. I kept the import rather than duplicating a local Text: a second Text type would not match core's TestResult, whose name and message are Text.
  • specs/test_framework/property_test_template.t27: There are no generics. for_all keeps its declared pair signature, and two specialised copies, for_all_triple and for_all_gf16, have identical bodies for the triple and single-GF16 call sites.
  • specs/test_framework/property_test_template.t27: metamorphic is specialised to T=GF16, U=f32, V=GF16, and differential to T=GF16Pair, U=f64. The <F,G,H> lists and where-clauses are kept only as comments. metamorphic's approx_equal(g_y, h_x, tol) call passes GF16 values to f64 params, exactly as the original did.
  • specs/test_framework/property_test_template.t27: Tests for_all_passes/fails: /_/ 0 is PairGenerator.zero, a GF16 +0.0 pair, and /_/ true and /_/ false are PairProperty.always_true and always_false.
  • specs/test_framework/property_test_template.t27: Test metamorphic_property_passes_when_relations_hold uses INVENTED stand-ins, and the file now says so: the constant zero generator, f = to_f32, g = to_gf16, and h = identity.
  • specs/test_framework/property_test_template.t27: Test differential_property_passes_within_tolerance uses INVENTED stand-ins, and the file now says so. The original call is missing one of generator, f and g, and which one is ambiguous. The translation assumes the generator is missing: the zero generator is used, and f = g = PairToF64.first.
  • specs/test_framework/property_test_template.t27: details is a Text value in all 10 TestResult literals.
  • specs/test_framework/property_test_template.t27: This file's TestResult fields and its Verdict and EngineeringStatus variants did not match core.t27 even before the translation. They are left as written.
  • specs/test_framework/property_test_template.t27 (removed): The generic parameter lists <F, G> and <F, G, H> and the where-clauses of metamorphic and differential were removed as syntax. They are kept verbatim in a comment above each fn.
  • specs/test_framework/runner.t27: TestBlock.input/expected, DomainFn and PropertyFn use f64 for Rust any, following core's any -> f64 mapping.
  • specs/test_framework/runner.t27: Unit test actual: result (a bool) is stored as 1.0 or 0.0, because core's actual is f64.
  • specs/test_framework/runner.t27: Gate pipeline expected: GatePipeline::all_true() and actual: pipeline are stored as the 6-bit gate mask (new helper gate_pipeline_mask, bit order of core's gate_pipeline_sequential_all_gates invariant; all gates true = 63). The mask is exact, so no gate state is lost.
  • specs/test_framework/runner.t27: GatePipeline::all_true() is defined nowhere (not in core.t27 and not elsewhere in specs/). It is called as gate_pipeline_all_true() in core's naming and still has no definition; a comment says so.
  • specs/test_framework/runner.t27: for_all: domain() and property() are evaluated in the runner for at most core's MAX_CASES (64) iterations. Core reports 'capped at' when iterations is larger.
  • specs/test_framework/runner.t27: Capacities: results use core's ResultList. MAX_RESULTS=64 is set in core, and core's push drops overflow silently (before this round, the runner's own 1024-slot list returned an error). Test blocks are capped at MAX_TEST_BLOCKS=1024, and spec files at MAX_SPEC_FILES=256 (error.TooManySpecFiles). Reports are truncated at core's REPORT_CAP.
  • specs/test_framework/runner.t27: {:.6} in the benchmark message is core's f64_to_text: up to 6 fraction digits with trailing zeros trimmed, so the text can be shorter than Rust's. The previous undefined host helper format_f64 is gone.
  • specs/test_framework/runner.t27: Error strings became named errors: "Invalid iteration count" is error.InvalidIterationCount and "Invalid tolerance" is error.InvalidTolerance. parse_u32/parse_f64 are undefined host parsers returning null on failure. print/print_int/exit are host I/O, as in core's test.
  • specs/test_framework/runner.t27: config_default returns the defaults. The original's trailing ; returned () in Rust.
  • specs/test_framework/runner.t27: The fn-type aliases TestFn, DomainFn, PropertyFn and PipelineFn lower to invalid C (static const int TestFn = fn ( ) bool;). This is a backend gap, noted in a comment.
  • specs/test_framework/runner.t27: The 4 status glyphs in string literals (U+2717, U+2713, U+25CB) are carried over unchanged from the original (nonAscii=4, same count as the original).
  • specs/tools/registry.t27: Map literals {K: v, ...} / [K: v, ...] are written as m = []; (empty map) plus m[K] = v; for each entry. This keeps the replace-then-fill meaning.
  • specs/tools/registry.t27: The empty map {} is written as the empty collection literal [].
  • specs/tools/schema.t27: The local ToolID / CallID tuple structs are single-field structs with field value. t27 has no tuple structs.
  • specs/tools/schema.t27: The aliased import's path "../session/schema.t27" names a file that does not exist in the repo. The original module name was session::schema, and the compiler does not resolve the path. This is stated in a comment in the file.
  • specs/tools/schema.t27: The map literals are written as an empty map plus index assignments, because t27 has no map-literal syntax. The meaning is the same.
  • specs/tri/collections/maybe.t27: Anonymous closures in tests are now named top-level functions with the same bodies.
  • specs/tri/collections/maybe.t27: The aliases are not generic. ADR-008 rejects pub const MaybeBindFn(T) = fn... (verified: 'right-hand side of parameterised const must be struct'). Their T is the module-level free T that nothing/pure/bind/map/join also use, not a type parameter of the alias or of bind/map, so the inline f: fn(T) -> Maybe(T) tie to the caller's T is lost. The Rust output is pub type MaybeBindFn = fn(T) -> Maybe<T>; with T unbound, and C emits the invalid static const int MaybeBindFn = fn ( T ) Maybe ( T );.
  • specs/tri/graph/graph_bfs.t27: Moving defer to an explicit call before the return behaves the same only because traverse has a single exit.
  • specs/tri/graph/graph_bfs.t27: The result == void check is now made through the type name @typeName(@TypeOf(result)) == "void". It makes the same claim.
  • specs/tri/graph/graph_bfs.t27: The allocator calls and std.ArrayList(usize) are kept as written, not turned into fixed-size arrays. They generate on all backends, and the sibling fenwick_tree.t27 uses the same allocator.alloc shape.
  • specs/tri/graph/graph_bfs.t27: The original is inconsistent: *[]usize is not an optional type, yet it is null-tested and unwrapped with .?. It is kept verbatim because the reviewer asked for the original annotation. Two lines I did not change mis-lower, and both need a compiler fix. The type argument []usize in allocator.alloc([]usize, n) lowers as an empty literal: Zig .{}, C { 0 }. ptr[i] = &[_]usize{}; lowers to Zig &.{ _ }, the empty-[_]T{} defect. I tested a type alias pub const AdjRow = []usize;. It fixes Zig and C, but gen-rust then emits pub const AdjRow: i32 = []usize;, so I did not use it.
  • specs/tri/search/aho_corasick.t27: Representation change on the public ACAutomaton type: the patterns are now offsets plus a pattern_at() accessor, with the same 256-pattern bound. Behaviour is unchanged: nothing else read .patterns, and every pattern can be recovered exactly. It is marked warn so the owner can accept or reject the struct change.
  • specs/tri/search/aho_corasick.t27: Rejected alternatives: a type alias for []const u8 or dropping const would only dodge the backend's text heuristic, and a module-level array would share state across builds.
  • specs/tri/search/aho_corasick.t27: Not fixed: the trie-insertion loop in build() still walks bytes of the raw patterns string, not the parsed patterns. That is an original logic bug, outside a syntax translation.

🤖 Generated with Claude Code

dmitrii-f-t27 and others added 2 commits September 24, 2026 11:51
 gHashTag#4793)

Each spec failed in the parser before any backend ran, so the Queen board
listed it as Broken. The syntax is translated to t27: Zig idioms
(std.ArrayList, for (xs) |x|, try std.testing.expect, [_]T{...}), Rust idioms
(let mut, Vec::new, format!, slices), the older t27 style (import x;,
module X { ... } blocks, given/when tests, '};' after structs) and typos.
Declarations, tests, invariants, benches, assertions and constants are kept;
where t27 has no direct form the spec says so in a comment.

All 62 now pass the seven explorer targets of the compiler built from
a103752 and t27c gen / gen-c / gen-rust / gen-verilog.

Closes gHashTag#4793

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Refs gHashTag#4793)

- t27c seal --save for every spec changed in the previous commit: 117 seal
  files updated, 6 new (specs that had none).
- tools/specs_generate_baseline.txt: drop the 61 entries that now generate
  (54 of the repaired specs, 7 fixed earlier on master and still listed).
- tools/duplicate_declarations_baseline.txt: benchmark 13, adamw 11 and
  file/operations 1 reach zero.
- docs/now entry for the change.

Refs gHashTag#4793

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dmitrii-f-t27
dmitrii-f-t27 merged commit 8265ff0 into gHashTag:master Sep 24, 2026
31 of 41 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

62 specs on master that no backend accepts: foreign-dialect syntax (Queen board Broken)

1 participant