Hand-written. ../harvested/execution-context.md is what the documents say; this file is what the
implementation found, and it wins. Each entry names the harvested entry it answers by that entry's
stable key.
- The cap-draining loop is adopted; the reason the entry gives for it does not apply to this port, and the inverse inference is available and wrong. Supersedes
execution-context/7459f067("The context store's cap-draining strategy should be a post-insert drain loop that continues until at or under the cap, rather than a single check-then-evict, so concurrent insert bursts converge to the bound instead of overshooting"). The instruction is followed to the letter —XCUT-14makes the loop a MUST ("MUST drain back under the cap after each insert using a loop (not a single pre-insert check-then-evict)"),CTX-12asks the same as a SHOULD,CTX-11requires only the draining, anddocs/sdk-design-ruby/05-pipeline-architecture.md§5.4 writes one — and it is the rationale that is false here. Design §5.4 makes the store "a plainHashbehind aThread::Mutex", and the insert and the drain sit inside onesynchronize. The proof is structural, and the obvious measurement is not evidence at all — recorded in that order because reaching for the measurement is the trap. Exactly one key is added per critical section and the loop's entry invariant issize <= cap, sosize <= cap + 1at the top of the loop and the body can run at most once; an overshoot is unreachable rather than merely rare. The tempting number is the drain-body iteration count: 8000 inserts from 16 threads against a cap of 64 leave exactly 64 entries and run the drain body exactly 7936 times on 3.2.11, 3.4.10 and 4.0.6. That number carries no information about the loop.7936 = 8000 - 64is forced by conservation — every distinct key inserted adds one entry, every drain iteration removes one — so any drain evicting one entry per iteration produces it, whatever its locking. Verified, one case per interpreter: a split-lock variant acquiring the mutex separately for the insert and for each eviction, in which overshoot genuinely is reachable, returns the identical 8000 / 64 / 7936; so does a singleifcarrying no loop at all. The two measurements that do discriminate are the maximum iterations in any one call and the maximum size ever observed — 1 andcapunder the one-synchronizeform on all three, against an observed size of 9 at cap 8 under 32 threads in the split-lock form. Under this design the loop and a single check-then-evict are behaviourally identical; the loop is written becauseXCUT-14requires one and because a future striped or lock-free map would need it, not because it buys convergence the mutex already provides. Why this needs recording rather than being a harmless imprecision: the inference runs backwards just as easily. A reader who believes the loop supplies the convergence property can conclude that the loop is what the mutex would otherwise be needed for, and narrow or remove the lock — at which pointCTX-7's "registered, overwritten, and removed concurrently without external locking" andCTX-8's "deterministically admit exactly one winner" both go with it, and neither failure is visible on CRuby, where the GVL hides an unsynchronised read-modify-write (the same shape../notes/concurrency-and-async.mdrecords for counters and phase 3a's P3-6 records for the close latch). The rules the substitution does not weaken and which are adopted verbatim:execution-context/d6a723ddand/08981649(the bound itself, and arbitrary victim selection), andconcurrency-and-async/c0fab747(protect only the smallest critical section) — the drain touches only the store's own hash and yields to no caller code, which is what keeps it inside the lock legitimately. Recorded perdocs/work/mvp/phase4/phase4a/2026-09-08-phase4a-execution-context-design.md. review ·docs/work/mvp/phase4/phase4a/2026-09-08-phase4a-execution-context-design.md· high · sha:manual-phase4a-drain-loop-degenerate - The one shared bounded-map implementation is reachable by its two later consumers, and only under a lexical condition the corpus holds as a separate rule. Supersedes
execution-context/c2eb344c("The context store's bounded backstop is implemented as a post-insert drain loop with arbitrary victim selection, sharing one implementation with the general bounded-map rule and with the per-nonce counter store's eviction"), which states the sharing without stating what it costs in Ruby. The entry is right and the sharing is achievable; what it omits is that every one of the three sites that shares it —CTX-11's store,XCUT-14's general rule andAUTH-19's per-nonce counter store — names it from inside amodule Dexpace; …body, and nothing outside this repository's own namespace needs the map at all, so the shared implementation can be aprivate_constant— whichapi-design/b0e18938's minimal-surface rule andNFR-4's lock both argue for, and whichModule#constantsexcludes from the runtime surface snapshot (verified). The condition, verified on 3.2.11, 3.4.10 and 4.0.6, one case per form: aprivate_constantdefined onDexpaceis reachable by a bare, unqualified reference frommodule Dexpace; module Storeand frommodule Dexpace; module Auth; module Digestat any depth; it is not reachable from the compactmodule Dexpace::Compactform, which raisesNameError: uninitialized constant; and it is not reachable through a qualifiedDexpace::BoundedMapeven from a file lexically insideDexpace, which raisesNameError: private constant … referenced. So "one implementation" holds exactly as far asmodule-organization/64e84d64("define nested constants using the fullmodule/classnesting form rather than compact path syntax, because the compact form causes Ruby to resolve un-prefixed names against only the file's top-level lexical scope") is followed — a rule this repository already requires for an unrelated reason, and which is load-bearing for this one. The two rules are recorded separately in the corpus and are coupled here so that phase 6'sAUTH-19store and phase 9'sXCUT-14audit meet a stated condition rather than aNameError. The contrasting case, decided the other way in the same phase, and the false reason that must not be recorded with it:OBS-25's no-op span and tracer factory are public constants — but not becausedexpace-conformanceis a different gem. Verified on all three, one case: a separately-required file that reopensmodule Dexpace; module Conformanceresolves the bareBoundedMapexactly as a file inside the defining gem does, because the reachability is lexical and per file, and a gem boundary is not a lexical one. What decides it is the reference form the assertion must write:OBS-25's "MUST NOT allocate per call" is a reference-identity claim spelledassert_same Dexpace::Instrumentation::NO_SPAN, bundle.span, a qualified reference, and the third verified case above shows a qualified reference to a private constant raises even from insideDexpace.BoundedMapsurvives being private because it is only ever named from inside amodule Dexpace; …body; the two singletons do not, because they are named from an assertion line. Recorded perdocs/work/mvp/phase4/phase4a/2026-09-08-phase4a-execution-context-design.md. review ·docs/work/mvp/phase4/phase4a/2026-09-08-phase4a-execution-context-design.md· high · sha:manual-phase4a-bounded-map-private-constant