Commit graph

8 commits

Author SHA1 Message Date
6b820fdd5f docs(porch-routing): brainstorm story 5 (routing + response ergonomics) to ready
- five decisions: head auto-registers with opt-out (+ patch/options/all);
  request ids mirror limiter trust model with a NON-crypto source; per-route
  body_limit is a SECOND check after routing (global BODY_MAX stays the
  pre-routing ceiling, over-limit = 413); Route fields are corpus-free;
  Vary accumulates by comma-join
- key finding: story 5 has NO upstream dependency, not even iteration 2 --
  request ids are not secrets, so a non-crypto source (time.ticks+counter)
  keeps it startable today; the one porch slice buildable right now
- three story assumptions corrected: per-route limit cannot replace the
  global (body read before routing); the container-owned-move corpus fixture
  has its OWN Route (adding fields is free); Vary needs no iteration 2
- validated against .dev/reference/fiber; zero language enhancement. Board synced

(cherry picked from commit 0589a13db1f3b7c220d9d9fdc76142af6a63c390)
2026-09-15 01:15:31 +02:00
274f7c5361 docs(porch-csrf): brainstorm stories 3 (sessions) + 4 (CSRF) to ready
sessions (3):
- six decisions: pure-auth-primitive row (no payload bag); wall-clock
  time.now not monotonic time.ticks (restart durability); login always
  mints a fresh id (fixation, no anon-session model); throttled last_seen
  touch at idle/20 (not a WAL write per request); Session writes
  req.principal; config refuses absolute < idle
- finding: no per-key actor pool, so NOT blocked on lang-41 (plain @table
  CRUD, same path storefront uses); the no-bag rule closes the one place
  fiber's Set(key,any)+msgp+RegisterType would have hit principle 13

csrf (4):
- five decisions: fiber's hybrid transport (session-stored CsrfToken
  @table + double-submit cookie, both must pass; no CSRF for sessionless
  apps); opt-in single-use (checkout example); double-click -> distinct
  SPENT refusal, NOT coupled to lang-41-blocked idempotency; trusted
  origin/referer/Sec-Fetch-Site second layer; refusal classes distinct in
  logs, opaque in body
- no actor pool, not blocked on lang-41

both validated against .dev/reference/fiber (v3, 3ca9a9d); exactly ZERO
language enhancement needed beyond iteration 2's random_bytes. Board synced.

(cherry picked from commit 3a4fb4215b23d2516362e2dd0acc5bec6c9aebc0)
2026-09-15 01:15:31 +02:00
6a67db252b docs(porch-cookies): brainstorm story 2 (randomness+cookies) to ready
- five forks locked: cookies: multi SetCookie beside unchanged headers
  map; bare-name random_bytes(n)->Bytes; structural-400 in parse_request
  + on-demand cookie() helper; base64(value).base64(mac) signing;
  app-supplied key, no middleware (that is iteration 3)
- validated against .dev/reference/fiber (v3, 3ca9a9d): exactly ONE
  language enhancement needed (the CSPRNG); repeated Set-Cookie, cookie
  attributes, parsing and signing all map to existing primitives
- corrects phase A registry: random_bytes joins the crypto-family
  bare-name table (emit.ml b_* + types.ml), NOT wob.h's module enum;
  next free id 84/90, not 110
- board: story 2 marked ready, porch-2 row rewritten off the stale
  wob.h/110 claim

(cherry picked from commit 4d31d5359436496aed40cb25611abc7ccd4d7875)
2026-09-15 01:15:30 +02:00
84cfbb1885 docs(porch-store): saturation gate leg closes out porch 1
- Add saturation leg (scripts/web-app-accept.sh): one-actor pool,
  WO_MAILBOX=2, 15 concurrent requests, exactly 3 served + 12 answer
  503; execution count matches the 200 count, retry-after + real
  cause verified on the 503s
- Guard make_pool(n<1) by clamping in make_pool itself, not
  pool_select's division -- that trap runs inside the middleware's
  own try/catch and would be swallowed as ordinary saturation forever
