Skip to content

Stores now support non-exact upload sizes & S3 store optimizations - #11

Merged
allada merged 1 commit into
masterfrom
s3-store-supports-estimates-and-buffers
Nov 5, 2021
Merged

allada merged 1 commit into
masterfrom
s3-store-supports-estimates-and-buffers

Conversation

@allada

@allada allada commented Nov 5, 2021 •

Copy link
Copy Markdown
Contributor

S3 store now is optimized and can upload multiple parts concurrently.
Non-exact upload sizes is supported for a follow-up change which
will allow compression to and from backend stores.


This change is Reviewable

@allada
allada force-pushed the s3-store-supports-estimates-and-buffers branch 2 times, most recently from dac98fa to f6da5ed Compare November 5, 2021 04:25

@allada allada left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 29 of 32 files at r1, 5 of 7 files at r2, 1 of 1 files at r3.
Reviewable status: 34 of 35 files reviewed, all discussions resolved (waiting on @allada)

S3 store now is optimized and can upload multiple parts concurrently.
Non-exact upload sizes is supported for a follow-up change which
will allow compression to and from backend stores.
@allada
allada force-pushed the s3-store-supports-estimates-and-buffers branch from f6da5ed to 6a9b50e Compare November 5, 2021 04:44

@allada allada left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 7 files at r2.
Reviewable status: 32 of 35 files reviewed, all discussions resolved (waiting on @allada)

@allada
allada merged commit d093fdd into master Nov 5, 2021
@allada
allada deleted the s3-store-supports-estimates-and-buffers branch November 11, 2021 06:21
rejuvenile added a commit to rejuvenile/nativelink that referenced this pull request Aug 19, 2026
…raceMachina#12/TraceMachina#13/TraceMachina#14: minor cleanups + boundary/mode tests

TraceMachina#8 (MINOR) — `fits()` defensive: added `(Some(_), Some(0)) => true` arm
so a future code path that records a stale `(used, 0)` cannot lock the
peer out of all picker rotations. Sits before the main `<=` arm.

TraceMachina#9 (MINOR) — Reverted visibility widening on
`BlobsAvailableState::fs_store` and `cas_server_fss` to private. Only
consumer is in the same module (`local_worker.rs`).

TraceMachina#11 (MINOR) — Replaced hand-rolled temp paths in
`blobs_in_stable_storage_handler_test.rs` and
`download_to_directory_mirror_test.rs` with `tempfile::Builder`. `.keep()`
disarms auto-cleanup so the FilesystemStore (lives past the test body
inside Arcs) doesn't see its content_path vanish mid-run.

TraceMachina#12 (MINOR) — Inlined `pick_mirror_endpoint` wrapper and renamed
`pick_mirror_endpoint_for_size` → `pick_mirror_endpoint`. The wrapper
was only used by tests (not prod) and the duplication added cognitive
load. All 5 test sites updated to pass `0` for size_bytes (preserves
pre-fix behavior of disabling capacity filter).

TraceMachina#13 (MINOR) — Added `test_fits_at_exact_boundary_returns_true`. Uses
two peers — "a" exactly at boundary, "b" with room — and asserts the
picker round-robins both. Mutate-verified: changing `<=` to `<` in
`fits()` makes the test FAIL (only "b" gets picked).

TraceMachina#14 (MINOR, Linux-only) — Added `mirror_materialize_sets_0o555_mode_on_disk`.
Builds a FastSlowStore whose fast tier is a real FilesystemStore, runs
the mirror-materialize path, then asserts the on-disk file's mode is
exactly 0o555 via `digest_content_path`. Guards against a regression
where the mirror-materialize path bypasses or post-overwrites the
canonical CAS read-execute mode.

cargo check --all-targets clean. mirror_durability_test: 15/15 pass
(was 14). worker_proxy_store unit tests: 31/31 pass (was 30).
Pre-existing unrelated failures in `bytestream_server_test`
(locality_stale_evicts_and_ingests, locality_timeout_falls_through_without_eviction,
write_too_many_bytes_fails) and `existence_store_test`
(copes_with_dropped_items) are NOT caused by this commit — they fail
identically on parent 70b2f59.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
rejuvenile added a commit to rejuvenile/nativelink that referenced this pull request Aug 19, 2026
…Machina#2+TraceMachina#3+TraceMachina#5+TraceMachina#9+TraceMachina#11 (BLOCK-class)

