Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f8fdd99
The floor's memory beat carries the seam it was sampled in, so the pe…
Sep 21, 2026
2ab6270
Merge remote-tracking branch 'origin/main' into session/loyal-ibex-544
Sep 21, 2026
5a8bd4d
The stall moves onto the beat line too, so nothing on it is joined by…
Sep 21, 2026
533d444
One reader of the seam slot, two renderings, because the consumers ow…
Sep 21, 2026
c543ac3
The torn-beat fixture carries a seam too, which the floor caught and …
Sep 21, 2026
19b8988
The peak-attribution refusal carries a typed cause, so the four ways …
Sep 21, 2026
537308e
The dated successor receipt, and the first floor reading that names i…
Sep 21, 2026
39e3159
Repair the receipt note: a placeholder substitution also replaced the…
Sep 21, 2026
aa20e00
Merge remote-tracking branch 'origin/main' into session/loyal-ibex-544
Sep 21, 2026
4c5ab13
The witness's annotation moves above its declaration, where an annota…
Sep 21, 2026
cd03d61
The reading standing names the tear, and the receipt can receive ever…
Sep 21, 2026
d16da0c
Every cause arm gets a claim that drives it, found by auditing rather…
Sep 21, 2026
8fae2bf
run_completed means the workload ran to its end, not that the floor r…
Sep 21, 2026
f78802d
Migrate the four stall readers the re-type left behind, one of them o…
Sep 21, 2026
9c8afa7
Name the producer where a beat figure was transcribed, and state the …
Sep 22, 2026
41badeb
The two attribution folds are a declared frontier, named as one, with…
Sep 22, 2026
1951ab3
Name the per-beat facts the typed receipt does not carry, with consum…
Sep 22, 2026
94ce10a
Name the producers in the receipt note instead of copying their figures
Sep 22, 2026
162e9d8
Merge remote-tracking branch 'origin/main' into session/loyal-ibex-544
Sep 22, 2026
e838871
Merge remote-tracking branch 'origin/main' into session/loyal-ibex-544
Sep 22, 2026
6d79919
Bind the seam to the sample in time, and stop the successful arm asse…
Sep 22, 2026
b25a3a6
Drop the seam reader's hand-written LOC delta, which rotted inside it…
Sep 22, 2026
0593d5b
The floor reads the corpus once and lends it, instead of reading it t…
Sep 22, 2026
d52ede9
The rename's own explanation named the new arm where it meant the old…
Sep 22, 2026
7d0061b
Merge main into session/loyal-ibex-544-d3
Sep 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions dag/gunbc/floor/floor_demand.dag
Original file line number Diff line number Diff line change
Expand Up @@ -909,14 +909,14 @@ type PeakLowerBoundCause
| SwapPolicyIsRead { swap_max: ByteSize }

// THE SUCCESSFUL ARM IS NAMED FOR WHAT IT ESTABLISHES, WHICH IS NOT EXACT DEMAND. It used to be
// called PeakIsUncensoredSampledMaximum, and that name asserted past its evidence in the way DESIGN 4d forbids: the
// called PeakIsDemand, and that name asserted past its evidence in the way DESIGN 4d forbids: the
// arm is reached when the workload completed, the SAMPLED peak showed no stall, and swap could
// not spill. Those remove two CENSORING mechanisms -- they do not make a sampled maximum the true
// maximum. memory.stat carries no high-water counter, so this receipt's peak is the largest value
// a PERIODIC sample caught, and a spike that rose and fell between two beats is invisible to it.
// This module's own beat-cadence note has said exactly that from the start; the fold promoted
// past it anyway, and the ARM NAME was the assertion, because a later reader consumes an arm
// called PeakIsUncensoredSampledMaximum as a fact rather than as the bet it is.
// called PeakIsDemand as a fact rather than as the bet it is.
//
// SO EVERY ARM OF THIS TYPE IS A LOWER BOUND, and they differ only in WHY. The uncensored arm is
// the strongest reading available from this instrument and it is still a floor on demand. An
Expand Down
63 changes: 57 additions & 6 deletions src/v1/stage0/src/cli_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40800,11 +40800,50 @@ pub fn assemble_prepared_subject_closure(
exclude_substrings: &[String],
closure: Option<(&MultiEntryIndex, &[String], &[String])>,
) -> Result<PreparedSubject, String> {
let full_index = build_module_index(source_roots);
let full_inventory = floor_source_inventory(&full_index);
let corpus = read_source_corpus_once(source_roots);
assemble_prepared_subject_from_corpus(&corpus, exclude_substrings, closure)
}

