Skip to content

docs(spec): language-neutral behavioral spec for the pipes pipeline - #126

Merged
mo4islona merged 3 commits into
mainfrom
spec/pipes-behavioral-spec
Jul 20, 2026
Merged

docs(spec): language-neutral behavioral spec for the pipes pipeline#126
mo4islona merged 3 commits into
mainfrom
spec/pipes-behavioral-spec

Conversation

@mo4islona

@mo4islona mo4islona commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

What

A full conformance-tier spec suite at spec/ — the language-neutral contract for the pipeline, written against the current TypeScript implementation as reference. Intended to let future implementations (Rust first) be built and verified against the same properties and the same persistent/wire formats, so implementations are interchangeable mid-stream.

Contents

  • Wire & format bindings (14): portal protocol (NDJSON stream, 409 fork signal, head headers), all four cursor-state formats (ClickHouse/Postgres/Parquet/BigQuery), cache format, observability HTTP surface, closed error-code registry.
  • Sink contract (05, 06): four durability classes (transactional / write-ahead / checkpointed-immutable / append-lagged) with per-class commit protocols, crash windows, and recovery obligations.
  • Safety & liveness (07, 08, 09): 29 safety invariants + 10 liveness properties (incl. single-slot ingest prefetch, PF-6/WP-12), fault-family response tables.
  • Conformance plan (13): reference-model oracle, 9 test classes with a kill-point matrix, honest traceability matrix from the current vitest inventory, and a dated gap register.
  • Decision log: 11 backfilled historical ADRs + 4 proposed ones awaiting ratification (decode-error hook unification, spec location, SLO targets, mandatory class-A repair hook).

Review pass (2026-07-19)

An 11-agent spec-vs-implementation audit verified every wire/format/parameter claim against the code and drove a revision:

  • Normative text corrected where it contradicted verified behavior: the deep-fork ancestor rule (WP-42 prose + reference-model pseudocode now match the tested resolveForkCursor semantics, including the previously undocumented floor fallback), per-network cursor timestamp units (tron reports milliseconds), head-only (204) handling, the class-T undo mechanism (after-image trigger, not before-image), and body-stall retryability.
  • Parquet coverage model scoped honestly: coverage naming / coverage state map / straddle refusal are marked contract-target (they live in unmerged PR fix(parquet): name files for the block range they cover #123); the traceability matrix is re-pinned to this branch's mainline base a739500, and the coverage row corrected from C to U ⚠ (GAP-17).
  • Gap register grown 16 → 34 (8 entries at P1): new entries for the class-T undo holes (GAP-18/19), orphan guards missing outside BigQuery (GAP-20), ClickHouse fork not being a commit point (GAP-21), per-segment lifecycle re-fires on fork (GAP-22), six unbound/unimplemented observability signals (GAP-28), cache codec discrimination (GAP-27), and the open fix PRs fix(runner): respect retry: 0 instead of coercing to default 5 #70/fix(portal-source): end batch spans on empty batches and stream end #71/fix(portal-source): make pipe() id dedup stable for 3+ same-id transformers #73 (GAP-32/33), among others. GAP-10 widened to name both wall-clock-ordered bindings; GAP-11 upgraded from suspected to confirmed (P1).
  • Self-consistency fixes: OB↔IB binding annotations, WP-3 vs DEF-9 legacy-key model, RP-31 scoped to migrating bindings, stale GAP citations, OQ-6/OQ-7 added, ADR-14 linked to OQ-4.

Coverage gate

Docs-only change — no runtime code touched, so there is no coverage diff to report. The spec's consistency checker is now committed (spec/check-spec.mjs) and CI-enforced on spec changes (.github/workflows/spec.yml): 428 IDs, 0 dangling references.

🤖 Generated with Claude Code

mo4islona and others added 3 commits July 20, 2026 15:39
…peline

An implementation-free contract for the pipeline: the abstract state and operation
model, numbered invariants and liveness properties, the failure model, replay and
performance regimes, SLI/SLOs and observability, per-sink interface bindings, the ADRs
behind those decisions, and a conformance/TDD plan carrying a prioritized gap register.
A cross-reference checker runs in CI so every ID and relative link stays resolvable.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
…the prior value

The snapshot trigger stored after-images for insert/update, so rolling back a row whose
pre-fork value came from a finalized block could only ever restore the earliest
unfinalized after-image — the value written over it, not the value it had. Replay now
takes, per row, the earliest before-image strictly above the ancestor; a row first seen
above the ancestor never existed there and is dropped instead.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
… batch

The Postgres sink tags every undo record with the batch's last block, so once the client
coalesced the finalized bulk with the first unfinalized block, a finalized block's writes
carried a tag above the finalized head — and a fork to that head rolled them back, with
no re-fetch to bring them home. A sink now asks for per-block delivery via read(), and it
is off by default: sinks that carry the block number on the rows themselves (ClickHouse)
get one batch per response instead of one per hot block.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@mo4islona
mo4islona force-pushed the spec/pipes-behavioral-spec branch from 3eecd65 to 32ed558 Compare July 20, 2026 11:41
@mo4islona
mo4islona merged commit 0ba094a into main Jul 20, 2026
2 checks passed
@mo4islona
mo4islona deleted the spec/pipes-behavioral-spec branch July 20, 2026 12:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant