Skip to content

The ladder is TNF, and the four families now have their vectors (Refs #2001) - #2075

Merged
gHashTag merged 11 commits into
masterfrom
fix/tnf-conformance-packs
Aug 10, 2026
Merged

The ladder is TNF, and the four families now have their vectors (Refs #2001)#2075
gHashTag merged 11 commits into
masterfrom
fix/tnf-conformance-packs

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

Merges the TNF rename together with the conformance packs it was missing.

What the rename does

GF-T -> TNF (Ternary Network Float) across specs, catalog ids, module names and packs.
It also restores GF-T as its own family rather than a former name, and adds BNF as the
control: BNF differs from TNF in exactly one thing, the radix the exponent field is encoded in,
so the pair measures what ternary encoding is worth instead of asserting it.

docs/NOW.md states the claim and its limits: the 2x is against our own control on a fabric
nobody sells, and on a real ternary network TNF measures mid-pack among fixed fields.

Why it could not merge before

The WP-18 conformance gate failed on the branch and passed on master — check
A_packset_equals_ssot reported 17 missing packs (bnf8..bnf1024, gft4..gft1024). The
catalogue had gained two families without their vectors, so it declared seventeen formats with no
artifact behind them.

Regenerated with the repository's own conformance/vectors/gen_all_formats.py: 109 formats
parsed, 109 packs, index rebuilt (bitexact 89, structural 20).

Gates, read directly rather than through a pipe

gate exit result
wp18_conformance_gate 0 CLEAN, six of six checks ok
check_catalog_count 0 SSOT == fresh regen == 109
check_catalog_integrity 0 17 GF + 9 GFT + 8 BNF + 9 TNF + gfternary, four families distinct
pack_index_consistency 0

The first run of the WP-18 gate reported exit 0 while printing DRIFT_OR_LEAK, because the exit
code came from tail and not from the gate. Master was baselined separately to establish the
failure was introduced here and not pre-existing.

gHashTag and others added 11 commits August 9, 2026 13:51
… published (Refs #2001)

I justified former_name="GF-T{N}" by claiming arXiv:2606.05017 and arXiv:2606.09686
cite the old name. They do not, and the correction matters because it changes what
the rename cost.

2606.05017 is the binary GF family; its source, docs/arxiv-submission/trinity-gf16.tex,
contains zero occurrences of "GF-T". 2606.09686 is this catalog, and the only commit
introducing an id=gft row is from 2026-08-09 -- mine. The ladder has never been
published under either name.

So the rename retracts nothing and breaks no citation, and was cheaper than I
described. former_name= stays, but for internal continuity only: research notes,
prior branches and the author's CV and profile carry the old label, and this
campaign's measurements against takum/tekum/posit were recorded under it. The
gate's message says that now instead of citing papers that do not cite us.

Two other things in the same header. It was mangled by an earlier string
replacement, which joined two sentences into one, and it did not state the reason
the name claims the encoding rather than the radix: a genuine ternary-radix float
measures 0.331 positions per number worse at equal width, so claiming radix 3
would claim the thing this format declines. Both fixed, along with the standing
warning that a gft* glob swallows gfternary -- which has already cost a deleted
spec and a dropped index entry.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The distinction the map turns on: almost everything the market calls a ternary
format is a ternary WEIGHT QUANTISER, not a ternary NUMBER. BitNet b1.58, TWN,
TernaryBERT, PTQTP, Sherry, CAT-Q, TWLA, BitNet v2, RobuQ and PT2-LLM all put
{-1, 0, +1} in the weights and keep binary floats for activations and
accumulation. None of them defines a ternary number.

That makes them our market rather than our competitors: they create demand for an
activation format and do not supply one.

Real ternary number formats are two. Ternary27 scales by 3^e; TEF scales by 2^e
with only the exponent encoded in balanced ternary. That comparison is already
measured -- kappa(r) = (r-1)^2/(r ln r) gives 0.721 at radix 2 and 1.214 at radix
3, so radix 3 buys 1.585x of range for 1.683x of error, a net loss of 0.331
positions per number.

Ours are three objects that get confused constantly and are now listed together:
the TEF ladder (ternary exponent, binary radix, nine rungs, six measured in
silicon), GFTernary (a 2-bit {-phi, 0, +phi} alphabet, not a float at all), and
TF3 (an 8-bit container for ternary weights whose spec exists but which is absent
from the catalogue).

former_name="GF-T{N}" is restored on the eight rungs that lost it in the squash
merge; only tef16 had kept it.

The positioning that follows is stated with its limit. The measured result --
fixed fields beat tapered ones by 2.4-6.4x in throughput per LUT on a ternary
network -- points exactly at the gap those quantisers leave. But "TEF is best"
does not survive a fair comparison; it sits mid-pack among fixed fields. What
sells is the group boundary, not the position inside the group.

The quantiser list is assembled from surveys and abstracts rather than full
readings, and the file says so: any public claim of "first" or "only" needs it
checked paper by paper.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
GF and this ladder are not the same lineage, and conflating them is what produced
two wrong names in a row. GF is built on the golden ratio: it sizes its exponent by
e = round((N-1)/phi^2), which puts e/m at 1/phi by construction. This ladder
deliberately left phi in order to be a reference, and its phi-distance therefore
RISES with N -- which the catalog already recorded as structural rather than as a
defect, without anyone drawing the conclusion that the name was wrong.

TNF says what it is built for. In a ternary network the weight is in {-1, 0, +1},
w*a is a select rather than a multiply, and the multiplier disappears -- so the
decoder stops being overhead amortised against thousands of LUTs and becomes the
body of a datapath measured in hundreds. That is the workload this ladder is a
reference for, and the measurements in trinity-fpga/fpga/tnet are on exactly that
datapath.

Renamed by explicit rung list, never by glob: specs/numeric/tnf*.t27, catalog ids
tnfN, modules triformat_tnfN, conformance packs, the integrity gate's neighbour
check, the numeric SSOT document and the erratum. Former names ride along in
former_name= -- GF-T through 2026, then TEF for one day.

Neighbours verified present afterwards rather than assumed: gfternary.t27 and
gf16.t27 are both still there. A gft* glob deleted the first of them once already
in this campaign, and the gate that now catches it was written because of that.

Gates: catalog count SSOT == fresh regen == 92, integrity CLEAN with 17 GF + 9 TNF
+ gfternary present and distinct, t27c clean on all nine specs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ng is worth (Refs #2001)

GF, GF-T, BNF and TNF are four formats on two axes -- phi-derived against
theorem-derived, binary against ternary -- and treating any pair of them as
renamings of each other is what produced two wrong names this week.

GF sizes its exponent by round((N-1)/phi^2), which is a statement about the
proportion between the fields. BNF and TNF size it for the range the workload
actually visits and then spend every position that remains, which is what the
precision law implies once you notice the exponent cancels out of it.

That difference is why GF-T leaves positions unspent, and it is what GF-T IS
rather than a defect in it: converting a binary exponent into trits frees
positions and a rule about proportions does not reclaim them. One free at N=8,
then 2, 4, 8, 18. TNF takes them, and the precision law prices the difference
exactly: 2^k, so 4x at 16 bits, 16x at 32 and 256x at 64.

BNF exists to measure rather than to argue. It differs from TNF in exactly one
thing -- the radix the exponent field is encoded in -- with the same width rule,
the same binary radix of the scale and the same uniform mantissa. The pair
therefore isolates the ternary encoding's contribution, and the answer is sharp:
identical at every width on a binary fabric, exactly as the no-free-range theorem
requires, and exactly 2x on a ternary one. One mantissa bit, the same at every
rung, because the packing loss is one position per exponent field regardless of
width. Not more, not less.

Eight rungs, all typechecking, catalog 92 -> 100 so the erratum owes a third
amendment. docs/FOUR_FAMILIES.md states what follows and what does not: the 2x is
against our own control on a fabric nobody sells, and on a measured ternary
network TNF sits mid-pack among fixed fields.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…Refs #2001)

GF-T is not an old name for TNF. Treating it as one is what let me overwrite it,
and restoring it means using the parameters it had rather than the ones I would
derive for it now.

My first reconstruction was wrong and the numbers said so immediately. Sizing
GF-T's exponent as "the same range as GF, in trits" gives unspent positions of 1,
2, 4, 8, 18, 35, 71, 144 and therefore a TNF advantage of up to 2^144, which is
not a format anyone would ship. The actual historical parameters -- E_t of 2, 3,
4, 6, 7, 8, 9, 10, 11 with mantissas 1, 4, 9, 25, 52, 115, 242, 497, 1006 -- leave
0, 0, 2, 0, 4, 4, 4, 4, 6 unspent, and those match what the oracle measured at the
start of this campaign: 4.03x, 15.43x, 15.99x and 15.24x against predictions of 4,
16, 16, 16.

An honest note now rides on the family: only the 16-bit rung actually inherits
phi, where M = 9 is GF16's phi-optimal mantissa carried over when its six-bit
exponent became four trits. The other rungs' exponents were sized ad hoc at
roughly log2(N) trits with no documented rule. Recorded rather than tidied, because
the family is what it was.

Each spec asserts its own unspent-position count, which is the invariant that
separates GF-T from TNF -- GF-T deliberately fails the width rule that TNF
satisfies, and the test says so in those words.

Catalog 92 -> 109 with GF-T's nine rungs restored and BNF's eight added. The
erratum takes a second amendment explaining why the count moved twice in one day:
Amendment 1 was a family that had zero rows, this one is two families that had been
conflated into one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…hat they are

GF-T's parameters were ad hoc: exponents sized at roughly log2(N) trits with no
documented rule, positions left unspent. That is not what a phi-derived family is,
and the fix is to apply GF's own rule rather than to invent a new one.

A trit is a position, so the rule transfers verbatim -- the golden section divides
the payload the way it divides a segment:

  GF:    e  = round((N-1)/phi^2) bits    M = N - 1 - e
  GF-T:  E_t = round((N-1)/phi^2) trits   M = N - 1 - E_t

All nine rungs land exactly, no position unspent, and E_t/M converges on 1/phi:
0.6667 at 16 bits, 0.6154 at 64, 0.6187 at 1024, a phi-distance of 0.0006 at the
top. By construction, exactly as in GF.

That also settles what the two axes are for. GF and GF-T come from the golden
ratio, brought in as a material axis from geometry. BNF and TNF come from the
theorems, as the optimisation result for ternary networks: where the weight is in
{-1,0,+1} the multiply disappears, the error depends on M alone, so size the
exponent for the range the workload visits and give the mantissa everything else.

The trade between the axes is measured rather than asserted. At 64 bits GF-T spans
1.4e11 binades against TNF's 1093 -- 1.3e8 times the range -- for 1.2e5 times the
error. Neither dominates. They are different points on one frontier, and the
corollary on the pair (M_eff, binades) forbids ranking them without naming a
workload. Phi decides how much range; the theorem decides how much is needed.

Each spec now asserts its own golden section rather than remembering it, and
docs/FOUR_FAMILIES.md carries what may be claimed on each axis and what may not --
including that TNF measures mid-pack among fixed fields on a real ternary network,
and that the 2x from the BNF control is against our own control on a fabric nobody
sells.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…2001)

Four families on two axes plus the 2-bit alphabet that shares their prefix, and
each of the five has been lost at least once -- to a glob, or to being mistaken
for a rename of another. So each is named explicitly, checked on disk rather than
in the catalog text, and no family may be a subset of another, which is what
'these are the same format under two names' looks like from outside.

The golden-section rule is guarded too: GF-T carried ad-hoc parameters once and
the rule vanishing is how that happened.

Negative-tested on each of the five individually. Removing gf16, gft16, bnf16,
tnf16 or gfternary.t27 each exits 1 with a distinct message; restoring returns 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The row said 'worse by 0.331 positions by T8' -- an estimate of the
mechanism, not a comparison. Done properly at equal STORAGE in bits
(equal positions would hand Ternary27 the win for free, since a trit
position carries log2(3) = 1.585 bits): 43 bits, m = 30.11, 385
binades, and the TNF43 family needs E_t = 6 of 11 available. Dominated
with five positions to spare.

The mechanism is T8: radix-3 scaling buys range x1.585 and costs error
x1.682. Stated as a law -- the TERNARY belongs in the exponent's
encoding, not in the scale's radix.

GF-T sits on the frontier with equality at 8/16/32/64 and is dominated
only at 128, where rounding round((N-1)/phi^2) leaves positions
unspent. The phi rule and the width rule agree wherever the phi
fraction rounds to an integer.

Also records a correction: weight quantisers were never competitors,
and saying 'we beat nobody in ternary' conflated them with number
formats. Among ternary number formats we do.

Refs #1245
…efs #2001)

The WP-18 gate failed on this branch and passed on master: check
A_packset_equals_ssot reported 17 missing packs -- bnf8..bnf1024 and
gft4..gft1024. The rename added BNF and restored GF-T as families in the
catalogue SSOT without their vectors, so the catalogue declared seventeen
formats that had no artifact behind them. That is the failure this repository
already has a name for: a record outliving the thing it points at.

Regenerated with the repository's own conformance/vectors/gen_all_formats.py,
which reads the catalogue and emits a pack per record. 109 formats parsed, 109
packs, index rebuilt: bitexact 89, structural 20.

I first wrote a separate generator and validated it by reproducing tnf16, tnf64
and tnf1024 byte for byte -- including the +-1000 probe clamp the wide rungs use
because f64 cannot hold their exponents. It was then thrown away in favour of
gen_all_formats.py: a second implementation of the same thing is a second thing
to keep in step, and the repository already had the first. What the exercise was
worth was learning that the probe clamp is a property of the artifacts, not
something to invent.

Gates, all four, on this tree:
  wp18_conformance_gate      exit 0, verdict CLEAN, six of six checks ok
  check_catalog_count        exit 0, SSOT == fresh regen == 109
  check_catalog_integrity    exit 0, 17 GF + 9 GFT + 8 BNF + 9 TNF + gfternary
  pack_index_consistency     exit 0

Exit codes read directly, not through a pipe -- the first run of this gate
reported exit 0 because the code came from tail rather than from the gate.
Master's last commit hardened the integrity gate around former_name="GF-T16" and
explained why that former name exists. This branch supersedes that model: GF-T is
restored as its own family on the phi axis, so it is not a former name of
anything, and the gate now guards the golden-section rule that distinguishes the
phi-derived pair from the theorem-derived one instead.

Taken from this branch in all three conflicts -- formats_catalog.t27,
check_catalog_integrity.py, NOW.md -- because the four-family model replaces the
former-name model rather than sitting beside it. former_name is still present on
eleven rows where it is genuinely a former name.

All four gates on the merged tree, exit codes read directly:
  check_catalog_count       0
  check_catalog_integrity   0  (109 rows, 17 GF + 9 GFT + 8 BNF + 9 TNF + gfternary)
  pack_index_consistency    0
  wp18_conformance_gate     0  CLEAN
@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-08-10 18:48:58 UTC

Summary

Status Count
Total Open PRs 19
PRs with Failing Checks 6
PRs with All Checks Green 13
READY 5
FAILING 6
PENDING 0

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=cd2822f290eb != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@github-actions

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

@gHashTag
gHashTag merged commit b928725 into master Aug 10, 2026
23 of 24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant