Parents and children of check-in [7363238ad5]
|
2026-07-31
| ||
| 20:54 |
merge logstore-open-cost: header-only open scan and the verify verb
Opening a repository checksummed every payload byte, so open cost scaled with the whole store rather than with what the caller asked for. The append path now scans header-only: 10k frames 42 MB 42.2ms -> 11.2ms 10k frames 410 MB 298.0ms -> 12.7ms 100k frames 416 MB 511.9ms -> 119.2ms 100 frames 419 MB 321.4ms -> 0.10ms openReadOnly -- the path every CLI verb reaches -- deliberately still verifies payloads. Nothing has moved on the production path yet. That is Slice 2, and it is gated on this merge's other half: zit verify, the on-demand fsck that has to exist before eager detection is removed. The 100k-frame run settles a question the plan left open. Slice 4's gate was 'build the sidecar index only if that shape exceeds 150ms after the scan change'; it lands at 119ms. The sidecar is dead, and mmap with it -- separately, a mapping would keep shunned bytes resident and readable until every mapping dropped, which defeats the reclamation guarantee rather than merely slowing it. Both should be recorded as evaluated-and-rejected at the logstore extension comment; that is not done here. Also adds --mode append|read-only to the open benchmark. Every open number this effort had produced measured LogStore.open, which no CLI verb enters; the two modes agreed within noise before the scan change, which is what makes the after numbers above a comparison rather than two guesses. Verified on the merged tree: fmt clean, test 2327/2327. gate 19/19 and e2e 671/671 were watched green at the branch tip, which is content-identical -- trunk did not move between the branch point and this merge. check-in: 90bd1b8015 user: dmestas tags: trunk | |
| 19:23 |
bench: measure openReadOnly, not just open
benchOpen timed LogStore.open -- the append path. Production never takes it: Repository.open falls back to openReadOnly, and Repository.logStore, the lazy content channel behind blob, cat, checkout and sync, calls openReadOnly with no cache in front. Every open number this effort has produced described a path no CLI verb enters. That was survivable while the two paths ran the same scan. It stops being survivable the moment either one scans header-only, at which point the bench would report the optimized path while production still paid the full cost. --mode append|read-only defaults to append so existing invocations report unchanged numbers, and the mode is in the output line because the two are only comparable when a captured log can tell them apart. Calibration on this tree, before any scan change: the modes agree within noise on all four shapes -- run B is 1% apart. That agreement is the check that the flag measures what it claims. check-in: e56a663b7a user: dmestas tags: logstore-open-cost | |
| 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 | |
| 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 | |
|
2026-07-30
| ||
| 21:47 |
release_assert: a guard against assert used as input validation
std.debug.assert is right for an internal invariant and wrong for a rule about data the function did not produce, and it is wrong in two different ways. Under the ReleaseSafe default it survives and PANICS: on the write path that is the trade we want, a crash over a durable bad frame, but on a peer-reachable path it is a remote denial of service. Under an explicitly chosen --release=fast it compiles to nothing and the input flows through unvalidated. One fix, a checked error, closes both. Flags an assert only when all of: the fn is pub, returns an error union so a rejection was already available, the assert names one of its own parameters, and no earlier return in the body already rejects on that parameter. That last rule is what makes it signal -- delta.applyCopy returns MalformedDelta and then asserts to restate it, which is the CORRECT shape and must not be flagged. The baseline is keyed on file, function and COUNT, never on line numbers: line numbers churn on every edit above them, while a count still catches a second bad assert added to a function that already has one. It fails in both directions, so a fixed finding must be removed from the list and the list can only shrink. Existing findings are recorded, not fixed. Triage belongs in issue 19, where the ReleaseSafe default already reduces the write-path subset to crash-instead-of-corrupt and leaves the sync-side ones as the live exposure. check-in: 949e2b5542 user: dmestas tags: trunk | |