Skip to content

CLAUDE.md memory margins are stale in three places; CRYPTO_HOT overstated 2.25x (81 B claimed, 36 B measured) #193

Closed

Description

@JC-000

Symptom

CLAUDE.md's Memory layout / Known issues sections state three memory-margin
figures. All three are wrong against a current build, and the one that matters
most is overstated by 2.25x — in the direction that makes a full region look
like it has room.

Measured 2026-09-05 from origin/master at dc06095, both shipped UCI
products, from build/c64-https.map:

BACKEND=uci USE_NISTCURVES_ONCHIP=1       -> cfg/c64-https-uci.cfg
  PRG 5f9e9fb9e70edd2a15ab2249120f161d1826262140fa6ce6f3e01410a876b474
BACKEND=uci USE_NISTCURVES_ONCHIP_COMB=1  -> cfg/c64-https-uci-onchip.cfg
  PRG c423476011e1928f5955e4773c3cf28c4876dcf76e70be9de40c2f4522f8bf72
CLAUDE.md claim measured onchip measured comb
:427 "CRYPTO_HOT margin under UCI is 81 B at v0.9.1+" 36 B 193 B
:424 "server-name validation took the comb tail from 714 to 223 B" — 159 B
:558 "comb adds RODATA/LIMLEE_BSS (~223 B tail free)" — 159 B

CRYPTO_HOT is the sharp one. 36 B is the tightest margin in the tree —
tighter than NET_BSS_TAIL's 43 B, tighter than NET_CODE's 67 B — and
CLAUDE.md says 81 B. Note also that 81 B matches neither profile: the two
cfgs give CRYPTO_HOT very different occupancy (36 B vs 193 B, because the
comb cfg moves all the rodata out to CRYPTO_OVERLAY), so a single
backend-wide figure cannot be right whatever its value. Same for the overlay
tail, quoted twice at 223 B and measured at 159 B under comb and 2,035 B under
onchip.

Why it matters

CRYPTO_HOT overflow is a documented, expensive failure. CLAUDE.md itself says
the margin "was one byte at v0.6.0" and to "watch it on every pin bump", and
#149 overflowed the neighbouring NET_CODE by 35 B and cost the UCI backend
entirely. Someone sizing a change against 81 B when there are 36 has 45 bytes
of imaginary headroom in the region that is hardest to grow.

To re-measure:

make clean && make BACKEND=uci USE_NISTCURVES_ONCHIP=1
awk '/^Segment list:/,0' build/c64-https.map

Last used address per region, minus the region end, is the tail. Full tables
for both products are now in the cfg headers (PR #188): each cfg carries a
dated, profile-tagged, PRG-hash-stamped Measured region occupancy block, and
those blocks are the natural thing for CLAUDE.md to point at.

Suggested fix

Per #161's rule — would this copy change if the fact did? — a byte count in
CLAUDE.md answers no, and there are now two cfg blocks that carry the same
facts next to the SEGMENTS lines that produce them. So prefer deleting
the three figures over refreshing them:

  • :427 → say CRYPTO_HOT is the tightest region under UCI and that the
    margin is profile-dependent, pointing at the occupancy block in the cfg
    the profile actually links. Keep "watch it on every pin bump".
  • :424 and :558 → drop the 223 B; :424's point (a new resident tenant
    shrinks what the rigs' MemoryArbiter can hand out, and broke
    rig_https_wiki.py) survives intact without a number, and tools/uci/_memory_policy.py
    already reads build/labels.txt rather than any written figure.

Notes

Found while measuring for #170 (PR #188) and confirmed independently by
adversarial review. Deliberately not folded into #188 — that PR is
comment-only inside cfg/, verified PRG-neutral, and other lanes are editing
CLAUDE.md concurrently. Filing rather than editing for the same reason.

Activity

  1. JC-000 commented on Sep 5, 2026

    @JC-000
    OwnerAuthor

    One more stale margin for this issue, from the #189 / #166 x25519 pin work.

    Known issues, USE_X25519_SIBLING=1 under UCI: CLAUDE.md says the overflow is
    1,280 B. Measured today it is 1,536 B
    , at both the old pin (v0.11.2) and the
    new one (v0.13.0) — so it is not something the bump moved:

    ld65: Warning: cfg/c64-https-uci.cfg(120): Segment 'X25519_BSS' overflows
          memory area 'CRYPTO_OVERLAY' by 1536 bytes
    

    The ip65 figure in the same paragraph (3,584 B) I did not re-measure.

    Also confirming the CRYPTO_HOT number this issue already names, since I
    measured all three shipped variants at dc06095 while sizing #190 — free space
    below the top of the region holding LIB_NISTCURVES_P256_CODE:

    product region last byte used free
    ip65-onchip CRYPTO_RESIDENT $6000-$9FFF $9FD7 40 B
    uci-onchip CRYPTO_HOT $6000-$9FFF $9FDB 36 B
    uci-comb CRYPTO_HOT $6000-$9FFF $9F3E 193 B

    So the single "81 B under UCI" line is wrong in both directions depending on
    the variant, which is probably the more useful way to state the fix: the margin
    is per-variant, not per-backend.

    Secondary regions, same builds: CRYPTO_OVERLAY free is 22 B (ip65-onchip),
    2,035 B (uci-onchip), 159 B (uci-comb) — the last against CLAUDE.md's
    "~223 B tail free" for comb.

    Not editing CLAUDE.md myself; other lanes are in that file.

  2. JC-000 commented on Sep 5, 2026

    @JC-000
    OwnerAuthor

    One more stale margin for this issue, from the #189 / #166 x25519 pin work.

    Known issues, USE_X25519_SIBLING=1 under UCI: CLAUDE.md says the overflow is
    1,280 B. Measured today it is 1,536 B
    , at both the old pin (v0.11.2) and the
    new one (v0.13.0) — so it is not something the bump moved:

    ld65: Warning: cfg/c64-https-uci.cfg(120): Segment 'X25519_BSS' overflows
          memory area 'CRYPTO_OVERLAY' by 1536 bytes
    

    The ip65 figure in the same paragraph (3,584 B) I did not re-measure.

    Also confirming the CRYPTO_HOT number this issue already names, since I
    measured all three shipped variants at dc06095 while sizing #190 — free space
    below the top of the region holding LIB_NISTCURVES_P256_CODE:

    product region last byte used free
    ip65-onchip CRYPTO_RESIDENT $6000-$9FFF $9FD7 40 B
    uci-onchip CRYPTO_HOT $6000-$9FFF $9FDB 36 B
    uci-comb CRYPTO_HOT $6000-$9FFF $9F3E 193 B

    So the single "81 B under UCI" line is wrong in both directions depending on
    the variant, which is probably the more useful way to state the fix: the margin
    is per-variant, not per-backend.

    Secondary regions, same builds: CRYPTO_OVERLAY free is 22 B (ip65-onchip),
    2,035 B (uci-onchip), 159 B (uci-comb) — the last against CLAUDE.md's
    "~223 B tail free" for comb.

    Not editing CLAUDE.md myself; other lanes are in that file.

  3. JC-000 commented on Sep 5, 2026

    @JC-000
    OwnerAuthor

    Two more instances, found while auditing README for #192. Both measured 2026-09-05 against dc06095. Adding here rather than editing CLAUDE.md, because several lanes are in that file right now.

    (Housekeeping: the comment immediately above this one was posted from my account by accident — two lanes collided on a shared scratchpad filename and my gh issue comment picked up the other lane's file. The content is theirs, from the #189/#166 pin work, and it is accurate; it independently reproduces the CRYPTO_HOT 36 B / 193 B and CRYPTO_OVERLAY 22 / 2,035 / 159 B numbers below from separate builds. Attributing it correctly rather than deleting it.)

    1. The ip65 free-block figure is stale, and CLAUDE.md contradicts itself about it

    CLAUDE.md:584 ("ip65 is essentially full: largest free block ~170-186 B (NET_CODE tail) … 16 B LOADER") and CLAUDE.md:125 (HTTPS_TARGET_RODATA … "NET_CODE tail (186 B, a joint budget)").

    Measured from build/c64-https.map for the shipped ip65-onchip product (BACKEND=ip65 USE_NISTCURVES_ONCHIP=1), region bounds from cfg/c64-https-ip65.cfg:

    region claimed measured
    NET_CODE tail ~170-186 B 56 B
    LOADER 16 B 21 B
    CRYPTO_OVERLAY 22 B 22 B ✓
    CRYPTO_RESIDENT 40 B 40 B ✓

    CLAUDE.md already disagrees with itself here. Its Networking-backend-ABI section (:230-232) says the tail "shrank from 170 to ~60 B beyond the default strings" — which matches the measurement — while the Memory-layout section 450 lines later still says ~170-186 B.

    Why it matters beyond tidiness: this is the number that decides whether the 491 B src/x509_name.s SAN check can ever fit on ip65 (#135). At 170 B the answer is "no, but not by much"; at 56 B it is "not remotely". Once #192 merges, README will say 56 B and CLAUDE.md will say ~170-186 B — a ~3x disagreement on a load-bearing figure, in the two documents a reader is most likely to consult.

    2. A verify figure differs between README and CLAUDE.md, and #192 makes the stale one look fresh

    README.md:34 (the release table, untouched by #192) says the comb image is "1.73x quicker verify (28.4 s vs 16.4 s, U64E at 48 MHz)". It matches tools/package/_common.sh, the packaging source of truth, so it is not wrong on its own terms.

    But CLAUDE.md's ECDSA table gives onchip @ 48 MHz as 30.5 s. Same device, same clock, same profile, two documents, ~7% apart, with nothing saying which supersedes.

    The specific hazard #192 introduces: it re-dates the surrounding Project Status section to 2026-09-05, so a reader will reasonably take the untouched 28.4 s as freshly verified. It was not. I did not re-measure it and could not have — it needs a U64E, and this lane ran no hardware.

    Resolution wanted: decide which figure stands, or record that they were taken at different pins and say so in both places. Neither is a rebuild-and-check; both need hardware.

  4. added a commit that references this issue on Sep 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions