Files
buzz/desktop
npub1cc3ha7z055mu0rwwu7806t2wt8mj3pvu0uv5mfp2c50dahaqhczshdalg6 1a2c86ebed fix(terminal): repair three defects the gate found in the work-bounded seam
All three were pre-registered predictions that the fixtures at a957d25b0 did
not cover, and each was independently reproduced before being fixed.

**Geometry ownership.** `Terminal::resize` took a whole `Size` and forwarded
two of its three fields to the feeder, so a scrollback change updated the
`Term` while the feeder kept charging its construction depth. That is most of
RIS's price -- 3,840 charged against 803,840 honest at 80x24 -- and because
`slice_bytes` is derived from the densest atom, it also left the *scheduler*
sized for the wrong grid: a stale 130-byte slice admits 65 RIS atoms where the
honest 4-byte slice admits two. The split was permanent; later resizes tracked
their own fields and never re-derived the third. `Feeder::resize` now takes
the whole `Size`, so there is one ownership boundary and no way to update two
of three.

A bound derived at construction from a value that can change afterwards is a
bound with an expiry date.

**Post-atom overrun.** Slices were sized against the whole budget, so a slice
could hold an oversized atom *and* the callbacks behind it: `ESC c` followed
by `Xmore` ran three callbacks where the law permits one. Width is now a
function of what *remains* of the budget, which is a single byte once an atom
worth more than the budget is in play. Two refinements the fixtures forced:
plain runs are metered by the plain-byte cost and stop at the next `ESC`
rather than being priced as though every byte might be RIS -- pricing them
that way is correct and costs 181 MB/s -> 69 MB/s for a bound on something
that cannot happen -- and the escape scan is capped at `MAX_SLICE`, because
searching the whole tail per slice is quadratic and measured as a 7x
regression, a bound costing more than the thing it bounds. A `mid_escape` flag
keeps a sequence split across slices on escape metering; without it the byte
after a lone `ESC` looks like text and the atom rides into a wide slice.

**Saturating arithmetic.** `columns * lines` was computed in `usize` before
the cast, and `Size` is unclamped with no caller bounding it. Debug panicked
inside the accounting path -- reachable from `drain`, which is the pump a
paused reader must keep calling -- and release wrapped. The wrap is the worse
half: it does not degrade the fence, it inverts it, because `slice_bytes`
divides the budget by the atom cost, so an undercharged atom yields a *wider*
slice exactly when the atom is most expensive. Convert first, saturate
throughout.

The fixtures are where most of the work went, because three of them had to be
rewritten after the obvious version passed on the broken tree:

* Resize is asserted by equality with a terminal *constructed* at the target
  depth, across charge and acquisition count -- stronger than any threshold
  and immune to the constants moving, since both arms move together. A sanity
  arm proves the comparison is deterministic first.
* Shrinking is asserted *directionally* after establishing a debt
  (shallow -> deep -> shallow). Equality would forbid conservative retention,
  and resizing straight down leaves a feeder indistinguishable from one built
  shallow -- which is also the signature of a feeder that never updated.
* `completed_units` is asserted but is explicitly *not* the discriminator: it
  reads the same in both arms, because the same callbacks run either way.
* Saturation asserts the direction -- widest atom, narrowest slice -- plus
  monotonicity across nine decades. "Does not panic" is satisfied by the
  wrapping version, which is the version that inverts the fence.
* Preconditions are asserted rather than assumed: the geometry must let the
  scheduling fields separate at all, and the payload must be RIS, the only
  escape reaching the only weight with a scrollback term.

24 mutants dead in debug and release, including one per repair.

Co-authored-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
2026-08-02 01:26:26 -04:00
..
2026-03-09 13:02:11 -07:00
2026-06-11 15:06:24 +00:00
2026-03-09 13:02:11 -07:00

Buzz

Desktop chat shell with:

  • Tauri + React + TypeScript + Vite
  • Tailwind CSS
  • shadcn/ui-ready shared components
  • Biome (lint/format/check)
  • Feature-driven frontend structure

Scripts

  • pnpm dev - run the web frontend
  • pnpm tauri dev - run the desktop app
  • pnpm build - typecheck and build frontend
  • pnpm typecheck - TypeScript checks
  • pnpm lint - Biome lint
  • pnpm format - Biome format (write)
  • pnpm check - Biome check

Structure

  • src/shared - reusable app-wide code (ui, lib, styles)
  • src/features - feature modules (vertical slices)
  • src/app - top-level app composition