diff --git a/packages/chord/docs/next/decisions.md b/packages/chord/docs/next/decisions.md index e1807c69a..db1ef860f 100644 --- a/packages/chord/docs/next/decisions.md +++ b/packages/chord/docs/next/decisions.md @@ -1679,6 +1679,10 @@ validation and copies the v2 kernel added around Delta. and behaviour (`abortTask`): a running run's abort is stored and its signal fired, resolving `"marked"` once `run` settled; a finishing run is only marked; a blocked run is dropped (`"marked"`, as Durable's orphan); no unsettled run with that id resolves `"terminal"` (Chord keeps no settled runs, Q9). Supersedes "job.abort stays until 6b". +- **Slice 6b D8: deferred persistence of a run's state, per change (owner, 2026-10-27: "agree"):** `ctx.state.change(fn, + ctx, { persistence: { kind: "deferred", withinMs? } })`, Durable's `CommitPersistence` shape (default 1,000 ms): + adopted and published at once, stored with the next immediate change, before the outcome is recorded, at close, or + after `withinMs`; a crash loses what is not stored. Only run state documents for now. - **The performance and memory bar, and converging reviews (owner, 2026-10-27: "yes"):** supersedes "as good as HEAD in everything" for Chord v2 slices and pi changes. CPU: each hot path (calls, changes, watches, links) within about 5% of HEAD, measured in bursts with alternating processes pinned to one CPU; worse is fixed or goes to the diff --git a/packages/chord/docs/next/design.md b/packages/chord/docs/next/design.md index d98f43e86..5e646fb5b 100644 --- a/packages/chord/docs/next/design.md +++ b/packages/chord/docs/next/design.md @@ -1446,8 +1446,9 @@ host.serve(ChatStore, ({ conversation }, self) => { // local: no princi cut off by a crash: `restarts + 1`, stored, then it resumes (rerun or abandon); a clean close writes its stopped runs back so the next activation counts nothing; a `ctx.state.change` (progress) resets the count; at five in a row the run ends with `failed { kind: "restart_limit", restarts }`, `finish` runs, `job_interrupted` is reported (no - parking, as Durable since #11139). A persisted state document may use the deferred - persistence option (stored within about a second, flushed before the outcome is recorded). + parking, as Durable since #11139). A persisted state document may defer storing a change + (`ctx.state.change(fn, ctx, { persistence: { kind: "deferred", withinMs? } })`, Durable's shape, default 1,000 ms; + stored before the outcome is recorded; slice 6b D8). - **Chaining:** `finish` may `tx.start` the next job, atomically with the outcome (separate steps, branches). - **Not jobs:** request/response work (a method), standing behaviour (a routine), input into running work (a flow, §20: the owner's document plus methods), multi-step durable work with sleeps, waits or ownership trees on a host diff --git a/packages/chord/docs/next/slice-6b.md b/packages/chord/docs/next/slice-6b.md index 1800397d1..b9d6e902e 100644 --- a/packages/chord/docs/next/slice-6b.md +++ b/packages/chord/docs/next/slice-6b.md @@ -188,12 +188,11 @@ same; Durable throws for an unknown one). - **Deferred state persistence:** -> **Decision needed (D8).** Design §15: "a persisted state document may use the deferred persistence option (stored -> within about a second, flushed before the outcome is recorded)", as Durable's `CommitPersistence` `deferred`. -> Options: (a) per change: `ctx.state.change(fn, ctx, { persistence: { kind: "deferred", withinMs? } })`, as Durable's -> commit option; (b) per definition: `defineState(..., { persistDeferred: 1000 })`. Proposal: (a), Durable's shape: a -> deferred change is adopted and published at once, stored with the next immediate change of the document, before -> the outcome, at close, or after `withinMs` (default 1,000 ms); a crash loses it (acceptable for progress output). +**Per change, Durable's shape (D8, owner, 2026-10-27):** `ctx.state.change(fn, ctx, { persistence: { kind: +"deferred", withinMs? } })` (default 1,000 ms, as Durable's `CommitPersistence`): adopted and published at once, +stored with the next immediate change of the document, before the outcome is recorded (so `outcome.state` has it), at +close, or after `withinMs`; a crash loses what is not stored. Only run state documents; other persisted documents get +it when a real case needs it. - **Fingerprint:** the job's fingerprint (args, result and state schemas) stored with every record; a record of the same version with another fingerprint is `blocked { version }` (slice 7's family; the carry-over's "a job