Revised Build Sequence — v2 (Supersedes Doc 07)

Date: 2026-07-16 Status: authoritative build sequence. Supersedes 07-completed-plan-build-sequence.md, which remains valid as the baseline — every slice ID from doc 07 keeps its meaning here. The changes come from 06-path-to-full-graph-engine.md (strategy) via 08-plan-delta-for-graph-engine-strategy.md (delta rationale).

Note for the agent currently building from doc 07: nothing you have built from Stages 0–2 is invalidated. Change markers below: [=] unchanged from doc 07 · [^] promoted/gate changed · [+] new in v2. If you are mid-slice on anything marked [=], continue as specified in doc 07. The only doc 07 content that changed meaning is: C2 and O3 gained a benchmark-publication gate, the validation cache left Stage 5’s “measure-first” bucket, and WAL sync design moved earlier. Everything else new is additive (Stage 2P and Stage 5 additions).

External anchor: PG19 GA (~fall 2026) — P1 must land before it.


Stage 0 — CI first [=]

S0 (KI-017). cargo fmt --check, clippy, cargo test, cargo doc, scripts/check_docs_drift.sh in a PR workflow; pgrx integration as a second job. Gate: green on a no-op PR, red on a seeded violation. Everything below depends on S0.

Stage 1 — Correctness and security

Parallel after S0. All [=] except C2’s gate.

Slice Register What Merge gate
C1 [=] KI-012 Advisory-lock durable ingest (per-graph lock as sql_build.rs does, around projection/ingest.rs + manifest.rs publication) Two-backend concurrent apply_sync() stress: no lost generation; throughput unchanged
C2 [^] KI-015 Bidirectional BFS: finish level, pick minimal combined-distance meeting node Two-meeting-point regression; existing tests green; bench unregressed. New gate: blocks any published benchmark (P2 publication)
C3 [=] KI-016 _sync_log retention: checkpointed prune below durable-watermark minimum, from maintenance() + run_scheduled_maintenance() Proptest: never deletes unapplied rows; log bounded under write-heavy test
C4 [=] KI-013 RLS topology boundary: security-docs section now; refuse-or-warn GUC for RLS-enabled tables Docs drift green; pgrx test for warn/refuse
C5 [=] KI-014 Tenant filter-vs-isolation docs + enforcement decision Docs updated; decision recorded

Stage 2 — Operational hardening

All [=] except O3’s gate.

Slice Register What Merge gate
O1 [=] KI-018 Poison-row dead-lettering via _sync_log.error_message; count in sync_health() Repeated-failure row skipped + surfaced; recovery documented
O2 [=] KI-019 Atomic artifact+sidecar commit; parent-dir fsync after rename Crash-window test recovers correctly
O3 [^] KI-020 truncated signal on capped traversal/path results Contract documented; false-“no path” covered. New gate: blocks P2 publication
O4 [=] KI-021 mutable_overlay production-status row + quickstart caveat Row live until L4 signoff
O5 [=] KI-024 README_zh.md version parity in drift check Fails on stale translation

Stage 2P — SQL/PGQ compatibility track [+]

New parallel track after S0. Owns the PG19 GA clock. Source: doc 06 Pillar A, doc 08 §3.

Slice What Depends on Merge gate Target
P1 [+] graph.import_property_graph(): read pg_propgraph_* → pgGraph registration; drift detection via pg_get_propgraphdef(); version-gated PG19+ S0 Round-trip on PG19 beta: CREATE PROPERTY GRAPH → import → build → traverse; drift flag on ALTER Before PG19 GA
P2 [+] LDBC SNB harness (sandbox/benchmark ldbc preset) incl. plain-PG19 GRAPH_TABLE same-box comparison S0 (build now); C2 + O3 (publish) Reproducible in-repo harness; baseline recorded Harness now; publish post-C2/O3
P3 [+] graph.graph_table(): standard SQL/PGQ pattern grammar incl. variable-length forms core rejects, resolved against imported property graphs; GQL-parser frontend adaptation feeding the typed adapter seam (query/sqlpgq_adapter.rs) P1 Compatibility matrix function; differential test vs PG19 on fixed-depth patterns GA + 0–6 mo
P4 [+] CustomScan/planner-hook feasibility prototype on GRAPH_TABLE join trees; outcome is a written finding either way (feasible → slice; not → upstream hook proposal with LDBC evidence) P1, P3 Finding documented + decision GA + 6–18 mo

Register edits required with P1/P3 (doc 08 §4): reword the roadmap “Reserved Features” SQL/PGQ row and the sqlpgq_adapter.rs doc comment — catalog import and the pattern-text surface no longer wait for PostgreSQL hooks; only transparent acceleration (P4) does. Scope all “replace native graph databases” language as workload replacement, cross-referenced to the existing non-goals table.

Stage 3 — Make live mode real

Depends on Stage 1 (C1, C3 hard prerequisites). All [=] plus one addition.

Slice Register What Merge gate
L1 [=] roadmap Auto-maintenance consumes sync_health() booleans; adaptive cadence; non-Docker setup documented Soak test: recommendations acted on; cadence tightens under pressure
L2 [=] roadmap mutable_overlay requires persist_on_build = on (no silent degrade) pgrx refusal test; docs
L3 [=] KI-023 Weighted shortest path over layered overlays Proptest: dirty-overlay results ≡ post-compaction; rejection path removed
L4 [=] KI-021 Benchmark + verification signoff; then relax mutable_enabled double gate Published numbers; KI-021 cleared
L5 [+] roadmap WAL/logical-decoding sync design (implementation stays Stage 6 R4): consumer shape, slot management, trigger-mode coexistence Design doc reviewed; Stage 3 choices don’t preclude it

Stage 4 — Hybrid auto mode [=]

Depends on Stage 3. H1 (empty-overlay fast path, part of KI-005) and H2 (projection_mode = 'auto' policy layer) exactly as doc 07.

Stage 5 — Performance (benchmark-driven)

Slice What Status
F1 [^] Per-generation artifact validation cache (kills the ~4.4 s first-backend cost; validate once per generation cluster-wide, not per backend) Promoted out of “measure first” — the measurement exists. Schedule after Stage 2; required before head-to-head marketing claims
F2 [=] Tenant-state borrow in BfsConfig Measure-first rule applies
F3 [=] Frontier pre-allocation clamp Measure-first rule applies
F4 [+] Shared mmap sections for reverse CSR / filter index / edge-type registry (answers the architecture-tradeoffs.mdx open question: yes) Prerequisite for F5; benchmark backend-count scaling
F5 [+] Direction-optimizing BFS (top-down/bottom-up switching) After F4; LDBC-verified win required

Stage 6 — Larger refactors [=]

R1 (KI-022 overlay unification), R2 (KI-025 builder regclass parity), R3 (KI-026 endianness guard), R4 (WAL sync implementation — design done in L5; background pre-applier).

Cross-cutting rules [=]

Unchanged from doc 07: TDD every slice; pgrx-free internals where possible; no Result<_, String> across layers; no new unsafe; docs-contract gate before public surface changes; benchmark against current baselines before claiming completion.

Dependency picture

S0 CI ──┬── Stage 1 (C1..C5) ─────────── Stage 3 (L1..L5) ── Stage 4 (H1,H2)
        ├── Stage 2 (O1..O5)                   │
        ├── Stage 2P: P1 import ── P3 graph_table() ── P4 hooks finding
        │        └── P2 harness ──(publish gated on C2+O3)
        ├── Stage 5: F1 now; F4 ── F5; F2/F3 measure-first
        └── Stage 6 last (R4 impl after L5 design)