writeonce/docs/stories/porch/10-memory-features-over-table.md
shoney.arickathil f3215c2f43 docs(status): master-only follow-ups to the 2026-09-15 cherry-pick
- the agent rename database-developer → codd (and its guide) happened inside
  lang-18's `aab4878` on dev, which stays there; the `docs(agents)` pick
  brought codd.md in beside the old file — remove the old name and its guide
- docs/stories/porch/09-idempotent-replay.md: added on dev by `79e6da4`, whose
  earlier pick onto master (`refactor(porch-store)`) landed without it — the
  board, porch 1 and porch 4 link to it
- docs/stories/porch/10-memory-features-over-table.md: the refine stub
  language 18's docs commit created on dev; the board and porch 00-story link
  to it, the code it waits on is not on master
- docs/examples/skill-catalog/README.md: the story link fix from `b3d8c40` that its
  earlier pick (`8311330`) dropped in conflict resolution — dev's version taken
- `just linkcheck` on master: every remaining broken link is a wmux story or
  spec (track not picked) or a developer-local `.dev/reference` symlink

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 01:24:36 +02:00

59 lines
2.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
track: porch
iteration: "10"
status: pending
readiness: refine
---
# porch 10 — memory features over `@table`: TTL cache, feature flags, durable jobs
> Part of [Story — `porch`, the writeonce web framework](00-story.md).
> **Stub, created 2026-09-11** by the language-18 re-brainstorm (fork 1): the
> three `.wo` pieces of
> [language 18](../language-runtime-database/18-memory-db-features.md) moved
> here; 18 keeps the language + engine half, `transaction { }`. Their spec
> text is Part B of
> [`2026-08-20-memory-db-features-design.md`](../../superpowers/specs/2026-08-20-memory-db-features-design.md);
> its jobs section is superseded (below).
## Carried over from 18, already settled — do not re-brainstorm
1. **Cache**: pure `.wo`, TTL + capacity, lazy expiry on read, FIFO eviction
over LRU (stated tradeoff), Text values (no generics), a time-injected
seam (`get_at`/`put_at`) so the fixture injects stamps instead of sleeping.
2. **Flags**: `@table(name: "wf_flags")` with `name @unique` and an Int 0/1
`on`; a read-through map filled on first read, updated in the same call as
the write. Framework tables carry the `wf_` prefix.
3. **Job row**: `wf_jobs` — `kind`, `payload` (Text, json), `attempts`,
`not_before` (wall ms, 0 = due). `enqueue` is an ordinary `insert` and is
what goes inside the business write's `transaction { }`.
## Re-settled by 18 on 2026-09-11 (fork 2) — the execution model
Drain-on-request and the `Dispatcher.idle()` seam are retired: they assumed
"no timers", which has been false since iteration 24. A job runner is an
**actor** the app spawns; the app `send`s it a poke *after* the block's
closing brace (a `send` inside the block is WO-E111 by design — the row must
be durable before anyone acts on it); the runner queries due jobs
(`not_before <= time.now`, `take budget`), deletes on success, bumps
`attempts` on failure, and re-arms itself with `time.after` for the earliest
`not_before` (one-shot, generation-counter idiom). The table is the durable
outbox; the poke is a hint — at boot the app pokes once and every survivor
runs without a request. The engine provides nothing new.
## To refine here (what makes this `ready`)
- Budget per drain and the backoff shape (app-side in v1 per the spec — keep
or move into the runner?).
- Where the runner lives (porch-owned actor class vs app-owned satisfying an
interface — the `Jr`/`Mw` wrapper pattern).
- The web-app demo and gate legs (order + `confirm` job in one block,
`kill -9` after the POST, restart, the job runs; flags across restart) —
these need 18's T1–T6 landed first.
- Whether porch 1's pool actor is the runner's home (serialize through the
same actor that owns store writes) or a second actor.
## Needs
Language 18 (`transaction { }`) for the demo's headline; nothing else beyond
what `spawn`/`send`/`time.after` and `@table` already provide.