Commit Graph

10 Commits

Author SHA1 Message Date
Claude (dbsp-backend) a020ac669f feat(incremental): Sum and Avg through an exact sum in both backends (improvise-hrjz)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-10-10 15:14:20 -07:00
Ed L 6dbbfdb6cb chore: more updates 2026-10-10 11:52:45 -07:00
Claude (agent-adr007) 7ddc50ac62 Merge commit '62066e1e1c972218b099a36f3f10440eb93d430e' into adr007/plan
# Conflicts:
#	context/code/core.md
#	context/test-evidence/core.md
2026-09-25 10:05:02 -07:00
Edward Langley 0ae25b99c5 chore: updating missing dep 2026-09-25 01:08:55 -07:00
Claude (agent-adr007) e56148fa64 feat(core): slugify and the gensym id allocator for ADR 007 (improvise-cq1q.2)
model::id adds slugify, which case folds, turns each run of spaces into one
`_`, strips everything outside a-z, 0-9, `-` and `_`, then drops leading
underscores. It also adds IdAllocator, which keeps one increment-only counter
per document plus every id seen this session; claim admits hand-written ids
verbatim. Full case folding comes from the unicase crate. Nothing calls it yet.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-24 22:02:32 -07:00
Edward Langley 6d5b4e328a improvise-km71: serde back in improvise-formula for FormulaId alone
tt22 removed the formula crate's serde dependency with the legacy JSON loader,
keeping serde only where a type crosses the wire. FormulaId crosses the wire, so
it is the third such type. No derive goes back on the formula AST.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-23 08:50:53 -07:00
Edward Langley f85fddbb2f harness/opfs-contract: refresh Cargo.lock for the dropped serde features (improvise-tt22) 2026-09-23 08:13:25 -07:00
Edward Langley 1550d390cb pr-reviews re-polls after a slow tick; the harness lock fails loudly
improvise-qnpi: `pr-reviews --wait` checked its deadline before the first
re-poll, so a second boundary between two reads of the clock skipped the
only poll (exit 1 with polls=1, reproduced under CPU load). The deadline
is now checked after each poll. A new case drives it with a PATH shim
whose `date` ticks one second per read, so it fails deterministically on
the old loop rather than under load.

improvise-mkbp: harness/opfs-contract/Cargo.lock pinned pest 2.9.1 while
its path deps require 2.9.2, so every build rewrote it. The resolved lock
is committed and build.sh starts with `cargo metadata --locked`; the
wasm-pack `-- --locked` route was tried and does not work (wasm-pack
re-resolves first). opfs.spec.js now names the fix when harness/serve/opfs
is missing, which is what running web/assemble.sh alone leaves.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-22 23:36:00 -07:00
Edward Langley fb507b9855 fix(opfs): a directory is not a document refresh could not measure
Copilot's second round on PR #24, and it found the hole in the previous
commit's own argument. That commit said an entry `refresh` cannot measure
counts as a document, "because the one cause is another tab holding the
exclusive handle". There is a second cause, and I missed it: **`keys()`
yields directories as well as files**, and `getFileHandle` on a directory
rejects with `TypeMismatchError`. So a directory would have been listed as
a document, and one can never be attached or read — the exact picker bug
the zero-byte filter exists to remove, reintroduced by the fix for it.

The two failures now get opposite answers, which is the whole of
`holds_bytes`:

- **`getFileHandle` fails** — the name is not a file. A directory, or an
  entry removed between `keys()` and here. Not a document; skip it.
- **`getFile` fails on a handle `getFileHandle` already returned** — the
  exclusive-lock case, a second tab of the same origin. That one still
  fails open, for the reasons the previous commit gives.

Argued *and* tested this time. `a_directory_entry_is_not_a_document` in the
harness makes a real directory in OPFS — `OpfsFs` has no directory
vocabulary at all, so the harness reaches `getDirectoryHandle` itself — and
asserts it is not listed, with a real file written beside it as the
precondition, so the check cannot pass by the directory never having been
created or by `keys()` walking nothing. Proved discriminating by flipping
the `None` arm back to `true`: it fails with `refresh() listed a directory
as a document: ["a-folder"]`.

