Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions .trinity/seals/pr_TriPrPreflight.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"built_by": "t27c-bootstrap@0.5.2+fdb6b28dd",
"built_by": "t27c-bootstrap@0.5.2+b258b9007",
"closure": [
{
"spec": "specs/tri/lab/receipt.t27",
Expand All @@ -11,27 +11,27 @@
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:d85f440682c707fd126ed726dc9a8c3713f33fa67528953a532a9eb40da55b81",
"gen_hash_rust": "sha256:d945336cc8dded5d2368a118984c549c629b7428fcd054089b7db46cfaa4ced2",
"gen_hash_verilog": "sha256:68f5baedb845f39d78c0aed0c6100be3574cd1d7a3bccd09b9e1d9042e589850",
"gen_hash_zig": "sha256:bf8cabe6e83216400e8702e979de7cd26cb4bfd5919a7f6fc557ca621092709a",
"gen_hash_c": "sha256:7b05ed840e722e114f7e7427e7808981f9fe5a01c2b45d5908c6dfef0394e952",
"gen_hash_rust": "sha256:d6ab06097d38589835a474ff94c2b97cccb59b0185844c936bbfd858b0a723de",
"gen_hash_verilog": "sha256:39f7e63349e6fe4ee7aa4e3fb71554cf09a3a9147f5faff0494d599239f4bb9a",
"gen_hash_zig": "sha256:6b0f5756fe610ad85c1b745922d896ce7f5d6a1f33668858c2964f6afe299465",
"module": "TriPrPreflight",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-18T05:09:07Z",
"sealed_at": "2026-10-19T18:07:06Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:24634647a1245ac9d776735bd4323f524d71f7c52f0928ce31066a114b68f409",
"spec_hash": "sha256:ce7132cb0b49246d3d86bdde48ecad5bc41f252d721dbfa0b1912306b7a39897",
"spec_path": "specs/tri/pr/preflight.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 19,
"total": 19,
"passed": 24,
"total": 24,
"vacuous": 0
},
"toolchain": {
"test_runner": "sha256:1982ae948e24d00c5d221ccec12dfce1eb01204b53e37b0f857f93b16d64629d",
"test_runner": "sha256:8512b80da533b79289110fca4a65f3336abd7a059ca4b72ea595d5e33ff8ad10",
"zig": "0.16.0"
}
}
138 changes: 130 additions & 8 deletions gen/rust/tri/pr/preflight.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Generated from .t27 spec
// DO NOT EDIT — generated by t27c
// NOT LOWERED BY THIS BACKEND: 19 test(s), 1 invariant(s), 0 function(s) with no body.
// NOT LOWERED BY THIS BACKEND: 24 test(s), 1 invariant(s), 0 function(s) with no body.
// This backend emits declarations only. The spec's checks live in
// the Zig and Verilog outputs; do not read this file as verified.

Expand Down Expand Up @@ -38,9 +38,13 @@ pub const STEP_SUITE: u8 = 15;

pub const STEP_DUPES_BASE: u8 = 16;

pub const STEPS: u8 = 17;
pub const STEP_BUDGET: u8 = 17;

pub const NO_STEP: u8 = 17;
pub const STEP_DEVHOME: u8 = 18;

pub const STEPS: u8 = 19;

pub const NO_STEP: u8 = 19;

pub const R_CHANGES: u8 = 0;

Expand All @@ -62,9 +66,13 @@ pub const R_SUITE: u8 = 8;

pub const R_CENSUS: u8 = 9;

pub const R_COUNT: u8 = 10;
pub const R_BUDGET: u8 = 10;

pub const R_DEVHOME: u8 = 11;

pub const RULES: u8 = 11;
pub const R_COUNT: u8 = 12;

pub const RULES: u8 = 13;

pub const P_PASS: u8 = 0;

