Spec Explorer: 81 of the 338 "broken" specs were never specs - #1089
Merged
Merged
Conversation
The board said `✕ Broken 338`. It was counting Markdown prose that happens to
carry the .t27 extension, TRI-27 assembly, the older `spec Name { }` dialect,
and the fixtures t27 damages on purpose. A parser asked to parse a document
fails, correctly, and the chip then reported that correct failure as a defect
in the corpus.
The compiler has always known the difference -- `t27c classify` answers "is
this file source?" before the parser is asked -- but the wasm bridge exposed
only analyze_source, so nothing downstream could ask. gHashTag/t27#4541 lifts
that rule into bootstrap/src/source_kind.rs and publishes it as `sourceKind`.
This is the consumer side.
What changed here:
corpusEntry carries sourceKind through, defaulting to `source`. A file
leaves the module count only when the classifier positively says it is not
one; an absent field never silently shrinks the denominator.
corpusAggregates counts health over modules and reports the rest as
`notSource` -- total, byKind and byHealth. The last of those is the evidence
that this is a separate axis rather than a fourth health state: 81 of these
files fail, and 31 of them compile cleanly.
SpecExplorer gains a `◇ Not a module` chip. Nothing is hidden: the four
health chips plus this one still add up to All. `inGroup()` replaces the
filter predicate that both `filtered` and `tagCounts` had been spelling out
separately, which is how the two could have disagreed.
The onboarding gate now checks a four-term sum. Adding the term rather than
dropping it matters -- OK+WARN+FAIL alone would hold over 1333 files while
SPEC_COUNT said 1454, green and wrong. HEALTH_FAIL_UNPARSED, _JS_ONLY and
HEALTH_PARTIAL are module-only for the same reason: over every entry the
first counts 228 against a HEALTH_FAIL of 156, and a subset larger than its
set is a denominator mismatch wearing the clothes of a new fact. The gate
now says so directly instead of leaving it to be noticed.
isSourceEntry is imported, not retyped. Two copies of that predicate is
exactly how the two denominators drift apart again.
Measured after regeneration against the new compiler:
1001 ok · 176 warn · 156 fail (of 1333 modules)
121 not a module: unclassified 66 · not-code 46 · alt-syntax 8 · mixed 1
1001 + 176 + 156 + 121 = 1454 ✓
Broken falls 218 -> 156 while the corpus itself grew by 35 files. The 156 that
remain are real: genuine module-level parse failures, a long tail rather than
a few shared gaps, and they are the next piece of work.
public/t27/ is regenerated by sync-t27-specs.mjs against the t27 branch,
including the vendored t27_compiler.wasm that carries the classifier.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Owner
Author
|
Reviewer bee Y: not merged. CONFLICTING with main, and its stated prerequisite gHashTag/t27#4541 (sourceKind in the wasm bridge) is still OPEN -- the body says 'needs that PR merged first'. 78 files / +32k lines including vendored data that will need regenerating against today's corpus (main's catalog is now 1771 specs, #1245). T27 work report is green but stale relative to a rebase. Leave open until t27#4541 merges, then rebase and regenerate. |
Owner
Author
Conflicts resolved: - apps/website/public/** (vendored corpus, manifest.json, shared-core.json, spec-*.json catalogs, t27_compiler.wasm): main's versions, as generated by main's sync. The PR's branch-built wasm and its 1454-spec manifest are dropped; main's catalogs record main's wasm sha, so mixing them would break the *-spec-contract checks. sourceKind activates on the next sync, which vendors a wasm built from t27 master (t27#4541 merged 2026-10-02). - specs/catalog/onboarding.t27: main's 2026-10-04 counts; PR's HEALTH_NOT_MODULE kept and set to 0 (main's manifest has no notSource); the `HEALTH_NOT_MODULE > 0` assert dropped since 0 is now the honest value. - public/llms.txt, public/agents.t27: regenerated with scripts/onboarding-from-spec.mjs (gate: spec tests 10, asserts 55, all hold). - qa/language-exceptions.json: main's, with the onboarding sha updated. - src/pages/SpecExplorer.tsx: main's inWorld() filter plus the PR's inGroup(). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… not list Main's sync owns public/t27/files; these five came from the PR's older sync. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
X Brain Health CheckScore: 100.0/100 X Brain is above merge threshold |
Contributor
🧪 Brain Stress Test ResultsTests: 261/261 passed, 0 leaked |
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.
The live board reads
◆ Course 9 · ✓ Working 976 · ⚠ Warnings 100 · ✕ Broken 338 · All 1414.81 of that 338 are not modules. Markdown prose that happens to carry the
.t27extension, TRI-27 assembly, the olderspec Name { }dialect, and the fixtures t27 damages on purpose. A parser asked to parse a document fails, correctly — and the chip reported that correct failure as a defect in our corpus, on the public face of the project.The compiler has always known the difference:
t27c classifyanswers "is this file source?" before the parser is asked. The wasm bridge exposed onlyanalyze_source, so nothing downstream could ask. gHashTag/t27#4541 lifts that rule intobootstrap/src/source_kind.rsand publishes it assourceKind. This is the consumer side and needs that PR merged first.Result
Broken falls 218 → 156 while the corpus itself grew by 35 files. Nothing is hidden: a
◇ Not a modulechip carries the 121, and the five chips still add up to All.It is an axis, not a fourth health state
notSource.byHealthis{ok: 31, warn: 9, fail: 81}. Eighty-one of these files fail — and thirty-one compile cleanly. Is this a module and does it compile are two questions, and the corpus answers them independently. That is whysourceKindis a second field rather than a fourth value ofhealth, and whyHealthwas not widened in the other four files that declare it: crons, skills and agents legitimately have three states.The gate had to learn the new denominator
onboarding-from-spec.mjsassertedHEALTH_OK + HEALTH_WARN + HEALTH_FAIL === SPEC_COUNT. Adding the fourth term rather than dropping it is load-bearing: the three-term sum would have held over 1333 files whileSPEC_COUNTsaid 1454 — green, and publishing a number that accounts for 121 fewer files than it claims.HEALTH_FAIL_UNPARSED,HEALTH_FAIL_JS_ONLYandHEALTH_PARTIALare now module-only for the same reason. Over every entry the first counts 228 against a HEALTH_FAIL of 156 — a subset larger than its set, which is a denominator mismatch wearing the clothes of a new fact. The gate now says that in words rather than leaving it to be noticed, andisSourceEntryis imported fromt27-corpus.mjsrather than retyped, because two copies of that predicate is precisely how the two denominators drift apart again.Also folded in
inGroup()replaces the filter predicate thatfilteredandtagCountshad each been spelling out separately — two copies of one rule, which is how a chip's count and its contents could have disagreed.What this does not fix
The 156 that remain are real: genuine module-level parse failures. Measured, they are a long tail rather than a few shared gaps — 55 module-level
Ident, 26 unterminated string, 13 module-levelSemicolon, and ~30 distinct one-offs. Two general parser gaps are worth filing on their own (};after a struct/enum declaration, and multi-liner#"…"#raw strings, which break because#is a t27 line comment). That is the next piece of work, not this PR.Verification
npm run build— exit 0. The onboarding gate reportsspec tests 9, asserts 51, all hold.npx tsc --noEmit— 0 errors.public/t27/regenerated bysync-t27-specs.mjsagainst the t27 branch, including the vendoredt27_compiler.wasmthat carries the classifier.🤖 Generated with Claude Code
Merge with main (2026-10-05)
origin/mainwas merged into this branch (182 commits behind). The vendored corpus underapps/website/public/was taken from main as main's own sync generated it:public/t27/files/**,manifest.json(1778 specs),shared-core.json, thespec-*.jsoncatalogs andt27_compiler.wasm. This PR's branch-built wasm and its 1454-spec manifest are not in the merged result, because main's catalogs pin main's wasm sha and mixing the two would break the*-spec-contractchecks.Consequence, stated plainly: main's manifest carries no
sourceKindand nonotSource, so after merge every file still counts as a module and theNot a modulechip reads 0. The code is in place and defaults safely; the reclassification turns on at the nextsync-t27-specs.mjsrun, which vendors a wasm built from t27 master (gHashTag/t27#4541 merged 2026-10-02). The figures in the sections above (1454, 121, 156) are the 2026-09-21 measurement on the branch, not what the site will show right after this merge.specs/catalog/onboarding.t27takes main's 2026-10-04 counts, keepsHEALTH_NOT_MODULEat 0 to match that manifest, and drops theHEALTH_NOT_MODULE > 0assert;public/llms.txtandpublic/agents.t27were regenerated withscripts/onboarding-from-spec.mjs.{ "version": 1, "head_sha": "5711aea441b2884de20d4dc28e9f1370ff7cac68", "summary": "The Spec Explorer learns to count files the compiler classifies as not a module separately from broken specs; merged with main, the code is in place and turns on at the next corpus sync.", "changes": [ "corpusEntry carries sourceKind through from the compiler, defaulting to source so an absent field never silently shrinks the module denominator", "corpusAggregates counts the three health states over modules only and reports the rest as notSource with total, byKind and byHealth", "SpecExplorer gains a Not-a-module chip, and inGroup() replaces the filter predicate that the list and the tag counts each spelled out separately, now alongside main's world filter", "The onboarding gate checks a four-term sum and makes HEALTH_FAIL_UNPARSED, HEALTH_FAIL_JS_ONLY and HEALTH_PARTIAL module-only, importing isSourceEntry from t27-corpus.mjs", "t27Compiler.ts declares the SourceKind union, the per-entry sourceKind field and the optional manifest notSource block", "Merged origin/main: the vendored corpus, manifest, catalogs and wasm are main's; onboarding.t27 takes main's counts with HEALTH_NOT_MODULE at 0, and llms.txt and agents.t27 were regenerated from it" ], "tests": [ { "command": "GitHub Actions Build & Test on the merged head", "status": "passed", "result": "Build and test job completed successfully in 3m15s", "evidence": "https://github.com/gHashTag/trinity/actions/runs/37224847965/job/111502277780" }, { "command": "Validate VIBEE Codegen and Count Pattern Coverage", "status": "passed", "result": "Both jobs in the workflow run passed on this head", "evidence": "https://github.com/gHashTag/trinity/actions/runs/37224847921" }, { "command": "Website checks workflow (npm run check:silicon step)", "status": "failed", "result": "Silicon coverage flags one unclassified vendored spec", "evidence": "https://github.com/gHashTag/trinity/actions/runs/37224847897/job/111502277495 names dmitrii-f-t27/trinity-memory/t27/rtl/gf16_attn.t27, a file from main's vendored corpus; this PR does not touch it or siliconHistory.ts" }, { "command": "Check Documentation Links", "status": "failed", "result": "The documentation link job failed on this head", "evidence": "https://github.com/gHashTag/trinity/actions/runs/37224846240/job/111502272187; this PR changes no Markdown documentation" }, { "command": "GitGuardian Security Checks", "status": "passed", "result": "No secrets detected on the merged head", "evidence": "GitGuardian check reported pass on PR #1089 head 5711aea4" } ], "limitations": [ "Main's manifest has no sourceKind or notSource, so right after merge the Not-a-module chip reads 0 and the broken count is unchanged; the reclassification only appears after the next sync-t27-specs run.", "The 1454, 121 and 156 figures in the description are the 2026-09-21 branch measurement and were not re-measured against main's 1778-spec corpus.", "The branch-built wasm carrying the classifier was dropped in favour of main's wasm to keep the catalog wasm sha contracts consistent.", "The HEALTH_NOT_MODULE greater-than-zero assert was removed because zero is the honest value against the current manifest; it should return once the manifest carries notSource.", "The Health type is still declared separately in several files; widening it was deliberately avoided, but the duplication remains." ], "tags": [ "t27", "compiler", "tooling", "observability" ], "blog": { "title": "A file named .t27 is not always a module, and the explorer now knows it", "summary": "The Spec Explorer counted Markdown documents, assembly listings and deliberately damaged fixtures as broken specs. This change teaches the site to read the compiler's own classifier and count those files apart, ready for the next corpus sync.", "outline": [ "The public Spec Explorer showed a red chip of broken specs, and on 2026-09-21 about a quarter of that number were files that were never meant to be parsed as modules at all, such as Markdown prose and assembly.", "The compiler already knew the difference through its classify subcommand, and gHashTag/t27#4541 moved that rule into a shared source file so the WebAssembly bridge used by the browser can answer it too.", "This change is the consumer side: each corpus entry carries a sourceKind field, the corpus counts health over modules only, and the remaining files are reported in their own notSource group instead of vanishing.", "The consistency gate behind the onboarding document now checks a four-term sum, because a three-term sum would keep passing over a smaller population while the published total claimed a larger one.", "Merging with main meant choosing one generated corpus. Main's manifest, catalogs and compiler binary were kept as a set, because the catalogs pin the binary's hash and mixing two builds would break those checks.", "The honest consequence is that the new chip reads zero until the next corpus sync vendors a compiler built from t27 master, at which point the files the classifier rejects leave the broken count on their own." ] } }