Skip to content

ci(brain): the step named "Build TRI Binary" did not build one - #739

Open
gHashTag wants to merge 1 commit into
mainfrom
fix/brain-ci-builds-the-binary
Open

ci(brain): the step named "Build TRI Binary" did not build one#739
gHashTag wants to merge 1 commit into
mainfrom
fix/brain-ci-builds-the-binary

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

brain-ci.yml has failed 10 of its last 10 runs on main. A comment already in the file records that before that it reported Brain health 0 below 80 on all 47 of its runs. It has never once produced a measurement.

The health threshold was never the problem. There was never a health number to compare against it.

The cause

Five steps named "Build TRI Binary" ran zig build tri -Dci=true. That target does not build anything installable — build.zig says so:

const tri_step = b.step("tri", "Run TRI - Unified Trinity CLI");
tri_step.dependOn(&run_tri.step);

The step runs the CLI. b.installArtifact(tri) hangs off the install step, which this target never reaches, so the executable is compiled into the cache and never copied to zig-out/bin. Every later step then found nothing:

./zig-out/bin/tri: No such file or directory
tri: command not found
::error::No health score was produced

A step named for building that instead runs is the same shape as the defects this repo has been clearing all fortnight: the name asserts one thing, the command does another, and the red that follows gets attributed to the subject rather than to the step.

The knowledge was already in the repo

tri-build.yml, one file over, carries:

# 'zig build tri' is a RUN step, so using it as the build gate conflated
# "does it compile" with "does it work"

Written for that gate, never propagated to this one. That is worth more attention than the fix: the fortnight's lesson keeps being learned per-file.

The change

zig build install -Dci=true in all five steps, plus an explicit check:

test -x ./zig-out/bin/tri || {
  echo "::error::zig build install produced no ./zig-out/bin/tri"
  exit 1
}

so the failure lands on the step that was supposed to produce the binary, not three steps later as a missing score. A gate that cannot obtain its instrument should name the step that failed to hand it over.

Unverified here

Whether tri stress --health then produces a score above the threshold. It has never run against a real binary, so its output is genuinely unknown — this PR is what makes that question askable, not what answers it. If the score comes back below 80, that is a real finding about the brain and the first one this gate will have ever delivered.

Five steps in this workflow ran `zig build tri -Dci=true` under that name. That
target does not build anything installable. build.zig says so plainly:

    const tri_step = b.step("tri", "Run TRI - Unified Trinity CLI");
    tri_step.dependOn(&run_tri.step);

The step RUNS the CLI. `b.installArtifact(tri)` hangs off the install step,
which this target never reaches, so the executable is compiled into the cache
and never copied to zig-out/bin. Every later step then found no binary:

    ./zig-out/bin/tri: No such file or directory
    tri: command not found
    ::error::No health score was produced

brain-ci.yml has failed 10 of its last 10 runs on main, and a comment already in
the file records that it reported "Brain health 0 below 80" on all 47 runs before
that. It has never once produced a measurement. The health threshold was never
the problem; there was never a health number to compare against it.

The fact was already written down one workflow over. tri-build.yml carries:

    # 'zig build tri' is a RUN step, so using it as the build gate conflated
    # "does it compile" with "does it work"

That note was written for one gate and never reached this one.

Now `zig build install -Dci=true`, plus an explicit `test -x ./zig-out/bin/tri`
that fails at the step that is supposed to produce the binary, rather than three
steps later as a mysterious missing score. A gate that cannot obtain its
instrument should say which step failed to hand it over.
@gHashTag gHashTag closed this Aug 26, 2026
@gHashTag gHashTag reopened this Aug 26, 2026
@gHashTag

gHashTag commented Sep 6, 2026

Copy link
Copy Markdown
Owner Author

This may now be mergeable, and it may fix two of the four permanently-red checks. It needs a rebase to find out.

Found while auditing CI gates from a different angle (#750, #751, #752). Not acting on this PR — it is yours and I have not touched it — but the state has changed underneath it since 2026-08-26.

The diagnosis here is right

zig build tri really does run the CLI rather than install it:

const tri_step = b.step("tri", "Run TRI - Unified Trinity CLI");
tri_step.dependOn(&run_tri.step);

b.installArtifact(tri) hangs off the install step, which tri never reaches. So the executable is compiled into the cache and never copied to zig-out/bin. A step named "Build TRI Binary" that does not build one.

But the fix was insufficient at the time, and the log shows why

The run on this branch is from 2026-08-26. Its failure chain is three deep:

::error::zig build install produced no ./zig-out/bin/tri   ← your own guard fired
tri: command not found                                      ← fallback to PATH
error: NotImplemented

So zig build install -Dci=true did not produce the binary either. Your guard is what makes that visible instead of a mystery health score three steps later — that part worked exactly as designed.

What changed since

Validate VIBEE Codegen runs zig build -Dci=true, which includes the install step, and it is green on current main (f32467d4f onward). Several things landed between 08-26 and now that touch exactly this: the Zig 0.16 migration guards in build.zig (#745, #746, #747, #749) removed targets that could not compile under CI's 0.15.2 toolchain.

That makes it plausible — not certain — that zig build install -Dci=true now produces zig-out/bin/tri, and therefore that this PR would go green.

Why this matters beyond the PR

⚡ Brain Health Check and 📋 Brain Health Report are two of the four checks I have been treating as "red on main regardless" all night, and skipping past on every PR. If the missing binary is their cause, this PR does not merely unblock itself — it removes two of the four, and a whole class of "that check is always red" reasoning goes with them.

The cheap way to find out

Rebase onto current main and let CI answer:

git fetch origin main && git rebase origin/main && git push --force-with-lease

I did not do this myself: rebasing and force-pushing someone else's branch is a real action on your work, and a re-run alone would not help — it would replay the same 11-day-old tree, since a re-run uses the commit's own build.zig, not main's.

If it goes green, withdrawn-live already passes on this branch, which would leave orphan-artefacts as the only permanently-red check on the repo.

gHashTag added a commit that referenced this pull request Sep 6, 2026
…een gate

#752 merged. Then, auditing from a different angle, found PR #739 -- open since
2026-08-26, +43/-5, the operator's own -- and it diagnoses why two of the four
checks this loop has skipped past all session are red.

`zig build tri` RUNS the CLI rather than installing it: build.zig declares
tri_step.dependOn(&run_tri.step), while b.installArtifact(tri) hangs off the
install step that target never reaches. A step named "Build TRI Binary" that
builds no binary, and Brain Health then reports a missing measurement.

Its fix was insufficient AT THE TIME -- the 08-26 log shows the guard firing,
then "tri: command not found", then "error: NotImplemented", three deep. But that
run predates this session. Validate VIBEE Codegen runs `zig build -Dci=true`,
which includes install, and is green on current main now that #745/#746/#747/#749
guarded the targets that could not compile under 0.15.2. So it plausibly works
now. Only a rebase can say; a re-run replays the commit's own build.zig.

Not acted on -- rebasing and force-pushing someone else's branch is a real action
on their work. Posted the diagnosis and the one command instead.

A38 is the uncomfortable part. This loop has repeated "four checks are red on
main regardless, ignore them" on every PR tonight, and wrote it into the
ci-gates skill as settled fact. It was never investigated. The phrase
"pre-existing failure" functioned exactly like a green gate: it made a red signal
safe to skip without looking, and every merge tonight was checked against that
list, so the reasoning was load-bearing.

Five iterations spent finding gates that pass without measuring, while routing
around four that fail without being diagnosed. Both are signals nobody reads.
"Pre-existing" describes when a problem started; it is never a reason it is
acceptable.
gHashTag added a commit that referenced this pull request Sep 6, 2026
A38's follow-through. I criticised this loop for never investigating the four
red checks it skipped past on every PR; the fix was to investigate them. It took
one command, after five iterations of not asking.

All four have causes, and they fall into two categories that had been conflated:

INFRASTRUCTURE, fixable by anyone --
  Brain Health Check and Brain Health Report both fail because `zig build tri`
  RUNS the CLI instead of installing it, so zig-out/bin/tri never exists and the
  health step has nothing to measure. Candidate fix open in #739; needs a rebase
  to retest against a tree where `zig build -Dci=true` is green.

CLAIMS ABOUT THE PAPER, the author's to settle --
  withdrawn-live flags 2 numbers that are NOT alike. 0.1797 sits in a \textbf{}
  cell of a live results table (line 4729) -- a real assertion of a withdrawn
  number. 0.92 appears in "The ratios an earlier draft reported --- 0.92x, 2.84x,
  5.53x --- were the unfilled M=9 rung" (line 1013), which withdraws the number
  in substance while failing the gate's syntactic test,
  `(is|are|was|were)\s+(withdrawn|retracted)`.

  orphan-artefacts reports 13 measurement JSONs under
  research/arxiv_tnf/measurements/ with no generator script. The gate's own
  output says the count "has stood for weeks".

Nothing changed in the paper. Whether 0.1797 should be 0.180/0.181, and whether
that 0.92 sentence counts as a withdrawal under this paper's conventions, are
judgements about a research claim -- not something to settle from a regex verdict
at 04:00.

A39: a gate reporting N failures may be reporting N different KINDS. These two
need two different owners -- one a content fix, one a classification call -- and
bundling them under one red is part of why neither got made. The checker's own
docstring shows its author already fought this battle once, over 0.1173 in a
caption, so the pattern has a history of being too syntactic.

ci-gates skill corrected. It previously listed the four as "red on main and not
yours", which is the sentence that taught the habit. Now a table naming each
cause and its owner, plus a section on reading run history before assuming a new
red is a regression -- a workflow that watches itself fires when you edit it, and
a job dormant for months may be broken independently of your change.
gHashTag added a commit that referenced this pull request Sep 6, 2026
Corrected by re-measuring a claim I had already made twice. The query used
`gh run list --branch main --limit 40`. Forty RUNS does not reach back far enough
to contain one run of every workflow, so a workflow that last fired hours earlier
falls out of the window entirely, contributes nothing to the group-by, and reads
as ABSENT rather than as red.

At --limit 200, main carries FIVE red checks:

  FPGA Docker Build                    B28, needs a decision
  AX7203 Format Cost Ablation          0 successes in 6 runs, ever
  Orphaned artefacts                   13 measurement JSONs, no generator
  S3AI Brain CI                        #739's candidate fix awaits a rebase
  Withdrawn numbers                    0.1797 real; 0.92 a classification artifact

One of the five is mine. #753 closed the paths auditor's blind spot, which
correctly reported that ax7203-format-cost.yml synthesises gf_adder_param.v and
gf_mul_param.v while watching only its own .yml -- so I gave it those watches. It
now fires and fails. It had never succeeded in 6 runs, so the change made a
broken thing visible rather than breaking it; that was the intended trade, and it
still belongs in the count I gave.

The underlying work stands: the four diagnoses hold, and fpga-bitstream really
did pass for the first time in its existence. But the summary line was false, and
a summary line is the part most likely to be read.

The shape is one this loop already knows: a count that shrinks because the
instrument could not see far enough looks exactly like progress. Same family as
counting a defect with a grep that cannot reach the whole corpus. The denominator
for CI health is WORKFLOWS, not recent runs.
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.

1 participant