Adding it also exposed that three checks were reading the leftovers of the
check before them — the battery broke the moment one was inserted in the
middle. Every check now wipes first, so the order of the battery is not
load-bearing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-19 23:03:34 -07:00
Edward Langley 7e991360df test(harness): a headless browser, and the first execution of OpfsFs
improvise-vvl3, absorbing improvise-xf1. The condition the user set when
deferring browser testing — "WE HAVE TO HAVE SOMETHING TO TEST" — has been
met: after improvise-9x6, djm, hwpi and the demo model there is a complete
self-contained application whose entire untested surface is what a harness
covers.

`python3 -m http.server` plus one Playwright project, in `harness/`:

  harness/opfs-contract/   a wasm crate that runs
                           `improvise_io::storage::contract::storage_contract`
                           against `OpfsFs` — the shared function, not a
                           transcription of it
  harness/www/opfs/        the page and the dedicated Web Worker it runs in;
                           `createSyncAccessHandle` exists nowhere else
  harness/tests/           two specs
  harness/build.sh         site + harness bundle -> harness/serve

It lives at the repo root rather than under `web/`, because `web/` is the
*source of what ships* and every file in it is copied to the site. The
harness serves the **assembled** tree (`web/assemble.sh`, extracted from
the CI workflow in this commit so there is one answer to "how is the site
arranged" rather than two) plus its own `/opfs/` — a harness that runs
against a different arrangement of files is testing something nobody
deploys. `harness/opfs-contract` is deliberately not a workspace member: it
only builds for wasm32, so a member would break `cargo test --workspace`.

What this runs that nothing has ever run:

- `storage_contract` against `OpfsFs`, at `""` **and** at `"docs"`. Two
  bugs fell straight out — improvise-vhcz's `list` path shape, whose fix
  the `"docs"` run guards (reverting it fails with `lists the one
  document`), and the zero-byte entry fix in the previous commit, which
  this found by failing on `starts empty`.
- The `keys()` async-iterator walk in `refresh`, hand-rolled through
  `js_sys::Reflect` and named by xf1 as the least certain code in the file.
  Three entries written out of order, so one passing by accident cannot
  carry it.
- `FileSystemReadWriteOptions`' `at` on read and write: a long write then a
  short one, which is where an append or a non-zero start shows up.
- `commit_deletes`, both halves — queued but still in OPFS before, gone
  after — and **across a reload**, which is the only way to ask whether
  OPFS persisted. That reload is also improvise-bck's persistence criterion
  at the storage layer.
- improvise-hwpi's three one-assertion shell tests, which that ticket said
  it could not write: status after a bad frame, status with no peer, one
  repaint on commit. Plus the first-frame watchdog, which was found by
  reading and only because someone went looking.

Check the checker, throughout, because a harness that passes against a stub
— or that silently skips because the worker never started — is exactly this
repo's characteristic defect wearing a green tick:

- `run_canary` deliberately fails, through the *same* reporting path every
  real check uses, and the spec asserts it is reported as a failure with its
  message intact.
- The spec asserts the report contains exactly the expected check names, in
  order, so a battery that quietly shrinks is a failure.
- Every shell assertion was injected and watched to fail: removing the
  bad-frame catch, the watchdog's `setTimeout`, the socket `error` listener
  and the `transport.send(frame)` on commit each fails its own test and
  only its own.
- The commit test types `20000` and asserts `20,000`, so a page that echoed
  what was typed instead of drawing what the host returned would fail.

One live bug is pinned rather than fixed. `a peer that cannot be reached`
asserts the *history* of `#status`, because improvise-m18f is real and
reproduced here: the socket's `close` listener overwrites the precise
"cannot reach" with "disconnected". That is filed and deliberately not the
same fix as the watchdog's (gotcha 48), so the test asserts both halves and
will speak up whichever one moves.

CI gets a `browser` job that can fail the build, and `pages-deploy` now
needs it. Playwright's Chromium download is ~80 MB and well under a minute
on ubuntu-latest, next to the two wasm-pack builds the job already needs —
so "impractical in this CI" does not arise. A harness nobody runs is worse
than none, because it reads as coverage.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-19 22:45:03 -07:00