Skip to content

feat(storage): stage topology append-only with linear ingest I/O #901

Description

@DecisionNerd

Problem

GraphForge's original large-ingest architecture caused both scale-linear RSS and superlinear immutable-generation work. The core architecture has now been repaired:

Attempt 5 on Fly confirmed that construction is disk-bound rather than RAM-bound: S20 ingest including seal/publication recovery completed at about 194.5 MB peak RSS. It also took 1,940.12 seconds and late probes observed roughly 59 GB read and 44 GB written. The remaining close work is therefore not another architecture rewrite or a larger machine. It is to remove harness-created fixed-cost amplification through #979, attribute and reconcile the actual storage work through #951, and prove the integrated post-#971 path against deterministic constant-factor ceilings and provider evidence.

Objective

Close the append-only construction gate by proving that the ordinary public construction path keeps memory bounded by configured work windows and keeps append, seal, authenticated publication, recovery, and retained storage within documented linear constant factors of accepted canonical data.

Completed prerequisites

These merged outcomes remain part of this issue's close evidence; they are not open implementation scope.

Remaining requirements

  • Complete fix(scale): use construction-budget Arrow batches for S20 ingest #979 so the S20 client submits bounded Arrow batches at the authoritative construction-session budget instead of multiplying durable transactions with a hidden 8,192-row subdivision.
  • Complete test(scale): attribute physical bytes per node and edge before SCALE26 #951 so logical bytes, allocated physical bytes, retained bytes, and transient lifecycle peak are attributed and reconciled by artifact and phase without double-counting shared/CAS objects.
  • Preserve resumable import, idempotency, cancellation, corruption handling, atomic one-generation publication, and ordinary reopen/query/export/verify/clean-import semantics.
  • Keep Rust authoritative and bindings thin.
  • Record content-free counters for append/merge, seal authentication/consumption, encode writes, CAS installation, hydration, fsync/synchronization, recovery reauthentication, and retained/transient storage.

Acceptance criteria

  • fix(scale): use construction-budget Arrow batches for S20 ingest #979 proves one authoritative construction chunk budget, direct bounded Arrow batches, and no hidden smaller durable-transaction boundary.
  • Aggregate topology rows decoded/encoded and application bytes read/written during a fresh import are O(N), with deterministic phase-specific constant-factor ceilings asserted by 1x/2x/4x tests.
  • Peak resident topology state is bounded by configured batch/shard/index-run limits and does not materially grow with previously imported edge count.
  • test(scale): attribute physical bytes per node and edge before SCALE26 #951 reconciles logical and allocated bytes for staging, canonical artifacts, authenticated publication, retained state, portable export, and clean import; physical retained plus transient peak remains within a documented linear factor of canonical output.
  • Writer open and endpoint resolution perform zero complete node/edge topology scans per construction batch.
  • Immediate execution uses carried authenticated artifact capabilities and fused unavoidable consumers; crash resume reauthenticates exactly where durable capability state is unavailable.
  • Interrupted staging resumes without duplicated live rows; abort/failure leave the prior generation authoritative; recovery never publishes corrupt or missing payloads.
  • Reopen, count, query, export, verify, and clean import operate on the canonical graph through ordinary product readers without a harness-only fallback.
  • A post-merge S20 lower qualification records RSS, configured/submitted chunks, accepted rows, artifact/sync counts, phase bytes/calls, append/seal/recovery elapsed time, and retained/transient disk. S22 runs only after S20 passes and measured headroom admits it.
  • Exact-head repository gates pass for each changed surface.

BDD completion scenarios

Linear constant-factor construction

Given a fixed construction budget and equivalent 1x, 2x, and 4x inputs
When construction, seal, publication, and recovery complete
Then peak resident state remains within the configured bounded envelope
And per-phase rows, bytes, artifacts, calls, and synchronizations grow within documented linear constant factors.

Atomic resumable publication

Given an import stops after several durable chunks or at a publication boundary
When the same session resumes and commits
Then each accepted row appears once
And readers observe either the prior project generation or the complete new generation, never a partial mixture.

Ordinary product readers

Given a graph built through the public append-only construction path
When it is reopened, queried, exported, verified, and imported cleanly
Then ordinary Rust-facade results, counts, and fingerprints match without a scale-harness-only fallback.

Observability

Emit aggregate counters only: configured/submitted rows and chunks, prior rows decoded, rows encoded, artifact/object counts, authentication/read/write bytes and calls by phase, fsyncs, elapsed time, current/peak RSS, logical/allocated retained bytes, and transient peak. Exclude graph identities, values, paths, credentials, and provider resource IDs.

Testing

Documentation

Document the public construction budget, append-only/sharded physical model, authenticated phase counters, retained-versus-transient storage, and the interpretation of deterministic versus provider evidence.

Non-goals

Distributed ingest, increasing RAM or timeouts, weakening integrity/durability, treating asymptotic O(N) alone as sufficient throughput evidence, changing Graph500 policy, or running S24/SCALE26 before #951 qualifies storage.

Relationships

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions