Files
LithosAnanake/docs/working/archive/session-logs/2026-07-24-punch-list.md
T

6.8 KiB

Punch List: Gaps from 2026-07-24 Session

Carried over to fix in a fresh session. Written at end-of-session while wrapping up — see CHANGELOG.md on both branches for what was accomplished today; this file is only the leftover gaps.


1. Port master's riscv64 bug fixes to lithosananke (highest priority)

Getting the hosted riscv64 acceptance test to build under clang on master surfaced several real bugs. They were fixed on master only. This broke an invariant established at the start of today's session: we verified via SHA-256 that the ASM-optimization headers (including include/vm_asm_opt_riscv64.h) were byte-identical between master and lithosananke. That's no longer true.

Most important: include/vm_asm_opt_riscv64.h's vm_pop_asm/vm_rpop_asm had a genuine SIGSEGV-causing register-reuse hazard (the inline asm referenced the dsp/rsp memory operand both before and after writing the output value operand, with nothing pinning the address register in between — clang's allocator picked the same register for both and corrupted the write-back; GCC happened to pick different registers and never hit it). Fixed on master (commit 4db9946a) by writing dsp/rsp back before loading the value. This bug is still live and unpatched in lithosananke's copy of the same file — latent today only because lithosananke's kernel build currently uses GCC, but it's a real crash risk if that ever changes (different GCC version, different -O level, or a future switch to clang).

Also unported to lithosananke, all from master commit 4db9946a:

  • src/inference_engine.cq48_from_u64(0.8)q48_from_double(0.8) (was silently truncating to 0)
  • src/math_portable.c-100LL << 16 (UB, shifting a negative value) → -(100LL << 16)
  • src/block_subsystem.c — removed dead lbn_to_pbn() (unused function, clang caught it)
  • src/physics_pipelining_metrics.c — removed dead q48_mul_q48()
  • src/word_source/editor_words.c — removed dead set_scr()
  • src/word_source/starforth_words.c — removed dead reset_count local

Action: cherry-pick or manually port these onto lithosananke, then re-verify the standing kernel 3-arch QEMU acceptance test still passes (dead-code removals and the two arithmetic fixes are behaviorally inert for the kernel path except where they touch real bugs; the asm fix is the one that actually matters).

2. Fix the broken riscv64 command in this branch's acceptance-test doc

docs/lithosananke/hosted-acceptance-test/README.md still documents the riscv64 leg using riscv64-linux-gnu-gcc, which cannot build this tree (nanosleep visibility failure under -std=c99, unrelated to any project change). This was already fixed in master's .claude/CLAUDE.md (the working command is clang-18 --target=riscv64-linux-gnu --sysroot=/usr/riscv64-linux-gnu with -std=c11 -pthread and -fuse-ld=lld) but the correction was never carried over to this doc.

Action: copy the corrected command block from master's .claude/CLAUDE.md (### "Run the acceptance test" section) into this doc.

3. riscv64 hosted build isn't reachable via plain make

There's no Makefile target that builds riscv64 hosted with clang — the only working invocation is the long manual command living in CLAUDE.md and commit messages. A plain make ARCH=riscv64 still fails with GCC.

Action (lower priority, needs a decision, not just a fix): decide whether to (a) add a riscv64-clang (or similar) Makefile target that wires in the working toolchain automatically, (b) fix GCC riscv64 compatibility directly (would need to chase the nanosleep visibility issue at its root — not yet diagnosed beyond "gcc riscv64 fails, clang succeeds with different flags"), or (c) leave it manual and just keep the docs accurate. Not urgent since the documented manual path works.

4. amd64 kernel dict_hash non-determinism — root cause is a hypothesis, not proven

Today's kernel acceptance re-run found amd64's dict_hash deviated from aarch64/riscv64 (which matched each other and the established reference exactly). Traced to capsule_dict_hash_hook() folding execution_heat into the hash, combined with amd64's boot log stating its timer runs in "RELATIVE mode (no determinism guarantees)" under this QEMU/hypervisor setup (no invariant TSC) — unlike aarch64/riscv64, which get real hardware timers. Plausible and consistent with existing ACL-RWT campaign data showing amd64's tick count already diverging from the other two architectures, but this was a single observation, not confirmed by repeated runs.

Action: re-run the amd64 kernel leg 3-5 times back to back and confirm dict_hash actually varies each time (proving jitter) rather than being stable-but-different (which would point to something else). If confirmed, consider whether CHANGELOG.md/CLAUDE.md's acceptance criteria need a one-line amendment: "identical dict_hash across all three architectures" should probably be scoped to aarch64/riscv64, with amd64 checked only for clean boot + PARITY:OK + E2E PASS.

5. lfs/riscv64/starforth isn't bit-for-bit what make fastest would produce

The committed riscv64 LFS binary (on master) was built with my manual clang invocation, which omitted several of TARGET_CFLAGS_fastest's flags (-funroll-loops -finline-functions -fomit-frame-pointer -fno-plt -fno-semantic-interposition) and used -fuse-ld=lld instead of the default linker. Functionally fine (acceptance test passed), but worth knowing it's not exactly reproducible via the standard make fastest recipe. Resolves naturally once item #3 is decided.

6. Repo size growth from committed QEMU acceptance-run artifacts

Not a bug, just a trend worth being aware of: today's two kernel acceptance runs on this branch alone added 1M+ lines of committed log/DoE-CSV data, including one 82MB serial log GitHub explicitly warned about (logs/20260724-191335/amd64/qemu-amd64-20260724-191335.log). Matches existing project convention (every real acceptance run gets committed), but if this keeps compounding it may eventually be worth a retention/pruning policy for logs/ and experiments/bare_metal/runs/. No action needed now — just flagging.


Not gaps, just context for next time

  • The 2 pre-existing SPAN.zero_input/SPAN.variable_test test failures (727/800 baseline on all three hosted architectures, observed on master) predate today's session — confirmed present before any of today's fixes were applied. Not investigated further today; still an open item if anyone wants to chase it down.
  • Today's aarch64/riscv64 .hidden ISR hardening (commit 5fe188bd) only has a CHANGELOG entry, not a dedicated writeup the way docs/lithosananke/amd64-isr-fix/README.md documents the original amd64 fix. Not urgent — the CHANGELOG entry covers it — but noting the asymmetry in case someone later wants doc parity.