Handoff — finish the VERIFIED audit (remaining items)¶
Date: 2026-08-02
Status of the work this continues: committed and pushed. See
NDInsight 6211e39 + 5809d8f, norskdata-ndfs 5208d28 + f73e1d0,
RetroFS 1c54721, RetroCore 7ee8dd811.
1. What this is about — read this first or you will repeat the mistake¶
A single documentation claim, marked VERIFIED, propagated a data-corruption bug into four independent NDFS implementations and survived months of green test suites.
The claim was that the NDFS allocation bitmap is addressed as byte N/8, bit N%8. It is
actually addressed as a 16-bit word: page N is bit N%16 of word N/16. On a big-endian
image those differ by a byte swap inside every word.
The evidence cited for it was a popcount comparison. Popcount is invariant under byte-swapping. It could not have failed whichever convention was right. That is the entire failure mode this audit is about:
A claim with a discrete alternative, marked VERIFIED, whose cited check gives the same answer whether the claim is true or false.
Three compounding traps made it survive:
- Round-trip tests cannot detect a symmetric error. Write with convention X, read with convention X passes for any self-consistent X, including a wrong one.
ndtoolis not an independent cross-reader.ndfs-c/CMakeLists.txt:target_link_libraries(ndtool ndfs). It links the very library it was cited as a check on, so it cannot disagree. This phrase appeared in four provenance footers and was false in all of them.- Agreement between re-implementations is not corroboration when they share an ancestor
doc. Four ports agreed with each other and were all wrong; the one hand-written
implementation (
RetroCore/Emulated.Utilities/ND/FileSystem) disagreed and was right. Weight provenance, not headcount.
Your job is to audit whether the EVIDENCE SUPPORTS a claim — not whether the claim is true. Those are different, narrower questions. Most remaining items are probably-correct claims with citations that cannot bear them. Say it that way. Do not delete a fact because its citation is weak; mark the citation.
2. Ground rules¶
- "CANNOT ASSESS" is a valuable answer. There are ~4400 VERIFIED tags in this repo. An agent under pressure to produce findings will invent them. Twenty solid findings beat a hundred plausible ones.
- Believe ND documentation.
Reference-Manuals/,Operations/SINTRAN/, and the manual mirror atE:\Dev\Ronny\mirror-sintran-com. Where the manuals are silent, carve the SINTRAN code (tools/sintran-segment-carver/versions/*/re/segments-ref/). Real ND microcode listings are atE:\Dev\Repos\Ronny\ND120CPUEMU\ND120CPU\ROM\. - Never cite our own re-implementation as proof of ND behaviour. That includes
ndfs-c,ndfs-py,ndfs-ts,RetroFS, RetroCore's emulator, andndtool. - When you add a regression test for a decoding bug, prove it works by reverting the fix and confirming the test actually fails. This was done for the fixes already made: the RetroFS relocation fixture fails 4 of 7 under the old formula, and 10 of 23 bit-order assertions fail under the old convention. A test that passes either way is worth nothing.
- Do not edit files outside the item you are working on. Several repos have unrelated in-progress work (BSD/FFS drivers, VolumeInfo, RetroCommander UI, ND500 handoffs).
3. Unresolved — needs new evidence, do not guess¶
These three were deliberately left open. Each names the experiment.
3.1 BSET ONE 10 DX — which bit? [MEDIUM]¶
SINTRAN/Filesystem/code-logic/allocation.md section 2 reads the disassembler's output
174217 BSET ONE 10 DX (at 006-S3FS 50647) as "bit 10".
SINTRAN/Filesystem/on-disk-format/extended-info-block.md states the disassembler convention
explicitly: "the disassembler prints the bit-number field pre-shifted: 170 octal = 120
decimal = 15 << 3, i.e. bit 15." Under that same convention 10 octal = 8 decimal =
1 << 3 = bit 1.
Two documents in the same set decode the identical field two ways. Only one can be right.
To settle: decode 174217 against the nd100-as BSET encoding table and state the
bit-field extraction explicitly, as extended-info-block.md does. Then trace the
JPL I 140 -> 051003 helper to find where the page-number-to-bit rotation actually happens —
a constant bit number cannot select the bit for an arbitrary page, so the sentence as written
does not describe a working bitmap primitive.
3.2 ACCP register roles at 0x770000 / 0x770004 [HIGH]¶
SINTRAN/ND5000/ACCP-COMPLETE-REFERENCE.md (~line 1509) marks several addresses CONFIRMED
on the evidence that an instruction names them, plus a hit count. That establishes the address
is touched, not its role — which is what the rows assert. A single
move.w #4,(0x770006) is equally consistent with a command register, a mode register, a mask,
or a length.
SINTRAN/ND5000/ACCP-EMULATION-STATUS-AND-HANDOFF.md (~line 682) describes 0x770004 as
"word data-in", while the reference calls it "a data register" with no direction. They
disagree, which is exactly what an instruction-existence check cannot settle.
This is the source for the emulated ACCP register map, so a wrong role silently mis-emulates the octobus transport.
To settle: for each address, follow the full data flow — what value is written, what is
subsequently read, what branch depends on it — or run the real firmware and observe which write
causes an observable state change. That method already worked at 0x114550 for the signature
matrix (same file, ~line 2331). The genuinely PROVEN rows, e.g. 0x660001 bit 4 tied to the
"$MF-bus memory timeout$" string, show what good evidence looks like here.
3.3 ND-120 microcode version byte [MEDIUM]¶
SINTRAN/OS/25-ND120-MICROCODE-VERSION.md claims the version is the low 8 bits of the 64-bit
microword at address octal 020, calibrated against one EPROM dump (version L, byte 0x0c,
and L is the 12th letter).
A 32 KB microcode image contains thousands of bytes equal to 0x0c. One point cannot
distinguish "this is the version field" from "this is an unrelated constant that happens to
equal 12", nor a version field from a fixed constant. The 0x0b -> K row is pure
extrapolation; that value was never read.
To settle: read microword 020 from a second ND-120 EPROM of a different revision and
confirm the low byte tracks that letter's alphabet position. Or find the loader code / ND
documentation that names the version location.
4. Remaining LOW items — judged not worth churn, listed for completeness¶
Each is a correct-looking claim with a citation that cannot support it. No failure mode identified. Fix only if you are already in the file.
| File | Item |
|---|---|
SINTRAN/Filesystem/on-disk-format/boot-sector.md §5.2, and line ~250 |
"VERIFIED against boot_loader.c" — circular for a claim about the ND format. Mitigating: the summary row at ~306 is honest (SMD path VERIFIED, others INFERRED); only the section heading over-claims. Better source: the ALD preset table in ND-06.014.2A p.232. |
SINTRAN/Filesystem/NDFS-VALIDATION.md line ~43 |
"Real disk decode + NDFS reader agree" is one party, not two. directory-label.md §5 has the real check — a second disk whose pointers were followed to actual content. Cite that. |
SINTRAN/Devices/SCSI/scsi-open-last-block-read.md §4d vs scsi-disk-format.md ~244 |
Two mutually exclusive field models for the same 12 bytes, both VERIFIED. "Reproduces every non-zero region" is a coverage check, invariant under how the third field is named. To settle: dump the datafield cells at 031770+X for the entries with run = 20 and run = 171. |
SINTRAN/Devices/SCSI/scsi-open-last-block-read.md ~93 |
Buffer base "confirmed because the first LDATX returns 004000" — a common value. Match a distinctive word instead (052331₈ at base+1). |
SINTRAN/Devices/SCSI/scsi-disk-format.md ~64, ~347 |
"SMD and floppy have no such table" from an all-zero block — an all-zero region separates nothing, n=1 per device class. Settle from the SMD driver carve (no last-block read on that mount path). |
SINTRAN/Devices/HDLC/HDLC-Frame-Format-Reference.md §5 ~232 |
S-frame type field stated as bits 5-4, but the hex bases differ in bits 3-2 and the ASCII diagram places it differently again. RNR/REJ/SREJ were never observed on the wire. Cite ISO 7776 or capture an RR frame. |
tools/boot-floppy/SCSI-DEVICE-STRINGS.md ~136, ~90 |
"No device-type field exists" by exhaustive accounting — but every observed code is 0..10 and every trailing count 0 or 2, so a one-byte field in any of those lanes reads as zero padding in every record. Compare high bytes across a Direct/Sequential mix (NDMICROP vs TANDBERG/EXABYTE). |
tools/boot-floppy/FIRST-BOOT.md ~11 |
"(VERIFIED)" top-line answer outruns the body's own tags — the two cited facts eliminate MACM and establish 22! reaches SINTR, but the file itself keeps three doors open at ~239, ~261, ~270. Scope the headline. |
tools/boot-floppy/versions/L-VSX-500-07/carve-crosscheck.md ~21 |
30 segments promoted medium→high on "28 exact matches", where the match rule is itself tagged INFERRED one paragraph earlier — circular. Also rows at ~45 have empty page/madr columns inside the table headed "28 exact matches". Quote the floppy's macro legend expansion per parameter, as was done for PXRO. |
tools/boot-floppy/patches/README.md ~127-148 |
Three claims (number = patch identifier; trailing letter = revision; H/J ascending, K descending) each resting on monotonicity, one worked example, or "by inspection" over 9 files. The genuinely discriminating fact — sparsity, "H-223 has 124 records for numbers up to 184" — appears at ~145 and is not what the VERIFIED tag cites. |
tools/boot-floppy/MACM-DIALOGUE.md ~480 |
"Exactly one mark is installed per generation run" from a single install site; the command-table extent is explicitly COULD NOT DETERMINE at ~58, so the binary was not swept. |
5. Areas already audited — do not redo¶
SINTRAN/Filesystem/**,norskdata-ndfs/docs/,RetroFS/docs/,RetroCore/DOCS/(NDFS)SINTRAN/Devices/**(SCSI, HDLC, Octobus)SINTRAN/XMSG/DOC/**,SINTRAN/TAD/**SINTRAN/OS/**,SINTRAN/SINTRAN Structures/**,SINTRAN/ND500/**,SINTRAN/ND5000/**tools/boot-floppy/**,tools/sintran-segment-carver/**
Clean, and worth protecting as examples of the right pattern:
tools/sintran-segment-carver/**andMON-CALL-INDEX.md(87 VERIFIED tags, the densest file in the repo) — clean, because it defines its vocabulary: "worker VERIFIED" is stated to mean "this is the carvedMCTAB[N]word", and the base/stride is pinned by a symbol-name-to-semantics correspondence that an off-by-one would destroy.SINTRAN/Filesystem/on-disk-format/extended-info-block.md— kernel-proven, and explicitly considers and rejects the XOR look-alike.SINTRAN/Filesystem/on-disk-format/create-directory-placement.md— a formula where the obvious alternative gives a demonstrably different answer, checked on three differently-sized images.SINTRAN/Filesystem/code-logic/allocation.md§4 — allocation direction resolved fromTESTP'sAAX -1, with "neverAAX 1" stated.SINTRAN/Devices/Octobus/OCTOBUS-PROTOCOL-REFERENCE.md— documents a claim being disproven live and retracted.SINTRAN/XMSG/DOC/XMSG-HEADER-WORD6-IS-A-CHECKSUM-2026-07-31.md— diagnoses this exact failure mode in its own earlier work: "the 'seed' was the contribution of the fields nobody was varying."
Useful negative result: tag density does not predict the failure mode. The two densest
files in the repo came back clean; page-bitmap.md had one bad tag and it cost four
implementations a corruption bug. Precision of definition predicts it; volume does not.
6. Verification commands¶
# Python (norskdata-ndfs/ndfs-py) 472 fast + 3 growth (~35 min)
PYTHONPATH=src python -m pytest tests -q --ignore=tests/test_object_directory_growth.py
# C (norskdata-ndfs/ndfs-c) 261
cmake --build build_win -j 8 && build_win/ndfs_tests
# TS (norskdata-ndfs/ndfs-ts) 396
npm test
# RetroFS 310 NDFS
dotnet test tests/RetroFS.Tests/RetroFS.Tests.csproj --filter "FullyQualifiedName~Ndfs"
# RetroCore 24 NDFS
dotnet test Emulated.Tests/Emulated.Tests.csproj --filter "FullyQualifiedName~NDFS"
Regression fixtures produced by this work, both captured from real SINTRAN:
norskdata-ndfs/testdata/BIGDISK0-K-201users.img.gz(also inRetroFS.Tests/TestData/) — 201 users, one thrice-relocated overflow object block. 2.7 MB gzipped from 78 MB.RetroCore/Emulated.Tests/NDFS/TestData/objblocks-1200p.img.gz— an Indexed object file, so the Indexed-to-SubIndexed conversion is actually exercised.
Driving a live SINTRAN headless (used to capture the above) is documented in the
sintran-console-driver memory note: read F:\RC\RonnyTest\<machine>\RetroCore.ini for the
telnet and DAP ports, send ESC first, answer prompts one field at a time.
7. Not part of this audit¶
The XMSG/COSMOS protocol work is the next thread and is not yours. Do not touch
SINTRAN/XMSG/SRC/** or the Xmsg.* C# projects.