Dispose the wave-6 class-1-window observations (release-contract-window-close)
The pre-release pass's last contract-text dispositions, each dated in-place citing the 2026-10-11 close-out pass (ADR-017 §2's terminal window): - Publish→wake ordering tolerance: documented tolerance (decided with the user) — core-contract.md streams paragraph + delivery-obligations bullet, ADR-015 §4 companion annotation; the wake = offset-order ADR amendment declined (commit-ordered pg visibility; hint-shaped wake posture). - ADR-023 §2: heartbeat(extend) and save_offset(offset) join the boundary/offset row (total — negatives well-defined), with the home rationale annotated; core-contract's domain paragraph mirrors; the backlog numeric-domain row registers the suite-duty follow-up. - ADR-021 §5: EventReceiver::try_recv's closed shape pinned (Err(Closed), mirroring ADR-008 §3); core-contract subscribe arms sentence extended. - get_job prose: core-contract queues section + queues.md's reads sentence now say the uniform id-global / get_job_tx-filtered split. - Mem-arithmetic observation: no-action disposition recorded in the task Notes (byte-level transplants; equivalence suite-pinned three-way). Suite stamps checked — no accumulation required (no cited § text changed meaning). Docs-only; gates green: build, workspace tests, clippy -D warnings, fmt, fuzz replay, rustdoc -D warnings, taskgraph validate (79 tasks).
This commit is contained in:
1 parent
8e27f4b64b
commit
a37c2887dc
6 files changed
+229
-16
No files matched your search
@@ -1,8 +1,6 @@
|
|||||||
---
|
---
|
||||||
status: draft
|
status: draft
|
||||||
last_updated: "2026-10-10 (ADR-024 — the mem engine joins the family;
|
last_updated: "2026-10-11 (the pre-release class-1 close-out pass — the publish→wake ordering tolerance recorded; ADR-023 §2's `heartbeat(extend)`/`save_offset` classifications; `EventReceiver::try_recv`'s closed shape; `get_job`'s id-global prose)"
|
||||||
the Store concept prose admits the engine-native constructor
|
|
||||||
exception)"
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Core contract
|
# Core contract
|
||||||
@@ -138,9 +136,18 @@ the engine's storage layer):
|
|||||||
chain); an exclusion mechanism must not silently hand back a lease
|
chain); an exclusion mechanism must not silently hand back a lease
|
||||||
the caller believes it holds.
|
the caller believes it holds.
|
||||||
- **Boundaries/offsets** (`trim_to(horizon)`, enqueue `delay`/
|
- **Boundaries/offsets** (`trim_to(horizon)`, enqueue `delay`/
|
||||||
`run_at`/`expires`) — total: any `i64` is well-defined (a negative
|
`run_at`/`expires`, `heartbeat(extend)`, `save_offset(offset)`) —
|
||||||
horizon deletes nothing; a negative delay resolves to a ready
|
total: any `i64` is well-defined (a negative horizon deletes
|
||||||
time in the past, i.e. ready now).
|
nothing; a negative delay resolves to a ready time in the past,
|
||||||
|
i.e. ready now; a negative `heartbeat(extend)` — the renewed claim
|
||||||
|
deadline is `now + extend` — shortens or voids the claim, and the
|
||||||
|
validity predicate then refuses the ops, never an error; a negative
|
||||||
|
offset save is stored, reads resume forward, and saves at-or-below
|
||||||
|
the checkpoint are the monotone no-ops)
|
||||||
|
*(the two 2026-10-11 classifications annotated in
|
||||||
|
[ADR-023](decisions/023-fourth-review-round.md) §2 by the
|
||||||
|
close-out pass; before that date the table covered only the first
|
||||||
|
three arguments)*.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
store.notify(channel, payload) handle.notify_tx(channel, payload)
|
store.notify(channel, payload) handle.notify_tx(channel, payload)
|
||||||
@@ -265,6 +272,34 @@ business-tx shape). Depth pinned by
|
|||||||
replay-on-attach as already pinned; offsets immutable. The
|
replay-on-attach as already pinned; offsets immutable. The
|
||||||
contract suite pins cross-engine equivalence against this row
|
contract suite pins cross-engine equivalence against this row
|
||||||
(same publish sequence → same offset sequence → same read order).
|
(same publish sequence → same offset sequence → same read order).
|
||||||
|
- **Wake-fire ordering tolerance** *(documented tolerance, 2026-10-11
|
||||||
|
— the pre-release class-1 close-out pass,
|
||||||
|
[ADR-017](decisions/017-contract-versioning.md) §2; disposes the
|
||||||
|
wave-6 review gate's recorded observation)*: nothing in the
|
||||||
|
contract pins wake-fire order to offset order. Offset allocation
|
||||||
|
precedes insert+wake on a multi-threaded runtime (the mem engine;
|
||||||
|
its documented current-thread posture never exercises it) and the
|
||||||
|
offset is sequence-assigned pre-commit with the wake fired
|
||||||
|
post-commit (the Postgres engine — commit order can invert
|
||||||
|
sequence order), so two concurrent publishes can complete out of
|
||||||
|
offset-allocation order. A subscriber's wake-driven drain that
|
||||||
|
finishes between the two completions can checkpoint past the
|
||||||
|
later-completing, lower-offset event: **the event stays in the
|
||||||
|
log** — direct `read_since` always sees it, and a fresh
|
||||||
|
`subscribe(consumer)` whose saved checkpoint is below it consumes
|
||||||
|
it normally — but the live subscriber whose cursor passed it is
|
||||||
|
not re-delivered it by the later wake. This is a documented
|
||||||
|
consequence of the wake contract's best-effort posture (hints, not
|
||||||
|
delivery promises); the offset-ASC read guarantee above is
|
||||||
|
unaffected — reads always run over the committed log in offset
|
||||||
|
order regardless of wake timing. Consumers requiring per-event
|
||||||
|
completeness across concurrent same-stream publishers need the
|
||||||
|
defensive re-read recipe (a lagged checkpoint, or a direct
|
||||||
|
`read_since` sweep below it). Pinned as a tolerance, not an
|
||||||
|
enforced guarantee (the heavier wake = offset-order amendment was
|
||||||
|
weighed and declined with the user: enforcement against commit-
|
||||||
|
ordered visibility is a redesign, and the wake mechanism's posture
|
||||||
|
is hint-shaped by construction).
|
||||||
- `read_since` / `read_from_consumer(offset)` — cursor-based reads;
|
- `read_since` / `read_from_consumer(offset)` — cursor-based reads;
|
||||||
`get_offset(consumer)` — checkpoint inspection. A read from a
|
`get_offset(consumer)` — checkpoint inspection. A read from a
|
||||||
trimmed-away offset region (below) resumes at the trim horizon's
|
trimmed-away offset region (below) resumes at the trim horizon's
|
||||||
@@ -308,6 +343,10 @@ business-tx shape). Depth pinned by
|
|||||||
([ADR-021](decisions/021-tx-reads-and-value-shape-fixes.md) §5):
|
([ADR-021](decisions/021-tx-reads-and-value-shape-fixes.md) §5):
|
||||||
`recv()`'s `Err` arm carries `Database` only (payloads cross raw;
|
`recv()`'s `Err` arm carries `Database` only (payloads cross raw;
|
||||||
`Codec` lives at `payload_as<T>`; `Closed` is the `None` arm);
|
`Codec` lives at `payload_as<T>`; `Closed` is the `None` arm);
|
||||||
|
the poll form's arms pin identically — `try_recv()`: `Ok(None)` =
|
||||||
|
idle (no event pending right now), `Err(Closed)` = the receiver
|
||||||
|
closed, `Database` otherwise (the closed shape annotated
|
||||||
|
2026-10-11, the close-out pass);
|
||||||
close is terminal and its *cause* is the documented engine
|
close is terminal and its *cause* is the documented engine
|
||||||
asymmetry — SQLite's receiver closes on watcher death (POC-pinned),
|
asymmetry — SQLite's receiver closes on watcher death (POC-pinned),
|
||||||
the pg receiver stays open across forwarder reconnects (reconnect
|
the pg receiver stays open across forwarder reconnects (reconnect
|
||||||
@@ -401,6 +440,14 @@ obligations:
|
|||||||
`last_error`/`died_at`), retention via `dead_letter_retention_s`
|
`last_error`/`died_at`), retention via `dead_letter_retention_s`
|
||||||
(default forever), no redrive API
|
(default forever), no redrive API
|
||||||
([ADR-010](decisions/010-queue-semantics-depth.md) §1–§4).
|
([ADR-010](decisions/010-queue-semantics-depth.md) §1–§4).
|
||||||
|
`get_job(job_id)` on the handle is an **id-global lookup** — the
|
||||||
|
handle carries the queue, but the lookup keys on the id alone and
|
||||||
|
resolves rows in any queue (uniform on all engines; annotated
|
||||||
|
2026-10-11, the close-out pass — the wave-6 review's recorded
|
||||||
|
prose ambiguity); the tx-side `get_job_tx(queue, job_id)` takes
|
||||||
|
the queue name and **is** queue-filtered
|
||||||
|
([ADR-019](decisions/019-mechanism-handle-surfaces.md) §1,
|
||||||
|
[ADR-021](decisions/021-tx-reads-and-value-shape-fixes.md) §1).
|
||||||
`QueueOpts` stamp onto the job row at enqueue (§3a) — queues are
|
`QueueOpts` stamp onto the job row at enqueue (§3a) — queues are
|
||||||
names, not config owners. The remaining v1-skeleton ops (`ack_batch`
|
names, not config owners. The remaining v1-skeleton ops (`ack_batch`
|
||||||
— the batch ack applies the uniform predicate per id, lapsed or
|
— the batch ack applies the uniform predicate per id, lapsed or
|
||||||
@@ -522,7 +569,12 @@ row is [ADR-009](decisions/009-scheduler-collapse.md) §4's. This spec
|
|||||||
inherits them and adds the consumer obligations:
|
inherits them and adds the consumer obligations:
|
||||||
|
|
||||||
- wake idempotence (notify's best-effort, coalescing behavior);
|
- wake idempotence (notify's best-effort, coalescing behavior);
|
||||||
- explicit offset saves (streams);
|
- explicit offset saves (streams); wake-fire ordering is a
|
||||||
|
documented tolerance, not a pinned guarantee — wake order need not
|
||||||
|
match offset order and a wake-driven subscriber can drain past an
|
||||||
|
event whose publish completed out of offset order (the streams
|
||||||
|
section's tolerance paragraph, 2026-10-11); recovery rides the
|
||||||
|
offset-ordered re-read the wake contract already obligates;
|
||||||
- visibility-timeout budgeting — heartbeat inside the deadline for
|
- visibility-timeout budgeting — heartbeat inside the deadline for
|
||||||
long work; the dual-execution window and reclaim-eats-attempt rules
|
long work; the dual-execution window and reclaim-eats-attempt rules
|
||||||
are documented consumer obligations
|
are documented consumer obligations
|
||||||
@@ -736,7 +788,12 @@ before the engine specs are called `stable`:
|
|||||||
the SQLite `LIMIT -1` dialect artifact is dead on both engines;
|
the SQLite `LIMIT -1` dialect artifact is dead on both engines;
|
||||||
durations reject (`try_lock`/`renew` with `ttl <= 0` are opaque
|
durations reject (`try_lock`/`renew` with `ttl <= 0` are opaque
|
||||||
`Err`s on both engines); boundaries are total (a negative
|
`Err`s on both engines); boundaries are total (a negative
|
||||||
`trim_to` horizon deletes nothing, idempotently).
|
`trim_to` horizon deletes nothing, idempotently; the same
|
||||||
|
totality over non-positive values covers `heartbeat(extend)`'s
|
||||||
|
relative-deadline argument and `save_offset`'s offset — both
|
||||||
|
classified 2026-10-11 by the close-out pass, the ADR-023 §2
|
||||||
|
annotation; their suite rows are the follow-up that
|
||||||
|
classification implies).
|
||||||
- **`encode_payload` typed failure**
|
- **`encode_payload` typed failure**
|
||||||
([ADR-023](decisions/023-fourth-review-round.md) §1) — the helper
|
([ADR-023](decisions/023-fourth-review-round.md) §1) — the helper
|
||||||
returns `Result<Vec<u8>, Error::Codec>`; enqueue/publish store and
|
returns `Result<Vec<u8>, Error::Codec>`; enqueue/publish store and
|
||||||
|
|||||||
@@ -201,6 +201,19 @@ never compared.)* It is deliberately *not* stronger than both engines can
|
|||||||
implement by a shared SQL shape (`ORDER BY offset ASC` is already
|
implement by a shared SQL shape (`ORDER BY offset ASC` is already
|
||||||
both engines' claim path) and not weaker than the mechanism's purpose
|
both engines' claim path) and not weaker than the mechanism's purpose
|
||||||
(replay demands monotone positions).
|
(replay demands monotone positions).
|
||||||
|
*(Annotation, 2026-10-11 — the pre-release class-1 close-out pass
|
||||||
|
([ADR-017](017-contract-versioning.md) §2), disposing the wave-6
|
||||||
|
review gate's recorded ordering observation with the user's
|
||||||
|
documented-tolerance call: this row pins *read* order — `offset ASC`
|
||||||
|
over the committed log — and pins nothing about **wake-fire order**;
|
||||||
|
wake-fire order need not match offset order, and a wake-driven
|
||||||
|
subscriber's drain can checkpoint past an event whose publish
|
||||||
|
completed out of offset order (the event stays in the log; a fresh
|
||||||
|
subscribe whose checkpoint is below it sees it). The tolerance's full
|
||||||
|
text and the consumer recipe live in
|
||||||
|
[core-contract.md](../../architecture/core-contract.md)'s streams
|
||||||
|
section — the delivery-guarantee obligations bullet carries it too.
|
||||||
|
The heavier wake = offset-order amendment was weighed and declined.)*
|
||||||
|
|
||||||
### 5. Retention: `trim_to` on the stream handle — a consumer-invoked bounded-growth op
|
### 5. Retention: `trim_to` on the stream handle — a consumer-invoked bounded-growth op
|
||||||
|
|
||||||
|
|||||||
@@ -258,6 +258,20 @@ The pinned shape's unpinned arms:
|
|||||||
absent-consumer = 0 rule,
|
absent-consumer = 0 rule,
|
||||||
[ADR-019](019-mechanism-handle-surfaces.md) §1, already defines
|
[ADR-019](019-mechanism-handle-surfaces.md) §1, already defines
|
||||||
the pre-save state).
|
the pre-save state).
|
||||||
|
- *(Annotation, 2026-10-11 — the pre-release class-1 close-out pass
|
||||||
|
([ADR-017](017-contract-versioning.md) §2), disposing the wave-6
|
||||||
|
review gate's recorded unpinned shape: **`EventReceiver::try_recv`'s
|
||||||
|
closed shape is `Err(Closed)`.** §5 pinned only `recv()`'s arms;
|
||||||
|
the poll form's arms are the same taxonomy applied without the
|
||||||
|
wait — `Ok(None)` = no event pending right now (idle), `Err(Closed)`
|
||||||
|
= the receiver closed (terminal — the same causes the `None` arm
|
||||||
|
documents, engine asymmetry included), and the rest of the `Err`
|
||||||
|
arm carries `Database` only, exactly like `recv()`. The shape
|
||||||
|
mirrors `WakeReceiver::try_recv`
|
||||||
|
([ADR-008](008-contract-v1-pinning.md) §3, where closed and idle are
|
||||||
|
distinguishable states by the same construction) and is uniform on
|
||||||
|
all three engines; core's rustdoc pinned it from landing, and the
|
||||||
|
mem engine's suite pins it in test.)*
|
||||||
|
|
||||||
## Consequences
|
## Consequences
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ classified by argument **kind**, not call site:
|
|||||||
|---|---|---|
|
|---|---|---|
|
||||||
| **Extent** ("at most this many") | `claim_batch(n)`, `read_since(limit)`, `read_from_consumer(limit)` | `n <= 0` → **empty value result** (claims nothing / reads nothing), not an error |
|
| **Extent** ("at most this many") | `claim_batch(n)`, `read_since(limit)`, `read_from_consumer(limit)` | `n <= 0` → **empty value result** (claims nothing / reads nothing), not an error |
|
||||||
| **Duration** (seconds of lease/TTL semantics) | `try_lock(ttl)`, `renew(ttl)` | `ttl <= 0` → **`Err`, opaque** (engine detail in the source chain, `Database`) — the substrate's existing guard (`ttl_s <= 0`), now pinned contract-side |
|
| **Duration** (seconds of lease/TTL semantics) | `try_lock(ttl)`, `renew(ttl)` | `ttl <= 0` → **`Err`, opaque** (engine detail in the source chain, `Database`) — the substrate's existing guard (`ttl_s <= 0`), now pinned contract-side |
|
||||||
| **Boundary / offset** (`<=` predicates, absolute or relative instants) | `trim_to(horizon)`, enqueue `delay`/`run_at`/`expires` | total — any `i64` is well-defined (negative horizon deletes nothing; negative delay → ready in the past → ready now); no clamping, no rejection |
|
| **Boundary / offset** (`<=` predicates, absolute or relative instants) | `trim_to(horizon)`, enqueue `delay`/`run_at`/`expires`; `heartbeat(extend)`, `save_offset(offset)` *(annotated 2026-10-11)* | total — any `i64` is well-defined (negative horizon deletes nothing; negative delay → ready in the past → ready now; negative extension → the renewed deadline `now + extend` is in the past, voiding the claim through the validity predicate, never an error; negative offset → stored, reads resume forward); no clamping, no rejection |
|
||||||
|
|
||||||
The rule the table pins: **extents clamp to empty (no-work is a
|
The rule the table pins: **extents clamp to empty (no-work is a
|
||||||
value, the pinned claims vocabulary), durations error, boundaries and
|
value, the pinned claims vocabulary), durations error, boundaries and
|
||||||
@@ -149,6 +149,28 @@ offsets are total.** Each disposition answers to a decided principle:
|
|||||||
- **Boundaries/offsets.** The remaining numerics are total by
|
- **Boundaries/offsets.** The remaining numerics are total by
|
||||||
accident of their SQL today; the table makes it rule, not accident
|
accident of their SQL today; the table makes it rule, not accident
|
||||||
— an implementer reading the table has nothing to improvise.
|
— an implementer reading the table has nothing to improvise.
|
||||||
|
*(Annotation, 2026-10-11 — the pre-release class-1 close-out pass
|
||||||
|
([ADR-017](017-contract-versioning.md) §2), disposing the wave-6
|
||||||
|
review gate's recorded under-classifications. Two arguments join
|
||||||
|
the boundary/offset row, and deliberately not the duration row:
|
||||||
|
`heartbeat(extend)`'s seconds-shaped argument is not lease/TTL —
|
||||||
|
`extend` is the new full deadline in seconds from now, so a
|
||||||
|
non-positive value is not a handed-back lease the caller believes
|
||||||
|
it holds (the duration rule's rejection rationale never applies);
|
||||||
|
it is a relative instant like `delay`, and the three engines'
|
||||||
|
uniform arithmetic (`saturating_add` / plain SQL integer add —
|
||||||
|
code of record, mem `queue.rs`, substrate `queue_ops.rs`, pg
|
||||||
|
`queue.rs`) is total over non-positive values: a negative extension
|
||||||
|
shortens the deadline, a past one is voided by the uniform
|
||||||
|
validity predicate on the *next* op, and the heartbeat itself
|
||||||
|
reports the successful renewal (`true`) exactly when the row was
|
||||||
|
processing and unexpired at call time. And `save_offset`'s offset
|
||||||
|
is literally an offset: a negative is stored as the checkpoint,
|
||||||
|
reads resume forward past it, and saves at-or-below the stored
|
||||||
|
checkpoint are the [ADR-019](019-mechanism-handle-surfaces.md) §6
|
||||||
|
monotone no-ops — rejections were never the behavior, so pinning
|
||||||
|
the duration row's shape here would have contradicted all three
|
||||||
|
engines.)*
|
||||||
|
|
||||||
This is a **core-contract amendment** (doc text on `claim_batch`,
|
This is a **core-contract amendment** (doc text on `claim_batch`,
|
||||||
both `read` forms, `try_lock`/`renew`, and a shared domain-rule
|
both `read` forms, `try_lock`/`renew`, and a shared domain-rule
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
status: draft
|
status: draft
|
||||||
last_updated: "2026-10-07 (ADR-021 + third-round follow-through: handle-form sweep_expired, ack_batch predicate, opts types)"
|
last_updated: "2026-10-11 (close-out pass: the reads sentence now says the uniform shapes — get_job id-global on the handle, get_job_tx queue-filtered)"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Queues, scheduler, outbox — semantics depth
|
# Queues, scheduler, outbox — semantics depth
|
||||||
@@ -44,9 +44,13 @@ made under; the ADRs carry the WHY.
|
|||||||
[ADR-020](decisions/020-enqueue-opt-semantics-and-bridges.md) §1/§2);
|
[ADR-020](decisions/020-enqueue-opt-semantics-and-bridges.md) §1/§2);
|
||||||
`ack / retry / fail / heartbeat` on the boxed `JobHandle` a claim
|
`ack / retry / fail / heartbeat` on the boxed `JobHandle` a claim
|
||||||
returns ([ADR-019](decisions/019-mechanism-handle-surfaces.md));
|
returns ([ADR-019](decisions/019-mechanism-handle-surfaces.md));
|
||||||
reads (`get_job`, and tx-side `get_job_tx` —
|
reads are pure reads, in two shapes — `get_job` on the queue handle
|
||||||
[ADR-021](decisions/021-tx-reads-and-value-shape-fixes.md) §1) are
|
is an **id-global lookup** (the handle carries the queue, the
|
||||||
name-taking pure reads, tx-shaped on the handle.
|
lookup keys on the id alone), the tx-side `get_job_tx`
|
||||||
|
([ADR-021](decisions/021-tx-reads-and-value-shape-fixes.md) §1) is
|
||||||
|
name-taking and **queue-filtered** (2026-10-11 close-out pass —
|
||||||
|
core-contract's queues section carries the split; the wave-6
|
||||||
|
review's recorded prose ambiguity).
|
||||||
- **Cut-flag context**: result storage is
|
- **Cut-flag context**: result storage is
|
||||||
[ADR-002](decisions/002-feature-scope.md)'s cut-flag row;
|
[ADR-002](decisions/002-feature-scope.md)'s cut-flag row;
|
||||||
[ADR-010](decisions/010-queue-semantics-depth.md) §7 reconsidered it
|
[ADR-010](decisions/010-queue-semantics-depth.md) §7 reconsidered it
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
id: release-contract-window-close
|
id: release-contract-window-close
|
||||||
name: Class-1 window's last dispositions — the wave-6 recorded observations
|
name: Class-1 window's last dispositions — the wave-6 recorded observations
|
||||||
status: pending
|
status: completed
|
||||||
depends_on: []
|
depends_on: []
|
||||||
scope: moderate
|
scope: moderate
|
||||||
risk: medium
|
risk: medium
|
||||||
@@ -92,8 +92,111 @@ accumulation.
|
|||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
> To be filled by implementation agent
|
All five dispositions landed 2026-10-11 as dated in-place annotations
|
||||||
|
citing this pass (the pre-release class-1 close-out pass,
|
||||||
|
[ADR-017](../docs/architecture/decisions/017-contract-versioning.md)
|
||||||
|
§2's terminating window). Docs-only — no code change (item 1's
|
||||||
|
enforced-guarantee alternative was declined with the user, so no
|
||||||
|
follow-up code task spawns).
|
||||||
|
|
||||||
|
1. **Publish→wake ordering tolerance — decided with the user,
|
||||||
|
documented tolerance.** The two candidates were raised with the
|
||||||
|
user (2026-10-11) and the documented-tolerance posture was chosen
|
||||||
|
over the ADR amendment (wake order per stream = offset order) —
|
||||||
|
the amendment is arguably unachievable on Postgres while offsets
|
||||||
|
are sequence-assigned pre-commit (commit order inverts sequence
|
||||||
|
order; enforcement needs hole-filling/redesign) and contradicts
|
||||||
|
the wake mechanism's hint-shaped best-effort posture. Landed:
|
||||||
|
core-contract.md's streams section carries the tolerance paragraph
|
||||||
|
(the full text: the mem multithreaded-runtime shape, the pg
|
||||||
|
sequence/commit shape, the event-stays-in-the-log promise, the
|
||||||
|
consumer recipe — lagged checkpoints or direct `read_since` sweeps
|
||||||
|
below them), the delivery-guarantee obligations list carries the
|
||||||
|
consumer-obligation bullet, and ADR-015 §4 carries the dated
|
||||||
|
companion annotation (the ordering row pins *read* order only;
|
||||||
|
wake order unpinned).
|
||||||
|
2. **`heartbeat(extend)` + `save_offset(offset)` — both join the
|
||||||
|
ADR-023 §2 boundary/offset row**, annotated in place with the
|
||||||
|
home rationale: the duration row's rejection rationale never
|
||||||
|
applies (a non-positive `extend` is a relative instant like
|
||||||
|
`delay`, not a lease handout — a negative shortens/voids the
|
||||||
|
claim and the uniform validity predicate governs; the three
|
||||||
|
engines' arithmetic — `saturating_add`/SQL integer add — is total
|
||||||
|
over non-positive values, and the heartbeat reports `true` when
|
||||||
|
the row was processing and unexpired at call time), and
|
||||||
|
`save_offset`'s offset is literally an offset (negative stored,
|
||||||
|
reads resume forward, regressions are the ADR-019 §6 monotone
|
||||||
|
no-ops) — pinning rejection would have contradicted all three
|
||||||
|
engines. core-contract.md's numeric-domain paragraph mirrors the
|
||||||
|
extension. The verification-backlog numeric-domain row was
|
||||||
|
extended to register the suite-duty follow-up those two
|
||||||
|
classifications imply (their suite rows did not land here —
|
||||||
|
docs-only task); before release-readiness, the review-wave-8 gate
|
||||||
|
owns the audit.
|
||||||
|
3. **`EventReceiver::try_recv`'s closed shape — ADR-021 §5 dated
|
||||||
|
annotation**: `Err(Closed)` (terminal; the `None` arm's causes),
|
||||||
|
`Ok(None)` = idle, `Database` otherwise — mirroring
|
||||||
|
`WakeReceiver::try_recv` (ADR-008 §3). Home is §5 so one
|
||||||
|
normative section governs every receiver Err/close arm. Verified
|
||||||
|
uniform by code read (mem `stream.rs`, sqlite `stream.rs`, pg
|
||||||
|
`stream.rs` all map channel disconnect → `Err(Closed)`); core's
|
||||||
|
rustdoc carried the shape from landing; the mem suite pins it.
|
||||||
|
4. **`get_job` prose — core-contract.md's queues section now says
|
||||||
|
the uniform behavior**: id-global lookup on the handle (rows in
|
||||||
|
any queue), `get_job_tx(queue, job_id)` queue-filtered. queues.md's
|
||||||
|
reads sentence — which mischaracterized both as "name-taking pure
|
||||||
|
reads" — corrected in the same pass. Code read verified the
|
||||||
|
uniform shapes (mem `queue.rs`/`tx.rs`'s `merged_get_job`;
|
||||||
|
SQLite substrate `get_job(conn, id)` vs the tx path; pg). ADR-019
|
||||||
|
§1's "queue-scoped claim/maintenance ops" phrasing stands — it
|
||||||
|
names claim/maintenance ops only, and the corrected core-contract
|
||||||
|
text now disambiguates the neighborhood.
|
||||||
|
5. **Mem-arithmetic observation — no-action disposition, recorded**:
|
||||||
|
the mem copies are byte-level transplants of the SQLite
|
||||||
|
implementations (`resolution.rs`, `scheduler.rs`'s `@every`
|
||||||
|
parser and `skip_forward`); equivalence is suite-pinned three-way
|
||||||
|
(`backoff_curve_equivalence`, `enqueue_opts_resolution` green on
|
||||||
|
all three columns, re-verified this session). ADR-012 §2's
|
||||||
|
one-owner rule is satisfied exactly as written (mem owns its
|
||||||
|
modules; the suite is the honesty instrument) — no code or doc
|
||||||
|
change warranted; the record here is the disposition.
|
||||||
|
|
||||||
|
**Suite stamps checked** (the task's accumulation duty): no existing
|
||||||
|
row's cited § text changed meaning, so no stamp accumulates. The four
|
||||||
|
rows citing ADR-023 §2 (`extent_clamp_semantics`,
|
||||||
|
`duration_refusal_on_non_positive_ttl`, the enqueue-opts resolution
|
||||||
|
row, the backoff row) test classifications the amendments left
|
||||||
|
meaning-identical — rows were *added* to the §2 table and annotated,
|
||||||
|
existing cells' semantics untouched; the receiver-arms row citing
|
||||||
|
ADR-021 §5 tests `recv()`/`save_offset`/close arms the annotation
|
||||||
|
left verbatim. The two new classified behaviors' suite rows are the
|
||||||
|
registered follow-up (Notes 2).
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
> To be filled on completion
|
`release-contract-window-close` completed 2026-10-11: all five
|
||||||
|
wave-6 recorded observations disposed as contract/ADR text with
|
||||||
|
dated annotations before ADR-017 §2's class-1 window terminates at
|
||||||
|
first release. Item 1 decided with the user — documented tolerance
|
||||||
|
for the publish→wake ordering observation, landed in core-contract.md
|
||||||
|
(streams tolerance paragraph + delivery-guarantee obligations bullet)
|
||||||
|
with the ADR-015 §4 companion annotation; the wake = offset-order ADR
|
||||||
|
amendment was presented and declined (unachievable against commit-
|
||||||
|
ordered pg visibility without redesign; contradictorily sharpen a
|
||||||
|
hint-shaped mechanism). Items 2–3: ADR-023 §2's boundary/offset row
|
||||||
|
gained `heartbeat(extend)` and `save_offset(offset)` (total —
|
||||||
|
negatives well-defined, with the homes' rationale annotated, the
|
||||||
|
core-contract domain paragraph mirrored, and the backlog numeric-
|
||||||
|
domain row registering the suite-duty follow-up); ADR-021 §5 gained
|
||||||
|
the `EventReceiver::try_recv` closed-shape annotation (`Err(Closed)`,
|
||||||
|
mirroring ADR-008 §3). Item 4: core-contract.md's `get_job` prose now
|
||||||
|
says the uniform id-global/`get_job_tx`-filtered split (queues.md's
|
||||||
|
mischaracterizing reads sentence corrected alongside). Item 5: the
|
||||||
|
mem-arithmetic observation's no-action disposition recorded above.
|
||||||
|
Suite-stamp accumulation checked — none required (no cited § text
|
||||||
|
changed meaning). Verified docs-only: `cargo build`, workspace tests
|
||||||
|
green (mem 102+25, SQLite 192+25, pg 125+25+9, core 25 — three-way
|
||||||
|
equivalence rows green), clippy `--all-targets -D warnings` clean,
|
||||||
|
`cargo fmt --check` clean, fuzz corpus replay green (6/6),
|
||||||
|
`RUSTDOCFLAGS="-D warnings" cargo doc --no-deps` zero warnings,
|
||||||
|
`taskgraph validate` green (79 tasks).
|
||||||
Reference in new issue
Block a user