docs: record Ε-W3 as landed and Phase Ε as complete
This commit is contained in:
+36
-2
@@ -1039,5 +1039,39 @@ genuine folder-name collision (`sanitizeRenameCount` vs `collisionRenameCount`)
|
|||||||
a hostile or foreign-spelled entry name (e.g. an unexpected extension) always
|
a hostile or foreign-spelled entry name (e.g. an unexpected extension) always
|
||||||
lands sanitized rather than verbatim.
|
lands sanitized rather than verbatim.
|
||||||
|
|
||||||
**Ε-W3 (`package-compat-fixtures`) has not landed** and is the only remaining
|
### Ε-W3 — The compatibility fixtures
|
||||||
wave of Phase Ε.
|
|
||||||
|
The phase's third and final wave, and with it Phase Ε's implementation is complete: the
|
||||||
|
version-compatibility policy stated in `docs/product/bank-package.md` is now a property
|
||||||
|
proven against frozen bytes rather than an assertion in a doc.
|
||||||
|
|
||||||
|
**Ε-W3-T1 — `package-compat-fixtures`.** A new checked-in corpus of 23 frozen `.rsbank`
|
||||||
|
fixtures under `tests/fixtures/package_compat/` — one v1 package written by the shipping
|
||||||
|
build (`1.4.0`), a synthetic additive-forward package (`formatVersion` 2 /
|
||||||
|
`minReaderVersion` 1) carrying three keys this build has never heard of, a synthetic
|
||||||
|
structural-refusal package (2/2), nine truncations (one per distinct decode failure
|
||||||
|
site, including one cut at `additive_forward.rsbank`'s own payload boundary), and eleven
|
||||||
|
hostile-name packages (six bad entry names, five bad nested `relativePath` values) —
|
||||||
|
every payload a single 300-byte 16-bit mono WAV, ~15 KB for the whole corpus. Two new
|
||||||
|
test targets decode and exercise it: `package_compat_tests` (frozen bytes decode to
|
||||||
|
exactly what the shipping build wrote, the additive fixture reads with every unknown key
|
||||||
|
skipped, every truncation classifies `Malformed` and never `TooNew`, every hostile name
|
||||||
|
is refused before any planner runs) and `package_round_trip_tests` (the same corpus
|
||||||
|
driven through the actual verbs — export → import → export over `v1_shipping.rsbank`
|
||||||
|
yields byte-identical payloads, and every refusal fixture refuses the whole import with
|
||||||
|
nothing landed and nothing in the index). A new repo-root `.gitattributes` (`*.rsbank
|
||||||
|
binary`) is load-bearing, not decoration: under `core.autocrlf = true`, git's NUL-sniffing
|
||||||
|
heuristic would text-classify a future short, ASCII-heavy fixture and CRLF-mangle it on a
|
||||||
|
Windows checkout, silently breaking the frozen-bytes premise the whole corpus rests on. A
|
||||||
|
standalone DAW verification script, `docs/verify-package-transfer.md`, covers the one
|
||||||
|
claim no unit test can make — a real cross-machine transfer, including the too-new
|
||||||
|
refusal, the truncated-download refusal, and mid-payload corruption, each read off as an
|
||||||
|
exact message string. **Open question resolved:** the recommendation (one-sample
|
||||||
|
packages, a few hundred bytes of payload each) was followed — the corpus holds
|
||||||
|
one-sample packages with a 300-byte payload each. **Deviation from spec:** the plan
|
||||||
|
called for a truncation cut mid-layout; RSBK stores no layout section (the layout is
|
||||||
|
derived from the manifest's entries, not stored as its own section), so the fixture that
|
||||||
|
exercises "the manifest parses, the layout computes, the exact-size proof fails" lands at
|
||||||
|
the payload boundary instead. No production module was touched — the wave adds test-tree
|
||||||
|
files, the corpus, its README, the verification script, and one path variable in the root
|
||||||
|
`CMakeLists.txt`.
|
||||||
|
|||||||
+14
-46
@@ -2404,6 +2404,9 @@ import gate can key on `LedgerStatus` alone without going through `pruneDryRun()
|
|||||||
enumeration+scan). **No Ε track touches `core/instrument/`, `shell/instrument/`, or any
|
enumeration+scan). **No Ε track touches `core/instrument/`, `shell/instrument/`, or any
|
||||||
capture backend.**
|
capture backend.**
|
||||||
|
|
||||||
|
**All three waves have landed — Phase Ε is complete.** W1 through W3 each carry their own
|
||||||
|
landed note below; see `docs/COMPLETED.md` for every track's full narrative.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Ε-W1 — The contract, the filesystem, and the ledger's new kind
|
### Ε-W1 — The contract, the filesystem, and the ledger's new kind
|
||||||
@@ -2568,52 +2571,17 @@ against a package this build is incapable of writing.
|
|||||||
**One track.** The whole deliverable is one corpus and the harness over it; splitting it
|
**One track.** The whole deliverable is one corpus and the harness over it; splitting it
|
||||||
would mean two tracks writing two halves of one fixture set.
|
would mean two tracks writing two halves of one fixture set.
|
||||||
|
|
||||||
#### Ε-W3-T1 — `package-compat-fixtures`
|
**Ε-W3-T1 has landed** — `package-compat-fixtures` — see `docs/COMPLETED.md` for the full
|
||||||
|
narrative. 23 frozen `.rsbank` fixtures now live under `tests/fixtures/package_compat/`
|
||||||
**Goal.** Turn the version-compatibility policy from an assertion in a doc into a property
|
(three version fixtures, nine truncations, eleven hostile-name packages, ~15 KB total),
|
||||||
proven against **frozen bytes**, so a later format change cannot silently break either
|
decoded by a new `package_compat_tests` and driven through export → import → export by a
|
||||||
direction.
|
new `package_round_trip_tests`, plus the DAW script `docs/verify-package-transfer.md` for
|
||||||
|
the one claim no unit test can make. A repo-root `.gitattributes` (`*.rsbank binary`)
|
||||||
**Spec:** `docs/product/bank-package.md` §"Version tagging: both directions".
|
keeps the frozen bytes frozen under `core.autocrlf`. No production module was touched.
|
||||||
|
**Open question resolved:** the recommendation was followed — the corpus is one-sample
|
||||||
**Surface boundary — owns:** a new checked-in fixture corpus under the package modules' test
|
packages with a 300-byte payload each. **Deviation from spec:** RSBK stores no layout
|
||||||
tree, the harness that decodes it, and one `docs/` verification script for the DAW half.
|
section (it is derived from the manifest), so the planned "mid-layout" truncation lands
|
||||||
**Does not own:** any production module — if a fixture reveals a defect, the fix is filed
|
at the payload boundary instead, where the manifest parses but the exact-size proof fails.
|
||||||
against the owning track's module and this track carries the failing test, not the patch.
|
|
||||||
|
|
||||||
**Behavior.**
|
|
||||||
- **Frozen bytes, not regenerated ones.** The corpus holds real `.rsbank` bytes committed to
|
|
||||||
the repo: a v1 package written by the shipping build, a synthetic
|
|
||||||
`formatVersion` = N+1 / `minReaderVersion` = current package (the additive-forward case),
|
|
||||||
and a synthetic `formatVersion` = N+1 / `minReaderVersion` = N+1 package (the refuse case).
|
|
||||||
A test that regenerates its own fixture proves only that the code agrees with itself —
|
|
||||||
which is precisely the failure mode a format ladder exists to catch.
|
|
||||||
- **A truncation corpus.** The valid package truncated at a spread of offsets, each asserted
|
|
||||||
`Malformed` rather than `TooNew`, so the two recoveries never get crossed.
|
|
||||||
- **A hostile-name corpus.** Packages whose entry names carry `..`, separators, and absolute
|
|
||||||
prefixes, each refused.
|
|
||||||
- **The round-trip anchor.** Export → import → export over the v1 fixture yields
|
|
||||||
byte-identical payloads.
|
|
||||||
- **A standalone DAW verification script** in `docs/`, following the
|
|
||||||
`docs/verify-track-scope-multitrack.md` precedent — the cross-machine transfer is the one
|
|
||||||
claim no unit test can make.
|
|
||||||
- **The corpus is append-only.** When a future format version ships, its fixture is added;
|
|
||||||
no existing fixture is ever regenerated or edited. Stated in the corpus's own README so the
|
|
||||||
rule survives the person who wrote it.
|
|
||||||
|
|
||||||
**Acceptance criteria.**
|
|
||||||
- All three version fixtures classify as specified, and the additive-forward one imports with
|
|
||||||
every known field intact and every unknown key skipped.
|
|
||||||
- Every truncation offset classifies `Malformed`; none classifies `TooNew`, `Readable`, or
|
|
||||||
crashes.
|
|
||||||
- Every hostile-name fixture is refused at decode, before any planner runs.
|
|
||||||
- The round-trip fixture's payloads are byte-identical after export → import → export.
|
|
||||||
- The DAW script exists and names its steps concretely enough to run without reading this
|
|
||||||
plan.
|
|
||||||
|
|
||||||
**Open questions.** **[propose at review]** how large the committed corpus is allowed to be —
|
|
||||||
the recommendation is one-sample packages with a few hundred bytes of payload each, since the
|
|
||||||
properties under test are structural and a large payload proves nothing extra.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user