# Deferred decisions Design decisions deliberately postponed, with enough context to pick them up again without re-deriving the analysis. Each entry records what is deferred, why, the options on the table, and the trigger that should reopen it. --- ## GOOBJ external (cross-package) symbol references **Status:** resolved (v0.29.0+, 2026-08-07). **Approach taken.** Instead of parsing the compiler's iexport data (which would have required either `golang.org/x/tools` or an in-house parser), the resolver reads the **GOOBJ data directly** from the target package's `.a` archive. The `.a` file contains a `_go_.o` member whose GOOBJ s is the same one gasm writes — the parser reuses the same layout (`blkSymdef`, `blkNonpkgdef`, the string table), so no new dependency was needed. **How it works.** 1. `go list -json -export ` finds the target package's `.a` file. 2. `extractGOOBJ` reads the ar archive, finds the `_go_.o` member, skips the `"go object …\n!\n"` preamble and parses the GOOBJ header. 3. `goobjFile.symbols()` walks `blkSymdef` and `blkNonpkgdef` in definition order — the same order the linker uses — to build the symbol → index mapping. 4. `resolveExternalSymbols` wires the resolved `{PkgIdx, SymIdx}` into the GOOBJ emission. The resolver is invoked automatically when `img.Externals` is non-empty; it runs `go list` as a subprocess (consistent with `toolchainObjectPreamble` which already calls `go tool asm`). All symbol data is cached per package for the lifetime of the GOOBJ emission. ## 2026-08-29 tooling round - `lint abi0-register-args`: flags kernels whose `// func` parameters are never read from the FP frame. Motivated by a real latent bug: kernels reading arguments from registers pass every test while the autogenerated `F.abi0` wrapper happens to leave the caller's register values intact, and break on a toolchain upgrade. - `lint nonportable-register-name`: the RAX/EAX register spellings are a gasm extension; go tool asm rejects them, so files using them only link through the gasm goobj path. - `lint unencodable-instruction`: a mnemonic in the architecture table that `asm.Encodable` rejects is flagged at edit time instead of failing at assembly time. - `audit-instructions`: black-box diff of the encoder against go tool asm. As of this round the tables fully overlap on names; the audit exists to catch drift in both directions (future supersets and future gaps). - `scaffold differential`: generates the direct-call differential skeleton (two independent seed sets, output and in-place buffer comparison) that a pipeline-level fuzz can never replace. - `verify --args`: scalar arguments for `-call`, closing the repro gap where only buffers could be supplied. - `debug --script/--timeout/--cover`: headless debugging with a watchdog armed before the ptrace attach (untracing sandboxes hang the attach), and label-level block coverage for the "did my test ever enter that branch" question. - Superset policy remains: gasm may accept spellings and encodings go tool asm lacks, but such kernels ship only via `gasm asm --format goobj`; the audit reports the superset surface. The register-alias superset is warned about by lint because the default `go build` path cannot consume it.