fix(trinity): the S01 manifest skips build.zig comments and counts the vendored t27 copies apart (Refs #3563) - #5474
Merged
Conversation
…e vendored t27 copies apart (Refs #3563) Two defects of tools/trinity_manifest.py, found by gHashTag/trinity's capability index (S12, gHashTag/trinity#989), which imports this checker byte for byte. 1. parse_build_zig ran its patterns over the raw text of build.zig, comments included. At the pin (gHashTag/trinity@976df517) that counted two steps that exist only in commented-out lines (needle-mcp, trinity-mcp) and two guarded installs (trinity-canvas, trinity-canvas-wasm-check); the reachability walk did the same with one @import. Zig sources are now read with every // comment (/// and //! too) blanked in place, offsets and line numbers kept; string literals, character literals and multiline string lines keep their //. 2. Every tracked .t27 outside the website mirror counted as canonical, so the consumer's vendored copies under external/t27/ read as its own specs (110 canonical at trinity main 37bb4a94, 70 of them copies). external/t27/ is now a second never-canonical prefix: counted apart (T27_VENDORED_FILES, 0 at the pin) and refused as a CANONICAL_SPEC (MIRROR_AS_CANONICAL). --self-check: 16 planted defects (3 new), parser controls on a fixture build.zig, and inventory() end to end over a planted repository; 16 mutants of the fix, each killed by its own assertion. Regenerated from a clean checkout at the pin: inventory.json (66 steps, 3 guarded installs, 748 reachable / 2082 unreachable .zig, 0 vendored), report.json, build_graph.json (its profiles). project.t27, the README and research.unreferenced-sources state the corrected counts. mcp.needle-mcp and mcp.trinity-mcp no longer own the commented steps; their acceptance is the install the cited CI run measured, and their evidence says the run steps are commented out. Four seals re-saved; seal --verify matches all four. Refs #3563 Refs gHashTag/trinity#989 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
This was referenced Oct 1, 2026
gHashTag
added a commit
to gHashTag/trinity
that referenced
this pull request
Oct 4, 2026
…ain.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>
gHashTag
added a commit
to gHashTag/trinity
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two defects in
tools/trinity_manifest.py(S01's checker), found by gHashTag/trinity's capability index (S12, gHashTag/trinity#989). The consumer vendorsspecs/trinity/**and this checker byte for byte underexternal/t27/(locked by itsspecs/reproduce/contracts.t27, gHashTag/trinity#1213), andtools/capabilities.pyimports the checker to inventory the trinity tree (gHashTag/trinity#1218).1.
build.zigwas read with its commentsparse_build_zigran its patterns over the raw text, so ab.stepor aninstallArtifactin a commented-out line counted. At the pin976df517that invented two steps and two guarded installs that the build does not define:step:needle-mcp// const needle_mcp_step = b.step("needle-mcp", ...)step:trinity-mcpexe:trinity-canvas(guarded)// b.installArtifact(trinity_canvas);exe:trinity-canvas-wasm-check(guarded)// b.installArtifact(wasm_canvas);The reachability walk read comments too:
src/background_agent/db/issue_bindings.zigwas "reachable" only through a commented@import.Fix:
blank_comments()replaces every//comment (///and//!too) with spaces, one for one, so offsets and line numbers are the file's own. String literals (with escapes), character literals (a quote held in'"'must not open a string) and multiline string lines keep their//. It is applied inparse_build_zig(steps, artifacts, installs, options, guards and theb.pathroots, which now come from the parser instead of a second raw read ininventory()) and inzig_reachability.2. The vendored copies were counted as canonical
Every tracked
.t27outside the website mirror was canonical, so trinity's copies underexternal/t27/read as its own specs. Measured at trinity main37bb4a94: the old checker reports 110 canonical, 70 of them the vendored copies; this branch reports 40 canonical + 70 vendored.Fix:
external/t27/is a second never-canonical prefix, counted apart in the inventory (dialects.t27_vendored), stated inproject.t27(T27_VENDORED_FILES, 0 at the pin), reported asvendored_contracts, and aCANONICAL_SPECpointing into it is refused asMIRROR_AS_CANONICAL. An inventory written before this count existed is refused (UNREADABLE) rather than judged by rules it predates.Negative controls
--self-checknow plants 16 defects (3 new: a vendored copy as canonical, an unstated vendored count, an inventory without the count), checks the blanker and the parser on a fixturebuild.zigholding every shape above (a commented step in//,///and//!form, aninstallArtifactin a comment, a//inside a string, after an escaped quote and in a multiline string line, a comment after a character literal holding a quote), and runsinventory()end to end over a planted git repository so the wiring is held, not only the functions.16 mutants of the fix, each applied to a copy outside the repository and only above the self-check: all 16 killed, each by the assertion aimed at it (no blanking in the parser or in
@import; no character literals; no escapes; no multiline strings; deleting instead of blanking; blanking through the newline; vendored counted canonical; vendored count zero / not compared / not refused; stale inventory not refused; roots read from the raw text; dialects without the vendored files; only///treated as a comment;zig_pathsempty). Two clauses that only matter for invalid Zig were removed rather than shipped untestable.What the corrected inventory changed
conformance/trinity/inventory.json, regenerated withpython3 tools/trinity_manifest.py inventory --trinity-root <clean checkout at 976df517>(the unfixed tool reproduces the committed file byte for byte from the same checkout):BUILD_STEPSINSTALLED_GUARDEDZIG_UNREACHABLE_FILEST27_VENDORED_FILESEverything else is identical (artifacts, options, the 173
b.pathroots,T27_CANONICAL_FILES31).report.jsonfollows, and the S03build_graph.jsonis regenerated only because its profiles come from the inventory (its own parser gives identical output with and without comments at the pin: 44 modules, 252 edges).python3 tools/trinity_manifest.py checkthen reported exactly: the missingT27_VENDORED_FILES, the three count mismatches above, andUNKNOWN_TARGETforstep:needle-mcpandstep:trinity-mcp. Resolved:mcp.needle-mcp/mcp.trinity-mcp: the commented-out steps leaveTARGETS.ACCEPTANCEbecomeszig build -Dci=true && test -x zig-out/bin/<name>-- the build that installs the binary, which is what the cited CI run (34678824282) measured -- soEVIDENCEstaysmeasured, andEVIDENCE_SOURCEnow says the run steps are commented out at the pin (lines 1481-1483 and 1525-1527) and that no run of either server is measured. Every other field is unchanged.project.t27: the corrected counts, the new constant, and comments saying what each read before; its test now assertsINSTALLED_GUARDED == 3.research.unreferenced-sources: its evidence text states 748 / 2082 instead of 749 / 2081.specs/trinity/README.md: the measured section corrected in place; two pre-existing em dashes replaced so the vendored file is ASCII.t27c seal --verifyreportsall hashes MATCHfor each.checkis now OK: 51 capabilities, 51 executables / 6 libraries / 73 tests / 66 steps all owned.Gates run locally
trinity_manifest.py --self-checkandcheck;tri hooks pre-commit(NOW gate, entry shape, conflict markers on the 14 staged paths, census pin);tri gates preview(check, check-now-freshness, validate; check-linked-issue was a proxy before this PR existed);tools/ci/check_specs_still_parse.pyagainst the merge base (4 changed specs, 0 newly unparseable);scripts/ci/now-sync-gate-diff.sh;check_json_parses,check_conflict_markers,check_withdrawn_live,check_duplicate_declarations,check_specs_parse.seal-verify, where exactly these four specs left the failing set);check_seal_currency(stale 592 -> 588, these four now current);published_figures --check(identical output);dupe_scan;check_assertionless_spec_tests;check_documented_commands_exist(only line numbers insidebuild_graph.jsonmoved);check_specs_generate(15specs/port/**, none here).Not in this PR
.t27at the pin live under trinity's ownt27/directory (t27/compiler7,t27/specs14). Whether those are trinity's specs or unlocked copies of this repository's is not decided here.tools/check_seal_coverage.pyhas been a one-line comment since bcb32d7 (131 seals are stale: the spec changed after sealing #5183), so the seal-coverage workflow passes by construction (seals here were checked witht27c seal --verifyinstead); andscripts/ci/now-sync-gate-diff.sh-- also run bytri gates preview-- writes a brokenmerge.union.driverinto the clone's shared git config and edits.gitattributeswhen run locally.Follow-up in gHashTag/trinity, after this merges
python3 tools/contracts.py vendor --t27 <clone> --revision <new t27 master>.specs/reproduce/capabilities.t27: removetrinity/mcp.needle-mcpandtrinity/mcp.trinity-mcpfromKNOWN_BLOCKEDwith their reasons. Both are inRUN; their new acceptance runs and passes, and a known-blocked card that measures complete fails the index (BLOCKED_NOW_MEASURED) until its line is removed.registry.commandsstays blocked.DRIFT_CODES): measured with this branch's checker and cards against trinity main 37bb4a94, 6 findings, allPIN_MISMATCH/COUNT_MISMATCH, among themT27_VENDORED_FILES = 0, the inventory says 70andT27_CANONICAL_FILES = 31, the inventory says 40; noUNKNOWN_TARGET.Refs #3563
Refs gHashTag/trinity#989
🤖 Generated with Claude Code