Expand Down Expand Up @@ -135,7 +143,13 @@ pub fn step_cmd(k: u8) -> &'static str {
if (k == STEP_SUITE) {
return "\"$T27C\" suite --repo-root . --ratchet --corpus-only 2>&1";
}
return "d=\"$(mktemp -d)\"; git worktree add -q --detach \"$d\" origin/master 2>&1 && (cd \"$d\" && python3 tools/dupe_scan.py 2>&1); x=$?; git worktree remove --force \"$d\" 2>&1; exit $x";
if (k == STEP_DUPES_BASE) {
return "d=\"$(mktemp -d)\"; git worktree add -q --detach \"$d\" origin/master 2>&1 && (cd \"$d\" && python3 tools/dupe_scan.py 2>&1); x=$?; git worktree remove --force \"$d\" 2>&1; exit $x";
}
if (k == STEP_BUDGET) {
return "{ b=\"$(git merge-base origin/master HEAD)\" && d=\"$(mktemp -d \"${TMPDIR:-/tmp}/budget.XXXXXX\")\" && git show \"${b}:gen/c/policy/own_language.c\" > \"$d/gate.c\" && printf '#include \"gate.c\"\\n#include <stdio.h>\\nint main(void){static char b[1<<22],o[1<<22];unsigned n=check_budget((uint8_t*)b,fread(b,1,sizeof b,stdin),(uint8_t*)o,sizeof o-1);fputs(o,stdout);return n!=0;}\\n' | cc -w -I \"$d\" -x c -o \"$d/budget\" - && git diff --numstat --no-renames \"${b}...HEAD\" > \"$d/in\" && \"$d/budget\" < \"$d/in\"; x=$?; rm -rf \"$d\"; exit $x; } 2>&1";
}
return "python3 -I tools/check_devhome_paths.py 2>&1";
}

