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
16 changes: 10 additions & 6 deletions .trinity/seals/t27f_t27f_spec_deps.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,26 @@
"spec": "specs/ci/affected.t27",
"spec_hash": "sha256:38a7bdc245f1974f0d5f1a55a45966decd70098afdb89e882f568da3650ee9f9"
},
{
"spec": "specs/claw/t27f_gate.t27",
"spec_hash": "sha256:856be049f9ef3de20cce2f7d18ca3b78a5f4a8ad660dddd8f2cf1aa97bc61ee7"
},
{
"spec": "specs/policy/text_lines.t27",
"spec_hash": "sha256:13c90895a4a44c760cce6b3b65f72f937298633062f040f8489486108ab0c2d1"
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:46e8cd0521a7d466c8d72b0072d7124fe4e125980d15053b4ff0f5e1e0e8f4e6",
"gen_hash_rust": "sha256:6402828161a1d1ddff1787a41297d158c0fd08b54540a4a606980b414ea8f2d2",
"gen_hash_verilog": "sha256:6a2d9fc3d039e9a989aa364d45502d701169bb5074a9726d7365d460702672a8",
"gen_hash_zig": "sha256:b26cd46a5e8acf928349c46c6f3a7a4ded7c18e7e0c14e9276a59dba54aed396",
"gen_hash_c": "sha256:8dfb9c21bc40906375fafd873fc6a53cbc80726a04beaf7ef3a7248ef6e92b5e",
"gen_hash_rust": "sha256:c80e910314b1eb91dff11da6a8b637bcfd411926c341e48b556caa26b394022e",
"gen_hash_verilog": "sha256:80dc78cf2dfdbf055cb38f149f2986575b0453994e2db9f9defdb288b3287be4",
"gen_hash_zig": "sha256:2a4a4580c07b6aee3d5d235f18adac2eb3ae03a04e03a38d59c25c9184e299ba",
"module": "t27f_spec_deps",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-18T22:02:00Z",
"sealed_at": "2026-10-18T22:12:14Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:54eeee44e930711d5a1740e9cde8c11720a05baf17951360adf14a17925b4575",
"spec_hash": "sha256:75aafa2bc9e6f0c54b721e34d216a498814a097585ba353f72a6aeb813fa4014",
"spec_path": "specs/t27f/spec_deps.t27",
"tests": {
"failed": 0,
Expand Down
77 changes: 36 additions & 41 deletions specs/t27f/spec_deps.t27
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ module t27f_spec_deps;

use policy::text_lines;
use ci::affected;
// lit_len, the length of a '$'-terminated literal, is reused from here, not copied (duplicate-bodies, #10685).
use claw::t27f_gate;

/// Which way a walk follows the edges: to what a spec imports, or to what imports it.
pub const DEPS_IMPORTS : u8 = 1;
Expand Down Expand Up @@ -67,13 +69,6 @@ pub const DEPS_REFUSED : str = "refused\t$";
pub const DEPS_WHY_FULL : str = "full\t$";
pub const DEPS_WHY_DEEP : str = "deep\t$";

/// Length of a '$'-terminated literal.
pub fn deps_len(lit: []const u8) -> usize {
var k : usize = 0;
while (lit[k] != LIST_END) { k += 1; }
return k;
}

/// Is s[f..t] one of the newline-terminated lines of set[lo..hi]?
pub fn deps_in_range(set: []const u8, lo: usize, hi: usize, s: []const u8, f: usize, t: usize) -> bool {
var i : usize = lo;
Expand Down Expand Up @@ -172,7 +167,7 @@ pub fn deps_put_span(out: []u8, w: usize, cap: usize, buf: []const u8, f: usize,

/// Write a '$'-terminated literal.
pub fn deps_put_lit(out: []u8, w: usize, cap: usize, lit: []const u8) -> usize {
return deps_put_span(out, w, cap, lit, 0, deps_len(lit));
return deps_put_span(out, w, cap, lit, 0, lit_len(lit));
}

/// Write v in decimal.
Expand Down Expand Up @@ -304,7 +299,7 @@ test the_import_layers_of_a_diamond_list_the_shared_spec_once {
var set : [64]u8 = undefined;
var b : [35]usize = undefined;
const g : str = DEPS_FIXTURE;
assert deps_walk(g, deps_len(g), "a", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_walk(g, lit_len(g), "a", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_depth(&b, 8) == 2;
assert deps_count(&set, b[1], b[2]) == 2;
assert deps_count(&set, b[2], b[3]) == 1;
Expand All @@ -316,7 +311,7 @@ test the_importer_layers_walk_the_other_way {
var set : [64]u8 = undefined;
var b : [35]usize = undefined;
const g : str = DEPS_FIXTURE;
assert deps_walk(g, deps_len(g), "a", 0, 1, DEPS_IMPORTERS, 8, &set, 64, &b) == DEPS_OK;
assert deps_walk(g, lit_len(g), "a", 0, 1, DEPS_IMPORTERS, 8, &set, 64, &b) == DEPS_OK;
assert deps_depth(&b, 8) == 2;
assert deps_in_range(&set, b[1], b[2], "e", 0, 1) == true;
assert deps_in_range(&set, b[2], b[3], "f", 0, 1) == true;
Expand All @@ -328,64 +323,64 @@ test negative_control_a_dag_does_not_flag_a_cycle {
var set : [64]u8 = undefined;
var b : [35]usize = undefined;
const g : str = DEPS_FIXTURE;
assert deps_walk(g, deps_len(g), "a", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_on_cycle(g, deps_len(g), "a", 0, 1, &set, b[deps_depth(&b, 8) + 1]) == false;
assert deps_walk(g, lit_len(g), "a", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_on_cycle(g, lit_len(g), "a", 0, 1, &set, b[deps_depth(&b, 8) + 1]) == false;
}

test a_spec_that_imports_the_focus_back_flags_it {
var set : [64]u8 = undefined;
var b : [35]usize = undefined;
const g : str = "a\tb\na\tc\nb\td\nc\td\nd\ta\n$";
assert deps_walk(g, deps_len(g), "a", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_on_cycle(g, deps_len(g), "a", 0, 1, &set, b[deps_depth(&b, 8) + 1]) == true;
assert deps_walk(g, lit_len(g), "a", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_on_cycle(g, lit_len(g), "a", 0, 1, &set, b[deps_depth(&b, 8) + 1]) == true;
}

// The shape found on the corpus: two specs that import each other (igla::race backend and rtl).
test two_specs_that_import_each_other_are_both_flagged {
var set : [64]u8 = undefined;
var b : [35]usize = undefined;
const g : str = "a\tt\na\tb\nb\tt\nb\ta\nc\tb\n$";
assert deps_walk(g, deps_len(g), "a", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_on_cycle(g, deps_len(g), "a", 0, 1, &set, b[deps_depth(&b, 8) + 1]) == true;
assert deps_walk(g, deps_len(g), "b", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_on_cycle(g, deps_len(g), "b", 0, 1, &set, b[deps_depth(&b, 8) + 1]) == true;
assert deps_walk(g, deps_len(g), "c", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_on_cycle(g, deps_len(g), "c", 0, 1, &set, b[deps_depth(&b, 8) + 1]) == false;
assert deps_walk(g, lit_len(g), "a", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_on_cycle(g, lit_len(g), "a", 0, 1, &set, b[deps_depth(&b, 8) + 1]) == true;
assert deps_walk(g, lit_len(g), "b", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_on_cycle(g, lit_len(g), "b", 0, 1, &set, b[deps_depth(&b, 8) + 1]) == true;
assert deps_walk(g, lit_len(g), "c", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_on_cycle(g, lit_len(g), "c", 0, 1, &set, b[deps_depth(&b, 8) + 1]) == false;
}

test a_self_import_flags_the_focus {
var set : [64]u8 = undefined;
var b : [35]usize = undefined;
const g : str = "a\ta\n$";
assert deps_walk(g, deps_len(g), "a", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_walk(g, lit_len(g), "a", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_depth(&b, 8) == 0;
assert deps_on_cycle(g, deps_len(g), "a", 0, 1, &set, b[1]) == true;
assert deps_on_cycle(g, lit_len(g), "a", 0, 1, &set, b[1]) == true;
}

test negative_control_a_cycle_the_focus_is_not_on_does_not_flag_it {
var set : [64]u8 = undefined;
var b : [35]usize = undefined;
const g : str = "a\tb\nb\tc\nc\tb\n$";
assert deps_walk(g, deps_len(g), "a", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_on_cycle(g, deps_len(g), "a", 0, 1, &set, b[deps_depth(&b, 8) + 1]) == false;
assert deps_walk(g, deps_len(g), "b", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_on_cycle(g, deps_len(g), "b", 0, 1, &set, b[deps_depth(&b, 8) + 1]) == true;
assert deps_walk(g, lit_len(g), "a", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_on_cycle(g, lit_len(g), "a", 0, 1, &set, b[deps_depth(&b, 8) + 1]) == false;
assert deps_walk(g, lit_len(g), "b", 0, 1, DEPS_IMPORTS, 8, &set, 64, &b) == DEPS_OK;
assert deps_on_cycle(g, lit_len(g), "b", 0, 1, &set, b[deps_depth(&b, 8) + 1]) == true;
}

test negative_control_a_set_that_does_not_fit_is_refused {
var set : [64]u8 = undefined;
var b : [35]usize = undefined;
const g : str = DEPS_FIXTURE;
assert deps_walk(g, deps_len(g), "a", 0, 1, DEPS_IMPORTS, 8, &set, 5, &b) == DEPS_ERR_FULL;
assert deps_walk(g, deps_len(g), "a", 0, 1, DEPS_IMPORTS, 8, &set, 8, &b) == DEPS_OK;
assert deps_walk(g, lit_len(g), "a", 0, 1, DEPS_IMPORTS, 8, &set, 5, &b) == DEPS_ERR_FULL;
assert deps_walk(g, lit_len(g), "a", 0, 1, DEPS_IMPORTS, 8, &set, 8, &b) == DEPS_OK;
}

test negative_control_a_walk_deeper_than_asked_is_refused {
var set : [64]u8 = undefined;
var b : [35]usize = undefined;
const g : str = "a\tb\nb\tc\nc\td\n$";
assert deps_walk(g, deps_len(g), "a", 0, 1, DEPS_IMPORTS, 2, &set, 64, &b) == DEPS_ERR_DEEP;
assert deps_walk(g, deps_len(g), "a", 0, 1, DEPS_IMPORTS, 3, &set, 64, &b) == DEPS_OK;
assert deps_walk(g, lit_len(g), "a", 0, 1, DEPS_IMPORTS, 2, &set, 64, &b) == DEPS_ERR_DEEP;
assert deps_walk(g, lit_len(g), "a", 0, 1, DEPS_IMPORTS, 3, &set, 64, &b) == DEPS_OK;
assert deps_depth(&b, 3) == 3;
}

Expand All @@ -397,10 +392,10 @@ test the_view_lays_out_importers_left_and_imports_right_with_exact_edges {
var es : [128]u8 = undefined;
var out : [512]u8 = undefined;
const g : str = DEPS_FIXTURE;
const w : usize = deps_view(g, deps_len(g), "a", 0, 1, 8, &imp, 64, &ib, &rev, 64, &rb, &es, 128, &out, 512);
const w : usize = deps_view(g, lit_len(g), "a", 0, 1, 8, &imp, 64, &ib, &rev, 64, &rb, &es, 128, &out, 512);
const want : str = "deps\ta\tcycle=0\timports=3\timporters=2\tdepth=2/2\nnode\t-2\t40\t40\tf\nnode\t-1\t300\t40\te\nnode\t0\t560\t40\ta\nnode\t1\t820\t40\tb\nnode\t1\t820\t104\tc\nnode\t2\t1080\t40\td\nedge\ta\tb\texact\nedge\ta\tc\texact\nedge\tb\td\texact\nedge\tc\td\texact\nedge\te\ta\texact\nedge\tf\te\texact\n$";
assert w == deps_len(want);
assert same(&out, 0, w, want, 0, deps_len(want)) == true;
assert w == lit_len(want);
assert same(&out, 0, w, want, 0, lit_len(want)) == true;
}

test negative_control_a_repeated_line_is_one_edge {
Expand All @@ -411,7 +406,7 @@ test negative_control_a_repeated_line_is_one_edge {
var es : [128]u8 = undefined;
var out : [256]u8 = undefined;
const g : str = "a\tb\na\tb\na\tb\n$";
const w : usize = deps_view(g, deps_len(g), "a", 0, 1, 8, &imp, 64, &ib, &rev, 64, &rb, &es, 128, &out, 256);
const w : usize = deps_view(g, lit_len(g), "a", 0, 1, 8, &imp, 64, &ib, &rev, 64, &rb, &es, 128, &out, 256);
assert w <= 256;
assert deps_count(&out, 0, w) == 4;
}
Expand All @@ -424,13 +419,13 @@ test negative_control_a_refused_walk_writes_one_refusal_line {
var es : [128]u8 = undefined;
var out : [256]u8 = undefined;
const g : str = DEPS_FIXTURE;
const w : usize = deps_view(g, deps_len(g), "a", 0, 1, 8, &imp, 5, &ib, &rev, 64, &rb, &es, 128, &out, 256);
const w : usize = deps_view(g, lit_len(g), "a", 0, 1, 8, &imp, 5, &ib, &rev, 64, &rb, &es, 128, &out, 256);
const want : str = "refused\tfull\ta\n$";
assert w == deps_len(want);
assert same(&out, 0, w, want, 0, deps_len(want)) == true;
const w2 : usize = deps_view(g, deps_len(g), "a", 0, 1, 1, &imp, 64, &ib, &rev, 64, &rb, &es, 128, &out, 256);
assert w == lit_len(want);
assert same(&out, 0, w, want, 0, lit_len(want)) == true;
const w2 : usize = deps_view(g, lit_len(g), "a", 0, 1, 1, &imp, 64, &ib, &rev, 64, &rb, &es, 128, &out, 256);
const want2 : str = "refused\tdeep\ta\n$";
assert same(&out, 0, w2, want2, 0, deps_len(want2)) == true;
assert same(&out, 0, w2, want2, 0, lit_len(want2)) == true;
}

test negative_control_a_view_that_does_not_fit_returns_more_than_cap {
Expand All @@ -441,6 +436,6 @@ test negative_control_a_view_that_does_not_fit_returns_more_than_cap {
var es : [128]u8 = undefined;
var out : [32]u8 = undefined;
const g : str = DEPS_FIXTURE;
assert deps_view(g, deps_len(g), "a", 0, 1, 8, &imp, 64, &ib, &rev, 64, &rb, &es, 128, &out, 32) > 32;
assert deps_view(g, deps_len(g), "a", 0, 1, 8, &imp, 64, &ib, &rev, 64, &rb, &es, 4, &out, 32) > 32;
assert deps_view(g, lit_len(g), "a", 0, 1, 8, &imp, 64, &ib, &rev, 64, &rb, &es, 128, &out, 32) > 32;
assert deps_view(g, lit_len(g), "a", 0, 1, 8, &imp, 64, &ib, &rev, 64, &rb, &es, 4, &out, 32) > 32;
}
Loading