feat(website): Spec Explorer — Chip tab, on-die view, and hardware history - #953
feat(website): Spec Explorer — Chip tab, on-die view, and hardware history#953gHashTag wants to merge 16 commits into
Conversation
A library of all 497 t27 specs. Pick one and see it through every stage the compiler puts it through: tokens, AST, type check, HIR, and five codegen backends (Zig, Verilog, Verilog-from-HIR, C, Rust). The compiler is not reimplemented in TypeScript. bootstrap/src/compiler.rs is built to wasm32-unknown-unknown and run in the browser, so what the page draws is what t27c produces and cannot drift from it. Three things made that practical, none of them obvious up front: compiler.rs carries exactly one external `use`, its only filesystem calls sit inside #[cfg(test)], and the whole module is 173 KB gzipped with every backend linked. Measured across the corpus: 5ms average per spec, 68ms for the largest (1618 lines, 3738 nodes). The page uses parse_ast_full rather than parse_ast. The difference matters: error recovery can discard declarations while still reporting a successful parse, and a tree that quietly omitted half its file would be the wrong thing to draw. 49 of 497 specs (9.9%) lose content this way, so the page shows a banner naming exactly what was dropped. api/c_api_contract.t27 is the clearest case -- 25 discarded declarations, and the generated Verilog says `module unknown` because the module declaration was among them. Also surfaced: the type checker runs in no codegen path (t27c compile gates on it, t27c gen does not), which the Types tab states rather than glossing. Vendored, not fetched at runtime, so the page works offline and deterministically; scripts/sync-t27-specs.mjs regenerates the snapshot and records the exact t27 commit, which the page displays. Route is unlisted, matching the convention for /play and /quantum. gitignore: bare `demos/` and `runtime/` rules matched at any depth and were silently dropping six specs from the snapshot; negated for this path only. Gates: typecheck ratchet unchanged (179/26, new files zero errors), aria refs resolve, vite build clean, route added to the qa audit list. Verified in a real browser against the production build, not just compiled.
Three things, all driven by the same point: a corpus that stops at specs/
cannot show a problem living outside it.
CORPUS 497 -> 667. Now every .t27 in the t27 repo, not just specs/.
Excluded: .git/, and .claude/ (git worktrees, i.e. second checkouts of files
already counted -- the same compiler/ast.t27 appears in every worktree).
chips/ alone contributed 147 real specs. Widening it immediately surfaced
problems that were invisible before:
typecheck failures 60 -> 149
specs losing content 49 -> 78 (9.9% -> 11.7%)
backend rejections 0 -> 6 verilog_hir, "duplicate signal name: "
Those six are gf16_to_fp16 / gf32_to_fp32 across chips/{euler,gamma,phi} --
every one outside specs/, so none of them appeared in the earlier scan. Note
the empty name in that error. The compiler's own specs lose content too:
compiler/parser/parser.t27 drops 2 declarations, and 10 more files under
compiler/ drop one each.
SYNTAX HIGHLIGHTING. The .t27 source is coloured from the compiler's OWN
token stream -- the lexer already said what every span is, so there is no
reason to re-guess it with regexes and no way for the colours to disagree
with the compiler. Generated output (Zig/Verilog/C/Rust) has no token stream
coming back, so that falls back to a small regex pass; it is presentation
only. New shared SpecCodeView adds line numbers and a copy button to every
code-bearing layer.
Also: byte/count badges on each tab so backends are comparable without
opening them, and the failing one reads red with an ✕.
NAV. Listed in Navigation.tsx PAGES (EN + RU), so it is reachable rather
than a URL you have to know.
Fixes found by testing rather than by reading:
- header overlapped its own text below ~1100px; inline styles cannot carry
media queries, so width is tracked and the optional labels drop out
- output dir renamed specs/ -> files/, since paths became repo-root-relative
and specs/demos/ was landing at specs/specs/demos/
- .gitignore: enumerating per-directory negations was whack-a-mole (the
widened corpus hit three more bare rules like `runtime/` and `legacy/`).
Replaced with one `!apps/website/public/t27/**`, which also re-includes the
excluded directories -- git cannot re-include a file whose parent is
excluded. 667 staged == 667 in manifest, verified.
All ten layer tabs exercised in a real browser against the production build.
Gates: ratchet 179/26 unchanged, aria clean, build clean.
…peline ribbon
The library was 668 rows sorted by path, which made a catalogue of the corpus
but not a way to see its state. Three changes, all from the same idea: the
working specs are the product, the broken ones are one click away.
HEALTH IS PRECOMPUTED, NOT GUESSED. sync-t27-specs.mjs now runs the same wasm
the browser runs over the whole corpus and records per-spec health in the
manifest. Compiling 668 specs in the browser just to colour a list would take
minutes; doing it at sync time costs one pass and makes the list instant.
453 ok · 209 warn · 6 fail (= 668, and they sum on purpose)
Worst-wins and disjoint: `fail` means a backend refused to emit at all, `warn`
means it emitted but the compiler dropped or flagged something, `ok` means
clean through every layer. Counts that do not add up are how a health page
loses credibility, so each spec is counted exactly once.
FILTER CHIPS CARRY THEIR COUNTS, defaulting to Working. Summary and navigation
are one control rather than two that can disagree. Status uses shape as well
as hue (✓ ⚠ ✕) so it survives a colour-blind reader, and a failing row names
its own cause inline -- "verilog_hir ✕ 3 type errors" -- rather than making
you open it to find out.
OPENS ON specs/demos/hello_world.t27 (new, t27#3276), badged START HERE. An
empty pane teaches nothing, and dropping a first-time visitor into a 1600-line
FPGA spec teaches less. That file is 98 lines and clean on every axis.
Each row now shows the spec's own header comment as a description (634 of 668
have one), with the directory dimmed and the basename bold.
PIPELINE RIBBON above the tabs: one bar per stage, height on a shared log
scale, red where a stage failed. It answers "where does this spec die" and
"why is the Verilog four times the Zig" without opening five tabs. Log scale
because linear flattens every stage next to a 45 KB Verilog output. Hand-
written SVG -- a chart library would outweigh the page.
Corpus health renders as one stacked bar rather than a 668-cell waffle: at
that count cells cannot be read as proportions, and six failures would be
three lost pixels.
The interesting decision here was NOT to add a loading indicator.
A compile is 200-300ms, which sits inside the 1-second "flow of thought"
threshold: the user notices a delay but stays in context, and no progress UI
is warranted. A spinner that mounts and unmounts in 250ms is a flash, and
flashes read as jank rather than speed -- the usual mitigation (don't show
before 200ms, then hold 400ms) would pad a 250ms operation to 450ms purely to
make its own indicator look deliberate. A skeleton is worse: two layout passes
inside 250ms, and it throws away the previous pane, which is the most useful
thing on screen. A shimmer needs ~800ms to read as a sweep at all.
So: selection paints immediately -- that sub-100ms response IS the feedback --
and the previous result stays put while the new one compiles. A dim exists but
carries `animation-delay: 200ms`, so a fast compile never starts the ramp and
a pathological one degrades gracefully. No JS timers.
Then the loading state was mostly deleted outright:
warm the wasm at mount, not at first click 189ms -> 43ms first compile
prefetch on pointerenter/focus hover is 80-150ms of free budget
cache the last 24 results revisit measured at 0ms
Motion tokens (--dur-fast 90ms, --dur-mid 160ms, --dur-flag 480ms, --shift
4px) live in one scoped block, which makes prefers-reduced-motion a token
rewrite rather than a retrofit -- 1ms rather than 0s, because at zero
animationend may never fire and anything awaiting it hangs. Reduced motion
drops the movement, never the feedback: colour, glyph and counts all stay.
Pane swaps are enter-only (90ms, opacity + 4px rise), keyed on spec+layer. A
cross-fade would need both panes in the DOM at once -- double the text nodes
for a code view, with a real chance of a scroll blip. Only opacity and
transform are animated; nothing that triggers layout. The AST tree is
deliberately not animated at all: a disclosure that can reveal 400 nodes would
drop frames, and the user is already looking at where the content will appear.
The failing-backend tab flashes exactly once (keyed by spec so it re-fires for
a different spec), never `infinite` -- in a dev tool that failure is on screen
for as long as it takes to fix, and a pulsing badge habituates within about
two minutes, having spent the signal it was meant to carry.
`scrollbar-gutter: stable` on the pane: a code tab that scrolls beside an AST
tab that does not would otherwise shift the pane horizontally on every switch.
Verified in the browser: 20ms first compile, 0ms revisit, no console errors.
…te's own tokens The library now opens on an ordered course: hello_world as the overview, then eight numbered lessons, then the rest of the corpus in path order. A gold "◆ Course" chip filters to just those nine. Each row carries a LESSON n badge so the reading order is visible without opening anything. The lessons are new in t27 (t27#3276) and all nine are health-clean, which matters more than it sounds: a course whose examples are flagged broken teaches the wrong lesson twice. Code theme rebuilt from index.css tokens instead of a stock editor palette. Keywords take --golden (#FFD700), identifiers take --accent (#00FF88), with a cool cyan for numbers and a soft violet for strings chosen to sit beside those two rather than compete. Panels moved off pure black to #0b0d0c: on OLED, white text on #000 smears during scroll, and this list scrolls a lot. Borders are now a low-alpha accent rather than white. Every colour clears 4.5:1 on the panel background except `comment`, which is deliberately quiet at ~4.6:1 and carries nothing a reader needs.
The corpus was one repo. It is five now: t27, tri-net, trinity-fpga, trinity
and tt-trinity-corona -- 676 -> 760 specs. Surveyed rather than assumed: all
213 repos were checked via the git tree API, and those five are the ones that
actually hold .t27 files.
Pulled as tarballs rather than cloned. One request per repo, no working copies
to keep in sync, nothing writable left behind, and the manifest records each
repo's exact commit so the snapshot can be traced.
DEDUPLICATED BY CONTENT, which turned out to matter more than expected. t27
vendors three whole chip repos: chips/{euler,gamma,phi} are byte-identical to
tt-trinity-{euler,gamma,phi}, verified by blob SHA before trusting it. 129
files were duplicates and are kept once. A knowledge library full of copies is
worse than a smaller honest one -- and the effect is visible in the failure
count, which fell 6 -> 3 purely because four of the six were the same two
files repeated across chips.
Two findings from the newly-reachable files:
- `trinity-fpga/t27/specs/base/types.t27` produces 0 tokens and no tree. It is
not t27 source at all -- it is TRI-27 assembly (`.data`, `.const`) sharing
the extension. Exactly one file in 760 is like this. Worth knowing that the
extension does not imply the language.
- Everything else parses. The corpus now sits at 522 ok / 235 warn / 3 fail.
Paths are namespaced by repo (`tri-net/specs/...`) so a spec's real home stays
visible, with t27 unprefixed since it is the primary source.
The page is an input surface now. Source is the landing tab, the text is editable the moment it loads, and there is no mode to enter first. TYPING IS THE TRIGGER. A compile is 5-70ms, comfortably inside the window where a result reads as immediate, so making someone ask for it was the wrong default. 200ms of quiet fires a compile; every layer and every metric updates from it. GO stays, and stays useful: it runs without waiting for the debounce, and it is the affordance that tells you the page compiles at all. ⌘⏎ does the same from the keyboard. HIGHLIGHTING SURVIVES EDITING, which a plain textarea cannot do. A transparent textarea sits over a highlighted layer sharing identical metrics -- same font, size, line-height, padding, tab-size, wrapping -- with their scroll positions kept in step. You type into the textarea, you read the layer beneath, and the compiler receives the textarea's raw value with no DOM in between. Colour still comes from the compiler's own token stream, so it cannot disagree with the compiler; the live compile is what keeps those tokens describing the text actually on screen. METRICS ARE DELTAS. "3481 tokens" alone says nothing; "3481 (+42)" against what the shipped spec produced turns this into an instrument. Tokens, nodes, depth, type errors and dropped declarations all carry their change, and each backend shows its output size plus whether an edit broke or fixed it. Two bugs found by testing rather than reading: - `highlightRef` was declared after the useMemo that reads it. useMemo runs its callback during the call, so the ref was still in its temporal dead zone -- a runtime throw that tsc does not catch. Moved above. - The debounce effect depended on `run`, whose identity changes every render, so the cleanup cancelled the pending timer before 200ms could elapse and the compile only landed on later edits. `run` is reached through a ref now and is no longer a dependency. Also: the RU language audit correctly flagged 446 English spec descriptions. They are comments quoted verbatim out of 760 source files, not UI copy -- translating them would misrepresent the files and hiding them would gut the page. They are registered as audit exceptions, generated by the sync script so the list cannot drift from what renders. The gate stays strict for real UI.
Every run of Claude Code Review has failed since it was added: 12 for 12
across six different branches, not something one PR introduced.
The job granted `pull-requests: read`, while its own prompt ends with "Use
`gh pr comment` with your Bash tool to leave your review as a comment on the
PR". A read-scoped token cannot comment, so the run reached its single turn
and errored. `pull-requests` and `issues` are now `write`.
The reason this took a while to see is worth fixing too: the log said only
Claude result reported subtype success with is_error:true
with the actual message swallowed behind "Rerun in debug mode or enable
`show_full_output: true`". That is now enabled, so the next failure states its
own cause instead of requiring a rerun to find out.
claude.yml carried the identical permissions bug. It has only ever been
skipped -- nobody has @claude-mentioned yet -- so there it is latent rather
than observed, but it would fail the same way on first real use. Fixed
alongside.
…laude_args The log's own suggestion -- enable `show_full_output: true` -- names an input claude-code-action@v1 does not have. Its inputs are trigger_phrase, assignee_trigger, label_trigger, base_branch, branch_prefix, branch_name_template, allowed_bots, allowed_non_write_users, include/exclude_comments_by_actor, prompt, settings, the auth and provider set, github_token, claude_args and additional_permissions. Checked against action.yml at the pinned SHA rather than assumed. Passing it also left the file with two `claude_args` keys, which is not valid YAML for a step's `with:` map. Both problems removed: verbosity now rides on claude_args as `--verbose`, and there is one key again. The permissions fix in the previous commit stands and is confirmed landed -- the runner now reports `Issues: write` / `PullRequests: write` where it previously reported read.
…very spec TAGS, DERIVED NOT HAND-APPLIED. 760 specs cannot be tagged by hand and stay correct, so every tag comes from a signal already in the file: its path, the AST node kinds it really contains, and what the backends produced. 43 tags in six families -- domain/, has/, issue/, size/, src/, health/ -- and every spec carries at least one. Multi-select filtering with AND semantics, because "FPGA specs that have tests" is the question people actually ask. Facet counts recompute against the rest of the filter, so a tag never promises results it cannot deliver; a tag that would yield nothing is disabled rather than a dead click. DEEP LINKS, which sharing needed first. Selecting a spec now writes #/specs?spec=<path> via replaceState -- replaceState, not push, so browsing 760 specs does not bury the back button. A shared link reopens that exact spec, and switches to the All filter when the linked spec is not in the default Working view, since otherwise the link would land on an empty list. SHARING to X, Telegram, LinkedIn, Hacker News and Reddit, plus copy-link. The share text carries the spec's measured facts -- tokens, AST nodes, backends emitting -- rather than a generic blurb. CONTRIBUTE, with no backend involved. "Propose a fix" opens GitHub's own editor for the file: for anyone without push access GitHub forks the repo and offers the pull request, which is the auto-PR path using the visitor's own session and no credentials passing through us. "Report" opens a prefilled issue carrying what the compiler measured, and shows a count when the spec actually has problems, so reports arrive with evidence instead of "it doesn't work". One limitation stated in the code rather than papered over: the editor draft is not pushed into the URL. GitHub's `value` prefill only applies to new files, and a multi-kilobyte spec would exceed URL limits regardless. DETAILED DESCRIPTIONS. Each spec gains a generated paragraph beside its header comment -- what it declares, what it carries, what it compiles to, what it emits, and why it is flagged. Built from the compile, so it cannot drift from the artifact the way a hand-written blurb would. Gates: ratchet unchanged at 179/26, aria clean, vite build clean.
… brains
The corpus is the Queen's core, so SPECS sits second in the HUD -- directly
after COMB, hotkey 2 -- rather than as an appendix behind the board views.
THE VIEW IS THE DOCTRINE'S OWN SCOREBOARD. It states the standing directive
(every part of the project expressed as a .t27 spec, the project generated from
those specs, spec as source of truth and Zig/Verilog/C/Rust as outputs) and
then puts the measured distance right underneath it:
522 clean · 235 flagged · 3 rejected · 760 specs across 5 repositories
and, in the panel that keeps it honest: the generated Verilog synthesises to
0 LUTs and 0 flip-flops across every spec Yosys accepts -- module shells with
IBUF/OBUF and nothing behind them -- while the bitstreams running on the board
today come from hand-written RTL. The directive is the goal; that line is the
distance. A directive with no counter beside it is a slogan.
Numbers come from the same manifest the Spec Explorer uses, produced by running
the real compiler over every spec, so the panel cannot drift from the corpus.
BOTH BRAINS CARRY IT.
- The bees': `agentBootstrapText` is what every agent joining over A2A reads.
It now carries the directive, including the instruction to prefer replacing
hand-written code with a spec that generates it over maintaining both -- and
explicitly that this is the goal and not the current state, so an agent
measures rather than asserts.
- The Queen's: doctrine 01 no longer says only "boundary, scenarios,
requirements". It says those are written as a .t27 spec and that every
language output is generated from it.
Three layout bugs, each found by measuring the rendered page rather than
reading the CSS:
- The sections inherited `display: flex` (row) from an existing rule, so each
label sat beside its paragraph and the section collapsed to the label's
height -- sections then painted over one another.
- Fixing that with a blanket `> section { display: block }` clobbered the stats
row, which is itself a section; it needs a higher-specificity selector to
keep its flex.
- Flex children shrink by default, and this column lives in a height-
constrained HUD body, so the sections compressed below their own text.
`flex-shrink: 0` on the children; the container scrolls instead.
Styles live in Queen.css, not index.css -- the first version went to the wrong
file and only appeared to work because index.css is global.
Gates: ratchet unchanged at 179/26, aria clean, build clean, layout verified
in the browser with an explicit overlap check (0).
# Conflicts: # apps/website/src/pages/Queen.tsx
…lays
The audit failed on /specs with lines like
; A trit is the unit this language is built on: three states, not two.
// A function declares its parameter types and its return type.
Those are comments inside hello_world.t27, rendered because the page opens on
the Source tab. They are the spec's own text, quoted verbatim, in whatever
language its author wrote. Translating them would misrepresent the file, and
the page's actual UI is fully translated -- so the gate was right that the
words are English and wrong about what it was looking at.
`collectRouteText` now clones the body, drops any `[data-lang-exempt]`
subtree, and reads the rest. The editor and the code view carry that
attribute; everything around them is still audited. This narrows the gate
rather than excluding the route, which would have switched it off for real UI
copy on the same page.
Verified by running the audit against the production build rather than
reasoning about it: RU-аудит PASS across 28 routes.
… of it The first version showed corpus counts and the directive. That was a readout about the tool; what belongs in the Queen is the tool. Picking a spec, editing it, pressing GO and watching every layer recompile now happens inside the HUD. An iframe rather than the SpecExplorer component inline, for two concrete reasons: SpecExplorer owns a full-viewport shell with its own header and sidebar and would fight the HUD's grid, and it instantiates a 477 KB compiler wasm that the host page has already loaded. Same origin, so the frame is a layout boundary rather than a security one -- which is exactly what was needed. SpecExplorer gains ?embed=1, which drops its page header. Inside the HUD that header would be a second title bar directly under the sector strip. The directive is now one line above the frame with the health counts inline (522 clean, 235 flagged, 3 rejected). The full statement and the measured gap live inside the explorer, where the numbers are already being computed -- no second place to keep them in sync. Verified in the browser at 1600x1000: strip 990x96, frame 990x635, and inside the frame the editor, the GO button and a hidden header. An earlier measurement read 32x0 and was not a layout bug -- the browser pane itself had collapsed to 16x16, so every element in the chain measured near zero. Worth checking the viewport before believing a zero.
The default filter was Working. That is 522 specs with no suggested order -- someone arriving has no way to know which one to open first, and the catalogue answers a question they have not formed yet. The course does have an order: hello_world, then eight lessons, each clean through every layer. It is now the default group, so the page opens on a path through the corpus rather than a pile of it. Every other group stays one click away and still carries its count. Also widens the deep-link override. It read `health !== 'ok'`, which was the right test against a Working default and the wrong one now: a link to a healthy spec outside the course would have landed on a filter excluding the very spec it named -- an open file beside a list that does not contain it. It now checks membership in the course instead. Verified in a browser on a fresh load, which is what a shared link actually is: the default shows Course 9 with the nine lessons in reading order, and a link to chips/euler/specs/fpga/gf16_to_fp16.t27 widens to All 760 with that spec loaded in the editor. Worth recording: an in-page hash change does NOT re-run the deep-link handler, because it only runs on mount and the SPA does not remount. That is correct for a shared link and would be wrong if anything ever navigated by hash internally.
Every .t27 spec gets an animated schematic of the datapath it declares, and the formats that have actually been through the AX7203 carry their evidence chain beside it. The schematic is derived from declarations the language already forces you to write: the bit width of every constant, the field layout of every packed struct, and the parameter and return widths of every function. Buses are drawn as parallel lanes with a travelling pulse, pausable. It is deliberately NOT presented as a netlist. The .t27 to Verilog backend emits module shells today -- 361 of 676 specs produce Verilog yosys accepts, and every one yields 0 LUTs and 0 flip-flops -- so no placement is drawn and the panel says why. The hardware section is keyed by an explicit spec-path table rather than by name similarity, so a spec cannot acquire a hardware claim by resembling one. gf4/8/12/16/20/24 carry ADD and MUL measured on silicon; SUB is shown as "bitstream ready, not yet flashed" rather than as a result. Specs with no run say so plainly instead of rendering an empty timeline that reads as pending. Figures are transcribed from GOLDENFLOAT_HW_CONFORMANCE_v0.2 and its evidence chain: CI run, bitstream SHA-256, JTAG flash, UART log. The panel states that the silicon results belong to hand-written RTL of the same format, not to the Verilog these specs compile to. Rows drawn are capped at 12; the diagram scales to the panel, so a 53-function spec would otherwise shrink every label past reading. The remainder is counted in words. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… of stale D98: the Spec Explorer gets a Chip tab. Every .t27 spec is drawn as the datapath it declares -- constant widths, packed-struct field layouts, function parameter and return widths -- with animated buses. Formats that have been through the AX7203 carry their evidence chain beside the drawing: gf4/8/12/16/ 20/24 ADD and MUL on silicon, SUB shown as bitstream-ready rather than as a result, everything else saying "no hardware run" outright. Keyed by an explicit spec-path table so no spec can acquire a hardware claim by resembling one. gHashTag/trinity#953. A43: most of the iteration went to a feature that "did not render" while the code was correct. Three staleness layers stacked: the preview server was `vite preview` serving a prebuilt dist/ and never reading src/; `npm run typecheck` is `tsc -b`, incremental, which re-checked nothing and exited quiet; and the browser held a cached index.html pointing at the previous chunk hash. Forcing the checker immediately surfaced a real ReferenceError in my own file -- `active?.path` where the scope's variable is `selected`. A checker that skipped the file reports exactly what a checker that approved it reports. One command ended it: `ps -eo pid,args | grep vite`, asked after three failed hypotheses rather than before the first. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The Chip tab and hardware-history work in this branch is being sent to Reason: this branch is 16 commits and 787 changed files, and it conflicts with The minimal PR adds three new files and five small edits to This PR stays open for the rest of the branch, which still needs its conflict |
What
Adds a Chip tab to the Spec Explorer. Every
.t27spec gets an animatedschematic of the datapath it declares, and the formats that have actually been
through the AX7203 carry their hardware evidence chain beside it.
This branch also carries the rest of the Spec Explorer line (16 commits): the
corpus browser, live editing, tags and deep links, health grouping, and the
Queen SPECS view.
The schematic
Derived from declarations the language already forces you to write — the bit
width of every constant, the field layout of every packed struct, the parameter
and return widths of every function. Buses render as parallel lanes with a
travelling pulse; the animation is pausable.
It is deliberately not presented as a netlist. The
.t27to Verilog backendemits module shells today: 361 of 676 specs produce Verilog yosys accepts, and
every one of them yields 0 LUTs and 0 flip-flops. There is no placement to draw,
and the panel says so rather than drawing something suggestive.
Rows are capped at 12. The SVG scales to the panel width, so a 53-function spec
would otherwise shrink every label past reading; the remainder is counted in
words instead of rendered illegibly.
The hardware history
Keyed by an explicit spec-path table, not by name similarity — a spec cannot
acquire a hardware claim by resembling one.
gf4,gf8,gf12,gf16,gf20,gf24— ADD and MUL measured on silicongf32and every other spec — "No hardware run", stated plainly rather thanrendered as an empty timeline that reads as pending
Each claim is displayed at the strength it was earned: declared / proven by SAT /
bitstream ready / on silicon. Figures are transcribed from
GOLDENFLOAT_HW_CONFORMANCE_v0.2and its evidence chain — CI run, bitstreamSHA-256, JTAG flash, UART log.
The panel states explicitly that the silicon results belong to hand-written RTL
of the same format, not to the Verilog these specs compile to. The spec and
the core describe the same number format; they are not the same artifact.
Verified
tsc -b --force— zero errors in the four touched/added files (repo baselineis 179 pre-existing errors, unchanged)
specs/numeric/gf16.t27shows ADD/MUL 512/512 on silicon with the NaN-fix note and the four-link chain;
a tutorial spec correctly shows "No hardware run"
Both EN and RU copy added for every new string.