pub fn step_each(k: u8) -> bool {
Expand Down Expand Up @@ -265,17 +279,21 @@ pub fn adds_workflow(c: &'static str) -> bool {
return false;
}

pub fn touches_census(c: &'static str) -> bool {
pub fn changes_under(c: &'static str, lit: &'static str) -> bool {
let mut n: u64 = 0;
while (n < entries(c)) {
if path_is(c, n, "tools/census/", "") {
if path_is(c, n, lit, "") {
return true;
}
n = (n + 1);
}
return false;
}

pub fn touches_census(c: &'static str) -> bool {
return changes_under(c, "tools/census/");
}

pub fn digits_end(text: &'static str, at: usize, to: usize) -> usize {
let mut k: usize = at;
while (((k < to) && (text.as_bytes()[(k) as usize] >= 48)) && (text.as_bytes()[(k) as usize] <= 57)) {
Expand Down Expand Up @@ -520,6 +538,43 @@ pub fn names_path(ev: &'static str, from: usize, to: usize, c: &'static str, n:
return false;
}

pub fn finding_path(ev: &'static str, at: usize, end: usize) -> usize {
if (opens_with(ev, at, end, "FAIL ") == false) {
return (ev.len() + 1);
}
let mut k: usize = (at + 5);
while (((k < end) && (ev.as_bytes()[(k) as usize] >= 97)) && (ev.as_bytes()[(k) as usize] <= 122)) {
k = (k + 1);
}
if (((k == (at + 5)) || (k >= end)) || (ev.as_bytes()[(k) as usize] != 32)) {
return (ev.len() + 1);
}
while ((k < end) && (ev.as_bytes()[(k) as usize] == 32)) {
k = (k + 1);
}
return k;
}

pub fn names_home(ev: &'static str, from: usize, to: usize, c: &'static str, n: u64) -> bool {
let pf: usize = path_start(c, n);
let pl: usize = (path_end(c, n) - pf);
let mut at: usize = from;
while (at < to) {
let mut end: usize = line_end(ev, at);
if (end > to) {
end = to;
}
let k: usize = finding_path(ev, at, end);
if (((k <= ev.len()) && ((end - k) >= pl)) && same(ev, k, c, pf, (pf + pl))) {
if (((k + pl) == end) || opens_with(ev, (k + pl), end, " ")) {
return true;
}
}
at = (end + 1);
}
return false;
}

pub fn exit_verdict(x: u64) -> u8 {
if (x == 0) {
return P_PASS;
Expand Down Expand Up @@ -613,6 +668,35 @@ pub fn once_verdict(c: &'static str, ev: &'static str, r: u8, quick: bool) -> u8
}
return exit_verdict(exit_of(ev, STEP_CENSUS, 0));
}
if (r == R_BUDGET) {
let bf: usize = body_from(ev, STEP_BUDGET, 0);
let bt: usize = body_to(ev, STEP_BUDGET, 0);
if ((find_in(ev, bf, bt, " hand-written foreign lines added") <= ev.len()) || (find_in(ev, bf, bt, ": unreadable numstat line") <= ev.len())) {
return P_FAIL;
}
if ((exit_of(ev, STEP_BUDGET, 0) == 0) && (bf == bt)) {
return P_PASS;
}
return P_UNREAD;
}
if (r == R_DEVHOME) {
let hf: usize = body_from(ev, STEP_DEVHOME, 0);
let ht: usize = body_to(ev, STEP_DEVHOME, 0);
let x: u64 = exit_of(ev, STEP_DEVHOME, 0);
if (x == 0) {
if has_line(ev, hf, ht, "OK: ") {
return P_PASS;
}
return P_UNREAD;
}
if ((x != 1) || (has_line(ev, hf, ht, "FAIL ") == false)) {
return P_UNREAD;
}
if (changes_under(c, "tools/devhome_baseline.txt") || changes_under(c, "tools/check_devhome_paths.py")) {
return P_FAIL;
}
return P_PASS;
}
return P_PASS;
}

Expand Down Expand Up @@ -641,6 +725,18 @@ pub fn entry_verdict(c: &'static str, ev: &'static str, r: u8, n: u64, quick: bo
}
return P_PASS;
}
if (r == R_DEVHOME) {
if (exit_of(ev, STEP_DEVHOME, 0) != 1) {
return P_PASS;
}
if (path_safe(c, n) == false) {
return P_UNREAD;
}
if names_home(ev, body_from(ev, STEP_DEVHOME, 0), body_to(ev, STEP_DEVHOME, 0), c, n) {
return P_FAIL;
}
return P_PASS;
}
if (is_target(c, n) == false) {
return P_PASS;
}
Expand Down Expand Up @@ -801,6 +897,12 @@ pub fn evidence_step(c: &'static str, ev: &'static str, r: u8, n: u64) -> u8 {
if ((r == R_CENSUS) && touches_census(c)) {
return STEP_CENSUS;
}
if (r == R_BUDGET) {
return STEP_BUDGET;
}
if (r == R_DEVHOME) {
return STEP_DEVHOME;
}
return NO_STEP;
}

Expand Down Expand Up @@ -893,6 +995,12 @@ pub fn rule_name(r: u8) -> &'static str {
if (r == R_CENSUS) {
return "census";
}
if (r == R_BUDGET) {
return "budget";
}
if (r == R_DEVHOME) {
return "devhome";
}
return "kept";
}

Expand Down Expand Up @@ -949,6 +1057,12 @@ pub fn rule_why(r: u8, v: u8) -> &'static str {
if (r == R_CENSUS) {
return "a new workflow moves the census: run `tri census pin --bless` and commit tools/census/ in the same change";
}
if (r == R_BUDGET) {
return "the foreign-line budget (the merge base's own_language gate) refuses this diff: at most 40 hand-written foreign lines added per file and 80 per diff, never more added than deleted -- write the logic in .t27 and generate it";
}
if (r == R_DEVHOME) {
return "a file this branch changes names a developer home directory (tools/check_devhome_paths.py): take the path from the environment or `git rev-parse --show-toplevel`; never re-bless to hide it";
}
return "the spec has fewer test blocks than on origin/master: deleting tests is not a fix";
}

Expand All @@ -968,6 +1082,14 @@ pub const EV: &'static str = "@@ preflight 0 0 0 0\n\n@@ preflight 1 0 0 3\nA\tx

pub const SUITE_OUT: &'static str = "@@ preflight 15 0 1 244\n - specs/x/new.t27 [gen]\n--- Ratchet (W628) ---\n UNEXPECTED PASSES : 3\n - specs/igla/coder/arch.t27 [parse] (fixed -- remove from the ledger)\n - specs/x/old.t27x [parse]\n - specs/x/old.t27 [parse-no-discard] (fixed)\nRATCHET: FAIL\n\n";

pub const BUDGET_C: &'static str = "M\t.trinity/seals/t27o_T27oLedger.json\nM\tcli/tri/src/main.rs\nA\tgen/rust/tools/t27o/ledger.rs\nM\tspecs/tools/t27o/ledger.t27\n";

pub const BUDGET_OUT: &'static str = "@@ preflight 17 0 1 212\nall files: more hand-written foreign lines added than deleted (owner rule 2026-10-09: no hand-written code in any language but t27 may grow; port it to .t27 and generate it); no exception and no label lifts this\n\n";

pub const HOME_C: &'static str = "A\tdocs/new.md\nM\tspecs/x/grew.t27\nM\tspecs/x/shrank.t27\nD\tspecs/x/gone.t27\nM\tdocs/a.md\n";

pub const HOME_FIND: &'static str = "@@ preflight 18 0 1 371\nFAIL new docs/new.md (1 occurrence(s))\nFAIL grew specs/x/grew.t27 1 -> 2\nFAIL shrank specs/x/shrank.t27 2 -> 1 -- re-bless to pin the lower count\nFAIL fixed specs/x/gone.t27 was 3 -- remove it from the baseline\n\n Use `git rev-parse --show-toplevel`, or an environment variable the\n caller sets. Re-bless with: python3 tools/check_devhome_paths.py --bless\n\n";

pub const RUN: &'static str = "{\n \"lab\": \"t27b-lab\",\n \"commit\": \"891a9087afcbc45ca68c87c07a2e4ff0ae5db00c\",\n \"finished\": \"2026-10-09T22:47:35Z\",\n \"top_blockers\": [\n {\n \"construct\": \"ExprCall(undeclared fn)\",\n \"file\": \"specs/x.t27\"\n }\n ],\n \"results\": [\n {\n \"file\": \"specs/a/b_c.t27\",\n \"reference\": \"pass\",\n \"reference_detail\": \"\",\n \"t27b\": \"pass_vacuous\",\n \"tests\": 0,\n \"invariants\": 0,\n \"asserts\": 0,\n \"blockers\": [],\n \"test_verdicts\": {},\n \"reference_disagree\": []\n },\n {\n \"file\": \"specs/queen/actors.t27\",\n \"reference\": \"pass\",\n \"t27b\": \"pass\",\n \"tests\": 37,\n \"asserts\": 2474,\n \"test_verdicts\": {\n \"file\": true,\n \"t27b\": true\n },\n \"reference_disagree\": []\n },\n {\n \"file\": \"specs/account/auth.t27\",\n \"reference\": \"blocked\",\n \"reference_detail\": \"does not compile: spec.zig:23:16: error: use of undeclared identifier 'Ok'\",\n \"t27b\": \"blocked\",\n \"tests\": 0,\n \"asserts\": null,\n \"blockers\": [\n \"ExprFieldAccess\"\n ],\n \"detail\": \"ExprFieldAccess\"\n }\n ]\n}\n";

pub fn line_end(text: &'static str, at: usize) -> usize {
Expand Down
Loading
Loading