- README: rate limiting + idempotency ledger rows moved to done,
  scoped to what the gate proves; documented Handler-decorator
  shape, Pool aliasing (WO-E222), call's scalar-only reply (WO-E226),
  pool size as a capacity decision
- Story: Progress table filled with real hashes, 7/9 acceptance
  criteria marked verified with citations, 2 marked verified by
  construction (never gated even in the original plan), status: done
- Status board: standup entry, porch 1 pending row updated
- Recorded a pre-existing runtime hang (main() returns cleanly, OS
  process sometimes hangs under concurrent call()-parked callers)
  that also reaches the new leg's teardown; contained with kill -9
  rather than asserted, so it can't flake the leg's actual subject

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 21934b18910070a3f24b8bd4367fcb9d397dc1fb)
2026-09-15 01:15:30 +02:00
8311330531 docs(db2-keys): reconcile databasev2 and porch markdown with the code
- loader's resident:keys refusal said "rows are still fully resident"
  and "until tasks 5c/5d land". Both false since f606fc9. Corrected to
  name the real blocker: UPDATE needs read-modify-append
- databasev2 00-story: the sequence graph drew 2->3->4, which reads as
  3 needing 2 and 4 needing 3. Both backwards, and it still drew the
  2->5->6 path the 2026-08-27 amendment retired. Redrawn stating only
  real dependencies, with 4 and 3 shown as composing rather than
  ordered, and the execution order that actually happened
- databasev2 03: the hazard and its Outstanding entry both claimed
  nothing fails "because iteration 2's storage half is unimplemented".
  Marked discharged, and recorded that the hazard named only half the
  danger — the bitmap walk would have dropped keys rows outright
- databasev2 06: pending -> hold (largely superseded, revisit only on
  a measurement); dated its 5c/5d references
- porch 01: rewritten to the settled shape. readiness ready, status
  in-progress, phases B and C marked superseded with why
- porch 01 claimed time.after "is still a reserved builtin id". False —
  builtin 90, implemented. That claim is what made the iteration look
  cheaper than it is
- porch README gains honest ledger rows for both features (partial,
  being rebuilt), not shipped
- skill-catalog README pointed at a story path that moved tracks;
  linkcheck now 0 broken

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit b3d8c403e1d19ac27ec966de85cb293e0765795c)
2026-08-30 20:36:55 +02:00
1fe808b7a4 docs(stories): add readiness, retire status: refine, sweep all 47 iterations
- `readiness: ready | refine` is a SECOND axis, orthogonal to status.
  `ready` = the brainstorm is complete and the decisions are LOCKED (a spec
  approved, or the forks explicitly confirmed). `refine` = open forks remain
  and it cannot be planned yet
- `status: refine` RETIRED because it carried both meanings at once, so a held
  iteration with an approved spec (language 18, 26) was indistinguishable from
  one nobody had thought about. status is now purely where the WORK is:
  done | in-progress | pending | hold — `pending` was already the board's own
  rendering word, so nothing new was invented
- all 47 iterations classified from EVIDENCE in their own text, not by guess:
  "the four forks are SETTLED" / "spec + plan approved" / "Approved spec:" for
  ready; "Forks the spec must settle" / "no spec exists yet" for refine. Every
  shipped iteration is ready by definition. 19 done, 5 in-progress, 15
  pending, 8 hold; 27 ready, 20 refine
- two iterations moved refine -> in-progress rather than -> pending: language
  31 and 34 are absorbed into 24 and work on them is literally happening, which
  the board already showed as 🔄 while their frontmatter said otherwise. That
  disagreement is now gone
- board legend, board-views' frontmatter contract, and two new Dataview
  queries updated — the useful one being `readiness: ready AND status:
  pending`, the startable set

WHAT THE NEW AXIS IMMEDIATELY SURFACED: of 15 pending iterations, exactly ONE
is startable — databasev2 4, io_uring group-commit, whose forks were confirmed
settled 2026-08-20. Everything else pending needs a brainstorm first. That was
invisible while one key carried both meanings, and it is now on the board.

