Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion dag/gunbc/ci_layer_roots.dag
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ data witness_exclusion_frontier: List<WitnessExclusionRow> = [
WitnessExclusionRow {
pattern: "stage0_rust_host_observation_live_witness_test.dag",
classification: OfflineLocalRecipe,
reason: "SUBSTANTIATED per-row: every fn in this file evaluates gunbc.stage0_rust_host_observation rust_source_host_observation, whose realization reaches git.Inspect.HeadCommit and git.Inspect.MergeBase. Neither carries a mock_response, so the hermetic envelope does not skip these -- it REFUSES, declining to fabricate rather than inventing a revision. Because a refusing discovery member fails its whole batch, leaving them enrolled took down the entire per-PR witness corpus (CI receipt on PR 7562: batch 3 discovery-corpus, 2 roots + 105 explicit). Publishing the mocks was tried and reverted: it only moves the refusal to the next unmocked operation, and mocking the whole revision-addressed chain would let scaffold_host_observation_is_live_and_observed pass against a constant sha -- reflection evidence standing in for the live read the witness exists to prove. Falsifier wet enrollment is not available either: falsifier_self_host_wet_cadence_active is false, so a row there would satisfy a coverage argument while executing nowhere. The honest state is excluded, reason stated, gap counted -- the same class and the same trigger as the wet_integration_offline_note rows.",
reason: "SUBSTANTIATED per-row: every fn in this file calls gunbc.stage0_rust_host_observation current_stage0_rust_source_observation, whose realization reaches git.Inspect.HeadCommit and git.Inspect.MergeBase. Neither carries a mock_response, so the hermetic envelope does not skip these -- it REFUSES, declining to fabricate rather than inventing a revision. Because a refusing discovery member fails its whole batch, leaving them enrolled took down the entire per-PR witness corpus (CI receipt on PR 7562: batch 3 discovery-corpus, 2 roots + 105 explicit). Publishing the mocks was tried and reverted: it only moves the refusal to the next unmocked operation, and mocking the whole revision-addressed chain would let scaffold_host_observation_is_live_and_observed pass against a constant sha -- reflection evidence standing in for the live read the witness exists to prove. Falsifier wet enrollment is not available either: falsifier_self_host_wet_cadence_active is false, so a row there would satisfy a coverage argument while executing nowhere. The honest state is excluded, reason stated, gap counted -- the same class and the same trigger as the wet_integration_offline_note rows.",
dissolve_on: "mock_response coverage lands for the git.Inspect revision-addressed operations AND the assertions are re-checked so that they still discriminate under a fixed mock (a liveness claim that a constant satisfies must be restated or dropped); or the wet lane un-darkens and these fns enroll there as declared execution rows. Either way this row deletes."
},
WitnessExclusionRow {
Expand Down
9 changes: 1 addition & 8 deletions dag/gunbc/roadmap_authority.dag
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import gunbc.roadmap_document {
}
import std.types { ContentHash }
import std.decl_ref { DeclarationRef, WholeDeclaration }
import gunbc.seed_growth { SeedGrowthJustification }
import gunbc.roadmap_model {
RoadmapNode,
RoadmapNodeIdentity,
Expand Down Expand Up @@ -377,14 +378,6 @@ fn edge(child: String, parent: String) -> RoadmapEdge {
RoadmapEdge { child: nid(s: child), parent: nid(s: parent) }
}

type SeedGrowthJustification {
hand_authored_declarations: List<DeclarationRef>
reason: String
owning_dissolution_lane: RoadmapNodeId
trigger: String
current_boundary: String
}

fn observation_scoped_run_seed_growth_justification() -> SeedGrowthJustification {
SeedGrowthJustification {
hand_authored_declarations: [
Expand Down
16 changes: 16 additions & 0 deletions dag/gunbc/seed_growth.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module gunbc.seed_growth

import std.decl_ref { DeclarationRef }
import gunbc.roadmap_model { RoadmapNodeId }
import std.types { String }
import v2.std.collection { List }

data seed_growth_note: String = "Temporary hand-authored Rust debt, stated as an obligation roster rather than a size. A SeedGrowthJustification says which declarations a change adds to the seed, why the substrate cannot yet carry them, which roadmap lane owns their dissolution, what triggers it, and what the current boundary is.\n\nWHY THIS IS ITS OWN AUTHORITY AND NOT PART OF THE ROADMAP. The carrier states a fact about a few Rust declarations; it does not need the roadmap graph, its node table, its edges, or its acceptance receipts. Homing the type in gunbc.roadmap_authority forced every low-level module that wanted to declare seed debt to import the entire roadmap to do it -- gunbc.stage0_rust_host_observation, a host-observation carrier, depended on the roadmap authority for this one type alone. That is the dependency pointing the wrong way: the roadmap consumes seed-debt facts, so the roadmap imports this module, not the reverse. RoadmapNodeId stays as the owning-lane reference because naming the lane IS the point of the row, and it comes from gunbc.roadmap_model, which is the identity vocabulary rather than the graph.\n\nWHAT THE ROSTER DOES NOT GUARANTEE, STATED SO IT IS NOT MISREAD AS CLOSED. hand_authored_declarations is an AUTHORED OBLIGATION ROSTER, not a derived denominator. It is strictly better than a line-count literal -- each row names a declaration that either resolves or does not -- but nothing structurally prevents a later helper added to the same Rust file from escaping it, because the roster is written by hand rather than derived from the source population. Closing that gap needs a census that compares every newly authored Rust declaration in a change against these rows and refuses on the difference; until such a join exists the honest rung is mechanically preventive for the declarations listed, and silent for the ones nobody listed. That completeness join belongs to the honest-frontier lane, not here."

type SeedGrowthJustification {
hand_authored_declarations: List<DeclarationRef>
reason: String
owning_dissolution_lane: RoadmapNodeId
trigger: String
current_boundary: String
}
2 changes: 1 addition & 1 deletion dag/gunbc/stage0_cargo_manifest.dag
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ data stage0_package_root: String = "src/v1/stage0/"

data stage0_cargo_bin_paths_observation_ref: DeclarationRef = DeclarationRef {
module_path: "gunbc.stage0_rust_host_observation",
decl_name: "rust_source_host_observation",
decl_name: "current_stage0_rust_source_observation",
field: WholeDeclaration
}
24 changes: 14 additions & 10 deletions dag/gunbc/stage0_rust_host_observation.dag
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module gunbc.stage0_rust_host_observation
import extdeps.git
import gunbc.output_policy { ExpectSuccess }
import gunbc.repo_identity { gunbc_merge_target_ref }
import gunbc.roadmap_authority { SeedGrowthJustification }
import gunbc.seed_growth { SeedGrowthJustification }
import gunbc.roadmap_model { RoadmapNodeId }
import gunbc.stage0_cargo_manifest {
CargoManifestBinParse,
Expand All @@ -15,16 +15,16 @@ import gunbc.stage0_cargo_manifest {
import std.content_hash { content_hash_atom }
import std.decl_ref { DeclarationRef, WholeDeclaration }
import std.disposition { Disposition, RealizationDispatch, Scaffold }
import std.types { GitRef, String }
import std.types { CommitSha, ContentHash, GitRef, String }
import v2.std.algebra { fold_list, list_snoc_item }
import v2.std.collection { List }

data stage0_rust_host_observation_note: String = "Rust-source OBSERVATION prerequisite only; lifecycle totality remains downstream in gunbc.stage0_rust_source_lifecycle_scaffold / v1-honest-frontier. extdeps.git owns the Git operation shapes. This module supplies repository policy (HEAD versus gunbc_merge_target_ref), filters the exact revision-addressed path population, normalizes authored Cargo target paths, hashes the exact manifest text through std.content_hash, and joins those facts. The temporary Rust seed owns only TOML decoding into CargoManifestBinParse plus its interpreter projection. CargoBin is a source role and cannot satisfy a maintenance disposition."

type RustSourceHostObservation
= RustManifestObserved {
repository_revision: String,
manifest_digest: String,
repository_revision: CommitSha,
manifest_content_identity: ContentHash,
tracked_rust_repo_paths: List<String>,
prior_tracked_rust_repo_paths: List<String>,
cargo_bin_repo_paths: List<String>
Expand Down Expand Up @@ -192,7 +192,7 @@ fn observe_stage0_rust_sources(
CargoBinRepoPathsProjected { paths: cargo_bin_repo_paths } =>
RustManifestObserved {
repository_revision: revision,
manifest_digest: content_hash_atom(value: manifest.content) as String,
manifest_content_identity: content_hash_atom(value: manifest.content),
tracked_rust_repo_paths: rust_paths_from_nul(raw: current_tree.paths_nul),
prior_tracked_rust_repo_paths: rust_paths_from_nul(raw: prior_tree.paths_nul),
cargo_bin_repo_paths: cargo_bin_repo_paths
Expand All @@ -206,11 +206,15 @@ fn observe_stage0_rust_sources(
}
}

data rust_source_host_observation: RustSourceHostObservation = observe_stage0_rust_sources(
manifest_repo_path: stage0_cargo_toml_repo_path,
package_root: stage0_package_root,
base_ref: gunbc_merge_target_ref as String
)
data host_observation_invocation_note: String = "THIS IS A FUNCTION AND NOT A TOP-LEVEL data BY CONSTRUCTION, WHICH IS THE WALL AND NOT A STYLE PREFERENCE. It was `data rust_source_host_observation = observe_stage0_rust_sources(...)`, and a top-level data declaration is EVALUATED WHEN A MODULE IMPORTS IT. So every module that named the symbol in an import list performed Git I/O as a consequence of loading, whether or not it used the value.\n\nThat is not hypothetical: it happened. A witness file kept the symbol in its import list after the three functions using it had moved to another file, and the dead import alone reached git.Inspect.HeadCommit under the hermetic envelope, refused, and failed the entire per-PR discovery batch of 105 rows -- on a file whose test bodies no longer touched the observation at all. Deleting the import fixed that incident. It did not fix the class, because the next module to import the symbol would have done the same thing, and nothing would have stopped it.\n\nAs a function the effect is reachable only by CALLING it. A module may import the RustSourceHostObservation coproduct, the path normalizers, and the verdict fold without observing the host, because none of those are this function. The wet entry calls it deliberately; the hermetic lane cannot reach the effect by importing anything. This is the DESIGN section 5 construction-over-validation move: documenting that imports evaluate live data does not stop the next import from doing so, and the determinism thread is the standing reminder that silence is not a wall.\n\nThe injection boundary is kept rather than replaced: rust_source_manifest_state_verdict(observation) still takes the observation as a parameter, so every consumer of the verdict remains pure and testable against constructed observations."

fn current_stage0_rust_source_observation() -> RustSourceHostObservation {
observe_stage0_rust_sources(
manifest_repo_path: stage0_cargo_toml_repo_path,
package_root: stage0_package_root,
base_ref: gunbc_merge_target_ref as String
)
}

data stage0_cargo_manifest_parser_seed_scaffold: Disposition = Scaffold {
dissolves_to: RealizationDispatch,
Expand Down
19 changes: 10 additions & 9 deletions dag/gunbc/stage0_rust_source_lifecycle_scaffold.dag
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ import gunbc.stage0_rust_host_observation {
RustManifestParseRefused,
RustManifestReadRefused,
RustSourceHostObservation,
rust_source_host_observation
current_stage0_rust_source_observation
}
import gunbc.stage0_emit_model {
generated_stage0_files,
is_generated_stage0_file
}
import std.types { ContentHash }
import std.decl_ref { DeclarationRef, WholeDeclaration }
import std.disposition { Disposition, Scaffold, SingleAuthority }
import gunbc.roadmap_model { RoadmapNodeId }
Expand Down Expand Up @@ -222,13 +223,13 @@ fn rust_source_manifest_state_verdict(observation: RustSourceHostObservation) ->
ManifestStateScaffoldRefused { cause: HostGitObservationRefused { detail: detail } }
RustManifestObserved {
repository_revision: repository_revision,
manifest_digest: manifest_digest,
manifest_content_identity: manifest_content_identity,
tracked_rust_repo_paths: tracked_paths,
prior_tracked_rust_repo_paths: prior_tracked_paths,
cargo_bin_repo_paths: cargo_bin_repo_paths
} =>
if repository_revision == "" || manifest_digest == "" {
ManifestStateScaffoldRefused { cause: HostManifestReadRefused { detail: "observed manifest missing repository_revision or manifest_digest" } }
if repository_revision == "" {
ManifestStateScaffoldRefused { cause: HostManifestReadRefused { detail: "observed manifest missing repository_revision" } }
} else {
let file_grain_paths = file_grain_lifecycle_repo_paths()
let classified_paths = observed_classified_repo_paths(file_grain_paths: file_grain_paths)
Expand Down Expand Up @@ -484,7 +485,7 @@ fn witness_observation_covering_lifecycle_plus_extra(extra_path: String) -> Rust
)
RustManifestObserved {
repository_revision: "witness-deadbeef",
manifest_digest: "witness-abc123",
manifest_content_identity: "witness-abc123" as ContentHash,
tracked_rust_repo_paths: list_concat_unique(acc: classified, items: [extra_path]),
prior_tracked_rust_repo_paths: classified,
cargo_bin_repo_paths: ["src/v1/stage0/src/main.rs"]
Expand All @@ -503,7 +504,7 @@ fn witness_hand_maintained_growth_observation() -> RustManifestObserved {
)
RustManifestObserved {
repository_revision: "witness-deadbeef",
manifest_digest: "witness-abc123",
manifest_content_identity: "witness-abc123" as ContentHash,
tracked_rust_repo_paths: classified,
prior_tracked_rust_repo_paths: prior_classified,
cargo_bin_repo_paths: ["src/v1/stage0/src/main.rs"]
Expand All @@ -517,7 +518,7 @@ fn witness_honest_minimal_observation_ok() -> RustManifestObserved {
)
RustManifestObserved {
repository_revision: "witness-deadbeef",
manifest_digest: "witness-abc123",
manifest_content_identity: "witness-abc123" as ContentHash,
tracked_rust_repo_paths: classified,
prior_tracked_rust_repo_paths: classified,
cargo_bin_repo_paths: ["src/v1/stage0/src/main.rs"]
Expand Down Expand Up @@ -547,7 +548,7 @@ fn witness_duplicate_tracked_observation() -> RustManifestObserved {
let tracked_with_dup = list_snoc_item(xs: classified, item: dup_path)
RustManifestObserved {
repository_revision: "witness-deadbeef",
manifest_digest: "witness-abc123",
manifest_content_identity: "witness-abc123" as ContentHash,
tracked_rust_repo_paths: tracked_with_dup,
prior_tracked_rust_repo_paths: classified,
cargo_bin_repo_paths: ["src/v1/stage0/src/main.rs"]
Expand Down Expand Up @@ -669,7 +670,7 @@ fn file_grain_paths_avoid_discovery_prefix_holds() -> Bool {
}

fn manifest_state_verdict_scaffold_holds() -> Bool {
match rust_source_manifest_state_verdict(observation: rust_source_host_observation) {
match rust_source_manifest_state_verdict(observation: current_stage0_rust_source_observation()) {
ManifestStateScaffoldOk => true
ManifestStateScaffoldRefused { cause: _ } => false
}
Expand Down
Loading
Loading