Skip to content

test(chaos): fault-proxy campaign — byte-identical backfill under injected Portal faults#149

Merged
dzhelezov merged 3 commits into
mainfrom
chaos/p1-fault-proxy
Jul 11, 2026
Merged

test(chaos): fault-proxy campaign — byte-identical backfill under injected Portal faults#149
dzhelezov merged 3 commits into
mainfrom
chaos/p1-fault-proxy

Conversation

@dzhelezov

Copy link
Copy Markdown
Collaborator

Adds a fault-injecting chaos campaign under harness/chaos/ that stands up an HTTP proxy in front of the SQD Portal and runs a fixed-range historical backfill (euler-app, range [20529207,20579207]) under one injected fault class per scenario, then verifies the resulting store is byte-identical (logical digest) to a clean baseline and that the indexed block intervals tile the window exactly.

Scenarios

8 body-fault scenarios — each fires ≥1 real fault and completes byte-identical, no missed faults:
429-burst, 5xx-storm, retry-after, tcp-reset-mid-ndjson, 90s-stall, truncated-gzip, malformed-ndjson, spurious-204.

Head scenarios:

  • head-freeze (frozen head below endBlock) — the Portal stalls (finalized head behind the requested range); the app makes little/no progress, then a clean restart on the same DB with the fault removed completes byte-identical. The one meaningful in-range head scenario.
  • head-regression-100k, head-flap — marked not-applicable: for a fixed-range historical backfill the manipulated head stays ≥ endBlock and never intersects the pinned range, and such a backfill never rolls back an already-finalized+indexed block. Head-reorg/rollback tolerance is a stream-mode property (covered by the stream soak), not this harness. These are reported as N/A — never counted as a head-tolerance PASS.

Verification is fail-closed

A scenario passes only if the verifier independently recomputes both digests (pg-digest) and confirms full interval tiling over the window; it fails closed on any empty digest or any gap. A byte-identical store still fails a run if a secondary gate (fault-fired count, or an AIMD concurrency bounds violation) fails — so the gate is not vacuous.

AIMD tracing

The fork's AIMD portal-gate concurrency is traced. Runs with fewer than 3 samples are labelled honestly as sparse — insufficient samples and never claim recovered.

Test/harness-only change (no product-code surface); evidence artifacts are gitignored.

dzhelezov and others added 3 commits July 10, 2026 23:43
… AIMD labels, biome gate

Addresses the blind 3-model REQUEST-CHANGES review of the P1 fault-proxy chaos
campaign. The core correctness property (digest-identity + interval-tiling, fails
closed) is preserved and unweakened; the fixes stop the head-* and AIMD *labels*
from overclaiming.

1. biome gate: `biome format --write` the 11 scenario JSONs (semantically identical)
   and rename the unused `init` param at chaos-aimd-trace.cjs:66 → `_init`, so
   `biome@2.5.2 check chaos-aimd-trace.cjs scenarios/faultproxy/` exits 0 (error-level).

2. AIMD sparse candor (finding #3): a single gate sample can no longer assert
   `recovered`. `sparse` (samples < 3) is reported honestly ("sparse — insufficient
   samples"), never as recovery. AIMD stays SECONDARY — sparse does not fail a
   scenario whose digest+intervals pass; only a genuine bounds violation (concurrency
   outside [min,max]) still fails the AIMD gate.

3. head recovery elif false-pass (finding #4): recovery now runs ONLY for head-freeze
   and ONLY when phase 1 did not complete (done != 1). A failed head_recovery_check
   propagates instead of retaining a stale pass. `byte-identical-recovery` is reserved
   for a genuine stall+resume; an unexpected completion labels `byte-identical-completion`.

4. head-freeze label candor (finding #5): honest note — "stalled without corruption;
   clean restart on the same DB (fault removed) completed byte-identical" — no
   partial-progress-resume implication.

5. head-regression-100k & head-flap vacuity (findings #1/#2, unanimous): these
   manipulate the head ABOVE the pinned endBlock so it never intersects the fixed
   range [20529207,20579207]; a fixed-range historical backfill never rolls back an
   already-finalized+indexed block, so they prove nothing the clean baseline did.
   Marked NOT-APPLICABLE (distinct verdict, not a head-tolerance PASS, not a fail) with
   a note pointing head-reorg/rollback coverage to the stream-mode soak. head-freeze
   (frozen head BELOW endBlock) remains the one meaningful in-range head scenario.
   Chosen the ORCHESTRATOR-approved N/A fallback over an in-range redesign because a
   genuine in-range regression/flap is not achievable non-contrived: regression is
   anchored to the drifting live head, and an in-range flap only duplicates head-freeze
   without exercising rollback (a stream-mode property).

Verified: biome check EXIT 0 on changed files; bash -n clean; head-freeze re-run on
the throwaway PG (54329) PASS byte-identical-recovery, digest == baseline, intervals
tile exactly, honest note emitted; N/A routing confirmed by code-trace; proxy.test.mjs
6/6.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…p hardcoded absolute paths)

Env-overridable defaults under $ART (the gitignored artifacts dir) so the
harness is portable and carries no machine-specific absolute paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dzhelezov dzhelezov merged commit 5a2fe88 into main Jul 11, 2026
14 checks passed
@dzhelezov dzhelezov deleted the chaos/p1-fault-proxy branch July 11, 2026 00:30
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