Skip to content

fix(brain-ci): tri stress --health measures 17 brain probes instead of a stub - #1328

Merged
gHashTag merged 4 commits into
mainfrom
fix/brain-ci-health-gate
Oct 4, 2026
Merged

gHashTag merged 4 commits into
mainfrom
fix/brain-ci-health-gate

Conversation

@gHashTag

@gHashTag gHashTag commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

Closes #1326

What was wrong

brain-ci.yml → ⚡ Brain Health Check runs ./zig-out/bin/tri stress --health. That command was a stub. It printed stress-test: ... not implemented yet and no Score: line, so the step correctly said brain health was NOT MEASURED and exited 1, and 📋 Brain Health Report went red with it. The last 100 brain-ci runs all failed this way.

#957 kept the job failing on purpose, because an unimplemented health check is a real deficiency. This PR does not relax that gate. It gives the gate something real to measure.

Option (a): tri stress --health now measures something

I chose option (a): implement the command honestly. Option (b), a neutral "not measured" outcome, was not needed, because the three brain regions already linked into tri have a contract that can be checked in about a second.

What the score is. src/tri/brain_health.zig runs 17 probes. Each probe checks one behavioural claim and prints it next to its PASS/FAIL row:

region probes
basal_ganglia (8) claim-free-task, refuse-second-claimant, heartbeat-owner-only, complete-releases, abandon-releases, ttl-expiry, shard-accounting, one-winner-per-task (8 threads race for 16 tasks)
reticular_formation (5) owns-published-strings, fifo-order, since-filter, limit-after-filter, bounded-ring
locus_coeruleus (4) exponential-doubling, capped-and-monotone, linear-and-constant, jitter-bounds
  • Score = 100 * passed / total. It is printed as exactly one plain-ASCII line, Score: <n.n>/100 (<passed> of <total> probes passed), then Status: HEALTHY (all passed) or Status: UNHEALTHY.
  • The command exits 1 if any probe fails.
  • Every probe uses fresh private instances (never getGlobal) and its own DebugAllocator. A leak fails the probe.
  • There are no constants in the score. It is the count of probes that passed. The negative controls below show that it moves.
  • Not covered, and the output says so: other src/brain regions, which are not linked into tri; and load or soak behaviour.
  • The same explanation is in the doc comment of brain_health.zig and in the workflow step.

Output from the CI build (zig build -Dci=true, zig 0.15.2):

  PASS  reticular_formation  limit-after-filter      max_events caps the events that pass the since filter, not the events scanned
  ...
Passed: 17/17 probes (basal_ganglia 8/8, reticular_formation 5/5, locus_coeruleus 4/4)
Not covered: other src/brain regions (not linked into tri); load and soak behaviour.
Score: 100.0/100 (17 of 17 probes passed)
Status: HEALTHY

A real bug the probes found: EventBus.poll

poll(since, a, max_events) scanned only the first max_events buffered events and then applied the since filter. With 3 old events and 2 new ones, poll(boundary, a, 1) returned 0 events instead of 1. The scan now covers the whole buffer and stops once max_events events have passed the filter, which is what the doc comment already promised. A new module test pins this: it fails on the old code (expected 1, found 0) and passes on the new code. poll(0, a, n) behaves as before.

Workflow step (health parser only)

  • The score is read as the number directly after Score: on the first Score: line, integer or decimal. The old parser took the first number anywhere on the line, so a colour escape ESC[32m before Score: read as 32.
  • HEALTHY now matches the whole line Status: HEALTHY. The old grep -q "HEALTHY" also matched UNHEALTHY.
  • A run above the threshold with failed probes now gets a ::warning:: annotation instead of passing silently.
  • Unchanged from fix(ci): brain-ci reported an unmeasured value as a score of zero #957: the not-measured and unparseable branches, the threshold of 80, and || true.
  • Token permissions. The repository default GITHUB_TOKEN is read-only and brain-ci.yml had no permissions: block. On the first PR run where the health check passed (run 37176287100), the job failed at Comment Health on PR with 403 Resource not accessible by integration. The stress comment and Critical State Notification have the same problem. Nobody saw it before, because those steps were skipped once the health check failed. The workflow now grants contents: read and pull-requests: write.

Threshold semantics, stated plainly. There are 17 probes, so one failure scores 94.1 and three score 82.4. Both pass this step's threshold of 80, with a warning. Four failures score 76.5 and fail the step. The CLI Smoke Test runs tri stress --health without || true and fails on any failed probe, but it only runs after brain-unit, brain-integration and brain-stress succeed, and they cannot today (see below).

Verification

This is the health step's own run: script, extracted verbatim from the workflow at the base commit (old) and in this PR (new). It runs under bash -e with GNU sed, as on ubuntu-latest, with tri stubbed to print each input:

tri output fed to the step tri exit old: score / HEALTHY / step new: score / HEALTHY / step new step annotations
real tri output, 17/17 0 100.0 / true / pass 100.0 / true / pass -
real probes, poll bug restored (16/17) 1 94.1 / true / pass 94.1 / false / pass warning: at least one probe failed
real probes, backoff cap removed (14/17) 1 82.4 / true / pass 82.4 / false / pass warning: at least one probe failed
synthetic failing score 41.2 1 41.2 / true / FAIL 41.2 / false / FAIL warning + error: Brain health 41.2 below threshold 80
synthetic 76.5 (13 of 17) 1 76.5 / true / FAIL 76.5 / false / FAIL warning + error: Brain health 76.5 below threshold 80
boundary 80.0 1 80.0 / true / pass 80.0 / false / pass warning: at least one probe failed
integer score 92 0 92 / true / pass 92 / true / pass -
unparseable Score: n/a 0 (empty) / unknown / FAIL (empty) / unknown / FAIL error: a 'Score:' line was present but carried no number
no Score line (old stub output) 0 (empty) / unknown / FAIL (empty) / unknown / FAIL error: brain health was NOT MEASURED
ANSI colour before Score: 1 32 / true / FAIL 94.1 / false / pass warning: at least one probe failed

The old column also shows the HEALTHY bug: every run with a Status line reported true.

Negative controls. Each row is the probes built against a mutated copy of one region; every one exits 1 with Status: UNHEALTHY:

mutation Score probes that failed
basal_ganglia: live-claim check disabled (if (false and existing.isValid())) 88.2 refuse-second-claimant; one-winner-per-task (task race-0 had 8 winners, want exactly 1)
locus_coeruleus: max_ms cap removed 82.4 capped-and-monotone; linear-and-constant; jitter-bounds
reticular_formation: old poll restored 94.1 limit-after-filter (returned 0 events, want 1)
reticular_formation: aux_string copy leaked 94.1 owns-published-strings (leak)

On GitHub Actions (ubuntu-latest):

  • Push run 37176194113: ⚡ Brain Health Check passed, logging Score: 100.0/100 (17 of 17 probes passed) and Status: HEALTHY. None of the previous 100 brain-ci runs got past this step.
  • PR run 37176287100: the health step passed with the same score. The job then failed at Comment Health on PR with a 403. That is fixed in 9097fc9: in PR run 37176676345 every step of the job passes and the health comment is posted. 📋 Brain Health Report now fails only in its aggregator step, because of the Unit Tests below. Its Critical State Notification posts instead of returning 403. That notification is headed "Brain Health Below Threshold" even when the health score is 100: pre-existing wording, left alone.

Other checks:

  • zig build -Dci=true (zig 0.15.2): exit 0, 1m58s.
  • ./zig-out/bin/tri stress --health: 17/17, exit 0, on 20 of 20 repeated runs. The standalone probe binary also passed 100 of 100 runs.
  • Module tests: zig test reticular_formation 48/48, basal_ganglia 51/51, locus_coeruleus 52/52.
  • zig fmt --check is clean on every touched file.
  • actionlint: 48 findings before and 48 after (44 SC2086 and 4 SC2129, all info/style, all pre-existing), none new.

State of the other brain-ci phases (separate failures, not fixed here)

  • 🧠 Unit Tests, 🔗 Integration and 🧪 Stress Test fail on their own. They run zig build test-basal-ganglia, test-reticular-formation, test-locus-coeruleus, test-intraparietal, test-hslm, test-brain and test-brain-stress. None of those steps exists:

    • zig build test-basal-ganglia -Dci=true → no step named 'test-basal-ganglia'.
    • They were removed from build.zig in 42490a2 (refactor: remove 4425 lines of migrated duplicates #517, 2026-04-19).
    • hslm moved to gHashTag/trinity-training.
    • src/brain/intraparietal_sulcus.zig does not compile standalone (undeclared hslm, u16/f32 type errors).

    Until now these jobs were skipped because the health check failed first. After this PR the health check passes, Unit Tests runs and fails, and the workflow and the Report job stay red for that separate, real reason. I am not papering over it.

  • 💨 CLI Smoke is skipped behind that chain. When it runs, tri stress --scan passes vacuously: it prints a not-implemented notice and exits 0.

  • 🧪 Stress Test parser still turns "no Score: line" into 0 (|| echo "0"), the same class fix(ci): brain-ci reported an unmeasured value as a score of zero #957 fixed for the health step. Its grep -oE "[0-9]+" also yields several numbers for a 270/300 line.

  • 📊 Export Metrics succeeds, but tri stress --metrics only prints the notice.

  • 🔨 Build Check passes. 🔒 Merge Gate runs on PRs only.

  • pr-opened (project-auto-status.yml) fails on this PR with gh: Bad credentials (HTTP 401). It has failed the same way on every recent PR: it is a repository token secret, not this change.

Limitations

  • The score covers only the three regions linked into tri. It is a functional self-check, not a load test.
  • The threshold of 80 lets up to 3 of 17 failed probes through the health step, with a warning. Strict all-pass enforcement lives in CLI Smoke, which cannot run until the missing build steps are restored.
  • A PR from a fork still gets a read-only token, so the PR-comment steps will 403 there.
  • poll still holds its mutex if initCapacity fails with OOM. That is pre-existing, out of scope, and the _opt and _lockfree copies, which are not linked into tri, were not touched.
{
  "version": 1,
  "head_sha": "9097fc9c49288aecba28d24a22a30e7b918d5245",
  "summary": "tri stress --health was a stub, so the brain-ci health gate failed on every run as not measured. It now runs 17 behavioural probes over basal_ganglia, reticular_formation and locus_coeruleus and reports Score as the passed fraction; the probes found and this PR fixes a real EventBus.poll bug.",
  "changes": [
    "New src/tri/brain_health.zig: 17 probes on fresh private instances, each on a leak-checking allocator, printing Score: n/100 as 100 * passed / total and exiting 1 on any failure.",
    "src/tri/tri_commands.zig: tri stress --health dispatches to the probes; the other stress modes still print a not-implemented notice.",
    "src/brain/reticular_formation.zig: EventBus.poll applies max_events after the since filter instead of to the first events scanned, with a module test that fails on the old code.",
    "brain-ci.yml health step reads only the number right after Score:, matches the whole Status: HEALTHY line, and annotates a passing run that had failed probes.",
    "brain-ci.yml grants contents: read and pull-requests: write, because its PR-comment steps failed with 403 under the read-only default token."
  ],
  "tests": [
    {
      "command": "zig build -Dci=true (zig 0.15.2)",
      "result": "Build finished with exit 0 in 1m58s and installed zig-out/bin/tri.",
      "status": "passed",
      "evidence": "ls -la zig-out/bin/tri shows the 35 MB binary; the zig sources are unchanged since 3a2717083."
    },
    {
      "command": "GitHub Actions brain-ci push run 37176194113 and PR run 37176287100, Brain Health Check job",
      "result": "Health step passed on both runs with Score: 100.0/100 and Status: HEALTHY on ubuntu-latest.",
      "status": "passed",
      "evidence": "Job logs; the PR run then hit a 403 in Comment Health on PR, fixed by the permissions block."
    },
    {
      "command": "./zig-out/bin/tri stress --health",
      "result": "17 of 17 probes passed, Score: 100.0/100, Status: HEALTHY, exit 0 on 20 of 20 runs.",
      "status": "passed",
      "evidence": "Probe rows and the Score and Status lines are quoted in the PR description."
    },
    {
      "command": "probes rebuilt against four mutated region sources (live-claim check, backoff cap, old poll, leaked string)",
      "result": "Every mutation exits 1 as UNHEALTHY with scores 88.2, 82.4, 94.1 and 94.1.",
      "status": "passed",
      "evidence": "Negative-control table in the PR description names the failing probe and its message."
    },
    {
      "command": "zig test src/brain/reticular_formation.zig, basal_ganglia.zig, locus_coeruleus.zig",
      "result": "48/48, 51/51 and 52/52 tests pass; the new poll test fails on the base code with expected 1, found 0.",
      "status": "passed",
      "evidence": "zig test summary lines; the base file with the new test reports 47 passed, 1 failed."
    },
    {
      "command": "health step run script, base vs head, over 10 inputs under bash -e with GNU sed",
      "result": "Score parsing, HEALTHY detection and the not-measured branches behave as in the verification table.",
      "status": "passed",
      "evidence": "Verification table in the PR description; the ANSI row reads 94.1 now and 32 on the base."
    },
    {
      "command": "actionlint .github/workflows/brain-ci.yml",
      "result": "48 findings on both base and head, all info or style shellcheck notes, none introduced here.",
      "status": "passed",
      "evidence": "44 SC2086 and 4 SC2129 on both versions of the file."
    },
    {
      "command": "zig build test-basal-ganglia -Dci=true",
      "result": "Fails with no step named test-basal-ganglia; the brain test steps left build.zig in #517.",
      "status": "failed",
      "evidence": "Unit, Integration and Stress jobs will now run and fail on this separate pre-existing cause."
    }
  ],
  "limitations": [
    "The score covers only the three brain regions linked into tri; other src/brain regions and load or soak behaviour are not measured.",
    "The threshold of 80 lets up to 3 of 17 failed probes pass the health step with a warning; all-pass is enforced only by CLI Smoke.",
    "Brain CI stays red after this PR because Unit, Integration and Stress call build steps that were removed in #517."
  ],
  "tags": ["brain_ci", "zig", "health_check", "honest_metrics"],
  "blog": {
    "title": "A health check that finally measures something, and finds a bug",
    "summary": "The brain CI gate failed on every run because tri stress --health was never implemented. Seventeen behavioural probes now produce the score, and on their first run one of them caught a real EventBus.poll bug.",
    "outline": [
      "Why the gate was red: the command printed a not-implemented notice and no Score line, and #957 rightly refused to turn that absence into a zero.",
      "What the score is: 100 times the passed fraction of 17 named probes over basal_ganglia, reticular_formation and locus_coeruleus, each on fresh instances and a leak-checking allocator.",
      "The bug the probes caught: EventBus.poll applied max_events before the since filter, so a limited poll after old events returned nothing.",
      "Two parser bugs in the workflow step: an ANSI escape read as a score of 32, and grep HEALTHY also matched UNHEALTHY, so every run looked healthy.",
      "What stays red and why: the unit, integration and stress jobs call build steps that were deleted in April, which is now visible instead of hidden behind a cascade."
    ]
  }
}

🤖 Generated with Claude Code

gHashTag and others added 3 commits October 4, 2026 10:47
poll(since, allocator, max_events) scanned only the first max_events
buffered events and then filtered them by `since`. Whenever those oldest
events were at or before `since`, it returned nothing even though newer
events matched: with three old events and two new ones,
poll(boundary, a, 1) returned 0 events instead of 1.

The scan now walks the whole buffer and stops once max_events events
have passed the filter, which is what the doc comment already promised
("Returns events with timestamp > since ... Limited by max_events").
poll(0, a, n) is unchanged.

Found by the new `tri stress --health` probe limit-after-filter. A module
test pins it: it fails on the old code (0 events) and passes on this one.

Refs #1326

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`tri stress --health` was a stub that printed "not implemented yet" and
no Score: line, so the brain-ci Brain Health Check failed on every run
as "not measured".

It now runs 17 probes against the three brain regions linked into tri:
basal_ganglia (8: claim, refuse, heartbeat, complete, abandon, TTL
expiry, shard accounting, an 8-thread one-winner-per-task race),
reticular_formation (5: string ownership, FIFO order, since filter,
limit-after-filter, bounded ring) and locus_coeruleus (4: exponential,
capped and monotone, linear and constant, jitter bounds).

Each probe uses fresh private instances (never the process globals) and
its own leak-checking allocator; a leak fails the probe. The output
lists every probe as PASS or FAIL with its claim, then one plain-ASCII
line

  Score: <n.n>/100 (<passed> of <total> probes passed)

where n = 100 * passed / total, then "Status: HEALTHY" or
"Status: UNHEALTHY". The command exits 1 if any probe failed. Nothing
in the score is a constant: removing the basal_ganglia live-claim check,
the locus_coeruleus cap or the poll fix drops it to 88.2, 82.4 and 94.1.

Not covered: other src/brain regions (not linked into tri), load and
soak behaviour. The other stress modes still only print a notice.

Refs #1326

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Brain Health Check parsed the first number anywhere on the Score:
line, so a colour escape such as ESC[32m before "Score:" read as 32.
It now reads only the number directly after "Score:" on the first
Score: line, integer or decimal.

The HEALTHY check used `grep -q "HEALTHY"`, which also matches
"UNHEALTHY", so every run with a Status line reported healthy. It now
matches the whole line "Status: HEALTHY".

A run above the threshold with failed probes now gets a warning
annotation instead of passing silently. The threshold (80), the
not-measured and unparseable branches, and `|| true` are unchanged.

The comment block describes what the score measures and states that the
CLI Smoke Test, which fails on any failed probe, only runs after
brain-unit, brain-integration and brain-stress succeed.

Closes #1326

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the status:in-progress 🔵 Agent working label Oct 4, 2026
The repository default GITHUB_TOKEN is read-only and brain-ci.yml had no
permissions block, so "Comment Health on PR" failed with 403 "Resource
not accessible by integration" on the first PR run where the health
check passed (run 37176287100). The same applies to the stress comment
and the Critical State Notification. Those steps were unreachable while
the health check failed first.

Grant contents: read and pull-requests: write at workflow level. A PR
from a fork still receives a read-only token.

Refs #1326

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

X Brain Health Check

Score: 100.0/100
Status: 🟢 HEALTHY
Threshold: 80/100

X Brain is above merge threshold

@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

🚨 CRITICAL: Brain Health Below Threshold

The brain health CI gate has failed. This PR cannot be merged until:

  1. All brain region unit tests pass
  2. Integration tests pass
  3. Stress test score >= 270/300
  4. Brain health score >= 80/100

Please review the failed job logs and fix the issues.

@gHashTag
gHashTag merged commit 292d827 into main Oct 4, 2026
30 of 43 checks passed
@github-actions github-actions Bot added status:completed Done and removed status:in-progress 🔵 Agent working labels Oct 4, 2026
gHashTag added a commit that referenced this pull request Oct 4, 2026
The gate needed brain-health-report without always(), so whenever the
report failed the gate was skipped. A skipped check renders grey, not
red: on #1328 (run 37176676345) the report failed and the Merge Gate
showed skipped. With always() the gate runs and its existing check
fails it for any report result other than success.

Refs #1331

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag added a commit that referenced this pull request Oct 4, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag added a commit that referenced this pull request Oct 4, 2026
#1328 landed on main as 292d827. This branch carried its four original
commits; the merge is clean and the diff against main now holds only the
#1331 change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag added a commit that referenced this pull request Oct 4, 2026
main moved by 20+ commits since 8a8f0d7 (providers tab #1302, brain health
#1328, FPGA recordings #1329, blog #1309). Clean merge. check:queen-runners,
queen-spec-sync, queen-contrast and queen-languages pass on the merged tree;
check:queen-honesty fails 3 on inputs byte-identical to main (Queen.tsx,
QueenCombBabylon.tsx), so that is main's state, not this branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag added a commit that referenced this pull request Oct 4, 2026
… that test nothing (#1333)

* fix(brain): EventBus.poll applies max_events after the since filter

poll(since, allocator, max_events) scanned only the first max_events
buffered events and then filtered them by `since`. Whenever those oldest
events were at or before `since`, it returned nothing even though newer
events matched: with three old events and two new ones,
poll(boundary, a, 1) returned 0 events instead of 1.

The scan now walks the whole buffer and stops once max_events events
have passed the filter, which is what the doc comment already promised
("Returns events with timestamp > since ... Limited by max_events").
poll(0, a, n) is unchanged.

Found by the new `tri stress --health` probe limit-after-filter. A module
test pins it: it fails on the old code (0 events) and passes on this one.

Refs #1326

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(tri): tri stress --health runs brain self-check probes

`tri stress --health` was a stub that printed "not implemented yet" and
no Score: line, so the brain-ci Brain Health Check failed on every run
as "not measured".

It now runs 17 probes against the three brain regions linked into tri:
basal_ganglia (8: claim, refuse, heartbeat, complete, abandon, TTL
expiry, shard accounting, an 8-thread one-winner-per-task race),
reticular_formation (5: string ownership, FIFO order, since filter,
limit-after-filter, bounded ring) and locus_coeruleus (4: exponential,
capped and monotone, linear and constant, jitter bounds).

Each probe uses fresh private instances (never the process globals) and
its own leak-checking allocator; a leak fails the probe. The output
lists every probe as PASS or FAIL with its claim, then one plain-ASCII
line

  Score: <n.n>/100 (<passed> of <total> probes passed)

where n = 100 * passed / total, then "Status: HEALTHY" or
"Status: UNHEALTHY". The command exits 1 if any probe failed. Nothing
in the score is a constant: removing the basal_ganglia live-claim check,
the locus_coeruleus cap or the poll fix drops it to 88.2, 82.4 and 94.1.

Not covered: other src/brain regions (not linked into tri), load and
soak behaviour. The other stress modes still only print a notice.

Refs #1326

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ci): brain health step reads the number right after Score:

The Brain Health Check parsed the first number anywhere on the Score:
line, so a colour escape such as ESC[32m before "Score:" read as 32.
It now reads only the number directly after "Score:" on the first
Score: line, integer or decimal.

The HEALTHY check used `grep -q "HEALTHY"`, which also matches
"UNHEALTHY", so every run with a Status line reported healthy. It now
matches the whole line "Status: HEALTHY".

A run above the threshold with failed probes now gets a warning
annotation instead of passing silently. The threshold (80), the
not-measured and unparseable branches, and `|| true` are unchanged.

The comment block describes what the score measures and states that the
CLI Smoke Test, which fails on any failed probe, only runs after
brain-unit, brain-integration and brain-stress succeed.

Closes #1326

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ci): grant brain-ci the token permission its PR comments need

The repository default GITHUB_TOKEN is read-only and brain-ci.yml had no
permissions block, so "Comment Health on PR" failed with 403 "Resource
not accessible by integration" on the first PR run where the health
check passed (run 37176287100). The same applies to the stress comment
and the Critical State Notification. Those steps were unreachable while
the health check failed first.

Grant contents: read and pull-requests: write at workflow level. A PR
from a fork still receives a read-only token.

Refs #1326

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(brain): stress_test reads claims through the sharded registry

stress_test.zig still read `registry.claims`, the single map the registry
had before it was split into 16 shards, so the file stopped compiling
(13 errors) and test-brain-stress could not run. Count with
Registry.count() and look a claim up in the one shard
Registry.getShardIndex names, under that shard's read lock. The tests
themselves are unchanged: 261/261 pass on zig 0.15.2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(brain): metrics_dashboard deinit and overwrite no longer corrupt or leak

Restoring test-brain ran the dashboard's own tests for the first time in
months (integration_test.zig imports the file by path). They found:

- RegionMetrics.deinit freed the alert through raw_metrics.allocator
  after raw_metrics.deinit() had set the map to undefined: a segfault at
  0xaaaa... whenever a region carried an alert. Read the allocator first.
- setMetric/setMetricOwned on an existing key leaked the new key copy and
  the replaced value, because HashMap.put keeps the stored key. Copy the
  key only on first insert and free the replaced value.
- Five tests leaked memory they owned (the singletons collect() creates,
  buffers setMetric copies) and one asserted a 23-byte prefix of a name
  formatAscii truncates to 20 bytes. The assertions now match the code.

test-brain: 151/151 pass, no leaks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(build): restore the brain test steps brain-ci calls

#517 (42490a2) removed test-basal-ganglia, test-reticular-formation,
test-locus-coeruleus, test-brain and test-brain-stress from build.zig while
brain-ci.yml kept calling them, so every Unit Tests leg failed with "no
step named ..." and nothing behind it ran. Point the steps back at the
source files, which were never removed.

Not restored: test-intraparietal (intraparietal_sulcus.zig is stubs around
the hslm library that left this repo and does not compile) and test-hslm
(hslm is tested in gHashTag/trinity-training; no such step ever existed).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ci): brain-ci runs only steps that exist and measure something

- Unit Tests: basal-ganglia, reticular-formation, locus-coeruleus only;
  intraparietal and hslm dropped with the reason in the file.
- Stress: pipefail-safe exit code plus zig's own "N/M tests passed"
  count. A missing count is NOT MEASURED and fails, never 0. The 270/300
  threshold and the hard-coded 100/100 PR table are gone; nothing ever
  produced them.
- CLI Smoke: only `tri stress --health`, no `|| true`. task stats, task
  list, event stats and stress --scan are unimplemented and exit 0.
- Export Brain Metrics job and the --record/--history steps removed: they
  call unimplemented subcommands, and the health job wrote "snapshot
  recorded" whether or not anything was.
- Report shows each job's real result instead of FAIL for skipped; the
  verdict still requires every job to succeed. Weekly artifact name is
  now unique (`with:` never expanded $(date)).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(build): link libc for the state_recovery brain module

captureState() calls std.c.getpid(). macOS links libc implicitly, so
test-brain passed locally, but on ubuntu-latest the integration binary
failed to compile with 'dependency on libc must be explicitly specified'
(brain-ci run 37180861619). A cross-compile for x86_64-linux-gnu
reproduces the error before this change and compiles cleanly after it.

Refs #1331

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ci): brain-ci merge gate fails red instead of skipping

The gate needed brain-health-report without always(), so whenever the
report failed the gate was skipped. A skipped check renders grey, not
red: on #1328 (run 37176676345) the report failed and the Merge Gate
showed skipped. With always() the gate runs and its existing check
fails it for any report result other than success.

Refs #1331

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* build(brain): spell out brain test roots so the S01 checker can see them

The capability index (external/t27/tools/trinity_manifest.py) finds build
targets only as `const X = b.addTest(.{ .root_module = b.createModule(.{
.root_source_file = b.path(...) }) })` and `b.step("literal", ...)`. The
helper-built roots and the region-step loop showed up as `test:None` and
hid three steps. Each brain test root and step is now written out, so
every target has a precise name a capability card can own. No test
changes: the same files are compiled with the same imports.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* build(reproduce): vendor gHashTag/t27@39e06aa0 and measure trinity/brain.regions

The brain test steps this PR restores (test-basal-ganglia,
test-reticular-formation, test-locus-coeruleus, test-brain,
test-brain-stress) and their six src/brain test roots had no S01 card,
so the capability index failed on each as UNASSIGNED_TARGET.
gHashTag/t27#5965 (39e06aa0, Closes gHashTag/t27#5953) adds the card
trinity/brain.regions that owns exactly those eleven targets.

- tools/contracts.py vendor --revision 39e06aa0: external/t27 and the
  lock move from de2a1aca; 76 files (the new card is the 76th). It also
  brings gHashTag/t27#5474: the S01 checker skips build.zig comments and
  counts the vendored copies apart, and the acceptance of mcp.needle-mcp
  and mcp.trinity-mcp becomes zig build -Dci=true && test -x
  zig-out/bin/<name>.
- specs/reproduce/capabilities.t27: trinity/brain.regions is in RUN. The
  profile's test step does not compile its roots, so its five zig build
  test-<region> commands are its only measure in the index.
  mcp.needle-mcp and mcp.trinity-mcp leave KNOWN_BLOCKED: they were
  blocked on steps that exist only in commented-out lines, and their
  new acceptance is the install the profile already makes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* build(reproduce): raise the contract-test floor to the 78 that run at t27@39e06aa0

The vendoring of gHashTag/t27@39e06aa0 added one spec test, the
card_is_bound_to_its_package test of specs/trinity/capabilities/
brain.regions.t27; no other vendored spec changed its number of tests.
t27c built at 39e06aa0 with zig 0.16.0 measures 58 specs and 78 tests,
all passing, so a floor left at 77 would let one test vanish unseen.

The other ledgers were re-checked against the new vendor and stand as
they are: the eleven TEST_BLOCKED specs fail with the same first error
each, lotus.t27 still drops 48 top-level tokens, and the two
specs/tools/mcp specs still declare no test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

brain-ci: tri stress --health is a stub, so the Brain Health Check fails on every run

1 participant