/// THE CORPUS READ, AS A VALUE A CALLER CAN OWN AND LEND TO MORE THAN ONE DEMAND.
///
/// `build_module_index` walks every source root and `read_to_string`s every `.dag` file; it is
/// not memoised and nothing above it carried the result, so a caller that prepared two subjects
/// read and indexed the WHOLE CORPUS TWICE. The floor is exactly that caller -- `run_required_floor`
/// prepares the policy closure and then the gate closure, and both call sites pass IDENTICAL source
/// roots, identical exclusions and the same entry index, differing only in their closure seeds.
///
/// So this is DESIGN §2's authored duplication, and the repair is the one §2 names: several demands
/// with a shared-state least common ancestor CARRY the first value rather than caching the second.
/// The ancestor reads once and lends; there is no key, no invalidation rule and no provider, because
/// none of those is what was missing -- the value simply was not carried.
pub struct SourceCorpusRead {
index: ModuleSourceIndex,
inventory: Vec<PreparedSourceView>,
}

pub fn read_source_corpus_once(source_roots: &[String]) -> SourceCorpusRead {
let index = build_module_index(source_roots);
let inventory = floor_source_inventory(&index);
SourceCorpusRead { index, inventory }
}

/// The subject fold over a corpus the CALLER read. Identical to the wrapper above in every respect
/// except that it does not do the reading, so two subjects prepared from one read see one corpus.
pub fn assemble_prepared_subject_from_corpus(
corpus: &SourceCorpusRead,
exclude_substrings: &[String],
closure: Option<(&MultiEntryIndex, &[String], &[String])>,
) -> Result<PreparedSubject, String> {
let full_index = &corpus.index;
let full_inventory = corpus.inventory.clone();
let mut discovery_exclusions: HashMap<String, String> = HashMap::new();
let index: ModuleSourceIndex = match closure {
None => full_index,
// THE ONLY TWO PLACES THE INDEX WAS MOVED rather than read. Both now clone, and what they
// clone is `Rc<SourceFile>` pointers plus their keys -- not file contents, and for the
// closure arm only the KEPT subset, which on the floor is a small fraction of the corpus.
// That is the cost of carrying one read instead of doing a second one, and it is the trade
// the duplication was paying in full on every floor run.
None => full_index.clone(),
Some((entry_index, prefixes, module_seeds)) => {
let started = std::time::Instant::now();
// THE CLOSURE IS THE LOADER'S BOTH-CLOSURE, NOT THE IMPORT HEADERS. A module in
Expand Down Expand Up @@ -40946,8 +40985,9 @@ pub fn assemble_prepared_subject_closure(
full_index.len()
);
full_index
.into_iter()
.filter(|(m, _)| keep.contains(m))
.iter()
.filter(|(m, _)| keep.contains(*m))
.map(|(m, sf)| (m.clone(), sf.clone()))
.collect()
}
};
Expand Down Expand Up @@ -41090,7 +41130,18 @@ pub fn prepare_repository_closure(
exclude_substrings: &[String],
closure: Option<(&MultiEntryIndex, &[String], &[String])>,
) -> Result<(PreparedRepository, Vec<PreparedSourceView>), String> {
let subject = assemble_prepared_subject_closure(source_roots, exclude_substrings, closure)?;
let corpus = read_source_corpus_once(source_roots);
prepare_repository_from_corpus(&corpus, exclude_substrings, closure)
}

/// The repository fold over a corpus the CALLER read; see `read_source_corpus_once` for why the
/// read is a value rather than something each prepare does for itself.
pub fn prepare_repository_from_corpus(
corpus: &SourceCorpusRead,
exclude_substrings: &[String],
closure: Option<(&MultiEntryIndex, &[String], &[String])>,
) -> Result<(PreparedRepository, Vec<PreparedSourceView>), String> {
let subject = assemble_prepared_subject_from_corpus(corpus, exclude_substrings, closure)?;
// THE SUBJECT IS STATED BY THE REFUSAL ITSELF, not only by the success path.
//
// The digest and the two counts are computed above, BEFORE the gate that can reject.
Expand Down
36 changes: 31 additions & 5 deletions src/v1/stage0/src/cli_run/required_floor_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3969,10 +3969,21 @@ pub struct RequiredFloorNominalSubjectSeeds {
pub fn required_floor_nominal_subject_seeds(
source_roots: &[String],
gate_entry_index: &MultiEntryIndex,
) -> Result<RequiredFloorNominalSubjectSeeds, String> {
let corpus = crate::cli_run::read_source_corpus_once(source_roots);
required_floor_nominal_subject_seeds_from_corpus(&corpus, gate_entry_index)
}

/// The seed fold over a corpus the CALLER read. `run_required_floor` is the least common ancestor
/// of this prepare and the gate prepare below it, so it reads once and lends to both; the wrapper
/// above stays for callers with only one demand (the lane resolution census).
pub fn required_floor_nominal_subject_seeds_from_corpus(
corpus: &crate::cli_run::SourceCorpusRead,
gate_entry_index: &MultiEntryIndex,
) -> Result<RequiredFloorNominalSubjectSeeds, String> {
let policy_seed = [REQUIRED_FLOOR_POLICY_MODULE.to_string()];
let (policy_prepared, _) = prepare_repository_closure(
source_roots,
let (policy_prepared, _) = crate::cli_run::prepare_repository_from_corpus(
corpus,
&floor_prepared_subject_exclusions(),
Some((gate_entry_index, &[], &policy_seed)),
)?;
Expand Down Expand Up @@ -5732,6 +5743,21 @@ pub fn run_required_floor(
// 4,260-module corpus, measured 2026-08-29), so it is built once here and lent to the
// policy-closure prepare and the gate-closure prepare alike.
let gate_entry_index = build_multi_entry_index(source_roots);
// ONE CORPUS READ FOR BOTH PREPARES, CARRIED FROM THE ANCESTOR THAT OWNS BOTH DEMANDS.
//
// This function prepares TWO subjects -- the policy closure through
// `required_floor_nominal_subject_seeds_from_corpus`, then the gate closure below -- and both
// call sites pass identical source roots, identical exclusions and this same
// `gate_entry_index`, differing ONLY in their closure seeds. Each prepare used to begin with
// its own `build_module_index(source_roots)`, which is not memoised: it walked every root and
// `read_to_string`d every `.dag` file in the corpus. So the floor read and indexed the whole
// corpus twice, on every run, for two questions that differ in their seeds and in nothing else.
//
// That is DESIGN §2's authored duplication rather than a cache obligation, and §2 names the
// repair: when several demands share a least common ancestor, CARRY the first value. This is
// that ancestor. The entry index one line above was already shared for exactly this reason --
// the corpus read simply never was.
let floor_corpus = crate::cli_run::read_source_corpus_once(source_roots);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Drop the shared corpus after the second prepare

In every required-floor run, floor_corpus owns the complete ModuleSourceIndex and full inventory, and lending it to both prepares does not consume either collection. Because it is never explicitly dropped, it remains alive through claim execution, so the later take and consumption of prepared.full_inventory no longer release the outside-closure source contents as intended. This retains the whole corpus in the memory-constrained floor after preparation; drop floor_corpus immediately after prepare_repository_from_corpus finishes, alongside gate_entry_index.

Useful? React with 👍 / 👎.

// ONE DERIVATION, CONSUMED FOUR WAYS. The same diff observation supplies changed-witness
// identities, newly enrolled identities, the compile-subject modules of
// `touched_entry_files`, and the match-bearing consumers of every coproduct whose arm set
Expand Down Expand Up @@ -5787,7 +5813,7 @@ pub fn run_required_floor(
required_gate_prefixes,
required_gate_authored_modules,
local_repo_wet_schedule_rows,
} = required_floor_nominal_subject_seeds(source_roots, &gate_entry_index)?;
} = required_floor_nominal_subject_seeds_from_corpus(&floor_corpus, &gate_entry_index)?;
// THE FLOOR'S OWN AUTHORITIES ARE ALWAYS IN THE SUBJECT: the floor evaluates its rosters
// (expected red, route gap, cost debt, the gate itself) in a frame over the prepared graph,
// and a gate roster that happened not to reach `v2.workflow.required_floor` refused with
Expand Down Expand Up @@ -5937,8 +5963,8 @@ pub fn run_required_floor(
)
.chain(arm_set_consumer_seeds.iter().cloned())
.collect();
let (mut prepared, prepared_sources) = prepare_repository_closure(
source_roots,
let (mut prepared, prepared_sources) = crate::cli_run::prepare_repository_from_corpus(
&floor_corpus,
&floor_prepared_subject_exclusions(),
Some((
&gate_entry_index,
Expand Down
Loading