Addresses 6 of 11 reviewer findings on the BlobsAvailable chunking
landing (PR3 of TraceMachina#80). Each fix is annotated with the originating
reviewer + finding ID.

ACCUMULATOR (nativelink-service/src/blobs_available_accumulator.rs):

* Fix TraceMachina#1 (invariant-prover BLOCK + dsr + code-reviewer): Add
  sequence-completeness gate at terminal commit. Before this fix, a
  terminal chunk arriving with gaps in `seen_sequences` committed a
  strict-subset partial — the half-applied-snapshot bug class the
  Path A semantics are meant to prevent. The new
  `BroadcastAccumulator::sequences_contiguous()` checks
  `seen_sequences == (1 << (max_seen_sequence + 1)) - 1`. On
  rejection: drop the partial accumulator, increment
  `dropped_incomplete_sequence` counter, warn-log, return None.
  Worker re-broadcasts on next tick.

* Fix TraceMachina#3 (red-team BLOCK + testing-czar IMP-4 + assumption-auditor
  REFUTED-1): Header scalars (worker_cas_endpoint, cpu_load_pct,
  mirror_used_bytes, etc.) now stored as `Option<HeaderScalars>`,
  populated only when `sequence == 0` arrives. If the terminal
  commits without seq=0 ever arriving, refuse (subsumed by Fix TraceMachina#1
  in practice but documented separately).
  `BroadcastAccumulator::new()` no longer reads scalars from "first
  chunk to arrive" — that path silently lost headers under
  out-of-order delivery.

* Fix TraceMachina#2 (dsr BLOCK-1 + red-team alt 1): Raise MAX_SEQUENCES from
  64 → 256 (bitset switched from u64 to u128-pair) AND
  MAX_ACCUMULATED_ENTRIES_PER_CONN from 200_000 → 1_000_000 to
  match the AC-pin per-endpoint cap of 1M. Worker FSS sizing 50K-
  200K + AC pins + cached_directory_digests easily reaches 1M
  total; the prior 200K cap silently dropped legitimate worker
  traffic.

* Fix TraceMachina#11 (security M1 + assumption-auditor REFUTED-2):
  - Pre-merge per-conn entries-cap projection: cap fires BEFORE
    `acc.merge(chunk)` so peak accumulator memory is bounded by
    `MAX_ACCUMULATED_ENTRIES_PER_CONN + MAX_ENTRIES_PER_CHUNK`,
    not `+ (one hostile chunk's worth)`.
  - Per-chunk entries cap (`MAX_ENTRIES_PER_CHUNK = 8192`):
    rejects oversized chunks before any per-broadcast state is
    touched.
  - Falsification test `entries_cap_drops_partial_at_2x_threshold`:
    drives 2× the cap of synthetic data, asserts cap eviction
    fires AT threshold (not far before, not after OOM).

* Fix TraceMachina#9 (dsr MAJOR-1): Per-reason `chunks_dropped_*` counters
  exposed via `pub drop_counts: ChunkDropCounts`. 9 reasons:
  token_zero, token_mismatch, per_conn_broadcasts_cap,
  per_conn_entries_cap, per_chunk_entries_cap, sequence_cap,
  validation_other, incomplete_sequence, missing_chunk_zero. Each
  warn-log carries the reason as a structured field. Test
  `drop_counters_cover_all_documented_reasons` exercises 7 of 9
  paths (the two missing-chunk-zero paths are structurally
  unreachable when the completeness gate fires first; counter
  exists for defense-in-depth).

* Fix TraceMachina#5 (invariant-prover + assumption-auditor): Replaced
  `out_of_order_sequence_within_window_tolerated` with
  `out_of_order_sequence_with_gap_rejected`. The old test
  ENSHRINED THE BUG by asserting `is_some()` on a commit that
  skipped sequence 1 — the new test asserts `is_none()` with the
  bespoke message "sequence-completeness gate must reject
  incomplete commit; saw is_some() instead — Fix TraceMachina#1
  (invariant-prover BLOCK) regression".

