| Comment: | merge trunk: shun, the release-assert guard, and the split test lanes
Trunk since d186a44e brought the repository shun table and its whole- branch verification fixes, the release-assert guard, the `test`/`gate` lane split, the structurally bounded logstore priority window, and the vendored crc32. Eight files conflicted. The decisions worth naming: Lanes. `git-import-e2e` was a compile-only proof hanging off `test`; that is exactly the cost trunk moved to `gate`, so it moves with `e2e` and `smoke`. `import-git-bench` stays on `test` because it registers a real unit-test run rather than a compile proof. `declared_steps` is the union plus `gate`. Sync ingest. Both sides rewrote it: trunk added the §7.7 receive-side shun admission, this branch added §7.1 phantom minting for a pushed tree's missing sub-manifests. They compose in one direction — admission is asked first, so a card §7.7 refuses is never stored and mints no phantoms either. The S references of an artifact this repository declines to hold are not names it should then go begging for. Client construction. Trunk factored the three verbs' `Client` literal into `syncClient` and threaded `RepoAdmission`; this branch had widened `project_code` into `RepoSyncIdentity`. The helper now carries both, which is what trunk's own comment asked for: three copies of that literal is how a repository filter comes to be wired into two verbs and not the third. Per-round server refresh. Trunk made the snapshot mandatory — `error.ServerStorage` rather than serving with no shun table — where this branch read its four sub-manifest fields through fail-open defaults. Trunk's reading wins for all six fields: serving a stale default is the failure, not the fallback. Two guards trunk owns caught real defects in this branch's code, which is the whole point of them: The total switch in `shunConsequence` refused to compile against the `submanifest` artifact type, exactly as its comment promised. It has an arm now. The release-assert guard found nine asserts on untrusted input across six functions. Two were reachable faults, not style: `lookupTree` asserted §4.4 on a sub-manifest a peer supplies, so a malformed node panicked a ReleaseSafe reader and was walked anyway under `--release=fast`. It returns `SubUnresolvable` now, which §5.2 already defines as "absent, or is not a SUBMANIFEST". The empty-S-run assert became an early `null`. The two sub-manifest writers refuse an empty group through a new `SubmanifestWriteError` rather than asserting; the builder's internal path keeps its allocation-only surface through `serializeLeafCore`, since the partitioner is what establishes non- emptiness there. The rest were tautologies or restatements of invariants the card parser already enforces, and now say so in a comment instead of carrying a panic. Verified on the merged tree: `gate`, `e2e`, `dst` (6 seeds x 1000 steps), `smoke` (S1-S10, including trunk's new shun interop), and `git- import-e2e` all green, `zig fmt --check` clean. Beyond the suite, the importer was run for real: the empty-email repro imports and its check- in carries `U mohye77`, and marktext imports end to end with the analyzed pin at k=5. |
|---|---|
| Timelines: | family | ancestors | descendants | both | sub-manifest |
| Files: | files | file ages | folders |
| SHA3-256: |
562cf5be74e7f40f59cad5237df8dd62 |
| User & Date: | dmestas on 2026-07-31 04:56:22.246 |
| Other Links: | branch diff | manifest | tags |
|
2026-07-31
| ||
| 19:06 |
import-git: the payload refusal names its numbers
ExportPayloadLimitExceeded was a bare error name. Importing sqlite cost 17 minutes to learn a single integer, and the operator still had to guess it: the stream is 12.2 GiB against a 4 GiB default. One error carried two unrelated bounds. max_total_data is the operator's --max-export-payload-bytes; max_data is a fixed 1 GiB per-payload ceiling no flag reaches. Reporting the wrong one sends an operator to a knob that cannot help, so PayloadOverrun records which bound refused, and the single -payload arm says plainly that no option raises it. The cumulative arm refuses to name a remedy value. Parsing stops at the overrun, so the observed total is a lower bound; 'above 9' would name a number that fails again. It reports the bound and says the full payload is larger, which is the honest shape of what the parser knows. Also corrects the budget's own doc comment, which claimed four GiB was 'the working set an import may claim on a commodity machine'. Measured resident size importing sqlite's 12.2 GiB stream: 21 MiB. Payload is streamed and released per event. What the cumulative half actually bounds is total history, so the default over-provisions memory by three orders of magnitude while refusing a mainstream repository. check-in: ee703cde16 user: dmestas tags: sub-manifest | |
| 04:56 |
merge trunk: shun, the release-assert guard, and the split test lanes
Trunk since d186a44e brought the repository shun table and its whole- branch verification fixes, the release-assert guard, the `test`/`gate` lane split, the structurally bounded logstore priority window, and the vendored crc32. Eight files conflicted. The decisions worth naming: Lanes. `git-import-e2e` was a compile-only proof hanging off `test`; that is exactly the cost trunk moved to `gate`, so it moves with `e2e` and `smoke`. `import-git-bench` stays on `test` because it registers a real unit-test run rather than a compile proof. `declared_steps` is the union plus `gate`. Sync ingest. Both sides rewrote it: trunk added the §7.7 receive-side shun admission, this branch added §7.1 phantom minting for a pushed tree's missing sub-manifests. They compose in one direction — admission is asked first, so a card §7.7 refuses is never stored and mints no phantoms either. The S references of an artifact this repository declines to hold are not names it should then go begging for. Client construction. Trunk factored the three verbs' `Client` literal into `syncClient` and threaded `RepoAdmission`; this branch had widened `project_code` into `RepoSyncIdentity`. The helper now carries both, which is what trunk's own comment asked for: three copies of that literal is how a repository filter comes to be wired into two verbs and not the third. Per-round server refresh. Trunk made the snapshot mandatory — `error.ServerStorage` rather than serving with no shun table — where this branch read its four sub-manifest fields through fail-open defaults. Trunk's reading wins for all six fields: serving a stale default is the failure, not the fallback. Two guards trunk owns caught real defects in this branch's code, which is the whole point of them: The total switch in `shunConsequence` refused to compile against the `submanifest` artifact type, exactly as its comment promised. It has an arm now. The release-assert guard found nine asserts on untrusted input across six functions. Two were reachable faults, not style: `lookupTree` asserted §4.4 on a sub-manifest a peer supplies, so a malformed node panicked a ReleaseSafe reader and was walked anyway under `--release=fast`. It returns `SubUnresolvable` now, which §5.2 already defines as "absent, or is not a SUBMANIFEST". The empty-S-run assert became an early `null`. The two sub-manifest writers refuse an empty group through a new `SubmanifestWriteError` rather than asserting; the builder's internal path keeps its allocation-only surface through `serializeLeafCore`, since the partitioner is what establishes non- emptiness there. The rest were tautologies or restatements of invariants the card parser already enforces, and now say so in a comment instead of carrying a panic. Verified on the merged tree: `gate`, `e2e`, `dst` (6 seeds x 1000 steps), `smoke` (S1-S10, including trunk's new shun interop), and `git- import-e2e` all green, `zig fmt --check` clean. Beyond the suite, the importer was run for real: the empty-email repro imports and its check- in carries `U mohye77`, and marktext imports end to end with the analyzed pin at k=5. check-in: 562cf5be74 user: dmestas tags: sub-manifest | |
| 03:13 |
fast-export: accept an author with an empty email
parseIdentity refused an identity carrying an empty address twice over, once as `open + 1 == close` and again as `email.len == 0`. That is not malformed input. Setting `user.email` to the empty string is ordinary git configuration; `git fast-export` writes the identity with an empty angle-bracket pair, and `git fast-import` reads that same stream back to the same commit. The construct is valid by git's own definition on both sides of its own tooling, and we rejected it. The cost was not cosmetic. Two such commits, reachable only through a merge's second parent, aborted the import of an entire 437 commit repository with `import-git: import failed: Malformed`, naming neither the line nor the rule. Only the email clauses are relaxed. The name clauses stay: git's own porcelain refuses an empty ident name, and the importer maps the identity's name onto the U card login, so a nameless identity would produce a nameless check-in. The two questions were conflated in a single condition, which is a large part of why this went unnoticed, so the guard now separates them and says why. This is the third defect on this branch of the same shape: a property of our own fixtures promoted into a rule about the world. The first two were bounds tuned to the width of our benchmark corpus. This one is sharper, a refusal of input the tool we integrate with emits by default. Every identity fixture in the parser tests carried a non-empty email, so a uniform corpus could not falsify a rule that keys on emptiness. Both tests are witnesses rather than decoration: each fails with Malformed against the previous parser and passes against this one. The unit test pins the construct and the empty-name refusal beside it; the differential test has git itself produce the commit and then asserts the imported check-in carries the login mohye77 rather than an empty user. check-in: 1f21f96558 user: dmestas tags: sub-manifest | |
| 02:43 |
build: split the unit lane from the full gate
zig build test was 9m13s, and the tests it actually ran were a small fraction of that: it also compiled the e2e and smoke harnesses in the pinned ReleaseSafe and then never executed them. test is now unit tests only -- 2m54s cold, 1m42s warm -- and the new gate step carries those two compile proofs. The dst, bench and smoke UNIT tests deliberately stay on test. They are unit tests despite their siblings' names, zig build dst/smoke run the simulation and the interop check rather than them, and CI invokes the lanes one by one and never invokes gate -- so moving them would have dropped them from CI while every step still looked green. ci_test's declared_steps records gate as intentionally not-in-CI, and names that failure mode for the next lane someone adds. check-in: 7363238ad5 user: dmestas tags: trunk | |