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
57 changes: 57 additions & 0 deletions .claude/skills/ci-gates/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8248,3 +8248,60 @@ line. Neither instrument is complete; together they bracket the answer.
**Where a deterministic instrument exists it is not a second opinion, it is the
answer.** Use the fan-out to name constructs and raise hypotheses; use the
compiler to decide.

## 325. A name is a name: read all of it

`module github::auth {` did not parse. The module-name reader took one
identifier and stopped, so the parser met a colon at module level and reported
something else entirely. Nine specs declared a path-qualified module and none
of them parsed.

The repair is not to give `::` a meaning. It is to read the whole NAME -- a
loop over `::`-separated segments, each of which may still be hyphenated,
because `module tritype-base;` was already legal and had to stay so.

**Both colons are required before either is consumed.** A single `:` after a
module name is not a path; swallowing it would turn a real error into a
stranger one further down the file. The existing path reader elsewhere in the
compiler consumes one colon and then optionally a second -- copying that idiom
verbatim would have inherited the looser rule.

Controls that made this safe to land: 621 specs parsed before and 627 after
with **zero** regressions, and seal drift moved 537 to 543 -- exactly the six
new specs, proving no previously-parsing spec's output changed.

## 326. The ritual on paper and the ritual in practice

`FROZEN.md` §5 says a change to `bootstrap/src/compiler.rs` needs M1-M4 green,
a PR marked `[GOLD-RING]`, a milestone, or Architect approval. That reads like
a stop sign at 3am.

The evidence says otherwise: the last 50 commits touching that file are eight
today alone, `FROZEN_HASH` is updated in **20 of the last 20**, and the phrase
GOLD-RING appears in **none** of them. The practice is: change the file, update
the seal in the same commit.

**When a document and the commit history disagree about what is allowed, the
history is the measurement.** Check it before treating a document as a gate --
and say which one you followed.

## 327. Three readings of my own new census, three wrong

`tri unparsed report` ranks the constructs that stop the compiler. Its first
three numbers were all wrong, and each was caught by asking a question the
output invited:

1. **118 specs "the compiler cannot read"** -- 21 of them are under
`fixtures/`, broken ON PURPOSE as inputs to a detector.
`tools/specs_generate_baseline.txt` already omits all 21. A census that
disagrees with the repository's own ledger is wrong before it is useful.
Now they get their own line rather than being dropped.
2. **"not decided" was 30 too large** -- the abstention listed only TOP-LEVEL
keywords, so a failing `return x;` or `let y = 1;` inside a body fell
through as undecided when it is plainly upstream.
3. **36 + 27 + 30 came to 93 against a total of 97** -- four rows were leaving
through a bare `continue` where the error named no readable line. Counted
now, and the arithmetic closes.

The rule that found all three: **make the printed numbers add up, out loud.**
A census whose parts do not sum to its total has a bucket you have not named.
8 changes: 4 additions & 4 deletions .trinity/seals/automation::wrapup.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"gen_hash_c": "none",
"gen_hash_rust": "none",
"gen_hash_verilog": "none",
"gen_hash_zig": "none",
"gen_hash_c": "sha256:ce7911d950a54065c04f7d5833e64c8656b200b285bc1c6afc750ff2855af24a",
"gen_hash_rust": "sha256:d9b107adfd304c6453f4efd8fe375e031233dcd1e13b02ea60f708feff82b6af",
"gen_hash_verilog": "sha256:84c34ae050c5d6e0b5eec9a7fcdd4b7d8a8ca61c56753fe6e7abb6c7007a0dda",
"gen_hash_zig": "sha256:33cb5ad0b90b063d7521cfccaed966b3376e70f2d28a10bfccb756ce6b7ddf86",
"module": "automation::wrapup",
"ring": 12,
"sealed_at": "2026-08-28T00:21:37Z",
Expand Down
13 changes: 7 additions & 6 deletions .trinity/seals/automation_automation::wrapup.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"gen_hash_c": "none",
"gen_hash_rust": "none",
"gen_hash_verilog": "none",
"gen_hash_zig": "none",
"gen_hash_c": "sha256:ce7911d950a54065c04f7d5833e64c8656b200b285bc1c6afc750ff2855af24a",
"gen_hash_rust": "sha256:d9b107adfd304c6453f4efd8fe375e031233dcd1e13b02ea60f708feff82b6af",
"gen_hash_verilog": "sha256:84c34ae050c5d6e0b5eec9a7fcdd4b7d8a8ca61c56753fe6e7abb6c7007a0dda",
"gen_hash_zig": "sha256:33cb5ad0b90b063d7521cfccaed966b3376e70f2d28a10bfccb756ce6b7ddf86",
"module": "automation::wrapup",
"ring": 12,
"sealed_at": "2026-08-28T00:21:37Z",
"sealed_at": "2026-08-29T20:30:37Z",
"sealed_by": "t27c-bootstrap@0.2.0",
"spec_hash": "sha256:ac2a7dd606abd2a289cfcf53e1362ad9e1d930066a8feaa18748f131db5971ca",
"spec_path": "specs/automation/wrapup-auto.t27"
}
}
8 changes: 4 additions & 4 deletions .trinity/seals/github::auth.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"gen_hash_c": "none",
"gen_hash_rust": "none",
"gen_hash_verilog": "none",
"gen_hash_zig": "none",
"gen_hash_c": "sha256:d61996eea454c66dec1c9a71f8d03bfeef54dd13eef251c2a9b23745e7f9c794",
"gen_hash_rust": "sha256:0c8b63c1529edd98bcc8e68f0ab775bd86b0c5a3d681dfda27ac0f8d1f38f165",
"gen_hash_verilog": "sha256:9327e54360dc57ae9a86132842c6aa9a5de2cfbd31d1c22525593dcc7dbfcfc4",
"gen_hash_zig": "sha256:1caa1683e55da970a531003f0e3a8bbe153a6a28131adf4466be276f64774eb2",
"module": "github::auth",
"ring": 12,
"sealed_at": "2026-08-28T00:22:25Z",
Expand Down
8 changes: 4 additions & 4 deletions .trinity/seals/github::comments.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"gen_hash_c": "none",
"gen_hash_rust": "none",
"gen_hash_verilog": "none",
"gen_hash_zig": "none",
"gen_hash_c": "sha256:0cdf800714cf243b5ab43b7725de3241382a329f2830ada2e2573cbc4fc0eff5",
"gen_hash_rust": "sha256:6426bd4276c663bf1bd07fadf7505105abe79a82a4d072a9b8d8d2cbb2391647",
"gen_hash_verilog": "sha256:6798d2cc2799c3328949f44d004a526409d7e0ddc368e8f6fc72eda5deca703e",
"gen_hash_zig": "sha256:ab668814038be68338558a21908b9d7b61382002e179f9337dc59dee2f344249",
"module": "github::comments",
"ring": 12,
"sealed_at": "2026-08-28T00:22:25Z",
Expand Down
8 changes: 4 additions & 4 deletions .trinity/seals/github::issues.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"gen_hash_c": "none",
"gen_hash_rust": "none",
"gen_hash_verilog": "none",
"gen_hash_zig": "none",
"gen_hash_c": "sha256:1903479f04739705d7b4a711bccd6aa081df49a25475d016e83a633e005f33a4",
"gen_hash_rust": "sha256:3ff56561e934319e4dc34969c5635b517143ba701a4dea07c8f272b5873f1a67",
"gen_hash_verilog": "sha256:fdce888391c35bccd7585512d9d3753d654af54a1e0118c3b94dff36a0b41094",
"gen_hash_zig": "sha256:a156482ac0af843d0e411702e16e4a1a1e844c21ccbd4d01b07c0a0fca216515",
"module": "github::issues",
"ring": 12,
"sealed_at": "2026-08-28T00:22:25Z",
Expand Down
8 changes: 4 additions & 4 deletions .trinity/seals/github::prs.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"gen_hash_c": "none",
"gen_hash_rust": "none",
"gen_hash_verilog": "none",
"gen_hash_zig": "none",
"gen_hash_c": "sha256:65b91c1216e41eb3d1d8b040a3ac6732e6e3f9ef13ac98d221b081a13f31e42a",
"gen_hash_rust": "sha256:3bc0749df78f07300bc0f1f1badb7ecec997a968068555106bb3df6bc337e7b0",
"gen_hash_verilog": "sha256:e98675e9c3f245707d48d1452980d65ad9ad9776e1823821a9d5e5df52965463",
"gen_hash_zig": "sha256:eb1721747e28fc0045ff612f4fa960ad3c044d0253e24aedeea3a3aea2a911d8",
"module": "github::prs",
"ring": 12,
"sealed_at": "2026-08-28T00:22:25Z",
Expand Down
8 changes: 4 additions & 4 deletions .trinity/seals/github::tests::e2e_full_flow.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"gen_hash_c": "none",
"gen_hash_rust": "none",
"gen_hash_verilog": "none",
"gen_hash_zig": "none",
"gen_hash_c": "sha256:0970c851fd35bc32976e4076cc67a582d9eadf54b60676c8cbab92859b4b7df2",
"gen_hash_rust": "sha256:0a3efa9f6b1b98d56f8b026a17df711b7ebad4d177bb1ae3cfa5a7aed1791661",
"gen_hash_verilog": "sha256:a5f40a1ce38a519d6f0b1be4bde6301b5943a15721445f4ad0b015fa8e298613",
"gen_hash_zig": "sha256:60a0f9bba9a5ad1c3161d13e8338e70fcf2d9a1b3573ddec4d833b617674cce4",
"module": "github::tests::e2e_full_flow",
"ring": 12,
"sealed_at": "2026-08-28T00:21:37Z",
Expand Down
13 changes: 7 additions & 6 deletions .trinity/seals/github_github::auth.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"gen_hash_c": "none",
"gen_hash_rust": "none",
"gen_hash_verilog": "none",
"gen_hash_zig": "none",
"gen_hash_c": "sha256:d61996eea454c66dec1c9a71f8d03bfeef54dd13eef251c2a9b23745e7f9c794",
"gen_hash_rust": "sha256:0c8b63c1529edd98bcc8e68f0ab775bd86b0c5a3d681dfda27ac0f8d1f38f165",
"gen_hash_verilog": "sha256:9327e54360dc57ae9a86132842c6aa9a5de2cfbd31d1c22525593dcc7dbfcfc4",
"gen_hash_zig": "sha256:1caa1683e55da970a531003f0e3a8bbe153a6a28131adf4466be276f64774eb2",
"module": "github::auth",
"ring": 12,
"sealed_at": "2026-08-28T00:22:25Z",
"sealed_at": "2026-08-29T20:30:37Z",
"sealed_by": "t27c-bootstrap@0.2.0",
"spec_hash": "sha256:4a02c3cd0fb34f6e9576d52e96910bc2937ffa3f921f315dd8887ec66f3776e5",
"spec_path": "specs/github/auth.t27"
}
}
13 changes: 7 additions & 6 deletions .trinity/seals/github_github::comments.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"gen_hash_c": "none",
"gen_hash_rust": "none",
"gen_hash_verilog": "none",
"gen_hash_zig": "none",
"gen_hash_c": "sha256:0cdf800714cf243b5ab43b7725de3241382a329f2830ada2e2573cbc4fc0eff5",
"gen_hash_rust": "sha256:6426bd4276c663bf1bd07fadf7505105abe79a82a4d072a9b8d8d2cbb2391647",
"gen_hash_verilog": "sha256:6798d2cc2799c3328949f44d004a526409d7e0ddc368e8f6fc72eda5deca703e",
"gen_hash_zig": "sha256:ab668814038be68338558a21908b9d7b61382002e179f9337dc59dee2f344249",
"module": "github::comments",
"ring": 12,
"sealed_at": "2026-08-28T00:22:25Z",
"sealed_at": "2026-08-29T20:30:37Z",
"sealed_by": "t27c-bootstrap@0.2.0",
"spec_hash": "sha256:7ea2370c5b1c69d599af13bb3956130320593d3aa72db524671aa7ac35e35604",
"spec_path": "specs/github/comments.t27"
}
}
13 changes: 7 additions & 6 deletions .trinity/seals/github_github::issues.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"gen_hash_c": "none",
"gen_hash_rust": "none",
"gen_hash_verilog": "none",
"gen_hash_zig": "none",
"gen_hash_c": "sha256:1903479f04739705d7b4a711bccd6aa081df49a25475d016e83a633e005f33a4",
"gen_hash_rust": "sha256:3ff56561e934319e4dc34969c5635b517143ba701a4dea07c8f272b5873f1a67",
"gen_hash_verilog": "sha256:fdce888391c35bccd7585512d9d3753d654af54a1e0118c3b94dff36a0b41094",
"gen_hash_zig": "sha256:a156482ac0af843d0e411702e16e4a1a1e844c21ccbd4d01b07c0a0fca216515",
"module": "github::issues",
"ring": 12,
"sealed_at": "2026-08-28T00:22:25Z",
"sealed_at": "2026-08-29T20:30:37Z",
"sealed_by": "t27c-bootstrap@0.2.0",
"spec_hash": "sha256:64d4d76ec19c214697c0f859f52391ebdd6f12947954308e51f49390b46d1ec4",
"spec_path": "specs/github/issues.t27"
}
}
13 changes: 7 additions & 6 deletions .trinity/seals/github_github::prs.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"gen_hash_c": "none",
"gen_hash_rust": "none",
"gen_hash_verilog": "none",
"gen_hash_zig": "none",
"gen_hash_c": "sha256:65b91c1216e41eb3d1d8b040a3ac6732e6e3f9ef13ac98d221b081a13f31e42a",
"gen_hash_rust": "sha256:3bc0749df78f07300bc0f1f1badb7ecec997a968068555106bb3df6bc337e7b0",
"gen_hash_verilog": "sha256:e98675e9c3f245707d48d1452980d65ad9ad9776e1823821a9d5e5df52965463",
"gen_hash_zig": "sha256:eb1721747e28fc0045ff612f4fa960ad3c044d0253e24aedeea3a3aea2a911d8",
"module": "github::prs",
"ring": 12,
"sealed_at": "2026-08-28T00:22:25Z",
"sealed_at": "2026-08-29T20:30:37Z",
"sealed_by": "t27c-bootstrap@0.2.0",
"spec_hash": "sha256:4e466319eaaca9d8dded516b01c4e044793adcf2dc0fd6b21baf29244e53b5f9",
"spec_path": "specs/github/prs.t27"
}
}
13 changes: 7 additions & 6 deletions .trinity/seals/tests_github::tests::e2e_full_flow.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"gen_hash_c": "none",
"gen_hash_rust": "none",
"gen_hash_verilog": "none",
"gen_hash_zig": "none",
"gen_hash_c": "sha256:0970c851fd35bc32976e4076cc67a582d9eadf54b60676c8cbab92859b4b7df2",
"gen_hash_rust": "sha256:0a3efa9f6b1b98d56f8b026a17df711b7ebad4d177bb1ae3cfa5a7aed1791661",
"gen_hash_verilog": "sha256:a5f40a1ce38a519d6f0b1be4bde6301b5943a15721445f4ad0b015fa8e298613",
"gen_hash_zig": "sha256:60a0f9bba9a5ad1c3161d13e8338e70fcf2d9a1b3573ddec4d833b617674cce4",
"module": "github::tests::e2e_full_flow",
"ring": 12,
"sealed_at": "2026-08-28T00:21:37Z",
"sealed_at": "2026-08-29T20:30:37Z",
"sealed_by": "t27c-bootstrap@0.2.0",
"spec_hash": "sha256:84a6ee5d56e617746da71f22a23e7c1db91639adfb29111a7ff4a84995d40569",
"spec_path": "specs/github/tests/e2e_full_flow.t27"
}
}
50 changes: 40 additions & 10 deletions bootstrap/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1546,17 +1546,47 @@ impl Parser {
// Module name can contain hyphens: e.g. "tritype-base"
let mut mod_name = String::new();
if self.current.kind == TokenKind::Ident {
mod_name.push_str(&self.current.lexeme);
self.advance();
// Consume hyphenated parts: - ident - ident ...
while self.current.kind == TokenKind::Minus {
mod_name.push('-');
self.advance(); // consume -
if self.current.kind == TokenKind::Ident
|| self.current.kind == TokenKind::Number
// A module name is one or more `::`-separated SEGMENTS, each of
// which may itself be hyphenated: `module tritype-base;`,
// `module github::issues { }`, `module a::b::c;`.
//
// The path form was read up to its first segment and no
// further, so `module github::auth {` left the parser looking
// at a colon at module level. Nine specs on master declare a
// path-qualified module and none of them parsed. The name is a
// NAME -- the repair is to read all of it, not to give `::` a
// meaning.
//
// BOTH colons are required before either is consumed. A single
// `:` after a module name is not a path, and swallowing it
// would turn a real error into a stranger one further down.
loop {
mod_name.push_str(&self.current.lexeme);
self.advance();
// Consume hyphenated parts: - ident - ident ...
while self.current.kind == TokenKind::Minus {
mod_name.push('-');
self.advance(); // consume -
if self.current.kind == TokenKind::Ident
|| self.current.kind == TokenKind::Number
{
mod_name.push_str(&self.current.lexeme);
self.advance();
}
}
if self.current.kind != TokenKind::Colon
|| self.peek.kind != TokenKind::Colon
{
mod_name.push_str(&self.current.lexeme);
self.advance();
break;
}
self.advance(); // consume first :
self.advance(); // consume second :
mod_name.push_str("::");
if self.current.kind != TokenKind::Ident {
// `module a::` with nothing after it. The name keeps the
// separator so the shape is visible rather than tidied
// away, and the caller meets the real token next.
break;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion bootstrap/stage0/FROZEN_HASH
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5958d7f24cb254e2149fb0c6ba265bfb11653ca1faef95f1f2bdbd4f7d49d35d
02ab350615e74f165346b62c205e6e34b6adcab73382fa2fd71280d50c5d9745
7 changes: 7 additions & 0 deletions cli/tri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod fleet;
mod fpga;
mod gates;
mod prose;
mod unparsed;
mod hooks;
mod mutate;
mod nownote;
Expand Down Expand Up @@ -170,6 +171,11 @@ enum Commands {
#[command(subcommand)]
action: prose::ProseCmd,
},
/// Specs the compiler cannot read, ranked by the construct that stops it.
Unparsed {
#[command(subcommand)]
action: unparsed::UnparsedCmd,
},
/// What `.trinity/seals` says about a spec, when it says it twice.
Seals {
#[command(subcommand)]
Expand Down Expand Up @@ -806,6 +812,7 @@ fn main() -> Result<()> {
Commands::Orphaned { action } => orphaned::run(action)?,
Commands::Discard { action } => discard::run(action)?,
Commands::Prose { action } => prose::run(action, std::env::current_dir()?)?,
Commands::Unparsed { action } => unparsed::run(action, std::env::current_dir()?)?,
Commands::Seals { action } => seals::run(action)?,
Commands::Hooks { action } => hooks::run(action)?,
}
Expand Down
Loading
Loading