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
7 changes: 4 additions & 3 deletions .github/workflows/gate-topology.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,15 @@ jobs:
for f in t27c checksums-$V.txt; do curl -fsSLo $f $B/$f; curl -fsSLo $f.sigstore.json $B/$f.sigstore.json
cosign verify-blob $f --bundle $f.sigstore.json --certificate-oidc-issuer https://token.actions.githubusercontent.com --certificate-identity-regexp "^https://github.com/gHashTag/t27/.github/workflows/t27o-release.yml@refs/tags/$V$"; done
sha256sum -c --ignore-missing checksums-$V.txt; chmod +x t27c; T=/tmp/t27c
printf '#include "%s/gen/c/claw/t27f_gate.c"\n#include <stdio.h>\n#include <stdlib.h>\nint main(int c,char**v){size_t k=1<<24,m;uint8_t*b=malloc(k),*o=malloc(k);size_t n=fread(b,1,k,stdin);if(n==k)return 2;\nif(c>1){m=t27f_scope(b,n,o,k);if(m>k)return 3;}else m=t27f_report(b,n,o,65000);fwrite(o,1,m,stdout);return 0;}\n' "$GITHUB_WORKSPACE" > h.c; cc -O1 -w -o law h.c; L=/tmp/law; set +e
printf '#include "%s/gen/c/claw/t27f_gate.c"\n#include <stdio.h>\n#include <stdlib.h>\nint main(int c,char**v){size_t k=1<<24,m;uint8_t*b=malloc(k),*o=malloc(k);size_t n=fread(b,1,k,stdin);if(n==k)return 2;\nif(c>1&&*v[1]==97)m=t27f_annotations(b,n,o,k);else if(c>1){m=t27f_scope(b,n,o,k);if(m>k)return 3;}else m=t27f_report(b,n,o,65000);fwrite(o,1,m,stdout);return 0;}\n' "$GITHUB_WORKSPACE" > h.c; cc -O1 -w -o law h.c; L=/tmp/law; set +e
gh api --paginate /installation/repositories -q '.repositories[].full_name' | while read -r r; do
gh pr list -R $r -L 100 --json number,headRefOid,baseRefName,files -q '.[]|select(any(.files[];.path|endswith(".t27")))|"\(.number) \(.headRefOid) \(.baseRefName)"' </dev/null | while read -r n s b; do
[ "$(gh api "repos/$r/commits/$s/check-runs?check_name=claw/t27f" -q .total_count </dev/null)" = 0 ] || continue
( set -eo pipefail; rm -rf /tmp/w; git clone -q --filter=blob:none --no-checkout "https://x-access-token:$GH_TOKEN@github.com/$r" /tmp/w; cd /tmp/w
git fetch -q origin "pull/$n/head"; git sparse-checkout set --no-cone '*.t27' '/.trinity/seals/'; git checkout -q FETCH_HEAD
{ git diff --name-only --diff-filter=d "origin/$b...HEAD"; echo --graph; if [ -d specs ]; then $T use-edges --specs-dir specs; fi; } | $L s > ../scope || echo --unreadable > ../scope
{ printf 'repo\t%s\n' $r; while read -r f; do if [ "$f" = --unreadable ]; then echo $f; else printf '@\t%s\t%s\thttps://raw.githubusercontent.com/%s/%s/%s\n' "$f" "$(sha256sum < "$f" | cut -c1-64)" $r $s "$f"; $T seal "$f" --verify 2>&1 </dev/null || true; fi; done < ../scope; } | $L > ../out
jq -Rs --arg s $s 'split("\n") as $l | {name: $l[0], head_sha: $s, status: "completed", conclusion: $l[1], output: {title: $l[2], summary: ($l[3:] | join("\n"))}}' ../out | gh api -X POST repos/$r/check-runs --input - > /dev/null ); [ $? = 0 ] || echo "::warning::claw/t27f did not check $r#$n"
{ printf 'repo\t%s\n' $r; while read -r f; do if [ "$f" = --unreadable ]; then echo $f; else printf '@\t%s\t%s\thttps://raw.githubusercontent.com/%s/%s/%s\n' "$f" "$(sha256sum < "$f" | cut -c1-64)" $r $s "$f"; $T seal "$f" --verify 2>&1 </dev/null || true; fi; done < ../scope; } > ../in; $L < ../in > ../out; $L a < ../in > ../ann
jq -cRs --arg s $s --rawfile a ../ann 'split("\n") as $l | [$a | split("--batch\n")[] | [split("\n")[] | select(. != "") | split("\t") | {path: .[0], start_line: (.[1] | tonumber), end_line: (.[1] | tonumber), annotation_level: .[2], title: .[3], message: .[4]}]] as $b | {title: $l[2], summary: ($l[3:] | join("\n"))} as $o | ({name: $l[0], head_sha: $s, status: "completed", conclusion: $l[1], output: ($o + {annotations: ($b[0] // [])})}, ($b[1:][] | {output: ($o + {annotations: .})}))' ../out > ../bodies
I=$(head -1 ../bodies | gh api -X POST repos/$r/check-runs --input - -q .id); tail -n +2 ../bodies | while read -r j; do printf '%s' "$j" | gh api -X PATCH repos/$r/check-runs/$I --input - > /dev/null; done ); [ $? = 0 ] || echo "::warning::claw/t27f did not check $r#$n"
done
done
16 changes: 8 additions & 8 deletions .trinity/seals/claw_ClawT27fGate.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,23 @@
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:75cfffcfd6a4ba47ac96aa1c0ebbc232f9cbb9c85003eb458014abffc2ee8350",
"gen_hash_rust": "sha256:79e0722227eb57bccb498fb165c69f59e0f38b0d93e0bfb5b803263289c56e33",
"gen_hash_verilog": "sha256:1d75c13c148bb32ac17685f94d1dba57ec103911c3c0074bdfd169bc10882a91",
"gen_hash_zig": "sha256:a5fcd394b3d9538a3fc58fc2dad169db8ca0a43d722ee12f65a8a79dc8e2d55d",
"gen_hash_c": "sha256:f04634c3086d38301f1099fd9e14e5a10f61abac58441271c080bc1abcab9c9c",
"gen_hash_rust": "sha256:cdafe83e3bfa9e4fae5d727c58ff3ea74be36bff109ae7f643b32770db78e7e5",
"gen_hash_verilog": "sha256:0eff930fe14e25bf33a511ab0015c3040678d2ff0818000f6a80efdc0527278c",
"gen_hash_zig": "sha256:bdbcb346f994bed18e49299cd96c51abb8ac22a128b8ab02a48079a69b490e46",
"module": "ClawT27fGate",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-18T07:27:09Z",
"sealed_at": "2026-10-18T07:41:52Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:d971531b23c57834d5ffbfd200748db34f51a291f44b87716dcb02910f8e1993",
"spec_hash": "sha256:856be049f9ef3de20cce2f7d18ca3b78a5f4a8ad660dddd8f2cf1aa97bc61ee7",
"spec_path": "specs/claw/t27f_gate.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 23,
"total": 23,
"passed": 28,
"total": 28,
"vacuous": 0
},
"toolchain": {
Expand Down
10 changes: 5 additions & 5 deletions .trinity/seals/claw_ClawT27fGatePins.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,24 @@
"closure": [
{
"spec": "specs/claw/t27f_gate.t27",
"spec_hash": "sha256:d971531b23c57834d5ffbfd200748db34f51a291f44b87716dcb02910f8e1993"
"spec_hash": "sha256:856be049f9ef3de20cce2f7d18ca3b78a5f4a8ad660dddd8f2cf1aa97bc61ee7"
},
{
"spec": "specs/t27f/hot.t27",
"spec_hash": "sha256:a2ea398b37bd4d85e279b69a7e3d12d7944a2f849a2d231db24973f5731d557b"
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:e4d2bd19107fff5f42908395ebd42a855bc4821f85014db435196d0a360aff79",
"gen_hash_c": "sha256:e35b884c19d8d6c37ed63beac053d40a5e86f9c73fa2941ff6cd0039c81bda84",
"gen_hash_rust": "sha256:4dc02033cea4ae56d81cca417e99faf450bfd97ffcbd7fed702b56b30119ce25",
"gen_hash_verilog": "sha256:a5a99dff99da4b4ebd3c15c210a92a3cb487039215158b2bb3c89a83eab168df",
"gen_hash_zig": "sha256:50ca11596eb89c8ffac6476a97349bd9efd9ec5e64ef6ea5ed1bf42793aeb8c9",
"gen_hash_zig": "sha256:e39bb7edf0cb96766984159a1d7c9f3b79f432094cd7c74cd6a9b660a3195efb",
"module": "ClawT27fGatePins",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-18T07:27:10Z",
"sealed_at": "2026-10-18T07:41:53Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:8cc4c19346755daeec7f6ad0e004bbd5b496fdf105eef7c36b4db2bb976c6f34",
"spec_hash": "sha256:1a4fc11a3ee61e990b6226621b4379fe34a727f0d1c830004bfddb5640836666",
"spec_path": "specs/claw/t27f_gate_pins.t27",
"tests": {
"failed": 0,
Expand Down
177 changes: 176 additions & 1 deletion gen/c/claw/t27f_gate.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ static const const char* DECISION_LABELS[4] = { "reuse$", "rebuild_spec$", "rebu
#define TABLE_HEAD "| path | digest | nodes | edges | verdict | decision | graph |$"
#define TABLE_RULE "|---|---|---|---|---|---|---|$"
#define SUMMARY_FOOT "nodes and edges are not measured here: the T27F exporter is t27f.wasm in the viewer, not t27c. The graph link passes the spec's raw URL as src=; the viewer does not read src= yet and opens its own spec list.$"
#define ANNOTATIONS_PER_PATCH 50
#define ANNOTATION_LINE 1
#define MARK_BATCH "--batch$"
#define LEVEL_NOTICE 0
#define LEVEL_WARNING 1
#define LEVEL_FAILURE 2
static const const char* LEVEL_NAMES[3] = { "notice$", "warning$", "failure$" };
#define ANNOTATION_TITLE "T27F seal: $"
static const const char* VERDICT_TEXTS[6] = { "The spec matches its saved seal.$", "The spec bytes match the saved seal, but its generated code does not: the compiler moved since sealing. Reseal it with t27c seal <path> --save.$", "This spec has no saved seal under .trinity/seals/. Seal it with t27c seal <path> --save; until then this check cannot show it sealed.$", "The saved seal was made for other bytes of this spec. Reseal it with t27c seal <path> --save once its tests hold.$", "The saved seal is vacuous: the spec tests assert nothing that can fail. Add such a test, then reseal.$", "t27c seal --verify printed nothing this check can read for this spec, or its record line was malformed.$" };
#define ROLE_CHECK 0
#define ROLE_REPORT 1
#define CONSUMERS 16
Expand Down Expand Up @@ -120,6 +129,9 @@ size_t put_query(uint8_t* out, size_t w, size_t cap, uint8_t* buf, size_t f, siz
size_t put_row(uint8_t* out, size_t w, size_t cap, uint8_t* buf, size_t r, size_t b);
size_t put_overflow(uint8_t* out, size_t cap);
size_t t27f_report(uint8_t* buf, size_t n, uint8_t* out, size_t cap);
uint8_t verdict_level(uint8_t v, uint8_t role);
size_t put_annotation(uint8_t* out, size_t w, size_t cap, uint8_t* buf, size_t r, size_t b, uint8_t role);
size_t t27f_annotations(uint8_t* buf, size_t n, uint8_t* out, size_t cap);
bool scope_spec(uint8_t* buf, size_t f, size_t t);
size_t t27f_scope(uint8_t* buf, size_t n, uint8_t* set, size_t scap);
uint32_t census_specs(void);
Expand Down Expand Up @@ -567,6 +579,65 @@ size_t t27f_report(uint8_t* buf, size_t n, uint8_t* out, size_t cap) {
return p;
}

uint8_t verdict_level(uint8_t v, uint8_t role) {
uint8_t c = verdict_conclusion(v);
if ((c != CONCL_FAILURE)) {
return LEVEL_NOTICE;
}
if ((role == ROLE_REPORT)) {
return LEVEL_WARNING;
}
return LEVEL_FAILURE;
}

size_t put_annotation(uint8_t* out, size_t w, size_t cap, uint8_t* buf, size_t r, size_t b, uint8_t role) {
size_t e = line_end(buf, r, b);
size_t x = text_end(buf, r, e);
size_t p1 = first_tab(buf, r, x);
size_t p2 = first_tab(buf, (p1 + 1), x);
uint8_t v = record_verdict(buf, r, b);
size_t p = put_range(out, w, cap, buf, (p1 + 1), p2);
p = put(out, p, cap, '\t');
p = put_decimal(out, p, cap, ANNOTATION_LINE);
p = put(out, p, cap, '\t');
p = put_msg(out, p, cap, LEVEL_NAMES[verdict_level(v, role)]);
p = put(out, p, cap, '\t');
p = put_msg(out, p, cap, ANNOTATION_TITLE);
p = put_msg(out, p, cap, VERDICT_NAMES[v]);
p = put(out, p, cap, '\t');
p = put_msg(out, p, cap, VERDICT_TEXTS[v]);
return put(out, p, cap, '\n');
}

size_t t27f_annotations(uint8_t* buf, size_t n, uint8_t* out, size_t cap) {
if ((input_readable(buf, n) == false)) {
return 0;
}
uint8_t role = input_role(buf, n);
size_t p = 0;
uint32_t k = 0;
size_t r = next_record(buf, 0, n);
while ((r < n)) {
size_t b = next_record(buf, (line_end(buf, r, n) + 1), n);
size_t x = text_end(buf, r, line_end(buf, r, b));
size_t p1 = first_tab(buf, r, x);
size_t p2 = first_tab(buf, (p1 + 1), x);
if (((record_verdict(buf, r, b) != V_SEALED) && (p2 > (p1 + 1)))) {
if (((k > 0) && ((k % ANNOTATIONS_PER_PATCH) == 0))) {
p = put_msg(out, p, cap, MARK_BATCH);
p = put(out, p, cap, '\n');
}
p = put_annotation(out, p, cap, buf, r, b, role);
k += 1;
}
r = b;
}
if ((p > cap)) {
return 0;
}
return p;
}

bool scope_spec(uint8_t* buf, size_t f, size_t t) {
size_t k = lit_len(SPEC_EXT);
if ((t <= (f + k))) {
Expand Down Expand Up @@ -1110,6 +1181,105 @@ void test_numbers_and_query_values_are_written_exactly(void) {
assert((holds(&out, 0, w, "a%20b%26c/d:e%23$") == true));
}

void test_every_row_that_is_not_sealed_gets_one_annotation_line(void) {
uint8_t out[4096] = {0};
const char* inp = "repo\tgHashTag/tt-trinity-phi\n@\tspecs/a.t27\t0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\turl\nspec_hash: MATCH\ngen_hash_zig: MATCH\ngen_hash_verilog: MATCH\ngen_hash_c: MATCH\ngen_hash_rust: MATCH\n@\tspecs/b.t27\t0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\turl\nError: No saved seal found at .trinity/seals/B.json. Run with --save first.\n@\tspecs/c.t27\t0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\turl\nspec_hash: MISMATCH (saved=sha256:aa, current=sha256:bb)\n$";
size_t w = t27f_annotations(inp, lit_len(inp), &out, 4096);
assert((w > 0));
assert((holds(&out, 0, w, "specs/b.t27\t1\tnotice\tT27F seal: unsealed\tThis spec has no saved seal under .trinity/seals/.$") == true));
assert((holds(&out, 0, w, "specs/c.t27\t1\tfailure\tT27F seal: stale-seal\tThe saved seal was made for other bytes of this spec.$") == true));
assert((holds(&out, 0, w, "specs/a.t27$") == false));
assert((holds(&out, 0, w, "--batch$") == false));
uint32_t lines = 0;
size_t i = 0;
while ((i < w)) {
if ((out[i] == '\n')) {
lines += 1;
}
i += 1;
}
assert((lines == 2));
}

void test_the_published_copy_annotates_a_failure_as_a_warning(void) {
uint8_t out[4096] = {0};
const char* stale = "repo\tgHashTag/ghashtag.github.io\n@\tt27/a.t27\t0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\turl\nspec_hash: MISMATCH (saved=sha256:aa, current=sha256:bb)\n$";
size_t w = t27f_annotations(stale, lit_len(stale), &out, 4096);
assert((holds(&out, 0, w, "t27/a.t27\t1\twarning\tT27F seal: stale-seal\t$") == true));
assert((verdict_level(V_STALE, ROLE_CHECK) == LEVEL_FAILURE));
assert((verdict_level(V_UNREADABLE, ROLE_REPORT) == LEVEL_WARNING));
assert((verdict_level(V_TOOLCHAIN, ROLE_REPORT) == LEVEL_NOTICE));
}

void test_the_annotations_are_cut_into_batches_of_fifty(void) {
uint8_t inp[16384] = {0};
uint8_t out[32768] = {0};
uint32_t rows = 100;
while ((rows <= 101)) {
size_t n = put_msg(&inp, 0, 16384, "repo\tgHashTag/trios\n$");
uint32_t j = 0;
while ((j < rows)) {
n = put_msg(&inp, n, 16384, "@\tspecs/a.t27\t0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\turl\nError: No saved seal found\n$");
j += 1;
}
assert((n < 16384));
size_t w = t27f_annotations(&inp, n, &out, 32768);
uint32_t marks = 0;
uint32_t before = 0;
uint32_t lines = 0;
size_t s = 0;
while ((s < w)) {
size_t e = line_end(&out, s, w);
if (has_prefix(MARK_BATCH, &out, s, e)) {
if ((marks == 0)) {
before = lines;
}
marks += 1;
} else {
lines += 1;
}
s = (e + 1);
}
assert((lines == rows));
assert((before == ANNOTATIONS_PER_PATCH));
if ((rows == 100)) {
assert((marks == 1));
}
if ((rows == 101)) {
assert((marks == 2));
}
rows += 1;
}
}

void test_negative_control_unreadable_input_or_no_room_writes_no_annotation(void) {
uint8_t out[4096] = {0};
const char* marked = "repo\tgHashTag/trios\n--unreadable\n@\tspecs/a.t27\t0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\turl\nError: parse error\n$";
assert((t27f_annotations(marked, lit_len(marked), &out, 4096) == 0));
const char* inp = "repo\tgHashTag/trios\n@\tspecs/a.t27\t0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\turl\nError: parse error\n$";
assert((t27f_annotations(inp, lit_len(inp), &out, 4096) > 0));
assert((t27f_annotations(inp, lit_len(inp), &out, 20) == 0));
const char* no_path = "repo\tgHashTag/trios\n@\t\t0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\turl\nError: parse error\n$";
assert((t27f_annotations(no_path, lit_len(no_path), &out, 4096) == 0));
const char* few_tabs = "repo\tgHashTag/trios\n@\tspecs/a.t27\nspec_hash: MATCH\n$";
size_t w = t27f_annotations(few_tabs, lit_len(few_tabs), &out, 4096);
assert((holds(&out, 0, w, "specs/a.t27\t1\tfailure\tT27F seal: unreadable\t$") == true));
}

void test_no_annotation_text_can_break_its_line(void) {
size_t v = 0;
while ((v < 6)) {
size_t k = 0;
while ((VERDICT_TEXTS[v][k] != LIST_END)) {
assert((VERDICT_TEXTS[v][k] != '\t'));
assert((VERDICT_TEXTS[v][k] != '\n'));
k += 1;
}
assert((k > 20));
v += 1;
}
}


/* -------------------------------------------------------
Test runner (compile with -DT27_TEST_MAIN to execute)
Expand Down Expand Up @@ -1141,7 +1311,12 @@ int main(void) {
test_negative_control_an_import_does_not_put_what_it_imports_in_scope();
test_negative_control_a_scope_without_its_marker_or_room_fails_closed();
test_numbers_and_query_values_are_written_exactly();
printf("All %d tests passed.\n", 23);
test_every_row_that_is_not_sealed_gets_one_annotation_line();
test_the_published_copy_annotates_a_failure_as_a_warning();
test_the_annotations_are_cut_into_batches_of_fifty();
test_negative_control_unreadable_input_or_no_room_writes_no_annotation();
test_no_annotation_text_can_break_its_line();
printf("All %d tests passed.\n", 28);
return 0;
}
#endif /* T27_TEST_MAIN */
Expand Down
Loading
Loading