Also caught by the sweep, unrelated to readiness but found by cross-checking
frontmatter against the board: SIX duplicate rows. Every iteration moved into
databasev2 was still listed in the LANGUAGE pending table under its retired id
(23, 32, 33, 20, 21, 27) as well as its new one. Stale copies removed. And two
databasev2 rows made claims the sweep contradicts — iteration 1 was billed
"startable today" while its forks are open, and 6 still called itself the
ceiling-raiser after 2 took that role.

Docs only. linkcheck 0 broken / 0 anchors.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 16:54:45 +02:00
746dc2b42b docs(databasev2): third track — the database beyond RAM, with per-table storage modes
- docs/stories/databasev2/, numbered from 1. Six PENDING database iterations
  moved from the language track and renumbered, keeping the old id in
  `was_language_iteration:` so a search for "iteration 32" still finds it:
  32 -> 3 WAL checkpoint, 23 -> 4 io_uring commit, 33 -> 7 single-file store,
  27 -> 8 query grammar, 20 -> 9 cross-program, 21 -> 10 keypair auth.
  Done work (9, 9b, 22) stays as v1 history; language 18 left whole
- the problem, read off the engine not guessed: rows are malloc'd slabs with
  addresses stable forever, NO eviction/spill/paging anywhere in database/src,
  the WAL never checkpoints so boot replays all history, and durability is one
  process-global WO_DATA so no table can say it matters more than another.
  An allocation failure IS a clean catchable WO_T_OOM — but swap thrash
  arrives first and carries no error signal at all, which is the real hazard
- four new iterations:
  1 measure the ceiling FIRST (curve not cliff; the three exits; kill -9 at
    exhaustion) — every later default should follow from a number
  2 `@table(mode: ram | durable | cold)` — the grammar ask. Small surface
    (Ast.table_cfg gains a key, the parser already rejects unknown args), big
    semantics: `durable` defaults so nothing changes silently, and the
    compiler refuses a durable row holding a `ref` into a ram table
  5 bounded tables + refuse/evict/back-pressure, shedding BEFORE the OS acts
  6 cold tiering — mostly forks, incl. whether the language surfaces the
    fault cost and whether @unique on cold is refused outright. A paged
    B-tree stays rejected: if tiering needs one, reject tiering
- 39 links repointed, link TEXT renumbered to track-local ids; arc gains one
  pointer row replacing the six moved; board + board-views cover three tracks
- linkcheck 0 broken / 0 anchors; no code blocks in any story

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 20:52:48 +02:00
01df75245f docs(porch): give the framework its own story track, iterations 1-8
- docs/stories/porch/ — a TRACK folder, not a status folder: status still
  lives only in frontmatter. Adds `track: porch` so a query over
  docs/stories/ can tell a porch 3 from a language 3
- 00-story.md carries the sequence, the dependency graph, and a table of
  what the track explicitly does NOT own (binding -> 29, cache -> 18,
  proxy -> 38, metrics -> 30, TLS/templates -> doctrine)
- eight iterations, each with phases, per-phase tasks, Given/When/Then
  criteria, out-of-scope and the forks a spec must settle:
  1 store-backed middleware (limiter + idempotency — needs nothing new,
    first on purpose so the store pattern is proven cheaply)
  2 randomness + cookies (phase A is language-track: a CSPRNG builtin;
    `Resp.headers` being a map cannot emit two Set-Cookie lines)
  3 sessions   4 CSRF   5 routing/response ergonomics (independent)
  6 streaming core (the seam 7 and 8 wait on; chunked-request refusal
    must survive)   7 SSE + compression   8 static + lifecycle hooks
- language iteration 39 -> status: hold, retitled superseded, with a row
  mapping each of its goals to the porch iteration that took it. Kept, not
  deleted: the Fiber study cites it and its randomness argument is what
  this track is built on
- board gains a porch section; board-views gains porch and both-track
  Dataview queries; porch README and the Fiber study §7 point at the track
- no code blocks in any story (plans carry concept and actions in words);
  linkcheck 0 broken / 0 anchors

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 20:17:33 +02:00