* Removed gratuitous `total_accumulated: AtomicUsize` (code-reviewer
  TraceMachina#4): always accessed under the inner mutex; reduced to a plain
  `usize` field on `AccumulatorInner`. Adds a `total_accumulated()`
  test helper.

CHUNKER (nativelink-util/src/blobs_available_chunking.rs):

* Fix TraceMachina#2 (dsr BLOCK-1): Added
  `BLOBS_AVAILABLE_MAX_CHUNKS_PER_BROADCAST = 256` MUST-equal-the-
  server-MAX_SEQUENCES constant. Changed
  `chunk_blobs_available()` signature from `Vec<...>` to
  `Result<Vec<...>, &'static str>`. Returns Err if a broadcast
  would emit > 256 chunks. New tests:
  `chunker_errors_when_exceeding_max_chunks_per_broadcast` and
  `chunker_allows_exact_max_chunks_per_broadcast` (boundary).

WORKER (nativelink-worker/src/local_worker.rs):

* `send_periodic_blobs_available` updated to handle the chunker's
  new Result return: on Err, warn-log and return Ok(()) (skip the
  tick; next tick retries). Better than emitting chunks the server
  silently discards.

INVARIANTS WALKED:

* terminal-chunk-commits ⇒ seen_sequences forms contiguous prefix
  [0, max_seen_sequence] (Fix TraceMachina#1 — re-established at
  blobs_available_accumulator.rs `sequences_contiguous()`).
* per-conn memory bound: `total_accumulated <=
  MAX_ACCUMULATED_ENTRIES_PER_CONN + MAX_ENTRIES_PER_CHUNK` even
  with a hostile chunk (Fix TraceMachina#11 — re-established at pre-merge
  cap-check).
* chunker output count <=
  BLOBS_AVAILABLE_MAX_CHUNKS_PER_BROADCAST = server's MAX_SEQUENCES
  (Fix TraceMachina#2 — enforced at chunker producer-side guard).

TESTS:

* nativelink-util chunker: 11/11 pass (added 2 tests).
* nativelink-service accumulator: 19/19 pass (added 7 tests,
  rewrote 1, removed 0).

Reviewers cited: invariant-prover BLOCK, distributed-systems-reviewer
BLOCK-1 + MAJOR-1, red-team blind-spot-1 + alt-1 + alt-2,
testing-czar IMP-2 + IMP-3 + IMP-4, code-reviewer Critical TraceMachina#1 +
suggestion TraceMachina#4, assumption-auditor REFUTED-1 + REFUTED-2,
security-reviewer M1 + M2.

Composite invariants this fix interacts with: Path A
(deferred-wipe) commit semantics, mirror_blobs ≥2-replica
durability (untouched — BlobsAvailable is locality hint only),
worker_instance_token contract from TraceMachina#97/TraceMachina#98.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
rejuvenile added a commit to rejuvenile/nativelink that referenced this pull request Aug 19, 2026
…ns + T9 pin order

Cadre fix-up B3+B4+B5+T9+N1+N2 for the chunked_b1_writev_test.rs and a
stale module doc-comment in chunked_writer.rs.

B3 — io_uring skip-guards: every Path-A test now calls
`skip_if_no_io_uring(test_name)` at entry; non-Linux / non-io-uring
hosts log a SKIP and return. Without the guard, Path B
(spawn_blocking) was silently exercised and tests "passed" for the
wrong reason — invariants like T4's "different digests parallelize"
became tautologies on the spawn_blocking path.

B4 — index-visibility assertions: replaced `let _ = results` discards
at T1 and T_multi with a new `assert_index_visible` helper that:
- passes a real `&mut [Option<u64>; 1]` slot,
- awaits has_with_results within a 5 s window,
- panics with bespoke "stale negative — index not updated post-rename"
  when results[0] is None,
- asserts the size matches the expected blob size.
Mutation target named in the panic message per CLAUDE.md
`feedback_index_visibility_contract` (2026-05-04).

B5 — T2 doc-comment: updated the stale "Mutation target" framing from
the prior coalesce-strict-< form (which can never fire under
COALESCE_TARGET == CHUNK_SIZE == 1 MiB) to match the design's §1/§4
load-bearing-win framing (io_uring bypass of the spawn_blocking pool
mutex, NOT coalescing amortization). Steady state IS one writev per
chunk; histogram inversion is the actual contract bug to guard.

T9 — pin-ordering correctness (cadre fix-up P1 falsification): new
`b1_writev_pin_only_advertises_post_cqe_bytes`. Injects writer error
BEFORE the first writev (N=0 trigger fires on writev_submit_count
>= 0 immediately), so NO chunk's writev CQE returns Ok. Asserts
`driver.pinned_chunk_count() == 0` and `driver.pinned_bytes() == 0`.
Mutation: comment out the populate inside `process_completion`'s
Ok-arm AND restore the driver-site populate unconditionally; T9
red-fails with the bespoke "pin advertised bytes before writev
completed" message. (Mutation verification step run in follow-up.)

N1 — chunked_writer.rs stale module doc-comment ("Phase status
(2026-06-03)") updated: wire-up, marker, helper, T1/T_multi/T_drop/
T2/T4/T5/T6/T7/T8 are all landed; cadre fix-up adds T9.

N2 — `use core::pin::Pin;` moved to the top `use` block (was
inline at the test body in the previous diff).

N3 (perf TraceMachina#11 hit_eof cleanup) — skipped: hit_eof is used for the
post-error post-EOF control flow in step 4. The proposed
`while chunk_rx.recv().await.is_some() {} break;` cleanup would
fast-forward to step 7's drain, which already exists; the duplication
is a NIT and the proposed change risks correctness regression in T8.

All 9 tests pass (T1, T_multi, T_drop, T2, T4, T5, T6, T7 unit pair,
T8, T9) on buildcache (Linux + io-uring kernel).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
rejuvenile added a commit to rejuvenile/nativelink that referenced this pull request Aug 19, 2026
…CacheStore construction

Invariant: an ECS over a registered-but-ref-wrapped backend must register
its invalidation callback (the ECS stale-positive triangle's eviction
corner). Violated: ECS::new_with_time queried supports_removal_callbacks()
on a freshly-created RefStore (cell=None) — false-for-unresolved
(e8b1498/TraceMachina#367, deliberate, preserved) latched vulnerable_mode=true at
EVERY boot of this binary+config; AC_INNER's eager-invalidation callback
was never registered on REDIS_AC_STORE (1 of 2 callbacks). Plausibly
present since the config landed ~May 11 (pre-deploy journal retention
prevented earlier detection). Fix: explicit inner_store(None) resolution
before the query — mirrors what FastSlowStore::new_validated does
accidentally at :1445.

distsys traced the post-fix composite end-to-end: callback registers on
the memory tier immediately and deferred-replays onto REDIS_AC_STORE at
first Redis op (notifications default-on). Boot-order safe (declaration
order + graceful degradation on missing names — guarded by test).

Tests: TDD red-verified (timestamp-proven chain) + mutation red with
bespoke 'TraceMachina#9' message; missing-name negative-contract test; callback
liveness via eviction→ECS-clear with timeout-pattern poll. [[test]]
required-features stanza added (testing-czar BLOCK — plain cargo test
refused clearly instead of E0599). Guard comment added on
RefStore::supports_removal_callbacks against future auto-resolve cleanup.

Reviewers 7/7 (records .claude/reviews/acbb767d-ecs-fix/): perf/code/
auditor/security/distsys/red-team landable; testing-czar BLOCK closed in
review batch. Follow-ups: TraceMachina#10 (FastSlow sibling), TraceMachina#11 (callback-chain
observability: vulnerable_mode=0 can mask a dead chain; FastSlow
capability honesty; metric help-text; get_store-abort edge;
production-shape propagation test).

Behavior changes: AC_INNER ECS registers eager invalidation at boot;
the startup vulnerable_mode ERROR no longer fires for ref-wrapped
registered backends.

Closes TraceMachina#9.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rejuvenile added a commit to rejuvenile/nativelink that referenced this pull request Aug 19, 2026
…k-chain correctness (ECS/FSS/RefStore)

## Invariant Walk

Invariant being violated: A store reporting supports_removal_callbacks()==true
must actually fire callbacks on every eviction observable to the composite;
any composition layer that returns true unconditionally without querying its
inner stores leaves ECS in a false-safe state where vulnerable_mode=false but
no callbacks ever fire.

Mechanism that violates it:
- fast_slow_store.rs: no supports_removal_callbacks override → trait default
  `true` inherited unconditionally; ECS(FastSlow{*, GrpcStore}) would see
  supports=true, register a dead callback, and never fire on GrpcStore-side
  evictions.
- fast_slow_store.rs:756-area register_slow_eviction_stable_set_listener
  called supports_removal_callbacks() on a possibly-unresolved RefStore; an
  unresolved RefStore returns false by design (e8b1498/TraceMachina#367 contract), so
  the BIS listener would log a false warn and skip registration.
- ref_store.rs:get_store loop: `store.register_item_callback(callback)?`
  returned Err WITHOUT writing the cell — permanently bricking the RefStore;
  every subsequent op re-entered the slow path and failed forever.

Mechanism that re-establishes it after the fix:
- fast_slow_store.rs: new supports_removal_callbacks override resolves both
  tier stores via inner_store(None) before querying, then returns
  fast.supports() && slow.supports(); ECS gets the correct composite answer.
- fast_slow_store.rs:register_slow_eviction_stable_set_listener: calls
  slow_store.inner_store(None) before supports_removal_callbacks(), forcing
  RefStore cell population so the capability query sees the resolved store.
- ref_store.rs:get_store: writes the cell BEFORE replaying callbacks; replay
  Err is logged + counted but resolution is considered succeeded (degraded,
  not bricked).

Composite invariants this fix interacts with:
- ECS vulnerable_mode triangle: gate (supports=false → vulnerable_mode=true)
  OR eager-invalidation-via-callback; fix ensures the gate correctly reflects
  whether callbacks can fire end-to-end.
- BIS listener registration: BIS ack requires the stable-set callback path
  fires on every slow-tier eviction; TraceMachina#10 fix ensures direct FastSlowStore::new
  callers with ref-wrapped slow stores don't silently lose the listener.
- RefStore resolution contract: after get_store() returns Ok, the cell is
  permanently written and all ops delegate to the resolved store even if
  callback replay partially failed.

Test that proves the fix re-establishes the invariant:
- capability_query_callback_chain_test.rs (all 9 tests, 0 failures):
  - fast_slow_supports_callbacks_false_when_slow_does_not (TraceMachina#11 Item 2)
  - fast_slow_supports_callbacks_true_when_both_tiers_support (TraceMachina#11)
  - fast_slow_supports_callbacks_true_when_slow_ref_resolves_to_memory (TraceMachina#11)
  - ref_store_get_store_not_bricked_by_callback_replay_failure (TraceMachina#11 Item 5)
  - ecs_over_ref_fast_slow_slow_tier_eviction_clears_cache (TraceMachina#11 Item 6)
  - ecs_invalidation_callbacks_fired_counter_increments (TraceMachina#11 Item 3)
  - fast_slow_new_ref_wrapped_slow_registers_bis_listener (TraceMachina#10)
  - ecs_over_fss_no_callback_slow_enters_vulnerable_mode (TraceMachina#11 Item 2 over-action)
  - fss_supports_callbacks_false_when_fast_does_not_and_rule (TraceMachina#11 AND-rule pin)

## Changes

### Item 1 (TraceMachina#10) — resolve RefStore before BIS listener capability query
fast_slow_store.rs: `register_slow_eviction_stable_set_listener` calls
`slow_store.inner_store(None::<StoreKey<'_>>)` before
`supports_removal_callbacks()`. Forces RefStore cell population so the
unresolved-cell false-return doesn't trigger a misleading warn.

### Item 2 (TraceMachina#11) — FastSlowStore supports_removal_callbacks honesty
New `StoreDriver::supports_removal_callbacks` override on FastSlowStore
resolves both tiers via `inner_store(None)` then returns
`fast.supports() && slow.supports()`. Pre-fix: trait default `true`
inherited unconditionally. AND rule is over-conservative for ECS stale-
positive prevention (slow-only suffices) but kept as defense-in-depth.

### Item 3 (TraceMachina#11) — ECS invalidation_callbacks_fired counter
New `CounterWithTime` field on ExistenceCacheStore, incremented in the
ExistenceCacheCallback::callback path when a cache entry is actually removed.
Metric counts evictions from ANY registered tier (fast-tier LRU churn AND
slow-tier evictions); nonzero does NOT prove slow-tier chain is alive; zero
over a churn window with active writes is the meaningful dead-chain signal.

### Item 4 (TraceMachina#11) — vulnerable_mode metric help-text correction
Updated metric help to describe the actual condition (construction-time
supports_removal_callbacks()==false) rather than the incorrect prior text
("register_item_callback failed at construction").

### Item 5 (TraceMachina#11) — RefStore cell-write-before-replay no-brick fix
ref_store.rs:get_store: writes the cell unconditionally before the callback
replay loop. Replay errors are degradations (log + counter), not failures.
New `callback_replay_failures: AtomicU64` metric field.

### Item 6 (TraceMachina#11) — Production-shape propagation test
New test `ecs_over_ref_fast_slow_slow_tier_eviction_clears_cache` exercises
the full AC-chain shape: ECS(RefStore→FastSlow{Memory, Memory}). Verifies
slow-tier eviction propagates via FastSlow fanout to ECS cache removal
within a 3-second deadline.

## AND Rule: Invariant + Correctness

FSS.supports_removal_callbacks() returns fast.supports() && slow.supports().
Only slow-tier evictions create ECS stale positives (fast-tier eviction while
slow still holds the blob = false negative, self-correcting). So slow.supports()
alone is sufficient; AND is defense-in-depth. A future fast tier returning
supports=false (e.g. WorkerProxyStore) would put ECS in vulnerable_mode=true
unnecessarily; revisit the rule then.

## Behavior Changes

FastSlowStore::supports_removal_callbacks: prior → new
  FastSlow{Memory, Memory}: true (default) → true (explicit; no change)
  FastSlow{Memory, GrpcStore}: true (default, wrong) → false (correct)
    GrpcStore.supports=false per ce4d2ec/TraceMachina#367 original commit (grpc_store.rs:3468)
  FastSlow{Memory, RefStore(Memory)}: true (default) → true (after resolve)
  FastSlow{Memory, NoCallbackStore}: true (default, wrong) → false (correct)

Production compositions (verified against /srv/nativelink/buildcache-native.json5):
  cas_FAST_SLOW_STORE = FSS{MemoryStore, FilesystemStore} (line 111-140)
    fast = plain MemoryStore (not SizePartitioningStore; SPS lives at cas_INNER
    level as the ECS backend). fast.supports=true, slow.supports=true.
    Composite stays true. No behavior flip. No ECS wraps directly.
  AC_BACKEND_CACHED = FSS{MemoryStore, RefStore(RedisStore)} (line ~66-area)
    Redis slow (enable_keyspace_notifications default true):
    composite stays true. NO flip. vulnerable_mode stays false, matching
    TraceMachina#9 deploy verification (vulnerable_mode=0).
  SMALL_CAS_CACHED = FSS{MemoryStore, RefStore(REDIS_CAS_SMALL)} (line 206-220)
    keyspace default true → composite true. No flip.

Mutations verified red:
  MUTATION-1 (TraceMachina#10 inner_store resolution): observability-only — no behavioral
    falsifier exists; the callback fires via RefStore queuing regardless; the
    fix corrects which warn arm fires. No mutation evidence claimed.
  MUTATION-2: remove supports_removal_callbacks from FastSlowStore → tests
    fast_slow_supports_callbacks_false_when_slow_does_not,
    ecs_over_fss_no_callback_slow_enters_vulnerable_mode,
    fss_supports_callbacks_false_when_fast_does_not_and_rule all fail with
    bespoke messages.
  MUTATION-3: remove invalidation_callbacks_fired.inc() → test
    ecs_invalidation_callbacks_fired_counter_increments fails with bespoke
    "TraceMachina#11: invalidation_callbacks_fired counter did not increment after eviction"
  MUTATION-5: re-add `return Err(err)` in replay loop → test
    ref_store_get_store_not_bricked_by_callback_replay_failure fails with bespoke
    "TraceMachina#11: ref bricked by callback replay failure"
  MUTATION (new test a): revert supports_removal_callbacks to true →
    ecs_over_fss_no_callback_slow_enters_vulnerable_mode red-fails with bespoke
    "TraceMachina#11 over-action: ECS(FSS{Mem, NoCallback}) must enter vulnerable_mode=true..."
  MUTATION (new test b): flip AND to || →
    fss_supports_callbacks_false_when_fast_does_not_and_rule red-fails with bespoke
    "TraceMachina#11 AND-rule: FSS{NoCallback-fast, Memory-slow}.supports() must be false..."

Cargo churn: tokio-epoll-uring exclude (Cargo.toml) + assert-panic/os_pipe
removals from Cargo.lock were NOT required for this branch to build
(verified: cargo check -p nativelink-store clean without exclude); reverted.

Bench scope: observability + callback-path (not data-plane hot path). Exempt
from data_plane_bench per CLAUDE.md (no ByteStream/FastSlow/FilesystemStore
hot-path changes).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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