Skip to content

M53 Card 2: an independent Go .tabs v2 codec (and go-toolchain builds GOWIN.ELF) - #1283

Merged
drawmeanelephant merged 2 commits into
mainfrom
agent/autocoder/m53-tabcodec
Sep 15, 2026
Merged

drawmeanelephant merged 2 commits into
mainfrom
agent/autocoder/m53-tabcodec

Conversation

@drawmeanelephant

Copy link
Copy Markdown
Owner

M53 Card 2 (umbrella #1244 is context only — it stays open).

Closes #1246

What this is

tools/go/tabcodec/ — an independent Go implementation of the TABWM .tabs v2 session format frozen in user/src/tabwm.zig, so a second language can own TABWM session state without touching the kernel, TABWM, or the Zig side.

Part Width Layout
header 6 B version(2) | active+1 (0 = none) | count | seq_lo | seq_hi | prefs
record 69 B title(32, NUL-padded) | flags(1) | group(12, NUL-padded) | bin(24, NUL-padded)

Encode/Decode mirror serialize_tabs_v2/parse_tabs_v2. Decode is total: a short header, a wrong version byte, count > 16, a truncated record body, and an out-of-range active index are all rejected with an error wrapping ErrCorrupt; bytes trailing the last record are ignored, exactly as the Zig parser does. At most 16 tabs, so a maximal file is 6 + 16*69 = 1110 bytes.

The one-line justfile change, carried here deliberately

just go-toolchain listed the five runtime fixtures explicitly, so it produced GOHELLO/GOARGS/GOROUT/GOSTRESS/GOPANIC but not GOWIN.ELF — and go-win's setup hook needs that binary, refusing with its build hint when it is missing. GOWIN.ELF became a fleet member in #1282, so a fresh just verify-vz reported the new gate as a setup failure. This adds tools/go/gowin.go to the argument list and updates the recipe's fixture/gate enumeration to match. The card that landed GOWIN.ELF could not declare the justfile, which is why it rides with this one.

Verified: just go-toolchain now stages all six, including .build/go/GOWIN.ELF (1,194,141 B).

Evidence

cd tools/go/tabcodec
go test ./... -count=1    ->  ok      (10 test functions, 25 subtests)
gofmt -l .                ->  (empty)
go vet ./...              ->  clean

Golden A parity — the exact state Zig test TWM/ST1 builds (tabs Calc and Files, the first pinned with CALC.BIN, the second frozen in group tools, active 0, seq 7) pins 144 bytes:

02010207000043616c63000000000000000000000000000000000000000000000000000000000100
00000000000000000000000043414c432e42494e0000000000000000000000000000000046696c6573
000000000000000000000000000000000000000000000000000002746f6f6c73000000000000000000
0000000000000000000000000000000000000000000000

The suite covers: Golden A encode parity plus field offsets, the checked-in testdata/golden-a.tabs fixture, round-trips (golden / empty / maximal / prefs), v1 refusal (TWM/ST3 parity), the TWM/ST4 rejection table plus short buffers, trailing-byte tolerance, fixed-field boundaries, encode of unrepresentable states, and a truncation × single-byte-mutation sweep proving Decode never panics.

Honest limit, also written into the package README: the Zig serializer is not callable from a host Go test, so the golden vector is derived from the frozen layout (and re-derived independently for review), not emitted by executing the Zig binary. Parity here is by derivation + review.

Scope

Host-only: no VM, no kernel, no TABWM change, no new gate spec. No GOWIN rewrite — tools/go/gowin.go and tools/gate/specs/go-win.spec are untouched by this branch. docs/status.md is not touched. Rebased onto main at fafe111.

Rollback

Close this PR unmerged (the claim on #1246 reopens) or git revert the two commits. Nothing here mutates kernel state, persisted data, or configuration; the justfile line is inert unless just go-toolchain is run.

An independent Go implementation of the TABWM .tabs v2 session format frozen
in user/src/tabwm.zig (6-byte header + 69-byte records): a total decoder and
host tests covering a pinned 144-byte golden vector for the state Zig test
TWM/ST1 builds, round-trips, v1 refusal (TWM/ST3 parity), the TWM/ST4
rejection table, trailing-byte tolerance, fixed-field boundaries, and a
truncation x mutation sweep proving Decode never panics.

Host-only: no VM, no kernel, no TABWM change, no new gate spec.

Closes #1246
The recipe listed the five runtime fixtures explicitly, so `just go-toolchain`
produced GOHELLO/GOARGS/GOROUT/GOSTRESS/GOPANIC but not GOWIN — and gate
go-win's setup hook needs that ELF, refusing with the exact build hint when it
is missing. GOWIN.ELF is a fleet member since #1282, so a fresh `just verify-vz`
reported the new gate as a setup failure. Adds tools/go/gowin.go to the
argument list and updates the recipe's fixture/gate enumeration to match.

No codec change: tools/go/tabcodec/** is untouched by this commit. Carried here
because the card that landed GOWIN.ELF could not declare the justfile.
@drawmeanelephant
drawmeanelephant merged commit 7b5c204 into main Sep 15, 2026
9 checks passed
@drawmeanelephant
drawmeanelephant deleted the agent/autocoder/m53-tabcodec branch September 15, 2026 01:15
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.

M53 Card 2: Go .tabs v2 codec

1 participant