# DF-3092 — fillinusemap tail / chainlength clamp (VERIFY result: FALSE POSITIVE)

Claim: dead tail-marking loop + word-relative clamp in chainlength() leave
"phantom free" clusters beyond pm_maxcluster, causing usemap_alloc KASSERT
panics (INVARIANTS) / out-of-volume allocation (release).

Result: **mechanism refuted.**  The initial FULL_RUN fill in fillinusemap()
(msdosfs_fat.c:897-898) covers every allocated bitmap word — bits beyond
pm_maxcluster are marked USED, so chainlength() cannot overcount and
usemap_alloc() never sees an out-of-range cluster.  Proven by source
analysis AND by runtime A/B on the guest: a 7-cluster append that the
finding predicts must *succeed* (or panic) instead returns ENOSPC with the
FAT tail untouched, while a 6-cluster append succeeds exactly to
pm_maxcluster and a 7th cluster fails ENOSPC.

## Reproduce

    # on the QEMU guest (as root; mount of a vnconfig image needs root)
    cd /root/df3092
    sh run.sh          # phases A-D, ~10 s, ends with tailcheck verdict

Expected (healthy kernel): phase A write(3584) → ENOSPC, alive; phase B
write(3072) → 3072; phase C write(512) → ENOSPC; tailcheck ALL PASS
(FAT[4110..4351] zero, BIG.TXT chain ends at 4109).

If a kernel ever prints phase A write success, or tailcheck FAIL lines,
the phantom allocation became real — re-open the finding.

## Files

    crafttail.c   crafts the FAT16 image (maxcluster=4109, 6 real free, 18 phantom)
    trigger.c     appends N bytes in one write(2)
    tailcheck.c   offline image verifier (FAT tail / dir entries / chain bounds)
    run.sh        the full A/B/C/D sequence
    run.log       FULL output of the decisive run (this verification)
    build.log     compiler output + guest env (uname)
    VERDICT.md    the full narrative with path:line citations
    manifest.json machine-readable catalog
    verdict.json  machine verdict (persisted by audit/persist_poc.py)

Note: trigger3092.c + the old run.log were the pre-existing seed; the
current run.sh/trigger.c/tailcheck.c supersede them.
