Repository navigation
Close the V4.1 Engram membership against the full index (stacked on #12010) - #12012
Conversation
… published row-store encoding key - gunbc.spark.v41_checkpoint_materialize: a fleet-converge mode (spark_v41_checkpoint_materialize) that materializes the ADMITTED V4.1 population (48 shards, index, 3 tokenizer files) on one Group A Spark. Every file is a gunbc.artifact_acquisition subject keyed ContentDigestSha256; the digest is computed on the host and compared in-model, so a present right file is a noop, a present wrong file refuses and is left in place, and a fetched file is staged and published by rename only after it matches. Sources: the host's Hub cache copy at the pinned revision, then hub_resolve_url. The disk requirement (bytes not already present at declared size) is stated and refused before any fetch. Transfers reuse model_snapshot_materialize's detached units; a run supervises briefly and a rerun reattaches. After the shards verify it reads the sha256 of the four storage-backed Engram spans. - Admission per ruling (proud-deer-538): hosts held by PairServingUnitOn FabricGroupA only; Group A's ArmDomain concurrency key; no host-effect claim (the committed-host staging claim in host_commitment is the stronger construction, not taken, stated in the annotation). - gunbc.spark.v41_engram_row_store v41_published_row_store_key: the row_store_encoding axis is keyed by sha256 over the encoding spec key + the planned spans' digests, joined to the plan by identity. RED: a reading over a different table set, a resident tensor or a shifted region refuses. The live reading row is Unread until a run's receipt is transcribed. The four rank-file identities stay D1's produced facts (noted in the candidate). - V41EngramResidencyPartition and v41_input move to gunbc.spark.v41_identity_input so the candidate can import the row store without a cycle. - fleet-converge.yml regenerated. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
extdeps.deepseek.deepseek_v4_1_flash carries deepseek_v4_1_flash_engram_index_selection: the .engram. selection over all 96085 weight_map names of the pinned index (sha256 74b0686a..., checked on read 2026-09-21), from which the member rows and the membership closure are DERIVED. The closure closes only over the pinned index identity and its full name count; otherwise it stays scoped. RED: a 13th .engram. name refuses the population (previously neither reconciled nor refused). The selection was read outside the interpreter because parse_json_document did not finish the 7.4 MB document in 15 minutes; running it as a fold is the stated next rung. The candidate witness's membership test becomes a pair: a scoped closure stays unestablished, the live closed population keys. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…lan reaches the receipt; no shell program strings in the mode - V41SpanPlanRefused carries v41_published_span_plan's defects into the receipt (span-plan-refused line), instead of an empty span list. - The directory listing is extdeps.tools.findutils find_regular_file_sizes_argv behind a test -d probe; free space is extdeps.tools.gnu_coreutils df_available_bytes_argv after mkdir -p of the directory, with the last line read in-model (no sh loop, no tail). - The span digest is extdeps.tools.sha256sum sha256sum_byte_span_argv: fixed bash text owned by the tool authority with path/offset/length as positional operands, and a frontier row naming its dissolution (a modeled pipeline realization). - The witness asserts the span argv's exact shape and that a refused plan reaches the receipt. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…bservation, compared against the pin - gunbc.spark.v41_index_engram_selection (observing layer): v41_index_engram_selection_read_wet digests a local copy of the index and runs a token scan that reads exactly the published shape (no escapes; metadata, total_size, weight_map; name/shard pairs) and refuses anything else; its receipt's own values are transcribed as literals into v41_index_engram_selection_reading. Run 2026-09-21 over the index fetched at dba1be0a: sha256 74b0686a..., 7470294 bytes, 96085 names, 12 .engram. members. - extdeps.deepseek.deepseek_v4_1_flash no longer carries a live selection: its closure stays MembershipScopedToReadRows; it owns the pure fold deepseek_v4_1_flash_engram_membership_closure_of, which now compares a READING (literals) against the pin -- a reading of another file or over fewer names stays scoped. - The candidate's population is v41_engram_population_observed(): the extdeps population until a reading is transcribed, the closed one after. - Witnesses: the scan over supplied text (selects, counts, refuses outside its shape); readings of another sha, fewer names, a 13th member (RED: refuses by name); the live reading closes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Addressed review 69728 in 61355eb. The finding was right: the guards compared the pin's symbols with themselves, and the only evidence was prose.
— sent from sleek-bee-348 |
…time_image_build (main) and spark_v41_checkpoint_materialize; repoint main's new V41EngramResidencyPartition/v41_input imports to gunbc.spark.v41_identity_input; fleet-converge.yml regenerated Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…t_host_held_by_subject The predicate 'is this host held by <subject>' is a host-commitment fact, and a second consumer (spark_v41_runtime_image_build, #12008 lane) is about to need it, so it lands in host_commitment (admit_host_held_by_subject, with admit_host_held_by_subject_among taking the held set as a supplied value) before it has two consumers. spark_v41_checkpoint_materialize consumes it; its local v41_group_a_admission is deleted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…led route, and index_bytes is a ByteSize - v41_index_engram_selection_reading is Unread again: a local diagnostic run of the scan is not an enrolled route, so its output does not land (DESIGN 4b(1), 5). The route is spark_v41_checkpoint_materialize: after the index verifies on the Spark, the mode reads its digest and size back, fetches the bytes and runs v41_scan_index_text over them; its receipt's index-selection lines are what the reading is transcribed from, the same standing as the span readings. Until then the observed population is the extdeps one, scoped, and the candidate's Engram axis stays unestablished. - index_bytes: ByteSize (no re-wrap at the use site). - Witnesses: the live reading is unread and the observed population scoped; the candidate pair's closed side is a supplied reading of the pinned file; the mode's receipt carries every field of the reading. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Addressed review 69785 in 71afc99. Both findings were right.
— sent from sleek-bee-348 |
…ost_disk_observation, byte quantities are ByteSize, the checkpoint directory is derived from the repo and the pin
- gunbc.host_disk_observation gains the one free-space argv (host_disk_free_space_argv) and the one reader (host_disk_observation_of_df -> DiskObserved { free_bytes: ByteSize } | DiskObservationRefused), so df output is read in the fact's declared home; the mode runs the argv over its own authenticated leg and consumes the typed observation. host_disk_observed_producer's HostEffectTransport dissolution is unchanged.
- V41DiskRead's required/available/population are ByteSize; v41_checkpoint_bytes and v41_required_bytes return ByteSize.
- v41_checkpoint_directory = /home/briansrls/models/<hub_repo_cache_directory_name>/<deepseek_v4_1_flash_revision>, so a revision bump lands in a new directory.
- fleet-converge.yml regenerated after the merge.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…rship # Conflicts: # dag/test/claim/spark/v41_checkpoint_materialize_witness_test.dag
file_offset and length are ByteSize, built from safetensors_shard_declared_overhead + the entry's begin (measure_add) and safetensors_entry_span without unwrapping; byte_size_count appears only where the value becomes argv or receipt/key text, and span equality compares counts at that same boundary. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…x size read refuses rather than widens - v41_pairs_of is one fold that keeps only the open name, the name count, the non-shard count and the SELECTED members, so it neither re-indexes the token list per element nor copies an accumulator proportional to the index (measured 2026-09-22: the scan over the pinned 7.4 MB index completes in ~2m12s with 96085 names and 12 members; an intermediate list_push-over-every-pair fold did not finish in 15 minutes). A name left without a shard refuses. - V41IndexSelectionRead.bytes is a ByteSize read by v41_wc_bytes; wc output that is not a count is an unread index (refusal), never an empty size on a line that reads as success. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Addressed review 69820 in a82ca86.
— sent from sleek-bee-348 |
…consumed at all three sites (review 69857) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…rk_apply (main) and spark_v41_checkpoint_materialize; fleet-converge.yml regenerated Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ion/sleek-bee-348-membership Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The floor refused this head on ONE blocker and flagged two more: ENROLMENT-MARGIN-REFUSED on the_v41_checkpoint_materialize_mode_serializes_on_group_a (690243 eval steps, cpu 2577ms against a 302ms margin), and COMPLETED-OVER-COST-REQUIREMENT on the_pair_serving_d0_mode_...admits_before_credentials (690270) and the_disk_requirement_counts_only_what_is_missing (113763). Each is the same defect at a different link, and none of it is the assertions' (DESIGN §3, a witness discriminates at ONE interface): the two workflow claims RENDERED THE WHOLE fleet-converge workflow to grep substrings out of it, paying the full emission for every question asked. The credential prelude's step order and the dispatch input roster are now their own declarations — fleet_converge_credential_prelude_steps and fleet_converge_dispatch_inputs — the job consumes them, and the claims read those values plus the concurrency-group expression and the materialize step directly. The emitted workflow is the same value; nothing about what it renders moved. v41_required_bytes split every listing line once per file per line. The listing is parsed once into V41ListedFile, and a line of any other shape is dropped there rather than counting a present file at some size. v41_published_span_of now consumes extdeps.safetensors.format's own safetensors_shard_bounds_resolution and keeps its three arms apart: a duplicated bound row is a contradiction in the supplied shard files, an absent one is a thing not yet read. Rendering both as one sentence erased a distinction the upstream model carries, so each arm gets its own refusal and its own claim. Measured locally after: 45915 / 67642 / 17271 eval steps, cpu 159 / 238 / 16ms. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
witty-moth-853 reached the same floor blocker from #12022 and split this claim three ways rather than only making it cheap. That is the better repair and this adopts it: as one claim the three independent listings shared a budget, so a regression in the one-short arm failed under the same name as one in the all-present arm. DESIGN section 3 -- a conjunction of independent cases forced through one budget when splitting them loses no coverage. The narrowed two-row population stays, as w_two_rows(): it is the REAL admitted population filtered, not a fixture, so the listing join is each claim's only subject while the 52-row shape remains the previous claim's. That is what keeps three separate claims from costing three whole-population folds. Measured: 17598 / 17052 / 17076 eval steps, cpu 20 / 15 / 15ms, against the 72300 budget -- from 113763 as one claim. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…read witty-moth-853 noticed while in this file that the_microvm_network_step_binds_the_dispatched_host_into_its_environment also calls expected_fleet_converge_yml_content(), and wondered whether it was the same latent shape. Measured: 706,541 eval steps, cpu 2242ms -- WORSE than the claim that actually refused this head (690,243). The roster check is what makes it worth fixing here rather than noting. Its two neighbours in this file -- fleet_converge_apply_step_binds_plan_hash_to_env_not_ shell_literal (240,820) and fleet_converge_workflow_has_no_heal_revalidation_paste_ through (232,737) -- are BOTH in v2.workflow.floor_cost_debt. This one is in neither that roster nor the grandfathered one, so it is unprotected: it did not block only because changed-witness selection did not reach it, and the next change that does reach it refuses. The two neighbours stay as they are; they are main's declared debt and not this lane's to re-open. The repair also makes the claim STRONGER, which is why it is not merely a cost edit. The two env conjuncts asserted the name and the expression SEPARATELY, so a step carrying both in different pairs satisfied them; the yml line beside them was carrying the actual binding. Reading the one rendered pair off the step keeps that binding, and the step id comes off the step rather than the render. 706,541 -> 20,538 eval steps, 2242ms -> 65ms. Discriminating red run before committing: perturbing the pattern to github.event.inputs.target fails the claim, so it reads the real pair and is not green by construction. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The floor refused 3efc95a with claims_failed=0, enrolment_margin_blocking=0 and all three earlier blockers cleared. One left: the_pair_serving_d0_invocation_is_bounded_and_the_step_timeout_is_the_declared_sum at 91,527 eval steps against the 72,300 new-witness budget. Another unprotected identity in this file -- in neither floor_cost_debt nor the grandfathered roster -- selected because a change here made it a changed witness. It built FOUR invocation strings, and three of them were there for a different fact than the claim is named for: that one gunbc_ci_sm_max_time reaches the keyring converge, the boot and the fan observe. A regression in the fan observe was reading as a d0 bounds failure, so the split is a subject repair as much as a cost one (DESIGN section 3, a claim discriminates at ONE interface). THE TWO-WAY SPLIT DOES NOT CLEAR THE BUDGET, and this is the part worth recording: moving those three conjuncts into one new claim measures 81,123 -- still over. The cost is the PRODUCER COUNT. Each sibling renders its own invocation in full, so three renders cost three renders wherever they sit, and splitting by subject only moves the number when it splits the producers apart. So it is four claims: the_pair_serving_d0_invocation_is_bounded_... 29,125 the_approval_keyring_converge_prelude_carries_... 40,043 the_mtcollins1_boot_prelude_carries_... 48,627 the_mtcollins1_fan_observe_prelude_carries_... 33,635 They do not sum to 81,123 -- 40+48+33 is about 122k -- because each claim pays its own module overhead. Total work rises and every identity goes under, which is what a per-identity gate asks for; the budget is not divisible. witty-moth-853 reached the same claim independently and made the two-way split on 02745ed without measuring it. Flagged before they landed it; they are reverting and taking this. Also sweeps three import lines in v41_checkpoint_materialize.dag that name six symbols the module never references (review 70015). Verified by grep, not by a green: a .dag import list does not bind, so a passing claim proves nothing about it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…splits at the producer 70042 is right and I verified its premise rather than its wording. All five bash_build_* builders exist, gunbc.ci.ci_failure_class builds this exact shape structurally, and gunbc.shell_command_text's own header says a second spelling IS the section 3 fork -- the hand-spelled dd | sha256sum text was the third independent reach. (Its serializer citation pointed at shell_command_text rather than v2.workflow.bash_command_fold_serialize, but the capability is real and wrapped, so the finding stands.) The pipeline is now a bash grammar tree serialized through that one authority. The frontier row admitting the fixed text is DELETED: its reason -- "no argv carrier here expresses a pipeline" -- is false on the current corpus, and its dissolution named a capability that had already landed, so it could never have fired. A frontier row whose reason does not hold is worse than none. THE CLAIM SPLITS AT THE PRODUCER, which is this branch's own lesson one link up. The subject "path/offset/length reach their declared slots" is a fact about how the argv is ASSEMBLED, not about the serializer -- but index 2 holds the program, so forcing the list to read index 4 paid for a render the claim never inspects. sha256sum_byte_span_argv_of now takes the program as a value: the_span_read_puts_its_operands_in_their_declared_slots 22 steps (was 204,605) Full operand coverage with an authorable RED -- any permutation of the seven fires it, where length(argv)==7 would stay green through all of them. THE INHABITANCE HALF KEEPS THE REAL ROUTE AND TAKES A DECLARED DROP. the_span_read_reads_exactly_its_region still runs the real producer with the really-serialized program and measures 204,569 against the 72,300 new-witness budget; the value is lazy, so inspecting the argv at ANY index forces the render and there is no cheaper inspection. Reducing it further would remove the last execution of the real path, which section 3's pairing obligation forbids. So: gunbc.rung_drop sha256_span_program_serialize_new_witness_eval_step_cost, its own list per that module's rule, with a restoration trigger naming the CAPABILITY in two independently sufficient clauses -- the program served across claim frames, OR the serializer fitting the budget. The claim still executes, still records its steps, and a semantic red or wall crossing still blocks. Whether 204,569 steps for fourteen words is itself a cost-shape defect in bash_command_fold_serialize is NOT asserted here -- it is a hypothesis, and the trigger is written so either outcome retires the drop. The row names the instrument that re-derives the figure rather than transcribing it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…import sweep) One conflict, in the witness file's import roster: this branch added v41_index_engram_selection, the parent added sha256sum_byte_span_argv_of to the sha256sum row. A roster conflict is a replace and not an append, so the members are unioned and one declaration of each kept -- taking either side alone would have dropped the other's symbol silently. Both sides' coverage is intact and re-run, 20 claims: this branch's index scan, membership and selection claims, and the parent's three disk-requirement splits and the two span claims that 70042's repair split at the producer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ervable The token scan's divergence from extdeps.languages.json rested on a transcribed figure -- "did not finish this 7.4 MB document in fifteen minutes in the interpreter (measured 2026-09-21)": a number, a date, no producer. 70075 is right that DESIGN section 6 forbids exactly that, and right about why it was load-bearing twice: the figure was the whole warrant for the fork AND the only way anyone could tell whether the stated dissolution trigger had fired. A trigger nobody can observe makes the fork permanent in practice, which is the section 4b(3) defect of a trigger that will be satisfied while the capability stays dead. The number is gone. v41_index_parse_json_probe_wet runs parse_json_document over the same index and reports which arm it reaches, so both the warrant and the trigger are a run anyone can make rather than a sentence anyone must believe. It is deliberately UNBOUNDED IN TIME: a run that does not return IS the reading, which is the state the divergence rests on and the one a copied duration could only assert. When it exits zero with JsonDocumentParsed the condition has FIRED, and the probe and the scan are deleted together. Executed, not just declared: run over a small index it reaches JsonDocumentParsed and writes the receipt, so the firing arm is reachable rather than decoration. THE SECOND HALF OF 70075 IS NOT MINE TO WRITE. It asks that the divergence be admitted by the operator rather than by this comment, per docs/plans/scaffold-admission-doctrine.md -- and that doctrine says approval is EXTERNAL to the diff precisely because an author who can write a scaffold can equally write a row claiming it was approved. So no admission row is added here. It is escalated against this head; the doctrine also says any later push invalidates it, which is why the instrument lands first and the ask follows. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The scan materialised the ~192k-element token list SIX times -- split, enumerate, filter, map inside v41_quoted_tokens, then enumerate/filter/map again ONLY to read three elements, and a third time ONLY to drop those same three. On the 7.4MB index that is six full copies on the converge mode's success gate, inside a routine whose reason for existing is that the general parser cannot chew a document of this size. 70086 is right and I verified every traversal in source. The parity is now fold state rather than an index, which is what removes `enumerate`: a segment is inside quotes exactly when it follows an odd number of quote characters, and that is a Bool the fold already carries. `split` is the one materialisation that remains; everything after it is a single fold that routes the first three quoted tokens to the head and the rest to v41_pair_step in order. v41_quoted_tokens and v41_pairs_of are deleted -- after the change nothing consumed them, and a declaration with no consumer is DESIGN section 3c's redundant work. WHAT IT ACCEPTS IS UNCHANGED, which was the binding constraint: a faster scan that accepts more would be a worse scan. Head must still be exactly metadata/total_size/weight_map, an unpaired trailing name still refuses, a non- .safetensors value still refuses, a zero-name map still refuses, byte-identical causes. the_scan_refuses_outside_its_shape and the thirteenth-tensor red both hold. THE REPAIR DID NOT MAKE IT FASTER, AND I AM NOT CLAIMING IT DID. Measured on the real pinned index, same container, sequential: before (six traversals): 2m42s after (one fold): 2m47s Byte-identical receipt both times -- 928 bytes, names=96085, the same 12 members -- so this is semantic equivalence established on the real subject rather than on a 200-byte fixture. But the wall clock did not move, which FALSIFIES the estimate I would have made and says the cost is not in the traversals at all. Five of six copies were free at this n; what remains is `split` itself or per-element interpreter overhead in the one fold. It lands anyway, on the ground DESIGN section 6 actually gives: a proven cost-shape defect is always fixed regardless of the realized n, and "n is small here" is not a time-stable fact. The justification is structural, not a percentage -- and the measurement is recorded as the adversary it is, not quietly dropped because it disagreed. That null result is also evidence for the parser lane (adhoc-cec2976b-a10): if list traversals are not what costs here, the >32-minute non-return of parse_json_document is unlikely to be traversal count either, and a shared primitive both routes touch is a live candidate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Review 70102 — no code change, and deliberately so. The one blocking item is the scaffold admission, and the doctrine says that admission cannot come from this diff.
Status of that admission: filed as an operator card, bound to this exact head The premise is no longer asserted. When the divergence was first proposed it rested on a transcribed figure with no producer, which review 70075 correctly refused under §6. Both sides have since been executed against the pinned artifact — sha256
Re-derive either with That measurement is also what takes Review 70086's other finding is fixed in — sent from sleek-bee-348 |
…12010's pre-squash head as the base, docs/design-rung-drops.md taken from main for heal to regenerate Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
The — sent from sleek-bee-348 |
…checkpoint_materialize_witness_test Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… its own step, behind a hard memory.max The token scan was a stated divergence from extdeps.languages.json, kept because parse_json_document did not read a 7.4MB index in the interpreter. After #12066 the operator ruled to drop the scaffold rather than admit it (option A): the scan, its local diagnostic and the parser probe are deleted, and the selection is a fold over parse_json_document's value (V41IndexScan -> V41IndexParse). The read moves out of the materialize run into its own entry and fleet-converge step, v41_index_selection_ci_wet, so a parse stopped for memory cannot take the fetch's per-file receipts with it. It verifies the index against its manifest row itself (v41_observe). Both entries now share one CI bracket, v41_group_a_ci_run, instead of two copies of the target, trust and credential setup. The parse runs only inside a hard memory fence: v41_memory_fence reads /proc/self/cgroup and every bounding level's memory.max and memory.high, and takes the tightest hard limit (extdeps.linux.cgroup_v2_memory cgroup_tightest_hard_memory_limit, the kernel's min-over-ancestors rule). memory.high alone is a located refusal. The fence goes in the step's receipt. gunbc.memory_cgroup_binding was tried first and dropped: it is a no-op under an existing hard limit. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… spark_v41_index_selection step) Produced by generated_artifact_gate main_wet_one --arg path=.github/workflows/fleet-converge.yml at 779d51c, locally under ulimit -v 24G (peak RSS 15.4 GiB, 494 s). Heal does not repair workflow files and the BuildBuddy runner OOM-killed the same regeneration. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Closes the V4.1 Engram membership against the full index. The
.engram.selection is now read from the pinnedmodel.safetensors.index.jsonbyextdeps.languages.jsonparse_json_document, with no scaffold.What changed in this revision (operator ruling, option A). Earlier heads read the index with a token scan, a stated divergence kept because the parser could not read a 7.4 MB index in the interpreter. After #12066 the ruling was to drop the scaffold rather than admit it.
v41_index_parse_json_probe_wet) are deleted.gunbc.spark.v41_index_engram_selectionv41_select_index_documentis a fold over the parsedweight_map. It refuses a non-JSON document, a missing or duplicatedweight_map, a map that is not an object, any value that is not a.safetensorsshard name, and an empty map. Escaped keys are decoded, where the scan refused any backslash. The result type is renamed fromV41IndexScantoV41IndexParseso the old name does not change meaning.gunbc.spark.v41_checkpoint_materializev41_index_selection_ci_wetruns as a second step ofspark_v41_checkpoint_materializeunderalways(). A parse stopped for memory therefore cannot take the fetch's per-file receipts with it. It verifies the index against its manifest row itself (v41_observe) before reading it.v41_group_a_ci_run(target, Group A admission, reach, credential, trust, ssh key), instead of two copies of that setup.v41_memory_fencereads/proc/self/cgroupfor the process that will parse, plusmemory.maxandmemory.highat every bounding level. It takes the tightest hard limit usingextdeps.linux.cgroup_v2_memorycgroup_tightest_hard_memory_limit, the kernel's minimum-over-ancestors rule.memory.highalone is a located refusal, because it is a throttle an allocation may cross, not a fence. The fence (directory, bytes, and every level read) goes in the step's receipt, so the first run that parses also proves what bounded it.Why not
gunbc.memory_cgroup_binding. It was tried and dropped.cgroup_bind_decisionreturnsUnnecessaryLimitAlreadyBindsunder any existing hardmemory.max, and elsewhere it creates its leaf at the cgroup root, which a non-root runner cannot do. On the executor it would have been a no-op or a refusal.Follow-up, not in this PR (B). Extend
gunbc.memory_cgroup_bindingto nest a tighter child cgroup under an existing hard limit. That would give a read a bound of its own inside the runner slot, rather than relying on the slot's grant.Evidence so far. On a remote runner, the parse-fold witnesses over
v41_index_engram_selection(selection, escaped key, not-a-shard and empty-map refusals) evaluatedtrue. Closures that include the materialize module were OOM-killed on that 7 GB runner, so CI's floor is the check for those. The live proof is the next srv5 run after this lands (srv5 holds the verified index).🤖 Generated with Claude Code