Changes touching this path
- TS SDK slice 1: in-memory public read against a real relay (#423)
Completes the slice-1 tracer bullet on top of the landed WASM core: an
in-memory agent connects to a relay and reads a public file byte-for-byte
with no .loot/ on disk. The single passing read() exercises the whole
stack — WASM codec + fetch transport + client-side path-scoping + AES
decrypt + host-side zstd inflate.
- loot-wasm: add encode_fetch_request so the /fetch wire framing (version
marker + have/wants) stays single-sourced with the binary; frozen-vector
parity added (native + wasm-pack test --node).
- sdk/ (@millerbyte/loot-sdk, ESM): connectRelay(url, identity) -> LootRepo
with list() and streaming read()/.bytes(). Transport speaks the relay HTTP
wire via fetch(); loot-net never crosses. Client-side path-scoping (#380):
a metadata fetch resolves path->oid, a scoped fetch pulls just that object's
bytes (both have=[], since the relay gathers objects+keys from the changes
not in `have`). zstd inflate is host-side (fzstd) — the wasm core has no zstd.
Typed errors (LootError/TransportError/NotFoundError/AuthError, #382).
- Seam 1: a vitest suite drives the real `loot serve` relay, seeded via the
real `loot` CLI (init -> author -> new -> push); 4 tests green (list, byte-
for-byte read, streaming, NotFound). The wasm pkg is built by
`npm run build:wasm` (gitignored, regenerated from crates/loot-wasm).
Deferred to later slices: write path, private/grant read, physical backend.
Refs #423, #421.
db75b0b7 · dbf3dbe6… - a stale core stops saying grantSealed and starts saying rebuild: the SDK suite stamps what it was built from (#914)
sdk/wasm/ is generated by wasm-pack from crates/loot-wasm and ignored by git AND
by loot, so it is the one input to the SDK suite that no checkout, land or lane
spawn ever updates — and nothing checked it. The failure did not look like
staleness: measured during #880, an out-of-date core produced 14 failures inside
test/grants.unit.test.ts naming an arity mismatch on grantSealed, which reads as
a defect in sealed-grant handling. It cost a diagnosis aimed at the most
security-sensitive code in the repo, for a bug that did not exist.
So the value is not preventing the stale run, it is making the stale run SAY SO
— the same shape as #843 and #847. `build:wasm` now records a stamp of what it
built from; `pretest` compares it and refuses, naming the rebuild and the #880
misdiagnosis so the next reader does not repeat it.
Content stamp, not mtime: this repo materializes whole trees routinely (every
lane spawn, adopt, op restore), so mtime would cry stale on a correct build
several times a day, and a guard that fires on a healthy tree gets switched off.
The hash covers loot-wasm path-dependency CLOSURE (walked, so a new path dep
joins on its own) plus the workspace manifest and lockfile — not all of crates/,
which would demand a 30s wasm rebuild every time an unrelated crate moved.
Proven in a lane: not-built refuses before vitest, a real wasm-pack build then
passes the check, and one appended line in loot-codec is caught. The behaviour
suites additionally need target/release binaries in the checkout — README now
says so, since a fresh lane fails them with ENOENT until cargo build --release
runs.
151884a4 · dbf3dbe6…diff - the runner major was the whole chain: sdk npm audit goes to zero, and 92/92 says the bump is safe (#951)
Seven vulnerabilities, and they were not seven problems. `npm audit fix` cleared
the two in-range ones (nanoid 3.3.16 -> 3.3.18, postcss 8.5.21 -> 8.5.26, a
two-entry lockfile diff, package.json untouched) and the remaining five were one
chain: esbuild <=0.24.2 through vite <=6.4.2 through vitest, four of the five
being nothing but that dependency reported at each hop.
So the decision was never five decisions. It was one: does the suite survive
vitest? The ticket said decide it on evidence, so it was measured rather than
argued.
vitest 2.1.x -> 4.1.10 (two majors)
baseline in the lane 58 passed | 34 skipped
after the bump 58 passed | 34 skipped (identical)
with the release binaries built so the behaviour suites can run:
9 files, 92 PASSED (92)
npm audit 0 vulnerabilities
tsc --noEmit clean
Not an overrides pin, which is how site/ solved the same advisory in #916: there
every declarer accepted the patched range, so the override violated no
constraint. Here the patch is esbuild 0.25 and vite 6 asks for ^0.24.2, so an
override would have forced a version outside a declared range and called it
fixed. The runner bump keeps every constraint satisfied and leaves nothing
pinned for the next person to re-read.
The lockfile diff is large and it is one thing: vite 8 swaps the bundler, so
esbuild and rollup leave entirely and rolldown arrives (38 added, 60 removed, 17
changed; 73 packages total, down from 95). Reviewed rather than absorbed (#894)
— the only package.json change is `vitest ^2.1.8 -> ^4.1.10`.
⚠ Measured against a FRESH wasm core, deliberately: #914's stamp gate now
refuses a stale one, and diagnosing a runner bump through a stale core is
exactly the misdiagnosis that ticket exists to prevent.
ec26fa25 · dbf3dbe6…diff - the figure the #1890 verdict rests on is now a column in the table it was missing from, taken the way that table was taken: the pre-#1572 clone spelling put back and the ignored sweep run once per arm, which reads the splice band at 41.3, 39.2, 38.0 and 37.2 percent of its own region on the before binary against 11.2, 6.2, 3.4 and 1.3 shipped, so the 37 percent the conclusion turned on is readable from the tree instead of from a session transcript, and the re-take reproduced every before and after cell already there to within one allocation. THE VERDICT IS NARROWED TO WHAT THE COUNT SHOWS: withdrawing the band ceiling and confirming the clean delta are separate acts and only the first was done, because a count does not convert to milliseconds - what is retired is a contradiction between two readings rather than the spread among the timings, and the published magnitude stays where they left it. two precision defects in the #2242 retraction go with it: the move over that size range is about 4.8x in the call and about 3.4x as a process and the sentence now names which, and rests on one reading is withdrawn because #2223 records no repetition count for its whole-verb rows, so what is known is that the figure does not reproduce and not how it was taken. the sweep doc had its axes inverted against the code under it and now states the property instead, that the shapes fall into runs holding one axis while the other moves, and the list class is answered for the third time in this run by replacing the two named untimed controls with the questions that decide membership. the duplicated in-loop guards are extracted: prove_the_position_has_not_ingested and prove_the_tip_was_spliced are asked by the timing and the count alike, each refusal written once and true of both. the named positive control is refused rather than built, because an in-tree knowingly worse arm means a wrong body in production code, and the before column now published stands in its place. sdk records the node type-stripping floor its .ts import imposes in engines, where npm reads it. red under mutation, counts read each time: the position control inverted failed all three allocation pins (0 passed and 3 failed, naming a position holding 1 change), and the splice control fed a false answer failed all three on its new text (0 passed and 3 failed), each restored to 3 passed. no migration, no wire or format byte moves and no host behaviour moves, so this owes no deploy. the workspace suite is green (4179 passed over 133 binaries, 9 ignored) (#2247)
c8b11725 · dbf3dbe6…diff
Renames are not followed. loot's tree maps a path to an address, so a rename is a delete and an add. This list is the history of the name, not of the bytes.