From f9db76b65a8bf5291396bdbb89b91d7745b16e3b Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Sun, 27 Sep 2026 15:45:02 +0000 Subject: [PATCH 01/75] fleet-converge: gate the reset-return dispatch admission on its own mode The build job's admission step carried if_condition: none, so every mode's dispatch paid a full gunbc run to reach ResetDispatchNotThisMode. It now carries fleet_converge_host_reset_return_step_if, derived from the one mode roster. The route witness asserts the gate. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/fleet-converge.yml | 1 + dag/gunbc/fleet/fleet_converge_workflow.dag | 8 +++++++- dag/test/claim/workflow_dispatch_input_witness_test.dag | 6 ++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/fleet-converge.yml b/.github/workflows/fleet-converge.yml index 61720a4bda7..37acae26a27 100644 --- a/.github/workflows/fleet-converge.yml +++ b/.github/workflows/fleet-converge.yml @@ -156,6 +156,7 @@ jobs: env: GUNBC_HOST_RESET_DISPATCH_MODE: ${{ github.event.inputs.mode }} GUNBC_HOST_RESET_OBSERVER: ${{ github.event.inputs.reset_observer }} + if: github.event.inputs.mode == 'host_reset_return' timeout-minutes: 5 - name: Pack release bins for cross-job handoff (tar keeps exec bits) run: | diff --git a/dag/gunbc/fleet/fleet_converge_workflow.dag b/dag/gunbc/fleet/fleet_converge_workflow.dag index ca2e5cf7975..538509e18bc 100644 --- a/dag/gunbc/fleet/fleet_converge_workflow.dag +++ b/dag/gunbc/fleet/fleet_converge_workflow.dag @@ -866,6 +866,12 @@ fn fleet_converge_build_job_capability_closure_holds() -> Bool { // therefore wastes one build. The safety property is unchanged -- the reset job needs `build` either // way, so it is never scheduled in the state this refuses. // +// GATED ON ITS OWN MODE, DERIVED FROM THE ONE ROSTER. The step once carried no if:, so every +// dispatch of every mode paid a full `gunbc run` (minutes) to be told ResetDispatchNotThisMode. The +// gate is fleet_converge_host_reset_return_step_if -- the same roster-derived condition the reset +// job's own steps carry -- so a skip here is exactly the NotThisMode arm, decided by the runner +// instead of by a process. +// // WHY NOT A DEFAULT ON THE INPUT, which was the review's other arm. Defaulting the observer would // make an omitted field silently select a machine and POWER-CYCLE ITS PAIRED SUBJECT. A default is // the right shape for a preference and the wrong one for an effect nobody asked for. Refusing costs @@ -883,7 +889,7 @@ fn fleet_converge_reset_observer_dispatch_admission_step() -> Step { ] }, working_directory: none, - if_condition: none, + if_condition: Present { value: fleet_converge_host_reset_return_step_if }, continue_on_error: none, timeout_minutes: Present { value: gunbc_ci_aux_step_timeout_minutes } } diff --git a/dag/test/claim/workflow_dispatch_input_witness_test.dag b/dag/test/claim/workflow_dispatch_input_witness_test.dag index 7a5dfcdc758..bf049bd9b11 100644 --- a/dag/test/claim/workflow_dispatch_input_witness_test.dag +++ b/dag/test/claim/workflow_dispatch_input_witness_test.dag @@ -456,15 +456,17 @@ test fn a_whitespace_only_observer_is_refused_as_unnamed() -> Bool { // match alone would stay green over a step whose env no longer hands the dispatch inputs to the // admission, or whose run invokes a different entry: it holds that the step reaches the modeled fold // (host_reset_return_dispatch_admission_wet reads both env names) with both inputs wired. Control: -// dropping fleet_converge_reset_observer_dispatch_admission_step() from the own list turns this red. +// dropping fleet_converge_reset_observer_dispatch_admission_step() from the own list turns this red, +// and so does removing its own-mode gate (it once ran, for minutes, on every mode's dispatch). test fn the_build_job_carries_the_reset_observer_dispatch_admission() -> Bool { any( fleet_converge_build_job_own_steps(), st => match st { - RunStep { name: _, id: i, run: r, shell: _, env: e, working_directory: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => + RunStep { name: _, id: i, run: r, shell: _, env: e, working_directory: _, if_condition: c, continue_on_error: _, timeout_minutes: _ } => match i { Present { value: v } => v == "reset_observer_dispatch_admission" + && (match c { Present { value: g } => g == fleet_converge_mode_step_if(mode: HostResetReturn) Absent => false }) && string_contains(s: r, pattern: gunbc_ci_host_reset_dispatch_admission_target.entry) && string_contains(s: r, pattern: gunbc_ci_host_reset_dispatch_admission_target.function) && step_env_binds(env: e, key: host_reset_dispatch_mode_env as String, input: "${{ github.event.inputs.mode }}") From 6bb3a12354235efc3a5175eb4b58bcb278adeb67 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Sun, 27 Sep 2026 19:14:53 +0000 Subject: [PATCH 02/75] fleet-converge witness: the admission step's gate must equal the reset job's gate Drift between the admission step's mode condition and the consuming host-reset-return job's condition would skip the observer refusal in the one mode it applies to. Both derive from the roster; the witness now asserts they stay equal. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../workflow_dispatch_input_witness_test.dag | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/dag/test/claim/workflow_dispatch_input_witness_test.dag b/dag/test/claim/workflow_dispatch_input_witness_test.dag index bf049bd9b11..f7d1ac761ba 100644 --- a/dag/test/claim/workflow_dispatch_input_witness_test.dag +++ b/dag/test/claim/workflow_dispatch_input_witness_test.dag @@ -10,9 +10,9 @@ import v2.std.collection { Present, Absent } import gunbc.fleet_converge_workflow { fleet_converge_fabric_writer_identity_observe_receipt_if, fleet_converge_fabric_writer_identity_observe_step_if, FleetConvergeWorkflowMode, fleet_converge_workflow_modes, fleet_converge_workflow_mode_wire, - fleet_converge_mode_step_if, fleet_converge_mode_scope, + fleet_converge_mode_step_if, fleet_converge_mode_scope, fleet_converge_host_reset_return_job, ApprovalBrokerDarkInstall, fleet_converge_approval_broker_dark_install_step_if, - FullHostPlan, LaunchEnvironmentPlan, AllocationStorePlan, DashboardDeploy, + FullHostPlan, LaunchEnvironmentPlan, AllocationStorePlan, DashboardDeploy, HostResetReturn, RunnerPasswordSessionToolConverge, fleet_converge_spark_bootstrap_step_if, fleet_converge_mode_options, fleet_converge_build_job_own_steps, @@ -457,7 +457,9 @@ test fn a_whitespace_only_observer_is_refused_as_unnamed() -> Bool { // admission, or whose run invokes a different entry: it holds that the step reaches the modeled fold // (host_reset_return_dispatch_admission_wet reads both env names) with both inputs wired. Control: // dropping fleet_converge_reset_observer_dispatch_admission_step() from the own list turns this red, -// and so does removing its own-mode gate (it once ran, for minutes, on every mode's dispatch). +// and so does removing its own-mode gate (it once ran, for minutes, on every mode's dispatch), or +// letting that gate drift from the consuming host-reset-return job's gate: the admission must run +// in exactly the mode whose job it protects, or the observer refusal is skipped where it applies. test fn the_build_job_carries_the_reset_observer_dispatch_admission() -> Bool { any( fleet_converge_build_job_own_steps(), @@ -466,7 +468,15 @@ test fn the_build_job_carries_the_reset_observer_dispatch_admission() -> Bool { match i { Present { value: v } => v == "reset_observer_dispatch_admission" - && (match c { Present { value: g } => g == fleet_converge_mode_step_if(mode: HostResetReturn) Absent => false }) + && (match c { + Present { value: g } => + g == fleet_converge_mode_step_if(mode: HostResetReturn) + && (match fleet_converge_host_reset_return_job().if_condition { + Present { value: jg } => g == jg + Absent => false + }) + Absent => false + }) && string_contains(s: r, pattern: gunbc_ci_host_reset_dispatch_admission_target.entry) && string_contains(s: r, pattern: gunbc_ci_host_reset_dispatch_admission_target.function) && step_env_binds(env: e, key: host_reset_dispatch_mode_env as String, input: "${{ github.event.inputs.mode }}") From 911abc43409dfe574b0db11bc872cc35476e1437 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Mon, 28 Sep 2026 08:41:14 +0000 Subject: [PATCH 03/75] Modeled operation realization: file transport arm + gunbc.filesystem_model Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/extdeps/transports/file.dag | 14 +- dag/gunbc/filesystem_model.dag | 202 ++++++++++++++++++ .../claim/modeled_filesystem_witness_test.dag | 191 +++++++++++++++++ src/v1/stage0/src/v1_interpreter.rs | 87 +++++++- src/v2/std/operation_realization.dag | 2 + 5 files changed, 491 insertions(+), 5 deletions(-) create mode 100644 dag/gunbc/filesystem_model.dag create mode 100644 dag/test/claim/modeled_filesystem_witness_test.dag diff --git a/dag/extdeps/transports/file.dag b/dag/extdeps/transports/file.dag index 830f6d17267..ceeb0934b04 100644 --- a/dag/extdeps/transports/file.dag +++ b/dag/extdeps/transports/file.dag @@ -1,6 +1,7 @@ module extdeps.transports.file -import std.types { FermiDepth } +import std.types { FermiDepth, Int, String } +import extdeps.filesystem.filesystem_io { FilesystemFailureKind } import std.fidelity { TransportFidelity } import extdeps.external_authority { ExternalAuthority } import extdeps.uri { Uri, Https } @@ -17,3 +18,14 @@ data file_transport_fidelity: TransportFidelity = TransportFidelity { depth: S, type FileTransportConfig { base_path: String } + +// WHAT THE FILE TRANSPORT OBSERVES, as a value: an operation that succeeded with its byte count and +// any content it read or listed, or one that failed with the host's CLOSED failure kind and its +// message. This is the observation a modeled operation realization (v2.std.operation_realization) +// supplies in place of a real filesystem call; the interpreter feeds it to the same declared-output +// projection a real file result reaches, so success, error, error_kind, content and byte_count are +// derived exactly as from a real call. A listing's content follows the realization's own contract: +// the entry names, sorted, one per line. +type FileExchangeObservation + = FileOperationSucceeded { byte_count: Int, content: String } + | FileOperationFailed { kind: FilesystemFailureKind, error: String } diff --git a/dag/gunbc/filesystem_model.dag b/dag/gunbc/filesystem_model.dag new file mode 100644 index 00000000000..daca446e524 --- /dev/null +++ b/dag/gunbc/filesystem_model.dag @@ -0,0 +1,202 @@ +module gunbc.filesystem_model + +import std.types { Bool, List, String } +import std.measure { second } +import v2.std.operation_argv { OperationRef, BoundOperationInvocation } +import v2.std.operation_realization { + OperationBinding, OperationCall, OperationStep, OperationObserved, OperationHarnessFault, + FileObserved, operation_input_text, +} +import extdeps.transports.file { FileExchangeObservation, FileOperationSucceeded, FileOperationFailed } +import extdeps.filesystem.filesystem_io { + FilesystemNotFound, FilesystemAlreadyExists, FilesystemNotDirectory, FilesystemOtherFailure, +} + +// A MODELED FILESYSTEM: the subset of POSIX file behaviour the file transport realizes, as a pure +// value a modeled operation realization embeds in its scenario state. It is generic -- a hold store, +// a SOL pid file and a capture file are all just paths in it -- and it reproduces the realization's +// own contract (v1 interpreter dispatch_file), not an idealised filesystem: +// - a write needs its parent directory to exist, and answers not_found otherwise; +// - write_create_new answers already_exists when the path exists, and never overwrites; +// - a listing is the immediate children's names, sorted, one per line; listing a file answers +// not_a_directory and listing an absent path answers not_found; +// - reading or writing a directory as a file answers `other`, as an EISDIR does. +// WHAT IT DOES NOT MODEL, stated so a green over it is not over-read: file modes (the declared mode of +// write_create_new_with_mode is accepted and not stored), ownership, symlinks, partial writes, and +// the atomicity of a real create-exclusive under concurrent processes. Those are properties of the real +// filesystem, and their evidence is the file-store tests that run against a real directory. +// byte_count is the content's string length, which equals its byte length for the ASCII content the +// consumers here write. +type ModeledFile { + path: String + content: String +} + +type ModeledFilesystem { + directories: List + files: List +} + +fn fs_is_directory(fs: ModeledFilesystem, path: String) -> Bool { + any_string(xs: fs.directories, x: path) +} + +fn any_string(xs: List, x: String) -> Bool { + !all(xs, y => y != x) +} + +fn fs_file(fs: ModeledFilesystem, path: String) -> ModeledFile? { + fold(fs.files, init: none, f: fn(acc, file) { + match acc { + Present { value: v } => Present { value: v } + Absent => if file.path == path { Present { value: file } } else { none } + } + }) +} + +// The parent of an absolute path: everything before its last separator. "/a/b" -> "/a", "/a" -> "/". +fn fs_parent(path: String) -> String { + let segments = split(s: path, delimiter: "/") + let kept = segments.take(n: count(segments) - 1) + let joined = join(kept, "/") + if joined == "" { "/" } else { joined } +} + +fn fs_leaf(path: String) -> String { + match split(s: path, delimiter: "/").last() { + Present { value: leaf } => leaf + Absent => path + } +} + +fn failed_with(kind: extdeps.filesystem.filesystem_io.FilesystemFailureKind, message: String) -> FileExchangeObservation { + FileOperationFailed { kind: kind, error: message } +} + +fn fs_read(fs: ModeledFilesystem, path: String) -> FileExchangeObservation { + match fs_file(fs: fs, path: path) { + Present { value: file } => FileOperationSucceeded { byte_count: string_length(s: file.content), content: file.content } + Absent => + if fs_is_directory(fs: fs, path: path) { failed_with(kind: FilesystemOtherFailure, message: concat("Is a directory: ", path)) } + else { failed_with(kind: FilesystemNotFound, message: concat("No such file or directory: ", path)) } + } +} + +type ModeledFileWrite { + fs: ModeledFilesystem + observation: FileExchangeObservation +} + +fn fs_write(fs: ModeledFilesystem, path: String, content: String, create_new: Bool) -> ModeledFileWrite { + if !fs_is_directory(fs: fs, path: fs_parent(path: path)) { + ModeledFileWrite { fs: fs, observation: failed_with(kind: FilesystemNotFound, message: concat("No such file or directory: ", path)) } + } else if fs_is_directory(fs: fs, path: path) { + ModeledFileWrite { fs: fs, observation: failed_with(kind: FilesystemOtherFailure, message: concat("Is a directory: ", path)) } + } else { + match fs_file(fs: fs, path: path) { + Present { value: _ } => + if create_new { + ModeledFileWrite { fs: fs, observation: failed_with(kind: FilesystemAlreadyExists, message: concat("File exists: ", path)) } + } else { + ModeledFileWrite { fs: fs_with_file(fs: fs, path: path, content: content), observation: FileOperationSucceeded { byte_count: string_length(s: content), content: "" } } + } + Absent => + ModeledFileWrite { fs: fs_with_file(fs: fs, path: path, content: content), observation: FileOperationSucceeded { byte_count: string_length(s: content), content: "" } } + } + } +} + +fn fs_with_file(fs: ModeledFilesystem, path: String, content: String) -> ModeledFilesystem { + ModeledFilesystem { + directories: fs.directories, + files: list_append(filter(fs.files, f => f.path != path), ModeledFile { path: path, content: content }), + } +} + +fn fs_delete(fs: ModeledFilesystem, path: String) -> ModeledFileWrite { + match fs_file(fs: fs, path: path) { + Present { value: _ } => + ModeledFileWrite { fs: ModeledFilesystem { directories: fs.directories, files: filter(fs.files, f => f.path != path) }, observation: FileOperationSucceeded { byte_count: 0, content: "" } } + Absent => + if fs_is_directory(fs: fs, path: path) { ModeledFileWrite { fs: fs, observation: failed_with(kind: FilesystemOtherFailure, message: concat("Is a directory: ", path)) } } + else { ModeledFileWrite { fs: fs, observation: failed_with(kind: FilesystemNotFound, message: concat("No such file or directory: ", path)) } } + } +} + +fn fs_list(fs: ModeledFilesystem, path: String) -> FileExchangeObservation { + if fs_is_directory(fs: fs, path: path) { + let file_names = map(filter(fs.files, f => fs_parent(path: f.path) == path), f => fs_leaf(path: f.path)) + let dir_names = map(filter(fs.directories, d => d != path && fs_parent(path: d) == path), d => fs_leaf(path: d)) + let listing = join(sort_by(concat_lists(a: file_names, b: dir_names), n => n), "\n") + FileOperationSucceeded { byte_count: string_length(s: listing), content: listing } + } else { + match fs_file(fs: fs, path: path) { + Present { value: _ } => failed_with(kind: FilesystemNotDirectory, message: concat("Not a directory: ", path)) + Absent => failed_with(kind: FilesystemNotFound, message: concat("No such file or directory: ", path)) + } + } +} + +fn concat_lists(a: List, b: List) -> List { + fold(b, init: a, f: fn(acc, x) { list_append(acc, x) }) +} + +// THE BINDINGS, through a lens into the scenario state, so any scenario world can embed a filesystem +// without this module knowing its shape. Filesystem operations take no virtual time. +data filesystem_io_operation_path: String = "dag/extdeps/filesystem/filesystem_io.dag" + +fn filesystem_operation(operation: String) -> OperationRef { + OperationRef { path: filesystem_io_operation_path, service: "Filesystem", operation: operation } +} + +fn file_step(state: S, observation: FileExchangeObservation) -> OperationStep { + OperationObserved { observation: FileObserved { observation: observation }, state: state, elapsed: second(count: 0) } +} + +fn filesystem_bindings(get: fn(S) -> ModeledFilesystem, put: fn(S, ModeledFilesystem) -> S) -> List> { + let reading = fn(state, call) { + match operation_input_text(invocation: call.invocation, name: "path") { + Absent => OperationHarnessFault { reason: "a filesystem read was dispatched without a path" as NonEmptyStr } + Present { value: path } => file_step(state: state, observation: fs_read(fs: get(state), path: path)) + } + } + let listing = fn(state, call) { + match operation_input_text(invocation: call.invocation, name: "path") { + Absent => OperationHarnessFault { reason: "a filesystem list was dispatched without a path" as NonEmptyStr } + Present { value: path } => file_step(state: state, observation: fs_list(fs: get(state), path: path)) + } + } + let deleting = fn(state, call) { + match operation_input_text(invocation: call.invocation, name: "path") { + Absent => OperationHarnessFault { reason: "a filesystem delete was dispatched without a path" as NonEmptyStr } + Present { value: path } => { + let w = fs_delete(fs: get(state), path: path) + file_step(state: put(state, w.fs), observation: w.observation) + } + } + } + [ + OperationBinding { at: filesystem_operation(operation: "Read"), handler: reading }, + OperationBinding { at: filesystem_operation(operation: "List"), handler: listing }, + OperationBinding { at: filesystem_operation(operation: "Delete"), handler: deleting }, + OperationBinding { at: filesystem_operation(operation: "Write"), handler: writing(get: get, put: put, create_new: false) }, + OperationBinding { at: filesystem_operation(operation: "WriteOwnerOnly"), handler: writing(get: get, put: put, create_new: false) }, + OperationBinding { at: filesystem_operation(operation: "WriteCreateNew"), handler: writing(get: get, put: put, create_new: true) }, + OperationBinding { at: filesystem_operation(operation: "WriteCreateNewWithMode"), handler: writing(get: get, put: put, create_new: true) }, + ] +} + +fn writing(get: fn(S) -> ModeledFilesystem, put: fn(S, ModeledFilesystem) -> S, create_new: Bool) -> fn(S, OperationCall) -> OperationStep { + fn(state, call) { + match operation_input_text(invocation: call.invocation, name: "path") { + Absent => OperationHarnessFault { reason: "a filesystem write was dispatched without a path" as NonEmptyStr } + Present { value: path } => match operation_input_text(invocation: call.invocation, name: "content") { + Absent => OperationHarnessFault { reason: "a filesystem write was dispatched without content" as NonEmptyStr } + Present { value: content } => { + let w = fs_write(fs: get(state), path: path, content: content, create_new: create_new) + file_step(state: put(state, w.fs), observation: w.observation) + } + } + } + } +} diff --git a/dag/test/claim/modeled_filesystem_witness_test.dag b/dag/test/claim/modeled_filesystem_witness_test.dag new file mode 100644 index 00000000000..346e733645a --- /dev/null +++ b/dag/test/claim/modeled_filesystem_witness_test.dag @@ -0,0 +1,191 @@ +module test.claim.modeled_filesystem_witness_test + +import std.types { Bool, List, NonEmptyStr, String } +import std.materialization_ladder { Frame, SharedStateFrame } +import std.effect_grant { + Read, Write, ServiceOpTree, NamespacePosition, + ModeledRealization, LifecycleByConstruction, Grant, Envelope, +} +import v2.std.operation_realization { + OperationRealization, OperationBinding, OperationCall, OperationStep, DispatchRecord, + OperationObserved, ShellObserved, DispatchObserved, + virtual_clock_origin, +} +import v2.std.witness_evaluation { + WitnessEvaluationFrame, WitnessReturned, WitnessRefused, WitnessInterrupted, + evaluate_in_witness_frame, witness_diagnostic_rendered_reason, +} +import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } +import std.measure { second } +import extdeps.transports.shell { ShellProcessExited } +import extdeps.filesystem.filesystem_io { + Filesystem, FilesystemFailureKindAdmitted, FilesystemAlreadyExists, admit_filesystem_failure_kind, +} +import gunbc.durable_exclusive_hold_file_store { + file_hold_acquire, FileHoldAcquired, FileHoldOccupied, +} +import gunbc.machine_intake_mtcollins1_maintenance_hold { boot_run_owner } +import gunbc.filesystem_model { + ModeledFilesystem, ModeledFile, filesystem_bindings, filesystem_operation, +} + +data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly + +// THE FILE ARM OF THE MODELED OPERATION REALIZATION, exercised through the real dispatcher and the +// production durable-hold store. Every subject calls production code -- file_hold_acquire runs the +// real compare-and-set fold (gunbc.durable_cas_file_store), which lists, reads and create-exclusively +// writes its slot through extdeps.filesystem.filesystem_io -- and the model answers only the file +// operations. The hold root is an ordinary path inside the modeled filesystem, so nothing touches +// /var/lib on the host running the witness. +data realization_identity: NonEmptyStr = "modeled-filesystem-witness" as NonEmptyStr + +data hold_root: NonEmptyStr = "/var/lib/gunbc/unit-holds" as NonEmptyStr + +data hold_key: NonEmptyStr = "operator-host-mtcollins1" as NonEmptyStr + +fn filesystem_grant(verb: std.effect_grant.Verb) -> Grant { + Grant { + verb: verb + root: NamespacePosition { tree: ServiceOpTree { service: "Filesystem" }, path: [] } + binding: ModeledRealization { realization: realization_identity as String } + lifecycle: LifecycleByConstruction + } +} + +fn filesystem_frame(initial: ModeledFilesystem) -> WitnessEvaluationFrame { + WitnessEvaluationFrame { + envelope: Envelope { + frame: Frame { name: "modeled-filesystem-witness", kind: SharedStateFrame } + grants: [filesystem_grant(verb: Read), filesystem_grant(verb: Write)] + } + rest_fixtures: [] + realization: Present { value: OperationRealization { + identity: realization_identity, + initial: initial, + epoch: virtual_clock_origin(), + bindings: filesystem_bindings(get: fn(fs) { fs }, put: fn(fs, next) { next }), + advance: fn(fs, now) { fs }, + } } + } +} + +fn empty_hold_store() -> ModeledFilesystem { + ModeledFilesystem { directories: ["/", "/var", "/var/lib", "/var/lib/gunbc", hold_root as String], files: [] } +} + +fn route_operations(route: List) -> List { + map(route, r => r.invocation.at.operation) +} + +fn acquired(o: gunbc.durable_exclusive_hold_file_store.FileHoldAcquireOutcome) -> Bool { + match o { + FileHoldAcquired { slot_key: _, owner: _, generation: _ } => true + _ => false + } +} + +fn occupied_by(o: gunbc.durable_exclusive_hold_file_store.FileHoldAcquireOutcome, owner: String) -> Bool { + match o { + FileHoldOccupied { slot_key: _, holder: h, generation: _ } => (h as String) == owner + _ => false + } +} + +// THE REAL COMPARE-AND-SET, TWO CONTENDERS FOR ONE UNIT. The first acquire commits into the empty +// store; the second, a different run for the SAME key in the SAME store, finds the committed slot and +// is refused as occupied by the first run. Both go through file_hold_acquire unchanged, so the verdict +// is the production fold's reading of what the model's filesystem holds, and the route shows the +// second contender never wrote. +test fn two_contenders_for_one_unit_get_one_hold() -> Bool { + let first_owner = boot_run_owner(run_id: "run-a" as NonEmptyStr) + let second_owner = boot_run_owner(run_id: "run-b" as NonEmptyStr) + let result = evaluate_in_witness_frame( + frame: filesystem_frame(initial: empty_hold_store()), + subject: fn(_scope) { + let first = file_hold_acquire(root: hold_root, slot_key: hold_key, requested_owner: first_owner) + let second = file_hold_acquire(root: hold_root, slot_key: hold_key, requested_owner: second_owner) + acquired(o: first) && occupied_by(o: second, owner: first_owner as String) + } + ) + match result { + WitnessReturned { value, route, state } => + value + && count(filter(route, r => r.invocation.at.service == "Filesystem")) == count(route) + && count(filter(route, r => starts_with(s: r.invocation.at.operation, prefix: "WriteCreateNew"))) == 1 + && match state { Present { value: fs } => store_holds_one_slot(fs: fs) Absent => false } + _ => false + } +} + +fn store_holds_one_slot(fs: ModeledFilesystem) -> Bool { + count(filter(fs.files, f => starts_with(s: f.path, prefix: hold_root as String))) == 1 +} + +// THE FAILURE KIND TRAVELS THE REAL CHANNEL. A create-exclusive write to an existing path answers +// already_exists, and the operation's declared error_kind field, read by the production admission +// admit_filesystem_failure_kind, decodes it to FilesystemAlreadyExists -- the same projection a host +// io::Error reaches. +test fn a_create_exclusive_write_over_an_existing_file_is_already_exists() -> Bool { + let seeded = ModeledFilesystem { directories: ["/", "/tmp"], files: [ModeledFile { path: "/tmp/slot", content: "held" }] } + match evaluate_in_witness_frame( + frame: filesystem_frame(initial: seeded), + subject: fn(_scope) { + let w = Filesystem.WriteCreateNew(path: "/tmp/slot", content: "mine") + !w.success && match admit_filesystem_failure_kind(observed: w.error_kind) { + FilesystemFailureKindAdmitted { kind: k } => match k { FilesystemAlreadyExists => true _ => false } + _ => false + } + } + ) { + WitnessReturned { value, state } => value && match state { Present { value: fs } => untouched(fs: fs) Absent => false } + _ => false + } +} + +fn untouched(fs: ModeledFilesystem) -> Bool { + all(fs.files, f => f.content == "held") +} + +// A LISTING IS THE REALIZATION'S OWN CONTRACT: immediate children, sorted, one per line, files and +// directories alike; a file listed as a directory is not_a_directory. +test fn a_listing_is_sorted_immediate_children() -> Bool { + let fs = ModeledFilesystem { + directories: ["/", "/d", "/d/sub", "/d/sub/deeper"], + files: [ModeledFile { path: "/d/b", content: "" }, ModeledFile { path: "/d/a", content: "" }, ModeledFile { path: "/d/sub/c", content: "" }], + } + match evaluate_in_witness_frame( + frame: filesystem_frame(initial: fs), + subject: fn(_scope) { + let listed = Filesystem.List(path: "/d") + let as_dir = Filesystem.List(path: "/d/a") + listed.success && listed.entries == "a\nb\nsub" && !as_dir.success && as_dir.error_kind == "not_a_directory" + } + ) { + WitnessReturned { value } => value + _ => false + } +} + +// AN OBSERVATION OF THE WRONG TRANSPORT IS A HARNESS FAULT: a file operation answered with a shell +// observation refuses rather than being read through either projection. +test fn a_file_operation_answered_as_a_shell_run_refuses() -> Bool { + let realization = OperationRealization { + identity: realization_identity, + initial: empty_hold_store(), + epoch: virtual_clock_origin(), + bindings: [OperationBinding { + at: filesystem_operation(operation: "Read"), + handler: fn(s, c) { OperationObserved { observation: ShellObserved { observation: ShellProcessExited { exit_code: 0, stdout: "x", stderr: "" } }, state: s, elapsed: second(count: 0) } }, + }], + advance: fn(s, now) { s }, + } + let frame = filesystem_frame(initial: empty_hold_store()) + match evaluate_in_witness_frame( + frame: WitnessEvaluationFrame { envelope: frame.envelope, rest_fixtures: [], realization: Present { value: realization } }, + subject: fn(_scope) { Filesystem.Read(path: "/x").success } + ) { + WitnessRefused { diagnostic } => + string_contains(s: witness_diagnostic_rendered_reason(diagnostic: diagnostic), pattern: "needs FileObserved") + _ => false + } +} diff --git a/src/v1/stage0/src/v1_interpreter.rs b/src/v1/stage0/src/v1_interpreter.rs index 1bcd4cdf3de..914e6bd6550 100644 --- a/src/v1/stage0/src/v1_interpreter.rs +++ b/src/v1/stage0/src/v1_interpreter.rs @@ -8277,9 +8277,10 @@ fn dispatch_modeled_operation( ); modeled_refused(&key, format!("harness fault: {reason}")) }; - if !is_shell_transport(transport.clone()) { + let shell_operation = is_shell_transport(transport.clone()); + if !shell_operation && !is_file_transport(transport.clone(), ctx.si()) { return Err(harness_fault( - "a modeled realization supplies shell transport observations only; this operation's transport is not shell".to_string(), + "a modeled realization supplies shell and file transport observations only; this operation's transport is neither".to_string(), )); } let handler = record_field(ctx, &binding, "handler") @@ -8357,7 +8358,20 @@ fn dispatch_modeled_operation( return Err(error); } }; - let shell = shell_result_of_observation(&observation, ctx).map_err(&harness_fault)?; + let projected = if shell_operation { + shell_result_of_observation(&observation, ctx) + .map_err(&harness_fault) + .map(|shell| shell_result_projection(shell, op_node, ctx)) + } else { + let path = match param_env.lookup(ctx.sym("path")) { + Some(Value::Str(p)) => p.to_string(), + _ => String::new(), + }; + file_result_of_observation(&observation, &path, ctx) + .map_err(&harness_fault) + .map(|file| map_file_outputs(&file, op_node, ctx)) + }; + let projected = projected?; log( variant_value( ctx, @@ -8369,7 +8383,7 @@ fn dispatch_modeled_operation( Some(advanced), false, ); - shell_result_projection(shell, op_node, ctx).map(Some) + projected.map(Some) } "OperationWorkerKilled" => { let committed = ctx @@ -8404,6 +8418,71 @@ fn dispatch_modeled_operation( } } +/// A modeled FileExchangeObservation as the file transport result the real dispatcher produces. +/// The failure kind is named by its closed .dag authority (`filesystem_failure_kind_name`), the same +/// channel a host `io::Error` is projected onto, so a consumer's kind admission reads it unchanged. +fn file_result_of_observation( + observation: &Value, + path: &str, + ctx: &InterpContext, +) -> Result { + let (arm, fields) = variant_parts(ctx, observation).ok_or("the observation is malformed")?; + if arm != "FileObserved" { + return Err(format!( + "a file operation was answered with a {arm} observation; a file operation needs FileObserved" + )); + } + let file = ctx + .field(&fields, "observation") + .ok_or("FileObserved carries no observation")?; + let (file_arm, file_fields) = + variant_parts(ctx, file).ok_or("the file observation is malformed")?; + let text = |name: &str| match ctx.field(&file_fields, name) { + Some(Value::Str(s)) => Ok(s.to_string()), + _ => Err(format!("the file observation carries no {name}")), + }; + match file_arm.as_str() { + "FileOperationSucceeded" => { + let byte_count = match ctx.field(&file_fields, "byte_count") { + Some(Value::Int(n)) => *n, + _ => return Err("the file observation carries no byte_count".to_string()), + }; + Ok(FileResult { + success: true, + byte_count, + path: path.to_string(), + error: String::new(), + error_kind: String::new(), + content: text("content")?, + }) + } + "FileOperationFailed" => { + let kind = ctx + .field(&file_fields, "kind") + .cloned() + .ok_or("the file observation carries no kind")?; + let kind_name = match run_in_context_with_args( + ctx, + "filesystem_failure_kind_name", + &[(Some("kind".to_string()), kind)], + false, + ) { + Ok(Value::Str(s)) => s.to_string(), + _ => return Err("the file observation's kind has no name".to_string()), + }; + Ok(FileResult { + success: false, + byte_count: 0, + path: path.to_string(), + error: text("error")?, + error_kind: kind_name, + content: String::new(), + }) + } + other => Err(format!("unrecognized file observation {other}")), + } +} + /// A modeled ShellExchangeObservation as the shell transport result the real dispatcher produces. fn shell_result_of_observation( observation: &Value, diff --git a/src/v2/std/operation_realization.dag b/src/v2/std/operation_realization.dag index 97e82210962..57ea3d906f9 100644 --- a/src/v2/std/operation_realization.dag +++ b/src/v2/std/operation_realization.dag @@ -11,6 +11,7 @@ import std.measure { Second, second, second_count } import std.checked_arithmetic { checked_int_to_nat } import std.execution_mode { ExecutionMode, Hermetic, Wet, Record } import extdeps.transports.shell { ShellExchangeObservation, ShellProcessExited } +import extdeps.transports.file { FileExchangeObservation } // A MODELED OPERATION REALIZATION: the dry arm of an operation's realization, bound per grant. // @@ -43,6 +44,7 @@ import extdeps.transports.shell { ShellExchangeObservation, ShellProcessExited } // and the dispatch log for the dynamic extent of one witness frame. type TransportObservation = ShellObserved { observation: ShellExchangeObservation } + | FileObserved { observation: FileExchangeObservation } // A step either answers with an observation, or reports that the worker died after the effect was // (or was not) committed and before any reply, or reports that the SCENARIO is malformed. The last From cd5bdd5119c07e51e5072e1217475ba1921f2dd5 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Mon, 28 Sep 2026 09:58:07 +0000 Subject: [PATCH 04/75] Boot dry realization: environment, local/remote exact-invocation, remote host, wall clock models Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/gunbc/bmc_dry_realization.dag | 58 +++++--- dag/gunbc/host_command_model.dag | 98 ++++++++++++++ .../mtcollins1_boot_dry_realization.dag | 74 ++++++++++ dag/gunbc/process_environment_model.dag | 58 ++++++++ dag/gunbc/remote_host_model.dag | 127 ++++++++++++++++++ dag/gunbc/wall_clock_model.dag | 89 ++++++++++++ src/v1/stage0/src/v1_interpreter.rs | 18 +++ 7 files changed, 505 insertions(+), 17 deletions(-) create mode 100644 dag/gunbc/host_command_model.dag create mode 100644 dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag create mode 100644 dag/gunbc/process_environment_model.dag create mode 100644 dag/gunbc/remote_host_model.dag create mode 100644 dag/gunbc/wall_clock_model.dag diff --git a/dag/gunbc/bmc_dry_realization.dag b/dag/gunbc/bmc_dry_realization.dag index 0fff5d963a8..f5b0e17eec9 100644 --- a/dag/gunbc/bmc_dry_realization.dag +++ b/dag/gunbc/bmc_dry_realization.dag @@ -38,38 +38,62 @@ fn bmc_ipmi_operation(operation: String) -> OperationRef { OperationRef { path: bmc_ipmi_operation_path, service: bmc_ipmi_service, operation: operation } } -fn exited(stdout: String, world: BmcWorld) -> OperationStep { - OperationObserved { - observation: ShellObserved { observation: ShellProcessExited { exit_code: 0, stdout: stdout, stderr: "" } }, - state: world, - elapsed: second(count: 1), - } -} +// ONE BMC COMMAND'S RESULT BEFORE IT IS PLACED IN A SCENARIO: the stdout the client would print and the +// world after it, or a harness fault. Handlers are written over the BMC world alone; bmc_bindings lifts +// them through a lens into whatever scenario state embeds the world. +type BmcReply + = BmcReplied { stdout: String, world: BmcWorld } + | BmcReplyFault { reason: NonEmptyStr } -fn bmc_chassis_status_handler(world: BmcWorld, call: OperationCall) -> OperationStep { - exited(stdout: ipmitool_chassis_status_power_line(power_on: bmc_power_is_on(world: world)), world: world) +fn bmc_chassis_status_reply(world: BmcWorld, call: OperationCall) -> BmcReply { + BmcReplied { stdout: ipmitool_chassis_status_power_line(power_on: bmc_power_is_on(world: world)), world: world } } -fn bmc_chassis_power_control_handler(world: BmcWorld, call: OperationCall) -> OperationStep { +fn bmc_chassis_power_control_reply(world: BmcWorld, call: OperationCall) -> BmcReply { match operation_input_text(invocation: call.invocation, name: "action") { - Absent => OperationHarnessFault { reason: "ChassisPowerControl was dispatched without an action input" as NonEmptyStr } + Absent => BmcReplyFault { reason: "ChassisPowerControl was dispatched without an action input" as NonEmptyStr } Present { value: verb } => match ipmi_chassis_control_action_of_verb(verb: verb) { - Absent => OperationHarnessFault { reason: join(["ChassisPowerControl action `", verb, "` names no IPMI chassis control action the model carries"], "") as NonEmptyStr } - Present { value: action } => exited(stdout: ipmitool_chassis_power_control_reply(action: action), world: bmc_chassis_control(world: world, action: action).world) + Absent => BmcReplyFault { reason: join(["ChassisPowerControl action `", verb, "` names no IPMI chassis control action the model carries"], "") as NonEmptyStr } + Present { value: action } => BmcReplied { stdout: ipmitool_chassis_power_control_reply(action: action), world: bmc_chassis_control(world: world, action: action).world } + } + } +} + +// One IPMI round trip takes one virtual second. +fn bmc_lift(get: fn(S) -> BmcWorld, put: fn(S, BmcWorld) -> S, reply: fn(BmcWorld, OperationCall) -> BmcReply) -> fn(S, OperationCall) -> OperationStep { + fn(state, call) { + match reply(get(state), call) { + BmcReplyFault { reason: r } => OperationHarnessFault { reason: r } + BmcReplied { stdout: out, world: w } => OperationObserved { + observation: ShellObserved { observation: ShellProcessExited { exit_code: 0, stdout: out, stderr: "" } }, + state: put(state, w), + elapsed: second(count: 1), + } } } } +fn bmc_bindings(get: fn(S) -> BmcWorld, put: fn(S, BmcWorld) -> S) -> List> { + [ + OperationBinding { at: bmc_ipmi_operation(operation: "ChassisStatus"), handler: bmc_lift(get: get, put: put, reply: bmc_chassis_status_reply) }, + OperationBinding { at: bmc_ipmi_operation(operation: "ChassisPowerControl"), handler: bmc_lift(get: get, put: put, reply: bmc_chassis_power_control_reply) }, + ] +} + +fn bmc_chassis_power_control_handler(world: BmcWorld, call: OperationCall) -> OperationStep { + let handler = bmc_lift(get: fn(w) { w }, put: fn(w, next) { next }, reply: bmc_chassis_power_control_reply) + handler(world, call) +} + fn bmc_dry_realization(identity: NonEmptyStr, initial: BmcWorld, epoch: Second) -> OperationRealization { OperationRealization { identity: identity, initial: initial, epoch: epoch, - bindings: [ - OperationBinding { at: bmc_ipmi_operation(operation: "ChassisStatus"), handler: bmc_chassis_status_handler }, - OperationBinding { at: bmc_ipmi_operation(operation: "ChassisPowerControl"), handler: bmc_chassis_power_control_handler }, + bindings: list_append( + bmc_bindings(get: fn(w) { w }, put: fn(w, next) { next }), virtual_delay_binding(at: sleep_delay_seconds_operation, seconds_input: "seconds"), - ], + ), advance: bmc_advance, } } diff --git a/dag/gunbc/host_command_model.dag b/dag/gunbc/host_command_model.dag new file mode 100644 index 00000000000..dc5fdd29373 --- /dev/null +++ b/dag/gunbc/host_command_model.dag @@ -0,0 +1,98 @@ +module gunbc.host_command_model + +import std.types { Bool, List, NonEmptyStr, String } +import std.measure { second } +import v2.std.operation_argv { OperationRef, InputText, InputTextList } +import v2.std.operation_realization { + OperationBinding, OperationCall, OperationStep, OperationObserved, OperationHarnessFault, + ShellObserved, +} +import extdeps.transports.shell { ShellExchangeObservation } +import extdeps.exec.command { ArgvCommand } + +// AN OPERATION THAT CARRIES A WHOLE COMMAND AS ITS INPUT, AND WHAT THE FAR SIDE ANSWERS. Some +// operations are one identity for every command they run: extdeps.shell.exec shell.Exec.RunArgv +// starts any local program, and extdeps.ssh.session ssh.Session.ExecPortableWords runs any remote +// command. Binding such an operation by identity alone would answer every command the same way, and +// answering by the program's NAME would be the executable-name binding the #12423 design decision +// refuses. So the binding is an EXACT-INVOCATION table, the keying REST replay already uses for its +// fixtures: a scenario lists the complete word sequences it models -- OBTAINED FROM THE PRODUCTION +// BUILDERS the code under test calls, never hand-spelled -- and a dispatched invocation is answered +// only when the concatenation of its named inputs equals one listed sequence. An unlisted invocation, +// or one matching two entries, is a harness fault, never a guessed answer. The answer is a function +// of the scenario state, so the far side's reply can depend on the world. +type ModeledInvocation { + words: List + answer: fn(S) -> ShellExchangeObservation +} + +data shell_exec_run_argv_operation: OperationRef = OperationRef { + path: "dag/extdeps/shell/exec.dag", + service: "shell.Exec", + operation: "RunArgv", +} + +data ssh_session_exec_portable_words_operation: OperationRef = OperationRef { + path: "dag/extdeps/ssh/session.dag", + service: "ssh.Session", + operation: "ExecPortableWords", +} + +// The words a LOCAL ArgvCommand dispatches as: its program then its arguments, exactly what +// command_over_transport builds for LocalExec and RunArgv receives. +fn local_command_words(command: ArgvCommand) -> List { + concat([command.program as String], command.arguments) +} + +fn dispatched_words(bindings: List, name: String) -> List? { + fold(bindings, init: none, f: fn(acc, b) { + match acc { + Present { value: v } => Present { value: v } + Absent => if b.name == name { + match b.value { + InputTextList { items: xs } => Present { value: xs } + InputText { text: t } => Present { value: [t] } + } + } else { none } + } + }) +} + +fn invocation_words(bindings: List, inputs: List) -> List? { + fold(inputs, init: Present { value: [] }, f: fn(acc, name) { + match acc { + Absent => none + Present { value: so_far } => match dispatched_words(bindings: bindings, name: name) { + Absent => none + Present { value: ws } => Present { value: concat(so_far, ws) } + } + } + }) +} + +fn exact_invocation_binding(at: OperationRef, inputs: List, table: List>) -> OperationBinding { + OperationBinding { + at: at, + handler: fn(state, call) { + match invocation_words(bindings: call.invocation.bindings, inputs: inputs) { + Absent => OperationHarnessFault { reason: join(["the invocation lacks one of its declared inputs: ", join(inputs, ", ")], "") as NonEmptyStr } + Present { value: words } => { + let matching = filter(table, m => m.words == words) + if count(matching) == 1 { + match matching.first() { + Present { value: m } => { + let answer = m.answer + OperationObserved { observation: ShellObserved { observation: answer(state) }, state: state, elapsed: second(count: 0) } + } + Absent => OperationHarnessFault { reason: "a matched invocation vanished" as NonEmptyStr } + } + } else if count(matching) == 0 { + OperationHarnessFault { reason: join(["no modeled invocation is exactly `", join(words, " "), "`"], "") as NonEmptyStr } + } else { + OperationHarnessFault { reason: join(["two modeled invocations are exactly `", join(words, " "), "`"], "") as NonEmptyStr } + } + } + } + }, + } +} diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag new file mode 100644 index 00000000000..fe043da3884 --- /dev/null +++ b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag @@ -0,0 +1,74 @@ +module gunbc.machine_intake_mtcollins1_boot_dry_realization + +import std.types { List, NonEmptyStr, String } +import std.measure { Second } +import v2.std.operation_realization { OperationRealization, virtual_delay_binding } +import gunbc.bmc_model { BmcWorld, bmc_advance } +import gunbc.bmc_dry_realization { bmc_bindings, sleep_delay_seconds_operation } +import gunbc.filesystem_model { ModeledFilesystem, filesystem_bindings } +import gunbc.process_environment_model { ModeledVariable, environment_binding } +import gunbc.host_command_model { ModeledInvocation, exact_invocation_binding, local_command_words, shell_exec_run_argv_operation } +import extdeps.transports.shell { ShellExchangeObservation, ShellProcessExited } +import extdeps.exec.command { env_prefixed_command } +import extdeps.tools.env { EnvSet } +import extdeps.ssh.openssh_client_commands { ssh_add_list_identities_command } +import gunbc.fleet_ssh_access { fleet_automation_ssh_key_fingerprint } +import gunbc.remote_host_model { ModeledRemoteHost, remote_host_binding } +import gunbc.wall_clock_model { ModeledWallClock, wall_clock_bindings } + +// THE DRY REALIZATION OF ONE mtcollins1 BOOT ATTEMPT'S WHOLE EFFECT DEMAND. The scenario world +// composes the one BMC model with the worker's filesystem (credential file, unit-hold store, SOL pid +// and capture files) and its process environment (credential path, SOL paths, run and revision +// identity). Every transition belongs to its own model; this module only places them side by side and +// lifts their bindings into the composite state. The real entry -- +// gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 -- runs unchanged over it. +type MtCollins1BootWorld { + bmc: BmcWorld + fs: ModeledFilesystem + environment: List + agent: ModeledSshAgent + remote_hosts: List + clock: ModeledWallClock +} + +// THE WORKER'S SSH AGENT: whether it holds the fleet automation key. Its listing follows +// `ssh-add -l`: one ` ()` line per identity, exit 0; and with no +// identities, "The agent has no identities." on stdout with exit 1 (ssh-add(1)). +type ModeledSshAgent { + socket: String + holds_fleet_key: Bool +} + +fn agent_listing(agent: ModeledSshAgent) -> ShellExchangeObservation { + if agent.holds_fleet_key { + ShellProcessExited { exit_code: 0, stdout: join(["256 ", fleet_automation_ssh_key_fingerprint, " fleet-automation@gunbc (ED25519)\n"], ""), stderr: "" } + } else { + ShellProcessExited { exit_code: 1, stdout: "The agent has no identities.\n", stderr: "" } + } +} + +fn boot_world_with_bmc(w: MtCollins1BootWorld, bmc: BmcWorld) -> MtCollins1BootWorld { + MtCollins1BootWorld { bmc: bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock } +} + +fn boot_world_with_fs(w: MtCollins1BootWorld, fs: ModeledFilesystem) -> MtCollins1BootWorld { + MtCollins1BootWorld { bmc: w.bmc, fs: fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock } +} + +fn mtcollins1_boot_dry_realization(identity: NonEmptyStr, initial: MtCollins1BootWorld, epoch: Second) -> OperationRealization { + let bmc = bmc_bindings(get: fn(w) { w.bmc }, put: boot_world_with_bmc) + let files = filesystem_bindings(get: fn(w) { w.fs }, put: boot_world_with_fs) + let local_commands = exact_invocation_binding(at: shell_exec_run_argv_operation, inputs: ["program", "arguments"], table: [ + ModeledInvocation { + words: local_command_words(command: env_prefixed_command(bindings: [EnvSet { name: "SSH_AUTH_SOCK", value: initial.agent.socket }], command: ssh_add_list_identities_command())), + answer: fn(w) { agent_listing(agent: w.agent) }, + }, + ]) + OperationRealization { + identity: identity, + initial: initial, + epoch: epoch, + bindings: concat(concat(concat(bmc, files), wall_clock_bindings(get: fn(w) { w.clock })), [environment_binding(get: fn(w) { w.environment }), virtual_delay_binding(at: sleep_delay_seconds_operation, seconds_input: "seconds"), local_commands, remote_host_binding(get: fn(w) { w.remote_hosts })]), + advance: fn(w, now) { boot_world_with_bmc(w: w, bmc: bmc_advance(world: w.bmc, now: now)) }, + } +} diff --git a/dag/gunbc/process_environment_model.dag b/dag/gunbc/process_environment_model.dag new file mode 100644 index 00000000000..7c659345545 --- /dev/null +++ b/dag/gunbc/process_environment_model.dag @@ -0,0 +1,58 @@ +module gunbc.process_environment_model + +import std.types { List, NonEmptyStr, String } +import std.measure { second } +import v2.std.operation_argv { OperationRef } +import v2.std.operation_realization { + OperationBinding, OperationCall, OperationStep, OperationObserved, OperationHarnessFault, + ShellObserved, operation_input_text, +} +import extdeps.transports.shell { ShellProcessExited } + +// A MODELED PROCESS ENVIRONMENT: the variables a scenario's worker was started with, answered through +// the realization's own contract for extdeps.shell shell.Env.Get (printenv): a set variable prints its +// value and exits 0; an unset one prints nothing and exits 1, which the operation's optional output +// projects to Absent -- exactly as a real printenv does. A variable set to the empty string is SET, and +// prints an empty line, so the consumer's own set-but-empty refusal is exercised rather than bypassed. +type ModeledVariable { + name: String + value: String +} + +data shell_env_get_operation: OperationRef = OperationRef { + path: "dag/extdeps/shell.dag", + service: "shell.Env", + operation: "Get", +} + +fn modeled_variable(variables: List, name: String) -> ModeledVariable? { + fold(variables, init: none, f: fn(acc, v) { + match acc { + Present { value: found } => Present { value: found } + Absent => if v.name == name { Present { value: v } } else { none } + } + }) +} + +fn environment_binding(get: fn(S) -> List) -> OperationBinding { + OperationBinding { + at: shell_env_get_operation, + handler: fn(state, call) { + match operation_input_text(invocation: call.invocation, name: "name") { + Absent => OperationHarnessFault { reason: "an environment read was dispatched without a name" as NonEmptyStr } + Present { value: name } => match modeled_variable(variables: get(state), name: name) { + Present { value: v } => OperationObserved { + observation: ShellObserved { observation: ShellProcessExited { exit_code: 0, stdout: concat(v.value, "\n"), stderr: "" } }, + state: state, + elapsed: second(count: 0), + } + Absent => OperationObserved { + observation: ShellObserved { observation: ShellProcessExited { exit_code: 1, stdout: "", stderr: "" } }, + state: state, + elapsed: second(count: 0), + } + } + } + }, + } +} diff --git a/dag/gunbc/remote_host_model.dag b/dag/gunbc/remote_host_model.dag new file mode 100644 index 00000000000..df1aa23cc36 --- /dev/null +++ b/dag/gunbc/remote_host_model.dag @@ -0,0 +1,127 @@ +module gunbc.remote_host_model + +import std.types { Bool, List, NonEmptyStr, String } +import std.measure { second } +import v2.std.operation_realization { + OperationBinding, OperationCall, OperationStep, OperationObserved, OperationHarnessFault, ShellObserved, +} +import extdeps.transports.shell { ShellExchangeObservation, ShellProcessExited } +import extdeps.exec.command { argv_words } +import extdeps.tools.gnu_coreutils { cat_command } +import extdeps.crypto.hash { sha256sum_file_command } +import gunbc.host_command_model { dispatched_words, ssh_session_exec_portable_words_operation } + +// A MODELED REMOTE HOST reached over extdeps.ssh.session ssh.Session.ExecPortableWords. The SSH client +// arguments are shaped as ` -- ` (gunbc.fleet_known_hosts_anchor +// shape_fleet_ssh_exec), and the far side sees exactly the endpoint and the remote words; the model is +// that far side. It answers ONLY the remote words the production command builders produce for the +// paths it holds -- extdeps.tools.gnu_coreutils cat_command and extdeps.crypto.hash +// sha256sum_file_command -- compared exactly, so nothing is dispatched on a program's name. Anything +// else, including a request for another endpoint, is a harness fault. +// +// NOT JUDGED HERE, and stated so a green over it is not over-read: the client-side options before the +// endpoint (host-key trust, credential, config suppression). They are the real OpenSSH client's to +// honour; their evidence is the SSH transport's own controls, not this model. +// +// A FILE IS ITS CONTENT AND ITS DECLARED DIGEST. An image is not hashed in .dag; the scenario declares +// the SHA-256 its bytes have, and the model reports it in sha256sum's own format. A path with no +// content is absent, and both commands answer as coreutils does for a missing file. +type ModeledRemoteFile { + path: String + content: String? + sha256: String? +} + +type ModeledRemoteHost { + endpoint: String + files: List +} + +fn remote_missing(tool: String, path: String) -> ShellExchangeObservation { + ShellProcessExited { exit_code: 1, stdout: "", stderr: join([tool, ": ", path, ": No such file or directory\n"], "") } +} + +fn remote_cat(file: ModeledRemoteFile) -> ShellExchangeObservation { + match file.content { + Absent => remote_missing(tool: "cat", path: file.path) + Present { value: c } => ShellProcessExited { exit_code: 0, stdout: c, stderr: "" } + } +} + +fn remote_sha256sum(file: ModeledRemoteFile) -> ShellExchangeObservation { + match file.content { + Absent => remote_missing(tool: "sha256sum", path: file.path) + Present { value: _ } => match file.sha256 { + Absent => ShellProcessExited { exit_code: 1, stdout: "", stderr: join(["sha256sum: ", file.path, ": Input/output error\n"], "") } + Present { value: d } => ShellProcessExited { exit_code: 0, stdout: join([d, " ", file.path, "\n"], ""), stderr: "" } + } + } +} + +type RemoteRequest { + endpoint: String + words: List +} + +// The far side of the client args: the word before the FIRST `--` is the endpoint, everything after +// it is the remote command -- which may itself carry a `--` (sha256sum -- ). No separator at all +// means the request is not one this shape produces. +fn remote_request(client_args: List) -> RemoteRequest? { + let separators = filter(client_args, a => a == "--") + if count(separators) == 0 { none } else { + let before = take_while(xs: client_args, keep: fn(a) { a != "--" }) + let after = client_args.skip(n: count(before) + 1) + match before.last() { + Absent => none + Present { value: endpoint } => Present { value: RemoteRequest { endpoint: endpoint, words: after } } + } + } +} + +fn take_while(xs: List, keep: fn(String) -> Bool) -> List { + fold(xs, init: TakeWhileState { kept: [], open: true }, f: fn(acc, x) { + if acc.open && keep(x) { TakeWhileState { kept: list_append(acc.kept, x), open: true } } + else { TakeWhileState { kept: acc.kept, open: false } } + }).kept +} + +type TakeWhileState { + kept: List + open: Bool +} + +fn remote_answer(host: ModeledRemoteHost, words: List) -> ShellExchangeObservation? { + fold(host.files, init: none, f: fn(acc, file) { + match acc { + Present { value: v } => Present { value: v } + Absent => + if words == argv_words(command: cat_command(path: file.path)) { Present { value: remote_cat(file: file) } } + else if words == argv_words(command: sha256sum_file_command(path: file.path)) { Present { value: remote_sha256sum(file: file) } } + else { none } + } + }) +} + +fn remote_host_binding(get: fn(S) -> List) -> OperationBinding { + OperationBinding { + at: ssh_session_exec_portable_words_operation, + handler: fn(state, call) { + match dispatched_words(bindings: call.invocation.bindings, name: "client_args") { + Absent => OperationHarnessFault { reason: "a remote exec was dispatched without client args" as NonEmptyStr } + Present { value: args } => match remote_request(client_args: args) { + Absent => OperationHarnessFault { reason: "the client args do not end in ` -- `" as NonEmptyStr } + Present { value: request } => { + let hosts = filter(get(state), h => h.endpoint == request.endpoint) + match hosts.first() { + Absent => OperationHarnessFault { reason: join(["no modeled host answers at ", request.endpoint], "") as NonEmptyStr } + Present { value: host } => match remote_answer(host: host, words: request.words) { + Absent => OperationHarnessFault { reason: join(["the modeled host at ", request.endpoint, " answers no command `", join(request.words, " "), "`"], "") as NonEmptyStr } + Present { value: observation } => OperationObserved { observation: ShellObserved { observation: observation }, state: state, elapsed: second(count: 1) } + } + } + } + } + } + }, + } +} diff --git a/dag/gunbc/wall_clock_model.dag b/dag/gunbc/wall_clock_model.dag new file mode 100644 index 00000000000..199470400bb --- /dev/null +++ b/dag/gunbc/wall_clock_model.dag @@ -0,0 +1,89 @@ +module gunbc.wall_clock_model + +import std.types { Int, List, String } +import std.measure { Second, second, second_count } +import v2.std.operation_argv { OperationRef } +import v2.std.operation_realization { + OperationBinding, OperationCall, OperationStep, OperationObserved, ShellObserved, +} +import extdeps.transports.shell { ShellProcessExited } + +// A MODELED WALL CLOCK: what the worker's `date` prints, as a function of the realization's virtual +// clock. The virtual clock (v2.std.operation_realization, a Nat-counted Second) is monotonic by +// construction; the WALL clock is not, and a real host's can step backwards (NTP, a VM restored from +// a snapshot). So the model keeps them apart: a reading is the Unix time the scenario assigns to the +// virtual origin, plus the virtual seconds elapsed, plus a signed step the scenario may set -- a +// negative step is a backward clock the consumer must survive, while virtual time, deadlines and +// scheduled events keep moving forward. +// +// It answers extdeps.clock Clock.Now in `date -u +%Y-%m-%dT%H:%M:%SZ` form, and Clock.UnixSecs and +// Clock.UnixMillis in `date +%s` and `date +%s%3N` form, over the proleptic Gregorian calendar. +type ModeledWallClock { + unix_at_origin: Int + step_seconds: Int +} + +fn wall_clock_unix(clock: ModeledWallClock, now: Second) -> Int { + clock.unix_at_origin + (second_count(s: now) as Int) + clock.step_seconds +} + +fn two_digits(n: Int) -> String { + if n < 10 { concat("0", to_string(n)) } else { to_string(n) } +} + +// Days since 1970-01-01 to a civil date: H. Hinnant, "chrono-Compatible Low-Level Date Algorithms", +// civil_from_days -- exact for the whole proleptic Gregorian range, no table. +type CivilDate { + year: Int + month: Int + day: Int +} + +fn floor_div(a: Int, b: Int) -> Int { + if a >= 0 { a / b } else { 0 - ((0 - a + b - 1) / b) } +} + +fn civil_from_days(days: Int) -> CivilDate { + let z = days + 719468 + let era = floor_div(a: z, b: 146097) + let doe = z - era * 146097 + let yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365 + let y = yoe + era * 400 + let doy = doe - (365 * yoe + yoe / 4 - yoe / 100) + let mp = (5 * doy + 2) / 153 + let d = doy - (153 * mp + 2) / 5 + 1 + let m = if mp < 10 { mp + 3 } else { mp - 9 } + CivilDate { year: if m <= 2 { y + 1 } else { y }, month: m, day: d } +} + +fn iso8601_utc(unix: Int) -> String { + let days = floor_div(a: unix, b: 86400) + let rem = unix - days * 86400 + let date = civil_from_days(days: days) + join([ + to_string(date.year), "-", two_digits(n: date.month), "-", two_digits(n: date.day), + "T", two_digits(n: rem / 3600), ":", two_digits(n: (rem - (rem / 3600) * 3600) / 60), ":", two_digits(n: rem - (rem / 60) * 60), "Z", + ], "") +} + +data clock_operation_path: String = "dag/extdeps/clock/clock.dag" + +fn clock_operation(operation: String) -> OperationRef { + OperationRef { path: clock_operation_path, service: "Clock", operation: operation } +} + +fn printed(state: S, text: String) -> OperationStep { + OperationObserved { + observation: ShellObserved { observation: ShellProcessExited { exit_code: 0, stdout: concat(text, "\n"), stderr: "" } }, + state: state, + elapsed: second(count: 0), + } +} + +fn wall_clock_bindings(get: fn(S) -> ModeledWallClock) -> List> { + [ + OperationBinding { at: clock_operation(operation: "Now"), handler: fn(state, call) { printed(state: state, text: iso8601_utc(unix: wall_clock_unix(clock: get(state), now: call.now))) } }, + OperationBinding { at: clock_operation(operation: "UnixSecs"), handler: fn(state, call) { printed(state: state, text: to_string(wall_clock_unix(clock: get(state), now: call.now))) } }, + OperationBinding { at: clock_operation(operation: "UnixMillis"), handler: fn(state, call) { printed(state: state, text: to_string(wall_clock_unix(clock: get(state), now: call.now) * 1000)) } }, + ] +} diff --git a/src/v1/stage0/src/v1_interpreter.rs b/src/v1/stage0/src/v1_interpreter.rs index 914e6bd6550..8b2ef4139db 100644 --- a/src/v1/stage0/src/v1_interpreter.rs +++ b/src/v1/stage0/src/v1_interpreter.rs @@ -8121,6 +8121,24 @@ fn bound_operation_invocation_value( continue; }; let bound = match value { + // An argv expansion binds as the words a real spawn receives, expanded by the same + // seed realization of v2.std.compilers.cli_surface ProcessArgvExpansion the shell + // dispatcher uses, never as a rendering of the carrier. + Value::Record { type_name, fields } + if resolve_sym(*type_name).rsplit('.').next() == Some("ProcessArgvExpansion") => + { + let mut words = Vec::new(); + push_process_argv_expansion(&mut words, &fields)?; + variant_value( + ctx, + "OperationInputValue", + "InputTextList", + vec![( + "items", + list_value(words.into_iter().map(str_value).collect::>()), + )], + ) + } Value::List(items) => { let texts: Vec = items.iter().map(|v| str_value(render_input(v))).collect(); variant_value( From 3967705250d10724b8c05b0afb5ea671d7ef2cae Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Mon, 28 Sep 2026 10:02:12 +0000 Subject: [PATCH 05/75] Witness the boot-world models' own semantics (calendar, backward step, remote request, coreutils formats, parent rule) Co-Authored-By: Claude Opus 5.5 (1M context) --- .../claim/boot_world_models_witness_test.dag | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 dag/test/claim/boot_world_models_witness_test.dag diff --git a/dag/test/claim/boot_world_models_witness_test.dag b/dag/test/claim/boot_world_models_witness_test.dag new file mode 100644 index 00000000000..756eec54443 --- /dev/null +++ b/dag/test/claim/boot_world_models_witness_test.dag @@ -0,0 +1,74 @@ +module test.claim.boot_world_models_witness_test + +import std.types { Bool, List, String } +import std.measure { second } +import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } +import extdeps.transports.shell { ShellProcessExited } +import extdeps.exec.command { argv_words } +import extdeps.tools.gnu_coreutils { cat_command } +import extdeps.crypto.hash { sha256sum_file_command } +import gunbc.wall_clock_model { ModeledWallClock, iso8601_utc, wall_clock_unix } +import gunbc.remote_host_model { ModeledRemoteHost, ModeledRemoteFile, remote_request, remote_answer } +import gunbc.filesystem_model { ModeledFilesystem, ModeledFile, fs_parent, fs_write, fs_list } + +data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly + +// THE MODELS' OWN SEMANTICS, checked apart from any orchestrator run, so a matrix case cannot pass +// against a model that is wrong in the same direction as the code under test. Reference values for the +// calendar are independent: Python's datetime.fromtimestamp(t, timezone.utc) for each instant. +test fn the_wall_clock_renders_utc_like_date() -> Bool { + iso8601_utc(unix: 0) == "1970-01-01T00:00:00Z" + && iso8601_utc(unix: 951782400) == "2000-02-29T00:00:00Z" + && iso8601_utc(unix: 1790000000) == "2026-09-21T14:13:20Z" + && iso8601_utc(unix: 4102444799) == "2099-12-31T23:59:59Z" + && iso8601_utc(unix: 0 - 1) == "1969-12-31T23:59:59Z" +} + +// A NEGATIVE STEP IS A WALL CLOCK THAT WENT BACKWARDS while virtual time moved forward. +test fn a_backward_step_reads_earlier_while_virtual_time_advances() -> Bool { + let clock = ModeledWallClock { unix_at_origin: 1790000000, step_seconds: 0 - 120 } + wall_clock_unix(clock: clock, now: second(count: 60)) == 1789999940 +} + +// THE FAR SIDE OF AN SSH REQUEST is the word before the first `--` and everything after it, so a +// remote command that itself carries `--` keeps it. +test fn a_remote_request_splits_at_the_first_separator() -> Bool { + match remote_request(client_args: ["-o", "BatchMode=yes", "srv2", "--", "sha256sum", "--", "/srv/x"]) { + Present { value: r } => r.endpoint == "srv2" && r.words == ["sha256sum", "--", "/srv/x"] + Absent => false + } + && match remote_request(client_args: ["srv2", "cat", "/srv/x"]) { Present { value: _ } => false Absent => true } +} + +// THE REMOTE HOST ANSWERS ONLY THE PRODUCTION BUILDERS' WORDS, in coreutils' formats. +test fn the_remote_host_answers_production_commands_in_coreutils_format() -> Bool { + let host = ModeledRemoteHost { endpoint: "srv2", files: [ + ModeledRemoteFile { path: "/srv/rec", content: Present { value: "abc\n" }, sha256: none }, + ModeledRemoteFile { path: "/srv/img", content: Present { value: "bytes" }, sha256: Present { value: "ff00" } }, + ModeledRemoteFile { path: "/srv/gone", content: none, sha256: none }, + ] } + let cat_ok = match remote_answer(host: host, words: argv_words(command: cat_command(path: "/srv/rec"))) { + Present { value: ShellProcessExited { exit_code: 0, stdout: "abc\n", stderr: _ } } => true + _ => false + } + let sum_ok = match remote_answer(host: host, words: argv_words(command: sha256sum_file_command(path: "/srv/img"))) { + Present { value: ShellProcessExited { exit_code: 0, stdout: "ff00 /srv/img\n", stderr: _ } } => true + _ => false + } + let gone = match remote_answer(host: host, words: argv_words(command: cat_command(path: "/srv/gone"))) { + Present { value: ShellProcessExited { exit_code: 1, stdout: _, stderr: "cat: /srv/gone: No such file or directory\n" } } => true + _ => false + } + let unlisted = match remote_answer(host: host, words: ["rm", "-rf", "/srv"]) { Present { value: _ } => false Absent => true } + cat_ok && sum_ok && gone && unlisted +} + +// THE FILESYSTEM'S PARENT RULE: a write under a directory the model does not hold is not_found. +test fn a_write_needs_its_parent_directory() -> Bool { + let fs = ModeledFilesystem { directories: ["/", "/run"], files: [] } + fs_parent(path: "/run/sol.pid") == "/run" && fs_parent(path: "/x") == "/" && fs_parent(path: "target/a.pub") == "target" + && match fs_write(fs: fs, path: "/var/x", content: "1", create_new: false).observation { + extdeps.transports.file.FileOperationFailed { kind: extdeps.filesystem.filesystem_io.FilesystemNotFound, error: _ } => true + _ => false + } +} From 96ba551277e83c08118e74c78aecb85357793d50 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Mon, 28 Sep 2026 10:12:05 +0000 Subject: [PATCH 06/75] Boot world: expanded BMC model (override, SEL, SOL session, cycle restore), ipmitool observed-output rows, SOL collector/process table, SDR dump, SMpro, uptime, host console Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/extdeps/bmc/ipmitool_observed_output.dag | 56 +++++ dag/gunbc/bmc_dry_realization.dag | 50 +++- dag/gunbc/bmc_model.dag | 140 ++++++++--- .../mtcollins1_boot_dry_realization.dag | 228 ++++++++++++++++-- .../operation_realization_witness_test.dag | 9 +- 5 files changed, 430 insertions(+), 53 deletions(-) create mode 100644 dag/extdeps/bmc/ipmitool_observed_output.dag diff --git a/dag/extdeps/bmc/ipmitool_observed_output.dag b/dag/extdeps/bmc/ipmitool_observed_output.dag new file mode 100644 index 00000000000..5b3831c55be --- /dev/null +++ b/dag/extdeps/bmc/ipmitool_observed_output.dag @@ -0,0 +1,56 @@ +module extdeps.bmc.ipmitool_observed_output + +import std.types { Int, NonEmptyStr, String } +import extdeps.external_authority { ExternalAuthority, CitedFigureStanding, TranscribedUncited } +import extdeps.uri { Uri, Https } + +data extdeps_external_authority_anchor: ExternalAuthority = ExternalAuthority { + uri: Uri { + scheme: Https + locator: "github.com/ipmitool/ipmitool" + } +} + +// WHAT ipmitool PRINTS, AS OBSERVED ON THE MT. COLLINS AMI MEGARAC BUILD. Each row is the client's +// output format for one operation, taken verbatim from a retained capture and cited by that capture's +// path and SHA-256, so a modeled realization renders exactly what the production decoder was built to +// read. These are client-format facts about the upstream tool on one controller build, not +// facts about any scenario; a row whose value is not in a retained capture says so in its standing. + +// `ipmitool chassis bootparam get 5` with no override pending. Source: run 36335369059 +// mtcollins1-boot-diagnostics.txt (sha256 eda19cde2e60d90d3d04946273e615eb5bf774496b9907e03d3bc15dbedc2c1c), +// "boot parameter 5 before", verbatim including the trailing space after "legacy) boot". +data ipmitool_bootparam5_no_override: String = "Boot parameter version: 1\nBoot parameter 5 is valid/unlocked\nBoot parameter data: 0000000000\n Boot Flags :\n - Boot Flag Invalid\n - Options apply to only next boot\n - BIOS PC Compatible (legacy) boot \n - Boot Device Selector : No override\n - BIOS verbosity : System Default\n - Console Redirection control : Console redirection occurs per BIOS configuration setting (default)\n - BIOS Mux Control Override : BIOS uses recommended setting of the mux at the end of POST\n" + +// The same read after `chassis bootdev cdrom options=efiboot`. Source: artifacts/bmc/mtcollins1-32dimm/30-bootdev.txt +// (sha256 6488554239e12f033203c9589285bd6ce27dfb5716658be931e2422ea238c4ba), the readback block. +data ipmitool_bootparam5_cdrom_efi_next_boot: String = "Boot parameter version: 1\nBoot parameter 5 is valid/unlocked\nBoot parameter data: a014000000\n Boot Flags :\n - Boot Flag Valid\n - Options apply to only next boot\n - BIOS EFI boot \n - Boot Device Selector : Force Boot from CD/DVD\n - BIOS verbosity : System Default\n - Console Redirection control : Console redirection occurs per BIOS configuration setting (default)\n - BIOS Mux Control Override : BIOS uses recommended setting of the mux at the end of POST\n" + +// `ipmitool chassis bootdev cdrom options=efiboot`. Same capture, line 2. +data ipmitool_bootdev_cdrom_reply: String = "Set Boot Device to cdrom\n" + +// What `ipmitool sol activate` prints first when its stdin is not a terminal. Source: +// artifacts/bmc/mtcollins1-32dimm/22-sol-probe.log (sha256 e24f9ed8d9cedff87e6d11327c602c31fd7c3d9e2ba16e7e1ab0f8a91cdfe41e), +// lines 1-2. +data ipmitool_sol_activate_preamble: String = "tcgetattr: Inappropriate ioctl for device\n[SOL Session operational. Use ~? for help]\n" + +// One `ipmitool sel elist` line: the record id in lowercase hex right-aligned in four columns, then +// date, time, sensor, event and state separated by ` | `. Source: artifacts/bmc/mtcollins1-32dimm/50-sel-final.txt +// (sha256 14e84cd9cbd2d89d6be46caff42c3d5ab0a19079fa4546d6e6ec449f759c7ba5) and the diagnostics capture above +// (ids ` 1` and ` b5a`). +fn ipmitool_sel_elist_line(record_id_hex: String, date: String, time: String, sensor: String, event: String, state: String) -> String { + let pad = if string_length(s: record_id_hex) >= 4 { "" } else if string_length(s: record_id_hex) == 3 { " " } else if string_length(s: record_id_hex) == 2 { " " } else { " " } + join([pad, record_id_hex, " | ", date, " | ", time, " | ", sensor, " | ", event, " | ", state, "\n"], "") +} + +// `ipmitool raw 0x06 0x52 ...` (Master Write-Read) answering two bytes. NO SMpro exchange with this +// controller is retained in the corpus (gunbc.machine_intake_mtcollins1_smpro_observation witness +// notes), so the spacing is ipmitool's raw-response print as the production decoder's own supplied +// samples spell it, and is carried with that standing. +data ipmitool_raw_two_bytes_standing: CitedFigureStanding = TranscribedUncited { + read_obligation: "a retained stdout of `ipmitool raw 0x06 0x52 2 ` against the Mt. Collins BMC, cited by digest" as NonEmptyStr +} + +fn ipmitool_raw_two_bytes(first_hex: String, second_hex: String) -> String { + join([" ", first_hex, " ", second_hex, "\n"], "") +} diff --git a/dag/gunbc/bmc_dry_realization.dag b/dag/gunbc/bmc_dry_realization.dag index f5b0e17eec9..ffafc952744 100644 --- a/dag/gunbc/bmc_dry_realization.dag +++ b/dag/gunbc/bmc_dry_realization.dag @@ -12,7 +12,14 @@ import extdeps.transports.shell { ShellProcessExited } import extdeps.bmc.ipmi_chassis_control { ipmi_chassis_control_action_of_verb, ipmitool_chassis_status_power_line, ipmitool_chassis_power_control_reply, } -import gunbc.bmc_model { BmcWorld, bmc_chassis_control, bmc_power_is_on, bmc_advance } +import gunbc.bmc_model { + BmcWorld, bmc_chassis_control, bmc_power_is_on, bmc_advance, bmc_with_override, + BootOverrideNone, BootOverrideCdromEfiNextBoot, +} +import extdeps.bmc.ipmitool_observed_output { + ipmitool_bootparam5_no_override, ipmitool_bootparam5_cdrom_efi_next_boot, ipmitool_bootdev_cdrom_reply, + ipmitool_sel_elist_line, +} // THE DRY ADAPTER BETWEEN THE extdeps.bmc INTERFACE AND THE ONE BMC MODEL. For each bound operation // it reads the actual inputs the dispatcher bound, asks gunbc.bmc_model for the transition, and @@ -54,11 +61,46 @@ fn bmc_chassis_power_control_reply(world: BmcWorld, call: OperationCall) -> BmcR Absent => BmcReplyFault { reason: "ChassisPowerControl was dispatched without an action input" as NonEmptyStr } Present { value: verb } => match ipmi_chassis_control_action_of_verb(verb: verb) { Absent => BmcReplyFault { reason: join(["ChassisPowerControl action `", verb, "` names no IPMI chassis control action the model carries"], "") as NonEmptyStr } - Present { value: action } => BmcReplied { stdout: ipmitool_chassis_power_control_reply(action: action), world: bmc_chassis_control(world: world, action: action).world } + Present { value: action } => BmcReplied { stdout: ipmitool_chassis_power_control_reply(action: action), world: bmc_chassis_control(world: world, action: action, now: call.now).world } + } + } +} + +fn input_is(call: OperationCall, name: String, expected: String) -> Bool { + match operation_input_text(invocation: call.invocation, name: name) { + Present { value: v } => v == expected + Absent => false + } +} + +fn bmc_bootparam_get_reply(world: BmcWorld, call: OperationCall) -> BmcReply { + if input_is(call: call, name: "parameter", expected: "5") { + BmcReplied { + stdout: match world.boot_override { + BootOverrideNone => ipmitool_bootparam5_no_override + BootOverrideCdromEfiNextBoot => ipmitool_bootparam5_cdrom_efi_next_boot + }, + world: world, } + } else { + BmcReplyFault { reason: "the model answers boot parameter 5 only" as NonEmptyStr } } } +// The override this controller has been observed to take: cdrom, EFI, next boot only. Any other +// device or option set is a request the model does not carry, and it refuses rather than guessing. +fn bmc_bootdev_reply(world: BmcWorld, call: OperationCall) -> BmcReply { + if input_is(call: call, name: "device", expected: "cdrom") && input_is(call: call, name: "options", expected: "efiboot") { + BmcReplied { stdout: ipmitool_bootdev_cdrom_reply, world: bmc_with_override(world: world, over: BootOverrideCdromEfiNextBoot) } + } else { + BmcReplyFault { reason: "the model carries the cdrom boot override with options=efiboot only" as NonEmptyStr } + } +} + +fn bmc_sel_elist_reply(world: BmcWorld, call: OperationCall) -> BmcReply { + BmcReplied { stdout: join(map(world.sel, r => ipmitool_sel_elist_line(record_id_hex: r.id_hex, date: r.date, time: r.time, sensor: r.sensor, event: r.event, state: r.state)), ""), world: world } +} + // One IPMI round trip takes one virtual second. fn bmc_lift(get: fn(S) -> BmcWorld, put: fn(S, BmcWorld) -> S, reply: fn(BmcWorld, OperationCall) -> BmcReply) -> fn(S, OperationCall) -> OperationStep { fn(state, call) { @@ -77,6 +119,10 @@ fn bmc_bindings(get: fn(S) -> BmcWorld, put: fn(S, BmcWorld) -> S) -> List fired: List + boot_override: BmcBootOverride + sel: List + sol_session_open: Bool + cycle_off_interval: Second + host_booted_at: Second? + booted_via_override: Bool +} + +fn bmc_world(power: BmcPower) -> BmcWorld { + BmcWorld { + power: power, pending: [], fired: [], boot_override: BootOverrideNone, sel: [], + sol_session_open: false, cycle_off_interval: second(count: 5), host_booted_at: none, booted_via_override: false, + } } // A COMMAND'S EFFECT AND ITS REPLY ARE SEPARATE FACTS. effect_taken says whether the world changed; -// the reply is the adapter's to render from the new world. §28.3 recommends a controller refuse a -// power cycle at an OFF host with completion code D5h; the Mt. Collins MegaRAC does not, and answers -// success doing nothing (extdeps.bmc.ipmi_chassis_control, run 36023602469). The model follows the -// observed unit, and that departure from the recommendation is the reason the arm exists. +// the reply is the adapter's to render. §28.3 recommends a controller refuse a power cycle at an OFF +// host with completion code D5h; the Mt. Collins MegaRAC does not, and answers success doing nothing +// (extdeps.bmc.ipmi_chassis_control, run 36023602469). The model follows the observed unit, and that +// departure from the recommendation is the reason the arm exists. type BmcChassisControlStep { world: BmcWorld effect_taken: Bool @@ -56,31 +88,81 @@ fn bmc_power_is_on(world: BmcWorld) -> Bool { } fn bmc_with_power(world: BmcWorld, power: BmcPower) -> BmcWorld { - BmcWorld { power: power, pending: world.pending, fired: world.fired } + BmcWorld { + power: power, pending: world.pending, fired: world.fired, boot_override: world.boot_override, sel: world.sel, + sol_session_open: world.sol_session_open, cycle_off_interval: world.cycle_off_interval, + host_booted_at: world.host_booted_at, booted_via_override: world.booted_via_override, + } +} + +fn bmc_with_override(world: BmcWorld, over: BmcBootOverride) -> BmcWorld { + BmcWorld { + power: world.power, pending: world.pending, fired: world.fired, boot_override: over, sel: world.sel, + sol_session_open: world.sol_session_open, cycle_off_interval: world.cycle_off_interval, + host_booted_at: world.host_booted_at, booted_via_override: world.booted_via_override, + } +} + +fn bmc_with_sol_session(world: BmcWorld, open: Bool) -> BmcWorld { + BmcWorld { + power: world.power, pending: world.pending, fired: world.fired, boot_override: world.boot_override, sel: world.sel, + sol_session_open: open, cycle_off_interval: world.cycle_off_interval, + host_booted_at: world.host_booted_at, booted_via_override: world.booted_via_override, + } +} + +fn bmc_with_pending(world: BmcWorld, pending: List, fired: List) -> BmcWorld { + BmcWorld { + power: world.power, pending: pending, fired: fired, boot_override: world.boot_override, sel: world.sel, + sol_session_open: world.sol_session_open, cycle_off_interval: world.cycle_off_interval, + host_booted_at: world.host_booted_at, booted_via_override: world.booted_via_override, + } +} + +// The host starts booting now: power is on, the boot is timed from here, and a pending next-boot +// override is consumed by it. +fn bmc_host_boots(world: BmcWorld, now: Second) -> BmcWorld { + let via = match world.boot_override { BootOverrideCdromEfiNextBoot => true BootOverrideNone => false } + BmcWorld { + power: BmcPowerOn, pending: world.pending, fired: world.fired, boot_override: BootOverrideNone, sel: world.sel, + sol_session_open: world.sol_session_open, cycle_off_interval: world.cycle_off_interval, + host_booted_at: Present { value: now }, booted_via_override: via, + } } -fn bmc_chassis_control(world: BmcWorld, action: IpmiChassisControlAction) -> BmcChassisControlStep { +fn bmc_chassis_control(world: BmcWorld, action: IpmiChassisControlAction, now: Second) -> BmcChassisControlStep { match action { - IpmiChassisPowerUp => BmcChassisControlStep { world: bmc_with_power(world: world, power: BmcPowerOn), effect_taken: !bmc_power_is_on(world: world) } + IpmiChassisPowerUp => + if bmc_power_is_on(world: world) { BmcChassisControlStep { world: world, effect_taken: false } } + else { BmcChassisControlStep { world: bmc_host_boots(world: world, now: now), effect_taken: true } } IpmiChassisPowerDown => BmcChassisControlStep { world: bmc_with_power(world: world, power: BmcPowerOff), effect_taken: bmc_power_is_on(world: world) } - IpmiChassisPowerCycle => BmcChassisControlStep { world: world, effect_taken: bmc_power_is_on(world: world) } - IpmiChassisHardReset => BmcChassisControlStep { world: world, effect_taken: bmc_power_is_on(world: world) } + IpmiChassisPowerCycle => + if bmc_power_is_on(world: world) { + let off = bmc_with_power(world: world, power: BmcPowerOff) + let restore = BmcScheduledEvent { at: second(count: second_count(s: now) + second_count(s: world.cycle_off_interval)), event: BmcPowerRestored } + BmcChassisControlStep { world: bmc_with_pending(world: off, pending: list_append(off.pending, restore), fired: off.fired), effect_taken: true } + } else { BmcChassisControlStep { world: world, effect_taken: false } } + IpmiChassisHardReset => + if bmc_power_is_on(world: world) { BmcChassisControlStep { world: bmc_host_boots(world: world, now: now), effect_taken: true } } + else { BmcChassisControlStep { world: world, effect_taken: false } } } } -fn bmc_apply_event(world: BmcWorld, event: BmcEvent) -> BmcWorld { +fn bmc_apply_event(world: BmcWorld, event: BmcEvent, at: Second) -> BmcWorld { match event { - BmcAcPowerLost {} => bmc_with_power(world: world, power: BmcPowerOff) + BmcAcPowerLost => bmc_with_power(world: world, power: BmcPowerOff) + BmcPowerRestored => bmc_host_boots(world: world, now: at) } } // Every event due at or before `now` fires, in schedule order, and moves from pending to fired. fn bmc_advance(world: BmcWorld, now: Second) -> BmcWorld { - fold(world.pending, init: BmcWorld { power: world.power, pending: [], fired: world.fired }, f: fn(acc, e) { + fold(world.pending, init: bmc_with_pending(world: world, pending: [], fired: world.fired), f: fn(acc, e) { if second_count(s: e.at) <= second_count(s: now) { - BmcWorld { power: bmc_apply_event(world: acc, event: e.event).power, pending: acc.pending, fired: list_append(acc.fired, e) } + let applied = bmc_apply_event(world: acc, event: e.event, at: e.at) + bmc_with_pending(world: applied, pending: acc.pending, fired: list_append(acc.fired, e)) } else { - BmcWorld { power: acc.power, pending: list_append(acc.pending, e), fired: acc.fired } + bmc_with_pending(world: acc, pending: list_append(acc.pending, e), fired: acc.fired) } }) } diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag index fe043da3884..8ca9bf3fed5 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag @@ -1,26 +1,34 @@ module gunbc.machine_intake_mtcollins1_boot_dry_realization -import std.types { List, NonEmptyStr, String } -import std.measure { Second } -import v2.std.operation_realization { OperationRealization, virtual_delay_binding } -import gunbc.bmc_model { BmcWorld, bmc_advance } -import gunbc.bmc_dry_realization { bmc_bindings, sleep_delay_seconds_operation } -import gunbc.filesystem_model { ModeledFilesystem, filesystem_bindings } +import std.types { Bool, Int, List, NonEmptyStr, String } +import std.measure { Second, second, second_count } +import v2.std.operation_argv { OperationRef } +import v2.std.operation_realization { + OperationRealization, OperationBinding, OperationCall, OperationStep, + OperationObserved, OperationHarnessFault, ShellObserved, + virtual_delay_binding, operation_input_text, +} +import gunbc.bmc_model { BmcWorld, bmc_advance, bmc_with_sol_session, bmc_power_is_on } +import gunbc.bmc_dry_realization { bmc_bindings, bmc_ipmi_operation, sleep_delay_seconds_operation } +import gunbc.filesystem_model { ModeledFilesystem, ModeledFile, filesystem_bindings, fs_with_file, fs_file, fs_write } import gunbc.process_environment_model { ModeledVariable, environment_binding } import gunbc.host_command_model { ModeledInvocation, exact_invocation_binding, local_command_words, shell_exec_run_argv_operation } import extdeps.transports.shell { ShellExchangeObservation, ShellProcessExited } import extdeps.exec.command { env_prefixed_command } import extdeps.tools.env { EnvSet } import extdeps.ssh.openssh_client_commands { ssh_add_list_identities_command } +import extdeps.bmc.ipmitool_observed_output { ipmitool_sol_activate_preamble } import gunbc.fleet_ssh_access { fleet_automation_ssh_key_fingerprint } import gunbc.remote_host_model { ModeledRemoteHost, remote_host_binding } import gunbc.wall_clock_model { ModeledWallClock, wall_clock_bindings } // THE DRY REALIZATION OF ONE mtcollins1 BOOT ATTEMPT'S WHOLE EFFECT DEMAND. The scenario world -// composes the one BMC model with the worker's filesystem (credential file, unit-hold store, SOL pid -// and capture files) and its process environment (credential path, SOL paths, run and revision -// identity). Every transition belongs to its own model; this module only places them side by side and -// lifts their bindings into the composite state. The real entry -- +// composes the one BMC model with what the worker running the attempt has around it: its filesystem +// (credential file, unit-hold store, SOL pid and capture files, /proc), its processes, its process +// environment, its SSH agent, the hosts it reaches over SSH, its clocks, and the host's console. Every +// transition belongs to its own model; this module places them side by side, lifts their bindings into +// the composite state, and owns only the handlers whose effect spans two of them (a collector the BMC +// session feeds and the worker's filesystem records). The real entry -- // gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 -- runs unchanged over it. type MtCollins1BootWorld { bmc: BmcWorld @@ -29,6 +37,8 @@ type MtCollins1BootWorld { agent: ModeledSshAgent remote_hosts: List clock: ModeledWallClock + worker: ModeledWorker + console: ModeledHostConsole } // THE WORKER'S SSH AGENT: whether it holds the fleet automation key. Its listing follows @@ -47,28 +57,210 @@ fn agent_listing(agent: ModeledSshAgent) -> ShellExchangeObservation { } } -fn boot_world_with_bmc(w: MtCollins1BootWorld, bmc: BmcWorld) -> MtCollins1BootWorld { - MtCollins1BootWorld { bmc: bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock } +// THE WORKER'S PROCESSES that the attempt starts: today, the SOL collector. A live process is visible +// the way the production liveness check reads it -- /proc//cmdline -- and a dead one is not. The +// model writes cmdline with spaces between arguments where Linux writes NULs; the production reader +// asks only whether it contains `ipmitool`, which both spellings answer the same way. +type ModeledProcess { + pid: Int + cmdline: String + capture_path: String + alive: Bool +} + +type ModeledWorker { + next_pid: Int + processes: List + uptime_at_origin: Int +} + +// THE HOST'S CONSOLE: what the machine prints on its serial line, each line at an offset from the +// start of the boot. A line reaches a capture only while the BMC's SOL session is open and a live +// collector appends it; a line printed while nobody is listening is lost, as it is on the real unit. +// emitted counts the lines of the current boot already printed. +type TimedConsoleLine { + after: Second + text: String +} + +type ModeledHostConsole { + lines: List + emitted: Int + boot: Second? +} + +fn with_bmc(w: MtCollins1BootWorld, bmc: BmcWorld) -> MtCollins1BootWorld { + MtCollins1BootWorld { bmc: bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console } +} + +fn with_fs(w: MtCollins1BootWorld, fs: ModeledFilesystem) -> MtCollins1BootWorld { + MtCollins1BootWorld { bmc: w.bmc, fs: fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console } +} + +fn with_worker(w: MtCollins1BootWorld, worker: ModeledWorker) -> MtCollins1BootWorld { + MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: worker, console: w.console } +} + +fn with_console(w: MtCollins1BootWorld, console: ModeledHostConsole) -> MtCollins1BootWorld { + MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: console } +} + +fn appended(fs: ModeledFilesystem, path: String, text: String) -> ModeledFilesystem { + match fs_file(fs: fs, path: path) { + Present { value: f } => fs_with_file(fs: fs, path: path, content: concat(f.content, text)) + Absent => fs_with_file(fs: fs, path: path, content: text) + } +} + +fn proc_cmdline_path(pid: Int) -> String { + join(["/proc/", to_string(pid), "/cmdline"], "") +} + +fn live_collectors(w: MtCollins1BootWorld) -> List { + filter(w.worker.processes, p => p.alive) +} + +fn exited_step(state: S, stdout: String, exit_code: Int) -> OperationStep { + OperationObserved { observation: ShellObserved { observation: ShellProcessExited { exit_code: exit_code, stdout: stdout, stderr: "" } }, state: state, elapsed: second(count: 1) } +} + +// `ipmitool sdr dump ` writes the controller's SDR repository to the named local file; the +// production code checks only that it succeeded and later reads through the file. The model writes a +// placeholder of the dump into the worker's filesystem, so a later read through it finds a file. +fn sdr_dump_handler(w: MtCollins1BootWorld, call: OperationCall) -> OperationStep { + match operation_input_text(invocation: call.invocation, name: "sdr_cache_file") { + Absent => OperationHarnessFault { reason: "sdr dump was dispatched without a cache file" as NonEmptyStr } + Present { value: path } => { + let written = fs_write(fs: w.fs, path: path, content: "", create_new: false) + exited_step(state: with_fs(w: w, fs: written.fs), stdout: join(["Dumping Sensor Data Repository to '", path, "'\n"], ""), exit_code: 0) + } + } +} + +// gunbc.machine_intake.sol_hold ActivateHeld: a shell starts `ipmitool ... sol activate` in the +// background with its output appended to the capture, records its pid in the pid file, and exits 0 once +// the background job exists. The collector then opens the BMC's SOL session. If the session is already +// held by another client, the real client prints the refusal and exits at once -- but the shell has +// already succeeded and written the pid, exactly as here. +fn sol_activate_held_handler(w: MtCollins1BootWorld, call: OperationCall) -> OperationStep { + match operation_input_text(invocation: call.invocation, name: "capture_path") { + Absent => OperationHarnessFault { reason: "ActivateHeld was dispatched without a capture path" as NonEmptyStr } + Present { value: capture } => match operation_input_text(invocation: call.invocation, name: "pid_path") { + Absent => OperationHarnessFault { reason: "ActivateHeld was dispatched without a pid path" as NonEmptyStr } + Present { value: pid_path } => { + let pid = w.worker.next_pid + let program = match operation_input_text(invocation: call.invocation, name: "ipmitool") { Present { value: p } => p Absent => "ipmitool" } + let already = w.bmc.sol_session_open + let process = ModeledProcess { pid: pid, cmdline: concat(program, " -H bmc -I lanplus sol activate"), capture_path: capture, alive: !already } + let fs1 = fs_write(fs: w.fs, path: pid_path, content: concat(to_string(pid), "\n"), create_new: false).fs + let fs2 = if already { appended(fs: fs1, path: capture, text: "Info: SOL payload already active on another session\n") } + else { fs_with_file(fs: appended(fs: fs1, path: capture, text: ipmitool_sol_activate_preamble), path: proc_cmdline_path(pid: pid), content: process.cmdline) } + let worker = ModeledWorker { next_pid: pid + 1, processes: list_append(w.worker.processes, process), uptime_at_origin: w.worker.uptime_at_origin } + let bmc = if already { w.bmc } else { bmc_with_sol_session(world: w.bmc, open: true) } + exited_step(state: with_bmc(w: with_worker(w: with_fs(w: w, fs: fs2), worker: worker), bmc: bmc), stdout: "", exit_code: 0) + } + } + } +} + +// `ipmitool sol deactivate` ends the BMC's SOL session; a collector attached to it loses its session +// and exits, so its /proc entry disappears. Its pid file is NOT removed -- nothing in the realization +// removes it -- which is exactly what the production teardown observes afterwards. +fn sol_deactivate_handler(w: MtCollins1BootWorld, call: OperationCall) -> OperationStep { + let fs = fold(live_collectors(w: w), init: w.fs, f: fn(acc, p) { + ModeledFilesystem { directories: acc.directories, files: filter(acc.files, f => f.path != proc_cmdline_path(pid: p.pid)) } + }) + let worker = ModeledWorker { next_pid: w.worker.next_pid, processes: map(w.worker.processes, p => ModeledProcess { pid: p.pid, cmdline: p.cmdline, capture_path: p.capture_path, alive: false }), uptime_at_origin: w.worker.uptime_at_origin } + exited_step(state: with_bmc(w: with_worker(w: with_fs(w: w, fs: fs), worker: worker), bmc: bmc_with_sol_session(world: w.bmc, open: false)), stdout: "", exit_code: 0) +} + +// Master Write-Read toward the SMpro. The retained attempt of 2026-09-27 (run 36335369059, +// mtcollins1-boot-diagnostics.txt sha256 eda19cde2e60d90d3d04946273e615eb5bf774496b9907e03d3bc15dbedc2c1c) recorded +// every probe refused with completion code 0xff, and no successful exchange is retained, so that is the +// grounded answer the model gives. The production code records SMpro passes and never gates on them. +fn smpro_refused_handler(w: MtCollins1BootWorld, call: OperationCall) -> OperationStep { + OperationObserved { + observation: ShellObserved { observation: ShellProcessExited { exit_code: 1, stdout: "", stderr: "Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0 cmd=0x52 rsp=0xff): Unspecified error\n" } }, + state: w, + elapsed: second(count: 1), + } +} + +// /proc/uptime: the worker's seconds since its own boot, `. ` (proc(5)). +data linux_procfs_read_uptime_operation: OperationRef = OperationRef { + path: "dag/extdeps/linux/procfs.dag", + service: "linux.Procfs", + operation: "ReadUptime", +} + +fn uptime_handler(w: MtCollins1BootWorld, call: OperationCall) -> OperationStep { + let up = w.worker.uptime_at_origin + (second_count(s: call.now) as Int) + OperationObserved { + observation: ShellObserved { observation: ShellProcessExited { exit_code: 0, stdout: join([to_string(up), ".00 ", to_string(up), ".00\n"], ""), stderr: "" } }, + state: w, + elapsed: second(count: 0), + } +} + +// THE CONSOLE ADVANCES WITH TIME. After the BMC's own events fire, every console line of the current +// boot whose offset has passed is printed; it reaches each live collector's capture only if the SOL +// session is open. A new boot restarts the console from its first line. +fn console_advance(w: MtCollins1BootWorld, now: Second) -> MtCollins1BootWorld { + match w.bmc.host_booted_at { + Absent => w + Present { value: booted } => { + let fresh = match w.console.boot { Present { value: b } => second_count(s: b) != second_count(s: booted) Absent => true } + let console = if fresh { ModeledHostConsole { lines: w.console.lines, emitted: 0, boot: Present { value: booted } } } else { w.console } + let elapsed = (second_count(s: now) as Int) - (second_count(s: booted) as Int) + let due = filter(console.lines.skip(n: console.emitted), l => (second_count(s: l.after) as Int) <= elapsed) + let printed = concat_text(lines: due) + let listening = w.bmc.sol_session_open && bmc_power_is_on(world: w.bmc) + let fs = if listening { fold(live_collectors(w: w), init: w.fs, f: fn(acc, p) { appended(fs: acc, path: p.capture_path, text: printed) }) } else { w.fs } + with_console(w: with_fs(w: w, fs: fs), console: ModeledHostConsole { lines: console.lines, emitted: console.emitted + count(due), boot: console.boot }) + } + } +} + +fn concat_text(lines: List) -> String { + join(map(lines, l => concat(l.text, "\n")), "") +} + +fn boot_advance(w: MtCollins1BootWorld, now: Second) -> MtCollins1BootWorld { + console_advance(w: with_bmc(w: w, bmc: bmc_advance(world: w.bmc, now: now)), now: now) } -fn boot_world_with_fs(w: MtCollins1BootWorld, fs: ModeledFilesystem) -> MtCollins1BootWorld { - MtCollins1BootWorld { bmc: w.bmc, fs: fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock } +data sol_hold_activate_held_operation: OperationRef = OperationRef { + path: "dag/gunbc/machine_intake/sol_hold.dag", + service: "gunbc.machine_intake.sol_hold", + operation: "ActivateHeld", } fn mtcollins1_boot_dry_realization(identity: NonEmptyStr, initial: MtCollins1BootWorld, epoch: Second) -> OperationRealization { - let bmc = bmc_bindings(get: fn(w) { w.bmc }, put: boot_world_with_bmc) - let files = filesystem_bindings(get: fn(w) { w.fs }, put: boot_world_with_fs) + let bmc = bmc_bindings(get: fn(w) { w.bmc }, put: with_bmc) + let files = filesystem_bindings(get: fn(w) { w.fs }, put: with_fs) let local_commands = exact_invocation_binding(at: shell_exec_run_argv_operation, inputs: ["program", "arguments"], table: [ ModeledInvocation { words: local_command_words(command: env_prefixed_command(bindings: [EnvSet { name: "SSH_AUTH_SOCK", value: initial.agent.socket }], command: ssh_add_list_identities_command())), answer: fn(w) { agent_listing(agent: w.agent) }, }, ]) + let spanning = [ + OperationBinding { at: bmc_ipmi_operation(operation: "SdrDumpAuthenticated"), handler: sdr_dump_handler }, + OperationBinding { at: bmc_ipmi_operation(operation: "SolDeactivate"), handler: sol_deactivate_handler }, + OperationBinding { at: bmc_ipmi_operation(operation: "MasterWriteReadAuthenticated"), handler: smpro_refused_handler }, + OperationBinding { at: sol_hold_activate_held_operation, handler: sol_activate_held_handler }, + OperationBinding { at: linux_procfs_read_uptime_operation, handler: uptime_handler }, + ] OperationRealization { identity: identity, initial: initial, epoch: epoch, - bindings: concat(concat(concat(bmc, files), wall_clock_bindings(get: fn(w) { w.clock })), [environment_binding(get: fn(w) { w.environment }), virtual_delay_binding(at: sleep_delay_seconds_operation, seconds_input: "seconds"), local_commands, remote_host_binding(get: fn(w) { w.remote_hosts })]), - advance: fn(w, now) { boot_world_with_bmc(w: w, bmc: bmc_advance(world: w.bmc, now: now)) }, + bindings: concat(concat(concat(concat(bmc, files), wall_clock_bindings(get: fn(w) { w.clock })), spanning), [ + environment_binding(get: fn(w) { w.environment }), + virtual_delay_binding(at: sleep_delay_seconds_operation, seconds_input: "seconds"), + local_commands, + remote_host_binding(get: fn(w) { w.remote_hosts }), + ]), + advance: boot_advance, } } diff --git a/dag/test/claim/operation_realization_witness_test.dag b/dag/test/claim/operation_realization_witness_test.dag index 74a36efc63c..52237a01a27 100644 --- a/dag/test/claim/operation_realization_witness_test.dag +++ b/dag/test/claim/operation_realization_witness_test.dag @@ -31,6 +31,7 @@ import extdeps.bmc.ipmi_chassis_control { import gunbc.machine_intake_oob_boot_handoff { read_chassis_power } import gunbc.bmc_model { BmcWorld, BmcPowerOn, BmcPowerOff, BmcScheduledEvent, BmcAcPowerLost, bmc_power_is_on, + bmc_world, bmc_with_pending, bmc_with_power, } import gunbc.bmc_dry_realization { bmc_dry_realization, bmc_ipmi_operation, bmc_chassis_power_control_handler, @@ -71,7 +72,7 @@ fn modeled_frame(realization: OperationRealization) -> WitnessEvaluati } fn world(power_on: Bool) -> BmcWorld { - BmcWorld { power: if power_on { BmcPowerOn } else { BmcPowerOff }, pending: [], fired: [] } + bmc_world(power: if power_on { BmcPowerOn } else { BmcPowerOff }) } fn read_power() -> ChassisPowerObservation { @@ -202,7 +203,7 @@ fn loss_fired_and_none_pending(w: BmcWorld) -> Bool { // (t 0 -> 1), sleeps five seconds through the production sleep helper (t 1 -> 6), and reads again. The // loss fired during the sleep with no operation issued at t=3, and the second read observes it. test fn a_scheduled_event_fires_during_a_quiet_wait() -> Bool { - let initial = BmcWorld { power: BmcPowerOn, pending: [BmcScheduledEvent { at: second(count: 3), event: BmcAcPowerLost {} }], fired: [] } + let initial = bmc_with_pending(world: bmc_world(power: BmcPowerOn), pending: [BmcScheduledEvent { at: second(count: 3), event: BmcAcPowerLost }], fired: []) let result = evaluate_in_witness_frame( frame: modeled_frame(realization: bmc_dry_realization(identity: realization_identity, initial: initial, epoch: virtual_clock_origin())), subject: fn(_scope) { @@ -307,7 +308,7 @@ test fn a_binding_to_an_undeclared_identity_refuses_before_the_subject_runs() -> // witness is the supervisor: it resumes a SECOND attempt from that world in a new frame, and the // resumed attempt reads before it writes and finds the host already on. fn killed_after_power_on(state: BmcWorld, call: OperationCall) -> OperationStep { - OperationWorkerKilled { committed: true, state: BmcWorld { power: BmcPowerOn, pending: state.pending, fired: state.fired } } + OperationWorkerKilled { committed: true, state: bmc_with_power(world: state, power: BmcPowerOn) } } test fn a_killed_worker_is_interrupted_and_a_resumed_attempt_reconciles() -> Bool { @@ -523,7 +524,7 @@ test fn frames_are_independent_after_the_outer_scope_ends() -> Bool { // fires) and reads off, exactly as the uninterrupted history does. Had the resume restarted at the // origin its reads would complete at 1 and the loss would not yet have fired. fn loss_at_five() -> BmcWorld { - BmcWorld { power: BmcPowerOn, pending: [BmcScheduledEvent { at: second(count: 5), event: BmcAcPowerLost {} }], fired: [] } + bmc_with_pending(world: bmc_world(power: BmcPowerOn), pending: [BmcScheduledEvent { at: second(count: 5), event: BmcAcPowerLost }], fired: []) } fn killed_without_commit(state: BmcWorld, call: OperationCall) -> OperationStep { From a712a75f0f228e0ff67743206d1d1b46f6c78e89 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Mon, 28 Sep 2026 10:30:17 +0000 Subject: [PATCH 07/75] MegaRAC media model + adapter; mtcollins1 boot acceptance matrix over the real entry (deadline refusal, pinned SOL-teardown defect, held-unit contender) Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/extdeps/bmc/megarac_observed_output.dag | 73 +++++ dag/gunbc/bmc_dry_realization.dag | 110 ++++++- .../mtcollins1_boot_dry_realization.dag | 20 +- dag/gunbc/megarac_media_model.dag | 138 +++++++++ ...mtcollins1_boot_acceptance_matrix_test.dag | 275 ++++++++++++++++++ 5 files changed, 608 insertions(+), 8 deletions(-) create mode 100644 dag/extdeps/bmc/megarac_observed_output.dag create mode 100644 dag/gunbc/megarac_media_model.dag create mode 100644 dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag diff --git a/dag/extdeps/bmc/megarac_observed_output.dag b/dag/extdeps/bmc/megarac_observed_output.dag new file mode 100644 index 00000000000..6633306a62b --- /dev/null +++ b/dag/extdeps/bmc/megarac_observed_output.dag @@ -0,0 +1,73 @@ +module extdeps.bmc.megarac_observed_output + +import std.types { Int, NonEmptyStr, String } +import extdeps.external_authority { ExternalAuthority, CitedFigureStanding, TranscribedUncited } +import extdeps.uri { Uri, Https } + +data extdeps_external_authority_anchor: ExternalAuthority = ExternalAuthority { + uri: Uri { + scheme: Https + locator: "www.ami.com/megarac/" + } +} + +// WHAT THE Mt. Collins MegaRAC (firmware 0.32) ANSWERS ON ITS MEDIA REST ROUTES, as observed. Each +// renderer reproduces a retained body's key order and spelling, with the fields a scenario varies +// substituted; its source is cited beside it. A body no retained exchange carries says so in its +// standing -- the production decoder reads only the members named there, and the rest of the body is +// the firmware's form as far as it has been read. + +// GET /api/settings/media/general. Source: test.claim.machine_intake.megarac_media_convergence_witness_test +// mtcollins1_media_general_2026_09_27, a read-only GET at 2026-09-27T18:37:18Z after boot run 36330382023, +// verbatim, with the share, mount and CD error code as parameters. The firmware escapes `/` as `\/`. +fn megarac_media_general_body(server: String, source_path: String, share_type: String, mount_cd: Int, cd_error_code: Int) -> String { + join([ + "{ \"id\": 1, \"local_media_support\": 0, \"remote_media_support\": 1, \"same_settings\": 0, \"cd_remote_server_address\": \"", server, + "\", \"cd_remote_source_path\": \"", json_escaped_slashes(s: source_path), + "\", \"cd_remote_share_type\": \"", share_type, + "\", \"cd_remote_domain_name\": \"\", \"cd_remote_user_name\": \"\", \"mount_cd\": ", to_string(mount_cd), + ", \"cd_image_name\": \"\", \"cd_error_code\": ", to_string(cd_error_code), + ", \"mount_hd\": 0, \"hd_remote_server_address\": \"\", \"hd_remote_source_path\": \"\", \"hd_remote_share_type\": \"\", \"hd_remote_domain_name\": \"\", \"hd_remote_user_name\": \"\", \"hd_image_name\": \"\", \"hd_error_code\": 0, \"rmedia_retry_count\": 3, \"rmedia_retry_interval\": 15 }", + ], "") +} + +fn json_escaped_slashes(s: String) -> String { + join(split(s: s, delimiter: "/"), "\\/") +} + +// One row of GET /api/settings/media/remote/configurations. Source: the cleared row retained in +// test.claim.machine_intake.megarac_media_convergence_witness_test +// (`[{"media_type":1,"image_name":"","redirection_status":0,"media_index":0,"session_index":255}]`), +// with the image, status and indices as parameters. +fn megarac_configuration_row(image_name: String, redirection_status: Int, media_index: Int, session_index: Int) -> String { + join(["{\"media_type\":1,\"image_name\":\"", image_name, "\",\"redirection_status\":", to_string(redirection_status), ",\"media_index\":", to_string(media_index), ",\"session_index\":", to_string(session_index), "}"], "") +} + +// One row of GET /api/settings/media/remote/images. Source: the listing row in the same witness, +// `{"image_name":"","image_index":5}`, with the index the real attach logs report. +fn megarac_image_row(image_name: String, image_index: Int) -> String { + join(["{\"image_name\":\"", image_name, "\",\"image_index\":", to_string(image_index), "}"], "") +} + +// The rejection a route gives a request without a valid session. Source: +// test.claim.machine_intake.megarac_session_release_witness_test, `{"error":"invalid session"}` with 401. +data megarac_invalid_session_body: String = "{\"error\":\"invalid session\"}" + +// POST /api/session. NO SESSION REPLY IS RETAINED VERBATIM. The member names are those the firmware's +// own web UI reads (source.min.js, probed 2026-09-27 on branch session/eager-koi-811), and the production +// decoder reads only CSRFToken. +data megarac_session_body_standing: CitedFigureStanding = TranscribedUncited { + read_obligation: "a retained POST /api/session reply from the Mt. Collins MegaRAC, cited by digest" as NonEmptyStr +} + +fn megarac_session_body(racsession_id: Int, csrf_token: String) -> String { + join(["{ \"ok\": 0, \"privilege\": 4, \"extendedpriv\": 259, \"racsession_id\": ", to_string(racsession_id), ", \"CSRFToken\": \"", csrf_token, "\" }"], "") +} + +// The replies to start-media, stop-media and DELETE /api/session on success are not decoded by the +// production code (readiness and re-observation decide), and none is retained verbatim. +data megarac_write_ack_body_standing: CitedFigureStanding = TranscribedUncited { + read_obligation: "retained 200 bodies of start-media, stop-media and DELETE /api/session from the Mt. Collins MegaRAC, cited by digest" as NonEmptyStr +} + +data megarac_write_ack_body: String = "{}" diff --git a/dag/gunbc/bmc_dry_realization.dag b/dag/gunbc/bmc_dry_realization.dag index ffafc952744..914b446b6ef 100644 --- a/dag/gunbc/bmc_dry_realization.dag +++ b/dag/gunbc/bmc_dry_realization.dag @@ -1,6 +1,6 @@ module gunbc.bmc_dry_realization -import std.types { Bool, List, NonEmptyStr, String } +import std.types { Bool, Int, List, NonEmptyStr, String } import std.measure { Second, second } import v2.std.operation_argv { OperationRef } import v2.std.operation_realization { @@ -16,6 +16,16 @@ import gunbc.bmc_model { BmcWorld, bmc_chassis_control, bmc_power_is_on, bmc_advance, bmc_with_override, BootOverrideNone, BootOverrideCdromEfiNextBoot, } +import gunbc.megarac_media_model { + MegaRacMediaWorld, megarac_session_valid, megarac_open_session, megarac_close_session, + megarac_start_media, megarac_stop_media, +} +import extdeps.bmc.megarac_observed_output { + megarac_media_general_body, megarac_configuration_row, megarac_image_row, megarac_invalid_session_body, + megarac_session_body, megarac_write_ack_body, +} +import extdeps.languages.json.parse { parse_json_document, JsonDocumentParsed, JsonDocumentUnreadable } +import gunbc.machine_intake_megarac_media_attach { json_string_member, json_number_member } import extdeps.bmc.ipmitool_observed_output { ipmitool_bootparam5_no_override, ipmitool_bootparam5_cdrom_efi_next_boot, ipmitool_bootdev_cdrom_reply, ipmitool_sel_elist_line, @@ -143,3 +153,101 @@ fn bmc_dry_realization(identity: NonEmptyStr, initial: BmcWorld, epoch: Second) advance: bmc_advance, } } + +// THE MEGARAC MEDIA ROUTES, answered over the media model as curl --fail-with-body sees them: a +// request with a valid session gets the firmware's body and exit 0; one without gets the 401 body on +// stdout, curl's own error line on stderr, and exit 22 (curl(1), --fail-with-body). The session probe's +// `-w "\n%{http_code}"` appends the status line. One request takes one virtual second. +data megarac_operation_path: String = "dag/extdeps/bmc/megarac.dag" + +fn megarac_operation(operation: String) -> OperationRef { + OperationRef { path: megarac_operation_path, service: "megarac.Media", operation: operation } +} + +fn curl_answer(state: S, exit_code: Int, stdout: String, stderr: String) -> OperationStep { + OperationObserved { observation: ShellObserved { observation: ShellProcessExited { exit_code: exit_code, stdout: stdout, stderr: stderr } }, state: state, elapsed: second(count: 1) } +} + +fn curl_refused_401(state: S, with_status_line: Bool) -> OperationStep { + curl_answer(state: state, exit_code: 22, stdout: if with_status_line { concat(megarac_invalid_session_body, "\n401") } else { megarac_invalid_session_body }, stderr: "curl: (22) The requested URL returned error: 401\n") +} + +fn call_text(call: OperationCall, name: String) -> String { + match operation_input_text(invocation: call.invocation, name: name) { Present { value: v } => v Absent => "" } +} + +fn megarac_configurations_body(media: MegaRacMediaWorld) -> String { + concat("[", concat(megarac_configuration_row(image_name: media.cd.image_name, redirection_status: media.cd.redirection_status, media_index: media.cd.media_index, session_index: media.cd.session_index), "]")) +} + +fn megarac_images_body(media: MegaRacMediaWorld) -> String { + concat("[", concat(join(map(media.images, i => megarac_image_row(image_name: i.image_name, image_index: i.image_index)), ","), "]")) +} + +fn megarac_authenticated(get: fn(S) -> MegaRacMediaWorld, render: fn(S, OperationCall) -> OperationStep) -> fn(S, OperationCall) -> OperationStep { + fn(state, call) { + if megarac_session_valid(world: get(state), cookie_jar: call_text(call: call, name: "cookie_jar"), csrf_token: call_text(call: call, name: "csrf_token")) { + render(state, call) + } else { + curl_refused_401(state: state, with_status_line: false) + } + } +} + +// The start and stop bodies are the production builders' JSON; the model reads them with the same +// member readers the production decoders use (gunbc.machine_intake_megarac_media_attach). +fn body_member_text(call: OperationCall, key: String) -> String? { + match parse_json_document(s: call_text(call: call, name: "json_body")) { + JsonDocumentParsed { value: doc } => json_string_member(doc: doc, key: key) + JsonDocumentUnreadable { gap: _ } => none + } +} + +fn body_member_int(call: OperationCall, key: String) -> Int? { + match parse_json_document(s: call_text(call: call, name: "json_body")) { + JsonDocumentParsed { value: doc } => match json_number_member(doc: doc, key: key) { + Present { value: n } => parse_int(s: n) + Absent => none + } + JsonDocumentUnreadable { gap: _ } => none + } +} + +fn megarac_bindings(get: fn(S) -> MegaRacMediaWorld, put: fn(S, MegaRacMediaWorld) -> S) -> List> { + [ + OperationBinding { at: megarac_operation(operation: "OpenSession"), handler: fn(state, call) { + let opened = megarac_open_session(world: get(state), cookie_jar: call_text(call: call, name: "cookie_jar")) + curl_answer(state: put(state, opened.world), exit_code: 0, stdout: megarac_session_body(racsession_id: opened.racsession_id, csrf_token: opened.csrf_token), stderr: "") + } }, + OperationBinding { at: megarac_operation(operation: "ProbeSessionOnMediaRoute"), handler: fn(state, call) { + if megarac_session_valid(world: get(state), cookie_jar: call_text(call: call, name: "cookie_jar"), csrf_token: call_text(call: call, name: "csrf_token")) { + curl_answer(state: state, exit_code: 0, stdout: concat(megarac_configurations_body(media: get(state)), "\n200"), stderr: "") + } else { curl_refused_401(state: state, with_status_line: true) } + } }, + OperationBinding { at: megarac_operation(operation: "GetMediaGeneral"), handler: megarac_authenticated(get: get, render: fn(state, call) { + let m = get(state) + curl_answer(state: state, exit_code: 0, stdout: megarac_media_general_body(server: m.share.server, source_path: m.share.source_path, share_type: m.share.share_type, mount_cd: m.mount_cd, cd_error_code: m.cd_error_code), stderr: "") + }) }, + OperationBinding { at: megarac_operation(operation: "GetRemoteConfigurations"), handler: megarac_authenticated(get: get, render: fn(state, call) { + curl_answer(state: state, exit_code: 0, stdout: megarac_configurations_body(media: get(state)), stderr: "") + }) }, + OperationBinding { at: megarac_operation(operation: "GetRemoteImages"), handler: megarac_authenticated(get: get, render: fn(state, call) { + curl_answer(state: state, exit_code: 0, stdout: megarac_images_body(media: get(state)), stderr: "") + }) }, + OperationBinding { at: megarac_operation(operation: "StartMedia"), handler: megarac_authenticated(get: get, render: fn(state, call) { + match body_member_text(call: call, key: "image_name") { + Absent => OperationHarnessFault { reason: "start-media was dispatched without a readable image_name" as NonEmptyStr } + Present { value: name } => match body_member_int(call: call, key: "image_index") { + Absent => OperationHarnessFault { reason: "start-media was dispatched without a readable image_index" as NonEmptyStr } + Present { value: idx } => curl_answer(state: put(state, megarac_start_media(world: get(state), image_name: name, image_index: idx, now: call.now)), exit_code: 0, stdout: megarac_write_ack_body, stderr: "") + } + } + }) }, + OperationBinding { at: megarac_operation(operation: "StopMedia"), handler: megarac_authenticated(get: get, render: fn(state, call) { + curl_answer(state: put(state, megarac_stop_media(world: get(state))), exit_code: 0, stdout: megarac_write_ack_body, stderr: "") + }) }, + OperationBinding { at: megarac_operation(operation: "CloseSession"), handler: megarac_authenticated(get: get, render: fn(state, call) { + curl_answer(state: put(state, megarac_close_session(world: get(state), cookie_jar: call_text(call: call, name: "cookie_jar"), csrf_token: call_text(call: call, name: "csrf_token"))), exit_code: 0, stdout: megarac_write_ack_body, stderr: "") + }) }, + ] +} diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag index 8ca9bf3fed5..bcaeb2e703f 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag @@ -9,7 +9,8 @@ import v2.std.operation_realization { virtual_delay_binding, operation_input_text, } import gunbc.bmc_model { BmcWorld, bmc_advance, bmc_with_sol_session, bmc_power_is_on } -import gunbc.bmc_dry_realization { bmc_bindings, bmc_ipmi_operation, sleep_delay_seconds_operation } +import gunbc.bmc_dry_realization { bmc_bindings, megarac_bindings, bmc_ipmi_operation, sleep_delay_seconds_operation } +import gunbc.megarac_media_model { MegaRacMediaWorld, megarac_media_advance } import gunbc.filesystem_model { ModeledFilesystem, ModeledFile, filesystem_bindings, fs_with_file, fs_file, fs_write } import gunbc.process_environment_model { ModeledVariable, environment_binding } import gunbc.host_command_model { ModeledInvocation, exact_invocation_binding, local_command_words, shell_exec_run_argv_operation } @@ -39,6 +40,7 @@ type MtCollins1BootWorld { clock: ModeledWallClock worker: ModeledWorker console: ModeledHostConsole + media: MegaRacMediaWorld } // THE WORKER'S SSH AGENT: whether it holds the fleet automation key. Its listing follows @@ -90,19 +92,23 @@ type ModeledHostConsole { } fn with_bmc(w: MtCollins1BootWorld, bmc: BmcWorld) -> MtCollins1BootWorld { - MtCollins1BootWorld { bmc: bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console } + MtCollins1BootWorld { bmc: bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: w.media } } fn with_fs(w: MtCollins1BootWorld, fs: ModeledFilesystem) -> MtCollins1BootWorld { - MtCollins1BootWorld { bmc: w.bmc, fs: fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console } + MtCollins1BootWorld { bmc: w.bmc, fs: fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: w.media } } fn with_worker(w: MtCollins1BootWorld, worker: ModeledWorker) -> MtCollins1BootWorld { - MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: worker, console: w.console } + MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: worker, console: w.console, media: w.media } } fn with_console(w: MtCollins1BootWorld, console: ModeledHostConsole) -> MtCollins1BootWorld { - MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: console } + MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: console, media: w.media } +} + +fn with_media(w: MtCollins1BootWorld, media: MegaRacMediaWorld) -> MtCollins1BootWorld { + MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: media } } fn appended(fs: ModeledFilesystem, path: String, text: String) -> ModeledFilesystem { @@ -226,7 +232,7 @@ fn concat_text(lines: List) -> String { } fn boot_advance(w: MtCollins1BootWorld, now: Second) -> MtCollins1BootWorld { - console_advance(w: with_bmc(w: w, bmc: bmc_advance(world: w.bmc, now: now)), now: now) + console_advance(w: with_media(w: with_bmc(w: w, bmc: bmc_advance(world: w.bmc, now: now)), media: megarac_media_advance(world: w.media, now: now)), now: now) } data sol_hold_activate_held_operation: OperationRef = OperationRef { @@ -236,7 +242,7 @@ data sol_hold_activate_held_operation: OperationRef = OperationRef { } fn mtcollins1_boot_dry_realization(identity: NonEmptyStr, initial: MtCollins1BootWorld, epoch: Second) -> OperationRealization { - let bmc = bmc_bindings(get: fn(w) { w.bmc }, put: with_bmc) + let bmc = concat(bmc_bindings(get: fn(w) { w.bmc }, put: with_bmc), megarac_bindings(get: fn(w) { w.media }, put: with_media)) let files = filesystem_bindings(get: fn(w) { w.fs }, put: with_fs) let local_commands = exact_invocation_binding(at: shell_exec_run_argv_operation, inputs: ["program", "arguments"], table: [ ModeledInvocation { diff --git a/dag/gunbc/megarac_media_model.dag b/dag/gunbc/megarac_media_model.dag new file mode 100644 index 00000000000..9a777506c8f --- /dev/null +++ b/dag/gunbc/megarac_media_model.dag @@ -0,0 +1,138 @@ +module gunbc.megarac_media_model + +import std.types { Bool, Int, List, String } +import std.measure { Second, second, second_count } + +// THE BMC's VIRTUAL-MEDIA SUBSYSTEM (AMI MegaRAC SP-X, firmware 0.32): the same controller as +// gunbc.bmc_model, held as its own record because its state -- web sessions, the NFS share binding, +// the image listing and the presented CD -- moves independently of power and IPMI. Pure transitions +// with time as an input; the wire shapes are extdeps.bmc.megarac and extdeps.bmc.megarac_observed_output. +// +// SESSIONS. POST /api/session opens a session the client holds through its cookie jar and a CSRF +// token; every other route needs both. DELETE /api/session closes it, after which the same cookie and +// token are refused with 401 -- the property the production release check re-observes. +type MegaRacSession { + cookie_jar: String + csrf_token: String + open: Bool +} + +type MegaRacShare { + server: String + source_path: String + share_type: String +} + +// THE PRESENTED CD, as one configurations row. redirection_status on this firmware: 0 stopped, 100 +// connecting, 1 started (extdeps.bmc.megarac). A start moves the row to connecting and, after the +// readiness delay, to started with a bound session index; session index 255 means no session. +// ready_at is when a connecting row becomes started. +type MegaRacCdRow { + image_name: String + redirection_status: Int + media_index: Int + session_index: Int + ready_at: Second? +} + +type MegaRacImage { + image_name: String + image_index: Int +} + +// ready_after is the controller's connecting interval. Observed 2026-09-27 (gunbc.machine_intake_megarac_media_attach +// readiness notes): status 100 at +6s, then 1 with session index 0 from +12s. +type MegaRacMediaWorld { + sessions: List + next_session: Int + share: MegaRacShare + mount_cd: Int + cd_error_code: Int + images: List + cd: MegaRacCdRow + ready_after: Second +} + +fn megarac_cleared_cd() -> MegaRacCdRow { + MegaRacCdRow { image_name: "", redirection_status: 0, media_index: 0, session_index: 255, ready_at: none } +} + +fn megarac_session_valid(world: MegaRacMediaWorld, cookie_jar: String, csrf_token: String) -> Bool { + !all(world.sessions, s => !(s.open && s.cookie_jar == cookie_jar && s.csrf_token == csrf_token)) +} + +fn megarac_session_by_jar(world: MegaRacMediaWorld, cookie_jar: String) -> Bool { + !all(world.sessions, s => !(s.open && s.cookie_jar == cookie_jar)) +} + +fn megarac_with_sessions(world: MegaRacMediaWorld, sessions: List, next_session: Int) -> MegaRacMediaWorld { + MegaRacMediaWorld { sessions: sessions, next_session: next_session, share: world.share, mount_cd: world.mount_cd, cd_error_code: world.cd_error_code, images: world.images, cd: world.cd, ready_after: world.ready_after } +} + +fn megarac_with_cd(world: MegaRacMediaWorld, cd: MegaRacCdRow) -> MegaRacMediaWorld { + MegaRacMediaWorld { sessions: world.sessions, next_session: world.next_session, share: world.share, mount_cd: world.mount_cd, cd_error_code: world.cd_error_code, images: world.images, cd: cd, ready_after: world.ready_after } +} + +type MegaRacOpened { + world: MegaRacMediaWorld + racsession_id: Int + csrf_token: String +} + +fn megarac_open_session(world: MegaRacMediaWorld, cookie_jar: String) -> MegaRacOpened { + let id = world.next_session + let token = concat("modeled-csrf-", to_string(id)) + MegaRacOpened { + world: megarac_with_sessions(world: world, sessions: list_append(world.sessions, MegaRacSession { cookie_jar: cookie_jar, csrf_token: token, open: true }), next_session: id + 1), + racsession_id: id, + csrf_token: token, + } +} + +fn megarac_close_session(world: MegaRacMediaWorld, cookie_jar: String, csrf_token: String) -> MegaRacMediaWorld { + megarac_with_sessions( + world: world, + sessions: map(world.sessions, s => if s.cookie_jar == cookie_jar && s.csrf_token == csrf_token { MegaRacSession { cookie_jar: s.cookie_jar, csrf_token: s.csrf_token, open: false } } else { s }), + next_session: world.next_session, + ) +} + +fn megarac_image_index(world: MegaRacMediaWorld, image_name: String) -> Int? { + fold(world.images, init: none, f: fn(acc, i) { + match acc { + Present { value: v } => Present { value: v } + Absent => if i.image_name == image_name { Present { value: i.image_index } } else { none } + } + }) +} + +// A start names an image and its listing index. The row connects, and becomes started after the +// connecting interval. A start naming an image the listing does not hold changes nothing; whether the +// firmware answers such a start with an error body is not observed, so the adapter reports the write as +// accepted and readiness -- which the production code waits on -- never arrives. +fn megarac_start_media(world: MegaRacMediaWorld, image_name: String, image_index: Int, now: Second) -> MegaRacMediaWorld { + match megarac_image_index(world: world, image_name: image_name) { + Present { value: idx } => + if idx == image_index { + megarac_with_cd(world: world, cd: MegaRacCdRow { + image_name: image_name, redirection_status: 100, media_index: 0, session_index: 255, + ready_at: Present { value: second(count: second_count(s: now) + second_count(s: world.ready_after)) }, + }) + } else { world } + Absent => world + } +} + +fn megarac_stop_media(world: MegaRacMediaWorld) -> MegaRacMediaWorld { + megarac_with_cd(world: world, cd: megarac_cleared_cd()) +} + +fn megarac_media_advance(world: MegaRacMediaWorld, now: Second) -> MegaRacMediaWorld { + match world.cd.ready_at { + Absent => world + Present { value: at } => + if second_count(s: at) <= second_count(s: now) { + megarac_with_cd(world: world, cd: MegaRacCdRow { image_name: world.cd.image_name, redirection_status: 1, media_index: world.cd.media_index, session_index: 0, ready_at: none }) + } else { world } + } +} diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag new file mode 100644 index 00000000000..23d5c5c7db6 --- /dev/null +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -0,0 +1,275 @@ +module test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test + +import std.types { Bool, Int, List, NonEmptyStr, String } +import std.measure { Second, second } +import std.materialization_ladder { Frame, SharedStateFrame } +import std.effect_grant { Read, Write, ServiceOpTree, NamespacePosition, ModeledRealization, LifecycleByConstruction, Grant, Envelope } +import v2.std.operation_argv { InputText, InputTextList } +import v2.std.operation_realization { DispatchRecord, virtual_clock_origin } +import v2.std.witness_evaluation { + WitnessEvaluation, WitnessEvaluationFrame, WitnessReturned, WitnessRefused, WitnessInterrupted, + evaluate_in_witness_frame, witness_diagnostic_rendered_reason, +} +import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } +import gunbc.bmc_model { BmcWorld, BmcPowerOff, bmc_world } +import gunbc.filesystem_model { ModeledFilesystem, ModeledFile } +import gunbc.process_environment_model { ModeledVariable } +import gunbc.remote_host_model { ModeledRemoteHost, ModeledRemoteFile } +import gunbc.wall_clock_model { ModeledWallClock } +import gunbc.megarac_media_model { MegaRacMediaWorld, MegaRacShare, MegaRacImage, megarac_cleared_cd } +import gunbc.machine_intake_mtcollins1_boot_dry_realization { + MtCollins1BootWorld, ModeledSshAgent, ModeledWorker, ModeledHostConsole, TimedConsoleLine, + mtcollins1_boot_dry_realization, +} +import gunbc.machine_intake_mtcollins1_boot_run { + MtCollins1BootAttempt, mtcollins1_boot_wet_on_srv1, mtcollins1_boot_exit_reason, + ActuationNotPoweredOn, ActuationPoweredOn, ActuationCensusEnded, +} +import gunbc.machine_intake_mtcollins1_boot_authorization { mtcollins1_boot_medium, mtcollins1_boot_medium_image_name, MtCollins1CensusMedium } +import gunbc.machine_intake_mtcollins1_census_image { mtcollins1_census_image, Mtcollins1CensusImageDerived } +import gunbc.machine_intake_mtcollins1_census_medium_readback { mtcollins1_census_record_path, mtcollins1_census_medium_served_path } +import gunbc.durable_exclusive_hold_file_store { file_hold_acquire } +import gunbc.machine_intake_mtcollins1_maintenance_hold { boot_run_owner, unit_hold_store_root, mtcollins1_unit_hold_key } + +data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly + +// THE mtcollins1 BOOT ACCEPTANCE MATRIX (gunbc#12423, operator ruling 2026-09-27). Every case runs THE +// REAL ENTRY -- gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1, unchanged -- over +// a dry realization of its whole effect demand (gunbc.machine_intake_mtcollins1_boot_dry_realization): +// the one BMC model, its virtual-media subsystem, the worker's filesystem, processes, environment and +// clocks, the SSH agent and srv2. Nothing in the orchestrator is replaced. Each case asserts the ROUTE +// the dispatcher logged -- which effects, in what order, under which hold -- and the typed outcome. +// +// EVIDENCE BOUNDARY, for every case here: the deepest real layer is the orchestration and every +// production decoder above the transport observation; the first substituted layer is the transport +// observation. None of these cases is evidence about what the physical controller, the ipmitool or +// curl clients, the SOL collector process or the host firmware do -- those are the companion transport +// controls and live acceptance -- and every modeled answer is grounded where the corpus retains one +// (extdeps.bmc.ipmitool_observed_output, extdeps.bmc.megarac_observed_output). +data realization_identity: NonEmptyStr = "mtcollins1-boot-matrix" as NonEmptyStr + +data credential_path: String = "/run/bmc-credential" + +data sol_capture_path: String = "/run/sol.capture" + +data sol_pid_path: String = "/run/sol.pid" + +fn grant(service: String, verb: std.effect_grant.Verb) -> Grant { + Grant { verb: verb, root: NamespacePosition { tree: ServiceOpTree { service: service }, path: [] }, binding: ModeledRealization { realization: realization_identity as String }, lifecycle: LifecycleByConstruction } +} + +// The services the entry's effect demand reaches, each granted to the dry realization for reading and +// writing. An operation of any other service refuses as uncovered. +data matrix_services: List = [ + "diagnostic.ipmi.Tool", "megarac.Media", "Filesystem", "shell.Env", "sleep.Delay", + "gunbc.machine_intake.sol_hold", "shell.Exec", "ssh.Session", "Clock", "linux.Procfs", +] + +fn matrix_frame(world: MtCollins1BootWorld) -> WitnessEvaluationFrame { + WitnessEvaluationFrame { + envelope: Envelope { + frame: Frame { name: "mtcollins1-boot-matrix", kind: SharedStateFrame } + grants: concat(map(matrix_services, s => grant(service: s, verb: Read)), map(matrix_services, s => grant(service: s, verb: Write))) + } + rest_fixtures: [] + realization: Present { value: mtcollins1_boot_dry_realization(identity: realization_identity, initial: world, epoch: virtual_clock_origin()) } + } +} + +fn run_attempt(world: MtCollins1BootWorld) -> WitnessEvaluation { + evaluate_in_witness_frame(frame: matrix_frame(world: world), subject: fn(_scope) { mtcollins1_boot_wet_on_srv1() }) +} + +// ─── THE HEALTHY WORLD, and the facts it is built from ─────────────────────────────────────────── +fn selected_digest() -> String { + match mtcollins1_boot_medium { + MtCollins1CensusMedium { output_digest: d } => d as String + _ => "" + } +} + +fn healthy_srv2() -> ModeledRemoteHost { + ModeledRemoteHost { endpoint: "srv2", files: match mtcollins1_census_image { + Mtcollins1CensusImageDerived { input: input } => [ + ModeledRemoteFile { path: mtcollins1_census_record_path(input: input) as String, content: Present { value: concat(selected_digest(), "\n") }, sha256: none }, + ModeledRemoteFile { path: mtcollins1_census_medium_served_path(medium: mtcollins1_boot_medium) as String, content: Present { value: "" }, sha256: Present { value: selected_digest() } }, + ] + _ => [] + } } +} + +fn healthy_media() -> MegaRacMediaWorld { + MegaRacMediaWorld { + sessions: [], next_session: 1, + share: MegaRacShare { server: "192.168.1.188", source_path: "/srv/bmc", share_type: "nfs" }, + mount_cd: 1, cd_error_code: 0, + images: [MegaRacImage { image_name: mtcollins1_boot_medium_image_name(medium: mtcollins1_boot_medium) as String, image_index: 5 }], + cd: megarac_cleared_cd(), + ready_after: second(count: 12), + } +} + +fn worker_filesystem() -> ModeledFilesystem { + ModeledFilesystem { + directories: ["target", "/", "/run", "/proc", "/var", "/var/lib", "/var/lib/gunbc", unit_hold_store_root as String], + files: [ModeledFile { path: credential_path, content: "secret" }], + } +} + +fn world_with_console(lines: List) -> MtCollins1BootWorld { + MtCollins1BootWorld { + bmc: bmc_world(power: BmcPowerOff), + fs: worker_filesystem(), + environment: [ + ModeledVariable { name: "GUNBC_HOST_RESET_BMC_CREDENTIAL_FILE", value: credential_path }, + ModeledVariable { name: "GUNBC_MTCOLLINS1_SOL_CAPTURE", value: sol_capture_path }, + ModeledVariable { name: "GUNBC_MTCOLLINS1_SOL_PID_FILE", value: sol_pid_path }, + ModeledVariable { name: "GITHUB_RUN_ID", value: "4242" }, + ModeledVariable { name: "SSH_AUTH_SOCK", value: "/run/ssh-agent.sock" }, + ModeledVariable { name: "GITHUB_SHA", value: "0123456789abcdef0123456789abcdef01234567" }, + ], + agent: ModeledSshAgent { socket: "/run/ssh-agent.sock", holds_fleet_key: true }, + remote_hosts: [healthy_srv2()], + clock: ModeledWallClock { unix_at_origin: 1790000000, step_seconds: 0 }, + worker: ModeledWorker { next_pid: 4000, processes: [], uptime_at_origin: 86400 }, + console: ModeledHostConsole { lines: lines, emitted: 0, boot: none }, + media: healthy_media(), + } +} + +// A census image that boots one socket and completes: the capture test.claim.machine_intake.mtcollins1_boot_run_witness_test +// `clean` shows reaching TerminalAccepted, printed a minute into the boot and closed at four minutes. +data one_socket_census_capture: String = "=====GUNBC-HOST-CAPTURE mtcollins1 attempt=1 begin 2026-09-18T00:00:00Z=====\n----SECTION boot-media----\n----ARGV boot-media: ls -l /dev/disk/by-label; blkid\nLABEL=\"GUNBC_MTC1_CENSUS_2404_3\"\n----EXIT boot-media: 0\n----SECTION nproc----\n----ARGV nproc: nproc\n80\n----EXIT nproc: 0\n----SECTION numa----\n----ARGV numa: cat /sys/devices/system/node/online; numactl -H\n0\navailable: 1 nodes (0)\nnode 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79\nnode 0 size: 255937 MB\nnode 0 free: 250112 MB\n----EXIT numa: 0\n----SECTION edac-before----\n----ARGV edac-before: (counters)\n== /sys/devices/system/edac/mc/mc0/ce_count == 0\n== /sys/devices/system/edac/mc/mc0/ue_count == 0\n----EXIT edac-before: 0\n----SECTION workload----\n----ARGV workload: (the rendered workload command)\nworkload-bytes=4294967296\nworkload-shm-avail-bytes=8373932032\nworkload-mem-available-bytes=15032385536\nworkload-preflight=fits\nworkload-write-rc=0\nworkload-digest-stable=yes\n----EXIT workload: 0\n----SECTION edac-after----\n----ARGV edac-after: (counters)\n== /sys/devices/system/edac/mc/mc0/ce_count == 0\n== /sys/devices/system/edac/mc/mc0/ue_count == 0\n----EXIT edac-after: 0\n=====GUNBC-HOST-CAPTURE mtcollins1 attempt=1 end 2026-09-18T00:04:00Z=====" + +fn console_of(capture: String, begin_after: Int, end_after: Int) -> List { + map(filter(split(s: capture, delimiter: "\n"), l => l != ""), l => TimedConsoleLine { + after: second(count: if starts_with(s: l, prefix: "=====GUNBC-HOST-CAPTURE mtcollins1 attempt=1 end") { end_after } else { begin_after }), + text: l, + }) +} + +// ─── ROUTE READING ───────────────────────────────────────────────────────────────────────────── +fn operation_name(r: DispatchRecord) -> String { + join([r.invocation.at.service, ".", r.invocation.at.operation], "") +} + +fn record_path(r: DispatchRecord) -> String { + fold(r.invocation.bindings, init: "", f: fn(acc, b) { + if acc != "" { acc } else if b.name == "path" { match b.value { InputText { text: t } => t InputTextList { items: _ } => "" } } else { "" } + }) +} + +fn is_hold_write(r: DispatchRecord) -> Bool { + r.invocation.at.service == "Filesystem" && starts_with(s: r.invocation.at.operation, prefix: "WriteCreateNew") + && starts_with(s: record_path(r: r), prefix: unit_hold_store_root as String) +} + +// The effects that change the controller or start a process against it. +data controller_writes: List = [ + "diagnostic.ipmi.Tool.ChassisPowerControl", "diagnostic.ipmi.Tool.ChassisBootDevWithOptions", + "megarac.Media.StartMedia", "megarac.Media.StopMedia", "diagnostic.ipmi.Tool.SolDeactivate", + "gunbc.machine_intake.sol_hold.ActivateHeld", +] + +fn is_controller_write(r: DispatchRecord) -> Bool { + !all(controller_writes, w => w != operation_name(r: r)) +} + +fn ordinals_where(route: List, keep: fn(DispatchRecord) -> Bool) -> List { + map(filter(route, r => keep(r)), r => r.ordinal) +} + +fn count_named(route: List, name: String) -> Int { + count(filter(route, r => operation_name(r: r) == name)) +} + +// EVERY CONTROLLER WRITE HAPPENS UNDER THE UNIT HOLD: after the hold's first commit and before its +// last (the release). The hold writes are the only WriteCreateNew calls under the hold root. +fn controller_writes_are_under_the_hold(route: List) -> Bool { + let holds = ordinals_where(route: route, keep: is_hold_write) + let writes = ordinals_where(route: route, keep: is_controller_write) + match holds.first() { + Absent => count(writes) == 0 + Present { value: acquired } => match holds.last() { + Absent => false + Present { value: released } => count(holds) >= 2 && all(writes, o => o > acquired && o < released) + } + } +} + +fn first_ordinal(route: List, name: String) -> Int { + match ordinals_where(route: route, keep: fn(r) { operation_name(r: r) == name }).first() { Present { value: o } => o Absent => 0 - 1 } +} + +fn outcome_reason(a: MtCollins1BootAttempt) -> String { + mtcollins1_boot_exit_reason(outcome: a.outcome) +} + +fn census_ended(a: MtCollins1BootAttempt) -> Bool { + match a.stage { + ActuationCensusEnded { selection: _, smpro_power_on: _, smpro_census: _ } => true + _ => false + } +} + +// ─── CASES ─────────────────────────────────────────────────────────────────────────────────────── + +// THE HOST NEVER PRINTS A CENSUS. The attempt goes all the way through -- media converged and ready, +// cdrom override set, power on -- and refuses at the terminal deadline with exactly the outcome the +// real attempt of 2026-09-27 recorded (run 36335369059). Route: the collector is started before any +// other controller write; the media start precedes the boot override, which precedes the one power +// action; every controller write is under the hold; the collector is torn down last. +test fn a_host_that_never_prints_a_census_refuses_at_the_deadline() -> Bool { + match run_attempt(world: world_with_console(lines: [])) { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "deadline reached without a host-capture terminal") + && count_named(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") == 1 + && count_named(route: route, name: "gunbc.machine_intake.sol_hold.ActivateHeld") == 1 + && first_ordinal(route: route, name: "gunbc.machine_intake.sol_hold.ActivateHeld") < first_ordinal(route: route, name: "megarac.Media.StartMedia") + && first_ordinal(route: route, name: "megarac.Media.StartMedia") < first_ordinal(route: route, name: "diagnostic.ipmi.Tool.ChassisBootDevWithOptions") + && first_ordinal(route: route, name: "diagnostic.ipmi.Tool.ChassisBootDevWithOptions") < first_ordinal(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") + && controller_writes_are_under_the_hold(route: route) + _ => false + } +} + +// A HEALTHY HOST CANNOT CURRENTLY REPORT SUCCESS. PINNED DEFECT, found by this matrix: the census +// closes and is accepted (the stage is ActuationCensusEnded), and the attempt still refuses at the SOL +// teardown, because after `sol deactivate` the collector exits and nothing removes its pid file, which +// the re-observation then reads as stale (gunbc.machine_intake_mtcollins1_boot_run +// mtcollins1_boot_release_sol). This case asserts TODAY'S behaviour so the defect stays visible; when +// the teardown is repaired it must FLIP to ExitSuccess, and that flip is the repair landing. +test fn pinned_a_healthy_census_is_refused_at_the_sol_teardown() -> Bool { + match run_attempt(world: world_with_console(lines: console_of(capture: one_socket_census_capture, begin_after: 60, end_after: 240))) { + WitnessReturned { value, route } => + census_ended(a: value) + && outcome_reason(a: value) == "refused: mtcollins1 boot: SOL pid file stale after deactivate" + && count_named(route: route, name: "diagnostic.ipmi.Tool.SolDeactivate") == 1 + && controller_writes_are_under_the_hold(route: route) + _ => false + } +} + +// THE SAME UNIT HELD BY ANOTHER RUN. Before this attempt starts, a different run's boot holds the +// unit (acquired through the production file_hold_acquire, into the same store). This attempt is +// refused at the hold with the controller untouched: no controller write of any kind appears in its +// route, and it never starts a SOL collector. +test fn a_second_run_for_a_held_unit_writes_nothing_to_the_controller() -> Bool { + let prior = evaluate_in_witness_frame( + frame: matrix_frame(world: world_with_console(lines: [])), + subject: fn(_scope) { file_hold_acquire(root: unit_hold_store_root, slot_key: mtcollins1_unit_hold_key, requested_owner: boot_run_owner(run_id: "4141" as NonEmptyStr)) } + ) + match prior { + WitnessReturned { state } => match state { + Absent => false + Present { value: held } => match run_attempt(world: held) { + WitnessReturned { value, route } => + starts_with(s: outcome_reason(a: value), prefix: "refused:") + && count(filter(route, r => is_controller_write(r: r))) == 0 + && count_named(route: route, name: "gunbc.machine_intake.sol_hold.ActivateHeld") == 0 + _ => false + } + } + _ => false + } +} From cb2f3b1dc7d92c0ef722e9ae6c734d687baaf57c Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Mon, 28 Sep 2026 11:44:04 +0000 Subject: [PATCH 08/75] Matrix: media, observation, resource and interruption cases asserting each case's own cause; media withdrawal and SOL-drop events Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/gunbc/bmc_model.dag | 4 + .../mtcollins1_boot_dry_realization.dag | 15 +- dag/gunbc/megarac_media_model.dag | 33 ++- ...mtcollins1_boot_acceptance_matrix_test.dag | 251 +++++++++++++++++- 4 files changed, 294 insertions(+), 9 deletions(-) diff --git a/dag/gunbc/bmc_model.dag b/dag/gunbc/bmc_model.dag index 1d52544a61a..0d36446aa05 100644 --- a/dag/gunbc/bmc_model.dag +++ b/dag/gunbc/bmc_model.dag @@ -26,11 +26,14 @@ type BmcBootOverride // An event the world undergoes on its own, independent of any request. AC loss is grounded in the // Mt. Collins SEL (run 36335369059, mtcollins1-boot-diagnostics.txt sha256 // eda19cde2e60d90d3d04946273e615eb5bf774496b9907e03d3bc15dbedc2c1c: `Power Unit ChassisPwrStatus | AC lost`). +// A dropped SOL session is the controller ending the serial session on its own, which the 2026-09-27 +// incident (gunbc#12423) recorded as a loss mid-boot while the management interface kept answering. // A power restore is the second half of a power cycle: the controller drops power, and after the // scenario's off interval brings it back, so a read taken inside the interval sees it off. type BmcEvent = BmcAcPowerLost | BmcPowerRestored + | BmcSolSessionDropped type BmcScheduledEvent { at: Second @@ -152,6 +155,7 @@ fn bmc_apply_event(world: BmcWorld, event: BmcEvent, at: Second) -> BmcWorld { match event { BmcAcPowerLost => bmc_with_power(world: world, power: BmcPowerOff) BmcPowerRestored => bmc_host_boots(world: world, now: at) + BmcSolSessionDropped => bmc_with_sol_session(world: world, open: false) } } diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag index bcaeb2e703f..1fbd1389723 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag @@ -231,8 +231,21 @@ fn concat_text(lines: List) -> String { join(map(lines, l => concat(l.text, "\n")), "") } +// A COLLECTOR LIVES ONLY WHILE ITS SESSION DOES. When the controller's SOL session ends -- on its own +// or by a deactivate -- the `ipmitool sol activate` client loses its session and exits, so its /proc +// entry disappears; its pid file stays, since nothing in the realization removes it. +fn collectors_follow_session(w: MtCollins1BootWorld) -> MtCollins1BootWorld { + if w.bmc.sol_session_open { w } else { + let fs = fold(live_collectors(w: w), init: w.fs, f: fn(acc, p) { + ModeledFilesystem { directories: acc.directories, files: filter(acc.files, f => f.path != proc_cmdline_path(pid: p.pid)) } + }) + with_worker(w: with_fs(w: w, fs: fs), worker: ModeledWorker { next_pid: w.worker.next_pid, processes: map(w.worker.processes, p => ModeledProcess { pid: p.pid, cmdline: p.cmdline, capture_path: p.capture_path, alive: false }), uptime_at_origin: w.worker.uptime_at_origin }) + } +} + fn boot_advance(w: MtCollins1BootWorld, now: Second) -> MtCollins1BootWorld { - console_advance(w: with_media(w: with_bmc(w: w, bmc: bmc_advance(world: w.bmc, now: now)), media: megarac_media_advance(world: w.media, now: now)), now: now) + let stepped = with_media(w: with_bmc(w: w, bmc: bmc_advance(world: w.bmc, now: now)), media: megarac_media_advance(world: w.media, now: now)) + console_advance(w: collectors_follow_session(w: stepped), now: now) } data sol_hold_activate_held_operation: OperationRef = OperationRef { diff --git a/dag/gunbc/megarac_media_model.dag b/dag/gunbc/megarac_media_model.dag index 9a777506c8f..3fb72c3a749 100644 --- a/dag/gunbc/megarac_media_model.dag +++ b/dag/gunbc/megarac_media_model.dag @@ -51,6 +51,8 @@ type MegaRacMediaWorld { images: List cd: MegaRacCdRow ready_after: Second + withdraw_at: Second? + withdraw_after_ready: Second? } fn megarac_cleared_cd() -> MegaRacCdRow { @@ -66,11 +68,11 @@ fn megarac_session_by_jar(world: MegaRacMediaWorld, cookie_jar: String) -> Bool } fn megarac_with_sessions(world: MegaRacMediaWorld, sessions: List, next_session: Int) -> MegaRacMediaWorld { - MegaRacMediaWorld { sessions: sessions, next_session: next_session, share: world.share, mount_cd: world.mount_cd, cd_error_code: world.cd_error_code, images: world.images, cd: world.cd, ready_after: world.ready_after } + MegaRacMediaWorld { sessions: sessions, next_session: next_session, share: world.share, mount_cd: world.mount_cd, cd_error_code: world.cd_error_code, images: world.images, cd: world.cd, ready_after: world.ready_after, withdraw_at: world.withdraw_at, withdraw_after_ready: world.withdraw_after_ready } } fn megarac_with_cd(world: MegaRacMediaWorld, cd: MegaRacCdRow) -> MegaRacMediaWorld { - MegaRacMediaWorld { sessions: world.sessions, next_session: world.next_session, share: world.share, mount_cd: world.mount_cd, cd_error_code: world.cd_error_code, images: world.images, cd: cd, ready_after: world.ready_after } + MegaRacMediaWorld { sessions: world.sessions, next_session: world.next_session, share: world.share, mount_cd: world.mount_cd, cd_error_code: world.cd_error_code, images: world.images, cd: cd, ready_after: world.ready_after, withdraw_at: world.withdraw_at, withdraw_after_ready: world.withdraw_after_ready } } type MegaRacOpened { @@ -127,12 +129,37 @@ fn megarac_stop_media(world: MegaRacMediaWorld) -> MegaRacMediaWorld { megarac_with_cd(world: world, cd: megarac_cleared_cd()) } +// A PRESENTATION CAN BE LOST AFTER IT WAS READY: withdraw_at, when set, is the instant the controller +// drops the presented CD on its own (the NFS export going away, the firmware's retry giving up), after +// which the row reads cleared. The production code re-observes the presentation before the handoff for +// exactly this. fn megarac_media_advance(world: MegaRacMediaWorld, now: Second) -> MegaRacMediaWorld { + let readied = megarac_media_ready(world: world, now: now) + match readied.withdraw_at { + Absent => readied + Present { value: at } => + if second_count(s: at) <= second_count(s: now) { + MegaRacMediaWorld { sessions: readied.sessions, next_session: readied.next_session, share: readied.share, mount_cd: readied.mount_cd, cd_error_code: readied.cd_error_code, images: readied.images, cd: megarac_cleared_cd(), ready_after: readied.ready_after, withdraw_at: none, withdraw_after_ready: readied.withdraw_after_ready } + } else { readied } + } +} + +fn megarac_media_ready(world: MegaRacMediaWorld, now: Second) -> MegaRacMediaWorld { match world.cd.ready_at { Absent => world Present { value: at } => if second_count(s: at) <= second_count(s: now) { - megarac_with_cd(world: world, cd: MegaRacCdRow { image_name: world.cd.image_name, redirection_status: 1, media_index: world.cd.media_index, session_index: 0, ready_at: none }) + megarac_withdrawal_armed(world: megarac_with_cd(world: world, cd: MegaRacCdRow { image_name: world.cd.image_name, redirection_status: 1, media_index: world.cd.media_index, session_index: 0, ready_at: none }), ready: at) } else { world } } } + +// A scenario may ask for the presentation to be lost a fixed interval after it became ready; the +// instant is armed when readiness arrives, so the loss follows the route rather than a guessed clock. +fn megarac_withdrawal_armed(world: MegaRacMediaWorld, ready: Second) -> MegaRacMediaWorld { + match world.withdraw_after_ready { + Absent => world + Present { value: after } => + MegaRacMediaWorld { sessions: world.sessions, next_session: world.next_session, share: world.share, mount_cd: world.mount_cd, cd_error_code: world.cd_error_code, images: world.images, cd: world.cd, ready_after: world.ready_after, withdraw_at: Present { value: second(count: second_count(s: ready) + second_count(s: after)) }, withdraw_after_ready: none } + } +} diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index 23d5c5c7db6..a87691a4ae4 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -11,15 +11,19 @@ import v2.std.witness_evaluation { evaluate_in_witness_frame, witness_diagnostic_rendered_reason, } import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } -import gunbc.bmc_model { BmcWorld, BmcPowerOff, bmc_world } +import gunbc.bmc_model { BmcWorld, BmcPowerOff, BmcScheduledEvent, BmcSolSessionDropped, bmc_world, bmc_with_sol_session, bmc_with_pending } import gunbc.filesystem_model { ModeledFilesystem, ModeledFile } import gunbc.process_environment_model { ModeledVariable } import gunbc.remote_host_model { ModeledRemoteHost, ModeledRemoteFile } import gunbc.wall_clock_model { ModeledWallClock } -import gunbc.megarac_media_model { MegaRacMediaWorld, MegaRacShare, MegaRacImage, megarac_cleared_cd } +import gunbc.megarac_media_model { MegaRacMediaWorld, MegaRacShare, MegaRacImage, MegaRacCdRow, megarac_cleared_cd } import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld, ModeledSshAgent, ModeledWorker, ModeledHostConsole, TimedConsoleLine, - mtcollins1_boot_dry_realization, + mtcollins1_boot_dry_realization, with_media, with_bmc, +} +import v2.std.operation_realization { + OperationRealization, OperationBinding, OperationCall, OperationStep, OperationObserved, OperationWorkerKilled, + DispatchWorkerKilled, } import gunbc.machine_intake_mtcollins1_boot_run { MtCollins1BootAttempt, mtcollins1_boot_wet_on_srv1, mtcollins1_boot_exit_reason, @@ -66,13 +70,17 @@ data matrix_services: List = [ ] fn matrix_frame(world: MtCollins1BootWorld) -> WitnessEvaluationFrame { + matrix_frame_over(realization: mtcollins1_boot_dry_realization(identity: realization_identity, initial: world, epoch: virtual_clock_origin())) +} + +fn matrix_frame_over(realization: OperationRealization) -> WitnessEvaluationFrame { WitnessEvaluationFrame { envelope: Envelope { frame: Frame { name: "mtcollins1-boot-matrix", kind: SharedStateFrame } grants: concat(map(matrix_services, s => grant(service: s, verb: Read)), map(matrix_services, s => grant(service: s, verb: Write))) } rest_fixtures: [] - realization: Present { value: mtcollins1_boot_dry_realization(identity: realization_identity, initial: world, epoch: virtual_clock_origin()) } + realization: Present { value: realization } } } @@ -106,6 +114,8 @@ fn healthy_media() -> MegaRacMediaWorld { images: [MegaRacImage { image_name: mtcollins1_boot_medium_image_name(medium: mtcollins1_boot_medium) as String, image_index: 5 }], cd: megarac_cleared_cd(), ready_after: second(count: 12), + withdraw_at: none, + withdraw_after_ready: none, } } @@ -264,7 +274,7 @@ test fn a_second_run_for_a_held_unit_writes_nothing_to_the_controller() -> Bool Absent => false Present { value: held } => match run_attempt(world: held) { WitnessReturned { value, route } => - starts_with(s: outcome_reason(a: value), prefix: "refused:") + string_contains(s: outcome_reason(a: value), pattern: "is held by 'mtcollins1-boot:4141'") && count(filter(route, r => is_controller_write(r: r))) == 0 && count_named(route: route, name: "gunbc.machine_intake.sol_hold.ActivateHeld") == 0 _ => false @@ -273,3 +283,234 @@ test fn a_second_run_for_a_held_unit_writes_nothing_to_the_controller() -> Bool _ => false } } + +// ─── MEDIA VARIATION ─────────────────────────────────────────────────────────────────────────────── +fn media_varied(media: MegaRacMediaWorld) -> MtCollins1BootWorld { + with_media(w: world_with_console(lines: []), media: media) +} + +fn media_with(images: List, share: MegaRacShare, cd: MegaRacCdRow, ready_after: Int, withdraw_after_ready: Second?) -> MegaRacMediaWorld { + MegaRacMediaWorld { + sessions: [], next_session: 1, share: share, mount_cd: 1, cd_error_code: 0, images: images, cd: cd, + ready_after: second(count: ready_after), withdraw_at: none, withdraw_after_ready: withdraw_after_ready, + } +} + +fn no_withdrawal() -> Second? { + none +} + +fn desired_image() -> String { + mtcollins1_boot_medium_image_name(medium: mtcollins1_boot_medium) as String +} + +data real_share: MegaRacShare = MegaRacShare { server: "192.168.1.188", source_path: "/srv/bmc", share_type: "nfs" } + +fn reached_no_power_action(route: List) -> Bool { + count_named(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") == 0 + && count_named(route: route, name: "diagnostic.ipmi.Tool.ChassisBootDevWithOptions") == 0 +} + +// THE IMAGE IS ALREADY PRESENTED AND READY. Convergence has nothing to do: no stop, no start, and the +// attempt proceeds to the boot exactly as from a fresh attach. +test fn an_already_presented_image_is_not_attached_again() -> Bool { + let presented = MegaRacCdRow { image_name: desired_image(), redirection_status: 1, media_index: 0, session_index: 0, ready_at: none } + match run_attempt(world: media_varied(media: media_with(images: [MegaRacImage { image_name: desired_image(), image_index: 5 }], share: real_share, cd: presented, ready_after: 12, withdraw_after_ready: no_withdrawal()))) { + WitnessReturned { value, route } => + count_named(route: route, name: "megarac.Media.StartMedia") == 0 + && count_named(route: route, name: "megarac.Media.StopMedia") == 0 + && count_named(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") == 1 + && controller_writes_are_under_the_hold(route: route) + _ => false + } +} + +// READINESS SLOWER THAN THE WAIT. The controller keeps the row connecting past the readiness budget; +// the attempt refuses without setting the boot override or touching power. +test fn media_that_never_becomes_ready_refuses_before_any_power_action() -> Bool { + match run_attempt(world: media_varied(media: media_with(images: [MegaRacImage { image_name: desired_image(), image_index: 5 }], share: real_share, cd: megarac_cleared_cd(), ready_after: 600, withdraw_after_ready: no_withdrawal()))) { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "did not reach Started with a bound session") + && string_contains(s: outcome_reason(a: value), pattern: "No boot-device or power handoff was made") + && count_named(route: route, name: "megarac.Media.StartMedia") == 1 + && reached_no_power_action(route: route) + _ => false + } +} + +// THE SAME FILENAME ON THE WRONG SHARE. The listing offers an image with the desired name, but the +// controller's CD share is bound to another server. It refuses before any power action; a start, if +// one is issued, must not be followed by the boot. +test fn the_right_filename_on_the_wrong_share_refuses_before_any_power_action() -> Bool { + let wrong = MegaRacShare { server: "192.168.1.99", source_path: "/srv/bmc", share_type: "nfs" } + match run_attempt(world: media_varied(media: media_with(images: [MegaRacImage { image_name: desired_image(), image_index: 5 }], share: wrong, cd: megarac_cleared_cd(), ready_after: 12, withdraw_after_ready: no_withdrawal()))) { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "remote-media share is not this unit's boot share") + && string_contains(s: outcome_reason(a: value), pattern: "observed 192.168.1.99:/srv/bmc") + && count_named(route: route, name: "megarac.Media.StartMedia") == 0 + && reached_no_power_action(route: route) + _ => false + } +} + +// THE LISTING NAMES THE IMAGE TWICE. Taking either row would let the controller's order choose which +// file is attached, so nothing is started and nothing is powered. +test fn a_listing_that_names_the_image_twice_starts_nothing() -> Bool { + let twice = [MegaRacImage { image_name: desired_image(), image_index: 5 }, MegaRacImage { image_name: desired_image(), image_index: 6 }] + match run_attempt(world: media_varied(media: media_with(images: twice, share: real_share, cd: megarac_cleared_cd(), ready_after: 12, withdraw_after_ready: no_withdrawal()))) { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "names the image more than once, so its index is ambiguous") + && count_named(route: route, name: "megarac.Media.StartMedia") == 0 + && reached_no_power_action(route: route) + _ => false + } +} + +// THE PRESENTATION IS LOST FIVE SECONDS AFTER IT BECAME READY: after the attach saw it ready and before +// the handoff. Measured window: a loss 3 to 8 seconds after readiness falls here; 1 second falls between +// two readiness looks (the attach never sees it ready), and 12 seconds or more falls after the handoff. +// The pre-handoff re-observation must see it gone and refuse without the boot override or power. +test fn a_presentation_lost_after_readiness_stops_the_handoff() -> Bool { + match run_attempt(world: media_varied(media: media_with(images: [MegaRacImage { image_name: desired_image(), image_index: 5 }], share: real_share, cd: megarac_cleared_cd(), ready_after: 12, withdraw_after_ready: Present { value: second(count: 5) }))) { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "pre-handoff recheck did not admit it") + && count_named(route: route, name: "megarac.Media.StartMedia") == 1 + && reached_no_power_action(route: route) + _ => false + } +} + +// PINNED: A PRESENTATION LOST AFTER THE HANDOFF IS NOT NAMED AS A CAUSE. Lost twenty seconds after +// readiness -- after the boot override and the power action -- the attempt goes on to the terminal +// deadline and refuses there, and the loss appears only in the recorded after-handoff look. The +// outcome does not say the medium disappeared under the boot (#12423 media: presentation withdrawal). +// When a loss after the handoff becomes a typed cause, this case flips. +test fn pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause() -> Bool { + match run_attempt(world: media_varied(media: media_with(images: [MegaRacImage { image_name: desired_image(), image_index: 5 }], share: real_share, cd: megarac_cleared_cd(), ready_after: 12, withdraw_after_ready: Present { value: second(count: 20) }))) { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "deadline reached without a host-capture terminal") + && count_named(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") == 1 + _ => false + } +} + +// ─── OBSERVATION FAILURES ───────────────────────────────────────────────────────────────────────── + +// ANOTHER CLIENT ALREADY HOLDS THE SOL SESSION. The collector starts and exits at once, so it is not +// held after the settle; the attempt refuses before any other controller write. +test fn a_sol_session_held_elsewhere_refuses_before_the_attach() -> Bool { + let w = world_with_console(lines: []) + match run_attempt(world: with_bmc(w: w, bmc: bmc_with_sol_session(world: w.bmc, open: true))) { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "SOL collector is not held after acquire") + && count_named(route: route, name: "megarac.Media.StartMedia") == 0 + && reached_no_power_action(route: route) + _ => false + } +} + +fn power_on_at(route: List) -> Int { + match filter(route, r => operation_name(r: r) == "diagnostic.ipmi.Tool.ChassisPowerControl").first() { + Present { value: r } => std.measure.second_count(s: r.completed_at) as Int + Absent => 0 - 1 + } +} + +// SOL IS LOST THIRTY SECONDS AFTER POWER-ON WHILE MANAGEMENT KEEPS ANSWERING, and the census would have +// printed at sixty. The drop is scheduled from the baseline route's own power-on instant. PINNED: the +// attempt learns of the loss only at the terminal deadline -- the capture stops growing and the watch +// polls to its bound -- so the first loss is not reported before the deadline (#12423 asks that it is). +// When loss detection lands this case must flip to an early, typed refusal. +test fn pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline() -> Bool { + let console = console_of(capture: one_socket_census_capture, begin_after: 60, end_after: 240) + match run_attempt(world: world_with_console(lines: console)) { + WitnessReturned { route: baseline } => { + let drop_at = power_on_at(route: baseline) + 30 + let w = world_with_console(lines: console) + match std.checked_arithmetic.checked_int_to_nat(n: drop_at) { + Absent => false + Present { value: drop_count } => { + let dropping = with_bmc(w: w, bmc: bmc_with_pending(world: w.bmc, pending: [BmcScheduledEvent { at: second(count: drop_count), event: BmcSolSessionDropped }], fired: [])) + match run_attempt(world: dropping) { + WitnessReturned { value, route } => + drop_at > 30 + && string_contains(s: outcome_reason(a: value), pattern: "deadline reached without a host-capture terminal") + && count_named(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") == 1 + _ => false + } + } + } + } + _ => false + } +} + +// ─── RESOURCE VARIATION ─────────────────────────────────────────────────────────────────────────── + +// TWO SOCKETS ANSWER. The census reports 160 CPUs over two NUMA nodes; the declared expectation for +// this unit is one socket and 80 CPUs, so the terminal verdict refuses on topology and reports what it +// observed -- the thread count and the per-node placement -- rather than a transport failure. The +// refused terminal is reported at the powered-on stage, not as a census that ended. +data two_socket_census_capture: String = "=====GUNBC-HOST-CAPTURE mtcollins1 attempt=1 begin 2026-09-18T00:00:00Z=====\n----SECTION boot-media----\n----ARGV boot-media: ls -l /dev/disk/by-label; blkid\nLABEL=\"GUNBC_MTC1_CENSUS_2404_3\"\n----EXIT boot-media: 0\n----SECTION nproc----\n----ARGV nproc: nproc\n160\n----EXIT nproc: 0\n----SECTION numa----\n----ARGV numa: cat /sys/devices/system/node/online; numactl -H\n0-1\navailable: 2 nodes (0-1)\nnode 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79\nnode 1 cpus: 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159\n----EXIT numa: 0\n----SECTION edac-before----\n----ARGV edac-before: (counters)\n== /sys/devices/system/edac/mc/mc0/ce_count == 0\n== /sys/devices/system/edac/mc/mc0/ue_count == 0\n----EXIT edac-before: 0\n----SECTION workload----\n----ARGV workload: (the rendered workload command)\nworkload-bytes=4294967296\nworkload-shm-avail-bytes=8373932032\nworkload-mem-available-bytes=15032385536\nworkload-preflight=fits\nworkload-write-rc=0\nworkload-digest-stable=yes\n----EXIT workload: 0\n----SECTION edac-after----\n----ARGV edac-after: (counters)\n== /sys/devices/system/edac/mc/mc0/ce_count == 0\n== /sys/devices/system/edac/mc/mc0/ue_count == 0\n----EXIT edac-after: 0\n=====GUNBC-HOST-CAPTURE mtcollins1 attempt=1 end 2026-09-18T00:04:00Z=====" + +test fn a_two_socket_answer_is_a_truthful_topology_refusal() -> Bool { + match run_attempt(world: world_with_console(lines: console_of(capture: two_socket_census_capture, begin_after: 60, end_after: 240))) { + WitnessReturned { value, route } => + !census_ended(a: value) + && string_contains(s: outcome_reason(a: value), pattern: "nproc observed 160, qualification expects 80") + && string_contains(s: outcome_reason(a: value), pattern: "node 0=80, node 1=80") + && count_named(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") == 1 + _ => false + } +} + +// ─── INTERRUPTION ───────────────────────────────────────────────────────────────────────────────── + +// THE WORKER DIES RIGHT AFTER THE START-MEDIA WRITE COMMITS, before its reply. The realization is the +// matrix's own with that one handler wrapped: the controller takes the start, and the worker is gone. +fn killed_after_start_media(realization: OperationRealization) -> OperationRealization { + OperationRealization { + identity: realization.identity, initial: realization.initial, epoch: realization.epoch, advance: realization.advance, + bindings: map(realization.bindings, b => if b.at.operation == "StartMedia" { + OperationBinding { at: b.at, handler: fn(state, call) { + let inner = b.handler + match inner(state, call) { + OperationObserved { observation: _, state: after, elapsed: _ } => OperationWorkerKilled { committed: true, state: after } + other => other + } + } } + } else { b }), + } +} + +fn as_another_run(w: MtCollins1BootWorld, run_id: String) -> MtCollins1BootWorld { + let env = map(w.environment, v => if v.name == "GITHUB_RUN_ID" { ModeledVariable { name: v.name, value: run_id } } else { v }) + MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: env, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: w.media } +} + +// PINNED: THE NEXT ATTEMPT IS LOCKED OUT BY THE DEAD RUN'S HOLD. The interrupted run never released the +// unit, so a new run finds it held by the dead one and refuses with the controller untouched -- safe, +// but it cannot reconcile: nothing retires a hold whose owner is gone, so every later attempt refuses +// until an operator intervenes (#12423: interrupted operations must be reconciled without undocumented +// preparation). When dead-owner reconciliation lands this case flips. +test fn pinned_an_interrupted_attempt_locks_out_the_next_one() -> Bool { + let realization = killed_after_start_media(realization: mtcollins1_boot_dry_realization(identity: realization_identity, initial: world_with_console(lines: []), epoch: virtual_clock_origin())) + match evaluate_in_witness_frame(frame: matrix_frame_over(realization: realization), subject: fn(_scope) { mtcollins1_boot_wet_on_srv1() }) { + WitnessInterrupted { at, state, now: interrupted_clock } => { + let next = as_another_run(w: state, run_id: "4243") + let resumed = evaluate_in_witness_frame( + frame: matrix_frame_over(realization: mtcollins1_boot_dry_realization(identity: realization_identity, initial: next, epoch: interrupted_clock)), + subject: fn(_scope) { mtcollins1_boot_wet_on_srv1() } + ) + at.invocation.at.operation == "StartMedia" + && match at.outcome { DispatchWorkerKilled { committed: c } => c _ => false } + && match resumed { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "is held by 'mtcollins1-boot:4242'") + && count(filter(route, r => is_controller_write(r: r))) == 0 + _ => false + } + } + _ => false + } +} From 1574a97ef3b911942ff9023af02b799f3c3bb12c Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Mon, 28 Sep 2026 12:03:23 +0000 Subject: [PATCH 09/75] Floor: rename the covering-grant binder and the matrix grant helper (UnimportedBareProvider on 'grant') Co-Authored-By: Claude Opus 5.5 (1M context) --- .../machine_intake/mtcollins1_boot_acceptance_matrix_test.dag | 4 ++-- src/v2/std/operation_realization.dag | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index a87691a4ae4..72881769836 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -58,7 +58,7 @@ data sol_capture_path: String = "/run/sol.capture" data sol_pid_path: String = "/run/sol.pid" -fn grant(service: String, verb: std.effect_grant.Verb) -> Grant { +fn matrix_grant(service: String, verb: std.effect_grant.Verb) -> Grant { Grant { verb: verb, root: NamespacePosition { tree: ServiceOpTree { service: service }, path: [] }, binding: ModeledRealization { realization: realization_identity as String }, lifecycle: LifecycleByConstruction } } @@ -77,7 +77,7 @@ fn matrix_frame_over(realization: OperationRealization) -> WitnessEvaluationFrame { envelope: Envelope { frame: Frame { name: "mtcollins1-boot-matrix", kind: SharedStateFrame } - grants: concat(map(matrix_services, s => grant(service: s, verb: Read)), map(matrix_services, s => grant(service: s, verb: Write))) + grants: concat(map(matrix_services, s => matrix_grant(service: s, verb: Read)), map(matrix_services, s => matrix_grant(service: s, verb: Write))) } rest_fixtures: [] realization: Present { value: realization } diff --git a/src/v2/std/operation_realization.dag b/src/v2/std/operation_realization.dag index 57ea3d906f9..d3b5b37f8b9 100644 --- a/src/v2/std/operation_realization.dag +++ b/src/v2/std/operation_realization.dag @@ -158,7 +158,7 @@ fn operation_handler_selection( let at = invocation.at match covering_grant(env: env, verb: operation_verb(readonly: readonly), target: operation_position(at: at)) { NoCoveringGrant { verb: _, target: _, frame: _ } => OperationHandlerRefused { cause: OperationUncovered { at: at } } - CoveredBy { grant } => match grant.binding { + CoveredBy { grant: covering } => match covering.binding { ModeledRealization { realization: named } => if named != (realization.identity as String) { OperationHandlerRefused { cause: OperationRealizationMismatch { at: at, named: named, active: realization.identity } } From 41b5730cb1c86b023e186d0fa97fd86bd0d79201 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Mon, 28 Sep 2026 13:16:42 +0000 Subject: [PATCH 10/75] Matrix floor pricing (cost-debt admissions + declared eval-step drop); wall clock on std.measure carriers; seed-growth row covers the file arm - Per eager-owl-205's ruling (msg_83af891b): the eleven matrix cases over the new-witness eval-step budget are typed cost-debt admissions (floor_cost_debt_admission mtcollins1_boot_matrix_typed_admissions, reason not reading) and members of a declared 4b(3) drop (gunbc.rung_drop mtcollins1_boot_matrix_new_witness_eval_step_cost, list floor_eval_step_cost_drop_boot_matrix_rows) whose restoration trigger is the natively emitted evaluation frame on the merge path. The two cases under the per-subject line are neither (a row there is stale). - Review 72230: ModeledWallClock carries EpochSecs and a signed std.measure SecondDisplacement (new, beside CelsiusDelta/ArcsecondDisplacement). - Seed-growth row names file_result_of_observation and the file/argv boundary. Co-Authored-By: Claude Opus 5.5 (1M context) --- ...eled_operation_realization_seed_growth.dag | 3 +- ...boot_matrix_new_witness_eval_step_cost.dag | 47 +++++++++++++++ dag/gunbc/rung_drop/roster.dag | 2 + dag/gunbc/wall_clock_model.dag | 10 ++-- dag/std/measure.dag | 13 +++++ .../claim/boot_world_models_witness_test.dag | 2 +- ...mtcollins1_boot_acceptance_matrix_test.dag | 2 +- src/v2/workflow/floor_cost_debt_admission.dag | 54 ++++++++++++++++- src/v2/workflow/floor_eval_step_cost_drop.dag | 58 ++++++++++++++++++- 9 files changed, 180 insertions(+), 11 deletions(-) create mode 100644 dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag diff --git a/dag/gunbc/modeled_operation_realization_seed_growth.dag b/dag/gunbc/modeled_operation_realization_seed_growth.dag index 4fbc25de101..eac23b41049 100644 --- a/dag/gunbc/modeled_operation_realization_seed_growth.dag +++ b/dag/gunbc/modeled_operation_realization_seed_growth.dag @@ -51,9 +51,10 @@ data modeled_operation_realization_seed_growth_justification: SeedGrowthJustific DeclarationRef { module_path: "v1_compiler.v1_interpreter", decl_name: "dispatch_modeled_operation", field: WholeDeclaration }, DeclarationRef { module_path: "v1_compiler.v1_interpreter", decl_name: "shell_result_of_observation", field: WholeDeclaration }, DeclarationRef { module_path: "v1_compiler.v1_interpreter", decl_name: "shell_result_projection", field: WholeDeclaration }, + DeclarationRef { module_path: "v1_compiler.v1_interpreter", decl_name: "file_result_of_observation", field: WholeDeclaration }, ], reason: "The seed interpreter is the only evaluator that runs the boot orchestrator, and the acceptance matrix (#12423, operator ruling 2026-09-27) must execute that orchestrator against controlled device histories. These items are the seed realization of a .dag contract: selection is v2.std.operation_realization operation_handler_selection over std.effect_grant covering_grant, admission is modeled_realization_admitted_in and operation_realization_duplicate, the virtual clock is virtual_clock_origin and virtual_clock_after over std.measure Second, and every scenario transition is gunbc.bmc_model. The Rust holds a state value, a clock value and the dispatch log, and dispatches; shell_result_projection is the existing wet shell projection extracted so the modeled observation reaches the same decoder path.", owning_dissolution_lane: "v1-materialization-kernel" as RoadmapNodeId, trigger: "Witnesses emit to native code and the emitted runtime realizes the evaluation frame and its modeled operation realization; these items then delete with the WITNESS_EVALUATION_FRAMES stack while test.claim.operation_realization_witness_test stays green without them. That witness is the deletion's regression control.", - current_boundary: "Shell transport observations only: a REST or file operation under a modeled frame refuses as a harness fault. Admitted only under Hermetic execution. No device logic in Rust. Nested frames inside an active realization are refused.", + current_boundary: "Shell and file transport observations (the file arm added by gunbc#12533 feeds the existing map_file_outputs; bound_operation_invocation_value records a ProcessArgvExpansion input as the words push_process_argv_expansion expands for a real spawn): a REST operation under a modeled frame refuses as a harness fault. Admitted only under Hermetic execution. No device logic in Rust. Nested frames inside an active realization are refused.", } diff --git a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag new file mode 100644 index 00000000000..b7f32f5e384 --- /dev/null +++ b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag @@ -0,0 +1,47 @@ +module gunbc.rung_drop.mtcollins1_boot_matrix_new_witness_eval_step_cost + +import std.types { String, List, NonEmptyStr } +import gunbc.rung_drop { RungDrop, Standing, TypedDeclaration, ReplacementStaged } +import gunbc.guarantee_rung { Mitigatable, MechanicallyPreventable } +import v2.workflow.floor_eval_step_cost_drop { floor_eval_step_cost_drop_boot_matrix_rows } + +// DECLARED 4b(3) DROP (gunbc#12533, 2026-09-28; the cost-debt ruling of eager-owl-205 on the #12423 +// matrix, msg_83af891b). The DECLARATION lives here; the POPULATION's authority is +// `v2.workflow.floor_eval_step_cost_drop` `floor_eval_step_cost_drop_boot_matrix_rows`. +// +// WHAT IS LOST IS ONE WALL, AND THE CLAIMS ARE UNTOUCHED. The eleven identities are planned, executed +// and measured on every pull request that edits them; a semantic red and a wall-clock crossing still +// block. Only the eval-step overrun is reported as `EvalStepsOverBudgetUnderDeclaredDrop` rather than +// refusing. The budget is not raised, and each identity is also a typed cost-debt admission +// (`v2.workflow.floor_cost_debt_admission` `mtcollins1_boot_matrix_typed_admissions`), which keeps it +// executing while its CPU is reported. +// +// WHY THE OVERRUN IS THE SUBJECT'S AND NOT DUPLICATED WORK. Each case asserts the ROUTE the real boot +// entry takes -- which effects, in which order, under which hold -- and its typed outcome, which #12423 +// requires be executed through the real production boundary. The decision folds each case reaches are +// already witnessed at their narrower interfaces with supplied values (the media convergence folds, +// the power selection, the host-capture verdict, the hold store); what only the entry can establish is +// that it reaches them with the state its own earlier steps built. The work computed identically +// across cases -- world construction and the route prefix up to the hold -- is named in gunbc#12533 as +// a follow-up to hoist; hoisting it lowers the bill and does not remove the subject. +data mtcollins1_boot_matrix_new_witness_eval_step_cost_population: List = floor_eval_step_cost_drop_boot_matrix_rows |> map(m => concat(concat(m.identity, ": over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by "), m.measured_by)) + +data mtcollins1_boot_matrix_new_witness_eval_step_cost: RungDrop = RungDrop { + identity: "mtcollins1_boot_matrix_new_witness_eval_step_cost" as NonEmptyStr, + + subject: "new-witness eval-step cost gate over the eleven mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered", + + declared: "2026-09-28", + + standing: Standing, + + declaration: TypedDeclaration { + previous: MechanicallyPreventable, + temporary: Mitigatable, + reason: ReplacementStaged { + replacement: "the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter", + }, + population: mtcollins1_boot_matrix_new_witness_eval_step_cost_population, + restoration_trigger: "THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these eleven identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither.", + } +} diff --git a/dag/gunbc/rung_drop/roster.dag b/dag/gunbc/rung_drop/roster.dag index be983db411d..596af1379d7 100644 --- a/dag/gunbc/rung_drop/roster.dag +++ b/dag/gunbc/rung_drop/roster.dag @@ -91,6 +91,7 @@ import gunbc.rung_drop.live_deploy_apply_render_new_witness_eval_step_cost { liv import gunbc.rung_drop.roadmap_live_forecast_new_witness_eval_step_cost { roadmap_live_forecast_new_witness_eval_step_cost } import gunbc.rung_drop.roadmap_page_style_new_witness_eval_step_cost { roadmap_page_style_new_witness_eval_step_cost } import gunbc.rung_drop.app_attest_interpreted_crypto_new_witness_eval_step_cost { app_attest_interpreted_crypto_new_witness_eval_step_cost } +import gunbc.rung_drop.mtcollins1_boot_matrix_new_witness_eval_step_cost { mtcollins1_boot_matrix_new_witness_eval_step_cost } import gunbc.rung_drop.app_attest_verifier_new_witness_eval_step_cost { app_attest_verifier_new_witness_eval_step_cost } import gunbc.rung_drop.app_attest_verifier_enrolment_dead_band_observed_only { app_attest_verifier_enrolment_dead_band_observed_only } import gunbc.rung_drop.sha256_span_program_serialize_new_witness_eval_step_cost { sha256_span_program_serialize_new_witness_eval_step_cost } @@ -183,6 +184,7 @@ data rung_drop_roster: List = [ roadmap_live_forecast_new_witness_eval_step_cost, roadmap_page_style_new_witness_eval_step_cost, app_attest_interpreted_crypto_new_witness_eval_step_cost, + mtcollins1_boot_matrix_new_witness_eval_step_cost, app_attest_verifier_new_witness_eval_step_cost, app_attest_verifier_enrolment_dead_band_observed_only, sha256_span_program_serialize_new_witness_eval_step_cost, diff --git a/dag/gunbc/wall_clock_model.dag b/dag/gunbc/wall_clock_model.dag index 199470400bb..cec79144ca2 100644 --- a/dag/gunbc/wall_clock_model.dag +++ b/dag/gunbc/wall_clock_model.dag @@ -1,7 +1,7 @@ module gunbc.wall_clock_model -import std.types { Int, List, String } -import std.measure { Second, second, second_count } +import std.types { EpochSecs, Int, List, String } +import std.measure { Second, second, second_count, SecondDisplacement, second_displacement_count } import v2.std.operation_argv { OperationRef } import v2.std.operation_realization { OperationBinding, OperationCall, OperationStep, OperationObserved, ShellObserved, @@ -19,12 +19,12 @@ import extdeps.transports.shell { ShellProcessExited } // It answers extdeps.clock Clock.Now in `date -u +%Y-%m-%dT%H:%M:%SZ` form, and Clock.UnixSecs and // Clock.UnixMillis in `date +%s` and `date +%s%3N` form, over the proleptic Gregorian calendar. type ModeledWallClock { - unix_at_origin: Int - step_seconds: Int + unix_at_origin: EpochSecs + step: SecondDisplacement } fn wall_clock_unix(clock: ModeledWallClock, now: Second) -> Int { - clock.unix_at_origin + (second_count(s: now) as Int) + clock.step_seconds + (clock.unix_at_origin as Int) + (second_count(s: now) as Int) + second_displacement_count(d: clock.step) } fn two_digits(n: Int) -> String { diff --git a/dag/std/measure.dag b/dag/std/measure.dag index 9386690dd35..d4ef4990025 100644 --- a/dag/std/measure.dag +++ b/dag/std/measure.dag @@ -1609,6 +1609,19 @@ fn second_count(s: Second) -> Nat { measure_count(s) } +// A SIGNED DURATION: a displacement in time that may be negative, as a wall clock stepping backwards +// is. Second is Nat-counted and so cannot carry it; this is the same instant-versus-displacement split +// CelsiusDelta and ArcsecondDisplacement make for their quantities. +type SecondDisplacement = Measure + +fn second_displacement(count: Int) -> SecondDisplacement { + Measure { count: count } +} + +fn second_displacement_count(d: SecondDisplacement) -> Int { + measure_count(d) +} + fn energy_from_power_and_time(power: Watt, time: Second) -> Joule { joule(watt_count(w: power) * second_count(s: time)) } diff --git a/dag/test/claim/boot_world_models_witness_test.dag b/dag/test/claim/boot_world_models_witness_test.dag index 756eec54443..51e2696b9b4 100644 --- a/dag/test/claim/boot_world_models_witness_test.dag +++ b/dag/test/claim/boot_world_models_witness_test.dag @@ -26,7 +26,7 @@ test fn the_wall_clock_renders_utc_like_date() -> Bool { // A NEGATIVE STEP IS A WALL CLOCK THAT WENT BACKWARDS while virtual time moved forward. test fn a_backward_step_reads_earlier_while_virtual_time_advances() -> Bool { - let clock = ModeledWallClock { unix_at_origin: 1790000000, step_seconds: 0 - 120 } + let clock = ModeledWallClock { unix_at_origin: 1790000000, step: std.measure.second_displacement(count: 0 - 120) } wall_clock_unix(clock: clock, now: second(count: 60)) == 1789999940 } diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index 72881769836..31fa7710e62 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -140,7 +140,7 @@ fn world_with_console(lines: List) -> MtCollins1BootWorld { ], agent: ModeledSshAgent { socket: "/run/ssh-agent.sock", holds_fleet_key: true }, remote_hosts: [healthy_srv2()], - clock: ModeledWallClock { unix_at_origin: 1790000000, step_seconds: 0 }, + clock: ModeledWallClock { unix_at_origin: 1790000000, step: std.measure.second_displacement(count: 0) }, worker: ModeledWorker { next_pid: 4000, processes: [], uptime_at_origin: 86400 }, console: ModeledHostConsole { lines: lines, emitted: 0, boot: none }, media: healthy_media(), diff --git a/src/v2/workflow/floor_cost_debt_admission.dag b/src/v2/workflow/floor_cost_debt_admission.dag index ad0029f8426..3eddf41b4fb 100644 --- a/src/v2/workflow/floor_cost_debt_admission.dag +++ b/src/v2/workflow/floor_cost_debt_admission.dag @@ -103,8 +103,60 @@ data app_attest_interpreted_crypto_typed_admissions: List = [ + FloorCostDebtTypedAdmission { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline", + reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, + }, + FloorCostDebtTypedAdmission { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_healthy_census_is_refused_at_the_sol_teardown", + reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, + }, + FloorCostDebtTypedAdmission { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again", + reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, + }, + FloorCostDebtTypedAdmission { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action", + reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, + }, + FloorCostDebtTypedAdmission { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action", + reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, + }, + FloorCostDebtTypedAdmission { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing", + reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, + }, + FloorCostDebtTypedAdmission { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff", + reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, + }, + FloorCostDebtTypedAdmission { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause", + reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, + }, + FloorCostDebtTypedAdmission { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline", + reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, + }, + FloorCostDebtTypedAdmission { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal", + reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, + }, + FloorCostDebtTypedAdmission { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_an_interrupted_attempt_locks_out_the_next_one", + reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, + }, +] + fn floor_cost_debt_typed_admissions() -> List { - app_attest_interpreted_crypto_typed_admissions + concat(app_attest_interpreted_crypto_typed_admissions, mtcollins1_boot_matrix_typed_admissions) } fn floor_cost_debt_typed_admitted_identities() -> List { diff --git a/src/v2/workflow/floor_eval_step_cost_drop.dag b/src/v2/workflow/floor_eval_step_cost_drop.dag index c1b9ee7711a..76aa9c2b69c 100644 --- a/src/v2/workflow/floor_eval_step_cost_drop.dag +++ b/src/v2/workflow/floor_eval_step_cost_drop.dag @@ -25,7 +25,9 @@ import std.types { NonEmptyStr } // - `floor_eval_step_cost_drop_span_program_rows`: the byte-span program inhabitance claim // (`sha256_span_program_serialize_new_witness_eval_step_cost`); // - `floor_eval_step_cost_drop_python_to_typescript_inhabitance_rows`: the python->typescript -// compile inhabitance claim (`python_to_typescript_compile_inhabitance_off_the_required_gate`). +// compile inhabitance claim (`python_to_typescript_compile_inhabitance_off_the_required_gate`); +// - `floor_eval_step_cost_drop_boot_matrix_rows`: the mtcollins1 boot acceptance matrix +// (`mtcollins1_boot_matrix_new_witness_eval_step_cost`). // The loss is a WORKFLOW fact -- which // identities the eval-step ceiling does not refuse -- so it lives beside the other two rosters the // ceiling consults (`v2.workflow.floor_grandfathered_roster`, `v2.workflow.floor_cost_debt`) and @@ -232,8 +234,60 @@ data floor_eval_step_cost_drop_python_to_typescript_inhabitance_rows: List = [ + EvalStepCostDropMeasurement { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline" as NonEmptyStr, + measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + }, + EvalStepCostDropMeasurement { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_healthy_census_is_refused_at_the_sol_teardown" as NonEmptyStr, + measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + }, + EvalStepCostDropMeasurement { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again" as NonEmptyStr, + measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + }, + EvalStepCostDropMeasurement { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action" as NonEmptyStr, + measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + }, + EvalStepCostDropMeasurement { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action" as NonEmptyStr, + measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + }, + EvalStepCostDropMeasurement { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing" as NonEmptyStr, + measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + }, + EvalStepCostDropMeasurement { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff" as NonEmptyStr, + measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + }, + EvalStepCostDropMeasurement { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause" as NonEmptyStr, + measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + }, + EvalStepCostDropMeasurement { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline" as NonEmptyStr, + measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + }, + EvalStepCostDropMeasurement { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal" as NonEmptyStr, + measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + }, + EvalStepCostDropMeasurement { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_an_interrupted_attempt_locks_out_the_next_one" as NonEmptyStr, + measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + }, +] + fn floor_eval_step_cost_drop_all_rows() -> List { - concat(concat(concat(concat(concat(concat(concat(floor_eval_step_cost_drop_rows, floor_eval_step_cost_drop_apply_render_rows), floor_eval_step_cost_drop_live_forecast_rows), floor_eval_step_cost_drop_page_style_rows), floor_eval_step_cost_drop_interpreted_crypto_rows), floor_eval_step_cost_drop_app_attest_verifier_rows), floor_eval_step_cost_drop_span_program_rows), floor_eval_step_cost_drop_python_to_typescript_inhabitance_rows) + concat(concat(concat(concat(concat(concat(concat(concat(floor_eval_step_cost_drop_rows, floor_eval_step_cost_drop_apply_render_rows), floor_eval_step_cost_drop_live_forecast_rows), floor_eval_step_cost_drop_page_style_rows), floor_eval_step_cost_drop_interpreted_crypto_rows), floor_eval_step_cost_drop_app_attest_verifier_rows), floor_eval_step_cost_drop_span_program_rows), floor_eval_step_cost_drop_python_to_typescript_inhabitance_rows), floor_eval_step_cost_drop_boot_matrix_rows) } // THE PROJECTION THE SEED RUNNER READS AND THE MODEL TESTS AGAINST. The runner refuses an empty or From c11634606da8601c381aa2973f0590f24b4b90f2 Mon Sep 17 00:00:00 2001 From: "gunbai-bot[bot]" <289086189+gunbai-bot[bot]@users.noreply.github.com> Date: Mon, 28 Sep 2026 14:03:10 +0000 Subject: [PATCH 11/75] chore: regenerate drifted generated artifacts (ci auto-heal) Ledger-Repair-Judged: docs/design-rung-drops.md Ledger-Rows-Repaired: docs/design-rung-drops.md mtcollins1_boot_matrix_new_witness_eval_step_cost Heal-Candidate-Run: 36427507942 --- docs/design-rung-drops.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index 97328cf2c18..0e81e536ad0 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -338,6 +338,10 @@ new-witness eval-step cost gate over the one roadmap page claim that derives the new-witness eval-step cost gate over the ten interpreted P-256 and P-384 point and group-law checks and SHA-384 FIPS vectors of the App Attest path: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the P-384 and SHA-384 primitives executing as natively emitted code rather than as interpreted bignat and Word64 folds). Population: test.claim.p384_dag_ecdsa_witness_test.the_p384_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_beside_the_base_point_is_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_with_a_coordinate_at_p_is_not_admitted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.apples_ca_and_root_keys_are_on_p384: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.sha384_fips_witness_test.sha384_of_the_empty_message_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published empty message and a one-octet message on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_abc_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published abc vector and abd on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_the_896_bit_message_is_the_published_two_block_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is four SHA-384 block compressions, the published 896-bit two-block vector and a last-block mutation on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.p256_dag_ecdsa_witness_test.the_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35708011844 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, well inside the wall deadline and over the new-witness eval-step budget. The billed work is one P-256 curve equation over the published base point as 11-limb bignat folds on an interpreter that reifies no machine width. It is a MEMBER BECAUSE IT WAS SPLIT OUT of a claim that also asserted n*G = infinity: that conjunction crossed the 8000ms wall deadline and was INTERRUPTED BEFORE ANY VERDICT, so both facts were being lost; the scalar multiplication left the floor for the native row the frontier names, and this cheap half now reaches a verdict. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field, test.claim.p384_dag_ecdsa_witness_test.doubling_and_adding_the_base_point_stay_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling, one addition and two projective curve-equation checks at 16 limbs, test.claim.p384_dag_ecdsa_witness_test.doubling_an_off_curve_point_stays_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling and one projective curve-equation check at 16 limbs. Restored when: THE CAPABILITY: gunbc test //gunbc/instruments:native-crypto-vectors EXECUTING ON THE MERGE PATH, i.e. as a phase of a required lane whose red blocks a merge, running these ten identities natively (its cases p256_the_base_point_is_on_the_curve, p384_the_base_point_is_on_the_curve, p384_red_a_point_beside_the_base_point_is_off_the_curve, p384_red_a_point_with_a_coordinate_at_p_is_not_admitted, p384_doubling_and_adding_the_base_point_stay_on_the_curve, p384_red_doubling_an_off_curve_point_stays_off_the_curve, p384_apples_ca_and_root_keys_are_on_the_curve and the sha384_* FIPS cases with their reds) while each still evaluates the real curve equation or the real hash; WHAT THAT MUST BE SUFFICIENT FOR: the P-384 parameters and SHA-384 are exercised on the acceptance path with no interpreted 16-limb fold inside a claim frame, so the interpreted identities can leave the floor for that row, or they measure under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives. The same row run BY NAME (as it exists since gunbc#12306) executes the facts natively but is NOT the acceptance path and retires nothing. Supplying the curve check's answer or the digest as a fixture, or deleting the identities, satisfies neither. +### new-witness eval-step cost gate over the eleven mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 + +new-witness eval-step cost gate over the eleven mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_healthy_census_is_refused_at_the_sol_teardown: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_an_interrupted_attempt_locks_out_the_next_one: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these eleven identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. + ### new-witness eval-step cost gate over six App Attest verifier claims -- the two real-path inhabitance claims over Apple's objects, three single structural steps priced by their own SHA-256s, and the wire-carrier join: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 new-witness eval-step cost gate over six App Attest verifier claims -- the two real-path inhabitance claims over Apple's objects, three single structural steps priced by their own SHA-256s, and the wire-carrier join: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the CBOR, DER and SHA-256 readers executing as natively emitted code over the sample objects rather than as interpreted octet-list folds). Population: test.claim.app_attest_verifier_witness_test.the_sample_passes_every_step_before_the_extension_steps: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b 4d089af1cb9 (gunbc#11989): verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget; the billed work is the real path end to end: Apple's attestation object through decode_attestation (CBOR, two DER certificates, the PEM-pinned root, authenticator data) and the whole structural fold with its SHA-256s. It is the attestation path's one inhabitance claim, so nothing here is supplied, test.claim.app_attest_verifier_witness_test.the_nonce_step_reds_on_other_client_data: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b 4d089af1cb9 (gunbc#11989): verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget; the billed work is nonce_step alone over supplied inputs: SHA-256 of the client data and SHA-256 of authData concatenated with it, two interpreted hashes, which is the step and nothing before it, test.claim.app_attest_verifier_witness_test.the_app_id_step_reds_on_another_app_id: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b 4d089af1cb9 (gunbc#11989): verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget; the billed work is app_id_step alone over supplied inputs: one interpreted SHA-256 of the App ID, test.claim.app_attest_verifier_witness_test.the_key_id_step_admits_the_real_key_and_reds_on_another_key_id: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b (gunbc#11989), and the required floor's required-ci-measurement-receipt: verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget; the billed work is key_id_step alone over supplied inputs, paired over its own subject: one interpreted SHA-256 of the credential certificate's 65-octet public key (the second comparison reuses it), test.claim.app_attest_verifier_witness_test.the_sample_assertion_passes_rp_id_and_refuses_on_absent_extensions: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b (gunbc#11989), and the required floor's required-ci-measurement-receipt: verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget; the billed work is the assertion's real path: the assertion object through assertion_parts and the fold's RP ID SHA-256, plus the attestation's leaf certificate read for the credential key (the attestation-to-assertion join). It is the assertion path's one inhabitance claim, paired with a wrong-App-ID refusal over the same subject, test.claim.signature_verify_join_witness_test.malformed_carriers_refuse_before_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b 4d089af1cb9 (gunbc#11989): verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget. THIS ROW'S BILLED WORK IS NOT THE VERIFIER ROWS': it touches no Apple object, no certificate and no hash. It base64url-decodes two carriers of the RFC 6979 A.2.5 P-256 vectors through extdeps.crypto.signature verify_signature, which asks signature_carrier_refusal FIRST and refuses on size before the implementation is consulted. What the budget prices is the interpreter walking those octet lists byte by byte to decode and size them. Restored when: THE CAPABILITY. MachineWidth reification (gunbc#11819) lets the extdeps.apple.app_attest closure emit, and these six identities execute on the natively emitted route -- the gunbc test instrument row the ecdsa_verification_realization_frontier names -- while each still exercises its own production code over its own inputs -- Apple's objects end to end for the two inhabitance claims, its one named step for the three step claims, the RFC 6979 carriers for the carrier-join claim; WHAT THAT MUST BE SUFFICIENT FOR: the verifier folds are exercised over the real sample on the acceptance path, and the carrier join over its real carriers, with no interpreted octet walk inside a claim frame, and the identities then measure under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, or leave the floor for that native row. Supplying the two inhabitance claims' inputs as fixtures, precomputing a step's hashes, or deleting the identities satisfies neither. From a0e46d8b6d4708350a09707632532682535719cc Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Mon, 28 Sep 2026 14:33:15 +0000 Subject: [PATCH 12/75] Matrix cost: bindings indexed once at admission, SOL drop armed by the host's boot (one attempt), stale cost-debt rows removed, drop population = the 8 over-budget cases, rung-drop projection regenerated The first floor run showed every typed cost-debt row stale: the matrix cases sit under the 500ms per-subject line, where such a row blocks. The honest fix is cost, not a different exemption: operation_realization_index maps bindings by identity once per frame (each of ~190 dispatches no longer scans the list), and the SOL-loss case no longer pays a baseline attempt. Measured locally the dearest case is now 220ms CPU (was 307ms on CI), under the 302ms enrolment margin. OperationBoundTwice/BindingMatch deleted (unreachable: duplicates refuse at admission). Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/gunbc/bmc_model.dag | 34 +++++++++--- ...boot_matrix_new_witness_eval_step_cost.dag | 11 ++-- ...mtcollins1_boot_acceptance_matrix_test.dag | 47 ++++++---------- docs/design-rung-drops.md | 4 ++ src/v1/stage0/src/v1_interpreter.rs | 14 ++++- src/v2/std/operation_realization.dag | 38 +++++-------- src/v2/workflow/floor_cost_debt_admission.dag | 54 +------------------ src/v2/workflow/floor_eval_step_cost_drop.dag | 21 ++------ 8 files changed, 86 insertions(+), 137 deletions(-) diff --git a/dag/gunbc/bmc_model.dag b/dag/gunbc/bmc_model.dag index 0d36446aa05..a82ce78dfc8 100644 --- a/dag/gunbc/bmc_model.dag +++ b/dag/gunbc/bmc_model.dag @@ -51,6 +51,9 @@ type BmcSelRecord { state: String } +// sol_drop_after_boot, when a scenario sets it, schedules the controller dropping its SOL session that +// long after the host starts booting, so the loss follows the route's own power-on rather than a clock +// guessed in advance. // host_booted_at is the virtual instant the host last started booting (power on, or the restore of a // cycle); the host's console is timed from it. booted_via_override records whether that boot consumed // the one-shot override. @@ -64,12 +67,13 @@ type BmcWorld { cycle_off_interval: Second host_booted_at: Second? booted_via_override: Bool + sol_drop_after_boot: Second? } fn bmc_world(power: BmcPower) -> BmcWorld { BmcWorld { power: power, pending: [], fired: [], boot_override: BootOverrideNone, sel: [], - sol_session_open: false, cycle_off_interval: second(count: 5), host_booted_at: none, booted_via_override: false, + sol_session_open: false, cycle_off_interval: second(count: 5), host_booted_at: none, booted_via_override: false, sol_drop_after_boot: none, } } @@ -94,7 +98,7 @@ fn bmc_with_power(world: BmcWorld, power: BmcPower) -> BmcWorld { BmcWorld { power: power, pending: world.pending, fired: world.fired, boot_override: world.boot_override, sel: world.sel, sol_session_open: world.sol_session_open, cycle_off_interval: world.cycle_off_interval, - host_booted_at: world.host_booted_at, booted_via_override: world.booted_via_override, + host_booted_at: world.host_booted_at, booted_via_override: world.booted_via_override, sol_drop_after_boot: world.sol_drop_after_boot, } } @@ -102,7 +106,7 @@ fn bmc_with_override(world: BmcWorld, over: BmcBootOverride) -> BmcWorld { BmcWorld { power: world.power, pending: world.pending, fired: world.fired, boot_override: over, sel: world.sel, sol_session_open: world.sol_session_open, cycle_off_interval: world.cycle_off_interval, - host_booted_at: world.host_booted_at, booted_via_override: world.booted_via_override, + host_booted_at: world.host_booted_at, booted_via_override: world.booted_via_override, sol_drop_after_boot: world.sol_drop_after_boot, } } @@ -110,7 +114,7 @@ fn bmc_with_sol_session(world: BmcWorld, open: Bool) -> BmcWorld { BmcWorld { power: world.power, pending: world.pending, fired: world.fired, boot_override: world.boot_override, sel: world.sel, sol_session_open: open, cycle_off_interval: world.cycle_off_interval, - host_booted_at: world.host_booted_at, booted_via_override: world.booted_via_override, + host_booted_at: world.host_booted_at, booted_via_override: world.booted_via_override, sol_drop_after_boot: world.sol_drop_after_boot, } } @@ -118,7 +122,7 @@ fn bmc_with_pending(world: BmcWorld, pending: List, fired: Li BmcWorld { power: world.power, pending: pending, fired: fired, boot_override: world.boot_override, sel: world.sel, sol_session_open: world.sol_session_open, cycle_off_interval: world.cycle_off_interval, - host_booted_at: world.host_booted_at, booted_via_override: world.booted_via_override, + host_booted_at: world.host_booted_at, booted_via_override: world.booted_via_override, sol_drop_after_boot: world.sol_drop_after_boot, } } @@ -126,10 +130,14 @@ fn bmc_with_pending(world: BmcWorld, pending: List, fired: Li // override is consumed by it. fn bmc_host_boots(world: BmcWorld, now: Second) -> BmcWorld { let via = match world.boot_override { BootOverrideCdromEfiNextBoot => true BootOverrideNone => false } + let pending = match world.sol_drop_after_boot { + Absent => world.pending + Present { value: after } => list_append(world.pending, BmcScheduledEvent { at: second(count: second_count(s: now) + second_count(s: after)), event: BmcSolSessionDropped }) + } BmcWorld { - power: BmcPowerOn, pending: world.pending, fired: world.fired, boot_override: BootOverrideNone, sel: world.sel, + power: BmcPowerOn, pending: pending, fired: world.fired, boot_override: BootOverrideNone, sel: world.sel, sol_session_open: world.sol_session_open, cycle_off_interval: world.cycle_off_interval, - host_booted_at: Present { value: now }, booted_via_override: via, + host_booted_at: Present { value: now }, booted_via_override: via, sol_drop_after_boot: world.sol_drop_after_boot, } } @@ -170,3 +178,15 @@ fn bmc_advance(world: BmcWorld, now: Second) -> BmcWorld { } }) } + +fn bmc_with_sol_drop_after_boot(world: BmcWorld, after: Second) -> BmcWorld { + BmcWorld { + power: world.power, pending: world.pending, fired: world.fired, boot_override: world.boot_override, sel: world.sel, + sol_session_open: world.sol_session_open, cycle_off_interval: world.cycle_off_interval, + host_booted_at: world.host_booted_at, booted_via_override: world.booted_via_override, sol_drop_after_boot: Present { value: after }, + } +} + +fn bmc_sol_drop_fired(world: BmcWorld) -> Bool { + !all(world.fired, e => match e.event { BmcSolSessionDropped => false _ => true }) +} diff --git a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag index b7f32f5e384..9a841cf09e1 100644 --- a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag +++ b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag @@ -9,12 +9,11 @@ import v2.workflow.floor_eval_step_cost_drop { floor_eval_step_cost_drop_boot_ma // matrix, msg_83af891b). The DECLARATION lives here; the POPULATION's authority is // `v2.workflow.floor_eval_step_cost_drop` `floor_eval_step_cost_drop_boot_matrix_rows`. // -// WHAT IS LOST IS ONE WALL, AND THE CLAIMS ARE UNTOUCHED. The eleven identities are planned, executed +// WHAT IS LOST IS ONE WALL, AND THE CLAIMS ARE UNTOUCHED. The eight identities are planned, executed // and measured on every pull request that edits them; a semantic red and a wall-clock crossing still // block. Only the eval-step overrun is reported as `EvalStepsOverBudgetUnderDeclaredDrop` rather than -// refusing. The budget is not raised, and each identity is also a typed cost-debt admission -// (`v2.workflow.floor_cost_debt_admission` `mtcollins1_boot_matrix_typed_admissions`), which keeps it -// executing while its CPU is reported. +// refusing. The budget is not raised. Their CPU stays under the enrolment margin, so they enrol +// without a cost-debt admission (one would be stale under the per-subject line and block). // // WHY THE OVERRUN IS THE SUBJECT'S AND NOT DUPLICATED WORK. Each case asserts the ROUTE the real boot // entry takes -- which effects, in which order, under which hold -- and its typed outcome, which #12423 @@ -29,7 +28,7 @@ data mtcollins1_boot_matrix_new_witness_eval_step_cost_population: List data mtcollins1_boot_matrix_new_witness_eval_step_cost: RungDrop = RungDrop { identity: "mtcollins1_boot_matrix_new_witness_eval_step_cost" as NonEmptyStr, - subject: "new-witness eval-step cost gate over the eleven mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered", + subject: "new-witness eval-step cost gate over the eight mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered", declared: "2026-09-28", @@ -42,6 +41,6 @@ data mtcollins1_boot_matrix_new_witness_eval_step_cost: RungDrop = RungDrop { replacement: "the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter", }, population: mtcollins1_boot_matrix_new_witness_eval_step_cost_population, - restoration_trigger: "THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these eleven identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither.", + restoration_trigger: "THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these eight identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither.", } } diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index 31fa7710e62..31cc33ca5e0 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -11,7 +11,7 @@ import v2.std.witness_evaluation { evaluate_in_witness_frame, witness_diagnostic_rendered_reason, } import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } -import gunbc.bmc_model { BmcWorld, BmcPowerOff, BmcScheduledEvent, BmcSolSessionDropped, bmc_world, bmc_with_sol_session, bmc_with_pending } +import gunbc.bmc_model { BmcWorld, BmcPowerOff, bmc_world, bmc_with_sol_session, bmc_with_sol_drop_after_boot, bmc_sol_drop_fired } import gunbc.filesystem_model { ModeledFilesystem, ModeledFile } import gunbc.process_environment_model { ModeledVariable } import gunbc.remote_host_model { ModeledRemoteHost, ModeledRemoteFile } @@ -409,38 +409,25 @@ test fn a_sol_session_held_elsewhere_refuses_before_the_attach() -> Bool { } } -fn power_on_at(route: List) -> Int { - match filter(route, r => operation_name(r: r) == "diagnostic.ipmi.Tool.ChassisPowerControl").first() { - Present { value: r } => std.measure.second_count(s: r.completed_at) as Int - Absent => 0 - 1 - } +// SOL IS LOST THIRTY SECONDS AFTER THE HOST STARTS BOOTING WHILE MANAGEMENT KEEPS ANSWERING, and the +// census would have printed at sixty. The drop is armed by the host's own boot in the model, so it +// follows the route's real power-on. PINNED: the attempt learns of the loss only at the terminal +// deadline -- the capture stops growing and the watch polls to its bound -- so the first loss is not +// reported before the deadline (#12423 asks that it is). The final world shows the drop fired, so the +// case is not green on a run where the loss never happened. When loss detection lands it must flip to +// an early, typed refusal. +fn sol_drop_fired_in(w: MtCollins1BootWorld) -> Bool { + bmc_sol_drop_fired(world: w.bmc) } -// SOL IS LOST THIRTY SECONDS AFTER POWER-ON WHILE MANAGEMENT KEEPS ANSWERING, and the census would have -// printed at sixty. The drop is scheduled from the baseline route's own power-on instant. PINNED: the -// attempt learns of the loss only at the terminal deadline -- the capture stops growing and the watch -// polls to its bound -- so the first loss is not reported before the deadline (#12423 asks that it is). -// When loss detection lands this case must flip to an early, typed refusal. test fn pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline() -> Bool { - let console = console_of(capture: one_socket_census_capture, begin_after: 60, end_after: 240) - match run_attempt(world: world_with_console(lines: console)) { - WitnessReturned { route: baseline } => { - let drop_at = power_on_at(route: baseline) + 30 - let w = world_with_console(lines: console) - match std.checked_arithmetic.checked_int_to_nat(n: drop_at) { - Absent => false - Present { value: drop_count } => { - let dropping = with_bmc(w: w, bmc: bmc_with_pending(world: w.bmc, pending: [BmcScheduledEvent { at: second(count: drop_count), event: BmcSolSessionDropped }], fired: [])) - match run_attempt(world: dropping) { - WitnessReturned { value, route } => - drop_at > 30 - && string_contains(s: outcome_reason(a: value), pattern: "deadline reached without a host-capture terminal") - && count_named(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") == 1 - _ => false - } - } - } - } + let w = world_with_console(lines: console_of(capture: one_socket_census_capture, begin_after: 60, end_after: 240)) + let dropping = with_bmc(w: w, bmc: bmc_with_sol_drop_after_boot(world: w.bmc, after: second(count: 30))) + match evaluate_in_witness_frame(frame: matrix_frame(world: dropping), subject: fn(_scope) { mtcollins1_boot_wet_on_srv1() }) { + WitnessReturned { value, route, state } => + string_contains(s: outcome_reason(a: value), pattern: "deadline reached without a host-capture terminal") + && count_named(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") == 1 + && match state { Present { value: end } => sol_drop_fired_in(w: end) Absent => false } _ => false } } diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index 97328cf2c18..fe7c3561532 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -338,6 +338,10 @@ new-witness eval-step cost gate over the one roadmap page claim that derives the new-witness eval-step cost gate over the ten interpreted P-256 and P-384 point and group-law checks and SHA-384 FIPS vectors of the App Attest path: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the P-384 and SHA-384 primitives executing as natively emitted code rather than as interpreted bignat and Word64 folds). Population: test.claim.p384_dag_ecdsa_witness_test.the_p384_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_beside_the_base_point_is_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_with_a_coordinate_at_p_is_not_admitted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.apples_ca_and_root_keys_are_on_p384: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.sha384_fips_witness_test.sha384_of_the_empty_message_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published empty message and a one-octet message on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_abc_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published abc vector and abd on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_the_896_bit_message_is_the_published_two_block_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is four SHA-384 block compressions, the published 896-bit two-block vector and a last-block mutation on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.p256_dag_ecdsa_witness_test.the_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35708011844 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, well inside the wall deadline and over the new-witness eval-step budget. The billed work is one P-256 curve equation over the published base point as 11-limb bignat folds on an interpreter that reifies no machine width. It is a MEMBER BECAUSE IT WAS SPLIT OUT of a claim that also asserted n*G = infinity: that conjunction crossed the 8000ms wall deadline and was INTERRUPTED BEFORE ANY VERDICT, so both facts were being lost; the scalar multiplication left the floor for the native row the frontier names, and this cheap half now reaches a verdict. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field, test.claim.p384_dag_ecdsa_witness_test.doubling_and_adding_the_base_point_stay_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling, one addition and two projective curve-equation checks at 16 limbs, test.claim.p384_dag_ecdsa_witness_test.doubling_an_off_curve_point_stays_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling and one projective curve-equation check at 16 limbs. Restored when: THE CAPABILITY: gunbc test //gunbc/instruments:native-crypto-vectors EXECUTING ON THE MERGE PATH, i.e. as a phase of a required lane whose red blocks a merge, running these ten identities natively (its cases p256_the_base_point_is_on_the_curve, p384_the_base_point_is_on_the_curve, p384_red_a_point_beside_the_base_point_is_off_the_curve, p384_red_a_point_with_a_coordinate_at_p_is_not_admitted, p384_doubling_and_adding_the_base_point_stay_on_the_curve, p384_red_doubling_an_off_curve_point_stays_off_the_curve, p384_apples_ca_and_root_keys_are_on_the_curve and the sha384_* FIPS cases with their reds) while each still evaluates the real curve equation or the real hash; WHAT THAT MUST BE SUFFICIENT FOR: the P-384 parameters and SHA-384 are exercised on the acceptance path with no interpreted 16-limb fold inside a claim frame, so the interpreted identities can leave the floor for that row, or they measure under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives. The same row run BY NAME (as it exists since gunbc#12306) executes the facts natively but is NOT the acceptance path and retires nothing. Supplying the curve check's answer or the digest as a fixture, or deleting the identities, satisfies neither. +### new-witness eval-step cost gate over the eight mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 + +new-witness eval-step cost gate over the eight mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_healthy_census_is_refused_at_the_sol_teardown: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these eight identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. + ### new-witness eval-step cost gate over six App Attest verifier claims -- the two real-path inhabitance claims over Apple's objects, three single structural steps priced by their own SHA-256s, and the wire-carrier join: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 new-witness eval-step cost gate over six App Attest verifier claims -- the two real-path inhabitance claims over Apple's objects, three single structural steps priced by their own SHA-256s, and the wire-carrier join: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the CBOR, DER and SHA-256 readers executing as natively emitted code over the sample objects rather than as interpreted octet-list folds). Population: test.claim.app_attest_verifier_witness_test.the_sample_passes_every_step_before_the_extension_steps: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b 4d089af1cb9 (gunbc#11989): verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget; the billed work is the real path end to end: Apple's attestation object through decode_attestation (CBOR, two DER certificates, the PEM-pinned root, authenticator data) and the whole structural fold with its SHA-256s. It is the attestation path's one inhabitance claim, so nothing here is supplied, test.claim.app_attest_verifier_witness_test.the_nonce_step_reds_on_other_client_data: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b 4d089af1cb9 (gunbc#11989): verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget; the billed work is nonce_step alone over supplied inputs: SHA-256 of the client data and SHA-256 of authData concatenated with it, two interpreted hashes, which is the step and nothing before it, test.claim.app_attest_verifier_witness_test.the_app_id_step_reds_on_another_app_id: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b 4d089af1cb9 (gunbc#11989): verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget; the billed work is app_id_step alone over supplied inputs: one interpreted SHA-256 of the App ID, test.claim.app_attest_verifier_witness_test.the_key_id_step_admits_the_real_key_and_reds_on_another_key_id: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b (gunbc#11989), and the required floor's required-ci-measurement-receipt: verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget; the billed work is key_id_step alone over supplied inputs, paired over its own subject: one interpreted SHA-256 of the credential certificate's 65-octet public key (the second comparison reuses it), test.claim.app_attest_verifier_witness_test.the_sample_assertion_passes_rp_id_and_refuses_on_absent_extensions: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b (gunbc#11989), and the required floor's required-ci-measurement-receipt: verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget; the billed work is the assertion's real path: the assertion object through assertion_parts and the fold's RP ID SHA-256, plus the attestation's leaf certificate read for the credential key (the attestation-to-assertion join). It is the assertion path's one inhabitance claim, paired with a wrong-App-ID refusal over the same subject, test.claim.signature_verify_join_witness_test.malformed_carriers_refuse_before_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b 4d089af1cb9 (gunbc#11989): verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget. THIS ROW'S BILLED WORK IS NOT THE VERIFIER ROWS': it touches no Apple object, no certificate and no hash. It base64url-decodes two carriers of the RFC 6979 A.2.5 P-256 vectors through extdeps.crypto.signature verify_signature, which asks signature_carrier_refusal FIRST and refuses on size before the implementation is consulted. What the budget prices is the interpreter walking those octet lists byte by byte to decode and size them. Restored when: THE CAPABILITY. MachineWidth reification (gunbc#11819) lets the extdeps.apple.app_attest closure emit, and these six identities execute on the natively emitted route -- the gunbc test instrument row the ecdsa_verification_realization_frontier names -- while each still exercises its own production code over its own inputs -- Apple's objects end to end for the two inhabitance claims, its one named step for the three step claims, the RFC 6979 carriers for the carrier-join claim; WHAT THAT MUST BE SUFFICIENT FOR: the verifier folds are exercised over the real sample on the acceptance path, and the carrier join over its real carriers, with no interpreted octet walk inside a claim frame, and the identities then measure under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, or leave the floor for that native row. Supplying the two inhabitance claims' inputs as fixtures, precomputing a step's hashes, or deleting the identities satisfies neither. diff --git a/src/v1/stage0/src/v1_interpreter.rs b/src/v1/stage0/src/v1_interpreter.rs index 8b2ef4139db..15e2acc0f48 100644 --- a/src/v1/stage0/src/v1_interpreter.rs +++ b/src/v1/stage0/src/v1_interpreter.rs @@ -7858,6 +7858,9 @@ fn current_witness_evaluation_frame() -> Option { struct ModeledRealizationSlot { envelope: Value, realization: Value, + /// The realization's bindings by operation identity (`operation_realization_index`), built + /// once at admission so no dispatch rescans the binding list. + index: Value, identity: String, state: Value, /// The virtual clock, an opaque `std.measure` `Second`: the dispatcher never reads its @@ -8084,9 +8087,16 @@ fn admit_modeled_realization( let advance = record_field(ctx, &realization, "advance") .ok_or_else(|| modeled_refused("(frame)", "the realization carries no advance function"))?; let state = apply_modeled_handler(&advance, &[initial, now.clone()], env, ctx)?; + let index = run_in_context_with_args( + ctx, + "operation_realization_index", + &[(Some("realization".to_string()), realization.clone())], + false, + )?; Ok(Some(ModeledRealizationSlot { envelope, realization, + index, identity, state, now, @@ -8195,6 +8205,7 @@ fn dispatch_modeled_operation( ( s.envelope.clone(), s.realization.clone(), + s.index.clone(), s.identity.clone(), s.state.clone(), s.now.clone(), @@ -8203,7 +8214,7 @@ fn dispatch_modeled_operation( }) }) }); - let Some((envelope, realization, identity, state, now, ordinal)) = snapshot else { + let Some((envelope, realization, index, identity, state, now, ordinal)) = snapshot else { return Ok(None); }; let key = format!("{service_name}.{op_name}"); @@ -8243,6 +8254,7 @@ fn dispatch_modeled_operation( &[ (Some("env".to_string()), envelope), (Some("realization".to_string()), realization.clone()), + (Some("index".to_string()), index), (Some("invocation".to_string()), invocation.clone()), ( Some("readonly".to_string()), diff --git a/src/v2/std/operation_realization.dag b/src/v2/std/operation_realization.dag index d3b5b37f8b9..054eaa00866 100644 --- a/src/v2/std/operation_realization.dag +++ b/src/v2/std/operation_realization.dag @@ -1,6 +1,6 @@ module v2.std.operation_realization -import std.types { Bool, Int, List, NonEmptyStr, String } +import std.types { Bool, Int, List, Map, NonEmptyStr, String } import std.effect_grant { Envelope, HandlerBinding, CoveredBy, NoCoveringGrant, covering_grant, NamespacePosition, ServiceOpTree, Read, Write, Verb, @@ -111,7 +111,6 @@ type OperationBindingRefusal | OperationBoundElsewhere { at: OperationRef, binding: HandlerBinding } | OperationRealizationMismatch { at: OperationRef, named: String, active: NonEmptyStr } | OperationNotBound { at: OperationRef } - | OperationBoundTwice { at: OperationRef, count: Int } type OperationHandlerSelection = OperationHandlerSelected { binding: OperationBinding } @@ -129,29 +128,13 @@ fn operation_verb(readonly: Bool) -> Verb { if readonly { Read } else { Write } } -type BindingMatch - = BindingMatchNone - | BindingMatchOne { binding: OperationBinding } - | BindingMatchMany { count: Int } - -fn binding_match(bindings: List>, at: OperationRef) -> BindingMatch { - fold(bindings, init: BindingMatchNone, f: fn(acc, b) { - if operation_ref_eq(a: b.at, b: at) { - match acc { - BindingMatchNone => BindingMatchOne { binding: b } - BindingMatchOne { binding: _ } => BindingMatchMany { count: 2 } - BindingMatchMany { count: n } => BindingMatchMany { count: n + 1 } - } - } else { acc } - }) -} - // THE SINGLE SELECTION DECISION, called by the dispatcher for every operation issued while a modeled // realization is active. Grant coverage first (the same covering_grant REST replay uses), then the -// named realization, then exactly one binding for the resolved identity. +// named realization, then the one binding the admitted index holds for the resolved identity. fn operation_handler_selection( env: Envelope, realization: OperationRealization, + index: Map>, invocation: BoundOperationInvocation, readonly: Bool, ) -> OperationHandlerSelection { @@ -163,10 +146,9 @@ fn operation_handler_selection( if named != (realization.identity as String) { OperationHandlerRefused { cause: OperationRealizationMismatch { at: at, named: named, active: realization.identity } } } else { - match binding_match(bindings: realization.bindings, at: at) { - BindingMatchNone => OperationHandlerRefused { cause: OperationNotBound { at: at } } - BindingMatchMany { count: n } => OperationHandlerRefused { cause: OperationBoundTwice { at: at, count: n } } - BindingMatchOne { binding: b } => OperationHandlerSelected { binding: b } + match map_get(index, operation_ref_key(at: at)) { + Absent => OperationHandlerRefused { cause: OperationNotBound { at: at } } + Present { value: b } => OperationHandlerSelected { binding: b } } } other => OperationHandlerRefused { cause: OperationBoundElsewhere { at: at, binding: other } } @@ -174,6 +156,14 @@ fn operation_handler_selection( } } +// THE BINDINGS BY IDENTITY, BUILT ONCE WHEN THE FRAME IS ADMITTED. Every dispatch then looks its +// operation up instead of scanning the binding list: the list is fixed for the frame's extent, so a +// per-dispatch scan re-derived the same fact on every call (DESIGN section 2). Admission has already +// refused a realization that binds one identity twice, so each key holds exactly one binding. +fn operation_realization_index(realization: OperationRealization) -> Map> { + fold(realization.bindings, init: empty_map(), f: fn(acc, b) { map_insert(acc, operation_ref_key(at: b.at), b) }) +} + // ADMISSION BEFORE THE SUBJECT RUNS: a realization binding one identity twice is malformed whatever // the subject later issues. Resolution of each binding against the operation registry is the // dispatcher's (it owns the registry); this is the part decidable from the value alone. diff --git a/src/v2/workflow/floor_cost_debt_admission.dag b/src/v2/workflow/floor_cost_debt_admission.dag index 3eddf41b4fb..ad0029f8426 100644 --- a/src/v2/workflow/floor_cost_debt_admission.dag +++ b/src/v2/workflow/floor_cost_debt_admission.dag @@ -103,60 +103,8 @@ data app_attest_interpreted_crypto_typed_admissions: List = [ - FloorCostDebtTypedAdmission { - identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline", - reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, - }, - FloorCostDebtTypedAdmission { - identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_healthy_census_is_refused_at_the_sol_teardown", - reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, - }, - FloorCostDebtTypedAdmission { - identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again", - reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, - }, - FloorCostDebtTypedAdmission { - identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action", - reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, - }, - FloorCostDebtTypedAdmission { - identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action", - reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, - }, - FloorCostDebtTypedAdmission { - identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing", - reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, - }, - FloorCostDebtTypedAdmission { - identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff", - reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, - }, - FloorCostDebtTypedAdmission { - identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause", - reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, - }, - FloorCostDebtTypedAdmission { - identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline", - reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, - }, - FloorCostDebtTypedAdmission { - identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal", - reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, - }, - FloorCostDebtTypedAdmission { - identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_an_interrupted_attempt_locks_out_the_next_one", - reason: "the subject is the real mtcollins1 boot entry (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1) evaluated end to end in the seed interpreter over the dry operation realization, as #12423 requires of the acceptance matrix; a narrower supplied value would drop the route under test; owner: the mtcollins1 boot acceptance matrix lane, discharged by the natively emitted evaluation frame" as NonEmptyStr, - }, -] - fn floor_cost_debt_typed_admissions() -> List { - concat(app_attest_interpreted_crypto_typed_admissions, mtcollins1_boot_matrix_typed_admissions) + app_attest_interpreted_crypto_typed_admissions } fn floor_cost_debt_typed_admitted_identities() -> List { diff --git a/src/v2/workflow/floor_eval_step_cost_drop.dag b/src/v2/workflow/floor_eval_step_cost_drop.dag index 76aa9c2b69c..e9e32abcabd 100644 --- a/src/v2/workflow/floor_eval_step_cost_drop.dag +++ b/src/v2/workflow/floor_eval_step_cost_drop.dag @@ -235,10 +235,11 @@ data floor_eval_step_cost_drop_python_to_typescript_inhabitance_rows: List = [ EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline" as NonEmptyStr, @@ -256,14 +257,6 @@ data floor_eval_step_cost_drop_boot_matrix_rows: List List { From 52b285027a613a28d6c4eed47c0e90c81d165c7e Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Mon, 28 Sep 2026 14:57:22 +0000 Subject: [PATCH 13/75] Floor: import the map operations from v2.std.collection (map_lookup, the total form) Co-Authored-By: Claude Opus 5.5 (1M context) --- src/v2/std/operation_realization.dag | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/v2/std/operation_realization.dag b/src/v2/std/operation_realization.dag index 054eaa00866..225cc431f40 100644 --- a/src/v2/std/operation_realization.dag +++ b/src/v2/std/operation_realization.dag @@ -7,6 +7,7 @@ import std.effect_grant { } import v2.std.operation_argv { OperationRef, BoundOperationInvocation, InputText, InputTextList } import std.list { first_duplicate_by_key } +import v2.std.collection { empty_map, map_insert, map_lookup } import std.measure { Second, second, second_count } import std.checked_arithmetic { checked_int_to_nat } import std.execution_mode { ExecutionMode, Hermetic, Wet, Record } @@ -146,7 +147,7 @@ fn operation_handler_selection( if named != (realization.identity as String) { OperationHandlerRefused { cause: OperationRealizationMismatch { at: at, named: named, active: realization.identity } } } else { - match map_get(index, operation_ref_key(at: at)) { + match map_lookup(m: index, key: operation_ref_key(at: at)) { Absent => OperationHandlerRefused { cause: OperationNotBound { at: at } } Present { value: b } => OperationHandlerSelected { binding: b } } @@ -161,7 +162,7 @@ fn operation_handler_selection( // per-dispatch scan re-derived the same fact on every call (DESIGN section 2). Admission has already // refused a realization that binds one identity twice, so each key holds exactly one binding. fn operation_realization_index(realization: OperationRealization) -> Map> { - fold(realization.bindings, init: empty_map(), f: fn(acc, b) { map_insert(acc, operation_ref_key(at: b.at), b) }) + fold(realization.bindings, init: empty_map(), f: fn(acc, b) { map_insert(m: acc, key: operation_ref_key(at: b.at), value: b) }) } // ADMISSION BEFORE THE SUBJECT RUNS: a realization binding one identity twice is malformed whatever From 53c1ce69d62dff6ad4b78ee1faeb5ed0ab17d0b8 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Mon, 28 Sep 2026 16:53:39 +0000 Subject: [PATCH 14/75] Matrix cost: remember each frame's handler selections; advance does nothing when nothing is due Measured on the deadline case (temporary instrumentation, reverted): the modeled dispatch was ~110ms of ~243ms CPU, and handler selection ~60ms of that -- the covering_grant fold re-derived per dispatch for ~15 distinct operations. The selection reads only the operation identity and readonly flag besides frame-fixed inputs, so the slot keeps each decided selection keyed by that complete identity. The world advance short-circuits when no BMC event, media transition or console line is due. Deadline case now 214ms local (was 307/284ms on CI runs). Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/gunbc/bmc_model.dag | 7 ++- .../mtcollins1_boot_dry_realization.dag | 19 ++++++- src/v1/stage0/src/v1_interpreter.rs | 57 ++++++++++++++----- 3 files changed, 65 insertions(+), 18 deletions(-) diff --git a/dag/gunbc/bmc_model.dag b/dag/gunbc/bmc_model.dag index a82ce78dfc8..7fd22b6d3df 100644 --- a/dag/gunbc/bmc_model.dag +++ b/dag/gunbc/bmc_model.dag @@ -167,8 +167,13 @@ fn bmc_apply_event(world: BmcWorld, event: BmcEvent, at: Second) -> BmcWorld { } } -// Every event due at or before `now` fires, in schedule order, and moves from pending to fired. +// Every event due at or before `now` fires, in schedule order, and moves from pending to fired. With +// nothing pending there is nothing to fire, and the world is returned as it is rather than rebuilt. fn bmc_advance(world: BmcWorld, now: Second) -> BmcWorld { + if count(world.pending) == 0 { world } else { bmc_advance_pending(world: world, now: now) } +} + +fn bmc_advance_pending(world: BmcWorld, now: Second) -> BmcWorld { fold(world.pending, init: bmc_with_pending(world: world, pending: [], fired: world.fired), f: fn(acc, e) { if second_count(s: e.at) <= second_count(s: now) { let applied = bmc_apply_event(world: acc, event: e.event, at: e.at) diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag index 1fbd1389723..28c827c2301 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag @@ -212,17 +212,23 @@ fn uptime_handler(w: MtCollins1BootWorld, call: OperationCall) -> OperationStep< // boot whose offset has passed is printed; it reaches each live collector's capture only if the SOL // session is open. A new boot restarts the console from its first line. fn console_advance(w: MtCollins1BootWorld, now: Second) -> MtCollins1BootWorld { + if count(w.console.lines) == 0 { w } else { console_advance_booted(w: w, now: now) } +} + +fn console_advance_booted(w: MtCollins1BootWorld, now: Second) -> MtCollins1BootWorld { match w.bmc.host_booted_at { Absent => w Present { value: booted } => { let fresh = match w.console.boot { Present { value: b } => second_count(s: b) != second_count(s: booted) Absent => true } let console = if fresh { ModeledHostConsole { lines: w.console.lines, emitted: 0, boot: Present { value: booted } } } else { w.console } + if !fresh && console.emitted >= count(console.lines) { w } else { let elapsed = (second_count(s: now) as Int) - (second_count(s: booted) as Int) let due = filter(console.lines.skip(n: console.emitted), l => (second_count(s: l.after) as Int) <= elapsed) let printed = concat_text(lines: due) let listening = w.bmc.sol_session_open && bmc_power_is_on(world: w.bmc) let fs = if listening { fold(live_collectors(w: w), init: w.fs, f: fn(acc, p) { appended(fs: acc, path: p.capture_path, text: printed) }) } else { w.fs } with_console(w: with_fs(w: w, fs: fs), console: ModeledHostConsole { lines: console.lines, emitted: console.emitted + count(due), boot: console.boot }) + } } } } @@ -235,7 +241,7 @@ fn concat_text(lines: List) -> String { // or by a deactivate -- the `ipmitool sol activate` client loses its session and exits, so its /proc // entry disappears; its pid file stays, since nothing in the realization removes it. fn collectors_follow_session(w: MtCollins1BootWorld) -> MtCollins1BootWorld { - if w.bmc.sol_session_open { w } else { + if w.bmc.sol_session_open || count(live_collectors(w: w)) == 0 { w } else { let fs = fold(live_collectors(w: w), init: w.fs, f: fn(acc, p) { ModeledFilesystem { directories: acc.directories, files: filter(acc.files, f => f.path != proc_cmdline_path(pid: p.pid)) } }) @@ -243,8 +249,17 @@ fn collectors_follow_session(w: MtCollins1BootWorld) -> MtCollins1BootWorld { } } +// Time only changes the world when something is scheduled -- a BMC event, a connecting or withdrawing +// presentation -- or when the console has lines left to print; otherwise the world is returned as it +// is, rather than rebuilt on every dispatch. +fn boot_world_idle(w: MtCollins1BootWorld) -> Bool { + count(w.bmc.pending) == 0 + && (match w.media.cd.ready_at { Absent => true Present { value: _ } => false }) + && (match w.media.withdraw_at { Absent => true Present { value: _ } => false }) +} + fn boot_advance(w: MtCollins1BootWorld, now: Second) -> MtCollins1BootWorld { - let stepped = with_media(w: with_bmc(w: w, bmc: bmc_advance(world: w.bmc, now: now)), media: megarac_media_advance(world: w.media, now: now)) + let stepped = if boot_world_idle(w: w) { w } else { with_media(w: with_bmc(w: w, bmc: bmc_advance(world: w.bmc, now: now)), media: megarac_media_advance(world: w.media, now: now)) } console_advance(w: collectors_follow_session(w: stepped), now: now) } diff --git a/src/v1/stage0/src/v1_interpreter.rs b/src/v1/stage0/src/v1_interpreter.rs index 15e2acc0f48..1c07976a545 100644 --- a/src/v1/stage0/src/v1_interpreter.rs +++ b/src/v1/stage0/src/v1_interpreter.rs @@ -7861,6 +7861,12 @@ struct ModeledRealizationSlot { /// The realization's bindings by operation identity (`operation_realization_index`), built /// once at admission so no dispatch rescans the binding list. index: Value, + /// Handler selections already decided in this frame, keyed by the COMPLETE input of + /// `operation_handler_selection` that varies: the operation's declaring file, service, + /// operation and whether it is readonly. The envelope, the realization and its index are fixed + /// for the frame's extent and the selection reads nothing else of the invocation, so a hit is + /// the same fact recomputed, never a different one. + selections: HashMap, identity: String, state: Value, /// The virtual clock, an opaque `std.measure` `Second`: the dispatcher never reads its @@ -8097,6 +8103,7 @@ fn admit_modeled_realization( envelope, realization, index, + selections: HashMap::new(), identity, state, now, @@ -8248,21 +8255,41 @@ fn dispatch_modeled_operation( }); record }; - let selection = run_in_context_with_args( - ctx, - "operation_handler_selection", - &[ - (Some("env".to_string()), envelope), - (Some("realization".to_string()), realization.clone()), - (Some("index".to_string()), index), - (Some("invocation".to_string()), invocation.clone()), - ( - Some("readonly".to_string()), - Value::Bool(op_declared_readonly(op_node, ctx)), - ), - ], - false, - )?; + let readonly = op_declared_readonly(op_node, ctx); + let selection_key = format!( + "{}#{}.{}#{}", + op_node.span.file, service_name, op_name, readonly + ); + let remembered = MODELED_REALIZATION_SLOTS.with(|slots| { + slots.borrow().last().and_then(|slot| { + slot.as_ref() + .and_then(|s| s.selections.get(&selection_key).cloned()) + }) + }); + let selection = match remembered { + Some(v) => v, + None => { + let decided = run_in_context_with_args( + ctx, + "operation_handler_selection", + &[ + (Some("env".to_string()), envelope), + (Some("realization".to_string()), realization.clone()), + (Some("index".to_string()), index), + (Some("invocation".to_string()), invocation.clone()), + (Some("readonly".to_string()), Value::Bool(readonly)), + ], + false, + )?; + MODELED_REALIZATION_SLOTS.with(|slots| { + if let Some(Some(slot)) = slots.borrow_mut().last_mut() { + slot.selections + .insert(selection_key.clone(), decided.clone()); + } + }); + decided + } + }; let (arm, fields) = variant_parts(ctx, &selection) .ok_or_else(|| modeled_refused(&key, "handler selection returned a malformed value"))?; let binding = match arm.as_str() { From 3f24cfcc61dcd77c8fb76b8696d09d553755cc3d Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Mon, 28 Sep 2026 17:55:40 +0000 Subject: [PATCH 15/75] WIP: clock jumps and cd_error_code model parameters (not yet cased) Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/gunbc/megarac_media_model.dag | 28 +++++++++++++++---- dag/gunbc/wall_clock_model.dag | 12 +++++++- .../claim/boot_world_models_witness_test.dag | 2 +- ...mtcollins1_boot_acceptance_matrix_test.dag | 6 ++-- 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/dag/gunbc/megarac_media_model.dag b/dag/gunbc/megarac_media_model.dag index 3fb72c3a749..bddadb72860 100644 --- a/dag/gunbc/megarac_media_model.dag +++ b/dag/gunbc/megarac_media_model.dag @@ -53,6 +53,8 @@ type MegaRacMediaWorld { ready_after: Second withdraw_at: Second? withdraw_after_ready: Second? + error_after_ready: Int? + error_clears_on_stop: Bool } fn megarac_cleared_cd() -> MegaRacCdRow { @@ -68,11 +70,11 @@ fn megarac_session_by_jar(world: MegaRacMediaWorld, cookie_jar: String) -> Bool } fn megarac_with_sessions(world: MegaRacMediaWorld, sessions: List, next_session: Int) -> MegaRacMediaWorld { - MegaRacMediaWorld { sessions: sessions, next_session: next_session, share: world.share, mount_cd: world.mount_cd, cd_error_code: world.cd_error_code, images: world.images, cd: world.cd, ready_after: world.ready_after, withdraw_at: world.withdraw_at, withdraw_after_ready: world.withdraw_after_ready } + MegaRacMediaWorld { sessions: sessions, next_session: next_session, share: world.share, mount_cd: world.mount_cd, cd_error_code: world.cd_error_code, images: world.images, cd: world.cd, ready_after: world.ready_after, withdraw_at: world.withdraw_at, withdraw_after_ready: world.withdraw_after_ready, error_after_ready: world.error_after_ready, error_clears_on_stop: world.error_clears_on_stop } } fn megarac_with_cd(world: MegaRacMediaWorld, cd: MegaRacCdRow) -> MegaRacMediaWorld { - MegaRacMediaWorld { sessions: world.sessions, next_session: world.next_session, share: world.share, mount_cd: world.mount_cd, cd_error_code: world.cd_error_code, images: world.images, cd: cd, ready_after: world.ready_after, withdraw_at: world.withdraw_at, withdraw_after_ready: world.withdraw_after_ready } + MegaRacMediaWorld { sessions: world.sessions, next_session: world.next_session, share: world.share, mount_cd: world.mount_cd, cd_error_code: world.cd_error_code, images: world.images, cd: cd, ready_after: world.ready_after, withdraw_at: world.withdraw_at, withdraw_after_ready: world.withdraw_after_ready, error_after_ready: world.error_after_ready, error_clears_on_stop: world.error_clears_on_stop } } type MegaRacOpened { @@ -125,8 +127,16 @@ fn megarac_start_media(world: MegaRacMediaWorld, image_name: String, image_index } } +// WHETHER A STOP CLEARS THE CD ERROR CODE IS NOT OBSERVED ON THIS FIRMWARE: the 2026-09-27 receipts show +// cd_error_code 16 standing with nothing presented, and no read after a stop was retained. The model +// takes it as a scenario parameter rather than electing an answer, so the matrix runs both. fn megarac_stop_media(world: MegaRacMediaWorld) -> MegaRacMediaWorld { - megarac_with_cd(world: world, cd: megarac_cleared_cd()) + let stopped = megarac_with_cd(world: world, cd: megarac_cleared_cd()) + if world.error_clears_on_stop { megarac_with_error(world: stopped, code: 0) } else { stopped } +} + +fn megarac_with_error(world: MegaRacMediaWorld, code: Int) -> MegaRacMediaWorld { + MegaRacMediaWorld { sessions: world.sessions, next_session: world.next_session, share: world.share, mount_cd: world.mount_cd, cd_error_code: code, images: world.images, cd: world.cd, ready_after: world.ready_after, withdraw_at: world.withdraw_at, withdraw_after_ready: world.withdraw_after_ready, error_after_ready: world.error_after_ready, error_clears_on_stop: world.error_clears_on_stop } } // A PRESENTATION CAN BE LOST AFTER IT WAS READY: withdraw_at, when set, is the instant the controller @@ -139,7 +149,7 @@ fn megarac_media_advance(world: MegaRacMediaWorld, now: Second) -> MegaRacMediaW Absent => readied Present { value: at } => if second_count(s: at) <= second_count(s: now) { - MegaRacMediaWorld { sessions: readied.sessions, next_session: readied.next_session, share: readied.share, mount_cd: readied.mount_cd, cd_error_code: readied.cd_error_code, images: readied.images, cd: megarac_cleared_cd(), ready_after: readied.ready_after, withdraw_at: none, withdraw_after_ready: readied.withdraw_after_ready } + MegaRacMediaWorld { sessions: readied.sessions, next_session: readied.next_session, share: readied.share, mount_cd: readied.mount_cd, cd_error_code: readied.cd_error_code, images: readied.images, cd: megarac_cleared_cd(), ready_after: readied.ready_after, withdraw_at: none, withdraw_after_ready: readied.withdraw_after_ready, error_after_ready: readied.error_after_ready, error_clears_on_stop: readied.error_clears_on_stop } } else { readied } } } @@ -157,9 +167,17 @@ fn megarac_media_ready(world: MegaRacMediaWorld, now: Second) -> MegaRacMediaWor // A scenario may ask for the presentation to be lost a fixed interval after it became ready; the // instant is armed when readiness arrives, so the loss follows the route rather than a guessed clock. fn megarac_withdrawal_armed(world: MegaRacMediaWorld, ready: Second) -> MegaRacMediaWorld { + let errored = match world.error_after_ready { Absent => world Present { value: code } => megarac_with_error(world: world, code: code) } + megarac_withdrawal_armed_after_error(world: errored, ready: ready) +} + +// A CD error code a scenario sets to appear with readiness: the presentation reports Started while the +// general route carries a nonzero cd_error_code, the combination the production pre-handoff recheck +// refuses. +fn megarac_withdrawal_armed_after_error(world: MegaRacMediaWorld, ready: Second) -> MegaRacMediaWorld { match world.withdraw_after_ready { Absent => world Present { value: after } => - MegaRacMediaWorld { sessions: world.sessions, next_session: world.next_session, share: world.share, mount_cd: world.mount_cd, cd_error_code: world.cd_error_code, images: world.images, cd: world.cd, ready_after: world.ready_after, withdraw_at: Present { value: second(count: second_count(s: ready) + second_count(s: after)) }, withdraw_after_ready: none } + MegaRacMediaWorld { sessions: world.sessions, next_session: world.next_session, share: world.share, mount_cd: world.mount_cd, cd_error_code: world.cd_error_code, images: world.images, cd: world.cd, ready_after: world.ready_after, withdraw_at: Present { value: second(count: second_count(s: ready) + second_count(s: after)) }, withdraw_after_ready: none, error_after_ready: world.error_after_ready, error_clears_on_stop: world.error_clears_on_stop } } } diff --git a/dag/gunbc/wall_clock_model.dag b/dag/gunbc/wall_clock_model.dag index cec79144ca2..9e2cd8f29f9 100644 --- a/dag/gunbc/wall_clock_model.dag +++ b/dag/gunbc/wall_clock_model.dag @@ -18,13 +18,23 @@ import extdeps.transports.shell { ShellProcessExited } // // It answers extdeps.clock Clock.Now in `date -u +%Y-%m-%dT%H:%M:%SZ` form, and Clock.UnixSecs and // Clock.UnixMillis in `date +%s` and `date +%s%3N` form, over the proleptic Gregorian calendar. +// A STEP IS A JUMP THE WALL CLOCK TAKES AT A VIRTUAL INSTANT: from `at` on, readings carry `by` in +// addition to the standing offset. Steps accumulate, so a backward jump followed by a forward one is two +// rows. Reading is a pure function of virtual time, so a jump needs no event to fire it. +type ModeledClockStep { + at: Second + by: SecondDisplacement +} + type ModeledWallClock { unix_at_origin: EpochSecs step: SecondDisplacement + jumps: List } fn wall_clock_unix(clock: ModeledWallClock, now: Second) -> Int { - (clock.unix_at_origin as Int) + (second_count(s: now) as Int) + second_displacement_count(d: clock.step) + let jumped = fold(clock.jumps, init: 0, f: fn(acc, j) { if second_count(s: j.at) <= second_count(s: now) { acc + second_displacement_count(d: j.by) } else { acc } }) + (clock.unix_at_origin as Int) + (second_count(s: now) as Int) + second_displacement_count(d: clock.step) + jumped } fn two_digits(n: Int) -> String { diff --git a/dag/test/claim/boot_world_models_witness_test.dag b/dag/test/claim/boot_world_models_witness_test.dag index 51e2696b9b4..c7a50bea82a 100644 --- a/dag/test/claim/boot_world_models_witness_test.dag +++ b/dag/test/claim/boot_world_models_witness_test.dag @@ -26,7 +26,7 @@ test fn the_wall_clock_renders_utc_like_date() -> Bool { // A NEGATIVE STEP IS A WALL CLOCK THAT WENT BACKWARDS while virtual time moved forward. test fn a_backward_step_reads_earlier_while_virtual_time_advances() -> Bool { - let clock = ModeledWallClock { unix_at_origin: 1790000000, step: std.measure.second_displacement(count: 0 - 120) } + let clock = ModeledWallClock { unix_at_origin: 1790000000, step: std.measure.second_displacement(count: 0 - 120), jumps: [] } wall_clock_unix(clock: clock, now: second(count: 60)) == 1789999940 } diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index 31cc33ca5e0..48d6c301ab1 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -116,6 +116,8 @@ fn healthy_media() -> MegaRacMediaWorld { ready_after: second(count: 12), withdraw_at: none, withdraw_after_ready: none, + error_after_ready: none, + error_clears_on_stop: false, } } @@ -140,7 +142,7 @@ fn world_with_console(lines: List) -> MtCollins1BootWorld { ], agent: ModeledSshAgent { socket: "/run/ssh-agent.sock", holds_fleet_key: true }, remote_hosts: [healthy_srv2()], - clock: ModeledWallClock { unix_at_origin: 1790000000, step: std.measure.second_displacement(count: 0) }, + clock: ModeledWallClock { unix_at_origin: 1790000000, step: std.measure.second_displacement(count: 0), jumps: [] }, worker: ModeledWorker { next_pid: 4000, processes: [], uptime_at_origin: 86400 }, console: ModeledHostConsole { lines: lines, emitted: 0, boot: none }, media: healthy_media(), @@ -292,7 +294,7 @@ fn media_varied(media: MegaRacMediaWorld) -> MtCollins1BootWorld { fn media_with(images: List, share: MegaRacShare, cd: MegaRacCdRow, ready_after: Int, withdraw_after_ready: Second?) -> MegaRacMediaWorld { MegaRacMediaWorld { sessions: [], next_session: 1, share: share, mount_cd: 1, cd_error_code: 0, images: images, cd: cd, - ready_after: second(count: ready_after), withdraw_at: none, withdraw_after_ready: withdraw_after_ready, + ready_after: second(count: ready_after), withdraw_at: none, withdraw_after_ready: withdraw_after_ready, error_after_ready: none, error_clears_on_stop: false, } } From fb71819228730f8d6aebbf2a6ee752be575e2ea5 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Mon, 28 Sep 2026 18:04:39 +0000 Subject: [PATCH 16/75] mtcollins1 media: a listing naming the image twice is its own typed cause with both identities, not invalid JSON (#12533 finding 5) Co-Authored-By: Claude Opus 5.5 (1M context) --- .../machine_intake/megarac_media_attach.dag | 23 +++++++++++++++---- .../mtcollins1_boot_diagnostic_bundle.dag | 6 +++++ ...megarac_media_convergence_witness_test.dag | 13 ++++++++++- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/dag/gunbc/machine_intake/megarac_media_attach.dag b/dag/gunbc/machine_intake/megarac_media_attach.dag index 7912ba29fc2..b4c1c5e1c6d 100644 --- a/dag/gunbc/machine_intake/megarac_media_attach.dag +++ b/dag/gunbc/machine_intake/megarac_media_attach.dag @@ -140,6 +140,7 @@ type MegaRacAttachOutcome | MegaRacImageListingEmpty | MegaRacImageListingUnparseable { detail: String } | MegaRacImageNotEnumerated { image_name: NonEmptyStr } + | MegaRacImageOfferedAmbiguously { image_name: NonEmptyStr, image_indices: List } | MegaRacForeignImagePresented { image_name: String, configurations: String } | MegaRacSeveralImagesPresented { configurations: String } | MegaRacStaleDetachNotAdmitted { stale_image: String, reason: NonEmptyStr } @@ -147,6 +148,7 @@ type MegaRacAttachOutcome | MegaRacRedirectionUncatalogued { image_name: String, wire: Int, configurations: String } | MegaRacRefreshClockUnreadable { detail: String, detach: MegaRacDetachEvidence } | MegaRacListingUnparseableAfterDetach { detail: String, detach: MegaRacDetachEvidence } + | MegaRacOfferedAmbiguouslyAfterDetach { image_name: NonEmptyStr, image_indices: List, detach: MegaRacDetachEvidence } | MegaRacNotEnumeratedAfterRefresh { image_name: NonEmptyStr, detach: MegaRacDetachEvidence, standing: RemoteMediaMountStanding } // THREE INDICES, THREE CONCEPTS, NEVER JOINED. image_list_index is the image's position in @@ -392,11 +394,14 @@ fn json_number_member(doc: JsonValue, key: String) -> String? { // Only then is the name counted, and a count above one is ambiguous. Unrelated optional members are // not required. A listing that names the image twice is ambiguous // and refuses (side-chat review 5331991982): taking the first match would let the controller's -// enumeration order choose which file is attached. +// enumeration order choose which file is attached. The ambiguity carries every matching row's +// image_index -- the identities the refusal is about -- so it is reported as what it is, a +// well-formed listing offering one name twice, and never folded into an unreadable document; a +// matching row with no numeric image_index is an unread member, exactly as on the unique arm. type ImageIndexLookup = ImageIndexUnique { image_index: String } | ImageIndexAbsent - | ImageIndexAmbiguous { count: Int } + | ImageIndexAmbiguous { image_indices: List } | ImageIndexUnreadable fn image_index_named(elements: List, image_name: String) -> ImageIndexLookup { @@ -405,8 +410,11 @@ fn image_index_named(elements: List, image_name: String) -> ImageInde ImageIndexUnreadable } else { let named = elements |> filter(e => match json_string_member(doc: e, key: "image_name") { Present { value: n } => n == image_name Absent => false }) - if (named |> count) > 1 { - ImageIndexAmbiguous { count: named |> count } + let indices = named |> flat_map(e => match json_number_member(doc: e, key: "image_index") { Present { value: idx } => [idx] Absent => [] }) + if (indices |> count) < (named |> count) { + ImageIndexUnreadable + } else if (named |> count) > 1 { + ImageIndexAmbiguous { image_indices: indices } } else { match named.first() { Absent => ImageIndexAbsent @@ -899,6 +907,7 @@ fn megarac_attach_from_listing( ImagesListingUnparseable { detail: d } => MegaRacImageListingUnparseable { detail: d } ImagesListingEmpty => MegaRacImageListingEmpty ImagesListingLacks => MegaRacImageNotEnumerated { image_name: image_name } + ImagesListingOffersAmbiguously { image_indices: ids } => MegaRacImageOfferedAmbiguously { image_name: image_name, image_indices: ids } ImagesListingOffers { image_index: idx } => megarac_start_then_readiness( bmc_host: bmc_host, @@ -1043,6 +1052,7 @@ fn megarac_enumerate_then_attach( ) { EnumerationClockUnreadable { detail: d } => MegaRacRefreshClockUnreadable { detail: d, detach: detach } EnumerationUnparseable { detail: d } => MegaRacListingUnparseableAfterDetach { detail: d, detach: detach } + EnumerationAmbiguous { image_indices: ids } => MegaRacOfferedAmbiguouslyAfterDetach { image_name: image_name, image_indices: ids, detach: detach } NotEnumeratedAfterRefresh { standing: st } => MegaRacNotEnumeratedAfterRefresh { image_name: image_name, detach: detach, standing: st } EnumeratedAfterRefresh { image_index: idx } => megarac_start_then_readiness( @@ -1118,6 +1128,7 @@ type EnumerationAfterRefresh = EnumeratedAfterRefresh { image_index: String } | NotEnumeratedAfterRefresh { standing: RemoteMediaMountStanding } | EnumerationUnparseable { detail: String } + | EnumerationAmbiguous { image_indices: List } | EnumerationClockUnreadable { detail: String } // A LISTING THAT REFUSES IS PENDING, A LISTING THAT PARSES AND LACKS THE NAME IS ABSENT, AND BOTH @@ -1147,6 +1158,7 @@ fn megarac_await_enumeration( ClockUnixMillisObserved { millis: now } => match reading { ImagesListingUnparseable { detail: d } => EnumerationUnparseable { detail: d } + ImagesListingOffersAmbiguously { image_indices: ids } => EnumerationAmbiguous { image_indices: ids } _ => { let evidence = content_hash_of_value(value: concat("megarac-remote-images:", images.body) as NonEmptyStr) let seen = observations.append(RemoteMediaListingObservation { @@ -1209,6 +1221,7 @@ type ImagesListingReading | ImagesListingEmpty | ImagesListingLacks | ImagesListingOffers { image_index: String } + | ImagesListingOffersAmbiguously { image_indices: List } fn images_listing_reading(body: String, image_name: NonEmptyStr) -> ImagesListingReading { match parse_json_document(s: body) { @@ -1223,7 +1236,7 @@ fn images_listing_reading(body: String, image_name: NonEmptyStr) -> ImagesListin match image_index_named(elements: elements, image_name: image_name as String) { ImageIndexAbsent => ImagesListingLacks ImageIndexUnique { image_index: idx } => ImagesListingOffers { image_index: idx } - ImageIndexAmbiguous { count: _ } => ImagesListingUnparseable { detail: concat("the listing names the image more than once, so its index is ambiguous: ", body) } + ImageIndexAmbiguous { image_indices: ids } => ImagesListingOffersAmbiguously { image_indices: ids } ImageIndexUnreadable => ImagesListingUnparseable { detail: concat("the listing has a row without one readable string image_name, or names the image without a numeric image_index: ", body) } } } diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_diagnostic_bundle.dag b/dag/gunbc/machine_intake/mtcollins1_boot_diagnostic_bundle.dag index de04cb86ff1..34454352ed5 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_diagnostic_bundle.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_diagnostic_bundle.dag @@ -105,6 +105,7 @@ import gunbc.machine_intake_megarac_media_attach { MegaRacImageListingEmpty, MegaRacImageListingUnparseable, MegaRacImageNotEnumerated, + MegaRacImageOfferedAmbiguously, MegaRacForeignImagePresented, MegaRacSeveralImagesPresented, MegaRacStaleDetachNotAdmitted, @@ -112,6 +113,7 @@ import gunbc.machine_intake_megarac_media_attach { MegaRacRedirectionUncatalogued, MegaRacRefreshClockUnreadable, MegaRacListingUnparseableAfterDetach, + MegaRacOfferedAmbiguouslyAfterDetach, MegaRacMediaStateUnestablished, MegaRacMediaStateUnestablishedBeforeWrite, MegaRacReadinessClockIncoherent, @@ -531,6 +533,8 @@ fn media_attach_outcome_reason(outcome: MegaRacAttachOutcome) -> String? { MegaRacImageListingEmpty => Present { value: "the image is not presented AND the controller offers no image available to attach, and nothing is presented to stop (stopping is what re-enumerates the share); check that the export is reachable from the controller and holds the file" } MegaRacImageListingUnparseable { detail: d } => Present { value: concat("the images listing was not valid JSON: ", d) } + MegaRacImageOfferedAmbiguously { image_name: n, image_indices: ids } => + Present { value: join(["the controller offers '", n as String, "' more than once (image_index ", join(ids, ", "), "), so which file would be attached is the controller's enumeration order; nothing was written"], "") } MegaRacImageNotEnumerated { image_name: n } => Present { value: concat("the image is not presented, and the controller offers other images but not '", concat(n as String, "'; nothing is presented to stop, and stopping is what re-enumerates the share, so check that the export holds exactly that file")) } MegaRacForeignImagePresented { image_name: n, configurations: c } => @@ -545,6 +549,8 @@ fn media_attach_outcome_reason(outcome: MegaRacAttachOutcome) -> String? { Present { value: join(["the row presenting '", n, "' reports redirection_status ", to_string(w), ", which is uncatalogued for this firmware; refusing before any write or power action: ", c], "") } MegaRacRefreshClockUnreadable { detail: d, detach: x } => Present { value: join(["the clock could not be read, so the re-enumeration window could not be declared or judged: ", d, " (the detach had been executed: ", detach_evidence_text(detach: x), ")"], "") } MegaRacListingUnparseableAfterDetach { detail: d, detach: x } => Present { value: join(["after the stale image was stopped (", detach_evidence_text(detach: x), "), the images listing was not valid JSON: ", d], "") } + MegaRacOfferedAmbiguouslyAfterDetach { image_name: n, image_indices: ids, detach: x } => + Present { value: join(["after the stale image was stopped (", detach_evidence_text(detach: x), "), the controller offers '", n as String, "' more than once (image_index ", join(ids, ", "), "), so which file would be attached is the controller's enumeration order; nothing further was written"], "") } MegaRacMediaStateUnestablished { image_name: n, route: r, look: l, looks: k, cd_before_any_write: cb, cd_at_ready: ca, general_at_ready: g } => Present { value: join(["this attempt cannot establish the media state of '", n as String, "': the presentation read Started (", readiness_look_text(l: l), ", ", to_string(k), " looks, route: ", attach_route_text(route: r), ") but cd_error_code before any write was ", cd_reading_text(r: cb), " and at readiness ", cd_reading_text(r: ca), " (general settings ", raw_read_text(r: g), "). Its meaning is unresolved, so this is a knowledge refusal, not a controller verdict. No boot-device or power handoff was made"], "") } MegaRacMediaStateUnestablishedBeforeWrite { cd_before_any_write: cb, reason: why } => diff --git a/dag/test/claim/machine_intake/megarac_media_convergence_witness_test.dag b/dag/test/claim/machine_intake/megarac_media_convergence_witness_test.dag index 030d5cd8f77..f4b8fa793a0 100644 --- a/dag/test/claim/machine_intake/megarac_media_convergence_witness_test.dag +++ b/dag/test/claim/machine_intake/megarac_media_convergence_witness_test.dag @@ -69,6 +69,7 @@ import gunbc.machine_intake_megarac_media_attach { RouteReplaced, ImagesListingOffers, ImagesListingUnparseable, + ImagesListingOffersAmbiguously, images_listing_reading, ConvergeStepAttachFromListing, attach_readiness, @@ -83,6 +84,7 @@ import gunbc.machine_intake_megarac_media_attach { MegaRacMediaStateUnestablished, MegaRacMediaStateUnestablishedBeforeWrite, MegaRacListingUnparseableAfterDetach, + MegaRacImageOfferedAmbiguously, MegaRacConfigurationsUnreadable, ReadinessClockIncoherent, ReadinessMalformed, @@ -712,10 +714,19 @@ test fn desired_beside_a_foreign_image_refuses_as_foreign_in_both_orders() -> Bo test fn a_listing_naming_the_image_twice_is_ambiguous_not_first_match() -> Bool { let listing = join(["[{\"image_name\":\"", desired_census as String, "\",\"image_index\":2},{\"image_name\":\"", desired_census as String, "\",\"image_index\":5}]"], "") - (match images_listing_reading(body: listing, image_name: desired_census) { ImagesListingUnparseable { detail: d } => string_contains(s: d, pattern: "ambiguous") _ => false }) + (match images_listing_reading(body: listing, image_name: desired_census) { ImagesListingOffersAmbiguously { image_indices: ids } => ids == ["2", "5"] _ => false }) && (match images_listing_reading(body: join(["[{\"image_name\":\"", desired_census as String, "\",\"image_index\":5}]"], ""), image_name: desired_census) { ImagesListingOffers { image_index: i } => i == "5" _ => false }) } +// A VALID LISTING THAT NAMES THE IMAGE TWICE IS NOT AN UNREADABLE DOCUMENT (gunbc#12533 finding 5). +// Its cause names both offered identities and never says "not valid JSON"; the red is the old label. +// A duplicated row whose image_index is not numeric stays an unread member, as on the unique arm. +test fn a_duplicate_listing_reports_both_identities_not_invalid_json() -> Bool { + let reason = media_attach_outcome_reason(outcome: MegaRacImageOfferedAmbiguously { image_name: desired_census, image_indices: ["2", "5"] }) + (match reason { Present { value: r } => string_contains(s: r, pattern: "(image_index 2, 5)") && string_contains(s: r, pattern: desired_census as String) && string_contains(s: r, pattern: "JSON") == false Absent => false }) + && (match images_listing_reading(body: join(["[{\"image_name\":\"", desired_census as String, "\",\"image_index\":2},{\"image_name\":\"", desired_census as String, "\"}]"], ""), image_name: desired_census) { ImagesListingUnparseable { detail: _ } => true _ => false }) +} + // ─── THE CODE'S DISPOSITION ON EVERY ROUTE ─────────────────────────────────────────────────────── data cd_unread: CdErrorReading = CdErrorUnread { detail: "cd_error_code missing" } From cfe96188cd6487aec8fd26c853cb136b660253e7 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Mon, 28 Sep 2026 18:05:56 +0000 Subject: [PATCH 17/75] mtcollins1 boot: a presentation affirmed lost after a confirmed handoff is the attempt's named cause (#12533 finding 4) Co-Authored-By: Claude Opus 5.5 (1M context) --- .../mtcollins1_boot_diagnostic_bundle.dag | 64 +++++++++++++++++++ .../machine_intake/mtcollins1_boot_run.dag | 4 +- ...megarac_media_convergence_witness_test.dag | 35 +++++++++- 3 files changed, 100 insertions(+), 3 deletions(-) diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_diagnostic_bundle.dag b/dag/gunbc/machine_intake/mtcollins1_boot_diagnostic_bundle.dag index de04cb86ff1..ca75477b210 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_diagnostic_bundle.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_diagnostic_bundle.dag @@ -696,6 +696,70 @@ fn end_media_text(e: MtCollins1EndMedia) -> String { } } +// A PRESENTATION AFFIRMED LOST AFTER THE HANDOFF IS A CAUSE, NOT ONLY A FINDING (gunbc#12533 +// finding 4). The after-handoff and end-of-attempt looks are taken for this attempt's own subject, +// under the hold, after the boot override and the power action were made. When either AFFIRMS the +// medium is no longer served, the host was booting from a medium the controller had stopped +// serving, and a failure the attempt reports afterwards -- a watch that reaches its deadline -- is +// that loss seen from downstream. So the attempt's verdict consumes the looks it took rather than +// leaving them to the bundle. Only an affirmed loss attributes: an unobserved or unestablished look +// says nothing about the medium and is never promoted to a cause. The earliest affirming look is +// named, because the phase is what the operator acts on. +type MediaLossPhase + = MediaLostAtAfterHandoff + | MediaLostAtEndOfAttempt + +fn media_loss_phase_text(p: MediaLossPhase) -> String { + match p { + MediaLostAtAfterHandoff => "after-handoff" + MediaLostAtEndOfAttempt => "end-of-attempt" + } +} + +type MediaLossAfterHandoff + = MediaLossAffirmed { phase: MediaLossPhase, reason: NonEmptyStr } + | MediaLossNotAffirmed + +fn media_loss_of_look(look: MegaRacAttachResult, phase: MediaLossPhase) -> MediaLossAfterHandoff { + match presentation_still_served(result: look) { + PresentationNoLongerReady { reason: why } => MediaLossAffirmed { phase: phase, reason: why } + _ => MediaLossNotAffirmed + } +} + +// PURE, over the two looks only a CONFIRMED handoff makes causal: a handoff that was withheld or +// never reached made no boot write, and one attempted but unconfirmed already carries its own cause +// (the handoff's), so neither is re-attributed to the medium. +fn media_loss_after_handoff(handoff: MtCollins1HandoffMedia, end: MtCollins1EndMedia) -> MediaLossAfterHandoff { + match handoff { + HandoffMediaAttempted { before: _, handoff: HandoffConfirmed, after: a } => + match media_loss_of_look(look: a, phase: MediaLostAtAfterHandoff) { + MediaLossAffirmed { phase: p, reason: r } => MediaLossAffirmed { phase: p, reason: r } + MediaLossNotAffirmed => + match end { + EndMediaObserved { look: l } => media_loss_of_look(look: l, phase: MediaLostAtEndOfAttempt) + EndMediaNotTaken { reason: _ } => MediaLossNotAffirmed + } + } + _ => MediaLossNotAffirmed + } +} + +// THE ATTEMPT'S TERMINAL CAUSE. A success stands -- the host reported its census, so whatever the +// controller did afterwards did not stop it (the finding still records the loss) -- and a failure is +// re-attributed to the loss, keeping the downstream symptom beside it rather than discarding it. +fn outcome_attributing_media_loss(outcome: ProcessExit, loss: MediaLossAfterHandoff) -> ProcessExit { + match outcome { + ExitSuccess => ExitSuccess + ExitFailure { code: c, reason: r } => + match loss { + MediaLossNotAffirmed => ExitFailure { code: c, reason: r } + MediaLossAffirmed { phase: p, reason: why } => + ExitFailure { code: c, reason: join(["mtcollins1 boot: media presentation lost at ", media_loss_phase_text(p: p), " (", why as String, "); the attempt then reported: ", r], "") } + } + } +} + type MtCollins1BootRunRecord { end_media: MtCollins1EndMedia handoff_media: MtCollins1HandoffMedia diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_run.dag b/dag/gunbc/machine_intake/mtcollins1_boot_run.dag index b26183c5d17..4231ce94b73 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_run.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_run.dag @@ -79,7 +79,7 @@ import gunbc.machine_intake_mtcollins1_boot_diagnostic_bundle { mtcollins1_boot_sel_snapshot, mtcollins1_boot_inventory, mtcollins1_boot_console, mtcollins1_boot_write_bundle, mtcollins1_boot_outcome_after_bundle, mtcollins1_boot_bundle_findings, bundle_write_receipt_line, mtcollins1_boot_diagnostics_allowance, AttemptIdentityReading, AttemptRunId, AttemptIdentityUnavailable, attempt_identity_text, - SmproReading, BootParam5Reading, BootParam5NotTaken, BootParam5Read, BootParam5Unread, PowerAfterUnobserved, MtCollins1BootRunRecord, run_record_not_taken, MtCollins1MediaAttachRecord, MediaAttachNotAttempted, MtCollins1HandoffMedia, recheck_text, MtCollins1EndMedia, EndMediaNotTaken, EndMediaObserved, HandoffMediaNotReached, HandoffMediaWithheldAtRecheck, HandoffMediaAttempted, HandoffConfirmed, HandoffAttemptedUnconfirmed, end_media_is_owed, mtcollins1_boot_param5, mtcollins1_boot_chassis_power, + SmproReading, BootParam5Reading, BootParam5NotTaken, BootParam5Read, BootParam5Unread, PowerAfterUnobserved, MtCollins1BootRunRecord, run_record_not_taken, MtCollins1MediaAttachRecord, MediaAttachNotAttempted, MtCollins1HandoffMedia, recheck_text, MtCollins1EndMedia, EndMediaNotTaken, EndMediaObserved, HandoffMediaNotReached, HandoffMediaWithheldAtRecheck, HandoffMediaAttempted, HandoffConfirmed, HandoffAttemptedUnconfirmed, end_media_is_owed, media_loss_after_handoff, outcome_attributing_media_loss, mtcollins1_boot_param5, mtcollins1_boot_chassis_power, PowerAfterAttempt, PoweredOffAfterCensusEnd, PoweredOffWithoutCensusEnd, PoweredOnAfterAttempt, PowerAfterNotTaken, power_after_attempt, OverrideNotHandedOff, boot_override_consumption, } import std.dissolution { dissolution_description } @@ -1316,7 +1316,7 @@ fn mtcollins1_boot_actuate( exit_failure(reason: "mtcollins1 boot: SOL pid file stale after deactivate") _ => ExitSuccess } - other => other + other => outcome_attributing_media_loss(outcome: other, loss: media_loss_after_handoff(handoff: gated.media, end: end_media)) }, stage: observed.stage, timing: mtcollins1_boot_phase_timing_of( diff --git a/dag/test/claim/machine_intake/megarac_media_convergence_witness_test.dag b/dag/test/claim/machine_intake/megarac_media_convergence_witness_test.dag index 030d5cd8f77..ab7a9d2152e 100644 --- a/dag/test/claim/machine_intake/megarac_media_convergence_witness_test.dag +++ b/dag/test/claim/machine_intake/megarac_media_convergence_witness_test.dag @@ -2,6 +2,7 @@ module test.claim.machine_intake.megarac_media_convergence_witness_test import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } import std.types { Bool, EpochMs, List, NonEmptyStr, String } +import std.process { ProcessExit, ExitSuccess, ExitFailure } import std.content_hash { ContentHash, content_hash_of_value } import extdeps.bmc.megarac { megarac_firmware_0_32 } import extdeps.provisioning.ubuntu_seeded_install_media { ubuntu_seeded_install_media_image_name, ubuntu_seeded_install_media_name_digest_prefix } @@ -106,7 +107,7 @@ import gunbc.machine_intake_megarac_media_attach { SessionReleaseNotAttempted, } import extdeps.bmc.ipmi_chassis_control { ChassisPowerRead } -import gunbc.machine_intake_mtcollins1_boot_diagnostic_bundle { media_attach_text, media_attach_outcome_reason, MediaAttachAttempted, MtCollins1MediaAttachRecord, detach_evidence_text, HandoffMediaAttempted, HandoffConfirmed, HandoffAttemptedUnconfirmed, MediaAttachNotAttempted, end_media_is_owed, HandoffMediaWithheldAtRecheck, handoff_media_findings } +import gunbc.machine_intake_mtcollins1_boot_diagnostic_bundle { media_attach_text, media_attach_outcome_reason, MediaAttachAttempted, MtCollins1MediaAttachRecord, detach_evidence_text, HandoffMediaAttempted, HandoffConfirmed, HandoffAttemptedUnconfirmed, MediaAttachNotAttempted, end_media_is_owed, HandoffMediaWithheldAtRecheck, handoff_media_findings, MtCollins1HandoffMedia, MtCollins1EndMedia, EndMediaObserved, EndMediaNotTaken, media_loss_after_handoff, outcome_attributing_media_loss } import gunbc.machine_intake_mtcollins1_media_attach { MediaGateReady, MediaGateWithheld, mtcollins1_media_gate, mtcollins1_media_share } data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly @@ -573,6 +574,38 @@ test fn a_withdrawn_row_after_the_handoff_is_an_affirmed_loss() -> Bool { only_finding_contains(findings: handoff_media_findings(h: HandoffMediaAttempted { before: served_look, handoff: HandoffConfirmed, after: observed(general: mtcollins1_media_general_2026_09_27_morning_as_reported, configurations: "[]") }), pattern: "LOST at or after") } +// A LOSS AFFIRMED AFTER A CONFIRMED HANDOFF IS THE ATTEMPT'S CAUSE (gunbc#12533 finding 4): the +// deadline failure is re-attributed to "media presentation lost at ", the earliest affirming +// look is the phase, and the downstream reason is kept. Controls, each on the same failure: a +// served look, an UNOBSERVED look, and an unconfirmed handoff leave the reason as it was; a success +// stands over an affirmed loss. +data withdrawn_look: MegaRacAttachResult = observed(general: mtcollins1_media_general_2026_09_27_morning_as_reported, configurations: "[]") +data deadline_failure: ProcessExit = ExitFailure { code: 1, reason: "mtcollins1 boot: deadline reached without a host-capture terminal" } + +fn attributed_reason(handoff: MtCollins1HandoffMedia, end: MtCollins1EndMedia) -> String { + match outcome_attributing_media_loss(outcome: deadline_failure, loss: media_loss_after_handoff(handoff: handoff, end: end)) { + ExitFailure { code: _, reason: r } => r + ExitSuccess => "" + } +} + +test fn a_presentation_lost_after_a_confirmed_handoff_is_the_named_cause() -> Bool { + let at_after = attributed_reason(handoff: HandoffMediaAttempted { before: served_look, handoff: HandoffConfirmed, after: withdrawn_look }, end: EndMediaObserved { look: withdrawn_look }) + let at_end = attributed_reason(handoff: HandoffMediaAttempted { before: served_look, handoff: HandoffConfirmed, after: served_look }, end: EndMediaObserved { look: withdrawn_look }) + starts_with(s: at_after, prefix: "mtcollins1 boot: media presentation lost at after-handoff (") + && string_contains(s: at_after, pattern: "deadline reached without a host-capture terminal") + && starts_with(s: at_end, prefix: "mtcollins1 boot: media presentation lost at end-of-attempt (") +} + +test fn an_unaffirmed_look_or_an_unconfirmed_handoff_leaves_the_cause_alone() -> Bool { + let failed = MegaRacAttachResult { outcome: MegaRacSessionRefused { detail: "curl: (7)" }, session_release: SessionReleaseNotAttempted, baseline: none } + let unchanged = "mtcollins1 boot: deadline reached without a host-capture terminal" + attributed_reason(handoff: HandoffMediaAttempted { before: served_look, handoff: HandoffConfirmed, after: served_look }, end: EndMediaObserved { look: served_look }) == unchanged + && attributed_reason(handoff: HandoffMediaAttempted { before: served_look, handoff: HandoffConfirmed, after: failed }, end: EndMediaObserved { look: failed }) == unchanged + && attributed_reason(handoff: HandoffMediaAttempted { before: served_look, handoff: HandoffAttemptedUnconfirmed { reason: "no read-back" }, after: withdrawn_look }, end: EndMediaObserved { look: withdrawn_look }) == unchanged + && (match outcome_attributing_media_loss(outcome: ExitSuccess, loss: media_loss_after_handoff(handoff: HandoffMediaAttempted { before: served_look, handoff: HandoffConfirmed, after: withdrawn_look }, end: EndMediaNotTaken { reason: "x" })) { ExitSuccess => true _ => false }) +} + // THE DISCRIMINATING CONTROL: a failed session with the prior good presentation unchanged is // UNOBSERVED, never LOST. test fn a_failed_look_is_indeterminate_not_lost() -> Bool { From 60dbd2b81cec64013691fed1acf36b13c4b8939b Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Mon, 28 Sep 2026 18:10:40 +0000 Subject: [PATCH 18/75] mtcollins1 unit hold: a boot's hold names its process, and a successor recovers it only once that process is observed dead (#12533 finding 2) Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/extdeps/linux/proc_pid_stat.dag | 17 + .../durable_exclusive_hold_file_store.dag | 44 +++ .../mtcollins1_maintenance_hold.dag | 296 +++++++++++++++++- dag/std/durable_exclusive_hold.dag | 69 ++++ .../durable_exclusive_hold_witness_test.dag | 55 +++- ...collins1_maintenance_hold_witness_test.dag | 31 +- 6 files changed, 491 insertions(+), 21 deletions(-) diff --git a/dag/extdeps/linux/proc_pid_stat.dag b/dag/extdeps/linux/proc_pid_stat.dag index bcb5e0ab8bd..ba216f91da5 100644 --- a/dag/extdeps/linux/proc_pid_stat.dag +++ b/dag/extdeps/linux/proc_pid_stat.dag @@ -112,3 +112,20 @@ fn proc_pid_stat_start_time(content: String) -> ProcPidStatStartTime { fn process_start_epoch_seconds(boot_epoch_seconds: EpochSecs, ticks_per_second: Hertz, start_ticks: Int) -> Int { boot_epoch_seconds + (start_ticks / hertz_count(h: ticks_per_second)) } + +// FIELD 1, pid (proc_pid_stat(5)): "The process ID." It precedes comm, so it is the text before the +// FIRST " (" -- comm is parenthesized and may contain anything, but nothing precedes it except the pid +// and one space. Read through /proc/self/stat this is how a process learns its own pid from the same +// file that carries its starttime, so the pair is one reading of one process, not two. +type ProcPidStatPid + = PidObserved { pid: Int } + | PidUnparseable { field: String } + +fn proc_pid_stat_pid(content: String) -> ProcPidStatPid { + let line = trim(s: content) + let field = match split(s: line, delimiter: " ").first() { Present { value: w } => w Absent => "" } + match parse_int(s: field) { + Present { value: pid } => if pid > 0 { PidObserved { pid: pid } } else { PidUnparseable { field: field } } + Absent => PidUnparseable { field: field } + } +} diff --git a/dag/gunbc/durable_exclusive_hold_file_store.dag b/dag/gunbc/durable_exclusive_hold_file_store.dag index 5f6e68cef07..7063c99497d 100644 --- a/dag/gunbc/durable_exclusive_hold_file_store.dag +++ b/dag/gunbc/durable_exclusive_hold_file_store.dag @@ -23,6 +23,7 @@ module gunbc.durable_exclusive_hold_file_store // pins the specimens byte-for-byte. import std.types { NonEmptyStr, String } +import std.decl_ref { decl_ref } import std.durable_compare_and_set { CasExpectation, ExpectSlotGeneration, CasCommitted, CasPreconditionFailed, CasStoreRefused, CasStoreFailure, CasSlotObservationRefused, @@ -38,6 +39,8 @@ import std.durable_exclusive_hold { HoldAcquireOccupied, HoldAcquireSlotUndecodable, HoldAcquireObservationUnavailable, HoldReleaseEligible, HoldReleaseRefused, DurableHoldReleaseRefusal, durable_hold_acquire_assess, durable_hold_release_assess, + DurableHoldHolderReport, DurableHoldRecoveryRefusal, HoldRecoveryEligible, HoldRecoveryRefused, + durable_hold_recovery_assess, } import gunbc.durable_cas_file_store { DefaultAccessCreateOnly, DerivedPayloadAdmitted, DerivedPayloadKeyNotSlotAddressable, @@ -323,3 +326,44 @@ fn file_hold_release_commit(plan: FileHoldReleasePlan) -> FileHoldReleaseOutcome } } } + +// RECOVERING A DEAD HOLDER'S HOLD FREES IT THROUGH THE SAME PLAN AND COMMIT AS A RELEASE: the write +// is identical -- held at N becomes free at N+1 -- and only the eligibility differs (the holder was +// observed dead rather than presenting itself). So the plan is minted here from THIS live read, bound +// to the report's holder and generation, and committed by file_hold_release_commit, which still tells +// a slot that moved after this read (Lost) from a store fault. The released_by carries the dead holder +// and the evidence, so the freed slot says why it was freed. +// +// The report is a verdict about the world that only the observing consumer can take, so this mint +// admits its callers by name: a caller that could hand it an authored HolderObservedDead would be the +// forged-release path the release plan's sole_constructor exists to close. +type FileHoldRecoveryAssessment + = FileHoldRecoveryPlanned { plan: FileHoldReleasePlan, dead_holder: DurableHoldOwnerRef, evidence: NonEmptyStr } + | FileHoldRecoveryNotEligible { slot_key: NonEmptyStr, refusal: DurableHoldRecoveryRefusal } + +fn file_hold_recovery_assess( + root: NonEmptyStr, + slot_key: NonEmptyStr, + report: DurableHoldHolderReport, + released_by: DurableHoldReleaseRef, +) -> FileHoldRecoveryAssessment + admit_callers: [ + decl_ref(module_path: "gunbc.machine_intake_mtcollins1_maintenance_hold", decl_name: "unit_hold_recover_dead_holder"), + ] +{ + match durable_hold_recovery_assess(observed: observe_file_hold(root: root, key: slot_key), report: report) { + HoldRecoveryRefused { refusal: r } => FileHoldRecoveryNotEligible { slot_key: slot_key, refusal: r } + HoldRecoveryEligible { generation: g, dead_holder: h, evidence: e } => + FileHoldRecoveryPlanned { + plan: FileHoldReleasePlan { + root: root, + slot_key: slot_key, + owner: h, + generation: g, + free_payload: hold_slot_payload(state: DurableHoldFree { released_by: released_by }), + }, + dead_holder: h, + evidence: e, + } + } +} diff --git a/dag/gunbc/machine_intake/mtcollins1_maintenance_hold.dag b/dag/gunbc/machine_intake/mtcollins1_maintenance_hold.dag index 99d0b48bc47..1c4220eb2e3 100644 --- a/dag/gunbc/machine_intake/mtcollins1_maintenance_hold.dag +++ b/dag/gunbc/machine_intake/mtcollins1_maintenance_hold.dag @@ -7,6 +7,22 @@ import v2.std.optional { Present, Absent } import std.durable_exclusive_hold { DurableHoldOwnerRef, DurableHoldReleaseRef, HoldSlotAbsent, HoldSlotFree, HoldSlotHeld, HoldSlotUndecodable, HoldObservationUnavailable, + DurableHoldHolderLiveness, HolderObservedLive, HolderObservedDead, HolderLivenessUnobservable, + DurableHoldHolderReport, DurableHoldRecoveryRefusal, + HoldRecoveryNothingHeld, HoldRecoveryHolderLive, HoldRecoveryHolderUnobservable, HoldRecoverySlotMoved, + HoldRecoveryReportForAnotherHolder, HoldRecoverySlotUndecodable, HoldRecoveryObservationUnavailable, +} +import std.nat { Nat } +import std.checked_arithmetic { checked_int_to_nat } +import std.algebra { trim } +import gunbc.build_cache_instance { ProcessIdentity, process_identity_eq } +import extdeps.linux.proc_pid_stat { + proc_pid_stat_start_time, StartTimeObserved, StartTimeCommUnterminated, StartTimeFieldAbsent, StartTimeUnparseable, + proc_pid_stat_pid, PidObserved, PidUnparseable, +} +import extdeps.filesystem.filesystem_io { + Filesystem, filesystem_exact_read, FilesystemExactRead, FilesystemExactPathRead, FilesystemExactPathAbsent, + FilesystemExactPathUnreadable, FilesystemExactPathKindUnrecognized, } import gunbc.durable_exclusive_hold_file_store { FileHoldAcquireOutcome, FileHoldAcquired, FileHoldOccupied, FileHoldAcquireLost, @@ -14,6 +30,7 @@ import gunbc.durable_exclusive_hold_file_store { FileHoldReleasePlanned, FileHoldReleaseNotEligible, FileHoldReleased, FileHoldReleaseLost, FileHoldReleaseStoreUnavailable, FileHoldReleaseKeyNotSlotAddressable, file_hold_acquire, file_hold_release_assess, file_hold_release_commit, observe_file_hold, + FileHoldRecoveryPlanned, FileHoldRecoveryNotEligible, file_hold_recovery_assess, } import gunbc.actions_run_binding { actions_variable_trimmed } import std.decl_ref { decl_ref } @@ -52,23 +69,66 @@ data mtcollins1_unit_hold_store_host: NonEmptyStr = operator_host_srv1 as NonEmp // WHO HOLDS THE UNIT IS A DECLARED SUM (review 70459), each kind carrying its detail. The durable // owner string is RENDERED from it and DECODED back to it here, in one place: nothing else builds an // owner string or reads a kind out of one. +// +// A BOOT RUN IS A PROCESS, SO ITS OWNER NAMES THE PROCESS (gunbc#12533 finding 2). A run id alone +// says which attempt took the slot and nothing about whether that attempt is still running, so a +// worker killed while holding the unit left a hold nobody could ever show to be dead, and every later +// attempt refused on it. The boot's owner therefore carries the holding process's identity -- boot id, +// pid and start time, gunbc.build_cache_instance ProcessIdentity, the triple that survives pid reuse +// and reboots -- and a successor recovers the slot only after OBSERVING that process gone. An operator +// maintenance hold is deliberately not a process (it outlives the session that took it), so it is +// never recovered; a host reset-return hold names no process yet, so it is never recovered either. type UnitHoldOwner = OperatorMaintenance { reason: NonEmptyStr } - | BootRun { run_id: NonEmptyStr } + | BootRun { run_id: NonEmptyStr, process: ProcessIdentity } | HostResetReturn { attempt: NonEmptyStr } fn unit_hold_owner_tag(o: UnitHoldOwner) -> String { match o { OperatorMaintenance { reason: _ } => "operator-maintenance:" - BootRun { run_id: _ } => "mtcollins1-boot:" + BootRun { run_id: _, process: _ } => "mtcollins1-boot:" HostResetReturn { attempt: _ } => "host-reset-return:" } } +// THE PROCESS PART OF A BOOT OWNER, rendered after the run id and decoded back here and nowhere else: +// `@boot=,pid=,start=`. +data unit_hold_process_marker: String = "@boot=" + +fn unit_hold_process_text(p: ProcessIdentity) -> String { + join([unit_hold_process_marker, p.boot_id as String, ",pid=", to_string(p.pid), ",start=", p.start_time as String], "") +} + +fn unit_hold_process_decode(text: String) -> ProcessIdentity? { + let parts = split(s: text, delimiter: ",") + if count(parts) != 3 { + none + } else { + let b = parts[0] + let pid_text = parts[1] + let start_text = parts[2] + if !starts_with(s: b, prefix: "boot=") || !starts_with(s: pid_text, prefix: "pid=") || !starts_with(s: start_text, prefix: "start=") { + none + } else { + let boot = substring(s: b, start: 5, end: string_length(b)) + let start = substring(s: start_text, start: 6, end: string_length(start_text)) + match parse_int(s: substring(s: pid_text, start: 4, end: string_length(pid_text))) { + Absent => none + Present { value: n } => + match checked_int_to_nat(n: n) { + Absent => none + Present { value: pid } => + if boot == "" || start == "" { none } else { Present { value: ProcessIdentity { boot_id: boot as NonEmptyStr, pid: pid, start_time: start as NonEmptyStr } } } + } + } + } + } +} + fn unit_hold_owner_detail(o: UnitHoldOwner) -> String { match o { OperatorMaintenance { reason: r } => r as String - BootRun { run_id: r } => r as String + BootRun { run_id: r, process: p } => concat(r as String, unit_hold_process_text(p: p)) HostResetReturn { attempt: a } => a as String } } @@ -80,7 +140,7 @@ fn unit_hold_owner_ref(o: UnitHoldOwner) -> DurableHoldOwnerRef { fn unit_hold_owner_label(o: UnitHoldOwner) -> String { match o { OperatorMaintenance { reason: r } => concat("operator maintenance: ", r as String) - BootRun { run_id: r } => concat("the mtcollins1 boot run ", r as String) + BootRun { run_id: r, process: p } => join(["the mtcollins1 boot run ", r as String, " (process ", to_string(p.pid), " on boot ", p.boot_id as String, ")"], "") HostResetReturn { attempt: a } => concat("host reset-return attempt ", a as String) } } @@ -104,7 +164,20 @@ fn decode_unit_hold_owner(owner: DurableHoldOwnerRef) -> UnitHoldOwnerDecode { if starts_with(s: raw, prefix: op) { match unit_hold_owner_detail_after(raw: raw, tag: op) { Present { value: d } => UnitHoldOwnerDecoded { owner: OperatorMaintenance { reason: d } } Absent => UnitHoldOwnerUnrecognized { raw: raw } } } else if starts_with(s: raw, prefix: boot) { - match unit_hold_owner_detail_after(raw: raw, tag: boot) { Present { value: d } => UnitHoldOwnerDecoded { owner: BootRun { run_id: d } } Absent => UnitHoldOwnerUnrecognized { raw: raw } } + match unit_hold_owner_detail_after(raw: raw, tag: boot) { + Absent => UnitHoldOwnerUnrecognized { raw: raw } + Present { value: d } => { + let halves = split(s: d as String, delimiter: unit_hold_process_marker) + if count(halves) != 2 || halves[0] == "" { + UnitHoldOwnerUnrecognized { raw: raw } + } else { + match unit_hold_process_decode(text: concat("boot=", halves[1])) { + Present { value: p } => UnitHoldOwnerDecoded { owner: BootRun { run_id: halves[0] as NonEmptyStr, process: p } } + Absent => UnitHoldOwnerUnrecognized { raw: raw } + } + } + } + } } else if starts_with(s: raw, prefix: reset) { match unit_hold_owner_detail_after(raw: raw, tag: reset) { Present { value: d } => UnitHoldOwnerDecoded { owner: HostResetReturn { attempt: d } } Absent => UnitHoldOwnerUnrecognized { raw: raw } } } else { @@ -123,15 +196,16 @@ fn operator_maintenance_owner(reason: NonEmptyStr) -> DurableHoldOwnerRef { unit_hold_owner_ref(o: OperatorMaintenance { reason: reason }) } -fn boot_run_owner(run_id: NonEmptyStr) -> DurableHoldOwnerRef { - unit_hold_owner_ref(o: BootRun { run_id: run_id }) +fn boot_run_owner(run_id: NonEmptyStr, process: ProcessIdentity) -> DurableHoldOwnerRef { + unit_hold_owner_ref(o: BootRun { run_id: run_id, process: process }) } // ── THE PROOF: MINTED ONLY INSIDE THE LIVE ACQUIRE'S FileHoldAcquired ARM ────────────────────── // Every function that performs a BMC write on a hold-gated unit takes a UnitHoldProof, and the // proof is sole_constructor: the compiler refuses a UnitHoldProof literal anywhere but this module // (SoleConstructorViolation), and this module mints one in exactly one place -- the FileHoldAcquired -// arm of unit_hold_acquire, right after the live compare-and-set landed. A supplied or authored +// arm of unit_hold_minted, admitted only to unit_hold_acquire and fed only that call's own live +// compare-and-set outcomes. A supplied or authored // acquire outcome therefore cannot become a proof: the pure refusal fold below reads outcomes, and // it returns text, never a proof. test.claim.machine_intake.mtcollins1_maintenance_hold_witness_test // enrolls test.probe.unit_hold_proof_forged_probe, where a forged proof is refused at the literal. @@ -164,15 +238,175 @@ fn unit_hold_refusal(outcome: FileHoldAcquireOutcome) -> NonEmptyStr? { } } -// THE ONE MINT. The live acquire and the proof are one boundary: the proof exists only when the -// compare-and-set this call performed committed a hold for this owner. -fn unit_hold_acquire(root: NonEmptyStr, key: NonEmptyStr, owner: DurableHoldOwnerRef) -> UnitHoldAcquisition +// ── WHETHER A HOLDING PROCESS STILL RUNS, OBSERVED ───────────────────────────────────────────── +// The store and every holder that can be recovered run on one host (mtcollins1_unit_hold_store_host; +// the boot admission refuses any other), so the holder's process is observable through this host's +// procfs. Three reads decide it, each typed by the host's own error kind: +// - /proc/sys/kernel/random/boot_id differs from the holder's boot -> the host rebooted since, so +// every process of that boot is gone: OBSERVED DEAD; +// - same boot, /proc//stat is ABSENT (the host answered NotFound) -> no such process: DEAD; +// - same boot, the stat reads and its starttime differs -> the pid was reused: DEAD; +// - same boot, same starttime -> the holder runs: LIVE. +// Any read the host refused for another reason, and any content that does not parse, is +// UNOBSERVABLE: the holder may well be alive, and nothing here concludes otherwise from a failed look. +data proc_boot_id_path: String = "/proc/sys/kernel/random/boot_id" + +data proc_self_stat_path: String = "/proc/self/stat" + +fn exact_read_of(path: String) -> FilesystemExactRead { + let read = Filesystem.Read(path: path) + filesystem_exact_read(path: path, content: read.content, success: read.success, error: read.error, error_kind: read.error_kind) +} + +type ExactText + = ExactTextRead { text: String } + | ExactTextAbsent + | ExactTextUnread { cause: NonEmptyStr } + +fn exact_text(path: String) -> ExactText { + match exact_read_of(path: path) { + FilesystemExactPathRead { path: _, content: c } => ExactTextRead { text: c } + FilesystemExactPathAbsent { path: _ } => ExactTextAbsent + FilesystemExactPathUnreadable { path: _, kind: _, error: e } => ExactTextUnread { cause: join([path, " could not be read: ", e], "") as NonEmptyStr } + FilesystemExactPathKindUnrecognized { path: _, observed: o, error: e } => ExactTextUnread { cause: join([path, " failed with an unrecognized error kind ", o, ": ", e], "") as NonEmptyStr } + } +} + +fn start_time_text(stat: String) -> String? { + match proc_pid_stat_start_time(content: stat) { + StartTimeObserved { ticks_since_boot: t } => Present { value: to_string(t) } + _ => none + } +} + +fn holder_process_liveness(p: ProcessIdentity) -> DurableHoldHolderLiveness { + match exact_text(path: proc_boot_id_path) { + ExactTextAbsent => HolderLivenessUnobservable { cause: concat(proc_boot_id_path, " is absent on this host") as NonEmptyStr } + ExactTextUnread { cause: c } => HolderLivenessUnobservable { cause: c } + ExactTextRead { text: t } => { + let now = trim(s: t) + if now == "" { + HolderLivenessUnobservable { cause: concat(proc_boot_id_path, " was empty") as NonEmptyStr } + } else if now != (p.boot_id as String) { + HolderObservedDead { evidence: join(["the host has booted since the holder started (boot ", p.boot_id as String, ", now ", now, ")"], "") as NonEmptyStr } + } else { + let stat_path = join(["/proc/", to_string(p.pid), "/stat"], "") + match exact_text(path: stat_path) { + ExactTextAbsent => HolderObservedDead { evidence: join(["no process ", to_string(p.pid), " on the holder's boot (", stat_path, " not found)"], "") as NonEmptyStr } + ExactTextUnread { cause: c } => HolderLivenessUnobservable { cause: c } + ExactTextRead { text: stat } => + match start_time_text(stat: stat) { + Absent => HolderLivenessUnobservable { cause: concat(stat_path, " carried no readable starttime") as NonEmptyStr } + Present { value: st } => + if st == (p.start_time as String) { + HolderObservedLive { evidence: join(["process ", to_string(p.pid), " started at tick ", st, " still runs"], "") as NonEmptyStr } + } else { + HolderObservedDead { evidence: join(["pid ", to_string(p.pid), " now names another process (start tick ", st, ", holder's ", p.start_time as String, ")"], "") as NonEmptyStr } + } + } + } + } + } + } +} + +// THIS PROCESS'S OWN IDENTITY, read from the same procfs a successor will read it back through: the +// boot id, and pid and starttime from ONE read of /proc/self/stat. A boot that cannot name itself does +// not take the unit -- a hold it could never be shown dead in is the lockout this replaces. +type SelfProcessIdentity + = SelfIdentified { process: ProcessIdentity } + | SelfUnidentified { cause: NonEmptyStr } + +fn self_process_identity() -> SelfProcessIdentity { + match exact_text(path: proc_boot_id_path) { + ExactTextAbsent => SelfUnidentified { cause: concat(proc_boot_id_path, " is absent on this host") as NonEmptyStr } + ExactTextUnread { cause: c } => SelfUnidentified { cause: c } + ExactTextRead { text: b } => { + let boot = trim(s: b) + match exact_text(path: proc_self_stat_path) { + ExactTextAbsent => SelfUnidentified { cause: concat(proc_self_stat_path, " is absent on this host") as NonEmptyStr } + ExactTextUnread { cause: c } => SelfUnidentified { cause: c } + ExactTextRead { text: stat } => + match proc_pid_stat_pid(content: stat) { + PidUnparseable { field: f } => SelfUnidentified { cause: concat("/proc/self/stat carried no pid: ", f) as NonEmptyStr } + PidObserved { pid: n } => + match start_time_text(stat: stat) { + Absent => SelfUnidentified { cause: "/proc/self/stat carried no readable starttime" as NonEmptyStr } + Present { value: st } => + match checked_int_to_nat(n: n) { + Absent => SelfUnidentified { cause: "/proc/self/stat pid is not a natural number" as NonEmptyStr } + Present { value: pid } => + if boot == "" { SelfUnidentified { cause: concat(proc_boot_id_path, " was empty") as NonEmptyStr } } + else { SelfIdentified { process: ProcessIdentity { boot_id: boot as NonEmptyStr, pid: pid, start_time: st as NonEmptyStr } } } + } + } + } + } + } + } +} + +// ── RECOVERING A HOLD WHOSE HOLDER WAS OBSERVED DEAD ─────────────────────────────────────────── +// Only a holder whose owner names a process can be observed, so only a decoded BootRun is looked at; +// every other owner is reported as not recoverable. The liveness verdict is bound to the holder and +// generation the refused acquire saw, and the recovery re-reads the slot, so a hold that changed hands +// in between is not the one freed. Age is never an input. +fn holder_report(holder: DurableHoldOwnerRef, generation: CasGeneration) -> DurableHoldHolderReport { + let liveness = match decode_unit_hold_owner(owner: holder) { + UnitHoldOwnerDecoded { owner: BootRun { run_id: _, process: p } } => holder_process_liveness(p: p) + UnitHoldOwnerDecoded { owner: OperatorMaintenance { reason: _ } } => + HolderLivenessUnobservable { cause: "an operator maintenance hold is not bound to a process; only the operator releases it" as NonEmptyStr } + UnitHoldOwnerDecoded { owner: HostResetReturn { attempt: _ } } => + HolderLivenessUnobservable { cause: "a host reset-return hold names no process, so its holder cannot be observed" as NonEmptyStr } + UnitHoldOwnerUnrecognized { raw: _ } => + HolderLivenessUnobservable { cause: "the holder's owner names no process this module can observe (it was written without one, or not by this module)" as NonEmptyStr } + } + DurableHoldHolderReport { holder: holder, generation: generation, liveness: liveness } +} + +type DeadHolderRecovery + = DeadHolderRecovered { dead_holder: DurableHoldOwnerRef, evidence: NonEmptyStr } + | DeadHolderNotRecovered { reason: NonEmptyStr } + +fn recovery_refusal_text(key: NonEmptyStr, r: DurableHoldRecoveryRefusal) -> NonEmptyStr { + let why = match r { + HoldRecoveryNothingHeld => "the slot was released before recovery" + HoldRecoveryHolderLive { generation: _, holder: h, evidence: e } => join(["is held by '", h as String, "', which is alive (", e as String, "); no BMC actuation until it is released"], "") + HoldRecoveryHolderUnobservable { generation: _, holder: h, cause: c } => join(["is held by '", h as String, "', whose liveness could not be observed (", c as String, "); an unobserved holder is not a dead one, so the hold stands"], "") + HoldRecoverySlotMoved { reported: _, observed: _ } => "moved while its holder was being observed; re-run" + HoldRecoveryReportForAnotherHolder { holder: h, reported: _ } => join(["changed hands to '", h as String, "' while its holder was being observed; re-run"], "") + HoldRecoverySlotUndecodable { generation: _, detail: d } => concat("became undecodable: ", d as String) + HoldRecoveryObservationUnavailable { cause: _ } => "could not be re-read for recovery; an unreadable interlock is not a released one" + } + join(["unit ", key as String, " ", why, "; controller untouched"], "") as NonEmptyStr +} + +fn unit_hold_recover_dead_holder(root: NonEmptyStr, key: NonEmptyStr, holder: DurableHoldOwnerRef, generation: CasGeneration) -> DeadHolderRecovery admit_callers: [ - decl_ref(module_path: "gunbc.machine_intake_mtcollins1_maintenance_hold", decl_name: "mtcollins1_boot_acquire_unit_hold"), - decl_ref(module_path: "gunbc.host_reset_return_run", decl_name: "host_reset_return_wet"), + decl_ref(module_path: "gunbc.machine_intake_mtcollins1_maintenance_hold", decl_name: "unit_hold_acquire"), + ] +{ + let report = holder_report(holder: holder, generation: generation) + let released_by = join(["recovered-dead-holder:", holder as String], "") as DurableHoldReleaseRef + match file_hold_recovery_assess(root: root, slot_key: key, report: report, released_by: released_by) { + FileHoldRecoveryNotEligible { slot_key: _, refusal: r } => DeadHolderNotRecovered { reason: recovery_refusal_text(key: key, r: r) } + FileHoldRecoveryPlanned { plan: p, dead_holder: h, evidence: e } => + match file_hold_release_commit(plan: p) { + FileHoldReleased { slot_key: _, generation: _ } => DeadHolderRecovered { dead_holder: h, evidence: e } + FileHoldReleaseLost { slot_key: _ } => DeadHolderNotRecovered { reason: join(["unit ", key as String, " moved before the dead holder's hold was freed; re-run; controller untouched"], "") as NonEmptyStr } + FileHoldReleaseStoreUnavailable { slot_key: _, cause: _ } => DeadHolderNotRecovered { reason: join(["unit hold store refused freeing the dead holder's hold on ", key as String, "; controller untouched"], "") as NonEmptyStr } + FileHoldReleaseKeyNotSlotAddressable { slot_key: _ } => DeadHolderNotRecovered { reason: join(["unit hold key ", key as String, " is not slot-addressable; controller untouched"], "") as NonEmptyStr } + } + } +} + +// The proof is built here, from an outcome only unit_hold_acquire's own live acquires produce: the +// admission is what keeps a supplied FileHoldAcquired from becoming a proof. +fn unit_hold_minted(root: NonEmptyStr, key: NonEmptyStr, outcome: FileHoldAcquireOutcome) -> UnitHoldAcquisition + admit_callers: [ + decl_ref(module_path: "gunbc.machine_intake_mtcollins1_maintenance_hold", decl_name: "unit_hold_acquire"), ] { - let outcome = file_hold_acquire(root: root, slot_key: key, requested_owner: owner) match outcome { FileHoldAcquired { slot_key: _, owner: o, generation: g } => UnitHeld { proof: UnitHoldProof { root: root, key: key, owner: o, generation: g } } @@ -184,6 +418,29 @@ fn unit_hold_acquire(root: NonEmptyStr, key: NonEmptyStr, owner: DurableHoldOwne } } +// THE ONE MINT. The live acquire and the proof are one boundary: the proof exists only when the +// compare-and-set this call performed committed a hold for this owner. An OCCUPIED slot is asked one +// further question -- is its holder observed dead? -- and only an observed-dead holder's hold is freed, +// after which this caller acquires once more like any acquirer. There is no loop: a slot taken by +// someone else in between refuses as occupied, naming them. +fn unit_hold_acquire(root: NonEmptyStr, key: NonEmptyStr, owner: DurableHoldOwnerRef) -> UnitHoldAcquisition + admit_callers: [ + decl_ref(module_path: "gunbc.machine_intake_mtcollins1_maintenance_hold", decl_name: "mtcollins1_boot_acquire_unit_hold"), + decl_ref(module_path: "gunbc.host_reset_return_run", decl_name: "host_reset_return_wet"), + ] +{ + let outcome = file_hold_acquire(root: root, slot_key: key, requested_owner: owner) + match outcome { + FileHoldOccupied { slot_key: _, holder: h, generation: g } => + match unit_hold_recover_dead_holder(root: root, key: key, holder: h, generation: g) { + DeadHolderNotRecovered { reason: r } => UnitHoldRefused { reason: r } + DeadHolderRecovered { dead_holder: _, evidence: _ } => + unit_hold_minted(root: root, key: key, outcome: file_hold_acquire(root: root, slot_key: key, requested_owner: owner)) + } + _ => unit_hold_minted(root: root, key: key, outcome: outcome) + } +} + fn unit_hold_proof_key(proof: UnitHoldProof) -> NonEmptyStr { proof.key } @@ -193,7 +450,12 @@ fn mtcollins1_boot_acquire_unit_hold(run_id: NonEmptyStr) -> UnitHoldAcquisition decl_ref(module_path: "gunbc.machine_intake_mtcollins1_boot_run", decl_name: "mtcollins1_boot_under_live_unit_hold"), ] { - unit_hold_acquire(root: unit_hold_store_root, key: mtcollins1_unit_hold_key, owner: boot_run_owner(run_id: run_id)) + match self_process_identity() { + SelfUnidentified { cause: c } => + UnitHoldRefused { reason: join(["this boot cannot name its own process (", c as String, "), and a hold it could never be shown dead in would lock the unit out if it died; controller untouched"], "") as NonEmptyStr } + SelfIdentified { process: p } => + unit_hold_acquire(root: unit_hold_store_root, key: mtcollins1_unit_hold_key, owner: boot_run_owner(run_id: run_id, process: p)) + } } // THE RELEASE CONSUMES THE PROOF AND KEEPS THE STEP'S OWN OUTCOME, saying when the hold was left: a @@ -266,8 +528,8 @@ fn mtcollins1_maintenance_hold_release() -> ProcessExit { match decode_unit_hold_owner(owner: o) { UnitHoldOwnerUnrecognized { raw: r } => exit_failure(reason: concat("mtcollins1 maintenance hold: held by an owner this module did not write, so it is not released from here: ", r)) - UnitHoldOwnerDecoded { owner: BootRun { run_id: r } } => - exit_failure(reason: concat("mtcollins1 maintenance hold: held by ", concat(unit_hold_owner_label(o: BootRun { run_id: r }), ", not by maintenance; that run frees its own hold"))) + UnitHoldOwnerDecoded { owner: BootRun { run_id: r, process: p } } => + exit_failure(reason: concat("mtcollins1 maintenance hold: held by ", concat(unit_hold_owner_label(o: BootRun { run_id: r, process: p }), ", not by maintenance; that run frees its own hold, and the next boot recovers it if that run is observed dead"))) UnitHoldOwnerDecoded { owner: HostResetReturn { attempt: a } } => exit_failure(reason: concat("mtcollins1 maintenance hold: held by ", concat(unit_hold_owner_label(o: HostResetReturn { attempt: a }), ", not by maintenance; that run frees its own hold"))) UnitHoldOwnerDecoded { owner: OperatorMaintenance { reason: _ } } => diff --git a/dag/std/durable_exclusive_hold.dag b/dag/std/durable_exclusive_hold.dag index e0bacffa70f..b6a1cb34e0a 100644 --- a/dag/std/durable_exclusive_hold.dag +++ b/dag/std/durable_exclusive_hold.dag @@ -169,3 +169,72 @@ fn durable_hold_release_assess( } } } + +// RECOVERY OF A HOLD WHOSE HOLDER WAS OBSERVED DEAD -- THE THIRD AMENDMENT (gunbc#12533 finding 2). +// +// Without it a holder that dies holding the slot holds it forever: acquire refuses while held, and +// only the holder may release. That is not a safe default but a lockout the protocol manufactured, +// because the holder's death is an observable fact about the world and nothing here could consume it. +// +// RECOVERY IS DECIDED BY AN OBSERVATION OF THE HOLDER, NEVER BY AGE. There is deliberately no clock, +// timestamp or duration anywhere in this assessment: a hold is never broken because it is old, only +// because its holder was OBSERVED gone. How a holder is observed is the consumer's (a process by boot, +// pid and start time; a lease by its declared deadline), so the protocol takes the verdict, not the +// method -- and takes it BOUND to the holder and generation it is about, so a verdict taken of one +// hold cannot recover another. Three verdicts, and the third is the reason there are three: a holder +// that could not be observed is not dead, and a recovery over it would be ⊤-as-ignorance. +type DurableHoldHolderLiveness + = HolderObservedLive { evidence: NonEmptyStr } + | HolderObservedDead { evidence: NonEmptyStr } + | HolderLivenessUnobservable { cause: NonEmptyStr } + +type DurableHoldHolderReport { + holder: DurableHoldOwnerRef + generation: CasGeneration + liveness: DurableHoldHolderLiveness +} + +// Each refusal names its own remedy: nothing held means acquire directly; a live holder means wait; +// an unobservable holder sends the caller to whatever prevented the look; a slot that moved since the +// report means the report is about a hold that no longer stands, whoever holds the slot now. +type DurableHoldRecoveryRefusal + = HoldRecoveryNothingHeld + | HoldRecoveryHolderLive { generation: CasGeneration, holder: DurableHoldOwnerRef, evidence: NonEmptyStr } + | HoldRecoveryHolderUnobservable { generation: CasGeneration, holder: DurableHoldOwnerRef, cause: NonEmptyStr } + | HoldRecoverySlotMoved { reported: CasGeneration, observed: CasGeneration } + | HoldRecoveryReportForAnotherHolder { holder: DurableHoldOwnerRef, reported: DurableHoldOwnerRef } + | HoldRecoverySlotUndecodable { generation: CasGeneration, detail: NonEmptyStr } + | HoldRecoveryObservationUnavailable { cause: CasUnreadableSlot } + +// The eligible arm frees the slot at the generation both the live read and the report name; it does +// not hand the slot to anyone. The successor then acquires through durable_hold_acquire_assess like +// every other acquirer, so there is still exactly one way a slot becomes held. +type DurableHoldRecoveryAssessment + = HoldRecoveryEligible { generation: CasGeneration, dead_holder: DurableHoldOwnerRef, evidence: NonEmptyStr } + | HoldRecoveryRefused { refusal: DurableHoldRecoveryRefusal } + +fn durable_hold_recovery_assess(observed: DurableHoldObservation, report: DurableHoldHolderReport) -> DurableHoldRecoveryAssessment { + match observed { + HoldSlotAbsent => HoldRecoveryRefused { refusal: HoldRecoveryNothingHeld } + HoldSlotFree { generation: _, released_by: _ } => HoldRecoveryRefused { refusal: HoldRecoveryNothingHeld } + HoldSlotUndecodable { generation: g, detail: d } => + HoldRecoveryRefused { refusal: HoldRecoverySlotUndecodable { generation: g, detail: d } } + HoldObservationUnavailable { cause: c } => + HoldRecoveryRefused { refusal: HoldRecoveryObservationUnavailable { cause: c } } + HoldSlotHeld { generation: g, owner: holder } => + if !durable_hold_owner_equal(left: holder, right: report.holder) { + HoldRecoveryRefused { refusal: HoldRecoveryReportForAnotherHolder { holder: holder, reported: report.holder } } + } else if cas_generation_count(g: g) != cas_generation_count(g: report.generation) { + HoldRecoveryRefused { refusal: HoldRecoverySlotMoved { reported: report.generation, observed: g } } + } else { + match report.liveness { + HolderObservedLive { evidence: e } => + HoldRecoveryRefused { refusal: HoldRecoveryHolderLive { generation: g, holder: holder, evidence: e } } + HolderLivenessUnobservable { cause: c } => + HoldRecoveryRefused { refusal: HoldRecoveryHolderUnobservable { generation: g, holder: holder, cause: c } } + HolderObservedDead { evidence: e } => + HoldRecoveryEligible { generation: g, dead_holder: holder, evidence: e } + } + } + } +} diff --git a/dag/test/claim/durable_exclusive_hold_witness_test.dag b/dag/test/claim/durable_exclusive_hold_witness_test.dag index 27b3af57801..8d696eaa972 100644 --- a/dag/test/claim/durable_exclusive_hold_witness_test.dag +++ b/dag/test/claim/durable_exclusive_hold_witness_test.dag @@ -7,7 +7,7 @@ import std.durable_compare_and_set { CasExpectation, ExpectSlotAbsent, ExpectSlotGeneration, CasSlotObservation, CasObservedReadable, CasObservedUnreadable, CasReadableAbsent, CasReadablePresent, CasSlotVersion, - CasUnreadableReadRefused, cas_generation_count, + CasUnreadableReadRefused, cas_generation_count, CasGeneration, } import std.durable_exclusive_hold { DurableHoldOwnerRef, DurableHoldReleaseRef, @@ -22,6 +22,10 @@ import std.durable_exclusive_hold { HoldReleaseHeldByAnotherOwner, HoldReleaseAgainstAnotherGeneration, HoldReleaseSlotUndecodable, HoldReleaseObservationUnavailable, durable_hold_acquire_assess, durable_hold_release_assess, durable_hold_owner_equal, + DurableHoldHolderReport, HolderObservedLive, HolderObservedDead, HolderLivenessUnobservable, + DurableHoldRecoveryAssessment, HoldRecoveryEligible, HoldRecoveryRefused, + HoldRecoveryNothingHeld, HoldRecoveryHolderLive, HoldRecoveryHolderUnobservable, HoldRecoverySlotMoved, + HoldRecoveryReportForAnotherHolder, durable_hold_recovery_assess, } import gunbc.durable_exclusive_hold_file_store { HoldPayloadDecode, HoldPayloadDecoded, HoldPayloadUndecodable, @@ -305,3 +309,52 @@ test fn holder_equality_is_exact() -> Bool { && !durable_hold_owner_equal(left: eh_owner(text: "demand-7|offer-1"), right: eh_owner(text: "Demand-7|offer-1")) && !durable_hold_owner_equal(left: eh_owner(text: "demand-7|offer-1"), right: eh_owner(text: "demand-7|offer-1 ")) } + +// ── RECOVERY OF A DEAD HOLDER'S HOLD (gunbc#12533 finding 2) ───────────────────────────────── +// The three controls the brief names, over one slot held by one owner at one generation, differing +// ONLY in the liveness verdict: a live holder blocks, an observed-dead holder is recovered at the +// generation both the read and the report name, and an unobservable holder refuses -- never +// recovered. There is no age input to vary: the assessment takes none. +fn eh_report(holder: String, generation: Int, dead: Int) -> DurableHoldHolderReport { + DurableHoldHolderReport { + holder: eh_owner(text: holder), + generation: generation as CasGeneration, + liveness: if dead == 0 { HolderObservedLive { evidence: "process 7 started at tick 90 still runs" } } + else if dead == 1 { HolderObservedDead { evidence: "no process 7 on the holder's boot" } } + else { HolderLivenessUnobservable { cause: "/proc/7/stat could not be read" } }, + } +} + +test fn a_live_holder_blocks_an_observed_dead_holder_is_recovered_and_an_unobservable_one_refuses() -> Bool { + let held = eh_held_at(owner: "mtcollins1-boot:4242", generation: 3) + (match durable_hold_recovery_assess(observed: held, report: eh_report(holder: "mtcollins1-boot:4242", generation: 3, dead: 0)) { + HoldRecoveryRefused { refusal: HoldRecoveryHolderLive { generation: _, holder: _, evidence: _ } } => true + _ => false + }) + && (match durable_hold_recovery_assess(observed: held, report: eh_report(holder: "mtcollins1-boot:4242", generation: 3, dead: 1)) { + HoldRecoveryEligible { generation: g, dead_holder: h, evidence: _ } => cas_generation_count(g: g) == 3 && (h as String) == "mtcollins1-boot:4242" + _ => false + }) + && (match durable_hold_recovery_assess(observed: held, report: eh_report(holder: "mtcollins1-boot:4242", generation: 3, dead: 2)) { + HoldRecoveryRefused { refusal: HoldRecoveryHolderUnobservable { generation: _, holder: _, cause: _ } } => true + _ => false + }) +} + +// A DEAD VERDICT RECOVERS ONLY THE HOLD IT WAS TAKEN OF: the same verdict against a slot that moved +// on, that another owner now holds, or that is already free recovers nothing. +test fn a_dead_verdict_recovers_only_the_hold_it_was_taken_of() -> Bool { + let dead = eh_report(holder: "mtcollins1-boot:4242", generation: 3, dead: 1) + (match durable_hold_recovery_assess(observed: eh_held_at(owner: "mtcollins1-boot:4242", generation: 5), report: dead) { + HoldRecoveryRefused { refusal: HoldRecoverySlotMoved { reported: _, observed: _ } } => true + _ => false + }) + && (match durable_hold_recovery_assess(observed: eh_held_at(owner: "operator-maintenance:reseat", generation: 3), report: dead) { + HoldRecoveryRefused { refusal: HoldRecoveryReportForAnotherHolder { holder: _, reported: _ } } => true + _ => false + }) + && (match durable_hold_recovery_assess(observed: eh_free_at(generation: 4), report: dead) { + HoldRecoveryRefused { refusal: HoldRecoveryNothingHeld } => true + _ => false + }) +} diff --git a/dag/test/claim/machine_intake/mtcollins1_maintenance_hold_witness_test.dag b/dag/test/claim/machine_intake/mtcollins1_maintenance_hold_witness_test.dag index baa0cf0c6c3..b28d952e40e 100644 --- a/dag/test/claim/machine_intake/mtcollins1_maintenance_hold_witness_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_maintenance_hold_witness_test.dag @@ -19,9 +19,12 @@ import gunbc.auth.mtcollins1_boot_federation { } import gunbc.auth.gcp_secret_access { SecretAccessGrant } import v2.std.optional { Present, Absent } +import gunbc.build_cache_instance { ProcessIdentity } data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly +data holder_process: ProcessIdentity = ProcessIdentity { boot_id: "73c8153e-0e0e-4480-a36c-bc7560c50e8b" as NonEmptyStr, pid: 3975, start_time: "81234" as NonEmptyStr } + // ── The interlock: the boot refuses under an active maintenance hold ────────────────────────── // Supplied at the interface (DESIGN §3, a witness discriminates at one interface), and only into the // PURE refusal fold: a supplied outcome yields text and never a UnitHoldProof, whose one mint is the @@ -55,12 +58,12 @@ test fn the_boot_refuses_under_an_active_maintenance_hold_and_names_the_holder() generation: first_generation(), } refused_naming(r: unit_hold_refusal(outcome: held), pattern: "operator-maintenance:reseating DIMMs") - && not_refused(r: unit_hold_refusal(outcome: FileHoldAcquired { slot_key: mtcollins1_unit_hold_key, owner: boot_run_owner(run_id: "42"), generation: first_generation() })) + && not_refused(r: unit_hold_refusal(outcome: FileHoldAcquired { slot_key: mtcollins1_unit_hold_key, owner: boot_run_owner(run_id: "42", process: holder_process), generation: first_generation() })) } // ANOTHER HOLDER IS A HOLDER: a running boot, or a host reset-return, excludes the next writer. test fn a_second_writer_refuses_while_another_run_holds_the_unit() -> Bool { - refused_naming(r: unit_hold_refusal(outcome: FileHoldOccupied { slot_key: mtcollins1_unit_hold_key, holder: boot_run_owner(run_id: "41"), generation: first_generation() }), pattern: "mtcollins1-boot:41") + refused_naming(r: unit_hold_refusal(outcome: FileHoldOccupied { slot_key: mtcollins1_unit_hold_key, holder: boot_run_owner(run_id: "41", process: holder_process), generation: first_generation() }), pattern: "mtcollins1-boot:41") && refused_naming(r: unit_hold_refusal(outcome: FileHoldOccupied { slot_key: mtcollins1_unit_hold_key, holder: host_reset_owner(attempt: "srv1-mtcollins1"), generation: first_generation() }), pattern: "host-reset-return:srv1-mtcollins1") } @@ -138,7 +141,7 @@ fn round_trips(o: UnitHoldOwner, label: String) -> Bool { test fn every_holder_kind_round_trips_and_a_foreign_owner_is_refused() -> Bool { round_trips(o: OperatorMaintenance { reason: "reseating DIMMs" as NonEmptyStr }, label: "operator maintenance: reseating DIMMs") - && round_trips(o: BootRun { run_id: "41" as NonEmptyStr }, label: "the mtcollins1 boot run 41") + && round_trips(o: BootRun { run_id: "41" as NonEmptyStr, process: holder_process }, label: "the mtcollins1 boot run 41 (process 3975 on boot 73c8153e-0e0e-4480-a36c-bc7560c50e8b)") && round_trips(o: HostResetReturn { attempt: "srv1-mtcollins1" as NonEmptyStr }, label: "host reset-return attempt srv1-mtcollins1") && match decode_unit_hold_owner(owner: "someone-else:x" as DurableHoldOwnerRef) { UnitHoldOwnerUnrecognized { raw: _ } => true @@ -149,3 +152,25 @@ test fn every_holder_kind_round_trips_and_a_foreign_owner_is_refused() -> Bool { UnitHoldOwnerDecoded { owner: _ } => false } } + +// A BOOT OWNER NAMES ITS PROCESS AND DECODES BACK TO IT (gunbc#12533 finding 2): the rendered owner +// carries boot id, pid and start time, and decodes to the same identity -- the identity a successor +// observes the holder by. A boot owner written WITHOUT a process (the spelling before this change, +// still possibly on disk) is not guessed into one: it decodes as unrecognized, so its holder is +// unobservable and its hold is refused rather than broken. +test fn a_boot_owner_carries_its_process_and_a_processless_one_is_not_recoverable() -> Bool { + let rendered = boot_run_owner(run_id: "4242", process: holder_process) as String + rendered == "mtcollins1-boot:4242@boot=73c8153e-0e0e-4480-a36c-bc7560c50e8b,pid=3975,start=81234" + && (match decode_unit_hold_owner(owner: rendered as DurableHoldOwnerRef) { + UnitHoldOwnerDecoded { owner: BootRun { run_id: r, process: p } } => (r as String) == "4242" && p.pid == 3975 && (p.start_time as String) == "81234" + _ => false + }) + && (match decode_unit_hold_owner(owner: "mtcollins1-boot:4242" as DurableHoldOwnerRef) { + UnitHoldOwnerUnrecognized { raw: _ } => true + _ => false + }) + && (match decode_unit_hold_owner(owner: "mtcollins1-boot:4242@boot=x,pid=-1,start=5" as DurableHoldOwnerRef) { + UnitHoldOwnerUnrecognized { raw: _ } => true + _ => false + }) +} From e25a17d930703159a018ee324c018dfc2c1cf695 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Mon, 28 Sep 2026 18:11:25 +0000 Subject: [PATCH 19/75] BMC model: an event a transition schedules is kept (power restore keeps its SOL drop) #12423 side-chat review 5342387382: bmc_advance_pending rebuilt pending from its own accumulator after each applied event, discarding events the transition had just scheduled -- a power cycle's restore arming the after-boot SOL drop lost that drop. The advance now fires the earliest due event from the world's own pending list, applies it, and repeats on the world that transition produced. New model control a_power_restore_keeps_the_sol_drop_it_schedules (ON host, cycle at 0, restore at 5, drop at 35; quiet advances to 10 and to 40); it fails on the previous fold. Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/gunbc/bmc_model.dag | 61 ++++++++++++++++--- .../claim/boot_world_models_witness_test.dag | 20 ++++++ 2 files changed, 71 insertions(+), 10 deletions(-) diff --git a/dag/gunbc/bmc_model.dag b/dag/gunbc/bmc_model.dag index 7fd22b6d3df..ef2554835a2 100644 --- a/dag/gunbc/bmc_model.dag +++ b/dag/gunbc/bmc_model.dag @@ -167,23 +167,64 @@ fn bmc_apply_event(world: BmcWorld, event: BmcEvent, at: Second) -> BmcWorld { } } -// Every event due at or before `now` fires, in schedule order, and moves from pending to fired. With -// nothing pending there is nothing to fire, and the world is returned as it is rather than rebuilt. +// EVERY EVENT DUE AT OR BEFORE `now` FIRES, EARLIEST FIRST, AND AN EVENT A TRANSITION SCHEDULES IS +// KEPT. One due event is taken off the world's own pending list, applied, and recorded as fired; the +// advance then repeats on the world THAT TRANSITION PRODUCED, so an event it scheduled -- a power +// restore arming its SOL drop -- stays pending and fires in turn if it too is due. (An earlier fold +// rebuilt pending from its own accumulator after each transition and so discarded exactly those +// events: #12423 side-chat review 5342387382.) Each step fires one due event, so the repetition ends. +// With nothing due the world is returned as it is rather than rebuilt. fn bmc_advance(world: BmcWorld, now: Second) -> BmcWorld { - if count(world.pending) == 0 { world } else { bmc_advance_pending(world: world, now: now) } + match bmc_first_due(pending: world.pending, now: now) { + Absent => world + Present { value: e } => { + let remaining = bmc_without_first(pending: world.pending, event: e) + let applied = bmc_apply_event(world: bmc_with_pending(world: world, pending: remaining, fired: world.fired), event: e.event, at: e.at) + bmc_advance(world: bmc_with_pending(world: applied, pending: applied.pending, fired: list_append(applied.fired, e)), now: now) + } + } } -fn bmc_advance_pending(world: BmcWorld, now: Second) -> BmcWorld { - fold(world.pending, init: bmc_with_pending(world: world, pending: [], fired: world.fired), f: fn(acc, e) { - if second_count(s: e.at) <= second_count(s: now) { - let applied = bmc_apply_event(world: acc, event: e.event, at: e.at) - bmc_with_pending(world: applied, pending: acc.pending, fired: list_append(acc.fired, e)) - } else { - bmc_with_pending(world: acc, pending: list_append(acc.pending, e), fired: acc.fired) +// The due event with the earliest instant; among equal instants, the first in schedule order. +fn bmc_no_event() -> BmcScheduledEvent? { + none +} + +fn bmc_first_due(pending: List, now: Second) -> BmcScheduledEvent? { + fold(pending, init: bmc_no_event(), f: fn(acc, e) { + if second_count(s: e.at) > second_count(s: now) { acc } else { + match acc { + Absent => Present { value: e } + Present { value: best } => if second_count(s: e.at) < second_count(s: best.at) { Present { value: e } } else { acc } + } } }) } +type BmcPendingRemoval { + kept: List + removed: Bool +} + +// Removes ONE occurrence -- the first equal to `event` -- so two identical scheduled events fire twice. +fn bmc_without_first(pending: List, event: BmcScheduledEvent) -> List { + fold(pending, init: BmcPendingRemoval { kept: [], removed: false }, f: fn(acc, e) { + if !acc.removed && second_count(s: e.at) == second_count(s: event.at) && bmc_event_eq(a: e.event, b: event.event) { + BmcPendingRemoval { kept: acc.kept, removed: true } + } else { + BmcPendingRemoval { kept: list_append(acc.kept, e), removed: acc.removed } + } + }).kept +} + +fn bmc_event_eq(a: BmcEvent, b: BmcEvent) -> Bool { + match a { + BmcAcPowerLost => match b { BmcAcPowerLost => true _ => false } + BmcPowerRestored => match b { BmcPowerRestored => true _ => false } + BmcSolSessionDropped => match b { BmcSolSessionDropped => true _ => false } + } +} + fn bmc_with_sol_drop_after_boot(world: BmcWorld, after: Second) -> BmcWorld { BmcWorld { power: world.power, pending: world.pending, fired: world.fired, boot_override: world.boot_override, sel: world.sel, diff --git a/dag/test/claim/boot_world_models_witness_test.dag b/dag/test/claim/boot_world_models_witness_test.dag index 51e2696b9b4..60a37223697 100644 --- a/dag/test/claim/boot_world_models_witness_test.dag +++ b/dag/test/claim/boot_world_models_witness_test.dag @@ -2,6 +2,8 @@ module test.claim.boot_world_models_witness_test import std.types { Bool, List, String } import std.measure { second } +import gunbc.bmc_model { BmcWorld, BmcPowerOn, bmc_world, bmc_with_sol_session, bmc_with_sol_drop_after_boot, bmc_chassis_control, bmc_advance, bmc_power_is_on, bmc_sol_drop_fired } +import extdeps.bmc.ipmi_chassis_control { IpmiChassisPowerCycle } import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } import extdeps.transports.shell { ShellProcessExited } import extdeps.exec.command { argv_words } @@ -72,3 +74,21 @@ test fn a_write_needs_its_parent_directory() -> Bool { _ => false } } + +// A POWER RESTORE KEEPS THE SOL DROP IT SCHEDULES (#12423 side-chat review 5342387382). An ON host with +// an open SOL session and a 30-second after-boot drop is power-cycled at t=0: the controller drops power +// and schedules the restore at t=5; the restore boots the host and schedules the drop at t=35. A quiet +// advance to t=10 fires only the restore; ONE quiet advance to t=40, spanning both due times, fires both +// -- the drop the restore scheduled is not discarded -- and leaves nothing pending. +fn cycled_on_host() -> BmcWorld { + let on = bmc_with_sol_drop_after_boot(world: bmc_with_sol_session(world: bmc_world(power: BmcPowerOn), open: true), after: second(count: 30)) + bmc_chassis_control(world: on, action: IpmiChassisPowerCycle, now: second(count: 0)).world +} + +test fn a_power_restore_keeps_the_sol_drop_it_schedules() -> Bool { + let at_ten = bmc_advance(world: cycled_on_host(), now: second(count: 10)) + let at_forty = bmc_advance(world: cycled_on_host(), now: second(count: 40)) + bmc_power_is_on(world: at_ten) && at_ten.sol_session_open && count(at_ten.fired) == 1 && count(at_ten.pending) == 1 + && bmc_power_is_on(world: at_forty) && !at_forty.sol_session_open && bmc_sol_drop_fired(world: at_forty) + && count(at_forty.fired) == 2 && count(at_forty.pending) == 0 +} From 9df49eb4b7a36e1196839cd2e5c7a6c5e2728268 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Mon, 28 Sep 2026 18:13:58 +0000 Subject: [PATCH 20/75] Matrix: the duplicate-listing case asserts its own cause with both identities (finding 5 flips) Co-Authored-By: Claude Opus 5.5 (1M context) --- .../mtcollins1_boot_acceptance_matrix_test.dag | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index 31cc33ca5e0..43457b55174 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -354,12 +354,14 @@ test fn the_right_filename_on_the_wrong_share_refuses_before_any_power_action() } // THE LISTING NAMES THE IMAGE TWICE. Taking either row would let the controller's order choose which -// file is attached, so nothing is started and nothing is powered. +// file is attached, so nothing is started and nothing is powered. The cause is its own and names both +// offered identities; the red is the old "not valid JSON" label (finding 5, repaired in #12553). test fn a_listing_that_names_the_image_twice_starts_nothing() -> Bool { let twice = [MegaRacImage { image_name: desired_image(), image_index: 5 }, MegaRacImage { image_name: desired_image(), image_index: 6 }] match run_attempt(world: media_varied(media: media_with(images: twice, share: real_share, cd: megarac_cleared_cd(), ready_after: 12, withdraw_after_ready: no_withdrawal()))) { WitnessReturned { value, route } => - string_contains(s: outcome_reason(a: value), pattern: "names the image more than once, so its index is ambiguous") + string_contains(s: outcome_reason(a: value), pattern: "more than once (image_index 5, 6)") + && !string_contains(s: outcome_reason(a: value), pattern: "not valid JSON") && count_named(route: route, name: "megarac.Media.StartMedia") == 0 && reached_no_power_action(route: route) _ => false From 5b8e3bf5bbc2b4e6551e0433f1c471caccc2e437 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Mon, 28 Sep 2026 18:14:45 +0000 Subject: [PATCH 21/75] Matrix: a presentation lost after the handoff is the reported cause (finding 4 flips; identity renamed in its cost-drop row) Co-Authored-By: Claude Opus 5.5 (1M context) --- .../mtcollins1_boot_acceptance_matrix_test.dag | 14 +++++++------- docs/design-rung-drops.md | 2 +- src/v2/workflow/floor_eval_step_cost_drop.dag | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index 31cc33ca5e0..24947a5358d 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -380,15 +380,15 @@ test fn a_presentation_lost_after_readiness_stops_the_handoff() -> Bool { } } -// PINNED: A PRESENTATION LOST AFTER THE HANDOFF IS NOT NAMED AS A CAUSE. Lost twenty seconds after -// readiness -- after the boot override and the power action -- the attempt goes on to the terminal -// deadline and refuses there, and the loss appears only in the recorded after-handoff look. The -// outcome does not say the medium disappeared under the boot (#12423 media: presentation withdrawal). -// When a loss after the handoff becomes a typed cause, this case flips. -test fn pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause() -> Bool { +// A PRESENTATION LOST AFTER THE HANDOFF IS THE NAMED CAUSE (finding 4, repaired in #12554). Lost +// twenty seconds after readiness -- after the boot override and the power action -- the watch still +// reaches its deadline, but the after-handoff look affirmed the loss, so the outcome names it and +// keeps the deadline beside it (#12423 media: presentation withdrawal). The red is the bare deadline. +test fn a_presentation_lost_after_the_handoff_is_the_reported_cause() -> Bool { match run_attempt(world: media_varied(media: media_with(images: [MegaRacImage { image_name: desired_image(), image_index: 5 }], share: real_share, cd: megarac_cleared_cd(), ready_after: 12, withdraw_after_ready: Present { value: second(count: 20) }))) { WitnessReturned { value, route } => - string_contains(s: outcome_reason(a: value), pattern: "deadline reached without a host-capture terminal") + starts_with(s: outcome_reason(a: value), prefix: "mtcollins1 boot: media presentation lost at after-handoff (") + && string_contains(s: outcome_reason(a: value), pattern: "deadline reached without a host-capture terminal") && count_named(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") == 1 _ => false } diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index e5c2079977c..31b9a533b94 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -340,7 +340,7 @@ new-witness eval-step cost gate over the ten interpreted P-256 and P-384 point a ### new-witness eval-step cost gate over the eight mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 -new-witness eval-step cost gate over the eight mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_healthy_census_is_refused_at_the_sol_teardown: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these eight identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. +new-witness eval-step cost gate over the eight mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_healthy_census_is_refused_at_the_sol_teardown: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these eight identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. ### new-witness eval-step cost gate over six App Attest verifier claims -- the two real-path inhabitance claims over Apple's objects, three single structural steps priced by their own SHA-256s, and the wire-carrier join: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 diff --git a/src/v2/workflow/floor_eval_step_cost_drop.dag b/src/v2/workflow/floor_eval_step_cost_drop.dag index e9e32abcabd..33b75acb53a 100644 --- a/src/v2/workflow/floor_eval_step_cost_drop.dag +++ b/src/v2/workflow/floor_eval_step_cost_drop.dag @@ -262,7 +262,7 @@ data floor_eval_step_cost_drop_boot_matrix_rows: List Date: Mon, 28 Sep 2026 18:16:58 +0000 Subject: [PATCH 22/75] Dry world models the boot worker's procfs identity and its death; the interrupted case flips to recovery, with live and unobservable holder controls (finding 2) Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/gunbc/filesystem_model.dag | 18 ++- .../mtcollins1_boot_dry_realization.dag | 32 ++++- .../claim/boot_world_models_witness_test.dag | 2 +- ...mtcollins1_boot_acceptance_matrix_test.dag | 110 +++++++++++++----- .../claim/modeled_filesystem_witness_test.dag | 5 +- 5 files changed, 130 insertions(+), 37 deletions(-) diff --git a/dag/gunbc/filesystem_model.dag b/dag/gunbc/filesystem_model.dag index daca446e524..e21efaafd1a 100644 --- a/dag/gunbc/filesystem_model.dag +++ b/dag/gunbc/filesystem_model.dag @@ -9,7 +9,7 @@ import v2.std.operation_realization { } import extdeps.transports.file { FileExchangeObservation, FileOperationSucceeded, FileOperationFailed } import extdeps.filesystem.filesystem_io { - FilesystemNotFound, FilesystemAlreadyExists, FilesystemNotDirectory, FilesystemOtherFailure, + FilesystemNotFound, FilesystemAlreadyExists, FilesystemNotDirectory, FilesystemOtherFailure, FilesystemPermissionDenied, } // A MODELED FILESYSTEM: the subset of POSIX file behaviour the file transport realizes, as a pure @@ -21,6 +21,8 @@ import extdeps.filesystem.filesystem_io { // - a listing is the immediate children's names, sorted, one per line; listing a file answers // not_a_directory and listing an absent path answers not_found; // - reading or writing a directory as a file answers `other`, as an EISDIR does. +// - a path in refused_reads answers permission_denied to a read, whether or not it exists: the one +// permission fact modeled, so a consumer's "could not look" arm is reachable over this model. // WHAT IT DOES NOT MODEL, stated so a green over it is not over-read: file modes (the declared mode of // write_create_new_with_mode is accepted and not stored), ownership, symlinks, partial writes, and // the atomicity of a real create-exclusive under concurrent processes. Those are properties of the real @@ -35,6 +37,7 @@ type ModeledFile { type ModeledFilesystem { directories: List files: List + refused_reads: List } fn fs_is_directory(fs: ModeledFilesystem, path: String) -> Bool { @@ -74,12 +77,22 @@ fn failed_with(kind: extdeps.filesystem.filesystem_io.FilesystemFailureKind, mes } fn fs_read(fs: ModeledFilesystem, path: String) -> FileExchangeObservation { + if any_string(xs: fs.refused_reads, x: path) { failed_with(kind: FilesystemPermissionDenied, message: concat("Permission denied: ", path)) } else { match fs_file(fs: fs, path: path) { Present { value: file } => FileOperationSucceeded { byte_count: string_length(s: file.content), content: file.content } Absent => if fs_is_directory(fs: fs, path: path) { failed_with(kind: FilesystemOtherFailure, message: concat("Is a directory: ", path)) } else { failed_with(kind: FilesystemNotFound, message: concat("No such file or directory: ", path)) } } + } +} + +fn fs_without_file(fs: ModeledFilesystem, path: String) -> ModeledFilesystem { + ModeledFilesystem { directories: fs.directories, files: filter(fs.files, f => f.path != path), refused_reads: fs.refused_reads } +} + +fn fs_refusing_reads_of(fs: ModeledFilesystem, path: String) -> ModeledFilesystem { + ModeledFilesystem { directories: fs.directories, files: fs.files, refused_reads: list_append(fs.refused_reads, path) } } type ModeledFileWrite { @@ -110,13 +123,14 @@ fn fs_with_file(fs: ModeledFilesystem, path: String, content: String) -> Modeled ModeledFilesystem { directories: fs.directories, files: list_append(filter(fs.files, f => f.path != path), ModeledFile { path: path, content: content }), + refused_reads: fs.refused_reads, } } fn fs_delete(fs: ModeledFilesystem, path: String) -> ModeledFileWrite { match fs_file(fs: fs, path: path) { Present { value: _ } => - ModeledFileWrite { fs: ModeledFilesystem { directories: fs.directories, files: filter(fs.files, f => f.path != path) }, observation: FileOperationSucceeded { byte_count: 0, content: "" } } + ModeledFileWrite { fs: fs_without_file(fs: fs, path: path), observation: FileOperationSucceeded { byte_count: 0, content: "" } } Absent => if fs_is_directory(fs: fs, path: path) { ModeledFileWrite { fs: fs, observation: failed_with(kind: FilesystemOtherFailure, message: concat("Is a directory: ", path)) } } else { ModeledFileWrite { fs: fs, observation: failed_with(kind: FilesystemNotFound, message: concat("No such file or directory: ", path)) } } diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag index 28c827c2301..12a20378ff4 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag @@ -11,7 +11,7 @@ import v2.std.operation_realization { import gunbc.bmc_model { BmcWorld, bmc_advance, bmc_with_sol_session, bmc_power_is_on } import gunbc.bmc_dry_realization { bmc_bindings, megarac_bindings, bmc_ipmi_operation, sleep_delay_seconds_operation } import gunbc.megarac_media_model { MegaRacMediaWorld, megarac_media_advance } -import gunbc.filesystem_model { ModeledFilesystem, ModeledFile, filesystem_bindings, fs_with_file, fs_file, fs_write } +import gunbc.filesystem_model { ModeledFilesystem, ModeledFile, filesystem_bindings, fs_with_file, fs_file, fs_write, fs_without_file } import gunbc.process_environment_model { ModeledVariable, environment_binding } import gunbc.host_command_model { ModeledInvocation, exact_invocation_binding, local_command_words, shell_exec_run_argv_operation } import extdeps.transports.shell { ShellExchangeObservation, ShellProcessExited } @@ -122,6 +122,32 @@ fn proc_cmdline_path(pid: Int) -> String { join(["/proc/", to_string(pid), "/cmdline"], "") } +// THE WORKER'S OWN PROCESS, as procfs shows it (proc(5), proc_pid_stat(5)): the host's boot id, and +// one stat line per process -- pid, a parenthesized comm, then fields 3.. with starttime at field 22 -- +// under /proc//stat and, for the reader itself, /proc/self/stat. The boot's unit-hold owner is +// read from these (gunbc.machine_intake_mtcollins1_maintenance_hold self_process_identity) and a +// successor observes the holder through them (holder_process_liveness), so a worker that starts writes +// both, and a worker that is killed loses its /proc//stat: the kernel removes a dead process's +// directory. Only the fields a reader uses are meaningful; the others are zeros. +data proc_boot_id_file: String = "/proc/sys/kernel/random/boot_id" + +fn proc_stat_path(pid: Int) -> String { + join(["/proc/", to_string(pid), "/stat"], "") +} + +fn proc_stat_line(pid: Int, start_ticks: Int) -> String { + join([to_string(pid), " (gunbc) S 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ", to_string(start_ticks), " 0 0\n"], "") +} + +fn worker_process_started(fs: ModeledFilesystem, boot_id: String, pid: Int, start_ticks: Int) -> ModeledFilesystem { + let line = proc_stat_line(pid: pid, start_ticks: start_ticks) + fs_with_file(fs: fs_with_file(fs: fs_with_file(fs: fs, path: proc_boot_id_file, content: concat(boot_id, "\n")), path: "/proc/self/stat", content: line), path: proc_stat_path(pid: pid), content: line) +} + +fn worker_process_killed(fs: ModeledFilesystem, pid: Int) -> ModeledFilesystem { + fs_without_file(fs: fs_without_file(fs: fs, path: proc_stat_path(pid: pid)), path: "/proc/self/stat") +} + fn live_collectors(w: MtCollins1BootWorld) -> List { filter(w.worker.processes, p => p.alive) } @@ -174,7 +200,7 @@ fn sol_activate_held_handler(w: MtCollins1BootWorld, call: OperationCall) -> Ope // removes it -- which is exactly what the production teardown observes afterwards. fn sol_deactivate_handler(w: MtCollins1BootWorld, call: OperationCall) -> OperationStep { let fs = fold(live_collectors(w: w), init: w.fs, f: fn(acc, p) { - ModeledFilesystem { directories: acc.directories, files: filter(acc.files, f => f.path != proc_cmdline_path(pid: p.pid)) } + fs_without_file(fs: acc, path: proc_cmdline_path(pid: p.pid)) }) let worker = ModeledWorker { next_pid: w.worker.next_pid, processes: map(w.worker.processes, p => ModeledProcess { pid: p.pid, cmdline: p.cmdline, capture_path: p.capture_path, alive: false }), uptime_at_origin: w.worker.uptime_at_origin } exited_step(state: with_bmc(w: with_worker(w: with_fs(w: w, fs: fs), worker: worker), bmc: bmc_with_sol_session(world: w.bmc, open: false)), stdout: "", exit_code: 0) @@ -243,7 +269,7 @@ fn concat_text(lines: List) -> String { fn collectors_follow_session(w: MtCollins1BootWorld) -> MtCollins1BootWorld { if w.bmc.sol_session_open || count(live_collectors(w: w)) == 0 { w } else { let fs = fold(live_collectors(w: w), init: w.fs, f: fn(acc, p) { - ModeledFilesystem { directories: acc.directories, files: filter(acc.files, f => f.path != proc_cmdline_path(pid: p.pid)) } + fs_without_file(fs: acc, path: proc_cmdline_path(pid: p.pid)) }) with_worker(w: with_fs(w: w, fs: fs), worker: ModeledWorker { next_pid: w.worker.next_pid, processes: map(w.worker.processes, p => ModeledProcess { pid: p.pid, cmdline: p.cmdline, capture_path: p.capture_path, alive: false }), uptime_at_origin: w.worker.uptime_at_origin }) } diff --git a/dag/test/claim/boot_world_models_witness_test.dag b/dag/test/claim/boot_world_models_witness_test.dag index 60a37223697..318ee92c1f3 100644 --- a/dag/test/claim/boot_world_models_witness_test.dag +++ b/dag/test/claim/boot_world_models_witness_test.dag @@ -67,7 +67,7 @@ test fn the_remote_host_answers_production_commands_in_coreutils_format() -> Boo // THE FILESYSTEM'S PARENT RULE: a write under a directory the model does not hold is not_found. test fn a_write_needs_its_parent_directory() -> Bool { - let fs = ModeledFilesystem { directories: ["/", "/run"], files: [] } + let fs = ModeledFilesystem { directories: ["/", "/run"], files: [], refused_reads: [] } fs_parent(path: "/run/sol.pid") == "/run" && fs_parent(path: "/x") == "/" && fs_parent(path: "target/a.pub") == "target" && match fs_write(fs: fs, path: "/var/x", content: "1", create_new: false).observation { extdeps.transports.file.FileOperationFailed { kind: extdeps.filesystem.filesystem_io.FilesystemNotFound, error: _ } => true diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index 31cc33ca5e0..5a140540513 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -12,14 +12,15 @@ import v2.std.witness_evaluation { } import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } import gunbc.bmc_model { BmcWorld, BmcPowerOff, bmc_world, bmc_with_sol_session, bmc_with_sol_drop_after_boot, bmc_sol_drop_fired } -import gunbc.filesystem_model { ModeledFilesystem, ModeledFile } +import gunbc.filesystem_model { ModeledFilesystem, ModeledFile, fs_refusing_reads_of } import gunbc.process_environment_model { ModeledVariable } import gunbc.remote_host_model { ModeledRemoteHost, ModeledRemoteFile } import gunbc.wall_clock_model { ModeledWallClock } import gunbc.megarac_media_model { MegaRacMediaWorld, MegaRacShare, MegaRacImage, MegaRacCdRow, megarac_cleared_cd } import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld, ModeledSshAgent, ModeledWorker, ModeledHostConsole, TimedConsoleLine, - mtcollins1_boot_dry_realization, with_media, with_bmc, + mtcollins1_boot_dry_realization, with_media, with_bmc, with_fs, + worker_process_started, worker_process_killed, proc_stat_path, } import v2.std.operation_realization { OperationRealization, OperationBinding, OperationCall, OperationStep, OperationObserved, OperationWorkerKilled, @@ -119,11 +120,20 @@ fn healthy_media() -> MegaRacMediaWorld { } } +// The worker host's boot, and the boot worker's own process (pid, start tick) as procfs shows it. +data worker_boot_id: String = "73c8153e-0e0e-4480-a36c-bc7560c50e8b" +data first_worker_pid: Int = 3100 +data first_worker_start: Int = 5000 + fn worker_filesystem() -> ModeledFilesystem { - ModeledFilesystem { - directories: ["target", "/", "/run", "/proc", "/var", "/var/lib", "/var/lib/gunbc", unit_hold_store_root as String], - files: [ModeledFile { path: credential_path, content: "secret" }], - } + worker_process_started( + fs: ModeledFilesystem { + directories: ["target", "/", "/run", "/proc", "/var", "/var/lib", "/var/lib/gunbc", unit_hold_store_root as String], + files: [ModeledFile { path: credential_path, content: "secret" }], + refused_reads: [], + }, + boot_id: worker_boot_id, pid: first_worker_pid, start_ticks: first_worker_start, + ) } fn world_with_console(lines: List) -> MtCollins1BootWorld { @@ -455,14 +465,19 @@ test fn a_two_socket_answer_is_a_truthful_topology_refusal() -> Bool { // THE WORKER DIES RIGHT AFTER THE START-MEDIA WRITE COMMITS, before its reply. The realization is the // matrix's own with that one handler wrapped: the controller takes the start, and the worker is gone. -fn killed_after_start_media(realization: OperationRealization) -> OperationRealization { +// THE WORKER DIES RIGHT AFTER StartMedia COMMITS: the dispatch reports it killed, and the kernel +// removes the dead process's /proc entry. stopped_after_start_media is the same interruption with the +// worker's process STILL RUNNING (the dispatch stopped being observed; the holder did not exit) -- the +// live-holder control. +fn interrupted_after_start_media(realization: OperationRealization, process_exits: Bool) -> OperationRealization { OperationRealization { identity: realization.identity, initial: realization.initial, epoch: realization.epoch, advance: realization.advance, bindings: map(realization.bindings, b => if b.at.operation == "StartMedia" { OperationBinding { at: b.at, handler: fn(state, call) { let inner = b.handler match inner(state, call) { - OperationObserved { observation: _, state: after, elapsed: _ } => OperationWorkerKilled { committed: true, state: after } + OperationObserved { observation: _, state: after, elapsed: _ } => + OperationWorkerKilled { committed: true, state: if process_exits { with_fs(w: after, fs: worker_process_killed(fs: after.fs, pid: first_worker_pid)) } else { after } } other => other } } } @@ -470,34 +485,71 @@ fn killed_after_start_media(realization: OperationRealization) -> OperationRealization { + interrupted_after_start_media(realization: realization, process_exits: true) +} + +fn stopped_after_start_media(realization: OperationRealization) -> OperationRealization { + interrupted_after_start_media(realization: realization, process_exits: false) +} + +// THE NEXT RUN IS A NEW WORKER PROCESS on the same host: a new run id, and its own pid and start tick +// in procfs. The first worker's /proc entry is left as the interruption left it. fn as_another_run(w: MtCollins1BootWorld, run_id: String) -> MtCollins1BootWorld { let env = map(w.environment, v => if v.name == "GITHUB_RUN_ID" { ModeledVariable { name: v.name, value: run_id } } else { v }) - MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: env, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: w.media } + let fs = worker_process_started(fs: w.fs, boot_id: worker_boot_id, pid: first_worker_pid + 1, start_ticks: first_worker_start + 9000) + MtCollins1BootWorld { bmc: w.bmc, fs: fs, environment: env, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: w.media } } -// PINNED: THE NEXT ATTEMPT IS LOCKED OUT BY THE DEAD RUN'S HOLD. The interrupted run never released the -// unit, so a new run finds it held by the dead one and refuses with the controller untouched -- safe, -// but it cannot reconcile: nothing retires a hold whose owner is gone, so every later attempt refuses -// until an operator intervenes (#12423: interrupted operations must be reconciled without undocumented -// preparation). When dead-owner reconciliation lands this case flips. -test fn pinned_an_interrupted_attempt_locks_out_the_next_one() -> Bool { - let realization = killed_after_start_media(realization: mtcollins1_boot_dry_realization(identity: realization_identity, initial: world_with_console(lines: []), epoch: virtual_clock_origin())) +// THE NEXT ATTEMPT RECOVERS THE DEAD RUN'S HOLD (finding 2, repaired in #12555). The interrupted run +// never released the unit; its process is gone from procfs, so the next run observes the holder dead, +// frees the hold and proceeds to the controller -- no operator step (#12423: interrupted operations are +// reconciled without undocumented preparation). The red is the old lockout: "is held by" with no write. +// The two controls beside it differ only in what procfs says of the holder: still running, and a stat +// read the host refuses. Neither is ever recovered, and neither writes to the controller. +fn resumed_after(realization: OperationRealization, refuse_holder_stat: Bool) -> WitnessEvaluation? { match evaluate_in_witness_frame(frame: matrix_frame_over(realization: realization), subject: fn(_scope) { mtcollins1_boot_wet_on_srv1() }) { WitnessInterrupted { at, state, now: interrupted_clock } => { - let next = as_another_run(w: state, run_id: "4243") - let resumed = evaluate_in_witness_frame( - frame: matrix_frame_over(realization: mtcollins1_boot_dry_realization(identity: realization_identity, initial: next, epoch: interrupted_clock)), - subject: fn(_scope) { mtcollins1_boot_wet_on_srv1() } - ) - at.invocation.at.operation == "StartMedia" - && match at.outcome { DispatchWorkerKilled { committed: c } => c _ => false } - && match resumed { - WitnessReturned { value, route } => - string_contains(s: outcome_reason(a: value), pattern: "is held by 'mtcollins1-boot:4242'") - && count(filter(route, r => is_controller_write(r: r))) == 0 - _ => false - } + let another = as_another_run(w: state, run_id: "4243") + let next = if refuse_holder_stat { with_fs(w: another, fs: fs_refusing_reads_of(fs: another.fs, path: proc_stat_path(pid: first_worker_pid))) } else { another } + if at.invocation.at.operation != "StartMedia" { none } else { + Present { value: evaluate_in_witness_frame( + frame: matrix_frame_over(realization: mtcollins1_boot_dry_realization(identity: realization_identity, initial: next, epoch: interrupted_clock)), + subject: fn(_scope) { mtcollins1_boot_wet_on_srv1() } + ) } + } } + _ => none + } +} + +fn fresh_realization() -> OperationRealization { + mtcollins1_boot_dry_realization(identity: realization_identity, initial: world_with_console(lines: []), epoch: virtual_clock_origin()) +} + +test fn an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one() -> Bool { + match resumed_after(realization: killed_after_start_media(realization: fresh_realization()), refuse_holder_stat: false) { + Present { value: WitnessReturned { value, route } } => + !string_contains(s: outcome_reason(a: value), pattern: "is held by") + && count(filter(route, r => is_controller_write(r: r))) > 0 + _ => false + } +} + +test fn a_live_holder_still_blocks_the_next_attempt() -> Bool { + match resumed_after(realization: stopped_after_start_media(realization: fresh_realization()), refuse_holder_stat: false) { + Present { value: WitnessReturned { value, route } } => + string_contains(s: outcome_reason(a: value), pattern: "which is alive") + && count(filter(route, r => is_controller_write(r: r))) == 0 + _ => false + } +} + +test fn an_unobservable_holder_is_refused_not_recovered() -> Bool { + match resumed_after(realization: killed_after_start_media(realization: fresh_realization()), refuse_holder_stat: true) { + Present { value: WitnessReturned { value, route } } => + string_contains(s: outcome_reason(a: value), pattern: "whose liveness could not be observed") + && count(filter(route, r => is_controller_write(r: r))) == 0 _ => false } } diff --git a/dag/test/claim/modeled_filesystem_witness_test.dag b/dag/test/claim/modeled_filesystem_witness_test.dag index 346e733645a..ba8111f3839 100644 --- a/dag/test/claim/modeled_filesystem_witness_test.dag +++ b/dag/test/claim/modeled_filesystem_witness_test.dag @@ -70,7 +70,7 @@ fn filesystem_frame(initial: ModeledFilesystem) -> WitnessEvaluationFrame ModeledFilesystem { - ModeledFilesystem { directories: ["/", "/var", "/var/lib", "/var/lib/gunbc", hold_root as String], files: [] } + ModeledFilesystem { directories: ["/", "/var", "/var/lib", "/var/lib/gunbc", hold_root as String], files: [], refused_reads: [] } } fn route_operations(route: List) -> List { @@ -126,7 +126,7 @@ fn store_holds_one_slot(fs: ModeledFilesystem) -> Bool { // admit_filesystem_failure_kind, decodes it to FilesystemAlreadyExists -- the same projection a host // io::Error reaches. test fn a_create_exclusive_write_over_an_existing_file_is_already_exists() -> Bool { - let seeded = ModeledFilesystem { directories: ["/", "/tmp"], files: [ModeledFile { path: "/tmp/slot", content: "held" }] } + let seeded = ModeledFilesystem { directories: ["/", "/tmp"], files: [ModeledFile { path: "/tmp/slot", content: "held" }], refused_reads: [] } match evaluate_in_witness_frame( frame: filesystem_frame(initial: seeded), subject: fn(_scope) { @@ -152,6 +152,7 @@ test fn a_listing_is_sorted_immediate_children() -> Bool { let fs = ModeledFilesystem { directories: ["/", "/d", "/d/sub", "/d/sub/deeper"], files: [ModeledFile { path: "/d/b", content: "" }, ModeledFile { path: "/d/a", content: "" }, ModeledFile { path: "/d/sub/c", content: "" }], + refused_reads: [], } match evaluate_in_witness_frame( frame: filesystem_frame(initial: fs), From fb19e1187a6b6aabf32e4a0a06e6bce888e97076 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Mon, 28 Sep 2026 18:43:18 +0000 Subject: [PATCH 23/75] Matrix: backward/forward wall-clock cases and cd_error_code cases over the real boot entry Clock jumps (ModeledClockStep, a pure function of virtual time) inside the media readiness wait: a backward step reaches the production ReadinessClockIncoherent refusal; a forward step closes the window; neither makes a handoff. cd_error_code: 16 with nothing presented (the 2026-09-27 state) refuses before the handoff; with the host on, nothing is written; an error appearing with readiness refuses; a stale lane image with 16 is replaced and booted when the stop clears the code and refused after the replace when it does not (whether it clears is an unobserved firmware fact, so both arms run); a foreign presented image is not stopped. Six of the eight join the declared eval-step drop. Co-Authored-By: Claude Opus 5.5 (1M context) --- ...boot_matrix_new_witness_eval_step_cost.dag | 6 +- ...mtcollins1_boot_acceptance_matrix_test.dag | 148 +++++++++++++++++- docs/design-rung-drops.md | 4 +- src/v2/workflow/floor_eval_step_cost_drop.dag | 26 ++- 4 files changed, 176 insertions(+), 8 deletions(-) diff --git a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag index 9a841cf09e1..21d517762ea 100644 --- a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag +++ b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag @@ -9,7 +9,7 @@ import v2.workflow.floor_eval_step_cost_drop { floor_eval_step_cost_drop_boot_ma // matrix, msg_83af891b). The DECLARATION lives here; the POPULATION's authority is // `v2.workflow.floor_eval_step_cost_drop` `floor_eval_step_cost_drop_boot_matrix_rows`. // -// WHAT IS LOST IS ONE WALL, AND THE CLAIMS ARE UNTOUCHED. The eight identities are planned, executed +// WHAT IS LOST IS ONE WALL, AND THE CLAIMS ARE UNTOUCHED. The fourteen identities are planned, executed // and measured on every pull request that edits them; a semantic red and a wall-clock crossing still // block. Only the eval-step overrun is reported as `EvalStepsOverBudgetUnderDeclaredDrop` rather than // refusing. The budget is not raised. Their CPU stays under the enrolment margin, so they enrol @@ -28,7 +28,7 @@ data mtcollins1_boot_matrix_new_witness_eval_step_cost_population: List data mtcollins1_boot_matrix_new_witness_eval_step_cost: RungDrop = RungDrop { identity: "mtcollins1_boot_matrix_new_witness_eval_step_cost" as NonEmptyStr, - subject: "new-witness eval-step cost gate over the eight mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered", + subject: "new-witness eval-step cost gate over the fourteen mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered", declared: "2026-09-28", @@ -41,6 +41,6 @@ data mtcollins1_boot_matrix_new_witness_eval_step_cost: RungDrop = RungDrop { replacement: "the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter", }, population: mtcollins1_boot_matrix_new_witness_eval_step_cost_population, - restoration_trigger: "THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these eight identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither.", + restoration_trigger: "THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these fourteen identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither.", } } diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index 48d6c301ab1..fc4c5cbeb99 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -11,11 +11,11 @@ import v2.std.witness_evaluation { evaluate_in_witness_frame, witness_diagnostic_rendered_reason, } import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } -import gunbc.bmc_model { BmcWorld, BmcPowerOff, bmc_world, bmc_with_sol_session, bmc_with_sol_drop_after_boot, bmc_sol_drop_fired } +import gunbc.bmc_model { BmcWorld, BmcPowerOff, BmcPowerOn, bmc_world, bmc_with_power, bmc_with_sol_session, bmc_with_sol_drop_after_boot, bmc_sol_drop_fired } import gunbc.filesystem_model { ModeledFilesystem, ModeledFile } import gunbc.process_environment_model { ModeledVariable } import gunbc.remote_host_model { ModeledRemoteHost, ModeledRemoteFile } -import gunbc.wall_clock_model { ModeledWallClock } +import gunbc.wall_clock_model { ModeledWallClock, ModeledClockStep } import gunbc.megarac_media_model { MegaRacMediaWorld, MegaRacShare, MegaRacImage, MegaRacCdRow, megarac_cleared_cd } import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld, ModeledSshAgent, ModeledWorker, ModeledHostConsole, TimedConsoleLine, @@ -503,3 +503,147 @@ test fn pinned_an_interrupted_attempt_locks_out_the_next_one() -> Bool { _ => false } } + +// ─── TIME ───────────────────────────────────────────────────────────────────────────────────────── +// The media readiness wait is bounded by the WALL clock (gunbc.machine_intake_megarac_media_attach +// megarac_await_readiness over extdeps.clock clock_unix_millis_read). In this scenario the attach's +// readiness looks run from t=16 to t=35 of virtual time, so a jump at t=20 lands inside the wait. +fn with_clock_jump(w: MtCollins1BootWorld, at: Int, by: Int) -> MtCollins1BootWorld { + match std.checked_arithmetic.checked_int_to_nat(n: at) { + Absent => w + Present { value: t } => MtCollins1BootWorld { + bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, + clock: ModeledWallClock { unix_at_origin: w.clock.unix_at_origin, step: w.clock.step, jumps: list_append(w.clock.jumps, ModeledClockStep { at: second(count: t), by: std.measure.second_displacement(count: by) }) }, + worker: w.worker, console: w.console, media: w.media, + } + } +} + +// THE WALL CLOCK STEPS BACK A MINUTE DURING THE READINESS WAIT. Virtual time keeps moving; the wall +// reading goes backwards. The wait refuses as unable to bound itself -- the production +// ReadinessClockIncoherent arm -- rather than waiting on a window it can no longer measure, and +// nothing after the attach is written. +test fn a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded() -> Bool { + match run_attempt(world: with_clock_jump(w: world_with_console(lines: []), at: 20, by: 0 - 60)) { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "the clock cannot bound the readiness wait") + && count_named(route: route, name: "megarac.Media.StartMedia") == 1 + && reached_no_power_action(route: route) + _ => false + } +} + +// THE WALL CLOCK JUMPS TEN MINUTES FORWARD DURING THE READINESS WAIT. The window reads as closed at the +// next look, and the attempt refuses without a handoff: a forward step shortens the wait, it never +// buys an unbounded one. +test fn a_wall_clock_jumping_forward_during_readiness_closes_the_window() -> Bool { + match run_attempt(world: with_clock_jump(w: world_with_console(lines: []), at: 20, by: 600)) { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "did not reach Started with a bound session") + && string_contains(s: outcome_reason(a: value), pattern: "(2 looks,") + && reached_no_power_action(route: route) + _ => false + } +} + +// ─── CD ERROR CODE ──────────────────────────────────────────────────────────────────────────────── +// cd_error_code on the general route: 16 is the value the Mt. Collins MegaRAC answered on 2026-09-27 +// with nothing presented (test.claim.machine_intake.megarac_media_convergence_witness_test +// mtcollins1_media_general_2026_09_27). Its meaning is not catalogued. Whether a stop clears it is +// not observed, so the stale-image cases run both arms of the model's parameter. +fn media_errored(code: Int, clears: Bool, after_ready: Int?, cd: MegaRacCdRow) -> MegaRacMediaWorld { + MegaRacMediaWorld { + sessions: [], next_session: 1, share: real_share, mount_cd: 1, cd_error_code: code, + images: [MegaRacImage { image_name: desired_image(), image_index: 5 }], cd: cd, + ready_after: second(count: 12), withdraw_at: none, withdraw_after_ready: none, + error_after_ready: after_ready, error_clears_on_stop: clears, + } +} + +fn no_error_after_ready() -> Int? { + none +} + +// Another census image of this lane: the same name stem with a different digest prefix. +data stale_lane_image: String = "gunbc-mtcollins1-census-ubuntu-24.04.3-arm64-0000000000000000.iso" + +fn presenting(image_name: String) -> MegaRacCdRow { + MegaRacCdRow { image_name: image_name, redirection_status: 1, media_index: 0, session_index: 0, ready_at: none } +} + +// CODE 16 WITH NOTHING PRESENTED AND THE HOST OFF -- the 2026-09-27 state. The attach proceeds and the +// presentation reaches Started, but the code is still 16 at readiness, so the attempt refuses as unable +// to establish the media state, with no handoff. +test fn cd_error_16_with_nothing_presented_refuses_before_the_handoff() -> Bool { + match run_attempt(world: media_varied(media: media_errored(code: 16, clears: true, after_ready: no_error_after_ready(), cd: megarac_cleared_cd()))) { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "cannot establish the media state") + && string_contains(s: outcome_reason(a: value), pattern: "cd_error_code before any write was 16") + && count_named(route: route, name: "megarac.Media.StopMedia") == 0 + && reached_no_power_action(route: route) + _ => false + } +} + +// CODE 16 WITH THE HOST ALREADY ON. Stopping the medium could withdraw what the host is running from, +// so the fresh-presentation experiment is not admitted and nothing is written at all. +test fn cd_error_16_with_the_host_on_writes_nothing() -> Bool { + let w = media_varied(media: media_errored(code: 16, clears: true, after_ready: no_error_after_ready(), cd: megarac_cleared_cd())) + match run_attempt(world: with_bmc(w: w, bmc: bmc_with_power(world: w.bmc, power: BmcPowerOn))) { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "the host is powered on; stopping the medium would withdraw what it may be running from") + && count(filter(route, r => is_controller_write(r: r) && r.invocation.at.service == "megarac.Media")) == 0 + && reached_no_power_action(route: route) + _ => false + } +} + +// A CODE THAT APPEARS WITH READINESS. The presentation reads Started while the general route reports +// 16 at readiness; the attempt refuses before the handoff. +test fn cd_error_appearing_with_readiness_refuses_before_the_handoff() -> Bool { + match run_attempt(world: media_varied(media: media_errored(code: 0, clears: true, after_ready: Present { value: 16 }, cd: megarac_cleared_cd()))) { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "cd_error_code before any write was 0 and at readiness 16") + && reached_no_power_action(route: route) + _ => false + } +} + +// A STALE IMAGE OF THIS LANE IS PRESENTED WITH CODE 16 AND THE HOST OFF, AND THE STOP CLEARS THE CODE. +// The attempt stops the stale image, attaches the desired one, and proceeds to the boot: stop, then +// start, then the override, then power. +test fn a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted() -> Bool { + match run_attempt(world: media_varied(media: media_errored(code: 16, clears: true, after_ready: no_error_after_ready(), cd: presenting(image_name: stale_lane_image)))) { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "deadline reached without a host-capture terminal") + && first_ordinal(route: route, name: "megarac.Media.StopMedia") < first_ordinal(route: route, name: "megarac.Media.StartMedia") + && first_ordinal(route: route, name: "megarac.Media.StartMedia") < first_ordinal(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") + && controller_writes_are_under_the_hold(route: route) + _ => false + } +} + +// THE SAME STALE IMAGE, BUT THE STOP DOES NOT CLEAR THE CODE. The replacement reaches Started with the +// code still 16, and the attempt refuses before the handoff. +test fn a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace() -> Bool { + match run_attempt(world: media_varied(media: media_errored(code: 16, clears: false, after_ready: no_error_after_ready(), cd: presenting(image_name: stale_lane_image)))) { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "cannot establish the media state") + && count_named(route: route, name: "megarac.Media.StopMedia") == 1 + && reached_no_power_action(route: route) + _ => false + } +} + +// A FOREIGN IMAGE IS PRESENTED -- not a census image of this lane. It is not this workflow's to stop: +// the attempt refuses and writes nothing to the media. +test fn a_foreign_presented_image_is_not_stopped() -> Bool { + match run_attempt(world: media_varied(media: media_errored(code: 0, clears: true, after_ready: no_error_after_ready(), cd: presenting(image_name: "gunbc-mtcollins1-census-older.iso")))) { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "it is not this workflow's to stop, so nothing was written") + && count_named(route: route, name: "megarac.Media.StopMedia") == 0 + && count_named(route: route, name: "megarac.Media.StartMedia") == 0 + && reached_no_power_action(route: route) + _ => false + } +} diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index fe7c3561532..7491f50a3e4 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -338,9 +338,9 @@ new-witness eval-step cost gate over the one roadmap page claim that derives the new-witness eval-step cost gate over the ten interpreted P-256 and P-384 point and group-law checks and SHA-384 FIPS vectors of the App Attest path: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the P-384 and SHA-384 primitives executing as natively emitted code rather than as interpreted bignat and Word64 folds). Population: test.claim.p384_dag_ecdsa_witness_test.the_p384_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_beside_the_base_point_is_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_with_a_coordinate_at_p_is_not_admitted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.apples_ca_and_root_keys_are_on_p384: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.sha384_fips_witness_test.sha384_of_the_empty_message_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published empty message and a one-octet message on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_abc_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published abc vector and abd on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_the_896_bit_message_is_the_published_two_block_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is four SHA-384 block compressions, the published 896-bit two-block vector and a last-block mutation on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.p256_dag_ecdsa_witness_test.the_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35708011844 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, well inside the wall deadline and over the new-witness eval-step budget. The billed work is one P-256 curve equation over the published base point as 11-limb bignat folds on an interpreter that reifies no machine width. It is a MEMBER BECAUSE IT WAS SPLIT OUT of a claim that also asserted n*G = infinity: that conjunction crossed the 8000ms wall deadline and was INTERRUPTED BEFORE ANY VERDICT, so both facts were being lost; the scalar multiplication left the floor for the native row the frontier names, and this cheap half now reaches a verdict. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field, test.claim.p384_dag_ecdsa_witness_test.doubling_and_adding_the_base_point_stay_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling, one addition and two projective curve-equation checks at 16 limbs, test.claim.p384_dag_ecdsa_witness_test.doubling_an_off_curve_point_stays_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling and one projective curve-equation check at 16 limbs. Restored when: THE CAPABILITY: gunbc test //gunbc/instruments:native-crypto-vectors EXECUTING ON THE MERGE PATH, i.e. as a phase of a required lane whose red blocks a merge, running these ten identities natively (its cases p256_the_base_point_is_on_the_curve, p384_the_base_point_is_on_the_curve, p384_red_a_point_beside_the_base_point_is_off_the_curve, p384_red_a_point_with_a_coordinate_at_p_is_not_admitted, p384_doubling_and_adding_the_base_point_stay_on_the_curve, p384_red_doubling_an_off_curve_point_stays_off_the_curve, p384_apples_ca_and_root_keys_are_on_the_curve and the sha384_* FIPS cases with their reds) while each still evaluates the real curve equation or the real hash; WHAT THAT MUST BE SUFFICIENT FOR: the P-384 parameters and SHA-384 are exercised on the acceptance path with no interpreted 16-limb fold inside a claim frame, so the interpreted identities can leave the floor for that row, or they measure under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives. The same row run BY NAME (as it exists since gunbc#12306) executes the facts natively but is NOT the acceptance path and retires nothing. Supplying the curve check's answer or the digest as a fixture, or deleting the identities, satisfies neither. -### new-witness eval-step cost gate over the eight mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 +### new-witness eval-step cost gate over the fourteen mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 -new-witness eval-step cost gate over the eight mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_healthy_census_is_refused_at_the_sol_teardown: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these eight identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. +new-witness eval-step cost gate over the fourteen mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_healthy_census_is_refused_at_the_sol_teardown: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch over dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag on the stacked matrix branch (eval_steps are host-independent), and the required floor of the pull request that adds it; the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_jumping_forward_during_readiness_closes_the_window: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch over dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag on the stacked matrix branch (eval_steps are host-independent), and the required floor of the pull request that adds it; the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch over dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag on the stacked matrix branch (eval_steps are host-independent), and the required floor of the pull request that adds it; the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch over dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag on the stacked matrix branch (eval_steps are host-independent), and the required floor of the pull request that adds it; the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch over dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag on the stacked matrix branch (eval_steps are host-independent), and the required floor of the pull request that adds it; the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch over dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag on the stacked matrix branch (eval_steps are host-independent), and the required floor of the pull request that adds it; the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these fourteen identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. ### new-witness eval-step cost gate over six App Attest verifier claims -- the two real-path inhabitance claims over Apple's objects, three single structural steps priced by their own SHA-256s, and the wire-carrier join: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 diff --git a/src/v2/workflow/floor_eval_step_cost_drop.dag b/src/v2/workflow/floor_eval_step_cost_drop.dag index e9e32abcabd..5056b439fc4 100644 --- a/src/v2/workflow/floor_eval_step_cost_drop.dag +++ b/src/v2/workflow/floor_eval_step_cost_drop.dag @@ -235,7 +235,7 @@ data floor_eval_step_cost_drop_python_to_typescript_inhabitance_rows: List List { From 2dbba796f4084395ec3117c58a9fa18f98256f97 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Mon, 28 Sep 2026 18:51:52 +0000 Subject: [PATCH 24/75] Fix the floor's refusals: optional list reads, the tag literal's process, callers of boot_run_owner; the held-unit case's other run is live in procfs Co-Authored-By: Claude Opus 5.5 (1M context) --- .../mtcollins1_maintenance_hold.dag | 23 ++++++++++++------- ...mtcollins1_boot_acceptance_matrix_test.dag | 12 ++++++---- .../claim/modeled_filesystem_witness_test.dag | 5 ++-- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/dag/gunbc/machine_intake/mtcollins1_maintenance_hold.dag b/dag/gunbc/machine_intake/mtcollins1_maintenance_hold.dag index 1c4220eb2e3..d1aef9b1d83 100644 --- a/dag/gunbc/machine_intake/mtcollins1_maintenance_hold.dag +++ b/dag/gunbc/machine_intake/mtcollins1_maintenance_hold.dag @@ -1,6 +1,6 @@ module gunbc.machine_intake_mtcollins1_maintenance_hold -import std.types { Bool, NonEmptyStr, String } +import std.types { Bool, Int, List, NonEmptyStr, String } import std.process { ProcessExit, ExitSuccess, ExitFailure, exit_failure } import std.durable_compare_and_set { CasGeneration } import v2.std.optional { Present, Absent } @@ -99,14 +99,21 @@ fn unit_hold_process_text(p: ProcessIdentity) -> String { join([unit_hold_process_marker, p.boot_id as String, ",pid=", to_string(p.pid), ",start=", p.start_time as String], "") } +fn text_at(xs: List, i: Int) -> String { + match xs.skip(n: i).first() { + Present { value: v } => v + Absent => "" + } +} + fn unit_hold_process_decode(text: String) -> ProcessIdentity? { let parts = split(s: text, delimiter: ",") if count(parts) != 3 { none } else { - let b = parts[0] - let pid_text = parts[1] - let start_text = parts[2] + let b = text_at(xs: parts, i: 0) + let pid_text = text_at(xs: parts, i: 1) + let start_text = text_at(xs: parts, i: 2) if !starts_with(s: b, prefix: "boot=") || !starts_with(s: pid_text, prefix: "pid=") || !starts_with(s: start_text, prefix: "start=") { none } else { @@ -159,7 +166,7 @@ fn unit_hold_owner_detail_after(raw: String, tag: String) -> NonEmptyStr? { fn decode_unit_hold_owner(owner: DurableHoldOwnerRef) -> UnitHoldOwnerDecode { let raw = owner as String let op = unit_hold_owner_tag(o: OperatorMaintenance { reason: "x" as NonEmptyStr }) - let boot = unit_hold_owner_tag(o: BootRun { run_id: "x" as NonEmptyStr }) + let boot = unit_hold_owner_tag(o: BootRun { run_id: "x" as NonEmptyStr, process: ProcessIdentity { boot_id: "x" as NonEmptyStr, pid: 1, start_time: "x" as NonEmptyStr } }) let reset = unit_hold_owner_tag(o: HostResetReturn { attempt: "x" as NonEmptyStr }) if starts_with(s: raw, prefix: op) { match unit_hold_owner_detail_after(raw: raw, tag: op) { Present { value: d } => UnitHoldOwnerDecoded { owner: OperatorMaintenance { reason: d } } Absent => UnitHoldOwnerUnrecognized { raw: raw } } @@ -168,11 +175,11 @@ fn decode_unit_hold_owner(owner: DurableHoldOwnerRef) -> UnitHoldOwnerDecode { Absent => UnitHoldOwnerUnrecognized { raw: raw } Present { value: d } => { let halves = split(s: d as String, delimiter: unit_hold_process_marker) - if count(halves) != 2 || halves[0] == "" { + if count(halves) != 2 || text_at(xs: halves, i: 0) == "" { UnitHoldOwnerUnrecognized { raw: raw } } else { - match unit_hold_process_decode(text: concat("boot=", halves[1])) { - Present { value: p } => UnitHoldOwnerDecoded { owner: BootRun { run_id: halves[0] as NonEmptyStr, process: p } } + match unit_hold_process_decode(text: concat("boot=", text_at(xs: halves, i: 1))) { + Present { value: p } => UnitHoldOwnerDecoded { owner: BootRun { run_id: text_at(xs: halves, i: 0) as NonEmptyStr, process: p } } Absent => UnitHoldOwnerUnrecognized { raw: raw } } } diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index 5a140540513..07783cc4a13 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -1,5 +1,6 @@ module test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test +import gunbc.build_cache_instance { ProcessIdentity } import std.types { Bool, Int, List, NonEmptyStr, String } import std.measure { Second, second } import std.materialization_ladder { Frame, SharedStateFrame } @@ -12,7 +13,7 @@ import v2.std.witness_evaluation { } import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } import gunbc.bmc_model { BmcWorld, BmcPowerOff, bmc_world, bmc_with_sol_session, bmc_with_sol_drop_after_boot, bmc_sol_drop_fired } -import gunbc.filesystem_model { ModeledFilesystem, ModeledFile, fs_refusing_reads_of } +import gunbc.filesystem_model { ModeledFilesystem, ModeledFile, fs_refusing_reads_of, fs_with_file } import gunbc.process_environment_model { ModeledVariable } import gunbc.remote_host_model { ModeledRemoteHost, ModeledRemoteFile } import gunbc.wall_clock_model { ModeledWallClock } @@ -20,7 +21,7 @@ import gunbc.megarac_media_model { MegaRacMediaWorld, MegaRacShare, MegaRacImage import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld, ModeledSshAgent, ModeledWorker, ModeledHostConsole, TimedConsoleLine, mtcollins1_boot_dry_realization, with_media, with_bmc, with_fs, - worker_process_started, worker_process_killed, proc_stat_path, + worker_process_started, worker_process_killed, proc_stat_path, proc_stat_line, } import v2.std.operation_realization { OperationRealization, OperationBinding, OperationCall, OperationStep, OperationObserved, OperationWorkerKilled, @@ -275,9 +276,12 @@ test fn pinned_a_healthy_census_is_refused_at_the_sol_teardown() -> Bool { // refused at the hold with the controller untouched: no controller write of any kind appears in its // route, and it never starts a SOL collector. test fn a_second_run_for_a_held_unit_writes_nothing_to_the_controller() -> Bool { + // The other run is still running: its process is in procfs, so it is a live holder, not a dead one. + let base = world_with_console(lines: []) + let other_running = with_fs(w: base, fs: fs_with_file(fs: base.fs, path: proc_stat_path(pid: 2900), content: proc_stat_line(pid: 2900, start_ticks: 100))) let prior = evaluate_in_witness_frame( - frame: matrix_frame(world: world_with_console(lines: [])), - subject: fn(_scope) { file_hold_acquire(root: unit_hold_store_root, slot_key: mtcollins1_unit_hold_key, requested_owner: boot_run_owner(run_id: "4141" as NonEmptyStr)) } + frame: matrix_frame(world: other_running), + subject: fn(_scope) { file_hold_acquire(root: unit_hold_store_root, slot_key: mtcollins1_unit_hold_key, requested_owner: boot_run_owner(run_id: "4141" as NonEmptyStr, process: ProcessIdentity { boot_id: worker_boot_id as NonEmptyStr, pid: 2900, start_time: "100" as NonEmptyStr })) } ) match prior { WitnessReturned { state } => match state { diff --git a/dag/test/claim/modeled_filesystem_witness_test.dag b/dag/test/claim/modeled_filesystem_witness_test.dag index ba8111f3839..ca802309a74 100644 --- a/dag/test/claim/modeled_filesystem_witness_test.dag +++ b/dag/test/claim/modeled_filesystem_witness_test.dag @@ -1,5 +1,6 @@ module test.claim.modeled_filesystem_witness_test +import gunbc.build_cache_instance { ProcessIdentity } import std.types { Bool, List, NonEmptyStr, String } import std.materialization_ladder { Frame, SharedStateFrame } import std.effect_grant { @@ -97,8 +98,8 @@ fn occupied_by(o: gunbc.durable_exclusive_hold_file_store.FileHoldAcquireOutcome // is the production fold's reading of what the model's filesystem holds, and the route shows the // second contender never wrote. test fn two_contenders_for_one_unit_get_one_hold() -> Bool { - let first_owner = boot_run_owner(run_id: "run-a" as NonEmptyStr) - let second_owner = boot_run_owner(run_id: "run-b" as NonEmptyStr) + let first_owner = boot_run_owner(run_id: "run-a" as NonEmptyStr, process: ProcessIdentity { boot_id: "b" as NonEmptyStr, pid: 10, start_time: "1" as NonEmptyStr }) + let second_owner = boot_run_owner(run_id: "run-b" as NonEmptyStr, process: ProcessIdentity { boot_id: "b" as NonEmptyStr, pid: 11, start_time: "2" as NonEmptyStr }) let result = evaluate_in_witness_frame( frame: filesystem_frame(initial: empty_hold_store()), subject: fn(_scope) { From e597579516ffa5d6ba13fcc3cc3ab40556c9bb92 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Mon, 28 Sep 2026 19:04:46 +0000 Subject: [PATCH 25/75] File arm refuses a pathless dispatch; modeled byte_count is a ByteSize of UTF-8 bytes - Review 72311: a file operation dispatched without a string `path` is a harness fault, not an empty path fed to map_file_outputs. - Review 72309 (relayed from #12554): FileOperationSucceeded.byte_count is a std.measure ByteSize, and gunbc.filesystem_model fills it with the UTF-8 byte length (std.bytes utf8_encode_bytes, as std.materialization_object does), matching the realization's content.len(), not the code-point count. The dispatcher reads it through extdeps.transports.file file_observation_byte_count. Control: a_modeled_read_counts_utf8_bytes. Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/extdeps/transports/file.dag | 9 +++++- dag/gunbc/filesystem_model.dag | 21 ++++++++----- .../claim/boot_world_models_witness_test.dag | 16 +++++++++- src/v1/stage0/src/v1_interpreter.rs | 31 +++++++++++++------ 4 files changed, 57 insertions(+), 20 deletions(-) diff --git a/dag/extdeps/transports/file.dag b/dag/extdeps/transports/file.dag index ceeb0934b04..cddd7a67933 100644 --- a/dag/extdeps/transports/file.dag +++ b/dag/extdeps/transports/file.dag @@ -1,6 +1,7 @@ module extdeps.transports.file import std.types { FermiDepth, Int, String } +import std.measure { ByteSize, byte_size_count } import extdeps.filesystem.filesystem_io { FilesystemFailureKind } import std.fidelity { TransportFidelity } import extdeps.external_authority { ExternalAuthority } @@ -27,5 +28,11 @@ type FileTransportConfig { // derived exactly as from a real call. A listing's content follows the realization's own contract: // the entry names, sorted, one per line. type FileExchangeObservation - = FileOperationSucceeded { byte_count: Int, content: String } + = FileOperationSucceeded { byte_count: ByteSize, content: String } | FileOperationFailed { kind: FilesystemFailureKind, error: String } + +// The byte count as the host integer the file transport's `byte_count` output field carries; the +// dispatcher reads a modeled observation's count through this rather than decoding the measure. +fn file_observation_byte_count(bytes: ByteSize) -> Int { + byte_size_count(b: bytes) as Int +} diff --git a/dag/gunbc/filesystem_model.dag b/dag/gunbc/filesystem_model.dag index daca446e524..008fdbc0401 100644 --- a/dag/gunbc/filesystem_model.dag +++ b/dag/gunbc/filesystem_model.dag @@ -1,7 +1,8 @@ module gunbc.filesystem_model import std.types { Bool, List, String } -import std.measure { second } +import std.measure { second, ByteSize, byte_size } +import std.bytes { bytes_octets, utf8_encode_bytes } import v2.std.operation_argv { OperationRef, BoundOperationInvocation } import v2.std.operation_realization { OperationBinding, OperationCall, OperationStep, OperationObserved, OperationHarnessFault, @@ -25,8 +26,12 @@ import extdeps.filesystem.filesystem_io { // write_create_new_with_mode is accepted and not stored), ownership, symlinks, partial writes, and // the atomicity of a real create-exclusive under concurrent processes. Those are properties of the real // filesystem, and their evidence is the file-store tests that run against a real directory. -// byte_count is the content's string length, which equals its byte length for the ASCII content the -// consumers here write. +// byte_count is the content's UTF-8 byte length, as the realization's own `content.len()` reports it -- +// not its code-point count -- computed as std.materialization_object does. +fn content_bytes(s: String) -> ByteSize { + byte_size(count: bytes_octets(b: utf8_encode_bytes(s: s)) |> count()) +} + type ModeledFile { path: String content: String @@ -75,7 +80,7 @@ fn failed_with(kind: extdeps.filesystem.filesystem_io.FilesystemFailureKind, mes fn fs_read(fs: ModeledFilesystem, path: String) -> FileExchangeObservation { match fs_file(fs: fs, path: path) { - Present { value: file } => FileOperationSucceeded { byte_count: string_length(s: file.content), content: file.content } + Present { value: file } => FileOperationSucceeded { byte_count: content_bytes(s: file.content), content: file.content } Absent => if fs_is_directory(fs: fs, path: path) { failed_with(kind: FilesystemOtherFailure, message: concat("Is a directory: ", path)) } else { failed_with(kind: FilesystemNotFound, message: concat("No such file or directory: ", path)) } @@ -98,10 +103,10 @@ fn fs_write(fs: ModeledFilesystem, path: String, content: String, create_new: Bo if create_new { ModeledFileWrite { fs: fs, observation: failed_with(kind: FilesystemAlreadyExists, message: concat("File exists: ", path)) } } else { - ModeledFileWrite { fs: fs_with_file(fs: fs, path: path, content: content), observation: FileOperationSucceeded { byte_count: string_length(s: content), content: "" } } + ModeledFileWrite { fs: fs_with_file(fs: fs, path: path, content: content), observation: FileOperationSucceeded { byte_count: content_bytes(s: content), content: "" } } } Absent => - ModeledFileWrite { fs: fs_with_file(fs: fs, path: path, content: content), observation: FileOperationSucceeded { byte_count: string_length(s: content), content: "" } } + ModeledFileWrite { fs: fs_with_file(fs: fs, path: path, content: content), observation: FileOperationSucceeded { byte_count: content_bytes(s: content), content: "" } } } } } @@ -116,7 +121,7 @@ fn fs_with_file(fs: ModeledFilesystem, path: String, content: String) -> Modeled fn fs_delete(fs: ModeledFilesystem, path: String) -> ModeledFileWrite { match fs_file(fs: fs, path: path) { Present { value: _ } => - ModeledFileWrite { fs: ModeledFilesystem { directories: fs.directories, files: filter(fs.files, f => f.path != path) }, observation: FileOperationSucceeded { byte_count: 0, content: "" } } + ModeledFileWrite { fs: ModeledFilesystem { directories: fs.directories, files: filter(fs.files, f => f.path != path) }, observation: FileOperationSucceeded { byte_count: byte_size(count: 0), content: "" } } Absent => if fs_is_directory(fs: fs, path: path) { ModeledFileWrite { fs: fs, observation: failed_with(kind: FilesystemOtherFailure, message: concat("Is a directory: ", path)) } } else { ModeledFileWrite { fs: fs, observation: failed_with(kind: FilesystemNotFound, message: concat("No such file or directory: ", path)) } } @@ -128,7 +133,7 @@ fn fs_list(fs: ModeledFilesystem, path: String) -> FileExchangeObservation { let file_names = map(filter(fs.files, f => fs_parent(path: f.path) == path), f => fs_leaf(path: f.path)) let dir_names = map(filter(fs.directories, d => d != path && fs_parent(path: d) == path), d => fs_leaf(path: d)) let listing = join(sort_by(concat_lists(a: file_names, b: dir_names), n => n), "\n") - FileOperationSucceeded { byte_count: string_length(s: listing), content: listing } + FileOperationSucceeded { byte_count: content_bytes(s: listing), content: listing } } else { match fs_file(fs: fs, path: path) { Present { value: _ } => failed_with(kind: FilesystemNotDirectory, message: concat("Not a directory: ", path)) diff --git a/dag/test/claim/boot_world_models_witness_test.dag b/dag/test/claim/boot_world_models_witness_test.dag index 60a37223697..ce1e736918a 100644 --- a/dag/test/claim/boot_world_models_witness_test.dag +++ b/dag/test/claim/boot_world_models_witness_test.dag @@ -11,7 +11,7 @@ import extdeps.tools.gnu_coreutils { cat_command } import extdeps.crypto.hash { sha256sum_file_command } import gunbc.wall_clock_model { ModeledWallClock, iso8601_utc, wall_clock_unix } import gunbc.remote_host_model { ModeledRemoteHost, ModeledRemoteFile, remote_request, remote_answer } -import gunbc.filesystem_model { ModeledFilesystem, ModeledFile, fs_parent, fs_write, fs_list } +import gunbc.filesystem_model { ModeledFilesystem, ModeledFile, fs_parent, fs_write, fs_list, fs_read } data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly @@ -92,3 +92,17 @@ test fn a_power_restore_keeps_the_sol_drop_it_schedules() -> Bool { && bmc_power_is_on(world: at_forty) && !at_forty.sol_session_open && bmc_sol_drop_fired(world: at_forty) && count(at_forty.fired) == 2 && count(at_forty.pending) == 0 } + +// A READ REPORTS UTF-8 BYTES, NOT CODE POINTS (review 72309): the realization's own file read reports +// content.len(), so the model must too. `é` is one code point and two bytes. +fn read_byte_count(fs: ModeledFilesystem, path: String) -> Int { + match fs_read(fs: fs, path: path) { + extdeps.transports.file.FileOperationSucceeded { byte_count: b, content: _ } => extdeps.transports.file.file_observation_byte_count(bytes: b) + _ => 0 - 1 + } +} + +test fn a_modeled_read_counts_utf8_bytes() -> Bool { + let fs = ModeledFilesystem { directories: ["/", "/t"], files: [ModeledFile { path: "/t/a", content: "é" }, ModeledFile { path: "/t/b", content: "abc" }] } + read_byte_count(fs: fs, path: "/t/a") == 2 && read_byte_count(fs: fs, path: "/t/b") == 3 +} diff --git a/src/v1/stage0/src/v1_interpreter.rs b/src/v1/stage0/src/v1_interpreter.rs index 1c07976a545..aa2bd7f3e7a 100644 --- a/src/v1/stage0/src/v1_interpreter.rs +++ b/src/v1/stage0/src/v1_interpreter.rs @@ -8420,13 +8420,15 @@ fn dispatch_modeled_operation( .map_err(&harness_fault) .map(|shell| shell_result_projection(shell, op_node, ctx)) } else { - let path = match param_env.lookup(ctx.sym("path")) { - Some(Value::Str(p)) => p.to_string(), - _ => String::new(), - }; - file_result_of_observation(&observation, &path, ctx) - .map_err(&harness_fault) - .map(|file| map_file_outputs(&file, op_node, ctx)) + // Every file-transport operation declares its path; one dispatched without a string + // path is a malformed dispatch and refuses, never an empty path the projection would + // report as if the operation had named one. + match param_env.lookup(ctx.sym("path")) { + Some(Value::Str(p)) => file_result_of_observation(&observation, &p, ctx), + _ => Err("a file operation was dispatched without a string path".to_string()), + } + .map_err(&harness_fault) + .map(|file| map_file_outputs(&file, op_node, ctx)) }; let projected = projected?; log( @@ -8500,9 +8502,18 @@ fn file_result_of_observation( }; match file_arm.as_str() { "FileOperationSucceeded" => { - let byte_count = match ctx.field(&file_fields, "byte_count") { - Some(Value::Int(n)) => *n, - _ => return Err("the file observation carries no byte_count".to_string()), + let bytes = ctx + .field(&file_fields, "byte_count") + .cloned() + .ok_or("the file observation carries no byte_count")?; + let byte_count = match run_in_context_with_args( + ctx, + "file_observation_byte_count", + &[(Some("bytes".to_string()), bytes)], + false, + ) { + Ok(Value::Int(n)) => n, + _ => return Err("the file observation's byte_count is not a byte size".to_string()), }; Ok(FileResult { success: true, From 5ccd728b1c4614de48e422512a1dddb7ee26c501 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Mon, 28 Sep 2026 19:05:14 +0000 Subject: [PATCH 26/75] Matrix: the lost-presentation case asserts the named cause wherever it appears in the reason, at either post-handoff look Co-Authored-By: Claude Opus 5.5 (1M context) --- .../mtcollins1_boot_acceptance_matrix_test.dag | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index 24947a5358d..f47f8e02440 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -382,12 +382,14 @@ test fn a_presentation_lost_after_readiness_stops_the_handoff() -> Bool { // A PRESENTATION LOST AFTER THE HANDOFF IS THE NAMED CAUSE (finding 4, repaired in #12554). Lost // twenty seconds after readiness -- after the boot override and the power action -- the watch still -// reaches its deadline, but the after-handoff look affirmed the loss, so the outcome names it and -// keeps the deadline beside it (#12423 media: presentation withdrawal). The red is the bare deadline. +// reaches its deadline, but a post-handoff look (after-handoff, or end-of-attempt when the handoff +// finished before the withdrawal) affirmed the loss, so the outcome names it and keeps the deadline +// beside it; which look sees it is the unit witnesses' subject, not this case's (#12423 media: presentation withdrawal). The red is the bare deadline. test fn a_presentation_lost_after_the_handoff_is_the_reported_cause() -> Bool { match run_attempt(world: media_varied(media: media_with(images: [MegaRacImage { image_name: desired_image(), image_index: 5 }], share: real_share, cd: megarac_cleared_cd(), ready_after: 12, withdraw_after_ready: Present { value: second(count: 20) }))) { WitnessReturned { value, route } => - starts_with(s: outcome_reason(a: value), prefix: "mtcollins1 boot: media presentation lost at after-handoff (") + (string_contains(s: outcome_reason(a: value), pattern: "media presentation lost at after-handoff (") + || string_contains(s: outcome_reason(a: value), pattern: "media presentation lost at end-of-attempt (")) && string_contains(s: outcome_reason(a: value), pattern: "deadline reached without a host-capture terminal") && count_named(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") == 1 _ => false From 355cd9d06e0de1af92a78fb2b59b00aefb24bd43 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Mon, 28 Sep 2026 19:08:54 +0000 Subject: [PATCH 27/75] Matrix: move the live-holder note above its declaration (annotations are module-item grain) Co-Authored-By: Claude Opus 5.5 (1M context) --- .../machine_intake/mtcollins1_boot_acceptance_matrix_test.dag | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index 07783cc4a13..fe571d15a1e 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -274,9 +274,9 @@ test fn pinned_a_healthy_census_is_refused_at_the_sol_teardown() -> Bool { // THE SAME UNIT HELD BY ANOTHER RUN. Before this attempt starts, a different run's boot holds the // unit (acquired through the production file_hold_acquire, into the same store). This attempt is // refused at the hold with the controller untouched: no controller write of any kind appears in its -// route, and it never starts a SOL collector. +// route, and it never starts a SOL collector. The other run is still running -- its process is in +// procfs -- so it is a live holder, not a dead one to recover. test fn a_second_run_for_a_held_unit_writes_nothing_to_the_controller() -> Bool { - // The other run is still running: its process is in procfs, so it is a live holder, not a dead one. let base = world_with_console(lines: []) let other_running = with_fs(w: base, fs: fs_with_file(fs: base.fs, path: proc_stat_path(pid: 2900), content: proc_stat_line(pid: 2900, start_ticks: 100))) let prior = evaluate_in_witness_frame( From 441d65356fa3bfeb8a25d71f1535cf91bc94dd0f Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Mon, 28 Sep 2026 19:49:25 +0000 Subject: [PATCH 28/75] Unit hold: the holder's identity carries its pid namespace; a missing pid is death only when read from that namespace, otherwise unobservable (review 72326) Co-Authored-By: Claude Opus 5.5 (1M context) --- .../mtcollins1_boot_dry_realization.dag | 26 ++++- .../mtcollins1_maintenance_hold.dag | 100 +++++++++++++----- ...mtcollins1_boot_acceptance_matrix_test.dag | 30 +++++- ...collins1_maintenance_hold_witness_test.dag | 17 +-- .../claim/modeled_filesystem_witness_test.dag | 4 +- 5 files changed, 136 insertions(+), 41 deletions(-) diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag index 12a20378ff4..c818dd919e3 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag @@ -1,5 +1,6 @@ module gunbc.machine_intake_mtcollins1_boot_dry_realization +import extdeps.tools.gnu_coreutils { readlink_command } import std.types { Bool, Int, List, NonEmptyStr, String } import std.measure { Second, second, second_count } import v2.std.operation_argv { OperationRef } @@ -128,7 +129,10 @@ fn proc_cmdline_path(pid: Int) -> String { // read from these (gunbc.machine_intake_mtcollins1_maintenance_hold self_process_identity) and a // successor observes the holder through them (holder_process_liveness), so a worker that starts writes // both, and a worker that is killed loses its /proc//stat: the kernel removes a dead process's -// directory. Only the fields a reader uses are meaningful; the others are zeros. +// directory. Only the fields a reader uses are meaningful; the others are zeros. The worker's pid +// namespace is the target of the /proc/self/ns/pid link, which the model stores as that path's text +// and answers to `readlink /proc/self/ns/pid` (readlink_answer); the kernel refuses to read the link +// itself, and production only ever readlinks it. data proc_boot_id_file: String = "/proc/sys/kernel/random/boot_id" fn proc_stat_path(pid: Int) -> String { @@ -139,9 +143,21 @@ fn proc_stat_line(pid: Int, start_ticks: Int) -> String { join([to_string(pid), " (gunbc) S 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ", to_string(start_ticks), " 0 0\n"], "") } -fn worker_process_started(fs: ModeledFilesystem, boot_id: String, pid: Int, start_ticks: Int) -> ModeledFilesystem { +data proc_self_pid_namespace_link: String = "/proc/self/ns/pid" + +fn worker_process_started(fs: ModeledFilesystem, boot_id: String, pid_namespace: String, pid: Int, start_ticks: Int) -> ModeledFilesystem { let line = proc_stat_line(pid: pid, start_ticks: start_ticks) - fs_with_file(fs: fs_with_file(fs: fs_with_file(fs: fs, path: proc_boot_id_file, content: concat(boot_id, "\n")), path: "/proc/self/stat", content: line), path: proc_stat_path(pid: pid), content: line) + let with_ns = fs_with_file(fs: fs, path: proc_self_pid_namespace_link, content: pid_namespace) + fs_with_file(fs: fs_with_file(fs: fs_with_file(fs: with_ns, path: proc_boot_id_file, content: concat(boot_id, "\n")), path: "/proc/self/stat", content: line), path: proc_stat_path(pid: pid), content: line) +} + +// readlink(1): the link's target and a newline on stdout, exit 0; for a missing link, a diagnostic +// on stderr and exit 1. +fn readlink_answer(w: MtCollins1BootWorld, path: String) -> ShellExchangeObservation { + match fs_file(fs: w.fs, path: path) { + Present { value: f } => ShellProcessExited { exit_code: 0, stdout: concat(f.content, "\n"), stderr: "" } + Absent => ShellProcessExited { exit_code: 1, stdout: "", stderr: "" } + } } fn worker_process_killed(fs: ModeledFilesystem, pid: Int) -> ModeledFilesystem { @@ -303,6 +319,10 @@ fn mtcollins1_boot_dry_realization(identity: NonEmptyStr, initial: MtCollins1Boo words: local_command_words(command: env_prefixed_command(bindings: [EnvSet { name: "SSH_AUTH_SOCK", value: initial.agent.socket }], command: ssh_add_list_identities_command())), answer: fn(w) { agent_listing(agent: w.agent) }, }, + ModeledInvocation { + words: local_command_words(command: readlink_command(path: proc_self_pid_namespace_link)), + answer: fn(w) { readlink_answer(w: w, path: proc_self_pid_namespace_link) }, + }, ]) let spanning = [ OperationBinding { at: bmc_ipmi_operation(operation: "SdrDumpAuthenticated"), handler: sdr_dump_handler }, diff --git a/dag/gunbc/machine_intake/mtcollins1_maintenance_hold.dag b/dag/gunbc/machine_intake/mtcollins1_maintenance_hold.dag index d1aef9b1d83..ea74599d698 100644 --- a/dag/gunbc/machine_intake/mtcollins1_maintenance_hold.dag +++ b/dag/gunbc/machine_intake/mtcollins1_maintenance_hold.dag @@ -16,6 +16,10 @@ import std.nat { Nat } import std.checked_arithmetic { checked_int_to_nat } import std.algebra { trim } import gunbc.build_cache_instance { ProcessIdentity, process_identity_eq } +import gunbc.command_runner { run_shell_command_capture } +import extdeps.exec.command { LocalExec } +import extdeps.shell.exec { ProcessOutcome, ProcessOutputPresent, ProcessOutputAbsent, ProcessRefused } +import extdeps.tools.gnu_coreutils { readlink_command } import extdeps.linux.proc_pid_stat { proc_pid_stat_start_time, StartTimeObserved, StartTimeCommUnterminated, StartTimeFieldAbsent, StartTimeUnparseable, proc_pid_stat_pid, PidObserved, PidUnparseable, @@ -75,28 +79,36 @@ data mtcollins1_unit_hold_store_host: NonEmptyStr = operator_host_srv1 as NonEmp // worker killed while holding the unit left a hold nobody could ever show to be dead, and every later // attempt refused on it. The boot's owner therefore carries the holding process's identity -- boot id, // pid and start time, gunbc.build_cache_instance ProcessIdentity, the triple that survives pid reuse -// and reboots -- and a successor recovers the slot only after OBSERVING that process gone. An operator +// and reboots -- and the PID NAMESPACE it was read in (review 72326): a pid means something only in +// its namespace, and boot_id is shared by every namespace on a host, so a successor in another +// namespace would find NotFound for a holder that is alive. A successor recovers the slot only after +// OBSERVING that process gone FROM THE HOLDER'S OWN NAMESPACE; from any other it cannot look. An operator // maintenance hold is deliberately not a process (it outlives the session that took it), so it is // never recovered; a host reset-return hold names no process yet, so it is never recovered either. type UnitHoldOwner = OperatorMaintenance { reason: NonEmptyStr } - | BootRun { run_id: NonEmptyStr, process: ProcessIdentity } + | BootRun { run_id: NonEmptyStr, process: ProcessIdentity, pid_namespace: NonEmptyStr } | HostResetReturn { attempt: NonEmptyStr } fn unit_hold_owner_tag(o: UnitHoldOwner) -> String { match o { OperatorMaintenance { reason: _ } => "operator-maintenance:" - BootRun { run_id: _, process: _ } => "mtcollins1-boot:" + BootRun { run_id: _, process: _, pid_namespace: _ } => "mtcollins1-boot:" HostResetReturn { attempt: _ } => "host-reset-return:" } } // THE PROCESS PART OF A BOOT OWNER, rendered after the run id and decoded back here and nowhere else: -// `@boot=,pid=,start=`. +// `@boot=,pid=,start=,pidns=`. data unit_hold_process_marker: String = "@boot=" -fn unit_hold_process_text(p: ProcessIdentity) -> String { - join([unit_hold_process_marker, p.boot_id as String, ",pid=", to_string(p.pid), ",start=", p.start_time as String], "") +fn unit_hold_process_text(p: ProcessIdentity, pid_namespace: NonEmptyStr) -> String { + join([unit_hold_process_marker, p.boot_id as String, ",pid=", to_string(p.pid), ",start=", p.start_time as String, ",pidns=", pid_namespace as String], "") +} + +type UnitHoldHolderProcess { + process: ProcessIdentity + pid_namespace: NonEmptyStr } fn text_at(xs: List, i: Int) -> String { @@ -106,26 +118,28 @@ fn text_at(xs: List, i: Int) -> String { } } -fn unit_hold_process_decode(text: String) -> ProcessIdentity? { +fn unit_hold_process_decode(text: String) -> UnitHoldHolderProcess? { let parts = split(s: text, delimiter: ",") - if count(parts) != 3 { + if count(parts) != 4 { none } else { let b = text_at(xs: parts, i: 0) let pid_text = text_at(xs: parts, i: 1) let start_text = text_at(xs: parts, i: 2) - if !starts_with(s: b, prefix: "boot=") || !starts_with(s: pid_text, prefix: "pid=") || !starts_with(s: start_text, prefix: "start=") { + let ns_text = text_at(xs: parts, i: 3) + if !starts_with(s: b, prefix: "boot=") || !starts_with(s: pid_text, prefix: "pid=") || !starts_with(s: start_text, prefix: "start=") || !starts_with(s: ns_text, prefix: "pidns=") { none } else { let boot = substring(s: b, start: 5, end: string_length(b)) let start = substring(s: start_text, start: 6, end: string_length(start_text)) + let ns = substring(s: ns_text, start: 6, end: string_length(ns_text)) match parse_int(s: substring(s: pid_text, start: 4, end: string_length(pid_text))) { Absent => none Present { value: n } => match checked_int_to_nat(n: n) { Absent => none Present { value: pid } => - if boot == "" || start == "" { none } else { Present { value: ProcessIdentity { boot_id: boot as NonEmptyStr, pid: pid, start_time: start as NonEmptyStr } } } + if boot == "" || start == "" || ns == "" { none } else { Present { value: UnitHoldHolderProcess { process: ProcessIdentity { boot_id: boot as NonEmptyStr, pid: pid, start_time: start as NonEmptyStr }, pid_namespace: ns as NonEmptyStr } } } } } } @@ -135,7 +149,7 @@ fn unit_hold_process_decode(text: String) -> ProcessIdentity? { fn unit_hold_owner_detail(o: UnitHoldOwner) -> String { match o { OperatorMaintenance { reason: r } => r as String - BootRun { run_id: r, process: p } => concat(r as String, unit_hold_process_text(p: p)) + BootRun { run_id: r, process: p, pid_namespace: n } => concat(r as String, unit_hold_process_text(p: p, pid_namespace: n)) HostResetReturn { attempt: a } => a as String } } @@ -147,7 +161,7 @@ fn unit_hold_owner_ref(o: UnitHoldOwner) -> DurableHoldOwnerRef { fn unit_hold_owner_label(o: UnitHoldOwner) -> String { match o { OperatorMaintenance { reason: r } => concat("operator maintenance: ", r as String) - BootRun { run_id: r, process: p } => join(["the mtcollins1 boot run ", r as String, " (process ", to_string(p.pid), " on boot ", p.boot_id as String, ")"], "") + BootRun { run_id: r, process: p, pid_namespace: _ } => join(["the mtcollins1 boot run ", r as String, " (process ", to_string(p.pid), " on boot ", p.boot_id as String, ")"], "") HostResetReturn { attempt: a } => concat("host reset-return attempt ", a as String) } } @@ -166,7 +180,7 @@ fn unit_hold_owner_detail_after(raw: String, tag: String) -> NonEmptyStr? { fn decode_unit_hold_owner(owner: DurableHoldOwnerRef) -> UnitHoldOwnerDecode { let raw = owner as String let op = unit_hold_owner_tag(o: OperatorMaintenance { reason: "x" as NonEmptyStr }) - let boot = unit_hold_owner_tag(o: BootRun { run_id: "x" as NonEmptyStr, process: ProcessIdentity { boot_id: "x" as NonEmptyStr, pid: 1, start_time: "x" as NonEmptyStr } }) + let boot = unit_hold_owner_tag(o: BootRun { run_id: "x" as NonEmptyStr, process: ProcessIdentity { boot_id: "x" as NonEmptyStr, pid: 1, start_time: "x" as NonEmptyStr }, pid_namespace: "x" as NonEmptyStr }) let reset = unit_hold_owner_tag(o: HostResetReturn { attempt: "x" as NonEmptyStr }) if starts_with(s: raw, prefix: op) { match unit_hold_owner_detail_after(raw: raw, tag: op) { Present { value: d } => UnitHoldOwnerDecoded { owner: OperatorMaintenance { reason: d } } Absent => UnitHoldOwnerUnrecognized { raw: raw } } @@ -179,7 +193,7 @@ fn decode_unit_hold_owner(owner: DurableHoldOwnerRef) -> UnitHoldOwnerDecode { UnitHoldOwnerUnrecognized { raw: raw } } else { match unit_hold_process_decode(text: concat("boot=", text_at(xs: halves, i: 1))) { - Present { value: p } => UnitHoldOwnerDecoded { owner: BootRun { run_id: text_at(xs: halves, i: 0) as NonEmptyStr, process: p } } + Present { value: h } => UnitHoldOwnerDecoded { owner: BootRun { run_id: text_at(xs: halves, i: 0) as NonEmptyStr, process: h.process, pid_namespace: h.pid_namespace } } Absent => UnitHoldOwnerUnrecognized { raw: raw } } } @@ -203,8 +217,8 @@ fn operator_maintenance_owner(reason: NonEmptyStr) -> DurableHoldOwnerRef { unit_hold_owner_ref(o: OperatorMaintenance { reason: reason }) } -fn boot_run_owner(run_id: NonEmptyStr, process: ProcessIdentity) -> DurableHoldOwnerRef { - unit_hold_owner_ref(o: BootRun { run_id: run_id, process: process }) +fn boot_run_owner(run_id: NonEmptyStr, process: ProcessIdentity, pid_namespace: NonEmptyStr) -> DurableHoldOwnerRef { + unit_hold_owner_ref(o: BootRun { run_id: run_id, process: process, pid_namespace: pid_namespace }) } // ── THE PROOF: MINTED ONLY INSIDE THE LIVE ACQUIRE'S FileHoldAcquired ARM ────────────────────── @@ -260,6 +274,25 @@ data proc_boot_id_path: String = "/proc/sys/kernel/random/boot_id" data proc_self_stat_path: String = "/proc/self/stat" +// THE READER'S PID NAMESPACE (namespaces(7), pid_namespaces(7)): /proc/self/ns/pid is a symbolic link +// whose target, `pid:[]`, identifies the namespace; two processes share a pid namespace exactly +// when the targets are equal. It is read with readlink(1), because the link is not a readable file. +data proc_self_pid_namespace_path: String = "/proc/self/ns/pid" + +type PidNamespaceReading + = PidNamespaceRead { namespace: NonEmptyStr } + | PidNamespaceUnread { cause: NonEmptyStr } + +fn own_pid_namespace() -> PidNamespaceReading { + match run_shell_command_capture(command: readlink_command(path: proc_self_pid_namespace_path), transport: LocalExec) { + ProcessOutputPresent { text: t } => + if trim(s: t) == "" { PidNamespaceUnread { cause: "readlink /proc/self/ns/pid printed nothing" as NonEmptyStr } } + else { PidNamespaceRead { namespace: trim(s: t) as NonEmptyStr } } + ProcessOutputAbsent => PidNamespaceUnread { cause: "readlink /proc/self/ns/pid printed nothing" as NonEmptyStr } + ProcessRefused { exit_code: c, stderr: e } => PidNamespaceUnread { cause: join(["readlink /proc/self/ns/pid exited ", to_string(c), ": ", e], "") as NonEmptyStr } + } +} + fn exact_read_of(path: String) -> FilesystemExactRead { let read = Filesystem.Read(path: path) filesystem_exact_read(path: path, content: read.content, success: read.success, error: read.error, error_kind: read.error_kind) @@ -286,7 +319,21 @@ fn start_time_text(stat: String) -> String? { } } -fn holder_process_liveness(p: ProcessIdentity) -> DurableHoldHolderLiveness { +// THE NAMESPACE GATE COMES FIRST: only a reader in the holder's own pid namespace can conclude +// anything from a pid, so a reader elsewhere -- or one that cannot name its namespace -- cannot look. +fn holder_process_liveness(p: ProcessIdentity, pid_namespace: NonEmptyStr) -> DurableHoldHolderLiveness { + match own_pid_namespace() { + PidNamespaceUnread { cause: c } => HolderLivenessUnobservable { cause: c } + PidNamespaceRead { namespace: mine } => + if (mine as String) != (pid_namespace as String) { + HolderLivenessUnobservable { cause: join(["the holder's pid namespace is ", pid_namespace as String, " and this reader's is ", mine as String, "; its pid cannot be looked up from here"], "") as NonEmptyStr } + } else { + holder_process_liveness_in_namespace(p: p) + } + } +} + +fn holder_process_liveness_in_namespace(p: ProcessIdentity) -> DurableHoldHolderLiveness { match exact_text(path: proc_boot_id_path) { ExactTextAbsent => HolderLivenessUnobservable { cause: concat(proc_boot_id_path, " is absent on this host") as NonEmptyStr } ExactTextUnread { cause: c } => HolderLivenessUnobservable { cause: c } @@ -321,7 +368,7 @@ fn holder_process_liveness(p: ProcessIdentity) -> DurableHoldHolderLiveness { // boot id, and pid and starttime from ONE read of /proc/self/stat. A boot that cannot name itself does // not take the unit -- a hold it could never be shown dead in is the lockout this replaces. type SelfProcessIdentity - = SelfIdentified { process: ProcessIdentity } + = SelfIdentified { process: ProcessIdentity, pid_namespace: NonEmptyStr } | SelfUnidentified { cause: NonEmptyStr } fn self_process_identity() -> SelfProcessIdentity { @@ -344,7 +391,12 @@ fn self_process_identity() -> SelfProcessIdentity { Absent => SelfUnidentified { cause: "/proc/self/stat pid is not a natural number" as NonEmptyStr } Present { value: pid } => if boot == "" { SelfUnidentified { cause: concat(proc_boot_id_path, " was empty") as NonEmptyStr } } - else { SelfIdentified { process: ProcessIdentity { boot_id: boot as NonEmptyStr, pid: pid, start_time: st as NonEmptyStr } } } + else { + match own_pid_namespace() { + PidNamespaceUnread { cause: c } => SelfUnidentified { cause: c } + PidNamespaceRead { namespace: n } => SelfIdentified { process: ProcessIdentity { boot_id: boot as NonEmptyStr, pid: pid, start_time: st as NonEmptyStr }, pid_namespace: n } + } + } } } } @@ -360,7 +412,7 @@ fn self_process_identity() -> SelfProcessIdentity { // in between is not the one freed. Age is never an input. fn holder_report(holder: DurableHoldOwnerRef, generation: CasGeneration) -> DurableHoldHolderReport { let liveness = match decode_unit_hold_owner(owner: holder) { - UnitHoldOwnerDecoded { owner: BootRun { run_id: _, process: p } } => holder_process_liveness(p: p) + UnitHoldOwnerDecoded { owner: BootRun { run_id: _, process: p, pid_namespace: n } } => holder_process_liveness(p: p, pid_namespace: n) UnitHoldOwnerDecoded { owner: OperatorMaintenance { reason: _ } } => HolderLivenessUnobservable { cause: "an operator maintenance hold is not bound to a process; only the operator releases it" as NonEmptyStr } UnitHoldOwnerDecoded { owner: HostResetReturn { attempt: _ } } => @@ -460,8 +512,8 @@ fn mtcollins1_boot_acquire_unit_hold(run_id: NonEmptyStr) -> UnitHoldAcquisition match self_process_identity() { SelfUnidentified { cause: c } => UnitHoldRefused { reason: join(["this boot cannot name its own process (", c as String, "), and a hold it could never be shown dead in would lock the unit out if it died; controller untouched"], "") as NonEmptyStr } - SelfIdentified { process: p } => - unit_hold_acquire(root: unit_hold_store_root, key: mtcollins1_unit_hold_key, owner: boot_run_owner(run_id: run_id, process: p)) + SelfIdentified { process: p, pid_namespace: n } => + unit_hold_acquire(root: unit_hold_store_root, key: mtcollins1_unit_hold_key, owner: boot_run_owner(run_id: run_id, process: p, pid_namespace: n)) } } @@ -535,8 +587,8 @@ fn mtcollins1_maintenance_hold_release() -> ProcessExit { match decode_unit_hold_owner(owner: o) { UnitHoldOwnerUnrecognized { raw: r } => exit_failure(reason: concat("mtcollins1 maintenance hold: held by an owner this module did not write, so it is not released from here: ", r)) - UnitHoldOwnerDecoded { owner: BootRun { run_id: r, process: p } } => - exit_failure(reason: concat("mtcollins1 maintenance hold: held by ", concat(unit_hold_owner_label(o: BootRun { run_id: r, process: p }), ", not by maintenance; that run frees its own hold, and the next boot recovers it if that run is observed dead"))) + UnitHoldOwnerDecoded { owner: BootRun { run_id: r, process: p, pid_namespace: n } } => + exit_failure(reason: concat("mtcollins1 maintenance hold: held by ", concat(unit_hold_owner_label(o: BootRun { run_id: r, process: p, pid_namespace: n }), ", not by maintenance; that run frees its own hold, and the next boot recovers it if that run is observed dead"))) UnitHoldOwnerDecoded { owner: HostResetReturn { attempt: a } } => exit_failure(reason: concat("mtcollins1 maintenance hold: held by ", concat(unit_hold_owner_label(o: HostResetReturn { attempt: a }), ", not by maintenance; that run frees its own hold"))) UnitHoldOwnerDecoded { owner: OperatorMaintenance { reason: _ } } => diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index fe571d15a1e..28898b519b7 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -123,6 +123,7 @@ fn healthy_media() -> MegaRacMediaWorld { // The worker host's boot, and the boot worker's own process (pid, start tick) as procfs shows it. data worker_boot_id: String = "73c8153e-0e0e-4480-a36c-bc7560c50e8b" +data worker_pid_namespace: String = "pid:[4026531836]" data first_worker_pid: Int = 3100 data first_worker_start: Int = 5000 @@ -133,7 +134,7 @@ fn worker_filesystem() -> ModeledFilesystem { files: [ModeledFile { path: credential_path, content: "secret" }], refused_reads: [], }, - boot_id: worker_boot_id, pid: first_worker_pid, start_ticks: first_worker_start, + boot_id: worker_boot_id, pid_namespace: worker_pid_namespace, pid: first_worker_pid, start_ticks: first_worker_start, ) } @@ -281,7 +282,7 @@ test fn a_second_run_for_a_held_unit_writes_nothing_to_the_controller() -> Bool let other_running = with_fs(w: base, fs: fs_with_file(fs: base.fs, path: proc_stat_path(pid: 2900), content: proc_stat_line(pid: 2900, start_ticks: 100))) let prior = evaluate_in_witness_frame( frame: matrix_frame(world: other_running), - subject: fn(_scope) { file_hold_acquire(root: unit_hold_store_root, slot_key: mtcollins1_unit_hold_key, requested_owner: boot_run_owner(run_id: "4141" as NonEmptyStr, process: ProcessIdentity { boot_id: worker_boot_id as NonEmptyStr, pid: 2900, start_time: "100" as NonEmptyStr })) } + subject: fn(_scope) { file_hold_acquire(root: unit_hold_store_root, slot_key: mtcollins1_unit_hold_key, requested_owner: boot_run_owner(run_id: "4141" as NonEmptyStr, process: ProcessIdentity { boot_id: worker_boot_id as NonEmptyStr, pid: 2900, start_time: "100" as NonEmptyStr }, pid_namespace: worker_pid_namespace as NonEmptyStr)) } ) match prior { WitnessReturned { state } => match state { @@ -500,8 +501,12 @@ fn stopped_after_start_media(realization: OperationRealization MtCollins1BootWorld { + as_another_run_in(w: w, run_id: run_id, pid_namespace: worker_pid_namespace) +} + +fn as_another_run_in(w: MtCollins1BootWorld, run_id: String, pid_namespace: String) -> MtCollins1BootWorld { let env = map(w.environment, v => if v.name == "GITHUB_RUN_ID" { ModeledVariable { name: v.name, value: run_id } } else { v }) - let fs = worker_process_started(fs: w.fs, boot_id: worker_boot_id, pid: first_worker_pid + 1, start_ticks: first_worker_start + 9000) + let fs = worker_process_started(fs: w.fs, boot_id: worker_boot_id, pid_namespace: pid_namespace, pid: first_worker_pid + 1, start_ticks: first_worker_start + 9000) MtCollins1BootWorld { bmc: w.bmc, fs: fs, environment: env, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: w.media } } @@ -512,9 +517,13 @@ fn as_another_run(w: MtCollins1BootWorld, run_id: String) -> MtCollins1BootWorld // The two controls beside it differ only in what procfs says of the holder: still running, and a stat // read the host refuses. Neither is ever recovered, and neither writes to the controller. fn resumed_after(realization: OperationRealization, refuse_holder_stat: Bool) -> WitnessEvaluation? { + resumed_in(realization: realization, refuse_holder_stat: refuse_holder_stat, pid_namespace: worker_pid_namespace) +} + +fn resumed_in(realization: OperationRealization, refuse_holder_stat: Bool, pid_namespace: String) -> WitnessEvaluation? { match evaluate_in_witness_frame(frame: matrix_frame_over(realization: realization), subject: fn(_scope) { mtcollins1_boot_wet_on_srv1() }) { WitnessInterrupted { at, state, now: interrupted_clock } => { - let another = as_another_run(w: state, run_id: "4243") + let another = as_another_run_in(w: state, run_id: "4243", pid_namespace: pid_namespace) let next = if refuse_holder_stat { with_fs(w: another, fs: fs_refusing_reads_of(fs: another.fs, path: proc_stat_path(pid: first_worker_pid))) } else { another } if at.invocation.at.operation != "StartMedia" { none } else { Present { value: evaluate_in_witness_frame( @@ -557,3 +566,16 @@ test fn an_unobservable_holder_is_refused_not_recovered() -> Bool { _ => false } } + +// A SUCCESSOR IN ANOTHER PID NAMESPACE CANNOT LOOK (review 72326). The holder is dead and its +// /proc entry gone, exactly as in the recovery case above; the only difference is that the next run +// reads a different /proc/self/ns/pid. From there a missing pid proves nothing, so the hold is +// refused, never recovered, and nothing is written. The red is recovery across namespaces. +test fn a_successor_in_another_pid_namespace_refuses_rather_than_recovering() -> Bool { + match resumed_in(realization: killed_after_start_media(realization: fresh_realization()), refuse_holder_stat: false, pid_namespace: "pid:[4026532999]") { + Present { value: WitnessReturned { value, route } } => + string_contains(s: outcome_reason(a: value), pattern: "its pid cannot be looked up from here") + && count(filter(route, r => is_controller_write(r: r))) == 0 + _ => false + } +} diff --git a/dag/test/claim/machine_intake/mtcollins1_maintenance_hold_witness_test.dag b/dag/test/claim/machine_intake/mtcollins1_maintenance_hold_witness_test.dag index b28d952e40e..3144de4c820 100644 --- a/dag/test/claim/machine_intake/mtcollins1_maintenance_hold_witness_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_maintenance_hold_witness_test.dag @@ -58,12 +58,12 @@ test fn the_boot_refuses_under_an_active_maintenance_hold_and_names_the_holder() generation: first_generation(), } refused_naming(r: unit_hold_refusal(outcome: held), pattern: "operator-maintenance:reseating DIMMs") - && not_refused(r: unit_hold_refusal(outcome: FileHoldAcquired { slot_key: mtcollins1_unit_hold_key, owner: boot_run_owner(run_id: "42", process: holder_process), generation: first_generation() })) + && not_refused(r: unit_hold_refusal(outcome: FileHoldAcquired { slot_key: mtcollins1_unit_hold_key, owner: boot_run_owner(run_id: "42", process: holder_process, pid_namespace: "pid:[4026531836]"), generation: first_generation() })) } // ANOTHER HOLDER IS A HOLDER: a running boot, or a host reset-return, excludes the next writer. test fn a_second_writer_refuses_while_another_run_holds_the_unit() -> Bool { - refused_naming(r: unit_hold_refusal(outcome: FileHoldOccupied { slot_key: mtcollins1_unit_hold_key, holder: boot_run_owner(run_id: "41", process: holder_process), generation: first_generation() }), pattern: "mtcollins1-boot:41") + refused_naming(r: unit_hold_refusal(outcome: FileHoldOccupied { slot_key: mtcollins1_unit_hold_key, holder: boot_run_owner(run_id: "41", process: holder_process, pid_namespace: "pid:[4026531836]"), generation: first_generation() }), pattern: "mtcollins1-boot:41") && refused_naming(r: unit_hold_refusal(outcome: FileHoldOccupied { slot_key: mtcollins1_unit_hold_key, holder: host_reset_owner(attempt: "srv1-mtcollins1"), generation: first_generation() }), pattern: "host-reset-return:srv1-mtcollins1") } @@ -141,7 +141,7 @@ fn round_trips(o: UnitHoldOwner, label: String) -> Bool { test fn every_holder_kind_round_trips_and_a_foreign_owner_is_refused() -> Bool { round_trips(o: OperatorMaintenance { reason: "reseating DIMMs" as NonEmptyStr }, label: "operator maintenance: reseating DIMMs") - && round_trips(o: BootRun { run_id: "41" as NonEmptyStr, process: holder_process }, label: "the mtcollins1 boot run 41 (process 3975 on boot 73c8153e-0e0e-4480-a36c-bc7560c50e8b)") + && round_trips(o: BootRun { run_id: "41" as NonEmptyStr, process: holder_process, pid_namespace: "pid:[4026531836]" as NonEmptyStr }, label: "the mtcollins1 boot run 41 (process 3975 on boot 73c8153e-0e0e-4480-a36c-bc7560c50e8b)") && round_trips(o: HostResetReturn { attempt: "srv1-mtcollins1" as NonEmptyStr }, label: "host reset-return attempt srv1-mtcollins1") && match decode_unit_hold_owner(owner: "someone-else:x" as DurableHoldOwnerRef) { UnitHoldOwnerUnrecognized { raw: _ } => true @@ -157,19 +157,20 @@ test fn every_holder_kind_round_trips_and_a_foreign_owner_is_refused() -> Bool { // carries boot id, pid and start time, and decodes to the same identity -- the identity a successor // observes the holder by. A boot owner written WITHOUT a process (the spelling before this change, // still possibly on disk) is not guessed into one: it decodes as unrecognized, so its holder is -// unobservable and its hold is refused rather than broken. +// unobservable and its hold is refused rather than broken. So is one naming a process but not the +// pid namespace it was read in (review 72326): its pid has no meaning without it. test fn a_boot_owner_carries_its_process_and_a_processless_one_is_not_recoverable() -> Bool { - let rendered = boot_run_owner(run_id: "4242", process: holder_process) as String - rendered == "mtcollins1-boot:4242@boot=73c8153e-0e0e-4480-a36c-bc7560c50e8b,pid=3975,start=81234" + let rendered = boot_run_owner(run_id: "4242", process: holder_process, pid_namespace: "pid:[4026531836]") as String + rendered == "mtcollins1-boot:4242@boot=73c8153e-0e0e-4480-a36c-bc7560c50e8b,pid=3975,start=81234,pidns=pid:[4026531836]" && (match decode_unit_hold_owner(owner: rendered as DurableHoldOwnerRef) { - UnitHoldOwnerDecoded { owner: BootRun { run_id: r, process: p } } => (r as String) == "4242" && p.pid == 3975 && (p.start_time as String) == "81234" + UnitHoldOwnerDecoded { owner: BootRun { run_id: r, process: p, pid_namespace: n } } => (n as String) == "pid:[4026531836]" && (r as String) == "4242" && p.pid == 3975 && (p.start_time as String) == "81234" _ => false }) && (match decode_unit_hold_owner(owner: "mtcollins1-boot:4242" as DurableHoldOwnerRef) { UnitHoldOwnerUnrecognized { raw: _ } => true _ => false }) - && (match decode_unit_hold_owner(owner: "mtcollins1-boot:4242@boot=x,pid=-1,start=5" as DurableHoldOwnerRef) { + && (match decode_unit_hold_owner(owner: "mtcollins1-boot:4242@boot=x,pid=3975,start=5" as DurableHoldOwnerRef) { UnitHoldOwnerUnrecognized { raw: _ } => true _ => false }) diff --git a/dag/test/claim/modeled_filesystem_witness_test.dag b/dag/test/claim/modeled_filesystem_witness_test.dag index ca802309a74..00b77c6366f 100644 --- a/dag/test/claim/modeled_filesystem_witness_test.dag +++ b/dag/test/claim/modeled_filesystem_witness_test.dag @@ -98,8 +98,8 @@ fn occupied_by(o: gunbc.durable_exclusive_hold_file_store.FileHoldAcquireOutcome // is the production fold's reading of what the model's filesystem holds, and the route shows the // second contender never wrote. test fn two_contenders_for_one_unit_get_one_hold() -> Bool { - let first_owner = boot_run_owner(run_id: "run-a" as NonEmptyStr, process: ProcessIdentity { boot_id: "b" as NonEmptyStr, pid: 10, start_time: "1" as NonEmptyStr }) - let second_owner = boot_run_owner(run_id: "run-b" as NonEmptyStr, process: ProcessIdentity { boot_id: "b" as NonEmptyStr, pid: 11, start_time: "2" as NonEmptyStr }) + let first_owner = boot_run_owner(run_id: "run-a" as NonEmptyStr, process: ProcessIdentity { boot_id: "b" as NonEmptyStr, pid: 10, start_time: "1" as NonEmptyStr }, pid_namespace: "pid:[1]" as NonEmptyStr) + let second_owner = boot_run_owner(run_id: "run-b" as NonEmptyStr, process: ProcessIdentity { boot_id: "b" as NonEmptyStr, pid: 11, start_time: "2" as NonEmptyStr }, pid_namespace: "pid:[1]" as NonEmptyStr) let result = evaluate_in_witness_frame( frame: filesystem_frame(initial: empty_hold_store()), subject: fn(_scope) { From b4cc96d3da8bd3797676a1ca22fc14613c9a9b57 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Mon, 28 Sep 2026 20:45:17 +0000 Subject: [PATCH 29/75] Hold witness takes its report generation from an observation; the recovery cases (and the duplicate-listing case, now over by procfs reads) join the boot-matrix cost-drop roster, measured by floor run 36474912729 Co-Authored-By: Claude Opus 5.5 (1M context) --- ...boot_matrix_new_witness_eval_step_cost.dag | 4 ++-- .../durable_exclusive_hold_witness_test.dag | 13 ++++++++++-- docs/design-rung-drops.md | 4 ++-- src/v2/workflow/floor_eval_step_cost_drop.dag | 20 +++++++++++++++++++ 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag index 9a841cf09e1..2a5adbda1ec 100644 --- a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag +++ b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag @@ -28,7 +28,7 @@ data mtcollins1_boot_matrix_new_witness_eval_step_cost_population: List data mtcollins1_boot_matrix_new_witness_eval_step_cost: RungDrop = RungDrop { identity: "mtcollins1_boot_matrix_new_witness_eval_step_cost" as NonEmptyStr, - subject: "new-witness eval-step cost gate over the eight mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered", + subject: "new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered", declared: "2026-09-28", @@ -41,6 +41,6 @@ data mtcollins1_boot_matrix_new_witness_eval_step_cost: RungDrop = RungDrop { replacement: "the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter", }, population: mtcollins1_boot_matrix_new_witness_eval_step_cost_population, - restoration_trigger: "THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these eight identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither.", + restoration_trigger: "THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither.", } } diff --git a/dag/test/claim/durable_exclusive_hold_witness_test.dag b/dag/test/claim/durable_exclusive_hold_witness_test.dag index 8d696eaa972..49c7118e0ee 100644 --- a/dag/test/claim/durable_exclusive_hold_witness_test.dag +++ b/dag/test/claim/durable_exclusive_hold_witness_test.dag @@ -7,7 +7,7 @@ import std.durable_compare_and_set { CasExpectation, ExpectSlotAbsent, ExpectSlotGeneration, CasSlotObservation, CasObservedReadable, CasObservedUnreadable, CasReadableAbsent, CasReadablePresent, CasSlotVersion, - CasUnreadableReadRefused, cas_generation_count, CasGeneration, + CasUnreadableReadRefused, cas_generation_count, CasGeneration, cas_generation_first, } import std.durable_exclusive_hold { DurableHoldOwnerRef, DurableHoldReleaseRef, @@ -315,10 +315,19 @@ test fn holder_equality_is_exact() -> Bool { // ONLY in the liveness verdict: a live holder blocks, an observed-dead holder is recovered at the // generation both the read and the report name, and an unobservable holder refuses -- never // recovered. There is no age input to vary: the assessment takes none. +// The report's generation is taken from an observation, the only place a CasGeneration comes from. +fn eh_generation_of(o: DurableHoldObservation) -> CasGeneration { + match o { + HoldSlotHeld { generation: g, owner: _ } => g + HoldSlotFree { generation: g, released_by: _ } => g + _ => cas_generation_first() + } +} + fn eh_report(holder: String, generation: Int, dead: Int) -> DurableHoldHolderReport { DurableHoldHolderReport { holder: eh_owner(text: holder), - generation: generation as CasGeneration, + generation: eh_generation_of(o: eh_held_at(owner: holder, generation: generation)), liveness: if dead == 0 { HolderObservedLive { evidence: "process 7 started at tick 90 still runs" } } else if dead == 1 { HolderObservedDead { evidence: "no process 7 on the holder's boot" } } else { HolderLivenessUnobservable { cause: "/proc/7/stat could not be read" } }, diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index e5c2079977c..fefb39666d8 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -338,9 +338,9 @@ new-witness eval-step cost gate over the one roadmap page claim that derives the new-witness eval-step cost gate over the ten interpreted P-256 and P-384 point and group-law checks and SHA-384 FIPS vectors of the App Attest path: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the P-384 and SHA-384 primitives executing as natively emitted code rather than as interpreted bignat and Word64 folds). Population: test.claim.p384_dag_ecdsa_witness_test.the_p384_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_beside_the_base_point_is_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_with_a_coordinate_at_p_is_not_admitted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.apples_ca_and_root_keys_are_on_p384: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.sha384_fips_witness_test.sha384_of_the_empty_message_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published empty message and a one-octet message on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_abc_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published abc vector and abd on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_the_896_bit_message_is_the_published_two_block_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is four SHA-384 block compressions, the published 896-bit two-block vector and a last-block mutation on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.p256_dag_ecdsa_witness_test.the_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35708011844 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, well inside the wall deadline and over the new-witness eval-step budget. The billed work is one P-256 curve equation over the published base point as 11-limb bignat folds on an interpreter that reifies no machine width. It is a MEMBER BECAUSE IT WAS SPLIT OUT of a claim that also asserted n*G = infinity: that conjunction crossed the 8000ms wall deadline and was INTERRUPTED BEFORE ANY VERDICT, so both facts were being lost; the scalar multiplication left the floor for the native row the frontier names, and this cheap half now reaches a verdict. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field, test.claim.p384_dag_ecdsa_witness_test.doubling_and_adding_the_base_point_stay_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling, one addition and two projective curve-equation checks at 16 limbs, test.claim.p384_dag_ecdsa_witness_test.doubling_an_off_curve_point_stays_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling and one projective curve-equation check at 16 limbs. Restored when: THE CAPABILITY: gunbc test //gunbc/instruments:native-crypto-vectors EXECUTING ON THE MERGE PATH, i.e. as a phase of a required lane whose red blocks a merge, running these ten identities natively (its cases p256_the_base_point_is_on_the_curve, p384_the_base_point_is_on_the_curve, p384_red_a_point_beside_the_base_point_is_off_the_curve, p384_red_a_point_with_a_coordinate_at_p_is_not_admitted, p384_doubling_and_adding_the_base_point_stay_on_the_curve, p384_red_doubling_an_off_curve_point_stays_off_the_curve, p384_apples_ca_and_root_keys_are_on_the_curve and the sha384_* FIPS cases with their reds) while each still evaluates the real curve equation or the real hash; WHAT THAT MUST BE SUFFICIENT FOR: the P-384 parameters and SHA-384 are exercised on the acceptance path with no interpreted 16-limb fold inside a claim frame, so the interpreted identities can leave the floor for that row, or they measure under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives. The same row run BY NAME (as it exists since gunbc#12306) executes the facts natively but is NOT the acceptance path and retires nothing. Supplying the curve check's answer or the digest as a fixture, or deleting the identities, satisfies neither. -### new-witness eval-step cost gate over the eight mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 +### new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 -new-witness eval-step cost gate over the eight mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_healthy_census_is_refused_at_the_sol_teardown: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these eight identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. +new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_healthy_census_is_refused_at_the_sol_teardown: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36474912729 of gunbc#12555, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, the interrupted-attempt cases twice (the killed run, then the next run over the world it left), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_live_holder_still_blocks_the_next_attempt: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36474912729 of gunbc#12555, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, the interrupted-attempt cases twice (the killed run, then the next run over the world it left), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unobservable_holder_is_refused_not_recovered: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36474912729 of gunbc#12555, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, the interrupted-attempt cases twice (the killed run, then the next run over the world it left), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_successor_in_another_pid_namespace_refuses_rather_than_recovering: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36474912729 of gunbc#12555, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, the interrupted-attempt cases twice (the killed run, then the next run over the world it left), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36474912729 of gunbc#12555, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, the interrupted-attempt cases twice (the killed run, then the next run over the world it left). Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. ### new-witness eval-step cost gate over six App Attest verifier claims -- the two real-path inhabitance claims over Apple's objects, three single structural steps priced by their own SHA-256s, and the wire-carrier join: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 diff --git a/src/v2/workflow/floor_eval_step_cost_drop.dag b/src/v2/workflow/floor_eval_step_cost_drop.dag index e9e32abcabd..bdca35cb223 100644 --- a/src/v2/workflow/floor_eval_step_cost_drop.dag +++ b/src/v2/workflow/floor_eval_step_cost_drop.dag @@ -273,6 +273,26 @@ data floor_eval_step_cost_drop_boot_matrix_rows: List List { From 1720c6571a04f7c99f6fde879446f7b17baaedb1 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Mon, 28 Sep 2026 20:58:26 +0000 Subject: [PATCH 30/75] Matrix: the held-unit case matches the owner's run id followed by its process identity, and asserts the holder was observed alive Co-Authored-By: Claude Opus 5.5 (1M context) --- .../machine_intake/mtcollins1_boot_acceptance_matrix_test.dag | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index 28898b519b7..3eee8025bcf 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -289,7 +289,8 @@ test fn a_second_run_for_a_held_unit_writes_nothing_to_the_controller() -> Bool Absent => false Present { value: held } => match run_attempt(world: held) { WitnessReturned { value, route } => - string_contains(s: outcome_reason(a: value), pattern: "is held by 'mtcollins1-boot:4141'") + string_contains(s: outcome_reason(a: value), pattern: "is held by 'mtcollins1-boot:4141@") + && string_contains(s: outcome_reason(a: value), pattern: "which is alive") && count(filter(route, r => is_controller_write(r: r))) == 0 && count_named(route: route, name: "gunbc.machine_intake.sol_hold.ActivateHeld") == 0 _ => false From 72b84eb155a5e44ea0688b3265bf8170ce188538 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Tue, 29 Sep 2026 03:07:44 +0000 Subject: [PATCH 31/75] Regenerate the std.measure stage0 mirror for SecondDisplacement Co-Authored-By: Claude Opus 5.5 (1M context) --- src/v1/stage0/src/std_measure.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/v1/stage0/src/std_measure.rs b/src/v1/stage0/src/std_measure.rs index d11b18a5588..36e02a18888 100644 --- a/src/v1/stage0/src/std_measure.rs +++ b/src/v1/stage0/src/std_measure.rs @@ -1645,6 +1645,19 @@ pub fn second_count(s: Second) -> Nat { measure_count(s.clone()) } +pub type SecondDisplacement = Rc>; + +pub fn second_displacement(count: i64) -> SecondDisplacement { + Rc::new(Measure { + count: count.clone(), + _phantom: std::marker::PhantomData, + }) +} + +pub fn second_displacement_count(d: SecondDisplacement) -> i64 { + measure_count(d.clone()) +} + pub fn energy_from_power_and_time(power: Watt, time: Second) -> Joule { joule(v1_rt::int_mul( watt_count(power.clone()), From b12eb7c4511060c9d011c8689beb84dde6ce7e1c Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Tue, 29 Sep 2026 04:22:04 +0000 Subject: [PATCH 32/75] Cost-drop rationale matches its rows: the five #12555 members and why each exceeds the budget (review 72465) Co-Authored-By: Claude Opus 5.5 (1M context) --- ...ins1_boot_matrix_new_witness_eval_step_cost.dag | 3 ++- src/v2/workflow/floor_eval_step_cost_drop.dag | 14 +++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag index 2a5adbda1ec..ac915b2f6ec 100644 --- a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag +++ b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag @@ -9,7 +9,8 @@ import v2.workflow.floor_eval_step_cost_drop { floor_eval_step_cost_drop_boot_ma // matrix, msg_83af891b). The DECLARATION lives here; the POPULATION's authority is // `v2.workflow.floor_eval_step_cost_drop` `floor_eval_step_cost_drop_boot_matrix_rows`. // -// WHAT IS LOST IS ONE WALL, AND THE CLAIMS ARE UNTOUCHED. The eight identities are planned, executed +// WHAT IS LOST IS ONE WALL, AND THE CLAIMS ARE UNTOUCHED. The member identities (thirteen: eight from +// gunbc#12533, five from gunbc#12555, enumerated in the population authority above) are planned, executed // and measured on every pull request that edits them; a semantic red and a wall-clock crossing still // block. Only the eval-step overrun is reported as `EvalStepsOverBudgetUnderDeclaredDrop` rather than // refusing. The budget is not raised. Their CPU stays under the enrolment margin, so they enrol diff --git a/src/v2/workflow/floor_eval_step_cost_drop.dag b/src/v2/workflow/floor_eval_step_cost_drop.dag index bdca35cb223..a640b7cd3b1 100644 --- a/src/v2/workflow/floor_eval_step_cost_drop.dag +++ b/src/v2/workflow/floor_eval_step_cost_drop.dag @@ -235,11 +235,15 @@ data floor_eval_step_cost_drop_python_to_typescript_inhabitance_rows: List = [ EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline" as NonEmptyStr, From c39cb247c9f35432e7b99cf07f47a870fed622cf Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Tue, 29 Sep 2026 04:49:36 +0000 Subject: [PATCH 33/75] Duplicate-listing arm in the two listing matches main's #12546 enumerated (enumeration decision: the ambiguity; presence: listed) Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/gunbc/machine_intake/megarac_media_attach.dag | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dag/gunbc/machine_intake/megarac_media_attach.dag b/dag/gunbc/machine_intake/megarac_media_attach.dag index b89e3b134d7..753fc1a1224 100644 --- a/dag/gunbc/machine_intake/megarac_media_attach.dag +++ b/dag/gunbc/machine_intake/megarac_media_attach.dag @@ -1210,6 +1210,7 @@ fn enumeration_decision(standing: RemoteMediaMountStanding, reading: ImagesListi ImagesListingUnparseable { detail: _ } => EnumerationDecided { result: NotEnumeratedAfterRefresh { standing: standing } } ImagesListingEmpty => EnumerationDecided { result: NotEnumeratedAfterRefresh { standing: standing } } ImagesListingLacks => EnumerationDecided { result: NotEnumeratedAfterRefresh { standing: standing } } + ImagesListingOffersAmbiguously { image_indices: ids } => EnumerationDecided { result: EnumerationAmbiguous { image_indices: ids } } } MountRequested { window: _ } => if remaining > 1 { EnumerationLookAgain } else { EnumerationDecided { result: NotEnumeratedAfterRefresh { standing: standing } } } @@ -1250,12 +1251,15 @@ fn images_listing_reading(body: String, image_name: NonEmptyStr) -> ImagesListin } } +// A name offered twice IS listed; the await loop refuses on the ambiguity before any look reaches the +// mount standing, so this arm states presence and decides nothing. fn images_listing_presence(reading: ImagesListingReading) -> RemoteMediaListing { match reading { ImagesListingOffers { image_index: _ } => MediaImageListed ImagesListingUnparseable { detail: _ } => MediaImageAbsentFromListing ImagesListingEmpty => MediaImageAbsentFromListing ImagesListingLacks => MediaImageAbsentFromListing + ImagesListingOffersAmbiguously { image_indices: _ } => MediaImageListed } } From c2ab8ad35f435c3ac05464f634b57f1482c8adea Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Tue, 29 Sep 2026 05:30:18 +0000 Subject: [PATCH 34/75] One Gregorian calendar: extdeps.units.iso8601 owns both directions (review 72483) The wall-clock model re-derived civil-from-days and hard-coded 86400/3600/60 beside extdeps.units.iso8601's own constants, while the roadmap reader carried a private days_from_civil with the same literals. Both directions and the month-length rule now live in extdeps.units.iso8601 over its constants; the reader and the wall-clock model import them. The reader's witness gains a round trip (format then parse), so the two directions cannot drift apart without a red. Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/extdeps/units/iso8601.dag | 73 ++++++++++++++++++- .../roadmap_launch_deployment_observe.dag | 26 ++----- dag/gunbc/wall_clock_model.dag | 44 +---------- .../claim/boot_world_models_witness_test.dag | 13 ++-- ...launch_deployment_observe_witness_test.dag | 1 + 5 files changed, 88 insertions(+), 69 deletions(-) diff --git a/dag/extdeps/units/iso8601.dag b/dag/extdeps/units/iso8601.dag index 7a7fbb29951..75b32a48f9f 100644 --- a/dag/extdeps/units/iso8601.dag +++ b/dag/extdeps/units/iso8601.dag @@ -1,6 +1,6 @@ module extdeps.units.iso8601 -import std.types { String } +import std.types { Int, String } import std.nat { Nat } import extdeps.external_authority { ExternalAuthority } import extdeps.uri { Uri, Https } @@ -26,3 +26,74 @@ fn iso8601_minutes_per_hour() -> Nat { fn iso8601_hours_per_day() -> Nat { 24 } + +fn iso8601_seconds_per_hour() -> Int { + (iso8601_minutes_per_hour() as Int) * (iso8601_seconds_per_minute() as Int) +} + +fn iso8601_seconds_per_day() -> Int { + (iso8601_hours_per_day() as Int) * iso8601_seconds_per_hour() +} + +// THE PROLEPTIC GREGORIAN CALENDAR THE DATE FORMAT SPELLS, in both directions over one day count +// (days since 1970-01-01): H. Hinnant, "chrono-Compatible Low-Level Date Algorithms", +// days_from_civil and civil_from_days -- exact over the whole range, no table. +type Iso8601CivilDate { + year: Int + month: Int + day: Int +} + +fn iso8601_floor_div(a: Int, b: Int) -> Int { + if a >= 0 { a / b } else { 0 - ((0 - a + b - 1) / b) } +} + +fn iso8601_days_from_civil(y: Int, m: Int, d: Int) -> Int { + let yy = if m <= 2 { y - 1 } else { y } + let era = iso8601_floor_div(a: yy, b: 400) + let yoe = yy - era * 400 + let mp = if m > 2 { m - 3 } else { m + 9 } + let doy = (153 * mp + 2) / 5 + d - 1 + let doe = yoe * 365 + yoe / 4 - yoe / 100 + doy + era * 146097 + doe - 719468 +} + +fn iso8601_civil_from_days(days: Int) -> Iso8601CivilDate { + let z = days + 719468 + let era = iso8601_floor_div(a: z, b: 146097) + let doe = z - era * 146097 + let yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365 + let y = yoe + era * 400 + let doy = doe - (365 * yoe + yoe / 4 - yoe / 100) + let mp = (5 * doy + 2) / 153 + let d = doy - (153 * mp + 2) / 5 + 1 + let m = if mp < 10 { mp + 3 } else { mp - 9 } + Iso8601CivilDate { year: if m <= 2 { y + 1 } else { y }, month: m, day: d } +} + +// The day-in-month bound with the leap rule, so a calendar-impossible day (Feb 30, Apr 31) is refused +// by a reader rather than normalized through the day count. +fn iso8601_gregorian_days_in_month(y: Int, m: Int) -> Int { + if m == 2 { + if y - (y / 4) * 4 == 0 && (y - (y / 100) * 100 != 0 || y - (y / 400) * 400 == 0) { 29 } else { 28 } + } else if m == 4 || m == 6 || m == 9 || m == 11 { 30 } else { 31 } +} + +fn iso8601_two_digits(n: Int) -> String { + if n < 10 { concat("0", to_string(n)) } else { to_string(n) } +} + +// Seconds since 1970-01-01T00:00:00Z to the UTC basic-extended form `YYYY-MM-DDThh:mm:ssZ`, the form +// `date -u +%Y-%m-%dT%H:%M:%SZ` prints; the inverse of a reader of that form over the same day count. +fn iso8601_utc_text(unix: Int) -> String { + let days = iso8601_floor_div(a: unix, b: iso8601_seconds_per_day()) + let rem = unix - days * iso8601_seconds_per_day() + let hour = rem / iso8601_seconds_per_hour() + let within_hour = rem - hour * iso8601_seconds_per_hour() + let minute = within_hour / (iso8601_seconds_per_minute() as Int) + let date = iso8601_civil_from_days(days: days) + join([ + to_string(date.year), "-", iso8601_two_digits(n: date.month), "-", iso8601_two_digits(n: date.day), + "T", iso8601_two_digits(n: hour), ":", iso8601_two_digits(n: minute), ":", iso8601_two_digits(n: within_hour - minute * (iso8601_seconds_per_minute() as Int)), "Z", + ], "") +} diff --git a/dag/gunbc/roadmap/roadmap_launch_deployment_observe.dag b/dag/gunbc/roadmap/roadmap_launch_deployment_observe.dag index 894ef87f0fb..868da4c6892 100644 --- a/dag/gunbc/roadmap/roadmap_launch_deployment_observe.dag +++ b/dag/gunbc/roadmap/roadmap_launch_deployment_observe.dag @@ -7,6 +7,7 @@ import gunbc.live_deploy.emit { belt_tick_cadence } import std.types { String, Bool, NonEmptyStr, Int, List } import std.algebra { trim } +import extdeps.units.iso8601 { iso8601_days_from_civil, iso8601_gregorian_days_in_month, iso8601_seconds_per_day, iso8601_seconds_per_hour, iso8601_seconds_per_minute } import extdeps.http.client import extdeps.languages.json.emit { JsonValue, JsonString, JsonBool, serialize_json } import extdeps.languages.json.parse { @@ -266,29 +267,12 @@ fn observe_workflow_document_routed(base_url: String) -> RoadmapWorkflowObservat // ---------------------------------------------------------------- instants // `%Y-%m-%dT%H:%M:%SZ` to seconds since 1970-01-01T00:00:00Z. Days-from-civil is the proleptic // Gregorian algorithm (Howard Hinnant, "chrono-Compatible Low-Level Date Algorithms"), exact for -// every date the format can spell. Anything that is not exactly that shape refuses. +// every date the format can spell; the calendar is extdeps.units.iso8601's, which also formats the +// same instants. Anything that is not exactly that shape refuses. fn two_digits_at(s: String, i: Int) -> Int? { parse_int(s: substring(s: s, start: i, end: i + 2)) } -fn days_from_civil(y: Int, m: Int, d: Int) -> Int { - let yy = if m <= 2 { y - 1 } else { y } - let era = (if yy >= 0 { yy } else { yy - 399 }) / 400 - let yoe = yy - era * 400 - let mp = if m > 2 { m - 3 } else { m + 9 } - let doy = (153 * mp + 2) / 5 + d - 1 - let doe = yoe * 365 + yoe / 4 - yoe / 100 + doy - era * 146097 + doe - 719468 -} - -// systemd-independent Gregorian day-in-month bound with the leap rule; a calendar-impossible day -// (Feb 30, Apr 31) must refuse rather than normalize silently through days_from_civil (review 57773). -fn gregorian_days_in_month(y: Int, m: Int) -> Int { - if m == 2 { - if y - (y / 4) * 4 == 0 && (y - (y / 100) * 100 != 0 || y - (y / 400) * 400 == 0) { 29 } else { 28 } - } else if m == 4 || m == 6 || m == 9 || m == 11 { 30 } else { 31 } -} - fn iso8601_utc_epoch_seconds(text: String) -> Second? { let t = trim(s: text) if string_length(s: t) != 20 { @@ -316,11 +300,11 @@ fn iso8601_utc_epoch_seconds(text: String) -> Second? { match two_digits_at(s: t, i: 17) { Absent => none Present { value: ss } => - if m < 1 || m > 12 || d < 1 || d > gregorian_days_in_month(y: y, m: m) || hh > 23 || mm > 59 || ss > 60 { + if m < 1 || m > 12 || d < 1 || d > iso8601_gregorian_days_in_month(y: y, m: m) || hh > 23 || mm > 59 || ss > 60 { none } else { { - let epoch = days_from_civil(y: y, m: m, d: d) * 86400 + hh * 3600 + mm * 60 + ss + let epoch = iso8601_days_from_civil(y: y, m: m, d: d) * iso8601_seconds_per_day() + hh * iso8601_seconds_per_hour() + mm * (iso8601_seconds_per_minute() as Int) + ss if epoch < 0 { none } else { diff --git a/dag/gunbc/wall_clock_model.dag b/dag/gunbc/wall_clock_model.dag index cec79144ca2..9e0e5033c31 100644 --- a/dag/gunbc/wall_clock_model.dag +++ b/dag/gunbc/wall_clock_model.dag @@ -7,6 +7,7 @@ import v2.std.operation_realization { OperationBinding, OperationCall, OperationStep, OperationObserved, ShellObserved, } import extdeps.transports.shell { ShellProcessExited } +import extdeps.units.iso8601 { iso8601_utc_text } // A MODELED WALL CLOCK: what the worker's `date` prints, as a function of the realization's virtual // clock. The virtual clock (v2.std.operation_realization, a Nat-counted Second) is monotonic by @@ -17,7 +18,7 @@ import extdeps.transports.shell { ShellProcessExited } // scheduled events keep moving forward. // // It answers extdeps.clock Clock.Now in `date -u +%Y-%m-%dT%H:%M:%SZ` form, and Clock.UnixSecs and -// Clock.UnixMillis in `date +%s` and `date +%s%3N` form, over the proleptic Gregorian calendar. +// Clock.UnixMillis in `date +%s` and `date +%s%3N` form; the calendar is extdeps.units.iso8601's. type ModeledWallClock { unix_at_origin: EpochSecs step: SecondDisplacement @@ -27,45 +28,6 @@ fn wall_clock_unix(clock: ModeledWallClock, now: Second) -> Int { (clock.unix_at_origin as Int) + (second_count(s: now) as Int) + second_displacement_count(d: clock.step) } -fn two_digits(n: Int) -> String { - if n < 10 { concat("0", to_string(n)) } else { to_string(n) } -} - -// Days since 1970-01-01 to a civil date: H. Hinnant, "chrono-Compatible Low-Level Date Algorithms", -// civil_from_days -- exact for the whole proleptic Gregorian range, no table. -type CivilDate { - year: Int - month: Int - day: Int -} - -fn floor_div(a: Int, b: Int) -> Int { - if a >= 0 { a / b } else { 0 - ((0 - a + b - 1) / b) } -} - -fn civil_from_days(days: Int) -> CivilDate { - let z = days + 719468 - let era = floor_div(a: z, b: 146097) - let doe = z - era * 146097 - let yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365 - let y = yoe + era * 400 - let doy = doe - (365 * yoe + yoe / 4 - yoe / 100) - let mp = (5 * doy + 2) / 153 - let d = doy - (153 * mp + 2) / 5 + 1 - let m = if mp < 10 { mp + 3 } else { mp - 9 } - CivilDate { year: if m <= 2 { y + 1 } else { y }, month: m, day: d } -} - -fn iso8601_utc(unix: Int) -> String { - let days = floor_div(a: unix, b: 86400) - let rem = unix - days * 86400 - let date = civil_from_days(days: days) - join([ - to_string(date.year), "-", two_digits(n: date.month), "-", two_digits(n: date.day), - "T", two_digits(n: rem / 3600), ":", two_digits(n: (rem - (rem / 3600) * 3600) / 60), ":", two_digits(n: rem - (rem / 60) * 60), "Z", - ], "") -} - data clock_operation_path: String = "dag/extdeps/clock/clock.dag" fn clock_operation(operation: String) -> OperationRef { @@ -82,7 +44,7 @@ fn printed(state: S, text: String) -> OperationStep { fn wall_clock_bindings(get: fn(S) -> ModeledWallClock) -> List> { [ - OperationBinding { at: clock_operation(operation: "Now"), handler: fn(state, call) { printed(state: state, text: iso8601_utc(unix: wall_clock_unix(clock: get(state), now: call.now))) } }, + OperationBinding { at: clock_operation(operation: "Now"), handler: fn(state, call) { printed(state: state, text: iso8601_utc_text(unix: wall_clock_unix(clock: get(state), now: call.now))) } }, OperationBinding { at: clock_operation(operation: "UnixSecs"), handler: fn(state, call) { printed(state: state, text: to_string(wall_clock_unix(clock: get(state), now: call.now))) } }, OperationBinding { at: clock_operation(operation: "UnixMillis"), handler: fn(state, call) { printed(state: state, text: to_string(wall_clock_unix(clock: get(state), now: call.now) * 1000)) } }, ] diff --git a/dag/test/claim/boot_world_models_witness_test.dag b/dag/test/claim/boot_world_models_witness_test.dag index ce1e736918a..4b98636bfaa 100644 --- a/dag/test/claim/boot_world_models_witness_test.dag +++ b/dag/test/claim/boot_world_models_witness_test.dag @@ -9,7 +9,8 @@ import extdeps.transports.shell { ShellProcessExited } import extdeps.exec.command { argv_words } import extdeps.tools.gnu_coreutils { cat_command } import extdeps.crypto.hash { sha256sum_file_command } -import gunbc.wall_clock_model { ModeledWallClock, iso8601_utc, wall_clock_unix } +import gunbc.wall_clock_model { ModeledWallClock, wall_clock_unix } +import extdeps.units.iso8601 { iso8601_utc_text } import gunbc.remote_host_model { ModeledRemoteHost, ModeledRemoteFile, remote_request, remote_answer } import gunbc.filesystem_model { ModeledFilesystem, ModeledFile, fs_parent, fs_write, fs_list, fs_read } @@ -19,11 +20,11 @@ data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly // against a model that is wrong in the same direction as the code under test. Reference values for the // calendar are independent: Python's datetime.fromtimestamp(t, timezone.utc) for each instant. test fn the_wall_clock_renders_utc_like_date() -> Bool { - iso8601_utc(unix: 0) == "1970-01-01T00:00:00Z" - && iso8601_utc(unix: 951782400) == "2000-02-29T00:00:00Z" - && iso8601_utc(unix: 1790000000) == "2026-09-21T14:13:20Z" - && iso8601_utc(unix: 4102444799) == "2099-12-31T23:59:59Z" - && iso8601_utc(unix: 0 - 1) == "1969-12-31T23:59:59Z" + iso8601_utc_text(unix: 0) == "1970-01-01T00:00:00Z" + && iso8601_utc_text(unix: 951782400) == "2000-02-29T00:00:00Z" + && iso8601_utc_text(unix: 1790000000) == "2026-09-21T14:13:20Z" + && iso8601_utc_text(unix: 4102444799) == "2099-12-31T23:59:59Z" + && iso8601_utc_text(unix: 0 - 1) == "1969-12-31T23:59:59Z" } // A NEGATIVE STEP IS A WALL CLOCK THAT WENT BACKWARDS while virtual time moved forward. diff --git a/dag/test/claim/roadmap/roadmap_launch_deployment_observe_witness_test.dag b/dag/test/claim/roadmap/roadmap_launch_deployment_observe_witness_test.dag index 667ba51f198..5ceaf860afe 100644 --- a/dag/test/claim/roadmap/roadmap_launch_deployment_observe_witness_test.dag +++ b/dag/test/claim/roadmap/roadmap_launch_deployment_observe_witness_test.dag @@ -29,6 +29,7 @@ test fn witness_iso8601_utc_epoch_seconds_matches_known_instants() -> Bool { && (match iso8601_utc_epoch_seconds(text: "2026-02-30T00:00:00Z") { Present { value: _ } => false Absent => true }) && (match iso8601_utc_epoch_seconds(text: "2027-04-31T00:00:00Z") { Present { value: _ } => false Absent => true }) && (match iso8601_utc_epoch_seconds(text: "2024-02-29T00:00:00Z") { Present { value: s } => second_count(s) == 1709164800 Absent => false }) + && (match iso8601_utc_epoch_seconds(text: iso8601_utc_text(unix: 4102444799)) { Present { value: s } => second_count(s) == 4102444799 Absent => false }) } // (2) Freshness: fresh within the cadence bound, stale beyond it, refused before the deploy, and From 7c60c3d6b226b0ad0ab8605ac167b1b58beba8b7 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Tue, 29 Sep 2026 05:58:49 +0000 Subject: [PATCH 35/75] wall_clock_model: name the reading helper wall_clock_printed (the floor's AmbiguousBareNameRead) Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/gunbc/wall_clock_model.dag | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dag/gunbc/wall_clock_model.dag b/dag/gunbc/wall_clock_model.dag index 9e0e5033c31..e231427cae3 100644 --- a/dag/gunbc/wall_clock_model.dag +++ b/dag/gunbc/wall_clock_model.dag @@ -34,7 +34,7 @@ fn clock_operation(operation: String) -> OperationRef { OperationRef { path: clock_operation_path, service: "Clock", operation: operation } } -fn printed(state: S, text: String) -> OperationStep { +fn wall_clock_printed(state: S, text: String) -> OperationStep { OperationObserved { observation: ShellObserved { observation: ShellProcessExited { exit_code: 0, stdout: concat(text, "\n"), stderr: "" } }, state: state, @@ -44,8 +44,8 @@ fn printed(state: S, text: String) -> OperationStep { fn wall_clock_bindings(get: fn(S) -> ModeledWallClock) -> List> { [ - OperationBinding { at: clock_operation(operation: "Now"), handler: fn(state, call) { printed(state: state, text: iso8601_utc_text(unix: wall_clock_unix(clock: get(state), now: call.now))) } }, - OperationBinding { at: clock_operation(operation: "UnixSecs"), handler: fn(state, call) { printed(state: state, text: to_string(wall_clock_unix(clock: get(state), now: call.now))) } }, - OperationBinding { at: clock_operation(operation: "UnixMillis"), handler: fn(state, call) { printed(state: state, text: to_string(wall_clock_unix(clock: get(state), now: call.now) * 1000)) } }, + OperationBinding { at: clock_operation(operation: "Now"), handler: fn(state, call) { wall_clock_printed(state: state, text: iso8601_utc_text(unix: wall_clock_unix(clock: get(state), now: call.now))) } }, + OperationBinding { at: clock_operation(operation: "UnixSecs"), handler: fn(state, call) { wall_clock_printed(state: state, text: to_string(wall_clock_unix(clock: get(state), now: call.now))) } }, + OperationBinding { at: clock_operation(operation: "UnixMillis"), handler: fn(state, call) { wall_clock_printed(state: state, text: to_string(wall_clock_unix(clock: get(state), now: call.now) * 1000)) } }, ] } From f96ba04ff8875dc5636ad904114d21485c4e2906 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Tue, 29 Sep 2026 06:24:41 +0000 Subject: [PATCH 36/75] Name String's declarer: extdeps.systemd.journalctl and extdeps.units.iso8601 import std.string_type The floor refused AmbiguousBareNameRead in gunbc.output_policy's scope: journalctl read String through std.types, which declares nothing by that name, while std.string_type and v2.std.text both declare it. The import now names the declarer, as the refusal's remedy says; iso8601, which this PR grew, gets the same import. Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/extdeps/systemd/journalctl.dag | 3 ++- dag/extdeps/units/iso8601.dag | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dag/extdeps/systemd/journalctl.dag b/dag/extdeps/systemd/journalctl.dag index 8ff9b302c4b..11ae274b776 100644 --- a/dag/extdeps/systemd/journalctl.dag +++ b/dag/extdeps/systemd/journalctl.dag @@ -1,6 +1,7 @@ module extdeps.systemd.journalctl -import std.types { NonEmptyStr, String, Bool } +import std.types { NonEmptyStr, Bool } +import std.string_type { String } import extdeps.external_authority { ExternalAuthority, ExternalModelScope, ExternalSubjectRef } import std.decl_ref { DeclarationRef, WholeDeclaration } import extdeps.uri { Uri, Https } diff --git a/dag/extdeps/units/iso8601.dag b/dag/extdeps/units/iso8601.dag index 75b32a48f9f..6ea3ecb5a7b 100644 --- a/dag/extdeps/units/iso8601.dag +++ b/dag/extdeps/units/iso8601.dag @@ -1,6 +1,7 @@ module extdeps.units.iso8601 -import std.types { Int, String } +import std.types { Int } +import std.string_type { String } import std.nat { Nat } import extdeps.external_authority { ExternalAuthority } import extdeps.uri { Uri, Https } From a7492a29bedd09332063277cf3905801d5cb711c Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Tue, 29 Sep 2026 06:41:10 +0000 Subject: [PATCH 37/75] Matrix: with_clock_jump takes the jump instant as a Second (review 72522) It took an Int and returned the world unchanged when the Int was negative, so a mistyped instant would have run the case with no jump. A Second cannot be negative, so there is no arm to fall back through. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../mtcollins1_boot_acceptance_matrix_test.dag | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index fc4c5cbeb99..c7d210e4e3e 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -508,14 +508,11 @@ test fn pinned_an_interrupted_attempt_locks_out_the_next_one() -> Bool { // The media readiness wait is bounded by the WALL clock (gunbc.machine_intake_megarac_media_attach // megarac_await_readiness over extdeps.clock clock_unix_millis_read). In this scenario the attach's // readiness looks run from t=16 to t=35 of virtual time, so a jump at t=20 lands inside the wait. -fn with_clock_jump(w: MtCollins1BootWorld, at: Int, by: Int) -> MtCollins1BootWorld { - match std.checked_arithmetic.checked_int_to_nat(n: at) { - Absent => w - Present { value: t } => MtCollins1BootWorld { - bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, - clock: ModeledWallClock { unix_at_origin: w.clock.unix_at_origin, step: w.clock.step, jumps: list_append(w.clock.jumps, ModeledClockStep { at: second(count: t), by: std.measure.second_displacement(count: by) }) }, - worker: w.worker, console: w.console, media: w.media, - } +fn with_clock_jump(w: MtCollins1BootWorld, at: Second, by: Int) -> MtCollins1BootWorld { + MtCollins1BootWorld { + bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, + clock: ModeledWallClock { unix_at_origin: w.clock.unix_at_origin, step: w.clock.step, jumps: list_append(w.clock.jumps, ModeledClockStep { at: at, by: std.measure.second_displacement(count: by) }) }, + worker: w.worker, console: w.console, media: w.media, } } @@ -524,7 +521,7 @@ fn with_clock_jump(w: MtCollins1BootWorld, at: Int, by: Int) -> MtCollins1BootWo // ReadinessClockIncoherent arm -- rather than waiting on a window it can no longer measure, and // nothing after the attach is written. test fn a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded() -> Bool { - match run_attempt(world: with_clock_jump(w: world_with_console(lines: []), at: 20, by: 0 - 60)) { + match run_attempt(world: with_clock_jump(w: world_with_console(lines: []), at: second(count: 20), by: 0 - 60)) { WitnessReturned { value, route } => string_contains(s: outcome_reason(a: value), pattern: "the clock cannot bound the readiness wait") && count_named(route: route, name: "megarac.Media.StartMedia") == 1 @@ -537,7 +534,7 @@ test fn a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded() -> Bo // next look, and the attempt refuses without a handoff: a forward step shortens the wait, it never // buys an unbounded one. test fn a_wall_clock_jumping_forward_during_readiness_closes_the_window() -> Bool { - match run_attempt(world: with_clock_jump(w: world_with_console(lines: []), at: 20, by: 600)) { + match run_attempt(world: with_clock_jump(w: world_with_console(lines: []), at: second(count: 20), by: 600)) { WitnessReturned { value, route } => string_contains(s: outcome_reason(a: value), pattern: "did not reach Started with a bound session") && string_contains(s: outcome_reason(a: value), pattern: "(2 looks,") From 0227a71ebd8bd246aacef1d43c047b6fd04746e8 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Tue, 29 Sep 2026 06:52:56 +0000 Subject: [PATCH 38/75] iso8601 keeps String through std.types: it is in the stage0 closure (Stage0EmittedEdgesNotCovered) extdeps.units.iso8601 is reached by std.measure, so it emits into the stage0 crate, which has no partition row for std.string_type; importing it there refused the regeneration. The floor's one ambiguous site was journalctl, which keeps its std.string_type import. Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/extdeps/units/iso8601.dag | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dag/extdeps/units/iso8601.dag b/dag/extdeps/units/iso8601.dag index 6ea3ecb5a7b..75b32a48f9f 100644 --- a/dag/extdeps/units/iso8601.dag +++ b/dag/extdeps/units/iso8601.dag @@ -1,7 +1,6 @@ module extdeps.units.iso8601 -import std.types { Int } -import std.string_type { String } +import std.types { Int, String } import std.nat { Nat } import extdeps.external_authority { ExternalAuthority } import extdeps.uri { Uri, Https } From 2c5d045bd0047b619c39bfa5e4867a72c5b2ee2d Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Tue, 29 Sep 2026 07:45:48 +0000 Subject: [PATCH 39/75] Calendar in extdeps.units.iso8601_calendar, off the compiler seed's closure extdeps.units.iso8601 is imported by std.measure, so the calendar added to it (review 72483) landed in the stage0 seed and the emitted v2 compiler: a stage0 mirror drift, Nat-as-Int casts the native emitter cannot realize, and every std.measure consumer's claim scope widened into bare-name ambiguities (String, then Unit, in journalctl). The calendar now lives in a sibling module over the same constants, imported only by its two consumers; iso8601 and journalctl are back to main's bytes. Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/extdeps/systemd/journalctl.dag | 3 +- dag/extdeps/units/iso8601.dag | 73 +---------------- dag/extdeps/units/iso8601_calendar.dag | 80 +++++++++++++++++++ .../roadmap_launch_deployment_observe.dag | 5 +- dag/gunbc/wall_clock_model.dag | 4 +- .../claim/boot_world_models_witness_test.dag | 2 +- 6 files changed, 88 insertions(+), 79 deletions(-) create mode 100644 dag/extdeps/units/iso8601_calendar.dag diff --git a/dag/extdeps/systemd/journalctl.dag b/dag/extdeps/systemd/journalctl.dag index 11ae274b776..8ff9b302c4b 100644 --- a/dag/extdeps/systemd/journalctl.dag +++ b/dag/extdeps/systemd/journalctl.dag @@ -1,7 +1,6 @@ module extdeps.systemd.journalctl -import std.types { NonEmptyStr, Bool } -import std.string_type { String } +import std.types { NonEmptyStr, String, Bool } import extdeps.external_authority { ExternalAuthority, ExternalModelScope, ExternalSubjectRef } import std.decl_ref { DeclarationRef, WholeDeclaration } import extdeps.uri { Uri, Https } diff --git a/dag/extdeps/units/iso8601.dag b/dag/extdeps/units/iso8601.dag index 75b32a48f9f..7a7fbb29951 100644 --- a/dag/extdeps/units/iso8601.dag +++ b/dag/extdeps/units/iso8601.dag @@ -1,6 +1,6 @@ module extdeps.units.iso8601 -import std.types { Int, String } +import std.types { String } import std.nat { Nat } import extdeps.external_authority { ExternalAuthority } import extdeps.uri { Uri, Https } @@ -26,74 +26,3 @@ fn iso8601_minutes_per_hour() -> Nat { fn iso8601_hours_per_day() -> Nat { 24 } - -fn iso8601_seconds_per_hour() -> Int { - (iso8601_minutes_per_hour() as Int) * (iso8601_seconds_per_minute() as Int) -} - -fn iso8601_seconds_per_day() -> Int { - (iso8601_hours_per_day() as Int) * iso8601_seconds_per_hour() -} - -// THE PROLEPTIC GREGORIAN CALENDAR THE DATE FORMAT SPELLS, in both directions over one day count -// (days since 1970-01-01): H. Hinnant, "chrono-Compatible Low-Level Date Algorithms", -// days_from_civil and civil_from_days -- exact over the whole range, no table. -type Iso8601CivilDate { - year: Int - month: Int - day: Int -} - -fn iso8601_floor_div(a: Int, b: Int) -> Int { - if a >= 0 { a / b } else { 0 - ((0 - a + b - 1) / b) } -} - -fn iso8601_days_from_civil(y: Int, m: Int, d: Int) -> Int { - let yy = if m <= 2 { y - 1 } else { y } - let era = iso8601_floor_div(a: yy, b: 400) - let yoe = yy - era * 400 - let mp = if m > 2 { m - 3 } else { m + 9 } - let doy = (153 * mp + 2) / 5 + d - 1 - let doe = yoe * 365 + yoe / 4 - yoe / 100 + doy - era * 146097 + doe - 719468 -} - -fn iso8601_civil_from_days(days: Int) -> Iso8601CivilDate { - let z = days + 719468 - let era = iso8601_floor_div(a: z, b: 146097) - let doe = z - era * 146097 - let yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365 - let y = yoe + era * 400 - let doy = doe - (365 * yoe + yoe / 4 - yoe / 100) - let mp = (5 * doy + 2) / 153 - let d = doy - (153 * mp + 2) / 5 + 1 - let m = if mp < 10 { mp + 3 } else { mp - 9 } - Iso8601CivilDate { year: if m <= 2 { y + 1 } else { y }, month: m, day: d } -} - -// The day-in-month bound with the leap rule, so a calendar-impossible day (Feb 30, Apr 31) is refused -// by a reader rather than normalized through the day count. -fn iso8601_gregorian_days_in_month(y: Int, m: Int) -> Int { - if m == 2 { - if y - (y / 4) * 4 == 0 && (y - (y / 100) * 100 != 0 || y - (y / 400) * 400 == 0) { 29 } else { 28 } - } else if m == 4 || m == 6 || m == 9 || m == 11 { 30 } else { 31 } -} - -fn iso8601_two_digits(n: Int) -> String { - if n < 10 { concat("0", to_string(n)) } else { to_string(n) } -} - -// Seconds since 1970-01-01T00:00:00Z to the UTC basic-extended form `YYYY-MM-DDThh:mm:ssZ`, the form -// `date -u +%Y-%m-%dT%H:%M:%SZ` prints; the inverse of a reader of that form over the same day count. -fn iso8601_utc_text(unix: Int) -> String { - let days = iso8601_floor_div(a: unix, b: iso8601_seconds_per_day()) - let rem = unix - days * iso8601_seconds_per_day() - let hour = rem / iso8601_seconds_per_hour() - let within_hour = rem - hour * iso8601_seconds_per_hour() - let minute = within_hour / (iso8601_seconds_per_minute() as Int) - let date = iso8601_civil_from_days(days: days) - join([ - to_string(date.year), "-", iso8601_two_digits(n: date.month), "-", iso8601_two_digits(n: date.day), - "T", iso8601_two_digits(n: hour), ":", iso8601_two_digits(n: minute), ":", iso8601_two_digits(n: within_hour - minute * (iso8601_seconds_per_minute() as Int)), "Z", - ], "") -} diff --git a/dag/extdeps/units/iso8601_calendar.dag b/dag/extdeps/units/iso8601_calendar.dag new file mode 100644 index 00000000000..c145d6b3853 --- /dev/null +++ b/dag/extdeps/units/iso8601_calendar.dag @@ -0,0 +1,80 @@ +module extdeps.units.iso8601_calendar + +import std.types { Int, String } +import extdeps.units.iso8601 { iso8601_seconds_per_minute, iso8601_minutes_per_hour, iso8601_hours_per_day } + +// THE ISO 8601 CALENDAR over extdeps.units.iso8601's time-unit constants: the proleptic Gregorian day +// count in both directions, the month-length rule, and the UTC text form. It is a module of its own, +// beside the constants rather than inside them, because std.measure imports the constants and so puts +// that module in the compiler seed's closure; the calendar has no compiler consumer, and adding it +// there would grow the seed for nothing. +fn iso8601_seconds_per_hour() -> Int { + (iso8601_minutes_per_hour() as Int) * (iso8601_seconds_per_minute() as Int) +} + +fn iso8601_seconds_per_day() -> Int { + (iso8601_hours_per_day() as Int) * iso8601_seconds_per_hour() +} + +// THE PROLEPTIC GREGORIAN CALENDAR THE DATE FORMAT SPELLS, in both directions over one day count +// (days since 1970-01-01): H. Hinnant, "chrono-Compatible Low-Level Date Algorithms", +// days_from_civil and civil_from_days -- exact over the whole range, no table. +type Iso8601CivilDate { + year: Int + month: Int + day: Int +} + +fn iso8601_floor_div(a: Int, b: Int) -> Int { + if a >= 0 { a / b } else { 0 - ((0 - a + b - 1) / b) } +} + +fn iso8601_days_from_civil(y: Int, m: Int, d: Int) -> Int { + let yy = if m <= 2 { y - 1 } else { y } + let era = iso8601_floor_div(a: yy, b: 400) + let yoe = yy - era * 400 + let mp = if m > 2 { m - 3 } else { m + 9 } + let doy = (153 * mp + 2) / 5 + d - 1 + let doe = yoe * 365 + yoe / 4 - yoe / 100 + doy + era * 146097 + doe - 719468 +} + +fn iso8601_civil_from_days(days: Int) -> Iso8601CivilDate { + let z = days + 719468 + let era = iso8601_floor_div(a: z, b: 146097) + let doe = z - era * 146097 + let yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365 + let y = yoe + era * 400 + let doy = doe - (365 * yoe + yoe / 4 - yoe / 100) + let mp = (5 * doy + 2) / 153 + let d = doy - (153 * mp + 2) / 5 + 1 + let m = if mp < 10 { mp + 3 } else { mp - 9 } + Iso8601CivilDate { year: if m <= 2 { y + 1 } else { y }, month: m, day: d } +} + +// The day-in-month bound with the leap rule, so a calendar-impossible day (Feb 30, Apr 31) is refused +// by a reader rather than normalized through the day count. +fn iso8601_gregorian_days_in_month(y: Int, m: Int) -> Int { + if m == 2 { + if y - (y / 4) * 4 == 0 && (y - (y / 100) * 100 != 0 || y - (y / 400) * 400 == 0) { 29 } else { 28 } + } else if m == 4 || m == 6 || m == 9 || m == 11 { 30 } else { 31 } +} + +fn iso8601_two_digits(n: Int) -> String { + if n < 10 { concat("0", to_string(n)) } else { to_string(n) } +} + +// Seconds since 1970-01-01T00:00:00Z to the UTC basic-extended form `YYYY-MM-DDThh:mm:ssZ`, the form +// `date -u +%Y-%m-%dT%H:%M:%SZ` prints; the inverse of a reader of that form over the same day count. +fn iso8601_utc_text(unix: Int) -> String { + let days = iso8601_floor_div(a: unix, b: iso8601_seconds_per_day()) + let rem = unix - days * iso8601_seconds_per_day() + let hour = rem / iso8601_seconds_per_hour() + let within_hour = rem - hour * iso8601_seconds_per_hour() + let minute = within_hour / (iso8601_seconds_per_minute() as Int) + let date = iso8601_civil_from_days(days: days) + join([ + to_string(date.year), "-", iso8601_two_digits(n: date.month), "-", iso8601_two_digits(n: date.day), + "T", iso8601_two_digits(n: hour), ":", iso8601_two_digits(n: minute), ":", iso8601_two_digits(n: within_hour - minute * (iso8601_seconds_per_minute() as Int)), "Z", + ], "") +} diff --git a/dag/gunbc/roadmap/roadmap_launch_deployment_observe.dag b/dag/gunbc/roadmap/roadmap_launch_deployment_observe.dag index 868da4c6892..c0e6f86f07d 100644 --- a/dag/gunbc/roadmap/roadmap_launch_deployment_observe.dag +++ b/dag/gunbc/roadmap/roadmap_launch_deployment_observe.dag @@ -7,7 +7,8 @@ import gunbc.live_deploy.emit { belt_tick_cadence } import std.types { String, Bool, NonEmptyStr, Int, List } import std.algebra { trim } -import extdeps.units.iso8601 { iso8601_days_from_civil, iso8601_gregorian_days_in_month, iso8601_seconds_per_day, iso8601_seconds_per_hour, iso8601_seconds_per_minute } +import extdeps.units.iso8601 { iso8601_seconds_per_minute } +import extdeps.units.iso8601_calendar { iso8601_days_from_civil, iso8601_gregorian_days_in_month, iso8601_seconds_per_day, iso8601_seconds_per_hour } import extdeps.http.client import extdeps.languages.json.emit { JsonValue, JsonString, JsonBool, serialize_json } import extdeps.languages.json.parse { @@ -267,7 +268,7 @@ fn observe_workflow_document_routed(base_url: String) -> RoadmapWorkflowObservat // ---------------------------------------------------------------- instants // `%Y-%m-%dT%H:%M:%SZ` to seconds since 1970-01-01T00:00:00Z. Days-from-civil is the proleptic // Gregorian algorithm (Howard Hinnant, "chrono-Compatible Low-Level Date Algorithms"), exact for -// every date the format can spell; the calendar is extdeps.units.iso8601's, which also formats the +// every date the format can spell; the calendar is extdeps.units.iso8601_calendar's, which also formats the // same instants. Anything that is not exactly that shape refuses. fn two_digits_at(s: String, i: Int) -> Int? { parse_int(s: substring(s: s, start: i, end: i + 2)) diff --git a/dag/gunbc/wall_clock_model.dag b/dag/gunbc/wall_clock_model.dag index e231427cae3..4180a8b828f 100644 --- a/dag/gunbc/wall_clock_model.dag +++ b/dag/gunbc/wall_clock_model.dag @@ -7,7 +7,7 @@ import v2.std.operation_realization { OperationBinding, OperationCall, OperationStep, OperationObserved, ShellObserved, } import extdeps.transports.shell { ShellProcessExited } -import extdeps.units.iso8601 { iso8601_utc_text } +import extdeps.units.iso8601_calendar { iso8601_utc_text } // A MODELED WALL CLOCK: what the worker's `date` prints, as a function of the realization's virtual // clock. The virtual clock (v2.std.operation_realization, a Nat-counted Second) is monotonic by @@ -18,7 +18,7 @@ import extdeps.units.iso8601 { iso8601_utc_text } // scheduled events keep moving forward. // // It answers extdeps.clock Clock.Now in `date -u +%Y-%m-%dT%H:%M:%SZ` form, and Clock.UnixSecs and -// Clock.UnixMillis in `date +%s` and `date +%s%3N` form; the calendar is extdeps.units.iso8601's. +// Clock.UnixMillis in `date +%s` and `date +%s%3N` form; the calendar is extdeps.units.iso8601_calendar's. type ModeledWallClock { unix_at_origin: EpochSecs step: SecondDisplacement diff --git a/dag/test/claim/boot_world_models_witness_test.dag b/dag/test/claim/boot_world_models_witness_test.dag index 4b98636bfaa..b1c5b5357bb 100644 --- a/dag/test/claim/boot_world_models_witness_test.dag +++ b/dag/test/claim/boot_world_models_witness_test.dag @@ -10,7 +10,7 @@ import extdeps.exec.command { argv_words } import extdeps.tools.gnu_coreutils { cat_command } import extdeps.crypto.hash { sha256sum_file_command } import gunbc.wall_clock_model { ModeledWallClock, wall_clock_unix } -import extdeps.units.iso8601 { iso8601_utc_text } +import extdeps.units.iso8601_calendar { iso8601_utc_text } import gunbc.remote_host_model { ModeledRemoteHost, ModeledRemoteFile, remote_request, remote_answer } import gunbc.filesystem_model { ModeledFilesystem, ModeledFile, fs_parent, fs_write, fs_list, fs_read } From 6e9568a1cee8557522c47811e2b396ae8b0cc3c5 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Tue, 29 Sep 2026 08:26:04 +0000 Subject: [PATCH 40/75] journalctl names the declarers of String and Unit (floor AmbiguousBareNameRead) The refusal is main's latent defect in extdeps.systemd.journalctl, which read String through std.types (a re-export) and Unit bare; it surfaces in the claim scope this PR's touched modules select. journalctl is outside the stage0 closure, so std.string_type is admissible there (the earlier stage0 edge refusal was the calendar in iso8601, since moved). Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/extdeps/systemd/journalctl.dag | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dag/extdeps/systemd/journalctl.dag b/dag/extdeps/systemd/journalctl.dag index 8ff9b302c4b..4af4cd7ad4b 100644 --- a/dag/extdeps/systemd/journalctl.dag +++ b/dag/extdeps/systemd/journalctl.dag @@ -1,6 +1,7 @@ module extdeps.systemd.journalctl -import std.types { NonEmptyStr, String, Bool } +import std.types { NonEmptyStr, Bool, Unit } +import std.string_type { String } import extdeps.external_authority { ExternalAuthority, ExternalModelScope, ExternalSubjectRef } import std.decl_ref { DeclarationRef, WholeDeclaration } import extdeps.uri { Uri, Https } From 826011d53b49f61a3ab807144952630412e2e9f0 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Tue, 29 Sep 2026 08:27:21 +0000 Subject: [PATCH 41/75] Rung-drop row: the route prefix is per-world, not a repeated computation (review 72549) Co-Authored-By: Claude Opus 5.5 (1M context) --- ...mtcollins1_boot_matrix_new_witness_eval_step_cost.dag | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag index 9a841cf09e1..4f3bdf819f3 100644 --- a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag +++ b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag @@ -20,9 +20,12 @@ import v2.workflow.floor_eval_step_cost_drop { floor_eval_step_cost_drop_boot_ma // requires be executed through the real production boundary. The decision folds each case reaches are // already witnessed at their narrower interfaces with supplied values (the media convergence folds, // the power selection, the host-capture verdict, the hold store); what only the entry can establish is -// that it reaches them with the state its own earlier steps built. The work computed identically -// across cases -- world construction and the route prefix up to the hold -- is named in gunbc#12533 as -// a follow-up to hoist; hoisting it lowers the bill and does not remove the subject. +// that it reaches them with the state its own earlier steps built. The route prefix up to the hold is +// NOT one computation repeated: each case evaluates the entry over its own world, so the same code runs +// on different inputs, and sharing it would mean resuming every case from one snapshot -- replacing the +// route from the entry that each case exists to assert. What IS shared is the pure construction of the +// healthy world the cases vary; hoisting it lowers the bill, is owed as a follow-up with a re-measure +// (gunbc#12533, review 72549), and retires nothing on its own. data mtcollins1_boot_matrix_new_witness_eval_step_cost_population: List = floor_eval_step_cost_drop_boot_matrix_rows |> map(m => concat(concat(m.identity, ": over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by "), m.measured_by)) data mtcollins1_boot_matrix_new_witness_eval_step_cost: RungDrop = RungDrop { From 488e12b2c141639c0150387e96f1efc23ee24233 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Tue, 29 Sep 2026 08:48:53 +0000 Subject: [PATCH 42/75] Six new matrix rows cite a measured run; rung-drop projection regenerated (reviews 72536, 72555) measured_by now names claim_batch over tree 363968020d4 with each identity's eval_steps (73,949 to 130,890, all over the 72,300 new-witness budget, all PASS). docs/design-rung-drops.md is regenerated by generated_artifact_gate main_wet rather than edited: the population lists the fourteen identities and the trigger reads fourteen. Also merges session/swift-deer-358-pr2. Co-Authored-By: Claude Opus 5.5 (1M context) --- docs/design-rung-drops.md | 2 +- src/v2/workflow/floor_eval_step_cost_drop.dag | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index deab401242a..b4922ed13ea 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -340,7 +340,7 @@ new-witness eval-step cost gate over the ten interpreted P-256 and P-384 point a ### new-witness eval-step cost gate over the fourteen mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 -new-witness eval-step cost gate over the fourteen mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_healthy_census_is_refused_at_the_sol_teardown: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these eight identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. +new-witness eval-step cost gate over the fourteen mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_healthy_census_is_refused_at_the_sol_teardown: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded over tree 363968020d4 (gunbc#12556), 2026-09-29: PASS, eval_steps=79543 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_jumping_forward_during_readiness_closes_the_window: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_wall_clock_jumping_forward_during_readiness_closes_the_window over tree 363968020d4 (gunbc#12556), 2026-09-29: PASS, eval_steps=73949 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions cd_error_16_with_nothing_presented_refuses_before_the_handoff over tree 363968020d4 (gunbc#12556), 2026-09-29: PASS, eval_steps=79851 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions cd_error_appearing_with_readiness_refuses_before_the_handoff over tree 363968020d4 (gunbc#12556), 2026-09-29: PASS, eval_steps=94988 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted over tree 363968020d4 (gunbc#12556), 2026-09-29: PASS, eval_steps=130890 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace over tree 363968020d4 (gunbc#12556), 2026-09-29: PASS, eval_steps=86045 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these fourteen identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. ### new-witness eval-step cost gate over six App Attest verifier claims -- the two real-path inhabitance claims over Apple's objects, three single structural steps priced by their own SHA-256s, and the wire-carrier join: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 diff --git a/src/v2/workflow/floor_eval_step_cost_drop.dag b/src/v2/workflow/floor_eval_step_cost_drop.dag index 5056b439fc4..41d5a08c3e6 100644 --- a/src/v2/workflow/floor_eval_step_cost_drop.dag +++ b/src/v2/workflow/floor_eval_step_cost_drop.dag @@ -275,27 +275,27 @@ data floor_eval_step_cost_drop_boot_matrix_rows: List Date: Tue, 29 Sep 2026 09:12:04 +0000 Subject: [PATCH 43/75] roadmap_served_observation names Filesystem's declarer (floor AmbiguousBareNameRead) Its Filesystem.Read/Write are the extdeps.filesystem.filesystem_io service; std.resources also declares the name. Main's latent defect, surfaced in the roadmap witness scope this PR edits. Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/gunbc/roadmap/roadmap_served_observation.dag | 1 + 1 file changed, 1 insertion(+) diff --git a/dag/gunbc/roadmap/roadmap_served_observation.dag b/dag/gunbc/roadmap/roadmap_served_observation.dag index 51d6e080e84..84b7780020d 100644 --- a/dag/gunbc/roadmap/roadmap_served_observation.dag +++ b/dag/gunbc/roadmap/roadmap_served_observation.dag @@ -4,6 +4,7 @@ import gunbc.site.markup { page_render_refusal_body } import gunbc.roadmap.roadmap_event_carrier { roadmap_event_carrier_layout_for_instance, roadmap_standings_read } import std.types { String, Int, Bool, List, NonEmptyStr } +import extdeps.filesystem.filesystem_io { Filesystem } import std.algebra { trim } import std.content_hash { content_hash_tagged_structural, content_hash_atom } import extdeps.http.server { MediaType, text_html_utf8, text_plain_utf8, application_json_utf8, ServeHttpResponse } From b7c671c620873f561c1584345fac2cde9b141483 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Tue, 29 Sep 2026 12:42:07 +0000 Subject: [PATCH 44/75] Rung-drop row: the shared world construction is measured, and owes no hoist (review 72606) claim_batch: building the healthy world, its census console and the frame costs 1,687-3,793 eval steps against 78,317-119,267 per member; with it removed every member stays over 72,300. The world is already a supplied value, which is the witness rule's remedy, not a derivation. Co-Authored-By: Claude Opus 5.5 (1M context) --- ...mtcollins1_boot_matrix_new_witness_eval_step_cost.dag | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag index 4f3bdf819f3..85519017afa 100644 --- a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag +++ b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag @@ -23,9 +23,12 @@ import v2.workflow.floor_eval_step_cost_drop { floor_eval_step_cost_drop_boot_ma // that it reaches them with the state its own earlier steps built. The route prefix up to the hold is // NOT one computation repeated: each case evaluates the entry over its own world, so the same code runs // on different inputs, and sharing it would mean resuming every case from one snapshot -- replacing the -// route from the entry that each case exists to assert. What IS shared is the pure construction of the -// healthy world the cases vary; hoisting it lowers the bill, is owed as a follow-up with a re-measure -// (gunbc#12533, review 72549), and retires nothing on its own. +// route from the entry that each case exists to assert. What IS shared is the construction of the +// healthy world the cases vary, and it is already the section 3 remedy: a SUPPLIED value, constructed +// directly rather than derived by executing production. MEASURED (claim_batch, 2026-09-29, review +// 72606): building that world with its census console and the frame costs 1,687 to 3,793 eval steps, +// against 78,317 to 119,267 for the member cases; with it removed even the cheapest member stays over +// the 72,300 budget. So hoisting it neither retires this drop nor removes a member, and none is owed. data mtcollins1_boot_matrix_new_witness_eval_step_cost_population: List = floor_eval_step_cost_drop_boot_matrix_rows |> map(m => concat(concat(m.identity, ": over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by "), m.measured_by)) data mtcollins1_boot_matrix_new_witness_eval_step_cost: RungDrop = RungDrop { From bd99cbb48998bcf1d95a9337700ae39d42d1dad9 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Wed, 30 Sep 2026 00:08:23 +0000 Subject: [PATCH 45/75] Matrix: bind #12434's SOL route; the two pinned SOL cases flip to controls The dry realization now answers the route #12434 landed: - processes carry a start time, visible as /proc//stat (field 22) beside cmdline; ActivateHeld publishes " ", sends the grounded preamble's banner to the capture and its stderr to the client diagnostics, and a foreign session's refusal to the diagnostics; - one exit transition (deactivate, session drop, ReleaseHeld) removes the /proc entry and records the supervisor's exit line; ReleaseHeld stops only the recorded instance; - the notice watcher the step starts before the entry is scenario state (with_notice_watcher); - shell.Move File is a rename in gunbc.filesystem_model; ipmitool mc info answers with the two fields the corpus read from this controller, its layout typed TranscribedUncited. Flips: pinned_a_healthy_census_is_refused_at_the_sol_teardown -> a_healthy_census_completes_and_releases_its_collector (ok; deactivate, ReleaseHeld, two retiring deletes, all under the hold). pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline -> a_sol_loss_mid_boot_is_reported_before_the_deadline (typed ObservationChannelLost, incident frozen, BMC answering, teardown within 60 s of power-on). The held-elsewhere case asserts the typed cause. claim_batch, the merged tree: matrix, realization, model and filesystem witnesses 42/42 PASS. The eval-step drop now covers nine members (the listing case crossed the budget on the longer route), each row re-measured; docs/design-rung-drops.md regenerated. Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/extdeps/bmc/ipmitool_observed_output.dag | 11 ++ dag/gunbc/bmc_dry_realization.dag | 7 + dag/gunbc/filesystem_model.dag | 41 ++++- .../mtcollins1_boot_dry_realization.dag | 162 ++++++++++++++---- ...boot_matrix_new_witness_eval_step_cost.dag | 8 +- ...mtcollins1_boot_acceptance_matrix_test.dag | 57 +++--- docs/design-rung-drops.md | 4 + src/v2/workflow/floor_eval_step_cost_drop.dag | 28 +-- 8 files changed, 244 insertions(+), 74 deletions(-) diff --git a/dag/extdeps/bmc/ipmitool_observed_output.dag b/dag/extdeps/bmc/ipmitool_observed_output.dag index 5b3831c55be..8d6583ae89b 100644 --- a/dag/extdeps/bmc/ipmitool_observed_output.dag +++ b/dag/extdeps/bmc/ipmitool_observed_output.dag @@ -54,3 +54,14 @@ data ipmitool_raw_two_bytes_standing: CitedFigureStanding = TranscribedUncited { fn ipmitool_raw_two_bytes(first_hex: String, second_hex: String) -> String { join([" ", first_hex, " ", second_hex, "\n"], "") } + +// `ipmitool mc info` against the Mt. Collins BMC: the two fields the corpus has read from this +// controller -- Firmware Revision 0.32 and IPMI Version 2.0 (gunbc.machine_intake_mtcollins1_access_observation) +// in ipmitool's ` : ` field layout. No verbatim stdout is retained, so the layout, and +// the absence of the other fields ipmitool prints, carry this standing. The boot's reachability read +// consumes only the exit and stderr. +data ipmitool_mc_info_standing: CitedFigureStanding = TranscribedUncited { + read_obligation: "a retained stdout of `ipmitool mc info` against the Mt. Collins BMC, cited by digest" as NonEmptyStr +} + +data ipmitool_mc_info_mt_collins: String = "Firmware Revision : 0.32\nIPMI Version : 2.0\n" diff --git a/dag/gunbc/bmc_dry_realization.dag b/dag/gunbc/bmc_dry_realization.dag index 914b446b6ef..7f7fa113851 100644 --- a/dag/gunbc/bmc_dry_realization.dag +++ b/dag/gunbc/bmc_dry_realization.dag @@ -27,6 +27,7 @@ import extdeps.bmc.megarac_observed_output { import extdeps.languages.json.parse { parse_json_document, JsonDocumentParsed, JsonDocumentUnreadable } import gunbc.machine_intake_megarac_media_attach { json_string_member, json_number_member } import extdeps.bmc.ipmitool_observed_output { + ipmitool_mc_info_mt_collins, ipmitool_bootparam5_no_override, ipmitool_bootparam5_cdrom_efi_next_boot, ipmitool_bootdev_cdrom_reply, ipmitool_sel_elist_line, } @@ -111,6 +112,11 @@ fn bmc_sel_elist_reply(world: BmcWorld, call: OperationCall) -> BmcReply { BmcReplied { stdout: join(map(world.sel, r => ipmitool_sel_elist_line(record_id_hex: r.id_hex, date: r.date, time: r.time, sensor: r.sensor, event: r.event, state: r.state)), ""), world: world } } +// `mc info` answers whenever the management controller does, whatever the host's power or SOL state. +fn bmc_mc_info_reply(world: BmcWorld, call: OperationCall) -> BmcReply { + BmcReplied { stdout: ipmitool_mc_info_mt_collins, world: world } +} + // One IPMI round trip takes one virtual second. fn bmc_lift(get: fn(S) -> BmcWorld, put: fn(S, BmcWorld) -> S, reply: fn(BmcWorld, OperationCall) -> BmcReply) -> fn(S, OperationCall) -> OperationStep { fn(state, call) { @@ -133,6 +139,7 @@ fn bmc_bindings(get: fn(S) -> BmcWorld, put: fn(S, BmcWorld) -> S) -> List(get: fn(S) -> ModeledFilesystem, put: fn(S, ModeledFil OperationBinding { at: filesystem_operation(operation: "WriteOwnerOnly"), handler: writing(get: get, put: put, create_new: false) }, OperationBinding { at: filesystem_operation(operation: "WriteCreateNew"), handler: writing(get: get, put: put, create_new: true) }, OperationBinding { at: filesystem_operation(operation: "WriteCreateNewWithMode"), handler: writing(get: get, put: put, create_new: true) }, + OperationBinding { at: shell_move_file_operation, handler: moving(get: get, put: put) }, ] } @@ -205,3 +207,40 @@ fn writing(get: fn(S) -> ModeledFilesystem, put: fn(S, ModeledFilesystem) -> } } } + +// extdeps.shell shell.Move File: `mv `, a rename within the one modeled +// filesystem. It replaces an existing destination file, as mv does, and fails -- exit 1 with mv's +// "cannot stat" -- when the source does not exist or the destination's directory does not. +data shell_move_file_operation: OperationRef = OperationRef { path: "dag/extdeps/shell.dag", service: "shell.Move", operation: "File" } + +fn fs_move(fs: ModeledFilesystem, source: String, destination: String) -> ModeledFileWrite { + match fs_file(fs: fs, path: source) { + Absent => ModeledFileWrite { fs: fs, observation: failed_with(kind: FilesystemNotFound, message: concat("No such file or directory: ", source)) } + Present { value: f } => + if !fs_is_directory(fs: fs, path: fs_parent(path: destination)) { + ModeledFileWrite { fs: fs, observation: failed_with(kind: FilesystemNotFound, message: concat("No such file or directory: ", destination)) } + } else { + let removed = ModeledFilesystem { directories: fs.directories, files: filter(fs.files, x => x.path != source) } + ModeledFileWrite { fs: fs_with_file(fs: removed, path: destination, content: f.content), observation: FileOperationSucceeded { byte_count: byte_size(count: 0), content: "" } } + } + } +} + +fn moving(get: fn(S) -> ModeledFilesystem, put: fn(S, ModeledFilesystem) -> S) -> fn(S, OperationCall) -> OperationStep { + fn(state, call) { + match operation_input_text(invocation: call.invocation, name: "source") { + Absent => OperationHarnessFault { reason: "a move was dispatched without a source" as NonEmptyStr } + Present { value: source } => match operation_input_text(invocation: call.invocation, name: "destination") { + Absent => OperationHarnessFault { reason: "a move was dispatched without a destination" as NonEmptyStr } + Present { value: destination } => { + let m = fs_move(fs: get(state), source: source, destination: destination) + let exited = match m.observation { + FileOperationSucceeded { byte_count: _, content: _ } => ShellProcessExited { exit_code: 0, stdout: "", stderr: "" } + FileOperationFailed { kind: _, error: _ } => ShellProcessExited { exit_code: 1, stdout: "", stderr: join(["mv: cannot stat '", source, "': No such file or directory\n"], "") } + } + OperationObserved { observation: ShellObserved { observation: exited }, state: put(state, m.fs), elapsed: second(count: 0) } + } + } + } + } +} diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag index 28c827c2301..40d603ef75a 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag @@ -2,6 +2,7 @@ module gunbc.machine_intake_mtcollins1_boot_dry_realization import std.types { Bool, Int, List, NonEmptyStr, String } import std.measure { Second, second, second_count } +import std.algebra { trim } import v2.std.operation_argv { OperationRef } import v2.std.operation_realization { OperationRealization, OperationBinding, OperationCall, OperationStep, @@ -19,6 +20,9 @@ import extdeps.exec.command { env_prefixed_command } import extdeps.tools.env { EnvSet } import extdeps.ssh.openssh_client_commands { ssh_add_list_identities_command } import extdeps.bmc.ipmitool_observed_output { ipmitool_sol_activate_preamble } +import extdeps.bmc.ipmi { ipmitool_sol_operational_banner } +import gunbc.machine_intake_sol_hold { sol_hold_exit_record_prefix } +import gunbc.machine_intake_mtcollins1_boot_run { mtcollins1_sol_notice_ready_suffix, mtcollins1_sol_notice_watcher_path, mtcollins1_sol_notice_token_env } import gunbc.fleet_ssh_access { fleet_automation_ssh_key_fingerprint } import gunbc.remote_host_model { ModeledRemoteHost, remote_host_binding } import gunbc.wall_clock_model { ModeledWallClock, wall_clock_bindings } @@ -59,14 +63,20 @@ fn agent_listing(agent: ModeledSshAgent) -> ShellExchangeObservation { } } -// THE WORKER'S PROCESSES that the attempt starts: today, the SOL collector. A live process is visible -// the way the production liveness check reads it -- /proc//cmdline -- and a dead one is not. The -// model writes cmdline with spaces between arguments where Linux writes NULs; the production reader -// asks only whether it contains `ipmitool`, which both spellings answer the same way. +// THE WORKER'S PROCESSES: the SOL collector the attempt starts, and the notice watcher the boot step +// starts before the entry runs. A live process is visible the way the production observers read it +// (gunbc.machine_intake_mtcollins1_boot_run mtcollins1_sol_collector_observe, sol_observer_refusal_of): +// /proc//stat, whose field 22 is the start time the hold publishes as " ", and +// /proc//cmdline. An exited process has neither. The model writes cmdline with spaces where Linux +// writes NULs; the production reader asks only whether it contains `ipmitool`, which both answer alike. +// diagnostic_path is where the hold sends the process's stderr and its exit record (empty: none). type ModeledProcess { pid: Int + start_time: Int + comm: String cmdline: String capture_path: String + diagnostic_path: String alive: Bool } @@ -122,8 +132,70 @@ fn proc_cmdline_path(pid: Int) -> String { join(["/proc/", to_string(pid), "/cmdline"], "") } +fn proc_stat_path(pid: Int) -> String { + join(["/proc/", to_string(pid), "/stat"], "") +} + +// proc(5) stat: " () ..." with the start time at field 22, which is word 19 of what +// follows the comm -- the position the production reader (proc_stat_after_comm) takes it from. The +// fields the readers do not consult are zero. +fn proc_stat_line(p: ModeledProcess) -> String { + join([to_string(p.pid), " (", p.comm, ") S ", join(map([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], _i => "0"), " "), " ", to_string(p.start_time), " 0\n"], "") +} + +// The published identity, as gunbc.machine_intake.sol_hold's supervisor writes it: " ". +fn process_identity(p: ModeledProcess) -> String { + join([to_string(p.pid), " ", to_string(p.start_time), "\n"], "") +} + +// Start times in clock ticks since the worker booted (USER_HZ 100), so a later process has a later one. +fn start_ticks(w: MtCollins1BootWorld, now: Second) -> Int { + (w.worker.uptime_at_origin + (second_count(s: now) as Int)) * 100 +} + +fn process_visible(fs: ModeledFilesystem, p: ModeledProcess) -> ModeledFilesystem { + fs_with_file(fs: fs_with_file(fs: fs, path: proc_stat_path(pid: p.pid), content: proc_stat_line(p: p)), path: proc_cmdline_path(pid: p.pid), content: p.cmdline) +} + +// A PROCESS EXITS: its /proc entry goes, and the hold's supervisor records the exit in the process's +// diagnostic file (sol_hold_exit_record_prefix). The one transition every way a process ends uses -- +// a deactivate, the controller dropping the session, a release. +fn process_gone(fs: ModeledFilesystem, p: ModeledProcess) -> ModeledFilesystem { + let without = ModeledFilesystem { directories: fs.directories, files: filter(fs.files, f => f.path != proc_stat_path(pid: p.pid) && f.path != proc_cmdline_path(pid: p.pid)) } + if p.diagnostic_path == "" { without } else { appended(fs: without, path: p.diagnostic_path, text: concat(sol_hold_exit_record_prefix, "0\n")) } +} + +fn process_dead(p: ModeledProcess) -> ModeledProcess { + ModeledProcess { pid: p.pid, start_time: p.start_time, comm: p.comm, cmdline: p.cmdline, capture_path: p.capture_path, diagnostic_path: p.diagnostic_path, alive: false } +} + +fn exit_processes(w: MtCollins1BootWorld, ending: fn(ModeledProcess) -> Bool) -> MtCollins1BootWorld { + let fs = fold(filter(w.worker.processes, p => p.alive && ending(p)), init: w.fs, f: fn(acc, p) { process_gone(fs: acc, p: p) }) + let processes = map(w.worker.processes, p => if p.alive && ending(p) { process_dead(p: p) } else { p }) + with_worker(w: with_fs(w: w, fs: fs), worker: ModeledWorker { next_pid: w.worker.next_pid, processes: processes, uptime_at_origin: w.worker.uptime_at_origin }) +} + +fn is_collector(p: ModeledProcess) -> Bool { + p.comm == "ipmitool" +} + fn live_collectors(w: MtCollins1BootWorld) -> List { - filter(w.worker.processes, p => p.alive) + filter(w.worker.processes, p => p.alive && is_collector(p: p)) +} + +fn started(w: MtCollins1BootWorld, p: ModeledProcess, fs: ModeledFilesystem) -> MtCollins1BootWorld { + with_worker(w: with_fs(w: w, fs: if p.alive { process_visible(fs: fs, p: p) } else { fs }), worker: ModeledWorker { next_pid: p.pid + 1, processes: list_append(w.worker.processes, p), uptime_at_origin: w.worker.uptime_at_origin }) +} + +// THE NOTICE WATCHER the boot step starts before the entry (gunbc.ci_spec): its token in the +// environment, its readiness file holding that token, and its record naming a live process -- what +// gunbc.machine_intake_mtcollins1_boot_run mtcollins1_sol_await_observer requires before any BMC +// contact. It is scenario state because the entry does not start it. +fn with_notice_watcher(w: MtCollins1BootWorld, capture_path: String, token: String) -> MtCollins1BootWorld { + let p = ModeledProcess { pid: w.worker.next_pid, start_time: start_ticks(w: w, now: second(count: 0)), comm: "bash", cmdline: "bash -c gunbc-sol-notice-watch", capture_path: capture_path, diagnostic_path: "", alive: true } + let fs = fs_with_file(fs: fs_with_file(fs: w.fs, path: concat(capture_path, mtcollins1_sol_notice_ready_suffix), content: concat(token, "\n")), path: mtcollins1_sol_notice_watcher_path(capture_path: capture_path), content: process_identity(p: p)) + let env = list_append(w.environment, ModeledVariable { name: mtcollins1_sol_notice_token_env as String, value: token }) + started(w: MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: env, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: w.media }, p: p, fs: fs) } fn exited_step(state: S, stdout: String, exit_code: Int) -> OperationStep { @@ -143,41 +215,59 @@ fn sdr_dump_handler(w: MtCollins1BootWorld, call: OperationCall) -> OperationSte } } -// gunbc.machine_intake.sol_hold ActivateHeld: a shell starts `ipmitool ... sol activate` in the -// background with its output appended to the capture, records its pid in the pid file, and exits 0 once -// the background job exists. The collector then opens the BMC's SOL session. If the session is already -// held by another client, the real client prints the refusal and exits at once -- but the shell has -// already succeeded and written the pid, exactly as here. +// gunbc.machine_intake.sol_hold ActivateHeld: the hold starts `ipmitool ... sol activate` in the +// background with its stdout appended to the capture and its stderr to the client diagnostic file, +// publishes " " to the pid file, and exits 0 once the job exists. On activation the +// client prints the grounded preamble (extdeps.bmc.ipmitool_observed_output +// ipmitool_sol_activate_preamble): its banner line on stdout, the rest on stderr. If the controller's +// session is already held, the client prints the refusal on stderr and exits at once, and the +// supervisor records that exit -- but the hold has already succeeded and published the pid. fn sol_activate_held_handler(w: MtCollins1BootWorld, call: OperationCall) -> OperationStep { match operation_input_text(invocation: call.invocation, name: "capture_path") { Absent => OperationHarnessFault { reason: "ActivateHeld was dispatched without a capture path" as NonEmptyStr } Present { value: capture } => match operation_input_text(invocation: call.invocation, name: "pid_path") { Absent => OperationHarnessFault { reason: "ActivateHeld was dispatched without a pid path" as NonEmptyStr } - Present { value: pid_path } => { - let pid = w.worker.next_pid - let program = match operation_input_text(invocation: call.invocation, name: "ipmitool") { Present { value: p } => p Absent => "ipmitool" } - let already = w.bmc.sol_session_open - let process = ModeledProcess { pid: pid, cmdline: concat(program, " -H bmc -I lanplus sol activate"), capture_path: capture, alive: !already } - let fs1 = fs_write(fs: w.fs, path: pid_path, content: concat(to_string(pid), "\n"), create_new: false).fs - let fs2 = if already { appended(fs: fs1, path: capture, text: "Info: SOL payload already active on another session\n") } - else { fs_with_file(fs: appended(fs: fs1, path: capture, text: ipmitool_sol_activate_preamble), path: proc_cmdline_path(pid: pid), content: process.cmdline) } - let worker = ModeledWorker { next_pid: pid + 1, processes: list_append(w.worker.processes, process), uptime_at_origin: w.worker.uptime_at_origin } - let bmc = if already { w.bmc } else { bmc_with_sol_session(world: w.bmc, open: true) } - exited_step(state: with_bmc(w: with_worker(w: with_fs(w: w, fs: fs2), worker: worker), bmc: bmc), stdout: "", exit_code: 0) + Present { value: pid_path } => match operation_input_text(invocation: call.invocation, name: "client_diagnostic_path") { + Absent => OperationHarnessFault { reason: "ActivateHeld was dispatched without a client diagnostic path" as NonEmptyStr } + Present { value: diag } => { + let program = match operation_input_text(invocation: call.invocation, name: "ipmitool") { Present { value: p } => p Absent => "ipmitool" } + let already = w.bmc.sol_session_open + let p = ModeledProcess { pid: w.worker.next_pid, start_time: start_ticks(w: w, now: call.now), comm: "ipmitool", cmdline: concat(program, " -H bmc -I lanplus sol activate"), capture_path: capture, diagnostic_path: diag, alive: !already } + let published = fs_write(fs: w.fs, path: pid_path, content: process_identity(p: p), create_new: false).fs + let preamble = filter(split(s: ipmitool_sol_activate_preamble, delimiter: "\n"), l => l != "") + let banner = join(map(filter(preamble, l => string_contains(s: l, pattern: ipmitool_sol_operational_banner)), l => concat(l, "\n")), "") + let stderr = join(map(filter(preamble, l => !string_contains(s: l, pattern: ipmitool_sol_operational_banner)), l => concat(l, "\n")), "") + let fs = if already { appended(fs: published, path: diag, text: concat("Info: SOL payload already active on another session\n", concat(sol_hold_exit_record_prefix, "1\n"))) } + else { appended(fs: appended(fs: published, path: capture, text: banner), path: diag, text: stderr) } + let bmc = if already { w.bmc } else { bmc_with_sol_session(world: w.bmc, open: true) } + exited_step(state: with_bmc(w: started(w: w, p: p, fs: fs), bmc: bmc), stdout: "", exit_code: 0) + } } } } } -// `ipmitool sol deactivate` ends the BMC's SOL session; a collector attached to it loses its session -// and exits, so its /proc entry disappears. Its pid file is NOT removed -- nothing in the realization -// removes it -- which is exactly what the production teardown observes afterwards. +// `ipmitool sol deactivate` ends the controller's SOL session, and a collector attached to it loses +// its session and exits. Its pid file and activation receipt stay: removing them is the production +// release's retirement, not the controller's. fn sol_deactivate_handler(w: MtCollins1BootWorld, call: OperationCall) -> OperationStep { - let fs = fold(live_collectors(w: w), init: w.fs, f: fn(acc, p) { - ModeledFilesystem { directories: acc.directories, files: filter(acc.files, f => f.path != proc_cmdline_path(pid: p.pid)) } - }) - let worker = ModeledWorker { next_pid: w.worker.next_pid, processes: map(w.worker.processes, p => ModeledProcess { pid: p.pid, cmdline: p.cmdline, capture_path: p.capture_path, alive: false }), uptime_at_origin: w.worker.uptime_at_origin } - exited_step(state: with_bmc(w: with_worker(w: with_fs(w: w, fs: fs), worker: worker), bmc: bmc_with_sol_session(world: w.bmc, open: false)), stdout: "", exit_code: 0) + exited_step(state: with_bmc(w: exit_processes(w: w, ending: is_collector), bmc: bmc_with_sol_session(world: w.bmc, open: false)), stdout: "", exit_code: 0) +} + +// gunbc.machine_intake.sol_hold ReleaseHeld: stops the process the pid file names only while that +// " " is a live instance with that start time (sol_hold_owned_condition), and succeeds +// once it is gone; a record naming no live instance has nothing to stop and also succeeds. +fn sol_release_held_handler(w: MtCollins1BootWorld, call: OperationCall) -> OperationStep { + match operation_input_text(invocation: call.invocation, name: "pid_path") { + Absent => OperationHarnessFault { reason: "ReleaseHeld was dispatched without a pid path" as NonEmptyStr } + Present { value: pid_path } => match fs_file(fs: w.fs, path: pid_path) { + Absent => exited_step(state: w, stdout: "", exit_code: 0) + Present { value: record } => { + let named = trim(s: record.content) + exited_step(state: exit_processes(w: w, ending: fn(p) { trim(s: process_identity(p: p)) == named }), stdout: "", exit_code: 0) + } + } + } } // Master Write-Read toward the SMpro. The retained attempt of 2026-09-27 (run 36335369059, @@ -241,12 +331,7 @@ fn concat_text(lines: List) -> String { // or by a deactivate -- the `ipmitool sol activate` client loses its session and exits, so its /proc // entry disappears; its pid file stays, since nothing in the realization removes it. fn collectors_follow_session(w: MtCollins1BootWorld) -> MtCollins1BootWorld { - if w.bmc.sol_session_open || count(live_collectors(w: w)) == 0 { w } else { - let fs = fold(live_collectors(w: w), init: w.fs, f: fn(acc, p) { - ModeledFilesystem { directories: acc.directories, files: filter(acc.files, f => f.path != proc_cmdline_path(pid: p.pid)) } - }) - with_worker(w: with_fs(w: w, fs: fs), worker: ModeledWorker { next_pid: w.worker.next_pid, processes: map(w.worker.processes, p => ModeledProcess { pid: p.pid, cmdline: p.cmdline, capture_path: p.capture_path, alive: false }), uptime_at_origin: w.worker.uptime_at_origin }) - } + if w.bmc.sol_session_open || count(live_collectors(w: w)) == 0 { w } else { exit_processes(w: w, ending: is_collector) } } // Time only changes the world when something is scheduled -- a BMC event, a connecting or withdrawing @@ -269,6 +354,12 @@ data sol_hold_activate_held_operation: OperationRef = OperationRef { operation: "ActivateHeld", } +data sol_hold_release_held_operation: OperationRef = OperationRef { + path: "dag/gunbc/machine_intake/sol_hold.dag", + service: "gunbc.machine_intake.sol_hold", + operation: "ReleaseHeld", +} + fn mtcollins1_boot_dry_realization(identity: NonEmptyStr, initial: MtCollins1BootWorld, epoch: Second) -> OperationRealization { let bmc = concat(bmc_bindings(get: fn(w) { w.bmc }, put: with_bmc), megarac_bindings(get: fn(w) { w.media }, put: with_media)) let files = filesystem_bindings(get: fn(w) { w.fs }, put: with_fs) @@ -283,6 +374,7 @@ fn mtcollins1_boot_dry_realization(identity: NonEmptyStr, initial: MtCollins1Boo OperationBinding { at: bmc_ipmi_operation(operation: "SolDeactivate"), handler: sol_deactivate_handler }, OperationBinding { at: bmc_ipmi_operation(operation: "MasterWriteReadAuthenticated"), handler: smpro_refused_handler }, OperationBinding { at: sol_hold_activate_held_operation, handler: sol_activate_held_handler }, + OperationBinding { at: sol_hold_release_held_operation, handler: sol_release_held_handler }, OperationBinding { at: linux_procfs_read_uptime_operation, handler: uptime_handler }, ] OperationRealization { diff --git a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag index 85519017afa..2ab9f02ae62 100644 --- a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag +++ b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag @@ -9,7 +9,7 @@ import v2.workflow.floor_eval_step_cost_drop { floor_eval_step_cost_drop_boot_ma // matrix, msg_83af891b). The DECLARATION lives here; the POPULATION's authority is // `v2.workflow.floor_eval_step_cost_drop` `floor_eval_step_cost_drop_boot_matrix_rows`. // -// WHAT IS LOST IS ONE WALL, AND THE CLAIMS ARE UNTOUCHED. The eight identities are planned, executed +// WHAT IS LOST IS ONE WALL, AND THE CLAIMS ARE UNTOUCHED. The nine identities are planned, executed // and measured on every pull request that edits them; a semantic red and a wall-clock crossing still // block. Only the eval-step overrun is reported as `EvalStepsOverBudgetUnderDeclaredDrop` rather than // refusing. The budget is not raised. Their CPU stays under the enrolment margin, so they enrol @@ -27,14 +27,14 @@ import v2.workflow.floor_eval_step_cost_drop { floor_eval_step_cost_drop_boot_ma // healthy world the cases vary, and it is already the section 3 remedy: a SUPPLIED value, constructed // directly rather than derived by executing production. MEASURED (claim_batch, 2026-09-29, review // 72606): building that world with its census console and the frame costs 1,687 to 3,793 eval steps, -// against 78,317 to 119,267 for the member cases; with it removed even the cheapest member stays over +// against 77,801 to 167,236 for the member cases (re-measured after #12434's route was bound); with it removed even the cheapest member stays over // the 72,300 budget. So hoisting it neither retires this drop nor removes a member, and none is owed. data mtcollins1_boot_matrix_new_witness_eval_step_cost_population: List = floor_eval_step_cost_drop_boot_matrix_rows |> map(m => concat(concat(m.identity, ": over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by "), m.measured_by)) data mtcollins1_boot_matrix_new_witness_eval_step_cost: RungDrop = RungDrop { identity: "mtcollins1_boot_matrix_new_witness_eval_step_cost" as NonEmptyStr, - subject: "new-witness eval-step cost gate over the eight mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered", + subject: "new-witness eval-step cost gate over the nine mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered", declared: "2026-09-28", @@ -47,6 +47,6 @@ data mtcollins1_boot_matrix_new_witness_eval_step_cost: RungDrop = RungDrop { replacement: "the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter", }, population: mtcollins1_boot_matrix_new_witness_eval_step_cost_population, - restoration_trigger: "THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these eight identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither.", + restoration_trigger: "THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these nine identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither.", } } diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index 31cc33ca5e0..c3caf077966 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -19,7 +19,7 @@ import gunbc.wall_clock_model { ModeledWallClock } import gunbc.megarac_media_model { MegaRacMediaWorld, MegaRacShare, MegaRacImage, MegaRacCdRow, megarac_cleared_cd } import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld, ModeledSshAgent, ModeledWorker, ModeledHostConsole, TimedConsoleLine, - mtcollins1_boot_dry_realization, with_media, with_bmc, + mtcollins1_boot_dry_realization, with_media, with_bmc, with_notice_watcher, } import v2.std.operation_realization { OperationRealization, OperationBinding, OperationCall, OperationStep, OperationObserved, OperationWorkerKilled, @@ -66,7 +66,7 @@ fn matrix_grant(service: String, verb: std.effect_grant.Verb) -> Grant { // writing. An operation of any other service refuses as uncovered. data matrix_services: List = [ "diagnostic.ipmi.Tool", "megarac.Media", "Filesystem", "shell.Env", "sleep.Delay", - "gunbc.machine_intake.sol_hold", "shell.Exec", "ssh.Session", "Clock", "linux.Procfs", + "gunbc.machine_intake.sol_hold", "shell.Exec", "ssh.Session", "Clock", "linux.Procfs", "shell.Move", ] fn matrix_frame(world: MtCollins1BootWorld) -> WitnessEvaluationFrame { @@ -127,7 +127,7 @@ fn worker_filesystem() -> ModeledFilesystem { } fn world_with_console(lines: List) -> MtCollins1BootWorld { - MtCollins1BootWorld { + with_notice_watcher(capture_path: sol_capture_path, token: "matrix-notice-token", w: MtCollins1BootWorld { bmc: bmc_world(power: BmcPowerOff), fs: worker_filesystem(), environment: [ @@ -144,7 +144,7 @@ fn world_with_console(lines: List) -> MtCollins1BootWorld { worker: ModeledWorker { next_pid: 4000, processes: [], uptime_at_origin: 86400 }, console: ModeledHostConsole { lines: lines, emitted: 0, boot: none }, media: healthy_media(), - } + }) } // A census image that boots one socket and completes: the capture test.claim.machine_intake.mtcollins1_boot_run_witness_test @@ -243,18 +243,21 @@ test fn a_host_that_never_prints_a_census_refuses_at_the_deadline() -> Bool { } } -// A HEALTHY HOST CANNOT CURRENTLY REPORT SUCCESS. PINNED DEFECT, found by this matrix: the census -// closes and is accepted (the stage is ActuationCensusEnded), and the attempt still refuses at the SOL -// teardown, because after `sol deactivate` the collector exits and nothing removes its pid file, which -// the re-observation then reads as stale (gunbc.machine_intake_mtcollins1_boot_run -// mtcollins1_boot_release_sol). This case asserts TODAY'S behaviour so the defect stays visible; when -// the teardown is repaired it must FLIP to ExitSuccess, and that flip is the repair landing. -test fn pinned_a_healthy_census_is_refused_at_the_sol_teardown() -> Bool { +// A HEALTHY HOST REPORTS SUCCESS, AND THE TEARDOWN RELEASES ONLY WHAT IT OWNS. The census closes and +// is accepted, and the attempt completes. This case was pinned as a defect -- the collector's pid file +// read as stale after the deactivate -- until #12434 made the release identity-checked and retiring; it +// is now the control that the repair holds. Route: the SOL deactivate, then the hold's ReleaseHeld +// of the recorded instance, then the retirement of its pid file and activation receipt; every +// controller write under the unit hold. +test fn a_healthy_census_completes_and_releases_its_collector() -> Bool { match run_attempt(world: world_with_console(lines: console_of(capture: one_socket_census_capture, begin_after: 60, end_after: 240))) { WitnessReturned { value, route } => census_ended(a: value) - && outcome_reason(a: value) == "refused: mtcollins1 boot: SOL pid file stale after deactivate" + && outcome_reason(a: value) == "ok" && count_named(route: route, name: "diagnostic.ipmi.Tool.SolDeactivate") == 1 + && first_ordinal(route: route, name: "diagnostic.ipmi.Tool.SolDeactivate") < first_ordinal(route: route, name: "gunbc.machine_intake.sol_hold.ReleaseHeld") + && first_ordinal(route: route, name: "gunbc.machine_intake.sol_hold.ReleaseHeld") < first_ordinal(route: route, name: "Filesystem.Delete") + && count_named(route: route, name: "Filesystem.Delete") == 2 && controller_writes_are_under_the_hold(route: route) _ => false } @@ -396,14 +399,17 @@ test fn pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause() // ─── OBSERVATION FAILURES ───────────────────────────────────────────────────────────────────────── -// ANOTHER CLIENT ALREADY HOLDS THE SOL SESSION. The collector starts and exits at once, so it is not -// held after the settle; the attempt refuses before any other controller write. +// ANOTHER CLIENT ALREADY HOLDS THE SOL SESSION. The collector starts and exits at once with the +// controller's refusal on its stderr, and the attempt refuses with that typed cause -- read from the +// client diagnostics, never the host capture -- before any other controller write, and without +// deactivating a session this hold did not establish. test fn a_sol_session_held_elsewhere_refuses_before_the_attach() -> Bool { let w = world_with_console(lines: []) match run_attempt(world: with_bmc(w: w, bmc: bmc_with_sol_session(world: w.bmc, open: true))) { WitnessReturned { value, route } => - string_contains(s: outcome_reason(a: value), pattern: "SOL collector is not held after acquire") + string_contains(s: outcome_reason(a: value), pattern: "SOL collector not established: the SOL payload is already active on another session") && count_named(route: route, name: "megarac.Media.StartMedia") == 0 + && count_named(route: route, name: "diagnostic.ipmi.Tool.SolDeactivate") == 0 && reached_no_power_action(route: route) _ => false } @@ -411,22 +417,29 @@ test fn a_sol_session_held_elsewhere_refuses_before_the_attach() -> Bool { // SOL IS LOST THIRTY SECONDS AFTER THE HOST STARTS BOOTING WHILE MANAGEMENT KEEPS ANSWERING, and the // census would have printed at sixty. The drop is armed by the host's own boot in the model, so it -// follows the route's real power-on. PINNED: the attempt learns of the loss only at the terminal -// deadline -- the capture stops growing and the watch polls to its bound -- so the first loss is not -// reported before the deadline (#12423 asks that it is). The final world shows the drop fired, so the -// case is not green on a run where the loss never happened. When loss detection lands it must flip to -// an early, typed refusal. +// follows the route's real power-on. The loss is reported when it is observed, not at the terminal +// deadline (#12423): a typed ObservationChannelLost, the incident frozen, the BMC shown answering, and +// the teardown within sixty seconds of the power action -- before the census could have printed. This +// case was pinned as reporting the loss only at the deadline until #12434's watch detected it. The final +// world shows the drop fired, so the case is not green on a run where the loss never happened. fn sol_drop_fired_in(w: MtCollins1BootWorld) -> Bool { bmc_sol_drop_fired(world: w.bmc) } -test fn pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline() -> Bool { +fn first_dispatch_second(route: List, name: String) -> Int { + match filter(route, r => operation_name(r: r) == name).first() { Present { value: r } => std.measure.second_count(s: r.dispatched_at) as Int Absent => 0 - 1 } +} + +test fn a_sol_loss_mid_boot_is_reported_before_the_deadline() -> Bool { let w = world_with_console(lines: console_of(capture: one_socket_census_capture, begin_after: 60, end_after: 240)) let dropping = with_bmc(w: w, bmc: bmc_with_sol_drop_after_boot(world: w.bmc, after: second(count: 30))) match evaluate_in_witness_frame(frame: matrix_frame(world: dropping), subject: fn(_scope) { mtcollins1_boot_wet_on_srv1() }) { WitnessReturned { value, route, state } => - string_contains(s: outcome_reason(a: value), pattern: "deadline reached without a host-capture terminal") + string_contains(s: outcome_reason(a: value), pattern: "ObservationChannelLost while the boot was being watched") + && string_contains(s: outcome_reason(a: value), pattern: "incident frozen to /run/sol.capture.loss") + && string_contains(s: outcome_reason(a: value), pattern: "BMC answered mc info") && count_named(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") == 1 + && first_dispatch_second(route: route, name: "diagnostic.ipmi.Tool.SolDeactivate") - first_dispatch_second(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") <= 60 && match state { Present { value: end } => sol_drop_fired_in(w: end) Absent => false } _ => false } diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index 22a709e6079..1a3e041ff35 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -342,6 +342,10 @@ new-witness eval-step cost gate over the one roadmap page claim that derives the new-witness eval-step cost gate over the ten interpreted P-256 and P-384 point and group-law checks and SHA-384 FIPS vectors of the App Attest path: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the P-384 and SHA-384 primitives executing as natively emitted code rather than as interpreted bignat and Word64 folds). Population: test.claim.p384_dag_ecdsa_witness_test.the_p384_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_beside_the_base_point_is_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_with_a_coordinate_at_p_is_not_admitted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.apples_ca_and_root_keys_are_on_p384: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.sha384_fips_witness_test.sha384_of_the_empty_message_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published empty message and a one-octet message on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_abc_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published abc vector and abd on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_the_896_bit_message_is_the_published_two_block_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is four SHA-384 block compressions, the published 896-bit two-block vector and a last-block mutation on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.p256_dag_ecdsa_witness_test.the_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35708011844 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, well inside the wall deadline and over the new-witness eval-step budget. The billed work is one P-256 curve equation over the published base point as 11-limb bignat folds on an interpreter that reifies no machine width. It is a MEMBER BECAUSE IT WAS SPLIT OUT of a claim that also asserted n*G = infinity: that conjunction crossed the 8000ms wall deadline and was INTERRUPTED BEFORE ANY VERDICT, so both facts were being lost; the scalar multiplication left the floor for the native row the frontier names, and this cheap half now reaches a verdict. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field, test.claim.p384_dag_ecdsa_witness_test.doubling_and_adding_the_base_point_stay_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling, one addition and two projective curve-equation checks at 16 limbs, test.claim.p384_dag_ecdsa_witness_test.doubling_an_off_curve_point_stays_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling and one projective curve-equation check at 16 limbs. Restored when: THE CAPABILITY: gunbc test //gunbc/instruments:native-crypto-vectors EXECUTING ON THE MERGE PATH, i.e. as a phase of a required lane whose red blocks a merge, running these ten identities natively (its cases p256_the_base_point_is_on_the_curve, p384_the_base_point_is_on_the_curve, p384_red_a_point_beside_the_base_point_is_off_the_curve, p384_red_a_point_with_a_coordinate_at_p_is_not_admitted, p384_doubling_and_adding_the_base_point_stay_on_the_curve, p384_red_doubling_an_off_curve_point_stays_off_the_curve, p384_apples_ca_and_root_keys_are_on_the_curve and the sha384_* FIPS cases with their reds) while each still evaluates the real curve equation or the real hash; WHAT THAT MUST BE SUFFICIENT FOR: the P-384 parameters and SHA-384 are exercised on the acceptance path with no interpreted 16-limb fold inside a claim frame, so the interpreted identities can leave the floor for that row, or they measure under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives. The same row run BY NAME (as it exists since gunbc#12306) executes the facts natively but is NOT the acceptance path and retires nothing. Supplying the curve check's answer or the digest as a fixture, or deleting the identities, satisfies neither. +### new-witness eval-step cost gate over the nine mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 + +new-witness eval-step cost gate over the nine mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_host_that_never_prints_a_census_refuses_at_the_deadline, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=167236 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_healthy_census_completes_and_releases_its_collector, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=158055 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_already_presented_image_is_not_attached_again, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=134675 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions media_that_never_becomes_ready_refuses_before_any_power_action, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=91254 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_presentation_lost_after_readiness_stops_the_handoff, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=97089 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=129921 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_sol_loss_mid_boot_is_reported_before_the_deadline, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=124297 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_two_socket_answer_is_a_truthful_topology_refusal, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=124495 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_listing_that_names_the_image_twice_starts_nothing, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=77801 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these nine identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. + ### new-witness eval-step cost gate over six App Attest verifier claims -- the two real-path inhabitance claims over Apple's objects, three single structural steps priced by their own SHA-256s, and the wire-carrier join: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 new-witness eval-step cost gate over six App Attest verifier claims -- the two real-path inhabitance claims over Apple's objects, three single structural steps priced by their own SHA-256s, and the wire-carrier join: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the CBOR, DER and SHA-256 readers executing as natively emitted code over the sample objects rather than as interpreted octet-list folds). Population: test.claim.app_attest_verifier_witness_test.the_sample_passes_every_step_before_the_extension_steps: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b 4d089af1cb9 (gunbc#11989): verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget; the billed work is the real path end to end: Apple's attestation object through decode_attestation (CBOR, two DER certificates, the PEM-pinned root, authenticator data) and the whole structural fold with its SHA-256s. It is the attestation path's one inhabitance claim, so nothing here is supplied, test.claim.app_attest_verifier_witness_test.the_nonce_step_reds_on_other_client_data: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b 4d089af1cb9 (gunbc#11989): verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget; the billed work is nonce_step alone over supplied inputs: SHA-256 of the client data and SHA-256 of authData concatenated with it, two interpreted hashes, which is the step and nothing before it, test.claim.app_attest_verifier_witness_test.the_app_id_step_reds_on_another_app_id: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b 4d089af1cb9 (gunbc#11989): verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget; the billed work is app_id_step alone over supplied inputs: one interpreted SHA-256 of the App ID, test.claim.app_attest_verifier_witness_test.the_key_id_step_admits_the_real_key_and_reds_on_another_key_id: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b (gunbc#11989), and the required floor's required-ci-measurement-receipt: verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget; the billed work is key_id_step alone over supplied inputs, paired over its own subject: one interpreted SHA-256 of the credential certificate's 65-octet public key (the second comparison reuses it), test.claim.app_attest_verifier_witness_test.the_sample_assertion_passes_rp_id_and_refuses_on_absent_extensions: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b (gunbc#11989), and the required floor's required-ci-measurement-receipt: verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget; the billed work is the assertion's real path: the assertion object through assertion_parts and the fold's RP ID SHA-256, plus the attestation's leaf certificate read for the credential key (the attestation-to-assertion join). It is the assertion path's one inhabitance claim, paired with a wrong-App-ID refusal over the same subject, test.claim.signature_verify_join_witness_test.malformed_carriers_refuse_before_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_app_attest_verifier_rows; measured by claim_batch --hermetic [witness] receipt at session/nimble-eagle-216-step3b 4d089af1cb9 (gunbc#11989): verdict pass, wall under the 8 s deadline, eval_steps read from that receipt's own line and over the new-witness budget. THIS ROW'S BILLED WORK IS NOT THE VERIFIER ROWS': it touches no Apple object, no certificate and no hash. It base64url-decodes two carriers of the RFC 6979 A.2.5 P-256 vectors through extdeps.crypto.signature verify_signature, which asks signature_carrier_refusal FIRST and refuses on size before the implementation is consulted. What the budget prices is the interpreter walking those octet lists byte by byte to decode and size them. Restored when: THE CAPABILITY. MachineWidth reification (gunbc#11819) lets the extdeps.apple.app_attest closure emit, and these six identities execute on the natively emitted route -- the gunbc test instrument row the ecdsa_verification_realization_frontier names -- while each still exercises its own production code over its own inputs -- Apple's objects end to end for the two inhabitance claims, its one named step for the three step claims, the RFC 6979 carriers for the carrier-join claim; WHAT THAT MUST BE SUFFICIENT FOR: the verifier folds are exercised over the real sample on the acceptance path, and the carrier join over its real carriers, with no interpreted octet walk inside a claim frame, and the identities then measure under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, or leave the floor for that native row. Supplying the two inhabitance claims' inputs as fixtures, precomputing a step's hashes, or deleting the identities satisfies neither. diff --git a/src/v2/workflow/floor_eval_step_cost_drop.dag b/src/v2/workflow/floor_eval_step_cost_drop.dag index 967c218d0d8..e521780e260 100644 --- a/src/v2/workflow/floor_eval_step_cost_drop.dag +++ b/src/v2/workflow/floor_eval_step_cost_drop.dag @@ -237,43 +237,47 @@ data floor_eval_step_cost_drop_python_to_typescript_inhabitance_rows: List = [ EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline" as NonEmptyStr, - measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_host_that_never_prints_a_census_refuses_at_the_deadline, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=167236 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, EvalStepCostDropMeasurement { - identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_healthy_census_is_refused_at_the_sol_teardown" as NonEmptyStr, - measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_healthy_census_completes_and_releases_its_collector, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=158055 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again" as NonEmptyStr, - measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_already_presented_image_is_not_attached_again, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=134675 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action" as NonEmptyStr, - measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions media_that_never_becomes_ready_refuses_before_any_power_action, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=91254 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff" as NonEmptyStr, - measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_presentation_lost_after_readiness_stops_the_handoff, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=97089 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause" as NonEmptyStr, - measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=129921 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, EvalStepCostDropMeasurement { - identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_sol_loss_mid_boot_is_reported_only_at_the_deadline" as NonEmptyStr, - measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_sol_loss_mid_boot_is_reported_before_the_deadline, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=124297 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal" as NonEmptyStr, - measured_by: "PR required floor run 36419407813 of gunbc#12533, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_two_socket_answer_is_a_truthful_topology_refusal, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=124495 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + }, + EvalStepCostDropMeasurement { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_listing_that_names_the_image_twice_starts_nothing, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=77801 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, ] From 45d967da2bdc3246b3e7997d7fa78ecb9c47ac26 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Wed, 30 Sep 2026 00:48:08 +0000 Subject: [PATCH 46/75] Matrix: the SOL-loss case requires exactly one teardown, after the power action and within 60 s At bd99cbb489 first_dispatch_second returned -1 when a dispatch was absent, so an absent teardown, or one before the power action, satisfied the delta bound (side-chat hold on #12533). Both instants are now Optional, the delay must exist and be nonnegative, and the route must carry exactly one SolDeactivate after the power action. Co-Authored-By: Claude Opus 5.5 (1M context) --- ...mtcollins1_boot_acceptance_matrix_test.dag | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index c3caf077966..13db7c2ddf0 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -426,8 +426,21 @@ fn sol_drop_fired_in(w: MtCollins1BootWorld) -> Bool { bmc_sol_drop_fired(world: w.bmc) } -fn first_dispatch_second(route: List, name: String) -> Int { - match filter(route, r => operation_name(r: r) == name).first() { Present { value: r } => std.measure.second_count(s: r.dispatched_at) as Int Absent => 0 - 1 } +fn first_dispatch_second(route: List, name: String) -> Int? { + match filter(route, r => operation_name(r: r) == name).first() { Present { value: r } => Present { value: std.measure.second_count(s: r.dispatched_at) as Int } Absent => none } +} + +// The teardown's delay after the power action, required to exist on both ends -- an absent deactivate +// or power action is not a zero -- and to be nonnegative and at most `bound` seconds (review of #12533 +// at bd99cbb489: a -1 sentinel let an absent or early teardown pass). +fn teardown_within(route: List, bound: Int) -> Bool { + match first_dispatch_second(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") { + Absent => false + Present { value: power } => match first_dispatch_second(route: route, name: "diagnostic.ipmi.Tool.SolDeactivate") { + Absent => false + Present { value: torn } => torn - power >= 0 && torn - power <= bound + } + } } test fn a_sol_loss_mid_boot_is_reported_before_the_deadline() -> Bool { @@ -439,7 +452,9 @@ test fn a_sol_loss_mid_boot_is_reported_before_the_deadline() -> Bool { && string_contains(s: outcome_reason(a: value), pattern: "incident frozen to /run/sol.capture.loss") && string_contains(s: outcome_reason(a: value), pattern: "BMC answered mc info") && count_named(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") == 1 - && first_dispatch_second(route: route, name: "diagnostic.ipmi.Tool.SolDeactivate") - first_dispatch_second(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") <= 60 + && count_named(route: route, name: "diagnostic.ipmi.Tool.SolDeactivate") == 1 + && first_ordinal(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") < first_ordinal(route: route, name: "diagnostic.ipmi.Tool.SolDeactivate") + && teardown_within(route: route, bound: 60) && match state { Present { value: end } => sol_drop_fired_in(w: end) Absent => false } _ => false } From a67a3dcf220b9771951b67eb3036bcca9fc393b9 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Wed, 30 Sep 2026 01:35:57 +0000 Subject: [PATCH 47/75] Matrix: six cases admitted to the enrolment dead band under one declared drop; two eval-step rows Side-chat ruling (eager-owl-205, 2026-09-30): the six cases CI measured strictly above the 302 ms enrolment margin and under the 500 ms line (396, 394, 378, 361, 339, 332 ms, run 36648847499) are rostered in v2.workflow.floor_enrolment_dead_band, self-staling both ways, under the declared drop gunbc.rung_drop.mtcollins1_boot_matrix_enrolment_dead_band_observed_only. Its population derives from those rows, and its trigger names the one capability both matrix drops wait on, now a single row (mtcollins1_boot_matrix_native_witness_capability) that the eval-step drop also reads. The CPU is #12434's own polling route run faithfully; ablation found no model hotspot. The eval-step drop gains the interrupted-attempt and wrong-share cases (74,419 and 77,423 on CI), eleven rows. Rung-drop and enrolment witnesses 19/19 PASS; docs/design-rung-drops.md regenerated. Co-Authored-By: Claude Opus 5.5 (1M context) --- ...trix_enrolment_dead_band_observed_only.dag | 44 +++++++++++++++++++ ...boot_matrix_new_witness_eval_step_cost.dag | 11 +++-- dag/gunbc/rung_drop/roster.dag | 2 + docs/design-rung-drops.md | 8 +++- src/v2/workflow/floor_enrolment_dead_band.dag | 34 +++++++++++++- src/v2/workflow/floor_eval_step_cost_drop.dag | 14 ++++-- 6 files changed, 104 insertions(+), 9 deletions(-) create mode 100644 dag/gunbc/rung_drop/mtcollins1_boot_matrix_enrolment_dead_band_observed_only.dag diff --git a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_enrolment_dead_band_observed_only.dag b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_enrolment_dead_band_observed_only.dag new file mode 100644 index 00000000000..934575ee04b --- /dev/null +++ b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_enrolment_dead_band_observed_only.dag @@ -0,0 +1,44 @@ +module gunbc.rung_drop.mtcollins1_boot_matrix_enrolment_dead_band_observed_only + +import std.types { NonEmptyStr, List, String } +import gunbc.rung_drop { RungDrop, Standing, TypedDeclaration, ReplacementStaged } +import gunbc.guarantee_rung { Mitigatable, MechanicallyPreventable } +import gunbc.rung_drop.mtcollins1_boot_matrix_new_witness_eval_step_cost { mtcollins1_boot_matrix_native_witness_capability } +import v2.workflow.floor_enrolment_dead_band { mtcollins1_boot_matrix_enrolment_dead_band_observed_only } + +// THE DECLARED RUNG DROP for the enrolment margin over the mtcollins1 boot matrix cases whose honest +// CPU lies in the gate's dead band (margin, per-subject line] (DESIGN 4b(3); side-chat ruling of +// eager-owl-205 on gunbc#12533, 2026-09-30; precedent `app_attest_verifier_enrolment_dead_band_observed_only`). +// The POPULATION's authority is `v2.workflow.floor_enrolment_dead_band` +// `mtcollins1_boot_matrix_enrolment_dead_band_observed_only`, each row carrying its CI-observed CPU. +// +// WHAT IS LOST IS THE ENROLMENT-MARGIN DECISION, AND ONLY THAT. The cases stay test fns and execute on +// every required floor that plans them; a semantic red, a runtime error, a route gap, a wall +// interruption and a missing terminal stay armed, and the eval-step overrun is the sibling drop's. The +// authority is self-staling on both sides: at or under the margin a row blocks as +// enrolment_dead_band_stale, above the line as enrolment_dead_band_wrong_ground. +// +// WHY THE COST IS NOT CUT: it is the subject. Each case runs the real entry, and the CPU above the +// margin is gunbc#12434's own SOL polling route -- watch ticks reading the pid file, /proc and the +// capture -- answered faithfully by the dry realization; an ablation on the merged tree found no model +// hotspot (a stubbed advance only shortened the route). The restoration is the same capability as the +// eval-step drop's, named once in `mtcollins1_boot_matrix_native_witness_capability`. +data mtcollins1_boot_matrix_enrolment_dead_band_observed_only_population: List = mtcollins1_boot_matrix_enrolment_dead_band_observed_only() |> map(o => concat(concat(o.identity, ": "), o.reason as String)) + +data mtcollins1_boot_matrix_enrolment_dead_band_observed_only_drop: RungDrop = RungDrop { + identity: "mtcollins1_boot_matrix_enrolment_dead_band_observed_only" as NonEmptyStr, + + subject: "the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided", + + declared: "2026-09-30", + + standing: Standing, + + declaration: TypedDeclaration { + previous: MechanicallyPreventable, + temporary: Mitigatable, + reason: ReplacementStaged { replacement: "the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on" }, + population: mtcollins1_boot_matrix_enrolment_dead_band_observed_only_population, + restoration_trigger: concat(concat("THE CAPABILITY: ", mtcollins1_boot_matrix_native_witness_capability), "; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither."), + } +} diff --git a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag index 2ab9f02ae62..3dc77e7bf87 100644 --- a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag +++ b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag @@ -9,7 +9,7 @@ import v2.workflow.floor_eval_step_cost_drop { floor_eval_step_cost_drop_boot_ma // matrix, msg_83af891b). The DECLARATION lives here; the POPULATION's authority is // `v2.workflow.floor_eval_step_cost_drop` `floor_eval_step_cost_drop_boot_matrix_rows`. // -// WHAT IS LOST IS ONE WALL, AND THE CLAIMS ARE UNTOUCHED. The nine identities are planned, executed +// WHAT IS LOST IS ONE WALL, AND THE CLAIMS ARE UNTOUCHED. The eleven identities are planned, executed // and measured on every pull request that edits them; a semantic red and a wall-clock crossing still // block. Only the eval-step overrun is reported as `EvalStepsOverBudgetUnderDeclaredDrop` rather than // refusing. The budget is not raised. Their CPU stays under the enrolment margin, so they enrol @@ -31,10 +31,15 @@ import v2.workflow.floor_eval_step_cost_drop { floor_eval_step_cost_drop_boot_ma // the 72,300 budget. So hoisting it neither retires this drop nor removes a member, and none is owed. data mtcollins1_boot_matrix_new_witness_eval_step_cost_population: List = floor_eval_step_cost_drop_boot_matrix_rows |> map(m => concat(concat(m.identity, ": over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by "), m.measured_by)) +// THE ONE CAPABILITY that retires both matrix cost drops -- this one and +// `gunbc.rung_drop.mtcollins1_boot_matrix_enrolment_dead_band_observed_only` -- named once so the two +// cannot drift apart: the cost of both is the seed interpreter running the real entry. +data mtcollins1_boot_matrix_native_witness_capability: String = "witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry" + data mtcollins1_boot_matrix_new_witness_eval_step_cost: RungDrop = RungDrop { identity: "mtcollins1_boot_matrix_new_witness_eval_step_cost" as NonEmptyStr, - subject: "new-witness eval-step cost gate over the nine mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered", + subject: "new-witness eval-step cost gate over the eleven mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered", declared: "2026-09-28", @@ -47,6 +52,6 @@ data mtcollins1_boot_matrix_new_witness_eval_step_cost: RungDrop = RungDrop { replacement: "the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter", }, population: mtcollins1_boot_matrix_new_witness_eval_step_cost_population, - restoration_trigger: "THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these nine identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither.", + restoration_trigger: concat(concat("THE CAPABILITY: ", mtcollins1_boot_matrix_native_witness_capability), "; WHAT THAT MUST BE SUFFICIENT FOR: each of these eleven identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither."), } } diff --git a/dag/gunbc/rung_drop/roster.dag b/dag/gunbc/rung_drop/roster.dag index e371113dfe5..1cf21185ecd 100644 --- a/dag/gunbc/rung_drop/roster.dag +++ b/dag/gunbc/rung_drop/roster.dag @@ -95,6 +95,7 @@ import gunbc.rung_drop.app_attest_interpreted_crypto_new_witness_eval_step_cost import gunbc.rung_drop.mtcollins1_boot_matrix_new_witness_eval_step_cost { mtcollins1_boot_matrix_new_witness_eval_step_cost } import gunbc.rung_drop.app_attest_verifier_new_witness_eval_step_cost { app_attest_verifier_new_witness_eval_step_cost } import gunbc.rung_drop.app_attest_verifier_enrolment_dead_band_observed_only { app_attest_verifier_enrolment_dead_band_observed_only } +import gunbc.rung_drop.mtcollins1_boot_matrix_enrolment_dead_band_observed_only { mtcollins1_boot_matrix_enrolment_dead_band_observed_only_drop } import gunbc.rung_drop.sha256_span_program_serialize_new_witness_eval_step_cost { sha256_span_program_serialize_new_witness_eval_step_cost } import gunbc.rung_drop.v41_row_store_host_realized_by_sample { v41_row_store_host_realized_by_sample } import gunbc.rung_drop.seam_monolith_control_unmeasured_derived_root { seam_monolith_control_unmeasured_derived_root } @@ -189,6 +190,7 @@ data rung_drop_roster: List = [ mtcollins1_boot_matrix_new_witness_eval_step_cost, app_attest_verifier_new_witness_eval_step_cost, app_attest_verifier_enrolment_dead_band_observed_only, + mtcollins1_boot_matrix_enrolment_dead_band_observed_only_drop, sha256_span_program_serialize_new_witness_eval_step_cost, v41_row_store_host_realized_by_sample, seam_monolith_control_unmeasured_derived_root, diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index 1a3e041ff35..025cf621baa 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -342,9 +342,9 @@ new-witness eval-step cost gate over the one roadmap page claim that derives the new-witness eval-step cost gate over the ten interpreted P-256 and P-384 point and group-law checks and SHA-384 FIPS vectors of the App Attest path: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the P-384 and SHA-384 primitives executing as natively emitted code rather than as interpreted bignat and Word64 folds). Population: test.claim.p384_dag_ecdsa_witness_test.the_p384_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_beside_the_base_point_is_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_with_a_coordinate_at_p_is_not_admitted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.apples_ca_and_root_keys_are_on_p384: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.sha384_fips_witness_test.sha384_of_the_empty_message_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published empty message and a one-octet message on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_abc_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published abc vector and abd on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_the_896_bit_message_is_the_published_two_block_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is four SHA-384 block compressions, the published 896-bit two-block vector and a last-block mutation on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.p256_dag_ecdsa_witness_test.the_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35708011844 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, well inside the wall deadline and over the new-witness eval-step budget. The billed work is one P-256 curve equation over the published base point as 11-limb bignat folds on an interpreter that reifies no machine width. It is a MEMBER BECAUSE IT WAS SPLIT OUT of a claim that also asserted n*G = infinity: that conjunction crossed the 8000ms wall deadline and was INTERRUPTED BEFORE ANY VERDICT, so both facts were being lost; the scalar multiplication left the floor for the native row the frontier names, and this cheap half now reaches a verdict. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field, test.claim.p384_dag_ecdsa_witness_test.doubling_and_adding_the_base_point_stay_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling, one addition and two projective curve-equation checks at 16 limbs, test.claim.p384_dag_ecdsa_witness_test.doubling_an_off_curve_point_stays_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling and one projective curve-equation check at 16 limbs. Restored when: THE CAPABILITY: gunbc test //gunbc/instruments:native-crypto-vectors EXECUTING ON THE MERGE PATH, i.e. as a phase of a required lane whose red blocks a merge, running these ten identities natively (its cases p256_the_base_point_is_on_the_curve, p384_the_base_point_is_on_the_curve, p384_red_a_point_beside_the_base_point_is_off_the_curve, p384_red_a_point_with_a_coordinate_at_p_is_not_admitted, p384_doubling_and_adding_the_base_point_stay_on_the_curve, p384_red_doubling_an_off_curve_point_stays_off_the_curve, p384_apples_ca_and_root_keys_are_on_the_curve and the sha384_* FIPS cases with their reds) while each still evaluates the real curve equation or the real hash; WHAT THAT MUST BE SUFFICIENT FOR: the P-384 parameters and SHA-384 are exercised on the acceptance path with no interpreted 16-limb fold inside a claim frame, so the interpreted identities can leave the floor for that row, or they measure under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives. The same row run BY NAME (as it exists since gunbc#12306) executes the facts natively but is NOT the acceptance path and retires nothing. Supplying the curve check's answer or the digest as a fixture, or deleting the identities, satisfies neither. -### new-witness eval-step cost gate over the nine mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 +### new-witness eval-step cost gate over the eleven mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 -new-witness eval-step cost gate over the nine mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_host_that_never_prints_a_census_refuses_at_the_deadline, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=167236 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_healthy_census_completes_and_releases_its_collector, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=158055 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_already_presented_image_is_not_attached_again, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=134675 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions media_that_never_becomes_ready_refuses_before_any_power_action, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=91254 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_presentation_lost_after_readiness_stops_the_handoff, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=97089 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=129921 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_sol_loss_mid_boot_is_reported_before_the_deadline, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=124297 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_two_socket_answer_is_a_truthful_topology_refusal, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=124495 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_listing_that_names_the_image_twice_starts_nothing, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=77801 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running these nine identities with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each case measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. +new-witness eval-step cost gate over the eleven mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_host_that_never_prints_a_census_refuses_at_the_deadline, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=167236 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_healthy_census_completes_and_releases_its_collector, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=158055 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_already_presented_image_is_not_attached_again, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=134675 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions media_that_never_becomes_ready_refuses_before_any_power_action, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=91254 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_presentation_lost_after_readiness_stops_the_handoff, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=97089 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=129921 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_sol_loss_mid_boot_is_reported_before_the_deadline, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=124297 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_two_socket_answer_is_a_truthful_topology_refusal, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=124495 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_listing_that_names_the_image_twice_starts_nothing, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=77801 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_an_interrupted_attempt_locks_out_the_next_one: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899, the COMPLETED-OVER-COST-REQUIREMENT line for this identity: verdict pass, eval_steps=74419 against the 72,300 new-witness budget, crossed once #12434's route was bound; the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899, the COMPLETED-OVER-COST-REQUIREMENT line for this identity: verdict pass, eval_steps=77423 against the 72,300 new-witness budget, crossed once #12434's route was bound; the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each of these eleven identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. ### new-witness eval-step cost gate over six App Attest verifier claims -- the two real-path inhabitance claims over Apple's objects, three single structural steps priced by their own SHA-256s, and the wire-carrier join: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 @@ -354,6 +354,10 @@ new-witness eval-step cost gate over six App Attest verifier claims -- the two r the enrolment-margin decision over exactly two App Attest verifier claims whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: a general dead-band standing in v2.workflow.floor_enrolment_margin, or these two identities executing with stable headroom below the margin). Population: test.claim.app_attest_verifier_witness_test.the_key_id_step_admits_the_real_key_and_reds_on_another_key_id, test.claim.app_attest_verifier_witness_test.the_sample_assertion_passes_rp_id_and_refuses_on_absent_extensions. Restored when: THE CAPABILITY, EITHER OF TWO: (a) these EXACT two identities execute on a named native route (the gunbc test instrument row gunbc.auth.approval_device_redemption ecdsa_verification_realization_frontier names) with stable headroom below the enrolment margin across the envelope floor_enrolment_margin derives; or (b) a general repair of the dead-band policy in v2.workflow.floor_enrolment_margin gives every newly enrolled identity in the band a representable standing (gunbc.recurring_failure_mode enrolment_dead_band_has_no_representable_standing). MachineWidth reification or the native frontier ALONE does not retire this row: what must hold is that the two readings are under the margin with headroom, or that the policy no longer needs an exact-identity authority. v2.workflow.floor_enrolment_dead_band and this row then delete together. +### the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided — declared 2026-09-30 + +the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 396 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 394 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 378 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 361 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 339 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 332 ms CPU, strictly above the 302 ms margin and under the 500 ms line. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. + ### new-witness eval-step cost gate over the one claim that inhabits the real byte-span argv with its really-serialized program: it still executes, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 new-witness eval-step cost gate over the one claim that inhabits the real byte-span argv with its really-serialized program: it still executes, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the serialized byte-span program reaching a claim frame as a served value rather than being re-rendered inside it, or a serialization that fits the budget). Population: test.claim.spark.v41_checkpoint_materialize_witness.the_span_read_reads_exactly_its_region: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_span_program_rows; measured by gunbc#12010, claim_batch over dag/test/claim/spark/v41_checkpoint_materialize_witness_test.dag; planned_as_changed_witness, verdict pass, over the new-witness budget. The billed work is the one real serialization of gunbc.sha256sum_byte_span sha256sum_byte_span_program through gunbc.shell_command_text, which this claim is the argv's only inhabitance route for. Restored when: THE CAPABILITY, EITHER CLAUSE SATISFIES IT, AND BOTH ARE STATED BECAUSE THE CAUSE IS NOT YET ESTABLISHED. (i) gunbc.sha256sum_byte_span sha256sum_byte_span_program is served across claim frames by v2.workflow.floor_pure_producer_share on the acceptance path; WHAT THAT MUST BE SUFFICIENT FOR: a required-floor claim asserting the real byte-span argv carries the really-serialized program does not re-render it inside its own frame. A share row not covering this identity's demand does not satisfy this clause. OR (ii) v2.workflow.bash_command_fold_serialize serializes a fourteen-word statement list inside the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives -- whether by repair of a cost-shape defect there or by any other means. IN EITHER CASE this identity must measure under that budget WHILE STILL EXECUTING the real serialization route. Deleting the identity, supplying the program as a fixture, asserting only length(argv), or relocating it to a home that does not execute it satisfies neither clause. diff --git a/src/v2/workflow/floor_enrolment_dead_band.dag b/src/v2/workflow/floor_enrolment_dead_band.dag index b5c7fe1e6e7..592bebfa025 100644 --- a/src/v2/workflow/floor_enrolment_dead_band.dag +++ b/src/v2/workflow/floor_enrolment_dead_band.dag @@ -40,6 +40,38 @@ fn app_attest_verifier_enrolment_dead_band_observed_only() -> List List { + [ + EnrolmentDeadBandObservation { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline", + reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 396 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, + }, + EnrolmentDeadBandObservation { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector", + reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 394 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, + }, + EnrolmentDeadBandObservation { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause", + reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 378 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, + }, + EnrolmentDeadBandObservation { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again", + reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 361 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, + }, + EnrolmentDeadBandObservation { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal", + reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 339 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, + }, + EnrolmentDeadBandObservation { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline", + reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 332 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, + }, + ] +} + fn enrolment_dead_band_identities() -> List { - app_attest_verifier_enrolment_dead_band_observed_only() |> map(o => o.identity) + concat(app_attest_verifier_enrolment_dead_band_observed_only(), mtcollins1_boot_matrix_enrolment_dead_band_observed_only()) |> map(o => o.identity) } diff --git a/src/v2/workflow/floor_eval_step_cost_drop.dag b/src/v2/workflow/floor_eval_step_cost_drop.dag index e521780e260..2c782630853 100644 --- a/src/v2/workflow/floor_eval_step_cost_drop.dag +++ b/src/v2/workflow/floor_eval_step_cost_drop.dag @@ -237,10 +237,10 @@ data floor_eval_step_cost_drop_python_to_typescript_inhabitance_rows: List = [ EvalStepCostDropMeasurement { @@ -279,6 +279,14 @@ data floor_eval_step_cost_drop_boot_matrix_rows: List Date: Wed, 30 Sep 2026 01:39:50 +0000 Subject: [PATCH 48/75] SOL establishment allowance is a monotonic deadline on /proc/uptime, not a count of polls Co-Authored-By: Claude Opus 5.5 (1M context) --- .../machine_intake/mtcollins1_boot_run.dag | 48 ++++++++++++++----- .../mtcollins1_boot_run_witness_test.dag | 18 ++++++- .../sol_hold_stdin_wet_witness_test.dag | 2 +- 3 files changed, 54 insertions(+), 14 deletions(-) diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_run.dag b/dag/gunbc/machine_intake/mtcollins1_boot_run.dag index b42eed74fd2..3d7ff7a8daf 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_run.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_run.dag @@ -14,7 +14,7 @@ import std.temporal_effect { held_lease_observed_verdict, } import std.algebra { trim } -import std.measure { Second, second, second_count, Minute, minute, HardwareThreadCount, hardware_thread_count_value, ByteSize, byte_size, byte_size_count } +import std.measure { Second, second, second_count, Millisecond, millisecond, millisecond_count, Minute, minute, HardwareThreadCount, hardware_thread_count_value, ByteSize, byte_size, byte_size_count } import std.checked_arithmetic { checked_int_to_nat } import std.process { ProcessExit, ExitSuccess, ExitFailure, exit_failure } import gunbc.machine_intake_mtcollins1_census_medium_readback { @@ -39,7 +39,7 @@ import gunbc.machine_intake_mtcollins1_boot_phase_timing { MtCollins1PhaseRunResult, PhaseVerified, PhaseRefused, MtCollins1PhaseStep, PhaseStepRan, PhaseStepSkipped, MtCollins1BootRoute, mtcollins1_boot_phase_timing_of, mtcollins1_boot_route_sol_refused, mtcollins1_smpro_pass_result, } -import extdeps.linux.proc_uptime { proc_uptime_read } +import extdeps.linux.proc_uptime { proc_uptime_read, UptimeObserved, UptimeRefused } import gunbc.machine_intake_oob_boot_handoff { oob_power_readback_allowance } import gunbc.machine_intake_mtcollins1_boot_milestone { MtCollins1BootTopologyExpectation, mtcollins1_boot_topology_expectation, @@ -110,10 +110,10 @@ data mtcollins1_boot_receipt_path: String = "artifacts/mtcollins1-boot-receipt.t data mtcollins1_boot_poll_cadence: Second = second(count: 15) -// The acquisition's establishment allowance (mtcollins1_sol_await_establishment), counted in POLLS: that -// many observations one second apart, each also paying its own reads and scheduling, so it is not a -// strict wall-clock deadline. The RMCP+ session setup and Activate Payload exchange take a few seconds. -// Paid inside the prelude allowance, which covers the acquisition. +// The acquisition's establishment allowance (mtcollins1_sol_await_establishment): a monotonic deadline +// measured on /proc/uptime from the start of the wait, polled about once a second. The RMCP+ session +// setup and Activate Payload exchange take a few seconds. Paid inside the prelude allowance, which +// covers the acquisition. data mtcollins1_boot_sol_establish_allowance: Second = second(count: 15) data mtcollins1_boot_prelude_allowance: Second = second(count: 120) @@ -512,6 +512,7 @@ type SolEstablishmentFailure | SolCollectorLeftUnexplained { collector: SolCollectorObservation, last_line: String } | SolActivationUnconfirmed { collector: SolCollectorObservation, allowance: Second } | SolActivationUnrecorded { detail: String } + | SolEstablishmentClockUnread { detail: String } | SolAdoptedActivationUnproven { collector: SolCollectorObservation, receipt: String } fn last_nonempty_line(s: String) -> String { @@ -547,6 +548,7 @@ fn sol_establishment_failure_text(failure: SolEstablishmentFailure) -> String { SolSessionRefused { cause: c } => bmc_read_cause_text(cause: c) SolCollectorLeftUnexplained { collector: o, last_line: l } => concat(sol_collector_observation_text(observation: o), "; its last line: ", if l == "" { "(none)" } else { l }) SolActivationUnconfirmed { collector: o, allowance: a } => concat(sol_collector_observation_text(observation: o), concat(", but the session did not print its operational banner within ", concat(to_string(second_count(s: a)), " s, so activation is unconfirmed"))) + SolEstablishmentClockUnread { detail: d } => concat("the establishment deadline could not be measured, so activation is unconfirmed: ", d) SolActivationUnrecorded { detail: d } => concat("the banner was seen but the activation receipt could not be recorded: ", d) SolAdoptedActivationUnproven { collector: o, receipt: r } => concat(sol_collector_observation_text(observation: o), concat("; no activation receipt names this instance, so an adopted collector is not taken as established (receipt: ", concat(if r == "" { "(none)" } else { r }, ")"))) }) @@ -597,7 +599,7 @@ fn mtcollins1_sol_activate_held( if !spawned.success { return exit_failure(reason: concat(dissolution_description(condition: mtcollins1_sol_hold_shell_emit_dissolution_trigger), concat(" ", sol_establishment_failure_text(failure: SolSpawnRefused { detail: concat(trim(s: spawned.transport_stderr), concat(" ", trim(s: spawned.stdout))) })))) } - match mtcollins1_sol_await_establishment(pid_path: pid_path, capture_path: capture_path, remaining: second_count(s: mtcollins1_boot_sol_establish_allowance) as Int) { + match mtcollins1_sol_await_establishment(pid_path: pid_path, capture_path: capture_path, allowance: mtcollins1_boot_sol_establish_allowance) { SolEstablished { at: _ } => ExitSuccess SolNotEstablished { failure: f } => exit_failure(reason: concat(sol_establishment_failure_text(failure: f), concat("; not deactivating a session this hold did not establish; client diagnostics: ", client_diagnostic_path))) @@ -631,7 +633,27 @@ fn sol_capture_opens_with_banner(capture: String) -> Bool { // publication pending, not a failure. The hold's own words end the wait early: its "pid not published" // line is SolPidNotPublished, and an exit record with nothing published is a collector that left. At // the deadline an unpublished collector is SolActivationUnconfirmed with that observation. -fn mtcollins1_sol_await_establishment(pid_path: String, capture_path: String, remaining: Int) -> SolEstablishment { +// THE ALLOWANCE IS A MONOTONIC DEADLINE, not a count of polls. The deadline is the /proc/uptime reading +// at the start of the wait plus the allowance, and each poll compares a fresh reading against it +// (sol_establishment_expired), so the time the wait grants does not depend on how long a poll takes: +// fast polls do not exhaust it early and slow polls do not stretch it. An unreadable clock refuses +// with its cause (SolEstablishmentClockUnread) rather than falling back to counting. +fn sol_establishment_deadline_ms(start: Millisecond, allowance: Second) -> Nat { + millisecond_count(m: start) + second_count(s: allowance) * 1000 +} + +fn sol_establishment_expired(now: Millisecond, deadline_ms: Nat) -> Bool { + millisecond_count(m: now) >= deadline_ms +} + +fn mtcollins1_sol_await_establishment(pid_path: String, capture_path: String, allowance: Second) -> SolEstablishment { + match proc_uptime_read() { + UptimeRefused { detail: d } => SolNotEstablished { failure: SolEstablishmentClockUnread { detail: d } } + UptimeObserved { uptime: u } => sol_await_establishment_until(pid_path: pid_path, capture_path: capture_path, allowance: allowance, deadline_ms: sol_establishment_deadline_ms(start: u, allowance: allowance)) + } +} + +fn sol_await_establishment_until(pid_path: String, capture_path: String, allowance: Second, deadline_ms: Nat) -> SolEstablishment { let at = clock_now_probed_at_or_unknown() let collector = mtcollins1_sol_collector_observe(pid_path: pid_path) let pending = match collector { @@ -657,11 +679,15 @@ fn mtcollins1_sol_await_establishment(pid_path: String, capture_path: String, re let client = Filesystem.Read(path: mtcollins1_sol_client_diagnostic_path(capture_path: capture_path)) return SolNotEstablished { failure: sol_establishment_failure(collector: collector, client_diagnostics: if client.success { client.content } else { "" }, at: at) } } - if remaining <= 0 { - return SolNotEstablished { failure: SolActivationUnconfirmed { collector: collector, allowance: mtcollins1_boot_sol_establish_allowance } } + let expired = match proc_uptime_read() { + UptimeRefused { detail: d } => return SolNotEstablished { failure: SolEstablishmentClockUnread { detail: d } } + UptimeObserved { uptime: n } => sol_establishment_expired(now: n, deadline_ms: deadline_ms) + } + if expired { + return SolNotEstablished { failure: SolActivationUnconfirmed { collector: collector, allowance: allowance } } } let _paced = sleep_delay_seconds_second_carrier_projection(duration: second(count: 1)) - mtcollins1_sol_await_establishment(pid_path: pid_path, capture_path: capture_path, remaining: remaining - 1) + sol_await_establishment_until(pid_path: pid_path, capture_path: capture_path, allowance: allowance, deadline_ms: deadline_ms) } // THE ACTIVATION RECEIPT IS BOUND TO THE INSTANCE. Once the banner is seen for the held collector, its diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_run_witness_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_run_witness_test.dag index b970bfaac27..0093b7faf92 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_run_witness_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_run_witness_test.dag @@ -1,12 +1,12 @@ module test.claim.machine_intake.mtcollins1_boot_run_witness_test import gunbc.machine_intake_mtcollins1_sol_notice { SolNotice, SolNoticeCollectorExited, sol_loss_notice_of, sol_exit_notices_of, sol_notice_annotation, SolSourceRead, SolSourceAbsent, SolSourceUnreadable } -import gunbc.machine_intake_mtcollins1_boot_run { sol_observer_refusal_of, ProcRead, ProcReadRefused } +import gunbc.machine_intake_mtcollins1_boot_run { sol_observer_refusal_of, ProcRead, ProcReadRefused, sol_establishment_deadline_ms, sol_establishment_expired } import extdeps.github.log_annotations { log_annotation_message_line } import gunbc.machine_intake_megarac_media_attach { megarac_convergence_allowance, megarac_presentation_look_allowance } import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } import std.types { Bool, Int, List, NonEmptyStr, String } -import std.measure { byte_size_count, second_count, minute_count, hardware_thread_count, hardware_thread_count_value } +import std.measure { byte_size_count, second_count, minute_count, hardware_thread_count, hardware_thread_count_value, millisecond, second } import v2.std.optional { Present } import gunbc.machine_intake_oob_boot_handoff { oob_power_readback_allowance } import gunbc.machine_intake_mtcollins1_boot_run { @@ -998,3 +998,17 @@ test fn the_boot_requires_the_recorded_live_watcher() -> Bool { (match ok { Present { value: _ } => false _ => true }) && [gone, reused, zombie, unread_stat, unread_record, empty].all(r => match r { Present { value: why } => string_contains(s: why, pattern: "the SOL notice watcher is required before a further BMC effect") _ => false }) } + +// THE ESTABLISHMENT ALLOWANCE IS ELAPSED TIME, NOT A POLL COUNT, in both directions, over supplied uptime +// instants. Twenty fast polls 100 ms apart -- twice a ten-poll count -- are all inside a ten-second +// allowance, so none has expired; three slow polls four seconds apart pass the deadline at the third +// though a ten-poll count would still have seven to go. The start is an arbitrary uptime reading. +test fn the_establishment_allowance_is_elapsed_time_not_a_poll_count() -> Bool { + let start = 350735470 + let deadline = sol_establishment_deadline_ms(start: millisecond(count: start), allowance: second(count: 10)) + let fast = map([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], i => sol_establishment_expired(now: millisecond(count: start + i * 100), deadline_ms: deadline)) + let slow = map([1, 2, 3], i => sol_establishment_expired(now: millisecond(count: start + i * 4000), deadline_ms: deadline)) + deadline == start + 10000 + && fast.all(e => !e) + && slow == [false, false, true] +} diff --git a/dag/test/claim/machine_intake/sol_hold_stdin_wet_witness_test.dag b/dag/test/claim/machine_intake/sol_hold_stdin_wet_witness_test.dag index d1fdc4a0c61..5b406cde2f7 100644 --- a/dag/test/claim/machine_intake/sol_hold_stdin_wet_witness_test.dag +++ b/dag/test/claim/machine_intake/sol_hold_stdin_wet_witness_test.dag @@ -259,7 +259,7 @@ fn refused_probe() -> String { fn establishment(script: String) -> SolEstablishment { let dir = scratch_dir() let run = probe_launch(dir: dir, script: script, pid_path: concat(dir, "/collector.pid")) - let e = if run.launched { mtcollins1_sol_await_establishment(pid_path: run.pid_path, capture_path: run.capture_path, remaining: 10) } else { SolNotEstablished { failure: SolActivationUnconfirmed { collector: SolCollectorUnrecorded, allowance: second(count: 0) } } } + let e = if run.launched { mtcollins1_sol_await_establishment(pid_path: run.pid_path, capture_path: run.capture_path, allowance: second(count: 10)) } else { SolNotEstablished { failure: SolActivationUnconfirmed { collector: SolCollectorUnrecorded, allowance: second(count: 0) } } } let _stopped = gunbc.machine_intake.sol_hold.ReleaseHeld(pid_path: run.pid_path as NonEmptyStr).success let _removed = shell.Remove.RecursiveForce(path: dir) e From 82ec7d4d605275794e3d4e744ccadb5ad52eb75a Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Wed, 30 Sep 2026 02:13:14 +0000 Subject: [PATCH 49/75] Integrate #12636: uptime answers over the file transport; one path resolution for wet and modeled #12636 binds linux.Procfs ReadUptime to the file transport with its path as a literal in the transport, not an input. The modeled file arm read the path from the inputs, a second and narrower route to the fact the wet dispatch resolves from the transport, and refused every matrix case at the uptime read. file_transport_path is now the one resolution both arms use (rostered in gunbc.modeled_operation_realization_seed_growth), and the dry uptime handler answers FileObserved with the record's final newline, the byte #12636 exists to keep. Re-measured on the merged tree: 51/51 PASS. The interrupted-attempt case is back under 72,300 (70,000) and leaves the eval-step drop; ten rows, each at this tree. Rung-drop and enrolment witnesses 19/19; docs/design-rung-drops.md regenerated. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../mtcollins1_boot_dry_realization.dag | 11 +++-- ...eled_operation_realization_seed_growth.dag | 1 + ...boot_matrix_new_witness_eval_step_cost.dag | 8 ++-- docs/design-rung-drops.md | 4 +- src/v1/stage0/src/v1_interpreter.rs | 40 +++++++++++++------ src/v2/workflow/floor_eval_step_cost_drop.dag | 30 ++++++-------- 6 files changed, 55 insertions(+), 39 deletions(-) diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag index 40d603ef75a..328db81e665 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag @@ -6,13 +6,14 @@ import std.algebra { trim } import v2.std.operation_argv { OperationRef } import v2.std.operation_realization { OperationRealization, OperationBinding, OperationCall, OperationStep, - OperationObserved, OperationHarnessFault, ShellObserved, + OperationObserved, OperationHarnessFault, ShellObserved, FileObserved, virtual_delay_binding, operation_input_text, } import gunbc.bmc_model { BmcWorld, bmc_advance, bmc_with_sol_session, bmc_power_is_on } import gunbc.bmc_dry_realization { bmc_bindings, megarac_bindings, bmc_ipmi_operation, sleep_delay_seconds_operation } import gunbc.megarac_media_model { MegaRacMediaWorld, megarac_media_advance } -import gunbc.filesystem_model { ModeledFilesystem, ModeledFile, filesystem_bindings, fs_with_file, fs_file, fs_write } +import gunbc.filesystem_model { ModeledFilesystem, ModeledFile, filesystem_bindings, fs_with_file, fs_file, fs_write, content_bytes } +import extdeps.transports.file { FileOperationSucceeded } import gunbc.process_environment_model { ModeledVariable, environment_binding } import gunbc.host_command_model { ModeledInvocation, exact_invocation_binding, local_command_words, shell_exec_run_argv_operation } import extdeps.transports.shell { ShellExchangeObservation, ShellProcessExited } @@ -282,7 +283,8 @@ fn smpro_refused_handler(w: MtCollins1BootWorld, call: OperationCall) -> Operati } } -// /proc/uptime: the worker's seconds since its own boot, `. ` (proc(5)). +// /proc/uptime: the worker's seconds since its own boot, `. ` and one newline +// (proc(5)), read over the file transport since gunbc#12636, so the record keeps its final newline. data linux_procfs_read_uptime_operation: OperationRef = OperationRef { path: "dag/extdeps/linux/procfs.dag", service: "linux.Procfs", @@ -291,8 +293,9 @@ data linux_procfs_read_uptime_operation: OperationRef = OperationRef { fn uptime_handler(w: MtCollins1BootWorld, call: OperationCall) -> OperationStep { let up = w.worker.uptime_at_origin + (second_count(s: call.now) as Int) + let record = join([to_string(up), ".00 ", to_string(up), ".00\n"], "") OperationObserved { - observation: ShellObserved { observation: ShellProcessExited { exit_code: 0, stdout: join([to_string(up), ".00 ", to_string(up), ".00\n"], ""), stderr: "" } }, + observation: FileObserved { observation: FileOperationSucceeded { byte_count: content_bytes(s: record), content: record } }, state: w, elapsed: second(count: 0), } diff --git a/dag/gunbc/modeled_operation_realization_seed_growth.dag b/dag/gunbc/modeled_operation_realization_seed_growth.dag index eac23b41049..ce1fa8a5438 100644 --- a/dag/gunbc/modeled_operation_realization_seed_growth.dag +++ b/dag/gunbc/modeled_operation_realization_seed_growth.dag @@ -52,6 +52,7 @@ data modeled_operation_realization_seed_growth_justification: SeedGrowthJustific DeclarationRef { module_path: "v1_compiler.v1_interpreter", decl_name: "shell_result_of_observation", field: WholeDeclaration }, DeclarationRef { module_path: "v1_compiler.v1_interpreter", decl_name: "shell_result_projection", field: WholeDeclaration }, DeclarationRef { module_path: "v1_compiler.v1_interpreter", decl_name: "file_result_of_observation", field: WholeDeclaration }, + DeclarationRef { module_path: "v1_compiler.v1_interpreter", decl_name: "file_transport_path", field: WholeDeclaration }, ], reason: "The seed interpreter is the only evaluator that runs the boot orchestrator, and the acceptance matrix (#12423, operator ruling 2026-09-27) must execute that orchestrator against controlled device histories. These items are the seed realization of a .dag contract: selection is v2.std.operation_realization operation_handler_selection over std.effect_grant covering_grant, admission is modeled_realization_admitted_in and operation_realization_duplicate, the virtual clock is virtual_clock_origin and virtual_clock_after over std.measure Second, and every scenario transition is gunbc.bmc_model. The Rust holds a state value, a clock value and the dispatch log, and dispatches; shell_result_projection is the existing wet shell projection extracted so the modeled observation reaches the same decoder path.", owning_dissolution_lane: "v1-materialization-kernel" as RoadmapNodeId, diff --git a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag index 3dc77e7bf87..e7c4c2f595d 100644 --- a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag +++ b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag @@ -9,7 +9,7 @@ import v2.workflow.floor_eval_step_cost_drop { floor_eval_step_cost_drop_boot_ma // matrix, msg_83af891b). The DECLARATION lives here; the POPULATION's authority is // `v2.workflow.floor_eval_step_cost_drop` `floor_eval_step_cost_drop_boot_matrix_rows`. // -// WHAT IS LOST IS ONE WALL, AND THE CLAIMS ARE UNTOUCHED. The eleven identities are planned, executed +// WHAT IS LOST IS ONE WALL, AND THE CLAIMS ARE UNTOUCHED. The ten identities are planned, executed // and measured on every pull request that edits them; a semantic red and a wall-clock crossing still // block. Only the eval-step overrun is reported as `EvalStepsOverBudgetUnderDeclaredDrop` rather than // refusing. The budget is not raised. Their CPU stays under the enrolment margin, so they enrol @@ -27,7 +27,7 @@ import v2.workflow.floor_eval_step_cost_drop { floor_eval_step_cost_drop_boot_ma // healthy world the cases vary, and it is already the section 3 remedy: a SUPPLIED value, constructed // directly rather than derived by executing production. MEASURED (claim_batch, 2026-09-29, review // 72606): building that world with its census console and the frame costs 1,687 to 3,793 eval steps, -// against 77,801 to 167,236 for the member cases (re-measured after #12434's route was bound); with it removed even the cheapest member stays over +// against 73,872 to 170,048 for the member cases (re-measured after #12434's route was bound); with it removed even the cheapest member stays over // the 72,300 budget. So hoisting it neither retires this drop nor removes a member, and none is owed. data mtcollins1_boot_matrix_new_witness_eval_step_cost_population: List = floor_eval_step_cost_drop_boot_matrix_rows |> map(m => concat(concat(m.identity, ": over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by "), m.measured_by)) @@ -39,7 +39,7 @@ data mtcollins1_boot_matrix_native_witness_capability: String = "witnesses emitt data mtcollins1_boot_matrix_new_witness_eval_step_cost: RungDrop = RungDrop { identity: "mtcollins1_boot_matrix_new_witness_eval_step_cost" as NonEmptyStr, - subject: "new-witness eval-step cost gate over the eleven mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered", + subject: "new-witness eval-step cost gate over the ten mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered", declared: "2026-09-28", @@ -52,6 +52,6 @@ data mtcollins1_boot_matrix_new_witness_eval_step_cost: RungDrop = RungDrop { replacement: "the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter", }, population: mtcollins1_boot_matrix_new_witness_eval_step_cost_population, - restoration_trigger: concat(concat("THE CAPABILITY: ", mtcollins1_boot_matrix_native_witness_capability), "; WHAT THAT MUST BE SUFFICIENT FOR: each of these eleven identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither."), + restoration_trigger: concat(concat("THE CAPABILITY: ", mtcollins1_boot_matrix_native_witness_capability), "; WHAT THAT MUST BE SUFFICIENT FOR: each of these ten identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither."), } } diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index 025cf621baa..397b8141473 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -342,9 +342,9 @@ new-witness eval-step cost gate over the one roadmap page claim that derives the new-witness eval-step cost gate over the ten interpreted P-256 and P-384 point and group-law checks and SHA-384 FIPS vectors of the App Attest path: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the P-384 and SHA-384 primitives executing as natively emitted code rather than as interpreted bignat and Word64 folds). Population: test.claim.p384_dag_ecdsa_witness_test.the_p384_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_beside_the_base_point_is_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_with_a_coordinate_at_p_is_not_admitted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.apples_ca_and_root_keys_are_on_p384: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.sha384_fips_witness_test.sha384_of_the_empty_message_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published empty message and a one-octet message on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_abc_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published abc vector and abd on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_the_896_bit_message_is_the_published_two_block_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is four SHA-384 block compressions, the published 896-bit two-block vector and a last-block mutation on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.p256_dag_ecdsa_witness_test.the_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35708011844 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, well inside the wall deadline and over the new-witness eval-step budget. The billed work is one P-256 curve equation over the published base point as 11-limb bignat folds on an interpreter that reifies no machine width. It is a MEMBER BECAUSE IT WAS SPLIT OUT of a claim that also asserted n*G = infinity: that conjunction crossed the 8000ms wall deadline and was INTERRUPTED BEFORE ANY VERDICT, so both facts were being lost; the scalar multiplication left the floor for the native row the frontier names, and this cheap half now reaches a verdict. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field, test.claim.p384_dag_ecdsa_witness_test.doubling_and_adding_the_base_point_stay_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling, one addition and two projective curve-equation checks at 16 limbs, test.claim.p384_dag_ecdsa_witness_test.doubling_an_off_curve_point_stays_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling and one projective curve-equation check at 16 limbs. Restored when: THE CAPABILITY: gunbc test //gunbc/instruments:native-crypto-vectors EXECUTING ON THE MERGE PATH, i.e. as a phase of a required lane whose red blocks a merge, running these ten identities natively (its cases p256_the_base_point_is_on_the_curve, p384_the_base_point_is_on_the_curve, p384_red_a_point_beside_the_base_point_is_off_the_curve, p384_red_a_point_with_a_coordinate_at_p_is_not_admitted, p384_doubling_and_adding_the_base_point_stay_on_the_curve, p384_red_doubling_an_off_curve_point_stays_off_the_curve, p384_apples_ca_and_root_keys_are_on_the_curve and the sha384_* FIPS cases with their reds) while each still evaluates the real curve equation or the real hash; WHAT THAT MUST BE SUFFICIENT FOR: the P-384 parameters and SHA-384 are exercised on the acceptance path with no interpreted 16-limb fold inside a claim frame, so the interpreted identities can leave the floor for that row, or they measure under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives. The same row run BY NAME (as it exists since gunbc#12306) executes the facts natively but is NOT the acceptance path and retires nothing. Supplying the curve check's answer or the digest as a fixture, or deleting the identities, satisfies neither. -### new-witness eval-step cost gate over the eleven mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 +### new-witness eval-step cost gate over the ten mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 -new-witness eval-step cost gate over the eleven mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_host_that_never_prints_a_census_refuses_at_the_deadline, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=167236 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_healthy_census_completes_and_releases_its_collector, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=158055 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_already_presented_image_is_not_attached_again, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=134675 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions media_that_never_becomes_ready_refuses_before_any_power_action, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=91254 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_presentation_lost_after_readiness_stops_the_handoff, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=97089 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=129921 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_sol_loss_mid_boot_is_reported_before_the_deadline, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=124297 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_two_socket_answer_is_a_truthful_topology_refusal, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=124495 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_listing_that_names_the_image_twice_starts_nothing, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=77801 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_an_interrupted_attempt_locks_out_the_next_one: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899, the COMPLETED-OVER-COST-REQUIREMENT line for this identity: verdict pass, eval_steps=74419 against the 72,300 new-witness budget, crossed once #12434's route was bound; the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899, the COMPLETED-OVER-COST-REQUIREMENT line for this identity: verdict pass, eval_steps=77423 against the 72,300 new-witness budget, crossed once #12434's route was bound; the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each of these eleven identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. +new-witness eval-step cost gate over the ten mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_host_that_never_prints_a_census_refuses_at_the_deadline, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=170048 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_healthy_census_completes_and_releases_its_collector, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=160637 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_already_presented_image_is_not_attached_again, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=137485 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions media_that_never_becomes_ready_refuses_before_any_power_action, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=92947 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_presentation_lost_after_readiness_stops_the_handoff, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=98794 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=132731 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_sol_loss_mid_boot_is_reported_before_the_deadline, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=129808 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_two_socket_answer_is_a_truthful_topology_refusal, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=126897 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_listing_that_names_the_image_twice_starts_nothing, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=79511 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions the_right_filename_on_the_wrong_share_refuses_before_any_power_action, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=73872 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each of these ten identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. ### new-witness eval-step cost gate over six App Attest verifier claims -- the two real-path inhabitance claims over Apple's objects, three single structural steps priced by their own SHA-256s, and the wire-carrier join: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 diff --git a/src/v1/stage0/src/v1_interpreter.rs b/src/v1/stage0/src/v1_interpreter.rs index 161334b2f58..4d8a0cae656 100644 --- a/src/v1/stage0/src/v1_interpreter.rs +++ b/src/v1/stage0/src/v1_interpreter.rs @@ -8420,12 +8420,14 @@ fn dispatch_modeled_operation( .map_err(&harness_fault) .map(|shell| shell_result_projection(shell, op_node, ctx)) } else { - // Every file-transport operation declares its path; one dispatched without a string - // path is a malformed dispatch and refuses, never an empty path the projection would - // report as if the operation had named one. - match param_env.lookup(ctx.sym("path")) { - Some(Value::Str(p)) => file_result_of_observation(&observation, &p, ctx), - _ => Err("a file operation was dispatched without a string path".to_string()), + // The path is the transport's own (file_transport_path), resolved exactly as the wet + // dispatch resolves it; one that is missing or empty refuses, never an empty path the + // projection would report as if the operation had named one. + match file_transport_path(transport, param_env, ctx) { + Ok(p) => file_result_of_observation(&observation, &p, ctx), + Err(e) => Err(format!( + "a file operation's transport path did not resolve: {e}" + )), } .map_err(&harness_fault) .map(|file| map_file_outputs(&file, op_node, ctx)) @@ -17314,18 +17316,20 @@ fn io_error_kind_name(e: &std::io::Error) -> String { .to_string() } -fn dispatch_file( - op_node: &Rc, +/// THE ONE RESOLUTION OF A FILE OPERATION'S PATH: the transport's own `path` property, evaluated and +/// template-substituted over the operation's inputs. The wet dispatch and the modeled realization both +/// read it here, so a modeled answer is recorded against exactly the path the real transport would +/// touch -- including an operation whose path is a literal in its transport and not an input +/// (linux.Procfs ReadUptime). A missing or empty path refuses. +fn file_transport_path( transport: &Rc, param_env: &Rc, ctx: &InterpContext, -) -> InterpResult { - let si = ctx.si(); - +) -> InterpResult { let path = match find_property( transport.properties.clone(), "base_path".to_string(), - si.clone(), + ctx.si(), ) { Some(path_node) => { let path_val = eval_expr(&path_node, param_env, ctx)?; @@ -17342,6 +17346,18 @@ fn dispatch_file( msg: "file transport resolved to an empty path".to_string(), }); } + Ok(path) +} + +fn dispatch_file( + op_node: &Rc, + transport: &Rc, + param_env: &Rc, + ctx: &InterpContext, +) -> InterpResult { + let si = ctx.si(); + + let path = file_transport_path(transport, param_env, ctx)?; // Optional explicit verb on the transport row (`transport file { path: ..., verb: "delete" }`). // Delete/List are structurally indistinguishable from Read (path-only inputs), so the diff --git a/src/v2/workflow/floor_eval_step_cost_drop.dag b/src/v2/workflow/floor_eval_step_cost_drop.dag index 2c782630853..98019739583 100644 --- a/src/v2/workflow/floor_eval_step_cost_drop.dag +++ b/src/v2/workflow/floor_eval_step_cost_drop.dag @@ -237,55 +237,51 @@ data floor_eval_step_cost_drop_python_to_typescript_inhabitance_rows: List = [ EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_host_that_never_prints_a_census_refuses_at_the_deadline, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=167236 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_host_that_never_prints_a_census_refuses_at_the_deadline, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=170048 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_healthy_census_completes_and_releases_its_collector, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=158055 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_healthy_census_completes_and_releases_its_collector, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=160637 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_already_presented_image_is_not_attached_again, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=134675 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_already_presented_image_is_not_attached_again, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=137485 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions media_that_never_becomes_ready_refuses_before_any_power_action, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=91254 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions media_that_never_becomes_ready_refuses_before_any_power_action, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=92947 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_presentation_lost_after_readiness_stops_the_handoff, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=97089 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_presentation_lost_after_readiness_stops_the_handoff, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=98794 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=129921 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=132731 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_sol_loss_mid_boot_is_reported_before_the_deadline, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=124297 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_sol_loss_mid_boot_is_reported_before_the_deadline, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=129808 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_two_socket_answer_is_a_truthful_topology_refusal, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=124495 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_two_socket_answer_is_a_truthful_topology_refusal, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=126897 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_listing_that_names_the_image_twice_starts_nothing, over this branch merged with main after #12434 (tree at 66f58d5cb6b plus the #12434 route binding), 2026-09-29: PASS, eval_steps=77801 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, - }, - EvalStepCostDropMeasurement { - identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_an_interrupted_attempt_locks_out_the_next_one" as NonEmptyStr, - measured_by: "PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899, the COMPLETED-OVER-COST-REQUIREMENT line for this identity: verdict pass, eval_steps=74419 against the 72,300 new-witness budget, crossed once #12434's route was bound; the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_listing_that_names_the_image_twice_starts_nothing, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=79511 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action" as NonEmptyStr, - measured_by: "PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899, the COMPLETED-OVER-COST-REQUIREMENT line for this identity: verdict pass, eval_steps=77423 against the 72,300 new-witness budget, crossed once #12434's route was bound; the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions the_right_filename_on_the_wrong_share_refuses_before_any_power_action, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=73872 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, }, ] From 1114e93f72d28b35695f5dd5ca2ca0df6a118b7c Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 30 Sep 2026 02:32:38 +0000 Subject: [PATCH 50/75] SOL establishment: read the clock before admitting a banner, consume the pace result and refuse a stalled clock, keep the deadline a Millisecond (std.measure second_to_millisecond) (review 5360526125, review 73010) Co-Authored-By: Claude Opus 5.5 (1M context) --- .../machine_intake/mtcollins1_boot_run.dag | 95 ++++++++++++++----- dag/std/measure.dag | 4 + .../mtcollins1_boot_run_witness_test.dag | 51 +++++++--- 3 files changed, 113 insertions(+), 37 deletions(-) diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_run.dag b/dag/gunbc/machine_intake/mtcollins1_boot_run.dag index 3d7ff7a8daf..70fcbae9e01 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_run.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_run.dag @@ -14,7 +14,7 @@ import std.temporal_effect { held_lease_observed_verdict, } import std.algebra { trim } -import std.measure { Second, second, second_count, Millisecond, millisecond, millisecond_count, Minute, minute, HardwareThreadCount, hardware_thread_count_value, ByteSize, byte_size, byte_size_count } +import std.measure { Second, second, second_count, Millisecond, millisecond, millisecond_count, second_to_millisecond, measure_add, measure_le, Minute, minute, HardwareThreadCount, hardware_thread_count_value, ByteSize, byte_size, byte_size_count } import std.checked_arithmetic { checked_int_to_nat } import std.process { ProcessExit, ExitSuccess, ExitFailure, exit_failure } import gunbc.machine_intake_mtcollins1_census_medium_readback { @@ -513,6 +513,8 @@ type SolEstablishmentFailure | SolActivationUnconfirmed { collector: SolCollectorObservation, allowance: Second } | SolActivationUnrecorded { detail: String } | SolEstablishmentClockUnread { detail: String } + | SolEstablishmentPaceRefused + | SolEstablishmentClockStalled { at_ms: Nat } | SolAdoptedActivationUnproven { collector: SolCollectorObservation, receipt: String } fn last_nonempty_line(s: String) -> String { @@ -549,6 +551,8 @@ fn sol_establishment_failure_text(failure: SolEstablishmentFailure) -> String { SolCollectorLeftUnexplained { collector: o, last_line: l } => concat(sol_collector_observation_text(observation: o), "; its last line: ", if l == "" { "(none)" } else { l }) SolActivationUnconfirmed { collector: o, allowance: a } => concat(sol_collector_observation_text(observation: o), concat(", but the session did not print its operational banner within ", concat(to_string(second_count(s: a)), " s, so activation is unconfirmed"))) SolEstablishmentClockUnread { detail: d } => concat("the establishment deadline could not be measured, so activation is unconfirmed: ", d) + SolEstablishmentPaceRefused => "the establishment wait could not pace its next poll, so activation is unconfirmed" + SolEstablishmentClockStalled { at_ms: t } => concat("the monotonic clock did not advance across a paced poll (uptime ", concat(to_string(t), " ms), so the establishment deadline cannot be measured and activation is unconfirmed")) SolActivationUnrecorded { detail: d } => concat("the banner was seen but the activation receipt could not be recorded: ", d) SolAdoptedActivationUnproven { collector: o, receipt: r } => concat(sol_collector_observation_text(observation: o), concat("; no activation receipt names this instance, so an adopted collector is not taken as established (receipt: ", concat(if r == "" { "(none)" } else { r }, ")"))) }) @@ -638,56 +642,97 @@ fn sol_capture_opens_with_banner(capture: String) -> Bool { // (sol_establishment_expired), so the time the wait grants does not depend on how long a poll takes: // fast polls do not exhaust it early and slow polls do not stretch it. An unreadable clock refuses // with its cause (SolEstablishmentClockUnread) rather than falling back to counting. -fn sol_establishment_deadline_ms(start: Millisecond, allowance: Second) -> Nat { - millisecond_count(m: start) + second_count(s: allowance) * 1000 +// THE ORDER IS OBSERVE, THEN READ THE CLOCK, THEN DECIDE. Success depends on a readable monotonic +// reading inside the deadline: a banner first observed at or after the deadline is not admitted, so a +// slow poll cannot carry an establishment past its allowance (sol_establishment_gate). The deadline +// is a Millisecond on /proc/uptime -- start plus the allowance through std.measure +// second_to_millisecond -- never an untyped count. +type SolEstablishmentGate + = GateEstablish + | GateExpired + | GateContinue + +fn sol_establishment_deadline(start: Millisecond, allowance: Second) -> Millisecond { + measure_add(a: start, b: second_to_millisecond(s: allowance)) +} + +fn sol_establishment_gate(banner_seen: Bool, now: Millisecond, deadline: Millisecond) -> SolEstablishmentGate { + if measure_le(a: deadline, b: now) { + GateExpired + } else if banner_seen { + GateEstablish + } else { + GateContinue + } } -fn sol_establishment_expired(now: Millisecond, deadline_ms: Nat) -> Bool { - millisecond_count(m: now) >= deadline_ms +// THE LOOP'S OWN TERMINATION DOES NOT DEPEND ON THE CLOCK BEING RIGHT. The pace's result is consumed: a +// refused pace ends the wait (SolEstablishmentPaceRefused). And after an admitted pace the next reading +// must be later than the previous one; a clock that did not advance ends the wait +// (SolEstablishmentClockStalled) instead of polling without bound. +type SolEstablishmentPace + = PaceAdvanced + | PaceRefused + | PaceClockStalled + +fn sol_establishment_pace(paced: Bool, previous: Millisecond, now: Millisecond) -> SolEstablishmentPace { + if !paced { + PaceRefused + } else if measure_le(a: now, b: previous) { + PaceClockStalled + } else { + PaceAdvanced + } } fn mtcollins1_sol_await_establishment(pid_path: String, capture_path: String, allowance: Second) -> SolEstablishment { match proc_uptime_read() { UptimeRefused { detail: d } => SolNotEstablished { failure: SolEstablishmentClockUnread { detail: d } } - UptimeObserved { uptime: u } => sol_await_establishment_until(pid_path: pid_path, capture_path: capture_path, allowance: allowance, deadline_ms: sol_establishment_deadline_ms(start: u, allowance: allowance)) + UptimeObserved { uptime: u } => sol_await_establishment_until(pid_path: pid_path, capture_path: capture_path, allowance: allowance, deadline: sol_establishment_deadline(start: u, allowance: allowance), previous: u, paced: true, first: true) } } -fn sol_await_establishment_until(pid_path: String, capture_path: String, allowance: Second, deadline_ms: Nat) -> SolEstablishment { +fn sol_await_establishment_until(pid_path: String, capture_path: String, allowance: Second, deadline: Millisecond, previous: Millisecond, paced: Bool, first: Bool) -> SolEstablishment { let at = clock_now_probed_at_or_unknown() let collector = mtcollins1_sol_collector_observe(pid_path: pid_path) - let pending = match collector { + let banner_seen = match collector { SolCollectorHeld => { let capture = Filesystem.Read(path: capture_path) - if capture.success && sol_capture_opens_with_banner(capture: capture.content) { - return sol_record_activation(pid_path: pid_path, at: at) - } - true + capture.success && sol_capture_opens_with_banner(capture: capture.content) } - SolCollectorUnobservable { cause: _ } => true + SolCollectorUnobservable { cause: _ } => false SolCollectorUnrecorded => { let client = Filesystem.Read(path: mtcollins1_sol_client_diagnostic_path(capture_path: capture_path)) let words = if client.success { client.content } else { "" } if string_contains(s: words, pattern: sol_hold_pid_not_published_line) || string_contains(s: words, pattern: sol_hold_pid_not_published_unstopped_line) || string_contains(s: words, pattern: sol_hold_exit_record_prefix) { return SolNotEstablished { failure: sol_establishment_failure(collector: collector, client_diagnostics: words, at: at) } } - true + false + } + _ => { + let client = Filesystem.Read(path: mtcollins1_sol_client_diagnostic_path(capture_path: capture_path)) + return SolNotEstablished { failure: sol_establishment_failure(collector: collector, client_diagnostics: if client.success { client.content } else { "" }, at: at) } } - _ => false - } - if !pending { - let client = Filesystem.Read(path: mtcollins1_sol_client_diagnostic_path(capture_path: capture_path)) - return SolNotEstablished { failure: sol_establishment_failure(collector: collector, client_diagnostics: if client.success { client.content } else { "" }, at: at) } } - let expired = match proc_uptime_read() { + let now = match proc_uptime_read() { UptimeRefused { detail: d } => return SolNotEstablished { failure: SolEstablishmentClockUnread { detail: d } } - UptimeObserved { uptime: n } => sol_establishment_expired(now: n, deadline_ms: deadline_ms) + UptimeObserved { uptime: n } => n } - if expired { - return SolNotEstablished { failure: SolActivationUnconfirmed { collector: collector, allowance: allowance } } + if !first { + match sol_establishment_pace(paced: paced, previous: previous, now: now) { + PaceRefused => return SolNotEstablished { failure: SolEstablishmentPaceRefused } + PaceClockStalled => return SolNotEstablished { failure: SolEstablishmentClockStalled { at_ms: millisecond_count(m: now) } } + PaceAdvanced => {} + } + } + match sol_establishment_gate(banner_seen: banner_seen, now: now, deadline: deadline) { + GateExpired => SolNotEstablished { failure: SolActivationUnconfirmed { collector: collector, allowance: allowance } } + GateEstablish => sol_record_activation(pid_path: pid_path, at: at) + GateContinue => { + let slept = sleep_delay_seconds_second_carrier_projection(duration: second(count: 1)) + sol_await_establishment_until(pid_path: pid_path, capture_path: capture_path, allowance: allowance, deadline: deadline, previous: now, paced: slept, first: false) + } } - let _paced = sleep_delay_seconds_second_carrier_projection(duration: second(count: 1)) - sol_await_establishment_until(pid_path: pid_path, capture_path: capture_path, allowance: allowance, deadline_ms: deadline_ms) } // THE ACTIVATION RECEIPT IS BOUND TO THE INSTANCE. Once the banner is seen for the held collector, its diff --git a/dag/std/measure.dag b/dag/std/measure.dag index 9386690dd35..11479384eac 100644 --- a/dag/std/measure.dag +++ b/dag/std/measure.dag @@ -1586,6 +1586,10 @@ fn nanoseconds_per_millisecond() -> Nat { 1000000 } +fn second_to_millisecond(s: Second) -> Millisecond { + millisecond(count: second_count(s: s) * milliseconds_per_second()) +} + fn millisecond_to_nanosecond(m: Millisecond) -> Nanosecond { nanosecond(count: millisecond_count(m: m) * nanoseconds_per_millisecond()) } diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_run_witness_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_run_witness_test.dag index 0093b7faf92..01d0e77418b 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_run_witness_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_run_witness_test.dag @@ -1,7 +1,7 @@ module test.claim.machine_intake.mtcollins1_boot_run_witness_test import gunbc.machine_intake_mtcollins1_sol_notice { SolNotice, SolNoticeCollectorExited, sol_loss_notice_of, sol_exit_notices_of, sol_notice_annotation, SolSourceRead, SolSourceAbsent, SolSourceUnreadable } -import gunbc.machine_intake_mtcollins1_boot_run { sol_observer_refusal_of, ProcRead, ProcReadRefused, sol_establishment_deadline_ms, sol_establishment_expired } +import gunbc.machine_intake_mtcollins1_boot_run { sol_observer_refusal_of, ProcRead, ProcReadRefused, sol_establishment_deadline, sol_establishment_gate, SolEstablishmentGate, GateEstablish, GateExpired, GateContinue, sol_establishment_pace, PaceAdvanced, PaceRefused, PaceClockStalled } import extdeps.github.log_annotations { log_annotation_message_line } import gunbc.machine_intake_megarac_media_attach { megarac_convergence_allowance, megarac_presentation_look_allowance } import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } @@ -999,16 +999,43 @@ test fn the_boot_requires_the_recorded_live_watcher() -> Bool { && [gone, reused, zombie, unread_stat, unread_record, empty].all(r => match r { Present { value: why } => string_contains(s: why, pattern: "the SOL notice watcher is required before a further BMC effect") _ => false }) } -// THE ESTABLISHMENT ALLOWANCE IS ELAPSED TIME, NOT A POLL COUNT, in both directions, over supplied uptime -// instants. Twenty fast polls 100 ms apart -- twice a ten-poll count -- are all inside a ten-second -// allowance, so none has expired; three slow polls four seconds apart pass the deadline at the third -// though a ten-poll count would still have seven to go. The start is an arbitrary uptime reading. -test fn the_establishment_allowance_is_elapsed_time_not_a_poll_count() -> Bool { +// THE ESTABLISHMENT GATE, over supplied uptime instants (the loop's own decision, sol_establishment_gate). +// ELAPSED TIME, NOT A POLL COUNT: twenty fast polls 100 ms apart -- twice a ten-poll count -- all +// continue inside a ten-second allowance; three slow polls four seconds apart expire at the third. +// A LATE BANNER IS NOT ADMITTED: a banner seen before the deadline establishes, the same banner first +// seen at or after it is expired. +fn gate_name(g: SolEstablishmentGate) -> String { + match g { + GateEstablish => "establish" + GateExpired => "expired" + GateContinue => "continue" + } +} + +fn gate_is(g: SolEstablishmentGate, want: String) -> Bool { + gate_name(g: g) == want +} + +test fn the_establishment_gate_is_elapsed_time_and_refuses_a_late_banner() -> Bool { let start = 350735470 - let deadline = sol_establishment_deadline_ms(start: millisecond(count: start), allowance: second(count: 10)) - let fast = map([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], i => sol_establishment_expired(now: millisecond(count: start + i * 100), deadline_ms: deadline)) - let slow = map([1, 2, 3], i => sol_establishment_expired(now: millisecond(count: start + i * 4000), deadline_ms: deadline)) - deadline == start + 10000 - && fast.all(e => !e) - && slow == [false, false, true] + let deadline = sol_establishment_deadline(start: millisecond(count: start), allowance: second(count: 10)) + let fast = map([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], i => gate_is(g: sol_establishment_gate(banner_seen: false, now: millisecond(count: start + i * 100), deadline: deadline), want: "continue")) + let slow = map([1, 2, 3], i => gate_name(g: sol_establishment_gate(banner_seen: false, now: millisecond(count: start + i * 4000), deadline: deadline))) + deadline == millisecond(count: start + 10000) + && fast.all(ok => ok) + && slow == ["continue", "continue", "expired"] + && gate_is(g: sol_establishment_gate(banner_seen: true, now: millisecond(count: start + 9999), deadline: deadline), want: "establish") + && gate_is(g: sol_establishment_gate(banner_seen: true, now: millisecond(count: start + 10000), deadline: deadline), want: "expired") + && gate_is(g: sol_establishment_gate(banner_seen: true, now: millisecond(count: start + 12000), deadline: deadline), want: "expired") +} + +// THE LOOP TERMINATES WITHOUT TRUSTING THE CLOCK (sol_establishment_pace): a refused pace is PaceRefused; +// an admitted pace followed by a reading no later than the previous one is PaceClockStalled; an +// admitted pace with an advancing clock continues. +test fn a_refused_pace_or_a_stalled_clock_ends_the_establishment_wait() -> Bool { + let before = millisecond(count: 1000) + (match sol_establishment_pace(paced: false, previous: before, now: millisecond(count: 2000)) { PaceRefused => true _ => false }) + && (match sol_establishment_pace(paced: true, previous: before, now: millisecond(count: 1000)) { PaceClockStalled => true _ => false }) + && (match sol_establishment_pace(paced: true, previous: before, now: millisecond(count: 900)) { PaceClockStalled => true _ => false }) + && (match sol_establishment_pace(paced: true, previous: before, now: millisecond(count: 2000)) { PaceAdvanced => true _ => false }) } From 88c07175acded338b5da5be686d6f219e17a763c Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 30 Sep 2026 02:45:01 +0000 Subject: [PATCH 51/75] Retire the stale unimported-bare-provider roster row for std/measure.dag#Time (ImportsFixed), which the touched-file gate now checks Co-Authored-By: Claude Opus 5.5 (1M context) --- src/v2/workflow/floor_unimported_bare_provider_debt_roster.dag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v2/workflow/floor_unimported_bare_provider_debt_roster.dag b/src/v2/workflow/floor_unimported_bare_provider_debt_roster.dag index d4ade40bea3..e26dc6c1d0d 100644 --- a/src/v2/workflow/floor_unimported_bare_provider_debt_roster.dag +++ b/src/v2/workflow/floor_unimported_bare_provider_debt_roster.dag @@ -906,7 +906,7 @@ data unimported_bare_provider_dispositions: List Date: Wed, 30 Sep 2026 02:46:42 +0000 Subject: [PATCH 52/75] Retire dag/std/measure.dag#Time from the unimported-bare-provider roster as NotAReference The floor refused RosterStale: the file no longer carries the pair. measure.dag has imported Time from extdeps.units.iso_80000_3 since 2026-09-05, before the roster was seeded on 2026-09-25, so the file did not change; the seeding reader derived an imported name as unimported, and the parsed reader (#12609) does not. That is NotAReference -- the READER changed -- not ImportsFixed, which would claim a file change that did not happen. This PR surfaced it by touching measure.dag. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/v2/workflow/floor_unimported_bare_provider_debt_roster.dag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v2/workflow/floor_unimported_bare_provider_debt_roster.dag b/src/v2/workflow/floor_unimported_bare_provider_debt_roster.dag index d4ade40bea3..05dd7118331 100644 --- a/src/v2/workflow/floor_unimported_bare_provider_debt_roster.dag +++ b/src/v2/workflow/floor_unimported_bare_provider_debt_roster.dag @@ -906,7 +906,7 @@ data unimported_bare_provider_dispositions: List Date: Wed, 30 Sep 2026 03:47:48 +0000 Subject: [PATCH 53/75] std.measure second_to_millisecond at #12492's position with its regenerated stage0 mirror (byte-identical to #12492, so the two merge without a duplicate) Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/std/measure.dag | 8 ++++---- src/v1/stage0/src/std_measure.rs | 7 +++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/dag/std/measure.dag b/dag/std/measure.dag index 11479384eac..d114a0fcc3b 100644 --- a/dag/std/measure.dag +++ b/dag/std/measure.dag @@ -1586,10 +1586,6 @@ fn nanoseconds_per_millisecond() -> Nat { 1000000 } -fn second_to_millisecond(s: Second) -> Millisecond { - millisecond(count: second_count(s: s) * milliseconds_per_second()) -} - fn millisecond_to_nanosecond(m: Millisecond) -> Nanosecond { nanosecond(count: millisecond_count(m: m) * nanoseconds_per_millisecond()) } @@ -1650,6 +1646,10 @@ fn minute_to_millisecond(m: Minute) -> Millisecond { millisecond(count: minute_count(m) * seconds_per_minute() * milliseconds_per_second()) } +fn second_to_millisecond(s: Second) -> Millisecond { + millisecond(count: second_count(s: s) * milliseconds_per_second()) +} + type Percent = Measure fn percent(count: Nat) -> Percent { diff --git a/src/v1/stage0/src/std_measure.rs b/src/v1/stage0/src/std_measure.rs index d11b18a5588..adf9528a58d 100644 --- a/src/v1/stage0/src/std_measure.rs +++ b/src/v1/stage0/src/std_measure.rs @@ -1697,6 +1697,13 @@ pub fn minute_to_millisecond(m: Minute) -> Millisecond { )) } +pub fn second_to_millisecond(s: Second) -> Millisecond { + millisecond(v1_rt::int_mul( + second_count(s.clone()), + milliseconds_per_second(), + )) +} + pub type Percent = Rc>; pub fn percent(count: Nat) -> Percent { From a94b82eac982e1c9694f221ffd1bd11342ceff72 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Wed, 30 Sep 2026 04:04:30 +0000 Subject: [PATCH 54/75] Eval-step drop: the interrupted-attempt case is back, at CI's 75,263 The floor's run 36661418914 measured it over 72,300 where a local claim_batch read 70,000; the floor's figure decides membership. Eleven rows; docs/design-rung-drops.md regenerated. Co-Authored-By: Claude Opus 5.5 (1M context) --- ...collins1_boot_matrix_new_witness_eval_step_cost.dag | 6 +++--- docs/design-rung-drops.md | 4 ++-- src/v2/workflow/floor_eval_step_cost_drop.dag | 10 +++++++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag index e7c4c2f595d..9154e0dcae7 100644 --- a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag +++ b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag @@ -9,7 +9,7 @@ import v2.workflow.floor_eval_step_cost_drop { floor_eval_step_cost_drop_boot_ma // matrix, msg_83af891b). The DECLARATION lives here; the POPULATION's authority is // `v2.workflow.floor_eval_step_cost_drop` `floor_eval_step_cost_drop_boot_matrix_rows`. // -// WHAT IS LOST IS ONE WALL, AND THE CLAIMS ARE UNTOUCHED. The ten identities are planned, executed +// WHAT IS LOST IS ONE WALL, AND THE CLAIMS ARE UNTOUCHED. The eleven identities are planned, executed // and measured on every pull request that edits them; a semantic red and a wall-clock crossing still // block. Only the eval-step overrun is reported as `EvalStepsOverBudgetUnderDeclaredDrop` rather than // refusing. The budget is not raised. Their CPU stays under the enrolment margin, so they enrol @@ -39,7 +39,7 @@ data mtcollins1_boot_matrix_native_witness_capability: String = "witnesses emitt data mtcollins1_boot_matrix_new_witness_eval_step_cost: RungDrop = RungDrop { identity: "mtcollins1_boot_matrix_new_witness_eval_step_cost" as NonEmptyStr, - subject: "new-witness eval-step cost gate over the ten mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered", + subject: "new-witness eval-step cost gate over the eleven mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered", declared: "2026-09-28", @@ -52,6 +52,6 @@ data mtcollins1_boot_matrix_new_witness_eval_step_cost: RungDrop = RungDrop { replacement: "the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter", }, population: mtcollins1_boot_matrix_new_witness_eval_step_cost_population, - restoration_trigger: concat(concat("THE CAPABILITY: ", mtcollins1_boot_matrix_native_witness_capability), "; WHAT THAT MUST BE SUFFICIENT FOR: each of these ten identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither."), + restoration_trigger: concat(concat("THE CAPABILITY: ", mtcollins1_boot_matrix_native_witness_capability), "; WHAT THAT MUST BE SUFFICIENT FOR: each of these eleven identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither."), } } diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index 397b8141473..b284c78d225 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -342,9 +342,9 @@ new-witness eval-step cost gate over the one roadmap page claim that derives the new-witness eval-step cost gate over the ten interpreted P-256 and P-384 point and group-law checks and SHA-384 FIPS vectors of the App Attest path: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the P-384 and SHA-384 primitives executing as natively emitted code rather than as interpreted bignat and Word64 folds). Population: test.claim.p384_dag_ecdsa_witness_test.the_p384_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_beside_the_base_point_is_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_with_a_coordinate_at_p_is_not_admitted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.apples_ca_and_root_keys_are_on_p384: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.sha384_fips_witness_test.sha384_of_the_empty_message_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published empty message and a one-octet message on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_abc_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published abc vector and abd on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_the_896_bit_message_is_the_published_two_block_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is four SHA-384 block compressions, the published 896-bit two-block vector and a last-block mutation on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.p256_dag_ecdsa_witness_test.the_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35708011844 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, well inside the wall deadline and over the new-witness eval-step budget. The billed work is one P-256 curve equation over the published base point as 11-limb bignat folds on an interpreter that reifies no machine width. It is a MEMBER BECAUSE IT WAS SPLIT OUT of a claim that also asserted n*G = infinity: that conjunction crossed the 8000ms wall deadline and was INTERRUPTED BEFORE ANY VERDICT, so both facts were being lost; the scalar multiplication left the floor for the native row the frontier names, and this cheap half now reaches a verdict. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field, test.claim.p384_dag_ecdsa_witness_test.doubling_and_adding_the_base_point_stay_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling, one addition and two projective curve-equation checks at 16 limbs, test.claim.p384_dag_ecdsa_witness_test.doubling_an_off_curve_point_stays_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling and one projective curve-equation check at 16 limbs. Restored when: THE CAPABILITY: gunbc test //gunbc/instruments:native-crypto-vectors EXECUTING ON THE MERGE PATH, i.e. as a phase of a required lane whose red blocks a merge, running these ten identities natively (its cases p256_the_base_point_is_on_the_curve, p384_the_base_point_is_on_the_curve, p384_red_a_point_beside_the_base_point_is_off_the_curve, p384_red_a_point_with_a_coordinate_at_p_is_not_admitted, p384_doubling_and_adding_the_base_point_stay_on_the_curve, p384_red_doubling_an_off_curve_point_stays_off_the_curve, p384_apples_ca_and_root_keys_are_on_the_curve and the sha384_* FIPS cases with their reds) while each still evaluates the real curve equation or the real hash; WHAT THAT MUST BE SUFFICIENT FOR: the P-384 parameters and SHA-384 are exercised on the acceptance path with no interpreted 16-limb fold inside a claim frame, so the interpreted identities can leave the floor for that row, or they measure under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives. The same row run BY NAME (as it exists since gunbc#12306) executes the facts natively but is NOT the acceptance path and retires nothing. Supplying the curve check's answer or the digest as a fixture, or deleting the identities, satisfies neither. -### new-witness eval-step cost gate over the ten mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 +### new-witness eval-step cost gate over the eleven mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 -new-witness eval-step cost gate over the ten mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_host_that_never_prints_a_census_refuses_at_the_deadline, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=170048 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_healthy_census_completes_and_releases_its_collector, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=160637 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_already_presented_image_is_not_attached_again, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=137485 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions media_that_never_becomes_ready_refuses_before_any_power_action, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=92947 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_presentation_lost_after_readiness_stops_the_handoff, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=98794 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=132731 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_sol_loss_mid_boot_is_reported_before_the_deadline, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=129808 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_two_socket_answer_is_a_truthful_topology_refusal, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=126897 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_listing_that_names_the_image_twice_starts_nothing, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=79511 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions the_right_filename_on_the_wrong_share_refuses_before_any_power_action, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=73872 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each of these ten identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. +new-witness eval-step cost gate over the eleven mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_host_that_never_prints_a_census_refuses_at_the_deadline, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=170048 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_healthy_census_completes_and_releases_its_collector, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=160637 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_already_presented_image_is_not_attached_again, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=137485 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions media_that_never_becomes_ready_refuses_before_any_power_action, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=92947 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_presentation_lost_after_readiness_stops_the_handoff, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=98794 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=132731 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_sol_loss_mid_boot_is_reported_before_the_deadline, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=129808 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_two_socket_answer_is_a_truthful_topology_refusal, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=126897 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_listing_that_names_the_image_twice_starts_nothing, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=79511 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions the_right_filename_on_the_wrong_share_refuses_before_any_power_action, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=73872 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_an_interrupted_attempt_locks_out_the_next_one: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36661418914 of gunbc#12533 at c308d7f3dd5, the COMPLETED-OVER-COST-REQUIREMENT line for this identity: verdict pass, eval_steps=75263 against the 72,300 new-witness budget (a local claim_batch over the same tree read 70,000; the floor's own figure decides membership); the billed work is the real boot entry executed twice in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each of these eleven identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. ### new-witness eval-step cost gate over six App Attest verifier claims -- the two real-path inhabitance claims over Apple's objects, three single structural steps priced by their own SHA-256s, and the wire-carrier join: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 diff --git a/src/v2/workflow/floor_eval_step_cost_drop.dag b/src/v2/workflow/floor_eval_step_cost_drop.dag index 98019739583..2db798bc442 100644 --- a/src/v2/workflow/floor_eval_step_cost_drop.dag +++ b/src/v2/workflow/floor_eval_step_cost_drop.dag @@ -237,10 +237,10 @@ data floor_eval_step_cost_drop_python_to_typescript_inhabitance_rows: List = [ EvalStepCostDropMeasurement { @@ -283,6 +283,10 @@ data floor_eval_step_cost_drop_boot_matrix_rows: List Date: Wed, 30 Sep 2026 09:44:34 +0000 Subject: [PATCH 55/75] SolEstablishmentClockStalled carries the uptime as a Millisecond, not a bare Nat (review 73135) Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/gunbc/machine_intake/mtcollins1_boot_run.dag | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_run.dag b/dag/gunbc/machine_intake/mtcollins1_boot_run.dag index 51173e3bc69..33203b54816 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_run.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_run.dag @@ -503,7 +503,7 @@ type SolEstablishmentFailure | SolActivationUnrecorded { detail: String } | SolEstablishmentClockUnread { detail: String } | SolEstablishmentPaceRefused - | SolEstablishmentClockStalled { at_ms: Nat } + | SolEstablishmentClockStalled { uptime: Millisecond } | SolAdoptedActivationUnproven { collector: SolCollectorObservation, receipt: String } fn last_nonempty_line(s: String) -> String { @@ -541,7 +541,7 @@ fn sol_establishment_failure_text(failure: SolEstablishmentFailure) -> String { SolActivationUnconfirmed { collector: o, allowance: a } => concat(sol_collector_observation_text(observation: o), concat(", but the session did not print its operational banner within ", concat(to_string(second_count(s: a)), " s, so activation is unconfirmed"))) SolEstablishmentClockUnread { detail: d } => concat("the establishment deadline could not be measured, so activation is unconfirmed: ", d) SolEstablishmentPaceRefused => "the establishment wait could not pace its next poll, so activation is unconfirmed" - SolEstablishmentClockStalled { at_ms: t } => concat("the monotonic clock did not advance across a paced poll (uptime ", concat(to_string(t), " ms), so the establishment deadline cannot be measured and activation is unconfirmed")) + SolEstablishmentClockStalled { uptime: t } => concat("the monotonic clock did not advance across a paced poll (uptime ", concat(to_string(millisecond_count(m: t)), " ms), so the establishment deadline cannot be measured and activation is unconfirmed")) SolActivationUnrecorded { detail: d } => concat("the banner was seen but the activation receipt could not be recorded: ", d) SolAdoptedActivationUnproven { collector: o, receipt: r } => concat(sol_collector_observation_text(observation: o), concat("; no activation receipt names this instance, so an adopted collector is not taken as established (receipt: ", concat(if r == "" { "(none)" } else { r }, ")"))) }) @@ -710,7 +710,7 @@ fn sol_await_establishment_until(pid_path: String, capture_path: String, allowan if !first { match sol_establishment_pace(paced: paced, previous: previous, now: now) { PaceRefused => return SolNotEstablished { failure: SolEstablishmentPaceRefused } - PaceClockStalled => return SolNotEstablished { failure: SolEstablishmentClockStalled { at_ms: millisecond_count(m: now) } } + PaceClockStalled => return SolNotEstablished { failure: SolEstablishmentClockStalled { uptime: now } } PaceAdvanced => {} } } From cb144c1e0c5702e0b148b5ca5c53854a93f2a351 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 30 Sep 2026 13:55:19 +0000 Subject: [PATCH 56/75] mtcollins1 KVM observer: log in through the context request client, not inside the UI root page fleet-converge run 36721915217 refused the boot: the observer journalled "page.evaluate: Execution context was destroyed, most likely because of a navigation" and released as login-unobserved. It loaded "/" only to borrow an origin and ran the session POST inside that document, which was replaced under it. The session POST, the services read and the session DELETE need a cookie jar, not a page, so they now go through the browser context's request client. The sessionStorage keys the viewer reads are seeded by a context init script. The root page is never loaded; the only in-page evaluations left are on viewer.html. No retry was added, and every typed refusal and journal word is unchanged. The loopback transport's root page now replaces itself on DOMContentLoaded, and a new wet control asserts the login is seen and the root is never served. Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/gunbc/bmc_megarac_web_transport.dag | 5 ++++- .../machine_intake/mtcollins1_kvm_still.dag | 19 ++++++++++++++++--- ...kvm_observer_protocol_wet_witness_test.dag | 16 ++++++++++++++++ src/v2/workflow/floor_route_gap.dag | 4 +++- src/v2/workflow/local_repo_wet_terminal.dag | 6 ++++++ 5 files changed, 45 insertions(+), 5 deletions(-) diff --git a/dag/gunbc/bmc_megarac_web_transport.dag b/dag/gunbc/bmc_megarac_web_transport.dag index 92d2fb10147..4d54c0cff66 100644 --- a/dag/gunbc/bmc_megarac_web_transport.dag +++ b/dag/gunbc/bmc_megarac_web_transport.dag @@ -27,6 +27,9 @@ import gunbc.owned_process { // // The stand-in viewer page is narrower than the vendor's: a canvas#kvm painted from the /kvm stream // once a frame arrives, drawn from a cross-origin image when the world's canvas_readable flag is false. +// The stand-in root page replaces itself on DOMContentLoaded and the transport logs that it was served: +// the shape that destroyed the observer's in-page login on fleet-converge run 36721915217. An observer +// that loads "/" and then evaluates in it fails here exactly as it did there. // // ADMISSION OF THIS SCAFFOLD (DESIGN §5, external to this diff): operator escalation msg_d5eebfff, // default-approved on recommendation A, 2026-09-28 -- not an explicit operator ruling. @@ -41,7 +44,7 @@ data megarac_web_transport_scaffold: Disposition = Scaffold { data megarac_web_transport_dissolution_trigger: DissolutionCondition = unbound_dissolution(description: "🟡 dissolve-on: gunbc.bmc_megarac_web_transport megarac_web_transport_script -- the loopback HTTP+WebSocket transport is a node -e string that enforces a model-derived transition table. RETIRED BY THE CAPABILITY: gunbc serve WebSocket support SUFFICIENT TO SERVE THE gunbc.bmc_model KVM STREAM -- accept the /kvm upgrade, hold the connection across requests, deliver frames, and close it when a model transition leaves the stream closed, with every HTTP and upgrade request decoded, answered by the gunbc.bmc_model transition and encoded in .dag per request. HTTP-only serve support does not retire it. Admission: operator escalation msg_d5eebfff, default-approved on recommendation A, 2026-09-28") -data megarac_web_transport_script: String = "const http=require('http');const crypto=require('crypto');const fs=require('fs');const [tablePath,logPath]=process.argv.slice(1);function log(m)\{fs.appendFileSync(logPath,Date.now()+' pid='+process.pid+' '+m+'\\n')}const T=JSON.parse(fs.readFileSync(tablePath,'utf8'));let current=T.initial;const canvasReadable=T.canvas_readable===true;const kvmPath=T.kvm_path;function key(op,args)\{return JSON.stringify([op].concat(args))}const rows=new Map();const advances=new Set();for(const r of T.rows)\{const k=r.from+'\\u0000'+key(r.request.op,r.request.args);if(rows.has(k))\{log('refused: duplicate table row '+JSON.stringify(k));process.exit(3)}rows.set(k,\{status:r.status,stream:r.stream_open?'open':'none',to:r.to,body:r.body});if(r.request.op==='advance')advances.add(+r.request.args[0])}let selfStart='unknown';try\{const st=fs.readFileSync('/proc/self/stat','utf8');selfStart=st.slice(st.lastIndexOf(')')+2).split(' ')[19]}catch(e)\{}let socket=null;function apply(k)\{const r=rows.get(current+'\\u0000'+k);if(!r)\{log('unmodeled state='+JSON.stringify(current)+' request='+k);return null} log('transition request='+k+' status='+r.status+' to='+JSON.stringify(r.to));current=r.to; if(socket&&r.stream!=='open')\{log('stream closed by the model');const s=socket;socket=null;s.destroy()}return r}const png=Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==','base64');const img=http.createServer((q,r)=>\{r.writeHead(200,\{'Content-Type':'image/png'});r.end(png)});function viewer()\{const port2=img.address().port;const taint=canvasReadable?'':\"const i=new Image();i.onload=()=>x.drawImage(i,0,0);i.src='http://localhost:\"+port2+\"/x.png';\"; return \"\"}function refuse(r,key)\{r.writeHead(599,\{'Content-Type':'text/plain'});r.end('unmodeled request: '+key)}function answer(r,key)\{const t=apply(key);if(!t)return refuse(r,key);r.writeHead(t.status,\{'Content-Type':'application/json'});r.end(t.body)}const s=http.createServer((q,r)=>\{let body='';q.on('data',d=>body+=d);q.on('end',()=>\{ if(q.url==='/')\{r.end('');return} if(q.url==='/viewer.html')\{r.writeHead(200,\{'Content-Type':'text/html'});r.end(viewer());return} if(q.url==='/api/session'&&q.method==='POST')\{const p=new URLSearchParams(body);return answer(r,key('login',[p.get('username')||'',p.get('password')||'']))} if(q.url==='/api/session'&&q.method==='DELETE')\{return answer(r,key('logout',[q.headers['x-csrftoken']||'']))} if(q.url==='/api/settings/services')\{return answer(r,key('services',[]))} r.writeHead(404);r.end()})});s.on('upgrade',(q,sock)=>\{const u=new URL(q.url,'http://x');if(u.pathname!==kvmPath)\{sock.destroy();return} const t=apply(key('connect',[u.searchParams.get('token')||'']));if(!t||t.status!==101)\{log('kvm refused');sock.destroy();return} const k=crypto.createHash('sha1').update(q.headers['sec-websocket-key']+'258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest('base64'); sock.write('HTTP/1.1 101 Switching Protocols\\r\\nUpgrade: websocket\\r\\nConnection: Upgrade\\r\\nSec-WebSocket-Accept: '+k+'\\r\\n\\r\\n'); sock.write(Buffer.from([0x81,0x05,0x66,0x72,0x61,0x6d,0x65]));socket=sock;log('kvm-open');sock.on('close',()=>\{if(socket===sock)socket=null})});const started=Date.now();for(const a of advances)\{setTimeout(()=>apply(key('advance',[String(a)])),a*1000)}img.listen(0,'127.0.0.1',()=>s.listen(0,'127.0.0.1',()=>log('listening start='+selfStart+' port='+s.address().port)));" +data megarac_web_transport_script: String = "const http=require('http');const crypto=require('crypto');const fs=require('fs');const [tablePath,logPath]=process.argv.slice(1);function log(m)\{fs.appendFileSync(logPath,Date.now()+' pid='+process.pid+' '+m+'\\n')}const T=JSON.parse(fs.readFileSync(tablePath,'utf8'));let current=T.initial;const canvasReadable=T.canvas_readable===true;const kvmPath=T.kvm_path;function key(op,args)\{return JSON.stringify([op].concat(args))}const rows=new Map();const advances=new Set();for(const r of T.rows)\{const k=r.from+'\\u0000'+key(r.request.op,r.request.args);if(rows.has(k))\{log('refused: duplicate table row '+JSON.stringify(k));process.exit(3)}rows.set(k,\{status:r.status,stream:r.stream_open?'open':'none',to:r.to,body:r.body});if(r.request.op==='advance')advances.add(+r.request.args[0])}let selfStart='unknown';try\{const st=fs.readFileSync('/proc/self/stat','utf8');selfStart=st.slice(st.lastIndexOf(')')+2).split(' ')[19]}catch(e)\{}let socket=null;function apply(k)\{const r=rows.get(current+'\\u0000'+k);if(!r)\{log('unmodeled state='+JSON.stringify(current)+' request='+k);return null} log('transition request='+k+' status='+r.status+' to='+JSON.stringify(r.to));current=r.to; if(socket&&r.stream!=='open')\{log('stream closed by the model');const s=socket;socket=null;s.destroy()}return r}const png=Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==','base64');const img=http.createServer((q,r)=>\{r.writeHead(200,\{'Content-Type':'image/png'});r.end(png)});function viewer()\{const port2=img.address().port;const taint=canvasReadable?'':\"const i=new Image();i.onload=()=>x.drawImage(i,0,0);i.src='http://localhost:\"+port2+\"/x.png';\"; return \"\"}function refuse(r,key)\{r.writeHead(599,\{'Content-Type':'text/plain'});r.end('unmodeled request: '+key)}function answer(r,key)\{const t=apply(key);if(!t)return refuse(r,key);r.writeHead(t.status,\{'Content-Type':'application/json'});r.end(t.body)}const s=http.createServer((q,r)=>\{let body='';q.on('data',d=>body+=d);q.on('end',()=>\{ if(q.url==='/')\{log('spa-root served');r.writeHead(200,\{'Content-Type':'text/html'});r.end(\"\");return} if(q.url==='/login.html')\{r.writeHead(200,\{'Content-Type':'text/html'});r.end('');return} if(q.url==='/viewer.html')\{r.writeHead(200,\{'Content-Type':'text/html'});r.end(viewer());return} if(q.url==='/api/session'&&q.method==='POST')\{const p=new URLSearchParams(body);return answer(r,key('login',[p.get('username')||'',p.get('password')||'']))} if(q.url==='/api/session'&&q.method==='DELETE')\{return answer(r,key('logout',[q.headers['x-csrftoken']||'']))} if(q.url==='/api/settings/services')\{return answer(r,key('services',[]))} r.writeHead(404);r.end()})});s.on('upgrade',(q,sock)=>\{const u=new URL(q.url,'http://x');if(u.pathname!==kvmPath)\{sock.destroy();return} const t=apply(key('connect',[u.searchParams.get('token')||'']));if(!t||t.status!==101)\{log('kvm refused');sock.destroy();return} const k=crypto.createHash('sha1').update(q.headers['sec-websocket-key']+'258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest('base64'); sock.write('HTTP/1.1 101 Switching Protocols\\r\\nUpgrade: websocket\\r\\nConnection: Upgrade\\r\\nSec-WebSocket-Accept: '+k+'\\r\\n\\r\\n'); sock.write(Buffer.from([0x81,0x05,0x66,0x72,0x61,0x6d,0x65]));socket=sock;log('kvm-open');sock.on('close',()=>\{if(socket===sock)socket=null})});const started=Date.now();for(const a of advances)\{setTimeout(()=>apply(key('advance',[String(a)])),a*1000)}img.listen(0,'127.0.0.1',()=>s.listen(0,'127.0.0.1',()=>log('listening start='+selfStart+' port='+s.address().port)));" // WHETHER THE TRANSPORT IS SERVING, AND IF NOT WHY. Readiness is bound to the whole launch INSTANCE: // only a listening line carrying BOTH the pid and the start time the owned launch recorded counts, so a diff --git a/dag/gunbc/machine_intake/mtcollins1_kvm_still.dag b/dag/gunbc/machine_intake/mtcollins1_kvm_still.dag index ab9cc1821d7..f7f7caf8bec 100644 --- a/dag/gunbc/machine_intake/mtcollins1_kvm_still.dag +++ b/dag/gunbc/machine_intake/mtcollins1_kvm_still.dag @@ -65,8 +65,21 @@ data mtcollins1_bmc_firmware: BmcFirmwareReleaseIdentity = megarac_firmware_0_32 // recovered from the served bundles cited on extdeps.bmc.megarac MegaRacScreenCaptureRoute: POST // /api/session and the sessionStorage keys its login handler sets; GET /api/settings/services and // the `kvm` row's viewer_count, which the UI's own launch() requires to be 0 before it opens -// viewer.html (else "only one KVM session is allowed"); then viewer.html in the same tab, and -// captureScreen()'s canvas#kvm.toDataURL("image/jpeg"). +// viewer.html (else "only one KVM session is allowed"); then viewer.html, and captureScreen()'s +// canvas#kvm.toDataURL("image/jpeg"). +// +// ONLY THE VIEWER IS A DOCUMENT (fleet-converge run 36721915217, 2026-09-30). The session POST, the +// services read and the session DELETE are HTTP exchanges that need a cookie jar, not a page, so they +// go through the browser context's own request client (it shares the jar the viewer's /kvm WebSocket +// uses); the sessionStorage keys are seeded by a context init script, which runs in every document of +// the controller's origin before that document's own scripts. The observer therefore never loads the +// UI's root page. It used to: it loaded "/" to borrow an origin and ran the login inside it, and on +// that run the journal read "page.evaluate: Execution context was destroyed, most likely because of a +// navigation" with session-release login-unobserved -- the root document was replaced under the login. +// That the vendor SPA redirects itself after DOMContentLoaded is INFERRED from that message, not read +// from its bundles; the repair does not depend on it, because no step now runs in a document the +// observer did not navigate to itself. The only in-page evaluations left are on viewer.html: the +// canvas wait and the toDataURL. // // ONE OBSERVER, HELD FOR THE WHOLE BOOT (side-chat acceptance (a), 2026-09-28). The observer is a // background process, started under the unit hold after the SOL acquire and BEFORE the handoff, that @@ -194,7 +207,7 @@ fn mtcollins1_kvm_observer_vocabulary_js() -> String { concat(kvm_journal_words_js(name: "EV", words: kvm_journal_event_words), kvm_journal_words_js(name: "CA", words: kvm_journal_cause_words)) } -data mtcollins1_kvm_observer_script_body: String = "const fs=require('fs');const path=require('path');const [base,user,pwFile,dir,attempt,cadenceMs,frameMs,maxPeriodic,pwModule]=process.argv.slice(1);const J=path.join(dir,'journal');function j(ev,kv)\{const t=Date.now();try\{fs.appendFileSync(J,t+' '+new Date(t).toISOString()+' '+ev+(kv?' '+kv:'')+'\\n')}catch(e)\{try\{process.stderr.write('journal write failed: '+ev+' '+String(e&&e.message)+'\\n')}catch(e2)\{}}}function one(e)\{return String(e&&e.message||e).replace(/[^ -~]+/g,' ').replace(/ +/g,' ').slice(0,300)}let browser=null,page=null,stopping=false,login='not-attempted',token=null,seq=0,periodic=0;let gen=0,live=null;async function teardown(why,code)\{if(stopping)return;stopping=true; j(EV.stopRequested,'by='+why); let rel; if(login==='accepted'&&page&&token)\{try\{rel=await page.evaluate(async t=>\{const r=await fetch('/api/session',\{method:'DELETE',headers:\{'X-CSRFTOKEN':t}});return r.ok?'released':'http-'+r.status},token)}catch(e)\{rel='release-failed detail='+JSON.stringify(one(e))}} else if(login==='unobserved')\{rel='login-unobserved'} else\{rel='no-session'} j(EV.sessionRelease,'result='+rel); let closed='closed';try\{if(browser)await browser.close();else closed='no-browser'}catch(e)\{closed='close-failed detail='+JSON.stringify(one(e))} j(EV.browserClose,'result='+closed); j(EV.stopped,'session='+rel.split(' ')[0]+' browser='+closed.split(' ')[0]); process.exit(code)}process.on('SIGTERM',()=>teardown('sigterm',0));process.on('SIGINT',()=>teardown('sigint',0));async function still(reason)\{seq+=1;const n=seq;const g=gen;const startedMs=Date.now(); if(!live||live.gen!==g)\{j(EV.acquisitionFailed,'seq='+n+' reason='+reason+' gen='+g+' cause='+CA.notConnected+'');return} try\{const url=await page.evaluate(()=>\{const c=document.getElementById('kvm');if(!c)throw new Error('no canvas#kvm');return c.toDataURL('image/jpeg')}); if(!live||live.gen!==g)\{j(EV.acquisitionFailed,'seq='+n+' reason='+reason+' gen='+g+' started_ms='+startedMs+' cause='+CA.connectionChangedDuringAcquisition+'');return} if(!url.startsWith('data:image/jpeg;base64,'))throw new Error('toDataURL answered '+url.slice(0,40)); const b=Buffer.from(url.slice(url.indexOf(',')+1),'base64');const f='still-'+n+'.jpg';fs.writeFileSync(path.join(dir,f),b); j(EV.still,'seq='+n+' reason='+reason+' gen='+g+' started_ms='+startedMs+' file='+f+' bytes='+b.length)} catch(e)\{j(EV.acquisitionFailed,'seq='+n+' reason='+reason+' gen='+g+' started_ms='+startedMs+' cause='+CA.canvasUnreadable+' detail='+JSON.stringify(one(e)))}}(async()=>\{ let pw;try\{pw=fs.readFileSync(pwFile,'utf8')}catch(e)\{j(EV.refused,'cause='+CA.credentialUnreadable+' detail='+JSON.stringify(one(e)));return teardown('refused',14)} let chromium;try\{chromium=require(pwModule).chromium}catch(e)\{j(EV.refused,'cause='+CA.toolchain+' detail='+JSON.stringify(one(e)));return teardown('refused',13)} try\{browser=await chromium.launch(\{headless:true})}catch(e)\{j(EV.refused,'cause='+CA.toolchain+' detail='+JSON.stringify(one(e)));return teardown('refused',13)} try\{const ctx=await browser.newContext(\{ignoreHTTPSErrors:true,viewport:\{width:1280,height:1024}});page=await ctx.newPage(); const expectedHost=new URL(base).host; await page.goto(base+'/',\{waitUntil:'domcontentloaded'}); login='unobserved'; const reply=await page.evaluate(async([u,p])=>\{const r=await fetch('/api/session',\{method:'POST',headers:\{'Content-Type':'application/x-www-form-urlencoded'},body:new URLSearchParams(\{username:u,password:p})});let b=null;try\{b=await r.json()}catch(e)\{}return\{status:r.status,b:b}},[user,pw]); if(reply.status!==200||!reply.b||reply.b.ok!==0)\{login='refused';j(EV.refused,'cause='+CA.login+' http='+reply.status);return teardown('refused',11)} login='accepted';token=reply.b.CSRFToken; await page.evaluate(([b,u])=>\{sessionStorage.setItem('garc',b.CSRFToken);sessionStorage.setItem('privilege_id',String(b.privilege));sessionStorage.setItem('extended_privilege',String(b.extendedpriv));sessionStorage.setItem('session_id',String(b.racsession_id));sessionStorage.setItem('username',u);sessionStorage.setItem('kvm_access','1');sessionStorage.setItem('vmedia_access','1')},[reply.b,user]); const seat=await page.evaluate(async t=>\{const r=await fetch('/api/settings/services',\{headers:\{'X-CSRFTOKEN':t}});const a=await r.json();const k=Array.isArray(a)?a.find(s=>s.service_name==='kvm'):null;return k?k.viewer_count:null},token); if(seat===null||seat===undefined)\{j(EV.refused,'cause='+CA.noKvmService+'');return teardown('refused',15)} if(seat!==0)\{j(EV.refused,'cause='+CA.seatBusy+' viewer_count='+seat);return teardown('refused',10)} page.on('websocket',ws=>\{let u;try\{u=new URL(ws.url())}catch(e)\{return} if(u.host!==expectedHost||u.pathname!=='/kvm')return; j(EV.connectionRequested,'url='+JSON.stringify(ws.url()));let mine=null; ws.on('framereceived',()=>\{if(!mine)\{gen+=1;mine=\{gen:gen};live=mine;j(EV.connectionOpen,'gen='+mine.gen+' url='+JSON.stringify(ws.url()))}}); ws.on('socketerror',e=>\{j(EV.connectionError,'gen='+(mine?mine.gen:0)+' detail='+JSON.stringify(one(e)));if(mine&&live===mine)live=null}); ws.on('close',()=>\{if(mine&&live===mine)\{live=null;j(EV.connectionLost,'gen='+mine.gen)}else if(!mine)\{j(EV.connectionRefused,'url='+JSON.stringify(ws.url()))}})}); await page.goto(base+'/viewer.html',\{waitUntil:'domcontentloaded'}); try\{await page.waitForFunction(()=>\{const c=document.getElementById('kvm');return !!c&&c.width>1&&c.height>1},null,\{timeout:Number(frameMs)})} catch(e)\{j(EV.refused,'cause='+CA.noFrame+' detail='+JSON.stringify(one(e)));return teardown('refused',12)} const deadline=Date.now()+Number(frameMs);while(!live&&Date.now()setTimeout(r,100))} if(!live)\{j(EV.refused,'cause='+CA.noKvmFrame+'');return teardown('refused',12)} j(EV.established,'host='+JSON.stringify(expectedHost)+' session='+String(reply.b.racsession_id)+' attempt='+attempt+' gen='+live.gen); let next=Date.now()+Number(cadenceMs); while(!stopping)\{ if(fs.existsSync(path.join(dir,'stop')))\{return teardown('stop-file',0)} let tf=[];try\{tf=fs.readdirSync(dir).filter(n=>n.startsWith('trigger-')).sort()}catch(e)\{j(EV.triggerScanFailed,'detail='+JSON.stringify(one(e)))} for(const n of tf)\{const p=path.join(dir,n);try\{fs.unlinkSync(p)}catch(e)\{continue}await still('trigger:'+n.slice(8))} if(Date.now()>=next&&periodicsetTimeout(r,250))} }catch(e)\{j(EV.failed,'detail='+JSON.stringify(one(e)));return teardown('failed',1)}})();" +data mtcollins1_kvm_observer_script_body: String = "const fs=require('fs');const path=require('path');const [base,user,pwFile,dir,attempt,cadenceMs,frameMs,maxPeriodic,pwModule]=process.argv.slice(1);const J=path.join(dir,'journal');function j(ev,kv)\{const t=Date.now();try\{fs.appendFileSync(J,t+' '+new Date(t).toISOString()+' '+ev+(kv?' '+kv:'')+'\\n')}catch(e)\{try\{process.stderr.write('journal write failed: '+ev+' '+String(e&&e.message)+'\\n')}catch(e2)\{}}}function one(e)\{return String(e&&e.message||e).replace(/[^ -~]+/g,' ').replace(/ +/g,' ').slice(0,300)}let browser=null,page=null,api=null,stopping=false,login='not-attempted',token=null,seq=0,periodic=0;let gen=0,live=null;async function teardown(why,code)\{if(stopping)return;stopping=true; j(EV.stopRequested,'by='+why); let rel; if(login==='accepted'&&api&&token)\{try\{const r=await api.delete(base+'/api/session',\{headers:\{'X-CSRFTOKEN':token}});rel=r.ok()?'released':'http-'+r.status()}catch(e)\{rel='release-failed detail='+JSON.stringify(one(e))}} else if(login==='unobserved')\{rel='login-unobserved'} else\{rel='no-session'} j(EV.sessionRelease,'result='+rel); let closed='closed';try\{if(browser)await browser.close();else closed='no-browser'}catch(e)\{closed='close-failed detail='+JSON.stringify(one(e))} j(EV.browserClose,'result='+closed); j(EV.stopped,'session='+rel.split(' ')[0]+' browser='+closed.split(' ')[0]); process.exit(code)}process.on('SIGTERM',()=>teardown('sigterm',0));process.on('SIGINT',()=>teardown('sigint',0));async function still(reason)\{seq+=1;const n=seq;const g=gen;const startedMs=Date.now(); if(!live||live.gen!==g)\{j(EV.acquisitionFailed,'seq='+n+' reason='+reason+' gen='+g+' cause='+CA.notConnected+'');return} try\{const url=await page.evaluate(()=>\{const c=document.getElementById('kvm');if(!c)throw new Error('no canvas#kvm');return c.toDataURL('image/jpeg')}); if(!live||live.gen!==g)\{j(EV.acquisitionFailed,'seq='+n+' reason='+reason+' gen='+g+' started_ms='+startedMs+' cause='+CA.connectionChangedDuringAcquisition+'');return} if(!url.startsWith('data:image/jpeg;base64,'))throw new Error('toDataURL answered '+url.slice(0,40)); const b=Buffer.from(url.slice(url.indexOf(',')+1),'base64');const f='still-'+n+'.jpg';fs.writeFileSync(path.join(dir,f),b); j(EV.still,'seq='+n+' reason='+reason+' gen='+g+' started_ms='+startedMs+' file='+f+' bytes='+b.length)} catch(e)\{j(EV.acquisitionFailed,'seq='+n+' reason='+reason+' gen='+g+' started_ms='+startedMs+' cause='+CA.canvasUnreadable+' detail='+JSON.stringify(one(e)))}}(async()=>\{ let pw;try\{pw=fs.readFileSync(pwFile,'utf8')}catch(e)\{j(EV.refused,'cause='+CA.credentialUnreadable+' detail='+JSON.stringify(one(e)));return teardown('refused',14)} let chromium;try\{chromium=require(pwModule).chromium}catch(e)\{j(EV.refused,'cause='+CA.toolchain+' detail='+JSON.stringify(one(e)));return teardown('refused',13)} try\{browser=await chromium.launch(\{headless:true})}catch(e)\{j(EV.refused,'cause='+CA.toolchain+' detail='+JSON.stringify(one(e)));return teardown('refused',13)} try\{const ctx=await browser.newContext(\{ignoreHTTPSErrors:true,viewport:\{width:1280,height:1024}});api=ctx.request;page=await ctx.newPage(); const expectedHost=new URL(base).host; login='unobserved'; const lr=await api.post(base+'/api/session',\{form:\{username:user,password:pw}});let lb=null;try\{lb=await lr.json()}catch(e)\{}const reply=\{status:lr.status(),b:lb}; if(reply.status!==200||!reply.b||reply.b.ok!==0)\{login='refused';j(EV.refused,'cause='+CA.login+' http='+reply.status);return teardown('refused',11)} login='accepted';token=reply.b.CSRFToken; await ctx.addInitScript(([h,b,u])=>\{if(location.host!==h)return;sessionStorage.setItem('garc',b.CSRFToken);sessionStorage.setItem('privilege_id',String(b.privilege));sessionStorage.setItem('extended_privilege',String(b.extendedpriv));sessionStorage.setItem('session_id',String(b.racsession_id));sessionStorage.setItem('username',u);sessionStorage.setItem('kvm_access','1');sessionStorage.setItem('vmedia_access','1')},[expectedHost,reply.b,user]); const sa=await(await api.get(base+'/api/settings/services',\{headers:\{'X-CSRFTOKEN':token}})).json();const kr=Array.isArray(sa)?sa.find(s=>s.service_name==='kvm'):null;const seat=kr?kr.viewer_count:null; if(seat===null||seat===undefined)\{j(EV.refused,'cause='+CA.noKvmService+'');return teardown('refused',15)} if(seat!==0)\{j(EV.refused,'cause='+CA.seatBusy+' viewer_count='+seat);return teardown('refused',10)} page.on('websocket',ws=>\{let u;try\{u=new URL(ws.url())}catch(e)\{return} if(u.host!==expectedHost||u.pathname!=='/kvm')return; j(EV.connectionRequested,'url='+JSON.stringify(ws.url()));let mine=null; ws.on('framereceived',()=>\{if(!mine)\{gen+=1;mine=\{gen:gen};live=mine;j(EV.connectionOpen,'gen='+mine.gen+' url='+JSON.stringify(ws.url()))}}); ws.on('socketerror',e=>\{j(EV.connectionError,'gen='+(mine?mine.gen:0)+' detail='+JSON.stringify(one(e)));if(mine&&live===mine)live=null}); ws.on('close',()=>\{if(mine&&live===mine)\{live=null;j(EV.connectionLost,'gen='+mine.gen)}else if(!mine)\{j(EV.connectionRefused,'url='+JSON.stringify(ws.url()))}})}); await page.goto(base+'/viewer.html',\{waitUntil:'domcontentloaded'}); try\{await page.waitForFunction(()=>\{const c=document.getElementById('kvm');return !!c&&c.width>1&&c.height>1},null,\{timeout:Number(frameMs)})} catch(e)\{j(EV.refused,'cause='+CA.noFrame+' detail='+JSON.stringify(one(e)));return teardown('refused',12)} const deadline=Date.now()+Number(frameMs);while(!live&&Date.now()setTimeout(r,100))} if(!live)\{j(EV.refused,'cause='+CA.noKvmFrame+'');return teardown('refused',12)} j(EV.established,'host='+JSON.stringify(expectedHost)+' session='+String(reply.b.racsession_id)+' attempt='+attempt+' gen='+live.gen); let next=Date.now()+Number(cadenceMs); while(!stopping)\{ if(fs.existsSync(path.join(dir,'stop')))\{return teardown('stop-file',0)} let tf=[];try\{tf=fs.readdirSync(dir).filter(n=>n.startsWith('trigger-')).sort()}catch(e)\{j(EV.triggerScanFailed,'detail='+JSON.stringify(one(e)))} for(const n of tf)\{const p=path.join(dir,n);try\{fs.unlinkSync(p)}catch(e)\{continue}await still('trigger:'+n.slice(8))} if(Date.now()>=next&&periodicsetTimeout(r,250))} }catch(e)\{j(EV.failed,'detail='+JSON.stringify(one(e)));return teardown('failed',1)}})();" data mtcollins1_kvm_observer_script: String = concat(mtcollins1_kvm_observer_vocabulary_js(), mtcollins1_kvm_observer_script_body) diff --git a/dag/test/claim/machine_intake/mtcollins1_kvm_observer_protocol_wet_witness_test.dag b/dag/test/claim/machine_intake/mtcollins1_kvm_observer_protocol_wet_witness_test.dag index 9fa6a99b73a..6622fb71577 100644 --- a/dag/test/claim/machine_intake/mtcollins1_kvm_observer_protocol_wet_witness_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_kvm_observer_protocol_wet_witness_test.dag @@ -150,6 +150,22 @@ test fn a_held_observer_is_admitted_and_its_triggered_still_is_hash_bound() -> B && string_contains(s: log, pattern: "stream closed by the model") } +// THE LOGIN DOES NOT RUN IN A DOCUMENT THAT CAN NAVIGATE AWAY (fleet-converge run 36721915217). The +// transport's root page replaces itself on DOMContentLoaded. The observer that loaded "/" and logged in +// by evaluating a fetch inside it journalled "failed ... Execution context was destroyed" against this +// transport, the hardware journal line for line, and was never established. The ROUTE is asserted, not +// only the answer: the controller saw the login and never served its root page. +test fn a_root_page_that_navigates_cannot_destroy_the_login() -> Bool { + let r = rig(w: world(other_viewers: 0, close_at: no_close(), canvas_readable: true)) + let admitted = match kvm_handoff_admission(start: r.start) { KvmHandoffAdmitted { session: s } => s == "7" _ => false } + let rec = mtcollins1_kvm_observer_finish(start: r.start, attempt: "wet", terminal_order: 3) + let log = transport_log(r: r) + let closed = close_rig(r: r) + admitted && released(rec: rec) && closed + && string_contains(s: log, pattern: "transition request=[\"login\",\"admin\",\"pw\"] status=200") + && !string_contains(s: log, pattern: "spa-root served") +} + // VIEWER SLOT BUSY: the model's other viewer makes viewer_count 1; the observer refuses with that count, // never connects, releases its session -- and the handoff is refused with that standing. test fn a_busy_viewer_slot_refuses_the_observer_and_the_handoff() -> Bool { diff --git a/src/v2/workflow/floor_route_gap.dag b/src/v2/workflow/floor_route_gap.dag index c4dcb3fe2bb..dc870ebc7c0 100644 --- a/src/v2/workflow/floor_route_gap.dag +++ b/src/v2/workflow/floor_route_gap.dag @@ -1932,8 +1932,10 @@ fn floor_route_gap_expectation_chunk_29() -> List { tail: Cons { head: FloorRouteGapExpectation { identity: "test.claim.machine_intake.mtcollins1_kvm_observer_protocol_wet_witness.a_relative_observer_directory_is_resolved_once", operation: "DirWithTemplate", ground: NoMockResponse {} }, tail: Cons { + head: FloorRouteGapExpectation { identity: "test.claim.machine_intake.mtcollins1_kvm_observer_protocol_wet_witness.a_root_page_that_navigates_cannot_destroy_the_login", operation: "Dir", ground: NoMockResponse {} }, + tail: Cons { head: FloorRouteGapExpectation { identity: "test.claim.machine_intake.sol_hold_stdin_wet_witness.a_channel_loss_asks_the_screen_and_the_ask_does_not_change_the_verdict", operation: "DirWithTemplate", ground: NoMockResponse {} }, - tail: Empty {} } } } } } } } } } } } } + tail: Empty {} } } } } } } } } } } } } } } fn floor_route_gap_expectation_chunks() -> List> { diff --git a/src/v2/workflow/local_repo_wet_terminal.dag b/src/v2/workflow/local_repo_wet_terminal.dag index 93e602a11d4..cb0e6bafbfa 100644 --- a/src/v2/workflow/local_repo_wet_terminal.dag +++ b/src/v2/workflow/local_repo_wet_terminal.dag @@ -2222,6 +2222,12 @@ fn local_repo_wet_schedule() -> List { function: "a_held_observer_is_admitted_and_its_triggered_still_is_hash_bound", expectation: ExpectedToHold {} }, + WetScheduledClaim { + identity: WitnessIdentity { module_path: "test.claim.machine_intake.mtcollins1_kvm_observer_protocol_wet_witness", function: "a_root_page_that_navigates_cannot_destroy_the_login" }, + entry: "dag/test/claim/machine_intake/mtcollins1_kvm_observer_protocol_wet_witness_test.dag", + function: "a_root_page_that_navigates_cannot_destroy_the_login", + expectation: ExpectedToHold {} + }, WetScheduledClaim { identity: WitnessIdentity { module_path: "test.claim.machine_intake.mtcollins1_kvm_observer_protocol_wet_witness", function: "a_busy_viewer_slot_refuses_the_observer_and_the_handoff" }, entry: "dag/test/claim/machine_intake/mtcollins1_kvm_observer_protocol_wet_witness_test.dag", From 9a580e56027d946046fadf869d2977a7f2fc3941 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 30 Sep 2026 15:05:06 +0000 Subject: [PATCH 57/75] mtcollins1: read-only fleet-converge mode fetches the BMC's own UI bundle (source.min.js) Operator decision msg_b3c77f62 (option A on escalation msg_13d5904d): a modeled read-only route to the firmware's UI bundle, so vendor codes such as cd_error_code are read from the vendor's source instead of escalated. - extdeps.bmc.megarac: megarac.Ui.GetServedBundle (readonly, no session, bytes as served) - gunbc.machine_intake_mtcollins1_ui_bundle_observe: mc info firmware revision first, refuse unless 0.32; fetch; sha256; report MATCH or DRIFT against the cited 2026-09-27 read (never refuses on drift); receipt on every path - fleet-converge mode mtcollins1_ui_bundle_observe: a mode row on the shared job, reusing the fan lane's credential prelude; bytes + receipt uploaded always() - witness: revision parse, the 0.32/0.33 discriminating pair, unread revision, digest match/drift Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/fleet-converge.yml | 34 +++- dag/extdeps/bmc/megarac.dag | 28 +++ dag/gunbc/ci/ci_spec.dag | 34 ++++ dag/gunbc/fleet/fleet_converge_workflow.dag | 45 ++++- .../megarac_served_ui_catalog_observation.dag | 7 + .../mtcollins1_ui_bundle_observe.dag | 163 ++++++++++++++++++ ...ollins1_ui_bundle_observe_witness_test.dag | 68 ++++++++ 7 files changed, 377 insertions(+), 2 deletions(-) create mode 100644 dag/gunbc/machine_intake/mtcollins1_ui_bundle_observe.dag create mode 100644 dag/test/claim/machine_intake/mtcollins1_ui_bundle_observe_witness_test.dag diff --git a/.github/workflows/fleet-converge.yml b/.github/workflows/fleet-converge.yml index b1b491ee729..e4b7537965d 100644 --- a/.github/workflows/fleet-converge.yml +++ b/.github/workflows/fleet-converge.yml @@ -13,7 +13,7 @@ on: mode: description: plan shows membership hunks; apply executes a prior plan artifact; org_actions_observe validates the org credential and refuses on runner-group drift; org_runner_roster_observe reads the organization's self-hosted runner registrations to exhaustion under the same token and refuses unless the roster is complete; app_control_plane_observe reads the gunbai-ci App registration and webhook config with a short-lived App JWT and refuses on hook-config drift; app_key_version_verify reads the gunbai-ci App private key at the EXACT Secret Manager version named by app_key_version, mints an installation token with it, and refuses unless GitHub accepts it and the key's rotation deadline has not passed -- no add, disable or destroy; runner_browser_toolchain_converge installs the declared Playwright/Chromium toolchain (apt host libraries as the administrator, digest-pinned node, Playwright and Chromium archives into the job user's root) on the selected host, which must be in the pool that runs the floor job, and refuses unless every digest, version and host library reads back and headless Chromium renders a local page; microvm_host_converge installs the cited Firecracker release on the selected host and reads the kvm grant back, refusing by name when the grant has not landed (the grant itself is applied by the full-host apply spine); microvm_network_apply stages the slot and host network files the model renders at the named expected_revision as root:root 0600 in a root-only directory over the fleet SSH edge as the host's ADMINISTRATOR, installs them with the modeled operations, reloads networkd, systemd-sysctl and the nft loader unit, and reads the ruleset back -- the job user is granted none of it, because install plus systemctl over content that principal can write is arbitrary root for any pull request; guest_image_observe reports the micro-VM base artifacts and their measured digests on the selected host and builds nothing; guest_image_converge builds the runner guest image there; microvm_boot_probe boots that image and reads its serial console; spark_grants and spark_bootstrap prepare the selected Spark; spark_serving_apply applies the promoted fabric groups' pair vLLM units over the password session, workers before heads; spark_native_serving_apply relaunches group B's native four-rank arm as ONE BOUNDED TRANSACTION -- an all-host preflight that mutates nothing and refuses on any unresolved artifact from an earlier run, the incumbent UNIT preserved (plus a diagnostic inspect of the incumbent container -- the container itself cannot outlive its unit, because these run --rm in the foreground under systemd), the head applied BEFORE the workers so every rank joins the head's new rendezvous store, then a readback of the COMPLETE realization through each container's own inspect -- every field the create spec states, the effective --node-rank off that container's argv, and NCCL's typed transport verdict on that incarnation -- plus the head's front door answering with this arm's served model, and then commit or a rollback of the whole arm -- and it is a separate mode because it reloads a 328 GB arm and nobody should reach it by asking for the pair units; spark_runtime_image_probe pulls the pinned runtime image on the selected Spark and reads its capabilities from inside its own digest, changing nothing; spark_v41_checkpoint_materialize fetches the admitted published DeepSeek V4.1 files onto the selected Group A Spark (about 510 GB; spark_v41_row_store_encode encodes the eight Engram row stores from the verified shards on the selected Group A Spark and reads each store's sha256; spark_v41_row_store_readback reads those stores back at their header, first and last record and every rank seam, with the published source rows at the same rows, and writes nothing; spark_v41_engram_differential compares upstream's Engram lookup kernel with the design-B file-backed lookup over sampled real rows of every row store, byte for byte, and writes nothing; it states the requirement and refuses before fetching when the disk cannot hold it), publishes each only after its sha256 matches the manifest, leaves a present file with the right digest alone and refuses one with the wrong digest, and reads the storage-backed Engram spans from the verified shards; a transfer runs detached and a rerun reattaches; spark_v41_runtime_image_build PRODUCES the DeepSeek V4.1 image on the selected Spark -- it verifies the candidate's three FlashInfer wheels against the digests the candidate keys, converges the patched source tree, builds from it, reads the produced configuration digest back from inside the image through the probe route, and admits that digest against the candidate's own recipe, refusing a digest that does not recompute from it -- and it is a separate mode from the probe because it occupies one host for hours where the probe occupies it for minutes; spark_v41_runtime_image_distribute moves that produced image, named by the configuration digest its production receipt read back, from the host that receipt names to the selected Group A Spark -- save, scp through the executor, load -- after stating its size against every filesystem a copy lands on, leaves a target already holding the digest untouched, refuses a target holding a different image under the tag, and refuses unless the target's image inspect Id reads back as that digest; spark_v41_group_a_launch reads the production image back under its tag on every Group A host, reads its registry inside its digest and every host's occupancy, and only when Group A is suspended for this candidate with every host held and vacant stages the Engram manifest and applies the V4.1 four-rank arm as one transaction at the capacity measurement's shape -- the target names only the session host; host_reset_return drives a rostered reset subject through its controller and measures the return FROM A PEER, and takes reset_observer rather than host because the observer must not be the subject; runner_host_file_observe reads the runner teardown drop-in, the needrestart deferral and the loaded teardown on the selected host as its administrator and writes nothing; runner_host_file_converge writes whichever of those two files differs, reloads systemd only if the drop-in changed, and refuses unless the manager then reports the declared teardown; microvm_controller_install writes the microVM slot controller's root-owned release locus (gunbc + sources + Firecracker + jailer) and the gunbc-microvm-slot@ template unit and the gunbc-microvm-slot-reserve broker unit on srv1 and starts neither; microvm_slot_reserve starts that broker unit once on srv1, which reserves the shakedown cell through the fabric broker route from inside the root process (slot, demand and offer derived from the model, never inputs), and uploads that invocation's reservation receipt, failing unless the reservation committed; microvm_slot_start starts the shakedown slot's controller unit once on srv1 (the instance is derived from the model, never an input), waits for it bounded by the unit's own stop timeout, and uploads that invocation's controller receipt; microvm_runner_group_ensure (srv1 only) reads the organization's runner groups and, only when the microvm-shakedown group is absent, files ONE operator approval, creates it restricted to the shakedown workflow on the default branch, and refuses unless the readback holds that restriction required: true - options: [plan, launch_environment_plan, allocation_store_plan, apply, org_actions_observe, app_control_plane_observe, microvm_host_converge, microvm_network_observe, microvm_network_apply, guest_image_observe, guest_image_converge, microvm_boot_probe, spark_grants, spark_bootstrap, spark_serving_apply, spark_native_serving_apply, spark_runtime_image_probe, spark_v41_checkpoint_materialize, spark_v41_row_store_encode, spark_v41_row_store_readback, spark_v41_engram_differential, spark_v41_runtime_image_build, spark_v41_runtime_image_distribute, spark_v41_group_a_launch, dashboard_deploy, approval_broker_dark_install, microvm_controller_install, microvm_slot_reserve, microvm_slot_start, rlm_launch_deployment_receipt, host_reset_return, runner_host_file_observe, runner_host_file_converge, site_pxe_edge_observe, site_pxe_edge_converge, runner_password_session_tool_converge, runner_browser_toolchain_converge, r2_mint_preflight, r2_object_write_mint, org_runner_roster_observe, approval_keyring_converge, approval_device_enrolment_code_issue, mtcollins1_boot, mtcollins1_fan_observe, mtcollins1_census_image_publish, mtcollins1_census_member_readback, host_credential_custody_converge, app_key_version_verify, r2_bucket_ensure, r2_bucket_admin_mint, fabric_writer_identity_observe, pair_serving_d0, microvm_runner_group_ensure, gcp_iam_converge, namecheap_observe] + options: [plan, launch_environment_plan, allocation_store_plan, apply, org_actions_observe, app_control_plane_observe, microvm_host_converge, microvm_network_observe, microvm_network_apply, guest_image_observe, guest_image_converge, microvm_boot_probe, spark_grants, spark_bootstrap, spark_serving_apply, spark_native_serving_apply, spark_runtime_image_probe, spark_v41_checkpoint_materialize, spark_v41_row_store_encode, spark_v41_row_store_readback, spark_v41_engram_differential, spark_v41_runtime_image_build, spark_v41_runtime_image_distribute, spark_v41_group_a_launch, dashboard_deploy, approval_broker_dark_install, microvm_controller_install, microvm_slot_reserve, microvm_slot_start, rlm_launch_deployment_receipt, host_reset_return, runner_host_file_observe, runner_host_file_converge, site_pxe_edge_observe, site_pxe_edge_converge, runner_password_session_tool_converge, runner_browser_toolchain_converge, r2_mint_preflight, r2_object_write_mint, org_runner_roster_observe, approval_keyring_converge, approval_device_enrolment_code_issue, mtcollins1_boot, mtcollins1_fan_observe, mtcollins1_ui_bundle_observe, mtcollins1_census_image_publish, mtcollins1_census_member_readback, host_credential_custody_converge, app_key_version_verify, r2_bucket_ensure, r2_bucket_admin_mint, fabric_writer_identity_observe, pair_serving_d0, microvm_runner_group_ensure, gcp_iam_converge, namecheap_observe] type: choice target: description: "Spark target host for the spark_* modes, naming the administrator credential the run materializes (any rostered Spark: srv5, srv6, srv7, srv8, srv9, srv10, srv11, srv12); apply reads the subject off the plan artifact" @@ -858,6 +858,38 @@ jobs: retention-days: 30 if: github.event.inputs.mode == 'mtcollins1_fan_observe' timeout-minutes: 10 + - name: "Mt. Collins UI bundle: firmware revision, then the served source.min.js and its sha256 (reads only)" + id: mtcollins1_ui_bundle_observe + run: |- + # 🟡 dissolve-on: gunbc_ci_mtcollins1_fan_observe_invoke - orch-emitted foreign-executor (GitHub Actions run:) credential runner: WIF access token by env, ONE pinned BMC secret version fetched over curl through the shared gunbc_ci_mtcollins1_bmc_credential_fetch_steps, a 0600 file under RUNNER_TEMP with a trap armed BEFORE the credential touches disk. The pipeline steps are modeled but each step body is a shell string built by concat, so the transport itself remains hand-shell; DISSOLVES WHEN the runner is authored as v2.extdeps.languages.bash_build nodes (typed, grammar-quoted words; command substitution; assignment; pipe; if/test; redirect; || true) emitted by v2.workflow.bash_emit bash_emit_stmts -- a route AVAILABLE today (#12422 retired the sibling pack runner on it), so this migration is unauthored, not blocked on a missing capability; set -euo pipefail, umask, export and trap are ordinary commands on that route, and the trap body is itself built from nodes and passed as one grammar-quoted word, so no new orchestration intent is a prerequisite. + set -euo pipefail + umask 077 + HDR_FILE="$RUNNER_TEMP/mtcollins1-fan-auth-header" + RESP_FILE="$RUNNER_TEMP/mtcollins1-fan-sm.json" + DEST_FILE="$RUNNER_TEMP/mtcollins1-bmc-credential" + trap 'rm -f "$HDR_FILE" "$RESP_FILE" "$DEST_FILE"' EXIT + printf 'Authorization: Bearer %s\n' "$WIF_ACCESS_TOKEN" > "$HDR_FILE" + curl -sSf --connect-timeout 10 --max-time 60 -o "$RESP_FILE" -H @"$HDR_FILE" "https://secretmanager.googleapis.com/v1/projects/gunbai-secrets/secrets/bmc-mtcollins1-gunbc/versions/2:access" && python3 -c 'import sys,json,base64; sys.stdout.buffer.write(base64.b64decode(json.load(open(sys.argv[1]))["payload"]["data"]))' "$RESP_FILE" > "$DEST_FILE" + chmod 600 "$DEST_FILE" + export GUNBC_MTCOLLINS1_BMC_CREDENTIAL_FILE="$DEST_FILE" + ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) + "$ROOT/target/release/gunbc" run --source-root "$ROOT/dag" --source-root "$ROOT/src/v2" --entry dag/gunbc/machine_intake/mtcollins1_ui_bundle_observe.dag --function mtcollins1_ui_bundle_observe_wet + cat "$ROOT/target/mtcollins1-ui-bundle-receipt.txt" + env: + WIF_ACCESS_TOKEN: ${{ steps.wif_auth.outputs.access_token }} + if: github.event.inputs.mode == 'mtcollins1_ui_bundle_observe' + timeout-minutes: 5 + - name: Upload Mt. Collins UI bundle bytes and receipt + id: mtcollins1_ui_bundle_observe_upload + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f + with: + name: mtcollins1-ui-bundle + path: target/mtcollins1-ui-bundle-* + if-no-files-found: error + retention-days: 90 + compression-level: 0 + if: always() && github.event.inputs.mode == 'mtcollins1_ui_bundle_observe' + timeout-minutes: 10 - name: "Fabric writer identity: the login this host presents at the fabric DB's served door (reads only)" id: fabric_writer_identity_observe run: |- diff --git a/dag/extdeps/bmc/megarac.dag b/dag/extdeps/bmc/megarac.dag index 79cb1eeed65..f5b2b2ad756 100644 --- a/dag/extdeps/bmc/megarac.dag +++ b/dag/extdeps/bmc/megarac.dag @@ -615,3 +615,31 @@ service megarac.Media { } } } + +// THE FIRMWARE'S OWN UI BUNDLE, SERVED AT A FIXED PATH. The SP-X web UI is one minified bundle the +// login page loads before any session exists, so the GET carries no cookie and no token and opens no +// session to release. The codes this module cites as "recovered from source.min.js" (start-media's +// 13410/13460, the served api/ surface, the KVM wire) were read from these bytes; the operation is the +// route that re-reads them instead of a hand-run probe. +// +// THE BYTES ARE WRITTEN AS SERVED. `Accept-Encoding: gzip` without --compressed asks for the encoding +// the 2026-09-27 read recorded (gzip) and leaves it undecoded, so a digest of dest_file is a digest of +// the served bytes, comparable with that read. stdout carries only the write-out: the HTTP status and +// the byte count, space-separated on one line. +data megarac_ui_bundle_path: NonEmptyStr = "/source.min.js" + +service megarac.Ui { + + operation GetServedBundle { + input { bmc_host: NonEmptyStr, bundle_path: NonEmptyStr, dest_file: NonEmptyStr, max_time: NonEmptyStr } + output { writeout: String from "stdout", stderr: String from "stderr", exit_code: Int from "exit_code", success: Bool from "exit_success" } + readonly + transport shell { + argv: ["curl", "--fail-with-body", "-sS", "-k", "--max-time", "{max_time}", "-H", "Accept-Encoding: gzip", "-o", "{dest_file}", "-w", "%\{http_code} %\{size_download}", "https://{bmc_host}{bundle_path}"] + } + exit { + 0 => Unit + nonzero => String "megarac UI bundle GET failed" + } + } +} diff --git a/dag/gunbc/ci/ci_spec.dag b/dag/gunbc/ci/ci_spec.dag index 9c2d4952a9a..94d522a1390 100644 --- a/dag/gunbc/ci/ci_spec.dag +++ b/dag/gunbc/ci/ci_spec.dag @@ -75,6 +75,7 @@ import gunbc.machine_intake_mtcollins1_fan_observe { mtcollins1_fan_credential_p import gunbc.fabric_writer_identity_observe { fabric_writer_identity_receipt_path } import gunbc.machine_intake_mtcollins1_census_image_publish { mtcollins1_census_image_receipt_path } import gunbc.machine_intake_mtcollins1_census_member_readback { census_member_readback_receipt_path } +import gunbc.machine_intake_mtcollins1_ui_bundle_observe { mtcollins1_ui_bundle_receipt_path } import std.dissolution { DissolutionCondition, dissolution_description, unbound_dissolution } @@ -995,6 +996,11 @@ data gunbc_ci_mtcollins1_fan_observe_target: GunbcRunStepTarget = GunbcRunStepTa function: "mtcollins1_fan_observe_wet", } +data gunbc_ci_mtcollins1_ui_bundle_observe_target: GunbcRunStepTarget = GunbcRunStepTarget { + entry: "dag/gunbc/machine_intake/mtcollins1_ui_bundle_observe.dag", + function: "mtcollins1_ui_bundle_observe_wet", +} + data gunbc_ci_mtcollins1_census_image_publish_target: GunbcRunStepTarget = GunbcRunStepTarget { entry: "dag/gunbc/machine_intake/mtcollins1_census_image_publish.dag", function: "mtcollins1_census_image_publish_wet", @@ -1281,6 +1287,7 @@ fn gunbc_run_step_targets() -> List { gunbc_ci_host_reset_return_target, gunbc_ci_host_reset_dispatch_admission_target, gunbc_ci_mtcollins1_fan_observe_target, + gunbc_ci_mtcollins1_ui_bundle_observe_target, gunbc_ci_mtcollins1_census_image_publish_target, gunbc_ci_mtcollins1_census_member_readback_target, gunbc_ci_spark_grant_install_target, @@ -1826,6 +1833,33 @@ fn gunbc_ci_mtcollins1_fan_observe_invoke() -> String { ) } +// THE UI BUNDLE LANE RUNS ON THE FAN LANE'S PRELUDE, NOT A COPY OF IT. It needs exactly what the fan +// series needs -- the one IPMI credential, for `mc info` -- and the bundle GET itself carries none, so +// a second prelude would be a second authority for the same materialization. It is the same +// hand-shell transport and carries the same marker and trigger. +data gunbc_ci_mtcollins1_ui_bundle_observe_shell_emit_scaffold: Disposition = Scaffold { + dissolves_to: SingleAuthority, + bind: DeclarationRef { + module_path: "gunbc.ci_spec", + decl_name: "gunbc_ci_mtcollins1_ui_bundle_observe_invoke", + field: WholeDeclaration + } +} + +fn gunbc_ci_mtcollins1_ui_bundle_observe_invoke() -> String { + concat( + concat("# ", concat(dissolution_description(condition: gunbc_ci_mtcollins1_fan_observe_shell_emit_dissolution_trigger), "\n")), + gunbc_run_step_script_with_prelude( + prelude: gunbc_ci_mtcollins1_fan_observe_credential_prelude(), + source_roots: witness_layer_roots, + entry: gunbc_ci_mtcollins1_ui_bundle_observe_target.entry, + function: gunbc_ci_mtcollins1_ui_bundle_observe_target.function, + claim_run: false, + receipt_rel: mtcollins1_ui_bundle_receipt_path + ) + ) +} + // The in-run ssh-agent teardown — a FRESH per-job effect (each isolated job starts and must kill // its own agent; nothing is memoizable across jobs), named so the workflow step and the // materialization gate's fresh-effect list reference ONE authority (§3), rather than an inline diff --git a/dag/gunbc/fleet/fleet_converge_workflow.dag b/dag/gunbc/fleet/fleet_converge_workflow.dag index 1f5e905826f..66e621be2c4 100644 --- a/dag/gunbc/fleet/fleet_converge_workflow.dag +++ b/dag/gunbc/fleet/fleet_converge_workflow.dag @@ -27,6 +27,7 @@ import gunbc.fleet.organization_runner_roster_read { organization_runner_roster_ import gunbc.cloudflare.r2_permission_group_observe { r2_mint_preflight_receipt_path } import gunbc.cloudflare.r2_bucket_ensure { r2_bucket_ensure_receipt_path } import gunbc.machine_intake_mtcollins1_fan_observe { mtcollins1_fan_observation_receipt_path } +import gunbc.machine_intake_mtcollins1_ui_bundle_observe { mtcollins1_ui_bundle_bytes_path, mtcollins1_ui_bundle_receipt_path } import gunbc.fabric_writer_identity_observe { fabric_writer_identity_receipt_path } import gunbc.machine_intake_mtcollins1_census_image_publish { mtcollins1_census_image_receipt_path } import gunbc.machine_intake_mtcollins1_census_member_readback { census_member_readback_receipt_path } @@ -123,6 +124,7 @@ import gunbc.ci_spec { gunbc_ci_app_key_version_verify_mint_script, gunbc_ci_app_key_version_verify_verdict_invoke, gunbc_ci_mtcollins1_fan_observe_invoke, + gunbc_ci_mtcollins1_ui_bundle_observe_invoke, gunbc_ci_fabric_writer_identity_observe_invoke, gunbc_ci_mtcollins1_census_image_publish_invoke, gunbc_ci_mtcollins1_census_member_readback_invoke, @@ -296,6 +298,7 @@ type FleetConvergeWorkflowMode | MtCollins1Boot | PairServingD0 | MtCollins1FanObserve + | MtCollins1UiBundleObserve | FabricWriterIdentityObserve | MtCollins1CensusImagePublish | MtCollins1CensusMemberReadback @@ -356,6 +359,7 @@ fn fleet_converge_workflow_mode_wire(mode: FleetConvergeWorkflowMode) -> String NamecheapObserve => "namecheap_observe" PairServingD0 => "pair_serving_d0" MtCollins1FanObserve => "mtcollins1_fan_observe" + MtCollins1UiBundleObserve => "mtcollins1_ui_bundle_observe" FabricWriterIdentityObserve => "fabric_writer_identity_observe" MtCollins1CensusImagePublish => "mtcollins1_census_image_publish" MtCollins1CensusMemberReadback => "mtcollins1_census_member_readback" @@ -385,7 +389,7 @@ fn fleet_converge_spark_target_description() -> String { ], "") } -data fleet_converge_workflow_modes: List = [FullHostPlan, LaunchEnvironmentPlan, AllocationStorePlan, FleetApply, OrgActionsObserve, AppControlPlaneObserve, MicrovmHostConverge, MicrovmNetworkObserve, MicrovmNetworkApply, GuestImageObserve, GuestImageConverge, MicrovmBootProbe, SparkGrants, SparkBootstrap, SparkServingApply, SparkNativeServingApply, SparkRuntimeImageProbe, SparkV41CheckpointMaterialize, SparkV41RowStoreEncode, SparkV41RowStoreReadback, SparkV41EngramDifferential, SparkV41RuntimeImageBuild, SparkV41RuntimeImageDistribute, SparkV41GroupALaunch, DashboardDeploy, ApprovalBrokerDarkInstall, MicrovmControllerInstall, MicrovmSlotReserve, MicrovmSlotStart, RlmLaunchDeploymentReceipt, HostResetReturn, RunnerHostFileObserve, RunnerHostFileConverge, SitePxeEdgeObserve, SitePxeEdgeConverge, RunnerPasswordSessionToolConverge, RunnerBrowserToolchainConverge, R2MintPreflight, R2ObjectWriteMint, OrgRunnerRosterObserve, ApprovalKeyringConverge, ApprovalDeviceEnrolmentCodeIssue, MtCollins1Boot, MtCollins1FanObserve, MtCollins1CensusImagePublish, MtCollins1CensusMemberReadback, HostCredentialCustodyConverge, AppKeyVersionVerify, R2BucketEnsure, R2BucketAdminMint, FabricWriterIdentityObserve, PairServingD0, MicrovmRunnerGroupEnsure, GcpIamConverge, NamecheapObserve] +data fleet_converge_workflow_modes: List = [FullHostPlan, LaunchEnvironmentPlan, AllocationStorePlan, FleetApply, OrgActionsObserve, AppControlPlaneObserve, MicrovmHostConverge, MicrovmNetworkObserve, MicrovmNetworkApply, GuestImageObserve, GuestImageConverge, MicrovmBootProbe, SparkGrants, SparkBootstrap, SparkServingApply, SparkNativeServingApply, SparkRuntimeImageProbe, SparkV41CheckpointMaterialize, SparkV41RowStoreEncode, SparkV41RowStoreReadback, SparkV41EngramDifferential, SparkV41RuntimeImageBuild, SparkV41RuntimeImageDistribute, SparkV41GroupALaunch, DashboardDeploy, ApprovalBrokerDarkInstall, MicrovmControllerInstall, MicrovmSlotReserve, MicrovmSlotStart, RlmLaunchDeploymentReceipt, HostResetReturn, RunnerHostFileObserve, RunnerHostFileConverge, SitePxeEdgeObserve, SitePxeEdgeConverge, RunnerPasswordSessionToolConverge, RunnerBrowserToolchainConverge, R2MintPreflight, R2ObjectWriteMint, OrgRunnerRosterObserve, ApprovalKeyringConverge, ApprovalDeviceEnrolmentCodeIssue, MtCollins1Boot, MtCollins1FanObserve, MtCollins1UiBundleObserve, MtCollins1CensusImagePublish, MtCollins1CensusMemberReadback, HostCredentialCustodyConverge, AppKeyVersionVerify, R2BucketEnsure, R2BucketAdminMint, FabricWriterIdentityObserve, PairServingD0, MicrovmRunnerGroupEnsure, GcpIamConverge, NamecheapObserve] // WHICH SCOPE A MODE SELECTS, WHERE IT SELECTS ONE AT ALL. // // EVERY MODE IS NAMED, AND THE WILDCARD IS DELIBERATELY ABSENT. A `_ => none` would read the same @@ -458,6 +462,7 @@ fn fleet_converge_mode_scope(mode: FleetConvergeWorkflowMode) -> FleetConvergeSc NamecheapObserve => none PairServingD0 => none MtCollins1FanObserve => none + MtCollins1UiBundleObserve => none FabricWriterIdentityObserve => none MtCollins1CensusImagePublish => none MtCollins1CensusMemberReadback => none @@ -586,6 +591,7 @@ fn fleet_converge_mode_fleet_ssh_key_demand(mode: FleetConvergeWorkflowMode) -> MtCollins1Boot => FleetSshKeyConsumed PairServingD0 => FleetSshKeyConsumed MtCollins1FanObserve => FleetSshKeyNotConsumed + MtCollins1UiBundleObserve => FleetSshKeyNotConsumed FabricWriterIdentityObserve => FleetSshKeyNotConsumed MtCollins1CensusImagePublish => FleetSshKeyConsumed MtCollins1CensusMemberReadback => FleetSshKeyConsumed @@ -1208,6 +1214,7 @@ fn fleet_converge_mode_mutation_domain(mode: FleetConvergeWorkflowMode) -> Fleet MtCollins1Boot => ExecutorDomain PairServingD0 => ArmDomain { group: fleet_arm_mutation_group_deepseek_group_a } MtCollins1FanObserve => ExecutorDomain + MtCollins1UiBundleObserve => ExecutorDomain FabricWriterIdentityObserve => ExecutorDomain MtCollins1CensusImagePublish => ExecutorDomain MtCollins1CensusMemberReadback => ExecutorDomain @@ -2071,6 +2078,39 @@ fn fleet_converge_mtcollins1_fan_observe_step() -> Step { } } +// MT. COLLINS' OWN UI BUNDLE AND ITS DIGEST (gunbc.machine_intake_mtcollins1_ui_bundle_observe): the +// firmware revision over IPMI, then the served source.min.js bytes, only under revision 0.32. Reads +// only, no web session. The receipt and the bytes are uploaded whatever the outcome, because a refused +// run's receipt is the one that says why it holds no bytes; a step condition without a status +// function is implicitly success() and would drop exactly that receipt. +data fleet_converge_mtcollins1_ui_bundle_observe_step_if: String = fleet_converge_mode_step_if(mode: MtCollins1UiBundleObserve) + +fn fleet_converge_mtcollins1_ui_bundle_observe_step() -> Step { + RunStep { + name: Present { value: "Mt. Collins UI bundle: firmware revision, then the served source.min.js and its sha256 (reads only)" }, + id: Present { value: "mtcollins1_ui_bundle_observe" }, + run: gunbc_ci_mtcollins1_ui_bundle_observe_invoke(), + shell: none, + env: Present { value: [ + kv(key: "WIF_ACCESS_TOKEN", value: yaml_string(s: "${{ steps.wif_auth.outputs.access_token }}")), + ] }, + working_directory: none, + if_condition: Present { value: fleet_converge_mtcollins1_ui_bundle_observe_step_if }, + continue_on_error: none, + timeout_minutes: Present { value: gunbc_ci_aux_step_timeout_minutes } + } +} + +fn fleet_converge_mtcollins1_ui_bundle_observe_upload_step() -> Step { + fleet_converge_receipt_upload_step( + id: "mtcollins1_ui_bundle_observe_upload", + name: "Upload Mt. Collins UI bundle bytes and receipt", + artifact: "mtcollins1-ui-bundle", + path: "target/mtcollins1-ui-bundle-*", + if_condition: join(["always() && ", fleet_converge_mtcollins1_ui_bundle_observe_step_if], "") + ) +} + // THE READING THE WRITER-ROSTER WALL WAITS FOR (gunbc.fabric_writer_identity_observe): from the // fleet host the dispatch names, through tailscale serve, what Tailscale-User-Login the fabric DB's // door sees. Reads only; the receipt is the roster's ground. Dispatched once per fleet host. @@ -3423,6 +3463,8 @@ fn fleet_converge_job() -> Job { fleet_converge_app_key_version_verify_receipt_upload_step(), fleet_converge_mtcollins1_fan_observe_step(), fleet_converge_mtcollins1_fan_observe_receipt_upload_step(), + fleet_converge_mtcollins1_ui_bundle_observe_step(), + fleet_converge_mtcollins1_ui_bundle_observe_upload_step(), fleet_converge_fabric_writer_identity_observe_step(), fleet_converge_fabric_writer_identity_observe_receipt_upload_step(), fleet_converge_pair_serving_d0_step(), @@ -3667,6 +3709,7 @@ fn fleet_converge_mode_job_id(mode: FleetConvergeWorkflowMode) -> NonEmptyStr { ApprovalDeviceEnrolmentCodeIssue => fleet_converge_shared_job_id MtCollins1Boot => "mtcollins1-boot" as NonEmptyStr MtCollins1FanObserve => fleet_converge_shared_job_id + MtCollins1UiBundleObserve => fleet_converge_shared_job_id MtCollins1CensusImagePublish => fleet_converge_shared_job_id MtCollins1CensusMemberReadback => fleet_converge_shared_job_id HostCredentialCustodyConverge => fleet_converge_shared_job_id diff --git a/dag/gunbc/machine_intake/megarac_served_ui_catalog_observation.dag b/dag/gunbc/machine_intake/megarac_served_ui_catalog_observation.dag index 95116b93386..2bbb9e9c70a 100644 --- a/dag/gunbc/machine_intake/megarac_served_ui_catalog_observation.dag +++ b/dag/gunbc/machine_intake/megarac_served_ui_catalog_observation.dag @@ -11,3 +11,10 @@ import std.types { NonEmptyStr } data megarac_spx_ui_surface_path: NonEmptyStr = "artifacts/bmc/mtcollins1-megarac-api-surface.txt" as NonEmptyStr data megarac_spx_ui_surface_sha256: NonEmptyStr = "4fc53fea3fe49bc3ed3b967511654223578d59d963546117ab524df11b419bcd" as NonEmptyStr + +// THE 2026-09-27 READ OF THE BUNDLE ITSELF, as its digest. extdeps.bmc.megarac cites this read for the +// screen-capture surfaces and the KVM wire; the bytes were not committed, so the digest is the only +// thing a later read can be compared with. gunbc.machine_intake_mtcollins1_ui_bundle_observe reports +// match or drift against it and does not refuse on drift: a different digest is a finding about the +// firmware's served UI, not a failed read. +data megarac_source_min_js_sha256_2026_09_27: NonEmptyStr = "5029fae278f7fc8f4dd4ad5eb8e4457e49fa25d4d0158d4bf9fbab09f57d4bf3" as NonEmptyStr diff --git a/dag/gunbc/machine_intake/mtcollins1_ui_bundle_observe.dag b/dag/gunbc/machine_intake/mtcollins1_ui_bundle_observe.dag new file mode 100644 index 00000000000..1e469bc5b32 --- /dev/null +++ b/dag/gunbc/machine_intake/mtcollins1_ui_bundle_observe.dag @@ -0,0 +1,163 @@ +module gunbc.machine_intake_mtcollins1_ui_bundle_observe + +import extdeps.shell +import extdeps.bmc.ipmi +import extdeps.bmc.megarac +import extdeps.tools.sha256sum +import std.algebra { trim } +import std.types { Bool, Int, List, NonEmptyStr, String } +import std.process { ExitSuccess, ProcessExit, exit_failure } +import extdeps.filesystem.filesystem_io { Filesystem } +import extdeps.tools.gnu_coreutils { coreutils_duration_operand } +import extdeps.bmc.megarac { megarac_ui_bundle_path } +import gunbc.machine_intake_mtcollins1_access_observation { mtcollins1_endpoint, mtcollins1_firmware } +import gunbc.machine_intake_mtcollins1_bmc_secure_observation { mtcollins1_secured_account } +import gunbc.machine_intake_mtcollins1_fan_observe { FanCredentialPathReady, FanCredentialPathUnset, FanCredentialPathEmpty, mtcollins1_fan_credential_path, mtcollins1_fan_credential_path_env } +import gunbc.machine_intake_mtcollins1_boot_diagnostic_bundle { mtcollins1_boot_ipmi_read_deadline, mtcollins1_boot_ipmi_kill_after } +import gunbc.machine_intake_megarac_media_attach { megarac_media_read_max_time_operand } +import gunbc.machine_intake_megarac_served_ui_catalog_observation { megarac_source_min_js_sha256_2026_09_27 } + +// ONE READ OF MT. COLLINS' OWN UI BUNDLE, SO A VENDOR CODE IS INTERPRETED FROM THE VENDOR'S SOURCE +// (operator, amended brief msg_20e45239 and decision msg_b3c77f62, 2026-09-30). The settings route +// answers cd_error_code 16 and nothing in the tree says what 16 names; the firmware's UI names its +// own codes in source.min.js, which is how start-media's 13410/13460 were recovered. This mode is the +// modeled route to those bytes: the controller's firmware revision is read over IPMI (`mc info`, +// read-only), the bundle is fetched only when that revision is the one this unit's facts are keyed +// on, and the served bytes, their sha256 and the comparison with the 2026-09-27 read are the receipt. +// +// NOTHING IS WRITTEN TO THE CONTROLLER AND NO WEB SESSION IS OPENED. The bundle is what the login page +// loads before a session exists, so the GET carries no credential (extdeps.bmc.megarac +// megarac.Ui.GetServedBundle); the only credential this run materializes is the IPMI one `mc info` +// needs, through the same prelude the fan observation uses. No unit hold is taken: like the fan +// series, nothing here changes chassis, media or boot state. + +data mtcollins1_ui_bundle_bytes_path: String = "target/mtcollins1-ui-bundle-source.min.js" + +data mtcollins1_ui_bundle_receipt_path: String = "target/mtcollins1-ui-bundle-receipt.txt" + +// THE REVISION AS `mc info` PRINTS IT: the value after the colon on the `Firmware Revision` line. +fn firmware_revision_of_mc_info(stdout: String) -> String? { + let lines = filter(split(s: stdout, delimiter: "\n"), l => starts_with(s: trim(s: l), prefix: "Firmware Revision")) + match lines.first() { + Absent => none + Present { value: line } => { + let after = split(s: line, delimiter: ":").skip(n: 1) + let v = trim(s: join(after, ":")) + if v == "" { none } else { Present { value: v } } + } + } +} + +// THE BUNDLE IS FETCHED ONLY UNDER THE REVISION THE UNIT'S FACTS ARE KEYED ON. Every code this +// module exists to recover is a 0.32 fact (mtcollins1_firmware); bytes from another build would be +// read as 0.32's table. +type UiBundleFirmwareStanding + = UiBundleFirmwareExpected { revision: NonEmptyStr } + | UiBundleFirmwareDiffers { revision: NonEmptyStr, expected: NonEmptyStr } + | UiBundleFirmwareUnread { detail: String } + +fn ui_bundle_firmware_standing(success: Bool, stdout: String, exit_code: Int, stderr: String) -> UiBundleFirmwareStanding { + if !success { + UiBundleFirmwareUnread { detail: join(["ipmitool mc info exited ", to_string(exit_code), ": ", trim(s: stderr)], "") } + } else { + match firmware_revision_of_mc_info(stdout: stdout) { + Absent => UiBundleFirmwareUnread { detail: concat("mc info printed no Firmware Revision line: ", stdout) } + Present { value: r } => + if r == (mtcollins1_firmware.raw_version as String) { UiBundleFirmwareExpected { revision: r as NonEmptyStr } } + else { UiBundleFirmwareDiffers { revision: r as NonEmptyStr, expected: mtcollins1_firmware.raw_version } } + } + } +} + +// MATCH OR DRIFT AGAINST THE 2026-09-27 READ, REPORTED AND NEVER A REFUSAL: a different digest is a +// finding about the served UI, not a failed read. +type UiBundleDigestComparison + = UiBundleDigestMatches + | UiBundleDigestDrifted { cited: NonEmptyStr } + +fn ui_bundle_digest_comparison(observed: String) -> UiBundleDigestComparison { + if observed == (megarac_source_min_js_sha256_2026_09_27 as String) { UiBundleDigestMatches } + else { UiBundleDigestDrifted { cited: megarac_source_min_js_sha256_2026_09_27 } } +} + +fn ui_bundle_digest_comparison_text(c: UiBundleDigestComparison) -> String { + match c { + UiBundleDigestMatches => "MATCH with the 2026-09-27 read" + UiBundleDigestDrifted { cited: d } => concat("DRIFT from the 2026-09-27 read, which was ", d as String) + } +} + +fn ui_bundle_firmware_text(f: UiBundleFirmwareStanding) -> String { + match f { + UiBundleFirmwareExpected { revision: r } => concat("firmware revision ", concat(r as String, " (expected)")) + UiBundleFirmwareDiffers { revision: r, expected: e } => join(["firmware revision ", r as String, " is NOT the expected ", e as String, "; the bundle was not fetched"], "") + UiBundleFirmwareUnread { detail: d } => concat("firmware revision UNREAD, so the bundle was not fetched: ", d) + } +} + +// THE RECEIPT IS WRITTEN ON EVERY PATH THAT REACHED THE CONTROLLER, and the exit carries the same +// sentence, so a refused run's artifact says why it holds no bytes. +fn ui_bundle_conclude(lines: List, outcome: ProcessExit) -> ProcessExit { + let body = join(concat([concat("subject=", mtcollins1_endpoint.host as String), concat("bundle_path=", megarac_ui_bundle_path as String)], lines), "\n") + let kept = Filesystem.Write(path: mtcollins1_ui_bundle_receipt_path, content: concat(body, "\n")) + if kept.success { outcome } else { + match outcome { + ExitSuccess => exit_failure(reason: concat("mtcollins1 ui bundle: the bundle was read and its receipt could not be written: ", kept.error)) + other => other + } + } +} + +fn ui_bundle_firmware_refused(firmware: UiBundleFirmwareStanding) -> ProcessExit { + ui_bundle_conclude(lines: [concat("firmware=", ui_bundle_firmware_text(f: firmware))], outcome: exit_failure(reason: concat("mtcollins1 ui bundle: ", ui_bundle_firmware_text(f: firmware)))) +} + +fn mtcollins1_ui_bundle_observe_with(username: NonEmptyStr, password_file: NonEmptyStr) -> ProcessExit { + let mc = diagnostic.ipmi.Tool.McInfo( + bmc_host: mtcollins1_endpoint.host, + username: username, + password_file: password_file, + deadline: coreutils_duration_operand(d: mtcollins1_boot_ipmi_read_deadline) as NonEmptyStr, + kill_after: coreutils_duration_operand(d: mtcollins1_boot_ipmi_kill_after) as NonEmptyStr, + ) + let firmware = ui_bundle_firmware_standing(success: mc.success, stdout: mc.stdout, exit_code: mc.exit_code, stderr: mc.transport_stderr) + let fw_line = concat("firmware=", ui_bundle_firmware_text(f: firmware)) + match firmware { + UiBundleFirmwareExpected { revision: _ } => {} + UiBundleFirmwareDiffers { revision: _, expected: _ } => return ui_bundle_firmware_refused(firmware: firmware) + UiBundleFirmwareUnread { detail: _ } => return ui_bundle_firmware_refused(firmware: firmware) + } + let got = megarac.Ui.GetServedBundle( + bmc_host: mtcollins1_endpoint.host, + bundle_path: megarac_ui_bundle_path, + dest_file: mtcollins1_ui_bundle_bytes_path as NonEmptyStr, + max_time: megarac_media_read_max_time_operand(), + ) + let fetch_line = join(["fetch=exit ", to_string(got.exit_code), " writeout(http_code size_download)=", trim(s: got.writeout), if trim(s: got.stderr) == "" { "" } else { concat(" stderr=", trim(s: got.stderr)) }], "") + if !got.success { + return ui_bundle_conclude(lines: [fw_line, fetch_line], outcome: exit_failure(reason: concat("mtcollins1 ui bundle: the bundle GET did not succeed: ", fetch_line))) + } + let digest = sha256sum.Sha256.DigestFile(path: mtcollins1_ui_bundle_bytes_path as NonEmptyStr) + let observed = match split(s: trim(s: digest.line), delimiter: " ").first() { Present { value: d } => d Absent => "" } + if !digest.success || observed == "" { + return ui_bundle_conclude(lines: [fw_line, fetch_line], outcome: exit_failure(reason: concat("mtcollins1 ui bundle: the fetched bytes could not be digested: ", digest.line))) + } + ui_bundle_conclude( + lines: [fw_line, fetch_line, concat("sha256=", observed), concat("comparison=", ui_bundle_digest_comparison_text(c: ui_bundle_digest_comparison(observed: observed))), concat("bytes=", mtcollins1_ui_bundle_bytes_path)], + outcome: ExitSuccess, + ) +} + +// REFUSALS BEFORE THE FIRST REQUEST, EACH NAMING WHAT IS MISSING, exactly as the fan observation's. +fn mtcollins1_ui_bundle_observe_wet() -> ProcessExit +{ + match mtcollins1_secured_account() { + Absent => exit_failure(reason: "mtcollins1 ui bundle: the BMC is not BmcSecured, so this run holds no account to read the firmware revision with; contacting NO host") + Present { value: username } => + match mtcollins1_fan_credential_path() { + FanCredentialPathUnset => exit_failure(reason: join(["mtcollins1 ui bundle: no ", mtcollins1_fan_credential_path_env as String, " in the environment; contacting NO host"], "")) + FanCredentialPathEmpty => exit_failure(reason: join(["mtcollins1 ui bundle: ", mtcollins1_fan_credential_path_env as String, " is set but empty; contacting NO host"], "")) + FanCredentialPathReady { path: p } => mtcollins1_ui_bundle_observe_with(username: username, password_file: p) + } + } +} diff --git a/dag/test/claim/machine_intake/mtcollins1_ui_bundle_observe_witness_test.dag b/dag/test/claim/machine_intake/mtcollins1_ui_bundle_observe_witness_test.dag new file mode 100644 index 00000000000..e50d8a45a68 --- /dev/null +++ b/dag/test/claim/machine_intake/mtcollins1_ui_bundle_observe_witness_test.dag @@ -0,0 +1,68 @@ +module test.claim.machine_intake.mtcollins1_ui_bundle_observe_witness_test + +import std.types { Bool, String } +import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } +import gunbc.machine_intake_megarac_served_ui_catalog_observation { megarac_source_min_js_sha256_2026_09_27 } +import gunbc.machine_intake_mtcollins1_ui_bundle_observe { + UiBundleDigestDrifted, + UiBundleDigestMatches, + UiBundleFirmwareDiffers, + UiBundleFirmwareExpected, + UiBundleFirmwareUnread, + firmware_revision_of_mc_info, + ui_bundle_digest_comparison, + ui_bundle_firmware_standing, +} + +data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly + +// `ipmitool mc info` as it prints, with the revision a parameter so the pair differs in one value. +fn mc_info_with(revision: String) -> String { + join([ + "Device ID : 32", + "Device Revision : 1", + concat("Firmware Revision : ", revision), + "IPMI Version : 2.0", + "Manufacturer ID : 10876", + ], "\n") +} + +test fn the_revision_is_the_value_after_the_colon() -> Bool { + match firmware_revision_of_mc_info(stdout: mc_info_with(revision: "0.32")) { + Present { value: r } => r == "0.32" + Absent => false + } +} + +// THE DISCRIMINATING PAIR: one value differs, and only 0.32 admits the fetch. +test fn only_the_expected_revision_admits_the_fetch() -> Bool { + (match ui_bundle_firmware_standing(success: true, stdout: mc_info_with(revision: "0.32"), exit_code: 0, stderr: "") { + UiBundleFirmwareExpected { revision: r } => (r as String) == "0.32" + _ => false + }) + && (match ui_bundle_firmware_standing(success: true, stdout: mc_info_with(revision: "0.33"), exit_code: 0, stderr: "") { + UiBundleFirmwareDiffers { revision: r, expected: e } => (r as String) == "0.33" && (e as String) == "0.32" + _ => false + }) +} + +// An unanswered read and an answer with no revision are both unread, never a revision. +test fn an_unread_revision_never_admits_the_fetch() -> Bool { + (match ui_bundle_firmware_standing(success: false, stdout: "", exit_code: 124, stderr: "") { + UiBundleFirmwareUnread { detail: d } => string_contains(s: d, pattern: "124") + _ => false + }) + && (match ui_bundle_firmware_standing(success: true, stdout: "Device ID : 32", exit_code: 0, stderr: "") { + UiBundleFirmwareUnread { detail: _ } => true + _ => false + }) +} + +// DRIFT IS REPORTED, AND THE CITED DIGEST RIDES WITH IT. +test fn the_cited_digest_matches_and_any_other_drifts() -> Bool { + (match ui_bundle_digest_comparison(observed: megarac_source_min_js_sha256_2026_09_27 as String) { UiBundleDigestMatches => true _ => false }) + && (match ui_bundle_digest_comparison(observed: "0000000000000000000000000000000000000000000000000000000000000000") { + UiBundleDigestDrifted { cited: c } => c == megarac_source_min_js_sha256_2026_09_27 + _ => false + }) +} From e067378ab5612cd6da23b7d0d5d52727b8c2c0f7 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Wed, 30 Sep 2026 15:23:57 +0000 Subject: [PATCH 58/75] WIP (wind-down): supplied toolchain resolution, cwd-resolving filesystem model, hostname; KVM dry observer not yet built State at the operator wind-down, NOT green: - mtcollins1_boot_wet_on_srv1 is one call into mtcollins1_boot_on_srv1_resolving_toolchain, which takes the toolchain resolution as a function called where the observer starts (eager-owl-205 ruling A); the matrix supplies Ready/NotReady/Unresolved from production values. - gunbc.filesystem_model resolves relative paths against a cwd lens; mkdir -p and realpath -e bound. - os.Hostname.ReadShort answers srv1; the #12492 KVM wet witness world() builds through the constructors. - OPEN: the Ready arm stops at gunbc.owned_process.launch LaunchOwned -- the dry KVM observer (owned process record, journal written through #12767's kvm_journal_line, triggers, stop) is not built, so 11 matrix cases fail; the NotReady/Unresolved cases and their no-launch assertions are not yet written; re-measure the drop rows after. Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/gunbc/filesystem_model.dag | 103 +++++++++++++++--- .../mtcollins1_boot_dry_realization.dag | 25 ++++- .../machine_intake/mtcollins1_boot_run.dag | 28 +++-- ...mtcollins1_boot_acceptance_matrix_test.dag | 71 ++++++++++-- ...kvm_observer_protocol_wet_witness_test.dag | 19 ++-- .../claim/modeled_filesystem_witness_test.dag | 2 +- .../probe/unit_hold_proof_forged_probe.dag | 11 +- 7 files changed, 215 insertions(+), 44 deletions(-) diff --git a/dag/gunbc/filesystem_model.dag b/dag/gunbc/filesystem_model.dag index 28ccb5f41c6..479e4e84a5a 100644 --- a/dag/gunbc/filesystem_model.dag +++ b/dag/gunbc/filesystem_model.dag @@ -159,24 +159,35 @@ fn file_step(state: S, observation: FileExchangeObservation) -> OperationStep OperationObserved { observation: FileObserved { observation: observation }, state: state, elapsed: second(count: 0) } } -fn filesystem_bindings(get: fn(S) -> ModeledFilesystem, put: fn(S, ModeledFilesystem) -> S) -> List> { +// A RELATIVE PATH IS RESOLVED AGAINST THE PROCESS'S WORKING DIRECTORY, once, here: the model stores +// absolute paths only, and every binding -- read, list, delete, write, move, mkdir -p and realpath -- +// resolves its operands through this one rule before touching it, so a directory made relative and +// read back through its canonical absolute path is one entry, as it is on the host. The working +// directory is the caller's (process) state, supplied as a lens. +fn fs_resolved(cwd: String, path: String) -> String { + if starts_with(s: path, prefix: "/") { path } + else if cwd == "/" { concat("/", path) } + else { concat(concat(cwd, "/"), path) } +} + +fn filesystem_bindings(get: fn(S) -> ModeledFilesystem, put: fn(S, ModeledFilesystem) -> S, cwd: fn(S) -> String) -> List> { let reading = fn(state, call) { match operation_input_text(invocation: call.invocation, name: "path") { Absent => OperationHarnessFault { reason: "a filesystem read was dispatched without a path" as NonEmptyStr } - Present { value: path } => file_step(state: state, observation: fs_read(fs: get(state), path: path)) + Present { value: path } => file_step(state: state, observation: fs_read(fs: get(state), path: fs_resolved(cwd: cwd(state), path: path))) } } let listing = fn(state, call) { match operation_input_text(invocation: call.invocation, name: "path") { Absent => OperationHarnessFault { reason: "a filesystem list was dispatched without a path" as NonEmptyStr } - Present { value: path } => file_step(state: state, observation: fs_list(fs: get(state), path: path)) + Present { value: path } => file_step(state: state, observation: fs_list(fs: get(state), path: fs_resolved(cwd: cwd(state), path: path))) } } let deleting = fn(state, call) { match operation_input_text(invocation: call.invocation, name: "path") { Absent => OperationHarnessFault { reason: "a filesystem delete was dispatched without a path" as NonEmptyStr } Present { value: path } => { - let w = fs_delete(fs: get(state), path: path) + let w = fs_delete(fs: get(state), path: fs_resolved(cwd: cwd(state), path: path)) file_step(state: put(state, w.fs), observation: w.observation) } } @@ -185,22 +196,24 @@ fn filesystem_bindings(get: fn(S) -> ModeledFilesystem, put: fn(S, ModeledFil OperationBinding { at: filesystem_operation(operation: "Read"), handler: reading }, OperationBinding { at: filesystem_operation(operation: "List"), handler: listing }, OperationBinding { at: filesystem_operation(operation: "Delete"), handler: deleting }, - OperationBinding { at: filesystem_operation(operation: "Write"), handler: writing(get: get, put: put, create_new: false) }, - OperationBinding { at: filesystem_operation(operation: "WriteOwnerOnly"), handler: writing(get: get, put: put, create_new: false) }, - OperationBinding { at: filesystem_operation(operation: "WriteCreateNew"), handler: writing(get: get, put: put, create_new: true) }, - OperationBinding { at: filesystem_operation(operation: "WriteCreateNewWithMode"), handler: writing(get: get, put: put, create_new: true) }, - OperationBinding { at: shell_move_file_operation, handler: moving(get: get, put: put) }, + OperationBinding { at: filesystem_operation(operation: "Write"), handler: writing(get: get, put: put, cwd: cwd, create_new: false) }, + OperationBinding { at: filesystem_operation(operation: "WriteOwnerOnly"), handler: writing(get: get, put: put, cwd: cwd, create_new: false) }, + OperationBinding { at: filesystem_operation(operation: "WriteCreateNew"), handler: writing(get: get, put: put, cwd: cwd, create_new: true) }, + OperationBinding { at: filesystem_operation(operation: "WriteCreateNewWithMode"), handler: writing(get: get, put: put, cwd: cwd, create_new: true) }, + OperationBinding { at: shell_move_file_operation, handler: moving(get: get, put: put, cwd: cwd) }, + OperationBinding { at: shell_mkdir_parents_operation, handler: making_parents(get: get, put: put, cwd: cwd) }, + OperationBinding { at: shell_path_canonical_operation, handler: canonicalising(get: get, cwd: cwd) }, ] } -fn writing(get: fn(S) -> ModeledFilesystem, put: fn(S, ModeledFilesystem) -> S, create_new: Bool) -> fn(S, OperationCall) -> OperationStep { +fn writing(get: fn(S) -> ModeledFilesystem, put: fn(S, ModeledFilesystem) -> S, cwd: fn(S) -> String, create_new: Bool) -> fn(S, OperationCall) -> OperationStep { fn(state, call) { match operation_input_text(invocation: call.invocation, name: "path") { Absent => OperationHarnessFault { reason: "a filesystem write was dispatched without a path" as NonEmptyStr } Present { value: path } => match operation_input_text(invocation: call.invocation, name: "content") { Absent => OperationHarnessFault { reason: "a filesystem write was dispatched without content" as NonEmptyStr } Present { value: content } => { - let w = fs_write(fs: get(state), path: path, content: content, create_new: create_new) + let w = fs_write(fs: get(state), path: fs_resolved(cwd: cwd(state), path: path), content: content, create_new: create_new) file_step(state: put(state, w.fs), observation: w.observation) } } @@ -226,14 +239,14 @@ fn fs_move(fs: ModeledFilesystem, source: String, destination: String) -> Modele } } -fn moving(get: fn(S) -> ModeledFilesystem, put: fn(S, ModeledFilesystem) -> S) -> fn(S, OperationCall) -> OperationStep { +fn moving(get: fn(S) -> ModeledFilesystem, put: fn(S, ModeledFilesystem) -> S, cwd: fn(S) -> String) -> fn(S, OperationCall) -> OperationStep { fn(state, call) { match operation_input_text(invocation: call.invocation, name: "source") { Absent => OperationHarnessFault { reason: "a move was dispatched without a source" as NonEmptyStr } Present { value: source } => match operation_input_text(invocation: call.invocation, name: "destination") { Absent => OperationHarnessFault { reason: "a move was dispatched without a destination" as NonEmptyStr } Present { value: destination } => { - let m = fs_move(fs: get(state), source: source, destination: destination) + let m = fs_move(fs: get(state), source: fs_resolved(cwd: cwd(state), path: source), destination: fs_resolved(cwd: cwd(state), path: destination)) let exited = match m.observation { FileOperationSucceeded { byte_count: _, content: _ } => ShellProcessExited { exit_code: 0, stdout: "", stderr: "" } FileOperationFailed { kind: _, error: _ } => ShellProcessExited { exit_code: 1, stdout: "", stderr: join(["mv: cannot stat '", source, "': No such file or directory\n"], "") } @@ -244,3 +257,67 @@ fn moving(get: fn(S) -> ModeledFilesystem, put: fn(S, ModeledFilesystem) -> S } } } + +// extdeps.shell shell.Mkdir Parents: `mkdir -p `, which makes the directory and every missing +// ancestor, succeeds when it already exists, and fails -- exit 1 with mkdir's own words -- when a file +// stands where one of those directories would go. +data shell_mkdir_parents_operation: OperationRef = OperationRef { path: "dag/extdeps/shell.dag", service: "shell.Mkdir", operation: "Parents" } + +fn fs_ancestors(path: String) -> List { + let parts = filter(split(s: path, delimiter: "/"), w => w != "") + fold(parts, init: [], f: fn(acc, part) { + list_append(acc, match acc.last() { Present { value: prev } => concat(concat(prev, "/"), part) Absent => concat("/", part) }) + }) +} + +fn fs_make_parents(fs: ModeledFilesystem, path: String) -> ModeledFileWrite { + let chain = fs_ancestors(path: path) + let blocked = filter(chain, d => match fs_file(fs: fs, path: d) { Present { value: _ } => true Absent => false }) + match blocked.first() { + Present { value: b } => ModeledFileWrite { fs: fs, observation: failed_with(kind: FilesystemNotDirectory, message: concat("mkdir: cannot create directory: Not a directory: ", b)) } + Absent => ModeledFileWrite { + fs: ModeledFilesystem { directories: fold(chain, init: fs.directories, f: fn(acc, d) { if any_string(xs: acc, x: d) { acc } else { list_append(acc, d) } }), files: fs.files }, + observation: FileOperationSucceeded { byte_count: byte_size(count: 0), content: "" }, + } + } +} + +fn shell_exited_of(observation: FileExchangeObservation, stdout: String) -> ShellProcessExited { + match observation { + FileOperationSucceeded { byte_count: _, content: _ } => ShellProcessExited { exit_code: 0, stdout: stdout, stderr: "" } + FileOperationFailed { kind: _, error: e } => ShellProcessExited { exit_code: 1, stdout: "", stderr: concat(e, "\n") } + } +} + +fn making_parents(get: fn(S) -> ModeledFilesystem, put: fn(S, ModeledFilesystem) -> S, cwd: fn(S) -> String) -> fn(S, OperationCall) -> OperationStep { + fn(state, call) { + match operation_input_text(invocation: call.invocation, name: "path") { + Absent => OperationHarnessFault { reason: "mkdir -p was dispatched without a path" as NonEmptyStr } + Present { value: path } => { + let m = fs_make_parents(fs: get(state), path: fs_resolved(cwd: cwd(state), path: path)) + OperationObserved { observation: ShellObserved { observation: shell_exited_of(observation: m.observation, stdout: "") }, state: put(state, m.fs), elapsed: second(count: 0) } + } + } + } +} + +// extdeps.shell shell.Path Canonical: `realpath -e -- `, the absolute path of an existing file or +// directory, one newline; a path that does not exist fails with realpath's own words. The model holds no +// symlinks, so the canonical path is the resolved one. +data shell_path_canonical_operation: OperationRef = OperationRef { path: "dag/extdeps/shell.dag", service: "shell.Path", operation: "Canonical" } + +fn canonicalising(get: fn(S) -> ModeledFilesystem, cwd: fn(S) -> String) -> fn(S, OperationCall) -> OperationStep { + fn(state, call) { + match operation_input_text(invocation: call.invocation, name: "path") { + Absent => OperationHarnessFault { reason: "realpath was dispatched without a path" as NonEmptyStr } + Present { value: path } => { + let resolved = fs_resolved(cwd: cwd(state), path: path) + let fs = get(state) + let exists = fs_is_directory(fs: fs, path: resolved) || (match fs_file(fs: fs, path: resolved) { Present { value: _ } => true Absent => false }) + let exited = if exists { ShellProcessExited { exit_code: 0, stdout: concat(resolved, "\n"), stderr: "" } } + else { ShellProcessExited { exit_code: 1, stdout: "", stderr: join(["realpath: ", path, ": No such file or directory\n"], "") } } + OperationObserved { observation: ShellObserved { observation: exited }, state: state, elapsed: second(count: 0) } + } + } + } +} diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag index 328db81e665..d4e12ba6344 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag @@ -357,6 +357,28 @@ data sol_hold_activate_held_operation: OperationRef = OperationRef { operation: "ActivateHeld", } +// `hostname -s` on the worker: the entry is mtcollins1_boot_wet_on_srv1, so the worker it models is +// srv1, printed as hostname(1) prints the short name, with one newline. +data os_hostname_read_short_operation: OperationRef = OperationRef { + path: "dag/extdeps/tools/hostname.dag", + service: "os.Hostname", + operation: "ReadShort", +} + +data dry_worker_short_hostname: String = "srv1" + +// The runner's working directory, where the boot step runs: its checkout. Relative paths the route +// uses (the observer's artifacts directory, the retained target files) resolve against it. +data dry_worker_checkout: String = "/home/runner/work/gunbc/gunbc" + +fn hostname_handler(w: MtCollins1BootWorld, call: OperationCall) -> OperationStep { + OperationObserved { + observation: ShellObserved { observation: ShellProcessExited { exit_code: 0, stdout: concat(dry_worker_short_hostname, "\n"), stderr: "" } }, + state: w, + elapsed: second(count: 0), + } +} + data sol_hold_release_held_operation: OperationRef = OperationRef { path: "dag/gunbc/machine_intake/sol_hold.dag", service: "gunbc.machine_intake.sol_hold", @@ -365,7 +387,7 @@ data sol_hold_release_held_operation: OperationRef = OperationRef { fn mtcollins1_boot_dry_realization(identity: NonEmptyStr, initial: MtCollins1BootWorld, epoch: Second) -> OperationRealization { let bmc = concat(bmc_bindings(get: fn(w) { w.bmc }, put: with_bmc), megarac_bindings(get: fn(w) { w.media }, put: with_media)) - let files = filesystem_bindings(get: fn(w) { w.fs }, put: with_fs) + let files = filesystem_bindings(get: fn(w) { w.fs }, put: with_fs, cwd: fn(w) { dry_worker_checkout }) let local_commands = exact_invocation_binding(at: shell_exec_run_argv_operation, inputs: ["program", "arguments"], table: [ ModeledInvocation { words: local_command_words(command: env_prefixed_command(bindings: [EnvSet { name: "SSH_AUTH_SOCK", value: initial.agent.socket }], command: ssh_add_list_identities_command())), @@ -379,6 +401,7 @@ fn mtcollins1_boot_dry_realization(identity: NonEmptyStr, initial: MtCollins1Boo OperationBinding { at: sol_hold_activate_held_operation, handler: sol_activate_held_handler }, OperationBinding { at: sol_hold_release_held_operation, handler: sol_release_held_handler }, OperationBinding { at: linux_procfs_read_uptime_operation, handler: uptime_handler }, + OperationBinding { at: os_hostname_read_short_operation, handler: hostname_handler }, ] OperationRealization { identity: identity, diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_run.dag b/dag/gunbc/machine_intake/mtcollins1_boot_run.dag index 4b9c03942c1..7ff2dd08362 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_run.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_run.dag @@ -94,7 +94,7 @@ import std.dissolution { dissolution_description } import extdeps.tools.sleep { sleep_delay_seconds_second_carrier_projection } import extdeps.filesystem.filesystem_io { Filesystem } import gunbc.owned_process { owned_process_record, OwnedRecorded, OwnedUnrecorded } -import gunbc.runner_browser_toolchain { runner_browser_toolchain_here_wet } +import gunbc.runner_browser_toolchain { runner_browser_toolchain_here_wet, RunnerBrowserToolchainResolution } import gunbc.machine_intake_mtcollins1_kvm_still { KvmObserverStart, KvmObserverStarted, KvmObserverNotStarted, KvmObserverRecord, KvmJournalEvent, KvmHandoffAdmitted, KvmHandoffRefused, kvm_handoff_admission, kvm_observer_standing_now, kvm_standing_text, @@ -1751,7 +1751,7 @@ fn mtcollins1_boot_screen_liveness_lines(standing: KvmObserverStanding) -> List< // runner without the browser toolchain, a busy viewer seat, a mismatched subject or a lost connection // all stop the boot there, with that standing as the cause. It gates on the witness existing, never on // what the screen shows. -fn mtcollins1_boot_screen_start(password_file: String, attempt: String) -> KvmObserverStart { +fn mtcollins1_boot_screen_start(password_file: String, attempt: String, resolve_toolchain: fn() -> RunnerBrowserToolchainResolution) -> KvmObserverStart { match mtcollins1_bmc_username { Absent => KvmObserverNotStarted { reason: "mtcollins1's BMC is not BmcSecured, so no account is modeled to log in to the viewer with" } Present { value: user } => @@ -1760,7 +1760,7 @@ fn mtcollins1_boot_screen_start(password_file: String, attempt: String) -> KvmOb bmc_host: mtcollins1_endpoint.host, username: user, password_file: password_file, - toolchain: runner_browser_toolchain_here_wet(), + toolchain: resolve_toolchain(), attempt: attempt, ) } @@ -2153,6 +2153,7 @@ fn mtcollins1_boot_actuate( attempt: String, sol_pid_path: String, sol_capture_path: String, + resolve_toolchain: fn() -> RunnerBrowserToolchainResolution, ) -> MtCollins1BootActuation admit_callers: [ decl_ref(module_path: "gunbc.machine_intake_mtcollins1_boot_run", decl_name: "mtcollins1_boot_under_live_unit_hold"), @@ -2185,7 +2186,7 @@ fn mtcollins1_boot_actuate( let acquired_at = clock_now_probed_at_or_unknown() as String let p5_before = mtcollins1_boot_param5_under_hold(password_file: password_file) let p5_before_read = proc_uptime_read() - let screen = mtcollins1_boot_screen_start(password_file: password_file, attempt: attempt) + let screen = mtcollins1_boot_screen_start(password_file: password_file, attempt: attempt, resolve_toolchain: resolve_toolchain) let before_attach = mtcollins1_sol_supervised(stage: SolLostBeforeAttach, pid_path: sol_pid_path, capture_path: sol_capture_path, password_file: password_file, last_live_at: acquired_at) let media = match before_attach { SolLostAt { outcome: o } => MediaAttachNotAttempted { reason: sol_supervision_refusal_reason(outcome: o) } @@ -2324,9 +2325,10 @@ fn mtcollins1_boot_under_live_unit_hold( password_file: String, sol_pid_path: String, sol_capture_path: String, + resolve_toolchain: fn() -> RunnerBrowserToolchainResolution, ) -> MtCollins1BootActuation admit_callers: [ - decl_ref(module_path: "gunbc.machine_intake_mtcollins1_boot_run", decl_name: "mtcollins1_boot_wet_on_srv1"), + decl_ref(module_path: "gunbc.machine_intake_mtcollins1_boot_run", decl_name: "mtcollins1_boot_on_srv1_resolving_toolchain"), ] { match mtcollins1_boot_acquire_unit_hold(run_id: run_id) { @@ -2339,6 +2341,7 @@ fn mtcollins1_boot_under_live_unit_hold( attempt: run_id as String, sol_pid_path: sol_pid_path, sol_capture_path: sol_capture_path, + resolve_toolchain: resolve_toolchain, ) MtCollins1BootActuation { outcome: unit_hold_release(proof: p, outcome: act.outcome), media: act.media, handoff_media: act.handoff_media, end_media: act.end_media, stage: act.stage, override_before: act.override_before, override_after: act.override_after, power_after: act.power_after, timing: act.timing, screen: act.screen } } @@ -2540,7 +2543,18 @@ fn mtcollins1_boot_wet() -> ProcessExit // THE "BEFORE" SEL SNAPSHOT IS A READONLY READ taken once the credential is read, and before the unit hold is taken, so the delta brackets every controller write // the attempt makes (gunbc#12093). +// THE WET ENTRY IS ONE CALL: the runner's own browser-toolchain resolution into the entry that runs +// the boot. Nothing else lives on this side, so every step of the boot is the inner entry's and runs +// wherever it does (ruling of eager-owl-205 on gunbc#12533). The resolution is passed as a function and +// called where the observer starts, exactly where the boot resolved it before, so the route's order +// and phase clock are unchanged; a caller that supplies it (the boot acceptance matrix) supplies a +// resolution arm without running the readback, which keeps its own witnesses. fn mtcollins1_boot_wet_on_srv1() -> MtCollins1BootAttempt +{ + mtcollins1_boot_on_srv1_resolving_toolchain(resolve_toolchain: fn() { runner_browser_toolchain_here_wet() }) +} + +fn mtcollins1_boot_on_srv1_resolving_toolchain(resolve_toolchain: fn() -> RunnerBrowserToolchainResolution) -> MtCollins1BootAttempt { let cred = actions_variable_trimmed(name: host_reset_bmc_credential_path_env) if cred == "" { @@ -2581,7 +2595,7 @@ fn mtcollins1_boot_wet_on_srv1() -> MtCollins1BootAttempt let subject = mtcollins1_boot_subject(execution_revision: sha as NonEmptyStr) match mtcollins1_bmc_username { Absent => { - let act = mtcollins1_boot_under_live_unit_hold(run_id: run_id as NonEmptyStr, subject: subject, password_file: cred, sol_pid_path: sol_pid_path, sol_capture_path: sol_capture_path) + let act = mtcollins1_boot_under_live_unit_hold(run_id: run_id as NonEmptyStr, subject: subject, password_file: cred, sol_pid_path: sol_pid_path, sol_capture_path: sol_capture_path, resolve_toolchain: resolve_toolchain) MtCollins1BootAttempt { outcome: act.outcome, media: act.media, @@ -2599,7 +2613,7 @@ fn mtcollins1_boot_wet_on_srv1() -> MtCollins1BootAttempt Present { value: user } => { let sdr = mtcollins1_boot_sdr_cache(username: user, password_file: cred as NonEmptyStr, path: concat(cred, mtcollins1_boot_sdr_cache_suffix) as NonEmptyStr) let before = mtcollins1_boot_sel_snapshot(username: user, password_file: cred as NonEmptyStr, sdr: sdr) - let act = mtcollins1_boot_under_live_unit_hold(run_id: run_id as NonEmptyStr, subject: subject, password_file: cred, sol_pid_path: sol_pid_path, sol_capture_path: sol_capture_path) + let act = mtcollins1_boot_under_live_unit_hold(run_id: run_id as NonEmptyStr, subject: subject, password_file: cred, sol_pid_path: sol_pid_path, sol_capture_path: sol_capture_path, resolve_toolchain: resolve_toolchain) MtCollins1BootAttempt { outcome: act.outcome, media: act.media, diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index 13db7c2ddf0..38e726a1fa8 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -26,19 +26,27 @@ import v2.std.operation_realization { DispatchWorkerKilled, } import gunbc.machine_intake_mtcollins1_boot_run { - MtCollins1BootAttempt, mtcollins1_boot_wet_on_srv1, mtcollins1_boot_exit_reason, + MtCollins1BootAttempt, mtcollins1_boot_on_srv1_resolving_toolchain, mtcollins1_boot_exit_reason, ActuationNotPoweredOn, ActuationPoweredOn, ActuationCensusEnded, } import gunbc.machine_intake_mtcollins1_boot_authorization { mtcollins1_boot_medium, mtcollins1_boot_medium_image_name, MtCollins1CensusMedium } import gunbc.machine_intake_mtcollins1_census_image { mtcollins1_census_image, Mtcollins1CensusImageDerived } import gunbc.machine_intake_mtcollins1_census_medium_readback { mtcollins1_census_record_path, mtcollins1_census_medium_served_path } import gunbc.durable_exclusive_hold_file_store { file_hold_acquire } +import gunbc.runner_browser_toolchain { + RunnerBrowserToolchainResolution, RunnerBrowserToolchainLocation, RunnerBrowserToolchainStanding, + BrowserToolchainReady, BrowserToolchainNotReady, BrowserToolchainUnresolved, + BrowserToolchainHostAdmitted, BrowserToolchainHostRefused, runner_browser_toolchain_host_admission, + TreeAdmission, TreeAdmitted, TreeAbsent, VersionMatches, HostLibrariesResolved, BrowserLaunchRendered, + runner_browser_toolchain_node, runner_browser_toolchain_automation, browser_toolchain_probe_title, browser_toolchain_probe_width_px, +} import gunbc.machine_intake_mtcollins1_maintenance_hold { boot_run_owner, unit_hold_store_root, mtcollins1_unit_hold_key } data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly // THE mtcollins1 BOOT ACCEPTANCE MATRIX (gunbc#12423, operator ruling 2026-09-27). Every case runs THE -// REAL ENTRY -- gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1, unchanged -- over +// REAL ENTRY -- gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_on_srv1_resolving_toolchain, which the +// wet entry mtcollins1_boot_wet_on_srv1 is a single call into, unchanged -- over // a dry realization of its whole effect demand (gunbc.machine_intake_mtcollins1_boot_dry_realization): // the one BMC model, its virtual-media subsystem, the worker's filesystem, processes, environment and // clocks, the SSH agent and srv2. Nothing in the orchestrator is replaced. Each case asserts the ROUTE @@ -66,7 +74,7 @@ fn matrix_grant(service: String, verb: std.effect_grant.Verb) -> Grant { // writing. An operation of any other service refuses as uncovered. data matrix_services: List = [ "diagnostic.ipmi.Tool", "megarac.Media", "Filesystem", "shell.Env", "sleep.Delay", - "gunbc.machine_intake.sol_hold", "shell.Exec", "ssh.Session", "Clock", "linux.Procfs", "shell.Move", + "gunbc.machine_intake.sol_hold", "shell.Exec", "ssh.Session", "Clock", "linux.Procfs", "shell.Move", "os.Hostname", "shell.Mkdir", "shell.Path", ] fn matrix_frame(world: MtCollins1BootWorld) -> WitnessEvaluationFrame { @@ -84,8 +92,55 @@ fn matrix_frame_over(realization: OperationRealization) -> } } +// THE RUNNER'S BROWSER TOOLCHAIN IS SUPPLIED, NOT READ BACK (ruling of eager-owl-205 on gunbc#12533). +// The wet entry resolves it with runner_browser_toolchain_here_wet -- a full readback of the installed +// tree against its pin, the host libraries, the versions and a launch probe -- which is a different +// subject with its own witnesses. The matrix supplies each resolution arm the boot can meet, built from +// the production location and probe values, and the inner entry calls it where the observer starts. +fn srv1_toolchain_location() -> RunnerBrowserToolchainLocation? { + match runner_browser_toolchain_host_admission(host: "srv1" as NonEmptyStr) { + BrowserToolchainHostAdmitted { deploy: _, location: loc } => Present { value: loc } + BrowserToolchainHostRefused { host: _, cause: _ } => none + } +} + +fn toolchain_standing(loc: RunnerBrowserToolchainLocation, tree: TreeAdmission) -> RunnerBrowserToolchainStanding { + RunnerBrowserToolchainStanding { + host: "srv1" as NonEmptyStr, location: loc, tree: tree, + versions: [ + VersionMatches { subject: "node" as NonEmptyStr, observed: runner_browser_toolchain_node.version as String }, + VersionMatches { subject: "playwright-core" as NonEmptyStr, observed: runner_browser_toolchain_automation.version as String }, + ], + libraries: [HostLibrariesResolved { binary: loc.headless_shell }, HostLibrariesResolved { binary: loc.chromium }], + launch: BrowserLaunchRendered { title: browser_toolchain_probe_title, rendered_width: browser_toolchain_probe_width_px, resolved_module: loc.playwright_module as String }, + after: tree, + } +} + +fn ready_toolchain() -> RunnerBrowserToolchainResolution { + match srv1_toolchain_location() { + Present { value: loc } => BrowserToolchainReady { location: loc, standing: toolchain_standing(loc: loc, tree: TreeAdmitted) } + Absent => BrowserToolchainUnresolved { cause: "matrix: srv1 is not admitted to the browser-toolchain pool" } + } +} + +fn not_ready_toolchain() -> RunnerBrowserToolchainResolution { + match srv1_toolchain_location() { + Present { value: loc } => BrowserToolchainNotReady { standing: toolchain_standing(loc: loc, tree: TreeAbsent { tree: loc.root }) } + Absent => BrowserToolchainUnresolved { cause: "matrix: srv1 is not admitted to the browser-toolchain pool" } + } +} + +fn unresolved_toolchain() -> RunnerBrowserToolchainResolution { + BrowserToolchainUnresolved { cause: "runner_browser_toolchain: hostname -s returned empty output" } +} + +fn boot_with_toolchain(toolchain: RunnerBrowserToolchainResolution) -> MtCollins1BootAttempt { + mtcollins1_boot_on_srv1_resolving_toolchain(resolve_toolchain: fn() { toolchain }) +} + fn run_attempt(world: MtCollins1BootWorld) -> WitnessEvaluation { - evaluate_in_witness_frame(frame: matrix_frame(world: world), subject: fn(_scope) { mtcollins1_boot_wet_on_srv1() }) + evaluate_in_witness_frame(frame: matrix_frame(world: world), subject: fn(_scope) { boot_with_toolchain(toolchain: ready_toolchain()) }) } // ─── THE HEALTHY WORLD, and the facts it is built from ─────────────────────────────────────────── @@ -121,7 +176,7 @@ fn healthy_media() -> MegaRacMediaWorld { fn worker_filesystem() -> ModeledFilesystem { ModeledFilesystem { - directories: ["target", "/", "/run", "/proc", "/var", "/var/lib", "/var/lib/gunbc", unit_hold_store_root as String], + directories: ["/", "/home", "/home/runner", "/home/runner/work", "/home/runner/work/gunbc", "/home/runner/work/gunbc/gunbc", "/home/runner/work/gunbc/gunbc/target", "/run", "/proc", "/var", "/var/lib", "/var/lib/gunbc", unit_hold_store_root as String], files: [ModeledFile { path: credential_path, content: "secret" }], } } @@ -446,7 +501,7 @@ fn teardown_within(route: List, bound: Int) -> Bool { test fn a_sol_loss_mid_boot_is_reported_before_the_deadline() -> Bool { let w = world_with_console(lines: console_of(capture: one_socket_census_capture, begin_after: 60, end_after: 240)) let dropping = with_bmc(w: w, bmc: bmc_with_sol_drop_after_boot(world: w.bmc, after: second(count: 30))) - match evaluate_in_witness_frame(frame: matrix_frame(world: dropping), subject: fn(_scope) { mtcollins1_boot_wet_on_srv1() }) { + match evaluate_in_witness_frame(frame: matrix_frame(world: dropping), subject: fn(_scope) { boot_with_toolchain(toolchain: ready_toolchain()) }) { WitnessReturned { value, route, state } => string_contains(s: outcome_reason(a: value), pattern: "ObservationChannelLost while the boot was being watched") && string_contains(s: outcome_reason(a: value), pattern: "incident frozen to /run/sol.capture.loss") @@ -510,12 +565,12 @@ fn as_another_run(w: MtCollins1BootWorld, run_id: String) -> MtCollins1BootWorld // preparation). When dead-owner reconciliation lands this case flips. test fn pinned_an_interrupted_attempt_locks_out_the_next_one() -> Bool { let realization = killed_after_start_media(realization: mtcollins1_boot_dry_realization(identity: realization_identity, initial: world_with_console(lines: []), epoch: virtual_clock_origin())) - match evaluate_in_witness_frame(frame: matrix_frame_over(realization: realization), subject: fn(_scope) { mtcollins1_boot_wet_on_srv1() }) { + match evaluate_in_witness_frame(frame: matrix_frame_over(realization: realization), subject: fn(_scope) { boot_with_toolchain(toolchain: ready_toolchain()) }) { WitnessInterrupted { at, state, now: interrupted_clock } => { let next = as_another_run(w: state, run_id: "4243") let resumed = evaluate_in_witness_frame( frame: matrix_frame_over(realization: mtcollins1_boot_dry_realization(identity: realization_identity, initial: next, epoch: interrupted_clock)), - subject: fn(_scope) { mtcollins1_boot_wet_on_srv1() } + subject: fn(_scope) { boot_with_toolchain(toolchain: ready_toolchain()) } ) at.invocation.at.operation == "StartMedia" && match at.outcome { DispatchWorkerKilled { committed: c } => c _ => false } diff --git a/dag/test/claim/machine_intake/mtcollins1_kvm_observer_protocol_wet_witness_test.dag b/dag/test/claim/machine_intake/mtcollins1_kvm_observer_protocol_wet_witness_test.dag index 9fa6a99b73a..721b480dc26 100644 --- a/dag/test/claim/machine_intake/mtcollins1_kvm_observer_protocol_wet_witness_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_kvm_observer_protocol_wet_witness_test.dag @@ -12,7 +12,7 @@ import gunbc.runner_browser_toolchain { RunnerBrowserToolchainLocation, RunnerBrowserToolchainResolution, runner_browser_toolchain_here_wet, runner_browser_toolchain_standing_text, BrowserToolchainReady, BrowserToolchainNotReady, BrowserToolchainUnresolved, } -import gunbc.bmc_model { BmcWorld, BmcWebWorld, BmcWebAccount, BmcPowerOn, BmcScheduledEvent, BmcKvmStreamClosed, BmcKvmIdle } +import gunbc.bmc_model { BmcWorld, BmcWebWorld, BmcWebAccount, BmcPowerOn, BmcScheduledEvent, BmcKvmStreamClosed, BmcKvmIdle, bmc_world, bmc_with_web, bmc_with_pending } import gunbc.bmc_megarac_web_adapter { MegaRacWebLogin, megarac_web_transition_table, megarac_web_exploration_depth } import gunbc.bmc_megarac_web_transport { MegaRacWebTransportStart, TransportServing, TransportNotServing, @@ -43,19 +43,14 @@ import gunbc.machine_intake_mtcollins1_boot_run { mtcollins1_boot_screen_boundar // established line and first hash-bound still (REAL ROUTE UNEXECUTED until the first hold-lifted boot). fn world(other_viewers: Int, close_at: Nat?, canvas_readable: Bool) -> BmcWorld { - BmcWorld { - power: BmcPowerOn, + bmc_with_pending( + world: bmc_with_web(world: bmc_world(power: BmcPowerOn), web: BmcWebWorld { + account: Present { value: BmcWebAccount { username: "admin", password: "pw", privilege: 4 } }, + sessions: [], next_session_id: 7, other_kvm_viewers: other_viewers, kvm: BmcKvmIdle {}, canvas_readable: canvas_readable, + }), pending: match close_at { Absent => [] Present { value: t } => [BmcScheduledEvent { at: second(count: t), event: BmcKvmStreamClosed {} }] }, fired: [], - web: BmcWebWorld { - account: Present { value: BmcWebAccount { username: "admin", password: "pw", privilege: 4 } }, - sessions: [], - next_session_id: 7, - other_kvm_viewers: other_viewers, - kvm: BmcKvmIdle {}, - canvas_readable: canvas_readable, - }, - } + ) } // A table the lifecycle controls never reach: their "node" exits or is blocked before it reads it. diff --git a/dag/test/claim/modeled_filesystem_witness_test.dag b/dag/test/claim/modeled_filesystem_witness_test.dag index 346e733645a..8e682e945cc 100644 --- a/dag/test/claim/modeled_filesystem_witness_test.dag +++ b/dag/test/claim/modeled_filesystem_witness_test.dag @@ -63,7 +63,7 @@ fn filesystem_frame(initial: ModeledFilesystem) -> WitnessEvaluationFrame String { "" } +// A toolchain resolution for the forged calls below: they are refused at admission, before any of it +// is consulted, so its value only has to be well-formed. +fn forged_toolchain() -> RunnerBrowserToolchainResolution { + BrowserToolchainUnresolved { cause: "forged" } +} + fn boot_the_hold_owning_path_from_outside() -> String { - let _x = mtcollins1_boot_under_live_unit_hold(run_id: "forged", subject: mtcollins1_boot_subject(execution_revision: "0000000000000000000000000000000000000000"), password_file: "/tmp/pw", sol_pid_path: "/tmp/pid", sol_capture_path: "/tmp/cap") + let _x = mtcollins1_boot_under_live_unit_hold(run_id: "forged", subject: mtcollins1_boot_subject(execution_revision: "0000000000000000000000000000000000000000"), password_file: "/tmp/pw", sol_pid_path: "/tmp/pid", sol_capture_path: "/tmp/cap", resolve_toolchain: fn() { forged_toolchain() }) "" } fn actuate_with_a_forged_proof_from_outside() -> String { - let _x = mtcollins1_boot_actuate(proof: forged_proof(), subject: mtcollins1_boot_subject(execution_revision: "0000000000000000000000000000000000000000"), password_file: "/tmp/pw", attempt: "forged", sol_pid_path: "/tmp/pid", sol_capture_path: "/tmp/cap") + let _x = mtcollins1_boot_actuate(proof: forged_proof(), subject: mtcollins1_boot_subject(execution_revision: "0000000000000000000000000000000000000000"), password_file: "/tmp/pw", attempt: "forged", sol_pid_path: "/tmp/pid", sol_capture_path: "/tmp/cap", resolve_toolchain: fn() { forged_toolchain() }) "" } From d24efbb87fafe1ff2af080136cbeab5c481efd23 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Wed, 30 Sep 2026 15:24:42 +0000 Subject: [PATCH 59/75] WIP: mtcollins1 boot: executing acceptance matrix over the real orchestrator --- dag/test/claim/zz_probe/boot_probe.dag | 94 ++++++++++++++++++++ dag/test/claim/zz_probe/contender_probe.dag | 26 ++++++ dag/test/claim/zz_probe/cost_probe_test.dag | 43 +++++++++ dag/test/claim/zz_probe/deadline_probe.dag | 21 +++++ dag/test/claim/zz_probe/fs_cost_probe.dag | 18 ++++ dag/test/claim/zz_probe/reasons2_probe.dag | 43 +++++++++ dag/test/claim/zz_probe/reasons_probe.dag | 31 +++++++ dag/test/claim/zz_probe/route_len_probe.dag | 12 +++ dag/test/claim/zz_probe/sol_flip_probe.dag | 39 ++++++++ dag/test/claim/zz_probe/two_socket_probe.dag | 13 +++ dag/test/claim/zz_probe/world_cost_probe.dag | 18 ++++ 11 files changed, 358 insertions(+) create mode 100644 dag/test/claim/zz_probe/boot_probe.dag create mode 100644 dag/test/claim/zz_probe/contender_probe.dag create mode 100644 dag/test/claim/zz_probe/cost_probe_test.dag create mode 100644 dag/test/claim/zz_probe/deadline_probe.dag create mode 100644 dag/test/claim/zz_probe/fs_cost_probe.dag create mode 100644 dag/test/claim/zz_probe/reasons2_probe.dag create mode 100644 dag/test/claim/zz_probe/reasons_probe.dag create mode 100644 dag/test/claim/zz_probe/route_len_probe.dag create mode 100644 dag/test/claim/zz_probe/sol_flip_probe.dag create mode 100644 dag/test/claim/zz_probe/two_socket_probe.dag create mode 100644 dag/test/claim/zz_probe/world_cost_probe.dag diff --git a/dag/test/claim/zz_probe/boot_probe.dag b/dag/test/claim/zz_probe/boot_probe.dag new file mode 100644 index 00000000000..8dc898a9d73 --- /dev/null +++ b/dag/test/claim/zz_probe/boot_probe.dag @@ -0,0 +1,94 @@ +module test.claim.zz_probe.boot_probe + +import std.types { Bool, List, NonEmptyStr, String } +import std.materialization_ladder { Frame, SharedStateFrame } +import std.effect_grant { Read, Write, ServiceOpTree, NamespacePosition, ModeledRealization, LifecycleByConstruction, Grant, Envelope } +import v2.std.operation_realization { DispatchRecord, virtual_clock_origin } +import v2.std.witness_evaluation { WitnessEvaluationFrame, WitnessReturned, WitnessRefused, WitnessInterrupted, evaluate_in_witness_frame, witness_diagnostic_rendered_reason } +import gunbc.bmc_model { BmcWorld, BmcPowerOff } +import gunbc.filesystem_model { ModeledFilesystem, ModeledFile } +import gunbc.process_environment_model { ModeledVariable } +import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld, mtcollins1_boot_dry_realization } +import gunbc.machine_intake_mtcollins1_boot_run { mtcollins1_boot_wet_on_srv1, mtcollins1_boot_exit_reason } +import gunbc.machine_intake_mtcollins1_boot_authorization { mtcollins1_boot_medium, MtCollins1CensusMedium } +import gunbc.machine_intake_mtcollins1_census_image { mtcollins1_census_image, Mtcollins1CensusImageDerived } +import gunbc.machine_intake_mtcollins1_census_medium_readback { mtcollins1_census_record_path, mtcollins1_census_medium_served_path } +import gunbc.remote_host_model { ModeledRemoteHost, ModeledRemoteFile } + +fn g(service: String, verb: std.effect_grant.Verb) -> Grant { + Grant { verb: verb, root: NamespacePosition { tree: ServiceOpTree { service: service }, path: [] }, binding: ModeledRealization { realization: "boot-probe" }, lifecycle: LifecycleByConstruction } +} + +fn grants() -> List { + let services = ["diagnostic.ipmi.Tool", "megarac.Media", "Filesystem", "shell.Env", "sleep.Delay", "gunbc.machine_intake.sol_hold", "coreutils.Stat", "redfish.Http", "shell.Exec", "ssh.Session", "Clock", "linux.Procfs"] + concat(map(services, s => g(service: s, verb: Read)), map(services, s => g(service: s, verb: Write))) +} + +fn world() -> MtCollins1BootWorld { + MtCollins1BootWorld { + bmc: gunbc.bmc_model.bmc_world(power: BmcPowerOff), + fs: ModeledFilesystem { directories: ["target", "/", "/run", "/var", "/var/lib", "/var/lib/gunbc", "/var/lib/gunbc/unit-holds"], files: [ModeledFile { path: "/run/bmc-credential", content: "secret" }] }, + environment: [ + ModeledVariable { name: "GUNBC_HOST_RESET_BMC_CREDENTIAL_FILE", value: "/run/bmc-credential" }, + ModeledVariable { name: "GUNBC_MTCOLLINS1_SOL_CAPTURE", value: "/run/sol.capture" }, + ModeledVariable { name: "GUNBC_MTCOLLINS1_SOL_PID_FILE", value: "/run/sol.pid" }, + ModeledVariable { name: "GITHUB_RUN_ID", value: "4242" }, + ModeledVariable { name: "SSH_AUTH_SOCK", value: "/run/ssh-agent.sock" }, + ModeledVariable { name: "GITHUB_SHA", value: "0123456789abcdef0123456789abcdef01234567" }, + ], + agent: gunbc.machine_intake_mtcollins1_boot_dry_realization.ModeledSshAgent { socket: "/run/ssh-agent.sock", holds_fleet_key: true }, + clock: gunbc.wall_clock_model.ModeledWallClock { unix_at_origin: 1790000000, step_seconds: 0 }, + worker: gunbc.machine_intake_mtcollins1_boot_dry_realization.ModeledWorker { next_pid: 4000, processes: [], uptime_at_origin: 86400 }, + console: gunbc.machine_intake_mtcollins1_boot_dry_realization.ModeledHostConsole { lines: census_console(), emitted: 0, boot: none }, + media: gunbc.megarac_media_model.MegaRacMediaWorld { + sessions: [], next_session: 1, + share: gunbc.megarac_media_model.MegaRacShare { server: "192.168.1.188", source_path: "/srv/bmc", share_type: "nfs" }, + mount_cd: 1, cd_error_code: 0, + images: [gunbc.megarac_media_model.MegaRacImage { image_name: gunbc.machine_intake_mtcollins1_boot_authorization.mtcollins1_boot_medium_image_name(medium: mtcollins1_boot_medium) as String, image_index: 5 }], + cd: gunbc.megarac_media_model.megarac_cleared_cd(), + ready_after: std.measure.second(count: 12), + }, + remote_hosts: [gunbc.remote_host_model.ModeledRemoteHost { endpoint: "srv2", files: healthy_srv2_files() }], + } +} + +fn describe(route: List) -> String { + join(map(route, r => join([r.invocation.at.service, ".", r.invocation.at.operation, "(", join(map(r.invocation.bindings, b => join([b.name, "=", match b.value { v2.std.operation_argv.InputText { text: t } => t v2.std.operation_argv.InputTextList { items: xs } => join(xs, " ") }], "")), ","), ")"], "")), " > ") +} + +fn probe() -> String { + let frame = WitnessEvaluationFrame { envelope: Envelope { frame: Frame { name: "boot-probe", kind: SharedStateFrame }, grants: grants() }, rest_fixtures: [], realization: Present { value: mtcollins1_boot_dry_realization(identity: "boot-probe" as NonEmptyStr, initial: world(), epoch: virtual_clock_origin()) } } + match evaluate_in_witness_frame(frame: frame, subject: fn(_s) { mtcollins1_boot_exit_reason(outcome: mtcollins1_boot_wet_on_srv1().outcome) }) { + WitnessReturned { value, route } => join(["RETURNED ", value, " || ", describe(route: route)], "") + WitnessRefused { diagnostic, route } => join(["REFUSED ", witness_diagnostic_rendered_reason(diagnostic: diagnostic), " || ", describe(route: route)], "") + WitnessInterrupted { route } => join(["INTERRUPTED || ", describe(route: route)], "") + } +} + +test fn zz_probe_boot() -> Bool { + probe() == "never" +} + +fn selected_digest() -> String { + match gunbc.machine_intake_mtcollins1_boot_authorization.mtcollins1_boot_medium { + gunbc.machine_intake_mtcollins1_boot_authorization.MtCollins1CensusMedium { output_digest: d } => d as String + _ => "" + } +} + +fn healthy_srv2_files() -> List { + match gunbc.machine_intake_mtcollins1_census_image.mtcollins1_census_image { + gunbc.machine_intake_mtcollins1_census_image.Mtcollins1CensusImageDerived { input: input } => [ + gunbc.remote_host_model.ModeledRemoteFile { path: gunbc.machine_intake_mtcollins1_census_medium_readback.mtcollins1_census_record_path(input: input) as String, content: Present { value: concat(selected_digest(), "\n") }, sha256: none }, + gunbc.remote_host_model.ModeledRemoteFile { path: gunbc.machine_intake_mtcollins1_census_medium_readback.mtcollins1_census_medium_served_path(medium: gunbc.machine_intake_mtcollins1_boot_authorization.mtcollins1_boot_medium) as String, content: Present { value: "" }, sha256: Present { value: selected_digest() } }, + ] + _ => [] + } +} + +data clean_capture: String = "=====GUNBC-HOST-CAPTURE mtcollins1 attempt=1 begin 2026-09-18T00:00:00Z=====\n----SECTION boot-media----\n----ARGV boot-media: ls -l /dev/disk/by-label; blkid\nLABEL=\"GUNBC_MTC1_CENSUS_2404_3\"\n----EXIT boot-media: 0\n----SECTION nproc----\n----ARGV nproc: nproc\n80\n----EXIT nproc: 0\n----SECTION numa----\n----ARGV numa: cat /sys/devices/system/node/online; numactl -H\n0\navailable: 1 nodes (0)\nnode 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79\nnode 0 size: 255937 MB\nnode 0 free: 250112 MB\n----EXIT numa: 0\n----SECTION edac-before----\n----ARGV edac-before: (counters)\n== /sys/devices/system/edac/mc/mc0/ce_count == 0\n== /sys/devices/system/edac/mc/mc0/ue_count == 0\n----EXIT edac-before: 0\n----SECTION workload----\n----ARGV workload: (the rendered workload command)\nworkload-bytes=4294967296\nworkload-shm-avail-bytes=8373932032\nworkload-mem-available-bytes=15032385536\nworkload-preflight=fits\nworkload-write-rc=0\nworkload-digest-stable=yes\n----EXIT workload: 0\n----SECTION edac-after----\n----ARGV edac-after: (counters)\n== /sys/devices/system/edac/mc/mc0/ce_count == 0\n== /sys/devices/system/edac/mc/mc0/ue_count == 0\n----EXIT edac-after: 0\n=====GUNBC-HOST-CAPTURE mtcollins1 attempt=1 end 2026-09-18T00:04:00Z=====\n" + +fn census_console() -> List { + let lines = filter(split(s: clean_capture, delimiter: "\n"), l => l != "") + map(lines, l => gunbc.machine_intake_mtcollins1_boot_dry_realization.TimedConsoleLine { after: std.measure.second(count: if starts_with(s: l, prefix: "=====GUNBC-HOST-CAPTURE mtcollins1 attempt=1 end") { 240 } else { 60 }), text: l }) +} diff --git a/dag/test/claim/zz_probe/contender_probe.dag b/dag/test/claim/zz_probe/contender_probe.dag new file mode 100644 index 00000000000..028694e52fc --- /dev/null +++ b/dag/test/claim/zz_probe/contender_probe.dag @@ -0,0 +1,26 @@ +module test.claim.zz_probe.contender_probe + +import std.types { NonEmptyStr, String } +import v2.std.witness_evaluation { WitnessReturned, WitnessRefused, WitnessInterrupted, evaluate_in_witness_frame, witness_diagnostic_rendered_reason } +import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { run_attempt, world_with_console, outcome_reason, matrix_frame } +import gunbc.durable_exclusive_hold_file_store { file_hold_acquire } +import gunbc.machine_intake_mtcollins1_maintenance_hold { boot_run_owner, unit_hold_store_root, mtcollins1_unit_hold_key } + +fn probe() -> String { + let prior = evaluate_in_witness_frame( + frame: matrix_frame(world: world_with_console(lines: [])), + subject: fn(_scope) { file_hold_acquire(root: unit_hold_store_root, slot_key: mtcollins1_unit_hold_key, requested_owner: boot_run_owner(run_id: "4141" as NonEmptyStr)) } + ) + match prior { + WitnessReturned { state } => match state { + Absent => "no state" + Present { value: held } => match run_attempt(world: held) { + WitnessReturned { value } => concat("RETURNED ", outcome_reason(a: value)) + WitnessRefused { diagnostic } => concat("REFUSED ", witness_diagnostic_rendered_reason(diagnostic: diagnostic)) + WitnessInterrupted { at: _ } => "INTERRUPTED" + } + } + WitnessRefused { diagnostic } => concat("PRIOR REFUSED ", witness_diagnostic_rendered_reason(diagnostic: diagnostic)) + WitnessInterrupted { at: _ } => "PRIOR INTERRUPTED" + } +} diff --git a/dag/test/claim/zz_probe/cost_probe_test.dag b/dag/test/claim/zz_probe/cost_probe_test.dag new file mode 100644 index 00000000000..991ee0451fb --- /dev/null +++ b/dag/test/claim/zz_probe/cost_probe_test.dag @@ -0,0 +1,43 @@ +module test.claim.zz_probe.cost_probe_test + +import std.types { Bool, Int, List, NonEmptyStr, String } +import std.materialization_ladder { Frame, SharedStateFrame } +import std.effect_grant { Read, Write, ServiceOpTree, NamespacePosition, ModeledRealization, LifecycleByConstruction, Grant, Envelope } +import v2.std.operation_realization { OperationRealization, virtual_clock_origin } +import v2.std.witness_evaluation { WitnessEvaluationFrame, WitnessReturned, evaluate_in_witness_frame } +import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld, mtcollins1_boot_dry_realization } +import gunbc.machine_intake_mtcollins1_boot_run { mtcollins1_boot_wet_on_srv1 } +import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { world_with_console, matrix_frame, matrix_frame_over, realization_identity } + +fn no_advance(r: OperationRealization) -> OperationRealization { + OperationRealization { identity: r.identity, initial: r.initial, epoch: r.epoch, bindings: r.bindings, advance: fn(w, now) { w } } +} + +test fn cp_baseline() -> Bool { + match evaluate_in_witness_frame(frame: matrix_frame(world: world_with_console(lines: [])), subject: fn(_s) { mtcollins1_boot_wet_on_srv1() }) { WitnessReturned { value: _ } => true _ => false } +} + +test fn cp_no_advance() -> Bool { + let r = no_advance(r: mtcollins1_boot_dry_realization(identity: realization_identity, initial: world_with_console(lines: []), epoch: virtual_clock_origin())) + match evaluate_in_witness_frame(frame: matrix_frame_over(realization: r), subject: fn(_s) { mtcollins1_boot_wet_on_srv1() }) { WitnessReturned { value: _ } => true _ => false } +} + +test fn cp_world_only() -> Bool { + let w = world_with_console(lines: []) + count(w.environment) > 0 +} + +fn sleeps(n: Int) -> Bool { + if n == 0 { true } else { + let ok = extdeps.tools.sleep.sleep_delay_seconds_second_carrier_projection(duration: std.measure.second(count: 1)) + ok && sleeps(n: n - 1) + } +} + +test fn cp_100_sleeps_full_frame() -> Bool { + match evaluate_in_witness_frame(frame: matrix_frame(world: world_with_console(lines: [])), subject: fn(_s) { sleeps(n: 100) }) { WitnessReturned { value } => value _ => false } +} + +test fn cp_0_sleeps_full_frame() -> Bool { + match evaluate_in_witness_frame(frame: matrix_frame(world: world_with_console(lines: [])), subject: fn(_s) { sleeps(n: 0) }) { WitnessReturned { value } => value _ => false } +} diff --git a/dag/test/claim/zz_probe/deadline_probe.dag b/dag/test/claim/zz_probe/deadline_probe.dag new file mode 100644 index 00000000000..209abdf7653 --- /dev/null +++ b/dag/test/claim/zz_probe/deadline_probe.dag @@ -0,0 +1,21 @@ +module test.claim.zz_probe.deadline_probe + +import std.types { Int, List, String } +import std.process { ProcessExit, ExitFailure, exit_failure } +import v2.std.witness_evaluation { WitnessReturned, WitnessRefused, WitnessInterrupted, witness_diagnostic_rendered_reason } +import v2.std.operation_realization { DispatchRecord } +import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld } +import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { run_attempt, world_with_console, outcome_reason, operation_name } + +fn route_text(route: List) -> String { + join(map(route, r => operation_name(r: r)), " > ") +} + +test fn probe() -> ProcessExit { + match run_attempt(world: world_with_console(lines: [])) { + WitnessReturned { value, route } => exit_failure(reason: concat(concat(outcome_reason(a: value), " ### "), route_text(route: route))) + WitnessRefused { diagnostic, route } => exit_failure(reason: concat(concat(concat("REFUSED ", witness_diagnostic_rendered_reason(diagnostic: diagnostic)), " ### "), route_text(route: route))) + WitnessInterrupted { at: _ } => exit_failure(reason: "INTERRUPTED") + } +} +data live_tree_disposition: v2.std.live_tree.LiveTreeDisposition = v2.std.live_tree.SubstrateInputsOnly diff --git a/dag/test/claim/zz_probe/fs_cost_probe.dag b/dag/test/claim/zz_probe/fs_cost_probe.dag new file mode 100644 index 00000000000..05ba86ff3b2 --- /dev/null +++ b/dag/test/claim/zz_probe/fs_cost_probe.dag @@ -0,0 +1,18 @@ +module test.claim.zz_probe.fs_cost_probe + +import std.types { Bool, Int, List, String } +import gunbc.filesystem_model { fs_read } +import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { world_with_console } + +data live_tree_disposition: v2.std.live_tree.LiveTreeDisposition = v2.std.live_tree.SubstrateInputsOnly + +test fn reads_166() -> Bool { + let w = world_with_console(lines: []) + let n = fold([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100], init: 0, f: fn(acc, i) { match fs_read(fs: w.fs, path: "/run/sol.capture.notice.ready") { extdeps.transports.file.FileOperationSucceeded { byte_count: _, content: _ } => acc + 1 _ => acc } }) + count(w.fs.files) >= 0 && n == 100 +} + +test fn build_only() -> Bool { + let w = world_with_console(lines: []) + count(w.fs.files) >= 0 +} diff --git a/dag/test/claim/zz_probe/reasons2_probe.dag b/dag/test/claim/zz_probe/reasons2_probe.dag new file mode 100644 index 00000000000..f26664fad43 --- /dev/null +++ b/dag/test/claim/zz_probe/reasons2_probe.dag @@ -0,0 +1,43 @@ +module test.claim.zz_probe.reasons2_probe + +import std.types { Bool, Int, List, String } +import std.measure { second, second_displacement } +import v2.std.witness_evaluation { WitnessReturned, WitnessRefused, WitnessInterrupted, witness_diagnostic_rendered_reason } +import gunbc.megarac_media_model { MegaRacMediaWorld, MegaRacImage, megarac_cleared_cd } +import gunbc.bmc_model { BmcPowerOn, bmc_with_power } +import gunbc.wall_clock_model { ModeledWallClock, ModeledClockStep } +import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld, with_bmc, with_media } +import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { run_attempt, world_with_console, outcome_reason, desired_image, real_share, healthy_media } + +fn summary(w: MtCollins1BootWorld) -> String { + match run_attempt(world: w) { + WitnessReturned { value, route } => concat(outcome_reason(a: value), concat(" || ops: ", join(map(filter(route, r => r.invocation.at.operation == "StopMedia" || r.invocation.at.operation == "StartMedia" || r.invocation.at.operation == "ChassisPowerControl" || r.invocation.at.operation == "ChassisBootDevWithOptions"), r => r.invocation.at.operation), ","))) + WitnessRefused { diagnostic } => concat("REFUSED ", witness_diagnostic_rendered_reason(diagnostic: diagnostic)) + WitnessInterrupted { at: _ } => "INTERRUPTED" + } +} + +fn jumped(by: Int) -> MtCollins1BootWorld { + let w = world_with_console(lines: []) + MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: ModeledWallClock { unix_at_origin: 1790000000, step: second_displacement(count: 0), jumps: [ModeledClockStep { at: second(count: 20), by: second_displacement(count: by) }] }, worker: w.worker, console: w.console, media: w.media } +} + +fn errored(code: Int, clears: Bool, after_ready: Int?) -> MegaRacMediaWorld { + let m = healthy_media() + MegaRacMediaWorld { sessions: m.sessions, next_session: m.next_session, share: m.share, mount_cd: m.mount_cd, cd_error_code: code, images: m.images, cd: m.cd, ready_after: m.ready_after, withdraw_at: none, withdraw_after_ready: none, error_after_ready: after_ready, error_clears_on_stop: clears } +} + +fn no_code() -> Int? { none } + +fn stale_errored(clears: Bool) -> MegaRacMediaWorld { + let m = errored(code: 16, clears: clears, after_ready: no_code()) + MegaRacMediaWorld { sessions: m.sessions, next_session: m.next_session, share: m.share, mount_cd: m.mount_cd, cd_error_code: m.cd_error_code, images: m.images, cd: gunbc.megarac_media_model.MegaRacCdRow { image_name: "gunbc-mtcollins1-census-ubuntu-24.04.3-arm64-0000000000000000.iso", redirection_status: 1, media_index: 0, session_index: 0, ready_at: none }, ready_after: m.ready_after, withdraw_at: none, withdraw_after_ready: none, error_after_ready: none, error_clears_on_stop: clears } +} + +fn probe() -> String { + let base = world_with_console(lines: []) + join([ + concat("E5 stale+16 clears: ", summary(w: with_media(w: base, media: stale_errored(clears: true)))), + concat("E6 stale+16 sticks: ", summary(w: with_media(w: base, media: stale_errored(clears: false)))), + ], " ||| ") +} diff --git a/dag/test/claim/zz_probe/reasons_probe.dag b/dag/test/claim/zz_probe/reasons_probe.dag new file mode 100644 index 00000000000..82e8af790ce --- /dev/null +++ b/dag/test/claim/zz_probe/reasons_probe.dag @@ -0,0 +1,31 @@ +module test.claim.zz_probe.reasons_probe + +import std.types { Int, List, String } +import std.measure { second } +import v2.std.witness_evaluation { WitnessReturned, WitnessRefused, WitnessInterrupted, witness_diagnostic_rendered_reason } +import gunbc.megarac_media_model { MegaRacShare, MegaRacImage, megarac_cleared_cd } +import gunbc.bmc_model { bmc_with_sol_session } +import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld, with_bmc } +import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { + run_attempt, world_with_console, outcome_reason, media_varied, media_with, desired_image, real_share, no_withdrawal, +} + +fn reason_of(w: MtCollins1BootWorld) -> String { + match run_attempt(world: w) { + WitnessReturned { value } => outcome_reason(a: value) + WitnessRefused { diagnostic } => concat("REFUSED ", witness_diagnostic_rendered_reason(diagnostic: diagnostic)) + WitnessInterrupted { at: _ } => "INTERRUPTED" + } +} + +fn withdrawn_after(d: Int) -> String { + let img = [MegaRacImage { image_name: desired_image(), image_index: 5 }] + match std.checked_arithmetic.checked_int_to_nat(n: d) { + Absent => "bad" + Present { value: n } => concat(concat(to_string(d), ": "), reason_of(w: media_varied(media: media_with(images: img, share: real_share, cd: megarac_cleared_cd(), ready_after: 12, withdraw_after_ready: Present { value: second(count: n) })))) + } +} + +fn probe() -> String { + join(map([3, 5, 8, 12, 20], d => withdrawn_after(d: d)), " ||| ") +} diff --git a/dag/test/claim/zz_probe/route_len_probe.dag b/dag/test/claim/zz_probe/route_len_probe.dag new file mode 100644 index 00000000000..9abbfda24e5 --- /dev/null +++ b/dag/test/claim/zz_probe/route_len_probe.dag @@ -0,0 +1,12 @@ +module test.claim.zz_probe.route_len_probe + +import std.types { String } +import v2.std.witness_evaluation { WitnessReturned, WitnessRefused, WitnessInterrupted } +import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { run_attempt, world_with_console } + +fn probe() -> String { + match run_attempt(world: world_with_console(lines: [])) { + WitnessReturned { route } => join(map(filter(route, r => r.invocation.at.operation == "StartMedia" || r.invocation.at.operation == "GetRemoteConfigurations" || r.invocation.at.operation == "ChassisPowerControl"), r => concat(concat(r.invocation.at.operation, "@"), to_string(std.measure.second_count(s: r.dispatched_at) as Int))), " ") + _ => "x" + } +} diff --git a/dag/test/claim/zz_probe/sol_flip_probe.dag b/dag/test/claim/zz_probe/sol_flip_probe.dag new file mode 100644 index 00000000000..ddecb68eb58 --- /dev/null +++ b/dag/test/claim/zz_probe/sol_flip_probe.dag @@ -0,0 +1,39 @@ +module test.claim.zz_probe.sol_flip_probe + +import std.types { Int, List, String } +import std.measure { second, second_count } +import std.process { ProcessExit, exit_failure } +import v2.std.witness_evaluation { WitnessReturned, WitnessRefused, WitnessInterrupted, witness_diagnostic_rendered_reason, evaluate_in_witness_frame } +import v2.std.operation_realization { DispatchRecord } +import gunbc.bmc_model { bmc_with_sol_session, bmc_with_sol_drop_after_boot, bmc_sol_drop_fired } +import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld, with_bmc } +import gunbc.machine_intake_mtcollins1_boot_run { mtcollins1_boot_wet_on_srv1 } +import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { run_attempt, world_with_console, outcome_reason, operation_name, console_of, one_socket_census_capture, matrix_frame, is_controller_write, census_ended } + +data live_tree_disposition: v2.std.live_tree.LiveTreeDisposition = v2.std.live_tree.SubstrateInputsOnly + +fn writes(route: List) -> String { + join(map(filter(route, r => is_controller_write(r: r) || operation_name(r: r) == "gunbc.machine_intake.sol_hold.ReleaseHeld" || operation_name(r: r) == "Filesystem.Delete"), r => concat(concat(operation_name(r: r), "@"), to_string(second_count(s: r.dispatched_at)))), " > ") +} + +fn report(w: MtCollins1BootWorld) -> ProcessExit { + match evaluate_in_witness_frame(frame: matrix_frame(world: w), subject: fn(_scope) { mtcollins1_boot_wet_on_srv1() }) { + WitnessReturned { value, route } => exit_failure(reason: join([outcome_reason(a: value), " ### census_ended=", if census_ended(a: value) { "yes" } else { "no" }, " ### ", writes(route: route)], "")) + WitnessRefused { diagnostic, route } => exit_failure(reason: concat("REFUSED ", witness_diagnostic_rendered_reason(diagnostic: diagnostic))) + WitnessInterrupted { at: _ } => exit_failure(reason: "INTERRUPTED") + } +} + +test fn healthy() -> ProcessExit { + report(w: world_with_console(lines: console_of(capture: one_socket_census_capture, begin_after: 60, end_after: 240))) +} + +test fn held_elsewhere() -> ProcessExit { + let w = world_with_console(lines: []) + report(w: with_bmc(w: w, bmc: bmc_with_sol_session(world: w.bmc, open: true))) +} + +test fn loss() -> ProcessExit { + let w = world_with_console(lines: console_of(capture: one_socket_census_capture, begin_after: 60, end_after: 240)) + report(w: with_bmc(w: w, bmc: bmc_with_sol_drop_after_boot(world: w.bmc, after: second(count: 30)))) +} diff --git a/dag/test/claim/zz_probe/two_socket_probe.dag b/dag/test/claim/zz_probe/two_socket_probe.dag new file mode 100644 index 00000000000..965e3ab5e4a --- /dev/null +++ b/dag/test/claim/zz_probe/two_socket_probe.dag @@ -0,0 +1,13 @@ +module test.claim.zz_probe.two_socket_probe + +import std.types { String } +import v2.std.witness_evaluation { WitnessReturned, WitnessRefused, WitnessInterrupted, witness_diagnostic_rendered_reason } +import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { run_attempt, world_with_console, console_of, two_socket_census_capture, outcome_reason, census_ended } + +fn probe() -> String { + match run_attempt(world: world_with_console(lines: console_of(capture: two_socket_census_capture, begin_after: 60, end_after: 240))) { + WitnessReturned { value } => join(["RETURNED ", outcome_reason(a: value), " census_ended=", if census_ended(a: value) { "yes" } else { "no" }], "") + WitnessRefused { diagnostic } => concat("REFUSED ", witness_diagnostic_rendered_reason(diagnostic: diagnostic)) + WitnessInterrupted { at: _ } => "INTERRUPTED" + } +} diff --git a/dag/test/claim/zz_probe/world_cost_probe.dag b/dag/test/claim/zz_probe/world_cost_probe.dag new file mode 100644 index 00000000000..09183bca213 --- /dev/null +++ b/dag/test/claim/zz_probe/world_cost_probe.dag @@ -0,0 +1,18 @@ +module test.claim.zz_probe.world_cost_probe + +import std.types { Bool, List } +import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } +import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { world_with_console, console_of, one_socket_census_capture, matrix_frame } + +data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly + +test fn build_empty_world() -> Bool { + let w = world_with_console(lines: []) + count(w.fs.directories) > 0 +} + +test fn build_census_world_and_frame() -> Bool { + let w = world_with_console(lines: console_of(capture: one_socket_census_capture, begin_after: 60, end_after: 240)) + let f = matrix_frame(world: w) + count(w.console.lines) > 0 && count(f.envelope.grants) > 0 +} From ec1b8190320c27a829dd77834d1003ae6683658a Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Wed, 30 Sep 2026 16:22:50 +0000 Subject: [PATCH 60/75] Integration: fs_make_parents carries refused_reads (#12533 x #12555); drop the uncommitted-intent zz_probe scratch probes from #12533's WIP commit --- dag/gunbc/filesystem_model.dag | 2 +- dag/test/claim/zz_probe/boot_probe.dag | 94 -------------------- dag/test/claim/zz_probe/contender_probe.dag | 26 ------ dag/test/claim/zz_probe/cost_probe_test.dag | 43 --------- dag/test/claim/zz_probe/deadline_probe.dag | 21 ----- dag/test/claim/zz_probe/fs_cost_probe.dag | 18 ---- dag/test/claim/zz_probe/reasons2_probe.dag | 43 --------- dag/test/claim/zz_probe/reasons_probe.dag | 31 ------- dag/test/claim/zz_probe/route_len_probe.dag | 12 --- dag/test/claim/zz_probe/sol_flip_probe.dag | 39 -------- dag/test/claim/zz_probe/two_socket_probe.dag | 13 --- dag/test/claim/zz_probe/world_cost_probe.dag | 18 ---- 12 files changed, 1 insertion(+), 359 deletions(-) delete mode 100644 dag/test/claim/zz_probe/boot_probe.dag delete mode 100644 dag/test/claim/zz_probe/contender_probe.dag delete mode 100644 dag/test/claim/zz_probe/cost_probe_test.dag delete mode 100644 dag/test/claim/zz_probe/deadline_probe.dag delete mode 100644 dag/test/claim/zz_probe/fs_cost_probe.dag delete mode 100644 dag/test/claim/zz_probe/reasons2_probe.dag delete mode 100644 dag/test/claim/zz_probe/reasons_probe.dag delete mode 100644 dag/test/claim/zz_probe/route_len_probe.dag delete mode 100644 dag/test/claim/zz_probe/sol_flip_probe.dag delete mode 100644 dag/test/claim/zz_probe/two_socket_probe.dag delete mode 100644 dag/test/claim/zz_probe/world_cost_probe.dag diff --git a/dag/gunbc/filesystem_model.dag b/dag/gunbc/filesystem_model.dag index 504891634aa..dd5b3d6974f 100644 --- a/dag/gunbc/filesystem_model.dag +++ b/dag/gunbc/filesystem_model.dag @@ -290,7 +290,7 @@ fn fs_make_parents(fs: ModeledFilesystem, path: String) -> ModeledFileWrite { match blocked.first() { Present { value: b } => ModeledFileWrite { fs: fs, observation: failed_with(kind: FilesystemNotDirectory, message: concat("mkdir: cannot create directory: Not a directory: ", b)) } Absent => ModeledFileWrite { - fs: ModeledFilesystem { directories: fold(chain, init: fs.directories, f: fn(acc, d) { if any_string(xs: acc, x: d) { acc } else { list_append(acc, d) } }), files: fs.files }, + fs: ModeledFilesystem { directories: fold(chain, init: fs.directories, f: fn(acc, d) { if any_string(xs: acc, x: d) { acc } else { list_append(acc, d) } }), files: fs.files, refused_reads: fs.refused_reads }, observation: FileOperationSucceeded { byte_count: byte_size(count: 0), content: "" }, } } diff --git a/dag/test/claim/zz_probe/boot_probe.dag b/dag/test/claim/zz_probe/boot_probe.dag deleted file mode 100644 index 8dc898a9d73..00000000000 --- a/dag/test/claim/zz_probe/boot_probe.dag +++ /dev/null @@ -1,94 +0,0 @@ -module test.claim.zz_probe.boot_probe - -import std.types { Bool, List, NonEmptyStr, String } -import std.materialization_ladder { Frame, SharedStateFrame } -import std.effect_grant { Read, Write, ServiceOpTree, NamespacePosition, ModeledRealization, LifecycleByConstruction, Grant, Envelope } -import v2.std.operation_realization { DispatchRecord, virtual_clock_origin } -import v2.std.witness_evaluation { WitnessEvaluationFrame, WitnessReturned, WitnessRefused, WitnessInterrupted, evaluate_in_witness_frame, witness_diagnostic_rendered_reason } -import gunbc.bmc_model { BmcWorld, BmcPowerOff } -import gunbc.filesystem_model { ModeledFilesystem, ModeledFile } -import gunbc.process_environment_model { ModeledVariable } -import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld, mtcollins1_boot_dry_realization } -import gunbc.machine_intake_mtcollins1_boot_run { mtcollins1_boot_wet_on_srv1, mtcollins1_boot_exit_reason } -import gunbc.machine_intake_mtcollins1_boot_authorization { mtcollins1_boot_medium, MtCollins1CensusMedium } -import gunbc.machine_intake_mtcollins1_census_image { mtcollins1_census_image, Mtcollins1CensusImageDerived } -import gunbc.machine_intake_mtcollins1_census_medium_readback { mtcollins1_census_record_path, mtcollins1_census_medium_served_path } -import gunbc.remote_host_model { ModeledRemoteHost, ModeledRemoteFile } - -fn g(service: String, verb: std.effect_grant.Verb) -> Grant { - Grant { verb: verb, root: NamespacePosition { tree: ServiceOpTree { service: service }, path: [] }, binding: ModeledRealization { realization: "boot-probe" }, lifecycle: LifecycleByConstruction } -} - -fn grants() -> List { - let services = ["diagnostic.ipmi.Tool", "megarac.Media", "Filesystem", "shell.Env", "sleep.Delay", "gunbc.machine_intake.sol_hold", "coreutils.Stat", "redfish.Http", "shell.Exec", "ssh.Session", "Clock", "linux.Procfs"] - concat(map(services, s => g(service: s, verb: Read)), map(services, s => g(service: s, verb: Write))) -} - -fn world() -> MtCollins1BootWorld { - MtCollins1BootWorld { - bmc: gunbc.bmc_model.bmc_world(power: BmcPowerOff), - fs: ModeledFilesystem { directories: ["target", "/", "/run", "/var", "/var/lib", "/var/lib/gunbc", "/var/lib/gunbc/unit-holds"], files: [ModeledFile { path: "/run/bmc-credential", content: "secret" }] }, - environment: [ - ModeledVariable { name: "GUNBC_HOST_RESET_BMC_CREDENTIAL_FILE", value: "/run/bmc-credential" }, - ModeledVariable { name: "GUNBC_MTCOLLINS1_SOL_CAPTURE", value: "/run/sol.capture" }, - ModeledVariable { name: "GUNBC_MTCOLLINS1_SOL_PID_FILE", value: "/run/sol.pid" }, - ModeledVariable { name: "GITHUB_RUN_ID", value: "4242" }, - ModeledVariable { name: "SSH_AUTH_SOCK", value: "/run/ssh-agent.sock" }, - ModeledVariable { name: "GITHUB_SHA", value: "0123456789abcdef0123456789abcdef01234567" }, - ], - agent: gunbc.machine_intake_mtcollins1_boot_dry_realization.ModeledSshAgent { socket: "/run/ssh-agent.sock", holds_fleet_key: true }, - clock: gunbc.wall_clock_model.ModeledWallClock { unix_at_origin: 1790000000, step_seconds: 0 }, - worker: gunbc.machine_intake_mtcollins1_boot_dry_realization.ModeledWorker { next_pid: 4000, processes: [], uptime_at_origin: 86400 }, - console: gunbc.machine_intake_mtcollins1_boot_dry_realization.ModeledHostConsole { lines: census_console(), emitted: 0, boot: none }, - media: gunbc.megarac_media_model.MegaRacMediaWorld { - sessions: [], next_session: 1, - share: gunbc.megarac_media_model.MegaRacShare { server: "192.168.1.188", source_path: "/srv/bmc", share_type: "nfs" }, - mount_cd: 1, cd_error_code: 0, - images: [gunbc.megarac_media_model.MegaRacImage { image_name: gunbc.machine_intake_mtcollins1_boot_authorization.mtcollins1_boot_medium_image_name(medium: mtcollins1_boot_medium) as String, image_index: 5 }], - cd: gunbc.megarac_media_model.megarac_cleared_cd(), - ready_after: std.measure.second(count: 12), - }, - remote_hosts: [gunbc.remote_host_model.ModeledRemoteHost { endpoint: "srv2", files: healthy_srv2_files() }], - } -} - -fn describe(route: List) -> String { - join(map(route, r => join([r.invocation.at.service, ".", r.invocation.at.operation, "(", join(map(r.invocation.bindings, b => join([b.name, "=", match b.value { v2.std.operation_argv.InputText { text: t } => t v2.std.operation_argv.InputTextList { items: xs } => join(xs, " ") }], "")), ","), ")"], "")), " > ") -} - -fn probe() -> String { - let frame = WitnessEvaluationFrame { envelope: Envelope { frame: Frame { name: "boot-probe", kind: SharedStateFrame }, grants: grants() }, rest_fixtures: [], realization: Present { value: mtcollins1_boot_dry_realization(identity: "boot-probe" as NonEmptyStr, initial: world(), epoch: virtual_clock_origin()) } } - match evaluate_in_witness_frame(frame: frame, subject: fn(_s) { mtcollins1_boot_exit_reason(outcome: mtcollins1_boot_wet_on_srv1().outcome) }) { - WitnessReturned { value, route } => join(["RETURNED ", value, " || ", describe(route: route)], "") - WitnessRefused { diagnostic, route } => join(["REFUSED ", witness_diagnostic_rendered_reason(diagnostic: diagnostic), " || ", describe(route: route)], "") - WitnessInterrupted { route } => join(["INTERRUPTED || ", describe(route: route)], "") - } -} - -test fn zz_probe_boot() -> Bool { - probe() == "never" -} - -fn selected_digest() -> String { - match gunbc.machine_intake_mtcollins1_boot_authorization.mtcollins1_boot_medium { - gunbc.machine_intake_mtcollins1_boot_authorization.MtCollins1CensusMedium { output_digest: d } => d as String - _ => "" - } -} - -fn healthy_srv2_files() -> List { - match gunbc.machine_intake_mtcollins1_census_image.mtcollins1_census_image { - gunbc.machine_intake_mtcollins1_census_image.Mtcollins1CensusImageDerived { input: input } => [ - gunbc.remote_host_model.ModeledRemoteFile { path: gunbc.machine_intake_mtcollins1_census_medium_readback.mtcollins1_census_record_path(input: input) as String, content: Present { value: concat(selected_digest(), "\n") }, sha256: none }, - gunbc.remote_host_model.ModeledRemoteFile { path: gunbc.machine_intake_mtcollins1_census_medium_readback.mtcollins1_census_medium_served_path(medium: gunbc.machine_intake_mtcollins1_boot_authorization.mtcollins1_boot_medium) as String, content: Present { value: "" }, sha256: Present { value: selected_digest() } }, - ] - _ => [] - } -} - -data clean_capture: String = "=====GUNBC-HOST-CAPTURE mtcollins1 attempt=1 begin 2026-09-18T00:00:00Z=====\n----SECTION boot-media----\n----ARGV boot-media: ls -l /dev/disk/by-label; blkid\nLABEL=\"GUNBC_MTC1_CENSUS_2404_3\"\n----EXIT boot-media: 0\n----SECTION nproc----\n----ARGV nproc: nproc\n80\n----EXIT nproc: 0\n----SECTION numa----\n----ARGV numa: cat /sys/devices/system/node/online; numactl -H\n0\navailable: 1 nodes (0)\nnode 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79\nnode 0 size: 255937 MB\nnode 0 free: 250112 MB\n----EXIT numa: 0\n----SECTION edac-before----\n----ARGV edac-before: (counters)\n== /sys/devices/system/edac/mc/mc0/ce_count == 0\n== /sys/devices/system/edac/mc/mc0/ue_count == 0\n----EXIT edac-before: 0\n----SECTION workload----\n----ARGV workload: (the rendered workload command)\nworkload-bytes=4294967296\nworkload-shm-avail-bytes=8373932032\nworkload-mem-available-bytes=15032385536\nworkload-preflight=fits\nworkload-write-rc=0\nworkload-digest-stable=yes\n----EXIT workload: 0\n----SECTION edac-after----\n----ARGV edac-after: (counters)\n== /sys/devices/system/edac/mc/mc0/ce_count == 0\n== /sys/devices/system/edac/mc/mc0/ue_count == 0\n----EXIT edac-after: 0\n=====GUNBC-HOST-CAPTURE mtcollins1 attempt=1 end 2026-09-18T00:04:00Z=====\n" - -fn census_console() -> List { - let lines = filter(split(s: clean_capture, delimiter: "\n"), l => l != "") - map(lines, l => gunbc.machine_intake_mtcollins1_boot_dry_realization.TimedConsoleLine { after: std.measure.second(count: if starts_with(s: l, prefix: "=====GUNBC-HOST-CAPTURE mtcollins1 attempt=1 end") { 240 } else { 60 }), text: l }) -} diff --git a/dag/test/claim/zz_probe/contender_probe.dag b/dag/test/claim/zz_probe/contender_probe.dag deleted file mode 100644 index 028694e52fc..00000000000 --- a/dag/test/claim/zz_probe/contender_probe.dag +++ /dev/null @@ -1,26 +0,0 @@ -module test.claim.zz_probe.contender_probe - -import std.types { NonEmptyStr, String } -import v2.std.witness_evaluation { WitnessReturned, WitnessRefused, WitnessInterrupted, evaluate_in_witness_frame, witness_diagnostic_rendered_reason } -import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { run_attempt, world_with_console, outcome_reason, matrix_frame } -import gunbc.durable_exclusive_hold_file_store { file_hold_acquire } -import gunbc.machine_intake_mtcollins1_maintenance_hold { boot_run_owner, unit_hold_store_root, mtcollins1_unit_hold_key } - -fn probe() -> String { - let prior = evaluate_in_witness_frame( - frame: matrix_frame(world: world_with_console(lines: [])), - subject: fn(_scope) { file_hold_acquire(root: unit_hold_store_root, slot_key: mtcollins1_unit_hold_key, requested_owner: boot_run_owner(run_id: "4141" as NonEmptyStr)) } - ) - match prior { - WitnessReturned { state } => match state { - Absent => "no state" - Present { value: held } => match run_attempt(world: held) { - WitnessReturned { value } => concat("RETURNED ", outcome_reason(a: value)) - WitnessRefused { diagnostic } => concat("REFUSED ", witness_diagnostic_rendered_reason(diagnostic: diagnostic)) - WitnessInterrupted { at: _ } => "INTERRUPTED" - } - } - WitnessRefused { diagnostic } => concat("PRIOR REFUSED ", witness_diagnostic_rendered_reason(diagnostic: diagnostic)) - WitnessInterrupted { at: _ } => "PRIOR INTERRUPTED" - } -} diff --git a/dag/test/claim/zz_probe/cost_probe_test.dag b/dag/test/claim/zz_probe/cost_probe_test.dag deleted file mode 100644 index 991ee0451fb..00000000000 --- a/dag/test/claim/zz_probe/cost_probe_test.dag +++ /dev/null @@ -1,43 +0,0 @@ -module test.claim.zz_probe.cost_probe_test - -import std.types { Bool, Int, List, NonEmptyStr, String } -import std.materialization_ladder { Frame, SharedStateFrame } -import std.effect_grant { Read, Write, ServiceOpTree, NamespacePosition, ModeledRealization, LifecycleByConstruction, Grant, Envelope } -import v2.std.operation_realization { OperationRealization, virtual_clock_origin } -import v2.std.witness_evaluation { WitnessEvaluationFrame, WitnessReturned, evaluate_in_witness_frame } -import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld, mtcollins1_boot_dry_realization } -import gunbc.machine_intake_mtcollins1_boot_run { mtcollins1_boot_wet_on_srv1 } -import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { world_with_console, matrix_frame, matrix_frame_over, realization_identity } - -fn no_advance(r: OperationRealization) -> OperationRealization { - OperationRealization { identity: r.identity, initial: r.initial, epoch: r.epoch, bindings: r.bindings, advance: fn(w, now) { w } } -} - -test fn cp_baseline() -> Bool { - match evaluate_in_witness_frame(frame: matrix_frame(world: world_with_console(lines: [])), subject: fn(_s) { mtcollins1_boot_wet_on_srv1() }) { WitnessReturned { value: _ } => true _ => false } -} - -test fn cp_no_advance() -> Bool { - let r = no_advance(r: mtcollins1_boot_dry_realization(identity: realization_identity, initial: world_with_console(lines: []), epoch: virtual_clock_origin())) - match evaluate_in_witness_frame(frame: matrix_frame_over(realization: r), subject: fn(_s) { mtcollins1_boot_wet_on_srv1() }) { WitnessReturned { value: _ } => true _ => false } -} - -test fn cp_world_only() -> Bool { - let w = world_with_console(lines: []) - count(w.environment) > 0 -} - -fn sleeps(n: Int) -> Bool { - if n == 0 { true } else { - let ok = extdeps.tools.sleep.sleep_delay_seconds_second_carrier_projection(duration: std.measure.second(count: 1)) - ok && sleeps(n: n - 1) - } -} - -test fn cp_100_sleeps_full_frame() -> Bool { - match evaluate_in_witness_frame(frame: matrix_frame(world: world_with_console(lines: [])), subject: fn(_s) { sleeps(n: 100) }) { WitnessReturned { value } => value _ => false } -} - -test fn cp_0_sleeps_full_frame() -> Bool { - match evaluate_in_witness_frame(frame: matrix_frame(world: world_with_console(lines: [])), subject: fn(_s) { sleeps(n: 0) }) { WitnessReturned { value } => value _ => false } -} diff --git a/dag/test/claim/zz_probe/deadline_probe.dag b/dag/test/claim/zz_probe/deadline_probe.dag deleted file mode 100644 index 209abdf7653..00000000000 --- a/dag/test/claim/zz_probe/deadline_probe.dag +++ /dev/null @@ -1,21 +0,0 @@ -module test.claim.zz_probe.deadline_probe - -import std.types { Int, List, String } -import std.process { ProcessExit, ExitFailure, exit_failure } -import v2.std.witness_evaluation { WitnessReturned, WitnessRefused, WitnessInterrupted, witness_diagnostic_rendered_reason } -import v2.std.operation_realization { DispatchRecord } -import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld } -import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { run_attempt, world_with_console, outcome_reason, operation_name } - -fn route_text(route: List) -> String { - join(map(route, r => operation_name(r: r)), " > ") -} - -test fn probe() -> ProcessExit { - match run_attempt(world: world_with_console(lines: [])) { - WitnessReturned { value, route } => exit_failure(reason: concat(concat(outcome_reason(a: value), " ### "), route_text(route: route))) - WitnessRefused { diagnostic, route } => exit_failure(reason: concat(concat(concat("REFUSED ", witness_diagnostic_rendered_reason(diagnostic: diagnostic)), " ### "), route_text(route: route))) - WitnessInterrupted { at: _ } => exit_failure(reason: "INTERRUPTED") - } -} -data live_tree_disposition: v2.std.live_tree.LiveTreeDisposition = v2.std.live_tree.SubstrateInputsOnly diff --git a/dag/test/claim/zz_probe/fs_cost_probe.dag b/dag/test/claim/zz_probe/fs_cost_probe.dag deleted file mode 100644 index 05ba86ff3b2..00000000000 --- a/dag/test/claim/zz_probe/fs_cost_probe.dag +++ /dev/null @@ -1,18 +0,0 @@ -module test.claim.zz_probe.fs_cost_probe - -import std.types { Bool, Int, List, String } -import gunbc.filesystem_model { fs_read } -import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { world_with_console } - -data live_tree_disposition: v2.std.live_tree.LiveTreeDisposition = v2.std.live_tree.SubstrateInputsOnly - -test fn reads_166() -> Bool { - let w = world_with_console(lines: []) - let n = fold([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100], init: 0, f: fn(acc, i) { match fs_read(fs: w.fs, path: "/run/sol.capture.notice.ready") { extdeps.transports.file.FileOperationSucceeded { byte_count: _, content: _ } => acc + 1 _ => acc } }) - count(w.fs.files) >= 0 && n == 100 -} - -test fn build_only() -> Bool { - let w = world_with_console(lines: []) - count(w.fs.files) >= 0 -} diff --git a/dag/test/claim/zz_probe/reasons2_probe.dag b/dag/test/claim/zz_probe/reasons2_probe.dag deleted file mode 100644 index f26664fad43..00000000000 --- a/dag/test/claim/zz_probe/reasons2_probe.dag +++ /dev/null @@ -1,43 +0,0 @@ -module test.claim.zz_probe.reasons2_probe - -import std.types { Bool, Int, List, String } -import std.measure { second, second_displacement } -import v2.std.witness_evaluation { WitnessReturned, WitnessRefused, WitnessInterrupted, witness_diagnostic_rendered_reason } -import gunbc.megarac_media_model { MegaRacMediaWorld, MegaRacImage, megarac_cleared_cd } -import gunbc.bmc_model { BmcPowerOn, bmc_with_power } -import gunbc.wall_clock_model { ModeledWallClock, ModeledClockStep } -import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld, with_bmc, with_media } -import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { run_attempt, world_with_console, outcome_reason, desired_image, real_share, healthy_media } - -fn summary(w: MtCollins1BootWorld) -> String { - match run_attempt(world: w) { - WitnessReturned { value, route } => concat(outcome_reason(a: value), concat(" || ops: ", join(map(filter(route, r => r.invocation.at.operation == "StopMedia" || r.invocation.at.operation == "StartMedia" || r.invocation.at.operation == "ChassisPowerControl" || r.invocation.at.operation == "ChassisBootDevWithOptions"), r => r.invocation.at.operation), ","))) - WitnessRefused { diagnostic } => concat("REFUSED ", witness_diagnostic_rendered_reason(diagnostic: diagnostic)) - WitnessInterrupted { at: _ } => "INTERRUPTED" - } -} - -fn jumped(by: Int) -> MtCollins1BootWorld { - let w = world_with_console(lines: []) - MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: ModeledWallClock { unix_at_origin: 1790000000, step: second_displacement(count: 0), jumps: [ModeledClockStep { at: second(count: 20), by: second_displacement(count: by) }] }, worker: w.worker, console: w.console, media: w.media } -} - -fn errored(code: Int, clears: Bool, after_ready: Int?) -> MegaRacMediaWorld { - let m = healthy_media() - MegaRacMediaWorld { sessions: m.sessions, next_session: m.next_session, share: m.share, mount_cd: m.mount_cd, cd_error_code: code, images: m.images, cd: m.cd, ready_after: m.ready_after, withdraw_at: none, withdraw_after_ready: none, error_after_ready: after_ready, error_clears_on_stop: clears } -} - -fn no_code() -> Int? { none } - -fn stale_errored(clears: Bool) -> MegaRacMediaWorld { - let m = errored(code: 16, clears: clears, after_ready: no_code()) - MegaRacMediaWorld { sessions: m.sessions, next_session: m.next_session, share: m.share, mount_cd: m.mount_cd, cd_error_code: m.cd_error_code, images: m.images, cd: gunbc.megarac_media_model.MegaRacCdRow { image_name: "gunbc-mtcollins1-census-ubuntu-24.04.3-arm64-0000000000000000.iso", redirection_status: 1, media_index: 0, session_index: 0, ready_at: none }, ready_after: m.ready_after, withdraw_at: none, withdraw_after_ready: none, error_after_ready: none, error_clears_on_stop: clears } -} - -fn probe() -> String { - let base = world_with_console(lines: []) - join([ - concat("E5 stale+16 clears: ", summary(w: with_media(w: base, media: stale_errored(clears: true)))), - concat("E6 stale+16 sticks: ", summary(w: with_media(w: base, media: stale_errored(clears: false)))), - ], " ||| ") -} diff --git a/dag/test/claim/zz_probe/reasons_probe.dag b/dag/test/claim/zz_probe/reasons_probe.dag deleted file mode 100644 index 82e8af790ce..00000000000 --- a/dag/test/claim/zz_probe/reasons_probe.dag +++ /dev/null @@ -1,31 +0,0 @@ -module test.claim.zz_probe.reasons_probe - -import std.types { Int, List, String } -import std.measure { second } -import v2.std.witness_evaluation { WitnessReturned, WitnessRefused, WitnessInterrupted, witness_diagnostic_rendered_reason } -import gunbc.megarac_media_model { MegaRacShare, MegaRacImage, megarac_cleared_cd } -import gunbc.bmc_model { bmc_with_sol_session } -import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld, with_bmc } -import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { - run_attempt, world_with_console, outcome_reason, media_varied, media_with, desired_image, real_share, no_withdrawal, -} - -fn reason_of(w: MtCollins1BootWorld) -> String { - match run_attempt(world: w) { - WitnessReturned { value } => outcome_reason(a: value) - WitnessRefused { diagnostic } => concat("REFUSED ", witness_diagnostic_rendered_reason(diagnostic: diagnostic)) - WitnessInterrupted { at: _ } => "INTERRUPTED" - } -} - -fn withdrawn_after(d: Int) -> String { - let img = [MegaRacImage { image_name: desired_image(), image_index: 5 }] - match std.checked_arithmetic.checked_int_to_nat(n: d) { - Absent => "bad" - Present { value: n } => concat(concat(to_string(d), ": "), reason_of(w: media_varied(media: media_with(images: img, share: real_share, cd: megarac_cleared_cd(), ready_after: 12, withdraw_after_ready: Present { value: second(count: n) })))) - } -} - -fn probe() -> String { - join(map([3, 5, 8, 12, 20], d => withdrawn_after(d: d)), " ||| ") -} diff --git a/dag/test/claim/zz_probe/route_len_probe.dag b/dag/test/claim/zz_probe/route_len_probe.dag deleted file mode 100644 index 9abbfda24e5..00000000000 --- a/dag/test/claim/zz_probe/route_len_probe.dag +++ /dev/null @@ -1,12 +0,0 @@ -module test.claim.zz_probe.route_len_probe - -import std.types { String } -import v2.std.witness_evaluation { WitnessReturned, WitnessRefused, WitnessInterrupted } -import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { run_attempt, world_with_console } - -fn probe() -> String { - match run_attempt(world: world_with_console(lines: [])) { - WitnessReturned { route } => join(map(filter(route, r => r.invocation.at.operation == "StartMedia" || r.invocation.at.operation == "GetRemoteConfigurations" || r.invocation.at.operation == "ChassisPowerControl"), r => concat(concat(r.invocation.at.operation, "@"), to_string(std.measure.second_count(s: r.dispatched_at) as Int))), " ") - _ => "x" - } -} diff --git a/dag/test/claim/zz_probe/sol_flip_probe.dag b/dag/test/claim/zz_probe/sol_flip_probe.dag deleted file mode 100644 index ddecb68eb58..00000000000 --- a/dag/test/claim/zz_probe/sol_flip_probe.dag +++ /dev/null @@ -1,39 +0,0 @@ -module test.claim.zz_probe.sol_flip_probe - -import std.types { Int, List, String } -import std.measure { second, second_count } -import std.process { ProcessExit, exit_failure } -import v2.std.witness_evaluation { WitnessReturned, WitnessRefused, WitnessInterrupted, witness_diagnostic_rendered_reason, evaluate_in_witness_frame } -import v2.std.operation_realization { DispatchRecord } -import gunbc.bmc_model { bmc_with_sol_session, bmc_with_sol_drop_after_boot, bmc_sol_drop_fired } -import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld, with_bmc } -import gunbc.machine_intake_mtcollins1_boot_run { mtcollins1_boot_wet_on_srv1 } -import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { run_attempt, world_with_console, outcome_reason, operation_name, console_of, one_socket_census_capture, matrix_frame, is_controller_write, census_ended } - -data live_tree_disposition: v2.std.live_tree.LiveTreeDisposition = v2.std.live_tree.SubstrateInputsOnly - -fn writes(route: List) -> String { - join(map(filter(route, r => is_controller_write(r: r) || operation_name(r: r) == "gunbc.machine_intake.sol_hold.ReleaseHeld" || operation_name(r: r) == "Filesystem.Delete"), r => concat(concat(operation_name(r: r), "@"), to_string(second_count(s: r.dispatched_at)))), " > ") -} - -fn report(w: MtCollins1BootWorld) -> ProcessExit { - match evaluate_in_witness_frame(frame: matrix_frame(world: w), subject: fn(_scope) { mtcollins1_boot_wet_on_srv1() }) { - WitnessReturned { value, route } => exit_failure(reason: join([outcome_reason(a: value), " ### census_ended=", if census_ended(a: value) { "yes" } else { "no" }, " ### ", writes(route: route)], "")) - WitnessRefused { diagnostic, route } => exit_failure(reason: concat("REFUSED ", witness_diagnostic_rendered_reason(diagnostic: diagnostic))) - WitnessInterrupted { at: _ } => exit_failure(reason: "INTERRUPTED") - } -} - -test fn healthy() -> ProcessExit { - report(w: world_with_console(lines: console_of(capture: one_socket_census_capture, begin_after: 60, end_after: 240))) -} - -test fn held_elsewhere() -> ProcessExit { - let w = world_with_console(lines: []) - report(w: with_bmc(w: w, bmc: bmc_with_sol_session(world: w.bmc, open: true))) -} - -test fn loss() -> ProcessExit { - let w = world_with_console(lines: console_of(capture: one_socket_census_capture, begin_after: 60, end_after: 240)) - report(w: with_bmc(w: w, bmc: bmc_with_sol_drop_after_boot(world: w.bmc, after: second(count: 30)))) -} diff --git a/dag/test/claim/zz_probe/two_socket_probe.dag b/dag/test/claim/zz_probe/two_socket_probe.dag deleted file mode 100644 index 965e3ab5e4a..00000000000 --- a/dag/test/claim/zz_probe/two_socket_probe.dag +++ /dev/null @@ -1,13 +0,0 @@ -module test.claim.zz_probe.two_socket_probe - -import std.types { String } -import v2.std.witness_evaluation { WitnessReturned, WitnessRefused, WitnessInterrupted, witness_diagnostic_rendered_reason } -import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { run_attempt, world_with_console, console_of, two_socket_census_capture, outcome_reason, census_ended } - -fn probe() -> String { - match run_attempt(world: world_with_console(lines: console_of(capture: two_socket_census_capture, begin_after: 60, end_after: 240))) { - WitnessReturned { value } => join(["RETURNED ", outcome_reason(a: value), " census_ended=", if census_ended(a: value) { "yes" } else { "no" }], "") - WitnessRefused { diagnostic } => concat("REFUSED ", witness_diagnostic_rendered_reason(diagnostic: diagnostic)) - WitnessInterrupted { at: _ } => "INTERRUPTED" - } -} diff --git a/dag/test/claim/zz_probe/world_cost_probe.dag b/dag/test/claim/zz_probe/world_cost_probe.dag deleted file mode 100644 index 09183bca213..00000000000 --- a/dag/test/claim/zz_probe/world_cost_probe.dag +++ /dev/null @@ -1,18 +0,0 @@ -module test.claim.zz_probe.world_cost_probe - -import std.types { Bool, List } -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } -import test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test { world_with_console, console_of, one_socket_census_capture, matrix_frame } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -test fn build_empty_world() -> Bool { - let w = world_with_console(lines: []) - count(w.fs.directories) > 0 -} - -test fn build_census_world_and_frame() -> Bool { - let w = world_with_console(lines: console_of(capture: one_socket_census_capture, begin_after: 60, end_after: 240)) - let f = matrix_frame(world: w) - count(w.console.lines) > 0 && count(f.envelope.grants) > 0 -} From 6cac35eb1a6ea472dc79e603a3005ca70af138ba Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Wed, 30 Sep 2026 19:21:41 +0000 Subject: [PATCH 61/75] mtcollins1 boot matrix: dry KVM observer, toolchain NotReady/Unresolved cases, #12437 claim split, regenerated rung drops (a) The dry world now answers gunbc.owned_process LaunchOwned for the KVM observer. It starts a process visible in /proc with its " " record at the pid path, and writes its journal only through gunbc.machine_intake_mtcollins1_kvm_still kvm_journal_line: connection-requested, connection-open, then established with the quoted host:port, session, attempt and gen. While live, it answers each trigger file with a still, and on the stop file it journals stop-requested, session release, browser close and stopped, then exits. A line kvm_journal_line refuses is a harness fault. Still digests are supplied beside the bytes (the gunbc.remote_host_model precedent); sha256sum answers only for those bytes. All 26 matrix cases PASS under claim_batch locally; at ec1b819, without this binding, 22 returned false. (b) a_toolchain_that_is_not_ready_... / an_unresolved_toolchain_...: no Mkdir, no LaunchOwned, no power action, and the refusal names the toolchain's standing. (c) The matrix now names the pairing claim that runs runner_browser_toolchain_here_wet for real: mtcollins1_kvm_observer_protocol_wet_witness a_held_observer_is_admitted_and_its_triggered_still_is_hash_bound. (e) #12437 (test-only) made the_build_job_carries_the_reset_observer_dispatch_admission build the whole host-reset-return job to read its if. Both gates read fleet_converge_host_reset_return_step_if, so the claim is split: the step side compares its gate to that datum, and the_host_reset_return_job_is_gated_by_the_admissions_gate holds the job side. (f) docs/design-rung-drops.md regenerated by tools.generated_artifact_gate main_wet on the merged tree; it wrote no other change. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../mtcollins1_boot_dry_realization.dag | 247 +++++++++++++++++- ...mtcollins1_boot_acceptance_matrix_test.dag | 48 +++- .../workflow_dispatch_input_witness_test.dag | 25 +- docs/design-rung-drops.md | 6 +- 4 files changed, 305 insertions(+), 21 deletions(-) diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag index 71ed06ee69e..2f5332a99dc 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag @@ -27,7 +27,16 @@ import gunbc.machine_intake_sol_hold { sol_hold_exit_record_prefix } import gunbc.machine_intake_mtcollins1_boot_run { mtcollins1_sol_notice_ready_suffix, mtcollins1_sol_notice_watcher_path, mtcollins1_sol_notice_token_env } import gunbc.fleet_ssh_access { fleet_automation_ssh_key_fingerprint } import gunbc.remote_host_model { ModeledRemoteHost, remote_host_binding } -import gunbc.wall_clock_model { ModeledWallClock, wall_clock_bindings } +import gunbc.wall_clock_model { ModeledWallClock, wall_clock_bindings, wall_clock_unix } +import extdeps.units.iso8601_calendar { iso8601_utc_text } +import std.checked_arithmetic { checked_int_to_nat } +import std.measure { millisecond } +import v2.std.operation_argv { InputText, InputTextList } +import gunbc.machine_intake_mtcollins1_kvm_still { + KvmInstant, KvmJournalEvent, KvmJournalRendered, KvmJournalRenderRefused, kvm_journal_line, + KvmJournalConnectionRequested, KvmJournalConnectionOpen, KvmJournalEstablished, KvmJournalStill, + KvmJournalStopRequested, KvmJournalSessionRelease, KvmJournalBrowserClose, KvmJournalStopped, +} // THE DRY REALIZATION OF ONE mtcollins1 BOOT ATTEMPT'S WHOLE EFFECT DEMAND. The scenario world // composes the one BMC model with what the worker running the attempt has around it: its filesystem @@ -47,6 +56,7 @@ type MtCollins1BootWorld { worker: ModeledWorker console: ModeledHostConsole media: MegaRacMediaWorld + screen: ModeledKvmViewer } // THE WORKER'S SSH AGENT: whether it holds the fleet automation key. Its listing follows @@ -104,23 +114,23 @@ type ModeledHostConsole { } fn with_bmc(w: MtCollins1BootWorld, bmc: BmcWorld) -> MtCollins1BootWorld { - MtCollins1BootWorld { bmc: bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: w.media } + MtCollins1BootWorld { bmc: bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: w.media, screen: w.screen } } fn with_fs(w: MtCollins1BootWorld, fs: ModeledFilesystem) -> MtCollins1BootWorld { - MtCollins1BootWorld { bmc: w.bmc, fs: fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: w.media } + MtCollins1BootWorld { bmc: w.bmc, fs: fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: w.media, screen: w.screen } } fn with_worker(w: MtCollins1BootWorld, worker: ModeledWorker) -> MtCollins1BootWorld { - MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: worker, console: w.console, media: w.media } + MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: worker, console: w.console, media: w.media, screen: w.screen } } fn with_console(w: MtCollins1BootWorld, console: ModeledHostConsole) -> MtCollins1BootWorld { - MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: console, media: w.media } + MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: console, media: w.media, screen: w.screen } } fn with_media(w: MtCollins1BootWorld, media: MegaRacMediaWorld) -> MtCollins1BootWorld { - MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: media } + MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: media, screen: w.screen } } fn appended(fs: ModeledFilesystem, path: String, text: String) -> ModeledFilesystem { @@ -236,7 +246,7 @@ fn with_notice_watcher(w: MtCollins1BootWorld, capture_path: String, token: Stri let p = ModeledProcess { pid: w.worker.next_pid, start_time: start_ticks(w: w, now: second(count: 0)), comm: "bash", cmdline: "bash -c gunbc-sol-notice-watch", capture_path: capture_path, diagnostic_path: "", alive: true } let fs = fs_with_file(fs: fs_with_file(fs: w.fs, path: concat(capture_path, mtcollins1_sol_notice_ready_suffix), content: concat(token, "\n")), path: mtcollins1_sol_notice_watcher_path(capture_path: capture_path), content: process_identity(p: p)) let env = list_append(w.environment, ModeledVariable { name: mtcollins1_sol_notice_token_env as String, value: token }) - started(w: MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: env, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: w.media }, p: p, fs: fs) + started(w: MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: env, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: w.media, screen: w.screen }, p: p, fs: fs) } fn exited_step(state: S, stdout: String, exit_code: Int) -> OperationStep { @@ -388,7 +398,226 @@ fn boot_world_idle(w: MtCollins1BootWorld) -> Bool { fn boot_advance(w: MtCollins1BootWorld, now: Second) -> MtCollins1BootWorld { let stepped = if boot_world_idle(w: w) { w } else { with_media(w: with_bmc(w: w, bmc: bmc_advance(world: w.bmc, now: now)), media: megarac_media_advance(world: w.media, now: now)) } - console_advance(w: collectors_follow_session(w: stepped), now: now) + kvm_observers_advance(w: console_advance(w: collectors_follow_session(w: stepped), now: now), now: now) +} + +// THE BMC KVM VIEWER AND THE OBSERVER HELD AGAINST IT (gunbc#12492: the boot's handoff is admitted +// only while the observer it started is established). The observer is the process +// gunbc.owned_process LaunchOwned starts over gunbc.machine_intake_mtcollins1_kvm_still +// kvm_observer_launch_in's node command. The model starts it the way the launch does -- a live process +// in /proc, its " " record at the pid path -- and writes its journal ONLY through +// kvm_journal_line, the writer the production parser is the inverse of, so the dry observer cannot +// speak a grammar the boot does not read. A line kvm_journal_line refuses is a harness fault, never a +// line written anyway. +// +// What it answers, as the observer script does once the viewer's /kvm socket delivers a frame: the +// connection lines, then established with the quoted host:port the base URL names, the viewer +// session, the attempt and the generation; then, while it lives, one still per trigger file (the +// script's 'trigger:'+name reason) and, on the stop file, stop-requested, the session release, the +// browser close and stopped, after which the process has exited. It takes no periodic still: the +// boot's attempt ends well inside mtcollins1_kvm_observer_cadence's first period in every scenario +// the matrix runs, and a longer one reports the gap through kvm_still_gaps as the real journal would. +// +// A still's bytes are one fixed modeled frame, and its digest is supplied beside it (the precedent is +// gunbc.remote_host_model ModeledRemoteFile.sha256): sha256sum answers that digest for exactly those +// bytes, reports a missing file as sha256sum does, and refuses as a harness fault for any other bytes +// rather than inventing a digest. +type ModeledKvmViewer { + session: String + still_bytes: String + still_sha256: String + observers: List +} + +type ModeledKvmObserver { + pid: Int + dir: String + seq: Int +} + +// printf '%s' '' | sha256sum +fn healthy_kvm_viewer() -> ModeledKvmViewer { + ModeledKvmViewer { session: "7", still_bytes: "", still_sha256: "550277e71ddf7d978137c4bd140a9b5cfda25500b365a7375fb91db8790f584c", observers: [] } +} + +fn with_screen(w: MtCollins1BootWorld, screen: ModeledKvmViewer) -> MtCollins1BootWorld { + MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: w.media, screen: screen } +} + +data kvm_observer_generation: String = "1" + +// The observer script writes Date.now() and its toISOString(); the model's wall clock is whole seconds. +fn kvm_instant(w: MtCollins1BootWorld, now: Second) -> KvmInstant? { + let unix = wall_clock_unix(clock: w.clock, now: now) + match checked_int_to_nat(n: unix * 1000) { + Present { value: ms } => Present { value: KvmInstant { since_epoch: millisecond(count: ms), iso: concat(join(split(s: iso8601_utc_text(unix: unix), delimiter: "Z"), ""), ".000Z") } } + Absent => none + } +} + +// The journal lines for these events, or the first event kvm_journal_line refuses to write. +type KvmModeledLines + = KvmModeledRendered { text: String } + | KvmModeledRefused { event_word: String, would_write: String } + +fn kvm_lines(events: List) -> KvmModeledLines { + fold(events, init: KvmModeledRendered { text: "" }, f: fn(acc, e) { + match acc { + KvmModeledRendered { text: t } => match kvm_journal_line(event: e) { + KvmJournalRendered { line: l } => KvmModeledRendered { text: concat(t, concat(l, "\n")) } + KvmJournalRenderRefused { event_word: word, would_write: line } => KvmModeledRefused { event_word: word, would_write: line } + } + refused => refused + } + }) +} + +fn operation_input_list(call: OperationCall, name: String) -> List? { + fold(call.invocation.bindings, init: none, f: fn(acc, b) { + match acc { + Present { value: v } => Present { value: v } + Absent => if b.name == name { match b.value { InputTextList { items: xs } => Present { value: xs } InputText { text: _ } => none } } else { none } + } + }) +} + +// kvm_observer_launch_in's operands end the node command: base URL, user, credential path, dir, +// attempt, cadence, frame wait, periodic limit, playwright module. +data kvm_observer_operand_count: Int = 9 + +fn kvm_operand(command: List, i: Int) -> String { + match command.skip(n: count(command) - kvm_observer_operand_count + i).first() { Present { value: v } => v Absent => "" } +} + +fn url_host(base_url: String) -> String { + match split(s: base_url, delimiter: "://").skip(n: 1).first() { + Present { value: rest } => match split(s: rest, delimiter: "/").first() { Present { value: h } => h Absent => "" } + Absent => "" + } +} + +// gunbc.owned_process LaunchOwned: starts the command detached, publishes " " to the +// pid path, and exits 0. The observer it starts reaches established at once in the healthy viewer. +fn owned_launch_handler(w: MtCollins1BootWorld, call: OperationCall) -> OperationStep { + match operation_input_text(invocation: call.invocation, name: "pid_path") { + Absent => OperationHarnessFault { reason: "LaunchOwned was dispatched without a pid path" as NonEmptyStr } + Present { value: pid_path } => match operation_input_list(call: call, name: "command") { + Absent => OperationHarnessFault { reason: "LaunchOwned was dispatched without a command" as NonEmptyStr } + Present { value: command } => + if count(command) < kvm_observer_operand_count { OperationHarnessFault { reason: "LaunchOwned's command is not the KVM observer's; the dry worker models no other owned process" as NonEmptyStr } } + else { match kvm_instant(w: w, now: call.now) { + Absent => OperationHarnessFault { reason: "the modeled wall clock reads before the epoch" as NonEmptyStr } + Present { value: at } => { + let dir = kvm_operand(command: command, i: 3) + let p = ModeledProcess { pid: w.worker.next_pid, start_time: start_ticks(w: w, now: call.now), comm: "node", cmdline: join(command, " "), capture_path: "", diagnostic_path: "", alive: true } + let journal = kvm_lines(events: [ + KvmJournalConnectionRequested { at: at }, + KvmJournalConnectionOpen { at: at, gen: kvm_observer_generation }, + KvmJournalEstablished { at: at, host: concat("\"", concat(url_host(base_url: kvm_operand(command: command, i: 0)), "\"")), session: w.screen.session, attempt: kvm_operand(command: command, i: 4), gen: kvm_observer_generation }, + ]) + match journal { + KvmModeledRefused { event_word: word, would_write: line } => OperationHarnessFault { reason: concat("kvm_journal_line refused the modeled ", concat(word, concat(" line: ", line))) as NonEmptyStr } + KvmModeledRendered { text: t } => { + let fs = appended(fs: fs_write(fs: w.fs, path: pid_path, content: process_identity(p: p), create_new: false).fs, path: concat(dir, "/journal"), text: t) + let screen = ModeledKvmViewer { session: w.screen.session, still_bytes: w.screen.still_bytes, still_sha256: w.screen.still_sha256, observers: list_append(w.screen.observers, ModeledKvmObserver { pid: p.pid, dir: dir, seq: 0 }) } + exited_step(state: with_screen(w: started(w: w, p: p, fs: fs), screen: screen), stdout: "", exit_code: 0) + } + } + } + } } + } + } +} + +fn kvm_observer_alive(w: MtCollins1BootWorld, o: ModeledKvmObserver) -> Bool { + !all(w.worker.processes, p => !(p.alive && p.pid == o.pid)) +} + +// THE OBSERVER'S LOOP, one pass per advance, in the script's order: the stop file ends it; otherwise +// each trigger file, in name order, is consumed and answered with a still. +fn kvm_observers_advance(w: MtCollins1BootWorld, now: Second) -> MtCollins1BootWorld { + if count(w.screen.observers) == 0 { w } else { + fold(w.screen.observers, init: w, f: fn(acc, o) { if kvm_observer_alive(w: acc, o: o) { kvm_observer_pass(w: acc, o: o, now: now) } else { acc } }) + } +} + +fn kvm_observer_pass(w: MtCollins1BootWorld, o: ModeledKvmObserver, now: Second) -> MtCollins1BootWorld { + match kvm_instant(w: w, now: now) { + Absent => w + Present { value: at } => + match fs_file(fs: w.fs, path: concat(o.dir, "/stop")) { + Present { value: _ } => kvm_observer_stopped(w: w, o: o, at: at) + Absent => kvm_observer_answer_triggers(w: w, o: o, at: at) + } + } +} + +fn kvm_journal_appended(w: MtCollins1BootWorld, o: ModeledKvmObserver, events: List) -> MtCollins1BootWorld { + match kvm_lines(events: events) { + KvmModeledRendered { text: t } => with_fs(w: w, fs: appended(fs: w.fs, path: concat(o.dir, "/journal"), text: t)) + KvmModeledRefused { event_word: _, would_write: _ } => w + } +} + +fn kvm_observer_stopped(w: MtCollins1BootWorld, o: ModeledKvmObserver, at: KvmInstant) -> MtCollins1BootWorld { + let journalled = kvm_journal_appended(w: w, o: o, events: [ + KvmJournalStopRequested { at: at, by: "stop-file" }, + KvmJournalSessionRelease { at: at, result: "released" }, + KvmJournalBrowserClose { at: at, result: "closed" }, + KvmJournalStopped { at: at, session: "released", browser: "closed" }, + ]) + exit_processes(w: journalled, ending: fn(p) { p.pid == o.pid }) +} + +fn kvm_trigger_files(w: MtCollins1BootWorld, o: ModeledKvmObserver) -> List { + map(filter(w.fs.files, f => starts_with(s: f.path, prefix: concat(o.dir, "/trigger-"))), f => f.path).sort_by(p => p) +} + +fn kvm_observer_answer_triggers(w: MtCollins1BootWorld, o: ModeledKvmObserver, at: KvmInstant) -> MtCollins1BootWorld { + let triggers = kvm_trigger_files(w: w, o: o) + if count(triggers) == 0 { w } else { + let answered = fold(triggers, init: w, f: fn(acc, path) { + let seq = kvm_observer_seq(w: acc, pid: o.pid) + 1 + let file = concat("still-", concat(to_string(seq), ".jpg")) + let name = join(split(s: path, delimiter: concat(o.dir, "/trigger-")), "") + let consumed = with_fs(w: acc, fs: fs_with_file(fs: fs_without_file(fs: acc.fs, path: path), path: concat(o.dir, concat("/", file)), content: acc.screen.still_bytes)) + with_kvm_seq(w: kvm_journal_appended(w: consumed, o: o, events: [KvmJournalStill { at: at, seq: to_string(seq), reason: concat("trigger:", name), file: file, gen: kvm_observer_generation }]), pid: o.pid, seq: seq) + }) + answered + } +} + +fn kvm_observer_seq(w: MtCollins1BootWorld, pid: Int) -> Int { + fold(w.screen.observers, init: 0, f: fn(acc, o) { if o.pid == pid { o.seq } else { acc } }) +} + +fn with_kvm_seq(w: MtCollins1BootWorld, pid: Int, seq: Int) -> MtCollins1BootWorld { + with_screen(w: w, screen: ModeledKvmViewer { session: w.screen.session, still_bytes: w.screen.still_bytes, still_sha256: w.screen.still_sha256, observers: map(w.screen.observers, o => if o.pid == pid { ModeledKvmObserver { pid: o.pid, dir: o.dir, seq: seq } } else { o }) }) +} + +data owned_process_launch_operation: OperationRef = OperationRef { + path: "dag/gunbc/owned_process.dag", + service: "gunbc.owned_process.launch", + operation: "LaunchOwned", +} + +data sha256sum_digest_file_operation: OperationRef = OperationRef { + path: "dag/extdeps/tools/sha256sum.dag", + service: "sha256sum.Sha256", + operation: "DigestFile", +} + +// sha256sum(1): " " and exit 0; a missing file is "No such file or directory", exit 1. +fn digest_file_handler(w: MtCollins1BootWorld, call: OperationCall) -> OperationStep { + match operation_input_text(invocation: call.invocation, name: "path") { + Absent => OperationHarnessFault { reason: "DigestFile was dispatched without a path" as NonEmptyStr } + Present { value: path } => match fs_file(fs: w.fs, path: path) { + Absent => OperationObserved { observation: ShellObserved { observation: ShellProcessExited { exit_code: 1, stdout: "", stderr: concat("sha256sum: ", concat(path, ": No such file or directory\n")) } }, state: w, elapsed: second(count: 0) } + Present { value: f } => + if f.content == w.screen.still_bytes { exited_step(state: w, stdout: concat(w.screen.still_sha256, concat(" ", concat(path, "\n"))), exit_code: 0) } + else { OperationHarnessFault { reason: concat("no digest is modeled for the bytes of ", path) as NonEmptyStr } } + } + } } data sol_hold_activate_held_operation: OperationRef = OperationRef { @@ -446,6 +675,8 @@ fn mtcollins1_boot_dry_realization(identity: NonEmptyStr, initial: MtCollins1Boo OperationBinding { at: sol_hold_release_held_operation, handler: sol_release_held_handler }, OperationBinding { at: linux_procfs_read_uptime_operation, handler: uptime_handler }, OperationBinding { at: os_hostname_read_short_operation, handler: hostname_handler }, + OperationBinding { at: owned_process_launch_operation, handler: owned_launch_handler }, + OperationBinding { at: sha256sum_digest_file_operation, handler: digest_file_handler }, ] OperationRealization { identity: identity, diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index f279e751541..ae3d7f1b396 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -21,7 +21,7 @@ import gunbc.megarac_media_model { MegaRacMediaWorld, MegaRacShare, MegaRacImage import gunbc.machine_intake_mtcollins1_boot_dry_realization { MtCollins1BootWorld, ModeledSshAgent, ModeledWorker, ModeledHostConsole, TimedConsoleLine, mtcollins1_boot_dry_realization, with_media, with_bmc, with_notice_watcher, with_fs, - worker_process_started, worker_process_killed, proc_stat_path, proc_stat_line, worker_process, + worker_process_started, worker_process_killed, proc_stat_path, proc_stat_line, worker_process, healthy_kvm_viewer, } import v2.std.operation_realization { OperationRealization, OperationBinding, OperationCall, OperationStep, OperationObserved, OperationWorkerKilled, @@ -77,6 +77,7 @@ fn matrix_grant(service: String, verb: std.effect_grant.Verb) -> Grant { data matrix_services: List = [ "diagnostic.ipmi.Tool", "megarac.Media", "Filesystem", "shell.Env", "sleep.Delay", "gunbc.machine_intake.sol_hold", "shell.Exec", "ssh.Session", "Clock", "linux.Procfs", "shell.Move", "os.Hostname", "shell.Mkdir", "shell.Path", + "gunbc.owned_process.launch", "sha256sum.Sha256", ] fn matrix_frame(world: MtCollins1BootWorld) -> WitnessEvaluationFrame { @@ -99,6 +100,11 @@ fn matrix_frame_over(realization: OperationRealization) -> // tree against its pin, the host libraries, the versions and a launch probe -- which is a different // subject with its own witnesses. The matrix supplies each resolution arm the boot can meet, built from // the production location and probe values, and the inner entry calls it where the observer starts. +// PAIRING (DESIGN s3): the real resolution is executed by +// test.claim.machine_intake.mtcollins1_kvm_observer_protocol_wet_witness +// a_held_observer_is_admitted_and_its_triggered_still_is_hash_bound, whose rig calls +// runner_browser_toolchain_here_wet on the floor pool and returns false on every arm but Ready, so +// deleting that integration turns it red; it also launches the real observer over the resolved location. fn srv1_toolchain_location() -> RunnerBrowserToolchainLocation? { match runner_browser_toolchain_host_admission(host: "srv1" as NonEmptyStr) { BrowserToolchainHostAdmitted { deploy: _, location: loc } => Present { value: loc } @@ -213,6 +219,7 @@ fn world_with_console(lines: List) -> MtCollins1BootWorld { worker: ModeledWorker { next_pid: 4000, processes: [], uptime_at_origin: 86400 }, console: ModeledHostConsole { lines: lines, emitted: 0, boot: none }, media: healthy_media(), + screen: healthy_kvm_viewer(), }) } @@ -332,6 +339,41 @@ test fn a_healthy_census_completes_and_releases_its_collector() -> Bool { } } +// THE RUNNER'S BROWSER TOOLCHAIN IS NOT READY, OR CANNOT BE RESOLVED (operator-accepted ruling A: the +// matrix supplies the resolution). The observer is REQUIRED for the handoff, so neither arm starts a +// viewer with a toolchain it could not vouch for: no observer directory is made, no process is launched, +// and the handoff refuses with the toolchain's own standing as its cause -- before any boot override or +// power action. +fn run_attempt_with_toolchain(world: MtCollins1BootWorld, toolchain: RunnerBrowserToolchainResolution) -> WitnessEvaluation { + evaluate_in_witness_frame(frame: matrix_frame(world: world), subject: fn(_scope) { boot_with_toolchain(toolchain: toolchain) }) +} + +fn no_observer_and_no_power_action(route: List) -> Bool { + count_named(route: route, name: "shell.Mkdir.Parents") == 0 + && count_named(route: route, name: "gunbc.owned_process.launch.LaunchOwned") == 0 + && reached_no_power_action(route: route) +} + +test fn a_toolchain_that_is_not_ready_starts_no_observer_and_no_power_action() -> Bool { + match run_attempt_with_toolchain(world: world_with_console(lines: []), toolchain: not_ready_toolchain()) { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "the required KVM observer was not established") + && string_contains(s: outcome_reason(a: value), pattern: "the runner browser toolchain is not ready") + && no_observer_and_no_power_action(route: route) + _ => false + } +} + +test fn an_unresolved_toolchain_starts_no_observer_and_no_power_action() -> Bool { + match run_attempt_with_toolchain(world: world_with_console(lines: []), toolchain: unresolved_toolchain()) { + WitnessReturned { value, route } => + string_contains(s: outcome_reason(a: value), pattern: "the required KVM observer was not established") + && string_contains(s: outcome_reason(a: value), pattern: "the runner browser toolchain is unresolved") + && no_observer_and_no_power_action(route: route) + _ => false + } +} + // THE SAME UNIT HELD BY ANOTHER RUN. Before this attempt starts, a different run's boot holds the // unit (acquired through the production file_hold_acquire, into the same store). This attempt is // refused at the hold with the controller untouched: no controller write of any kind appears in its @@ -597,7 +639,7 @@ fn as_another_run(w: MtCollins1BootWorld, run_id: String) -> MtCollins1BootWorld fn as_another_run_in(w: MtCollins1BootWorld, run_id: String, pid_namespace: String) -> MtCollins1BootWorld { let env = map(w.environment, v => if v.name == "GITHUB_RUN_ID" { ModeledVariable { name: v.name, value: run_id } } else { v }) let fs = worker_process_started(fs: w.fs, boot_id: worker_boot_id, pid_namespace: pid_namespace, pid: first_worker_pid + 1, start_ticks: first_worker_start + 9000) - MtCollins1BootWorld { bmc: w.bmc, fs: fs, environment: env, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: w.media } + MtCollins1BootWorld { bmc: w.bmc, fs: fs, environment: env, agent: w.agent, remote_hosts: w.remote_hosts, clock: w.clock, worker: w.worker, console: w.console, media: w.media, screen: w.screen } } // THE NEXT ATTEMPT RECOVERS THE DEAD RUN'S HOLD (finding 2, repaired in #12555). The interrupted run @@ -678,7 +720,7 @@ fn with_clock_jump(w: MtCollins1BootWorld, at: Second, by: Int) -> MtCollins1Boo MtCollins1BootWorld { bmc: w.bmc, fs: w.fs, environment: w.environment, agent: w.agent, remote_hosts: w.remote_hosts, clock: ModeledWallClock { unix_at_origin: w.clock.unix_at_origin, step: w.clock.step, jumps: list_append(w.clock.jumps, ModeledClockStep { at: at, by: std.measure.second_displacement(count: by) }) }, - worker: w.worker, console: w.console, media: w.media, + worker: w.worker, console: w.console, media: w.media, screen: w.screen, } } diff --git a/dag/test/claim/workflow_dispatch_input_witness_test.dag b/dag/test/claim/workflow_dispatch_input_witness_test.dag index ad98e8fd314..eb0e565800a 100644 --- a/dag/test/claim/workflow_dispatch_input_witness_test.dag +++ b/dag/test/claim/workflow_dispatch_input_witness_test.dag @@ -10,7 +10,7 @@ import v2.std.collection { Present, Absent } import gunbc.fleet_converge_workflow { fleet_converge_fabric_writer_identity_observe_receipt_if, fleet_converge_fabric_writer_identity_observe_step_if, FleetConvergeWorkflowMode, fleet_converge_workflow_modes, fleet_converge_workflow_mode_wire, - fleet_converge_mode_step_if, fleet_converge_mode_scope, fleet_converge_host_reset_return_job, + fleet_converge_mode_step_if, fleet_converge_mode_scope, fleet_converge_host_reset_return_job, fleet_converge_host_reset_return_step_if, ApprovalBrokerDarkInstall, fleet_converge_approval_broker_dark_install_step_if, FullHostPlan, LaunchEnvironmentPlan, AllocationStorePlan, DashboardDeploy, HostResetReturn, RunnerPasswordSessionToolConverge, @@ -500,8 +500,12 @@ test fn a_whitespace_only_observer_is_refused_as_unnamed() -> Bool { // (host_reset_return_dispatch_admission_wet reads both env names) with both inputs wired. Control: // dropping fleet_converge_reset_observer_dispatch_admission_step() from the own list turns this red, // and so does removing its own-mode gate (it once ran, for minutes, on every mode's dispatch), or -// letting that gate drift from the consuming host-reset-return job's gate: the admission must run -// in exactly the mode whose job it protects, or the observer refusal is skipped where it applies. +// letting that gate drift from fleet_converge_host_reset_return_step_if, the one gate the consuming +// host-reset-return job also reads (the_host_reset_return_job_is_gated_by_the_admissions_gate holds +// the job's side): the admission must run in exactly the mode whose job it protects, or the observer +// refusal is skipped where it applies. The two sides are two claims because they are two producers; +// joined in one, this claim built the whole job to read one field (gunbc#12437) and paid 2.4x its +// budget for it. test fn the_build_job_carries_the_reset_observer_dispatch_admission() -> Bool { any( fleet_converge_build_job_own_steps(), @@ -513,10 +517,7 @@ test fn the_build_job_carries_the_reset_observer_dispatch_admission() -> Bool { && (match c { Present { value: g } => g == fleet_converge_mode_step_if(mode: HostResetReturn) - && (match fleet_converge_host_reset_return_job().if_condition { - Present { value: jg } => g == jg - Absent => false - }) + && g == fleet_converge_host_reset_return_step_if Absent => false }) && string_contains(s: r, pattern: gunbc_ci_host_reset_dispatch_admission_target.entry) @@ -530,6 +531,16 @@ test fn the_build_job_carries_the_reset_observer_dispatch_admission() -> Bool { ) } +// THE JOB'S SIDE OF THE SAME GATE, from the real job producer: the host-reset-return job is gated by +// fleet_converge_host_reset_return_step_if, the gate the dispatch admission step carries. Control: +// gating the job by any other condition, or ungating it, turns this red. +test fn the_host_reset_return_job_is_gated_by_the_admissions_gate() -> Bool { + match fleet_converge_host_reset_return_job().if_condition { + Present { value: jg } => jg == fleet_converge_host_reset_return_step_if + Absent => false + } +} + fn step_env_binds(env: List?, key: String, input: String) -> Bool { match env { Present { value: kvs } => diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index 0ee61e4f35c..26cfb449814 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -342,9 +342,9 @@ new-witness eval-step cost gate over the one roadmap page claim that derives the new-witness eval-step cost gate over the ten interpreted P-256 and P-384 point and group-law checks and SHA-384 FIPS vectors of the App Attest path: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the P-384 and SHA-384 primitives executing as natively emitted code rather than as interpreted bignat and Word64 folds). Population: test.claim.p384_dag_ecdsa_witness_test.the_p384_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_beside_the_base_point_is_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.a_point_with_a_coordinate_at_p_is_not_admitted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.p384_dag_ecdsa_witness_test.apples_ca_and_root_keys_are_on_p384: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by merge-queue required floor run 35678328407 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, wall under 2000ms, over the new-witness eval-step budget: the billed work is interpreted 384-bit field arithmetic (16 limbs) or a SHA-384 block over Word64 pairs, test.claim.sha384_fips_witness_test.sha384_of_the_empty_message_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published empty message and a one-octet message on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_abc_is_the_published_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is two single-block SHA-384 compressions, the published abc vector and abd on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.sha384_fips_witness_test.sha384_of_the_896_bit_message_is_the_published_two_block_value_and_one_octet_discriminates: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35703555837 (gunbc#11981, head 0b0a2dffe), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, over the new-witness eval-step budget and above the per-subject line. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field. The billed work is four SHA-384 block compressions, the published 896-bit two-block vector and a last-block mutation on an interpreter that reifies no machine width; the published positive and its discriminating mutation are one subject, so the cost is caused by the claim's own boundary and not by neighbouring vectors, test.claim.p256_dag_ecdsa_witness_test.the_base_point_is_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by required floor run 35708011844 (gunbc#11981), artifact required-ci-measurement-receipt; planned_as_changed_witness, verdict pass, well inside the wall deadline and over the new-witness eval-step budget. The billed work is one P-256 curve equation over the published base point as 11-limb bignat folds on an interpreter that reifies no machine width. It is a MEMBER BECAUSE IT WAS SPLIT OUT of a claim that also asserted n*G = infinity: that conjunction crossed the 8000ms wall deadline and was INTERRUPTED BEFORE ANY VERDICT, so both facts were being lost; the scalar multiplication left the floor for the native row the frontier names, and this cheap half now reaches a verdict. The standing figure is whatever this identity's row reads in the artifact named above, never a number copied into this field, test.claim.p384_dag_ecdsa_witness_test.doubling_and_adding_the_base_point_stay_on_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling, one addition and two projective curve-equation checks at 16 limbs, test.claim.p384_dag_ecdsa_witness_test.doubling_an_off_curve_point_stays_off_the_curve: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_interpreted_crypto_rows; measured by claim_batch --hermetic [witness] receipt on session/nimble-eagle-216-step3 (added for review 69917 after run 35678328407): verdict pass, wall under the 8 s deadline, over the new-witness eval-step budget; the billed work is one Jacobian doubling and one projective curve-equation check at 16 limbs. Restored when: THE CAPABILITY: gunbc test //gunbc/instruments:native-crypto-vectors EXECUTING ON THE MERGE PATH, i.e. as a phase of a required lane whose red blocks a merge, running these ten identities natively (its cases p256_the_base_point_is_on_the_curve, p384_the_base_point_is_on_the_curve, p384_red_a_point_beside_the_base_point_is_off_the_curve, p384_red_a_point_with_a_coordinate_at_p_is_not_admitted, p384_doubling_and_adding_the_base_point_stay_on_the_curve, p384_red_doubling_an_off_curve_point_stays_off_the_curve, p384_apples_ca_and_root_keys_are_on_the_curve and the sha384_* FIPS cases with their reds) while each still evaluates the real curve equation or the real hash; WHAT THAT MUST BE SUFFICIENT FOR: the P-384 parameters and SHA-384 are exercised on the acceptance path with no interpreted 16-limb fold inside a claim frame, so the interpreted identities can leave the floor for that row, or they measure under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives. The same row run BY NAME (as it exists since gunbc#12306) executes the facts natively but is NOT the acceptance path and retires nothing. Supplying the curve check's answer or the digest as a fixture, or deleting the identities, satisfies neither. -### new-witness eval-step cost gate over the eleven mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 +### new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 -new-witness eval-step cost gate over the eleven mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_host_that_never_prints_a_census_refuses_at_the_deadline, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=170048 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_healthy_census_completes_and_releases_its_collector, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=160637 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_already_presented_image_is_not_attached_again, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=137485 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions media_that_never_becomes_ready_refuses_before_any_power_action, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=92947 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_presentation_lost_after_readiness_stops_the_handoff, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=98794 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=132731 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_sol_loss_mid_boot_is_reported_before_the_deadline, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=129808 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_two_socket_answer_is_a_truthful_topology_refusal, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=126897 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_listing_that_names_the_image_twice_starts_nothing, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=79511 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions the_right_filename_on_the_wrong_share_refuses_before_any_power_action, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=73872 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_an_interrupted_attempt_locks_out_the_next_one: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36661418914 of gunbc#12533 at c308d7f3dd5, the COMPLETED-OVER-COST-REQUIREMENT line for this identity: verdict pass, eval_steps=75263 against the 72,300 new-witness budget (a local claim_batch over the same tree read 70,000; the floor's own figure decides membership); the billed work is the real boot entry executed twice in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each of these eleven identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. +new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_host_that_never_prints_a_census_refuses_at_the_deadline, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=170048 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_healthy_census_completes_and_releases_its_collector, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=160637 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_already_presented_image_is_not_attached_again, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=137485 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions media_that_never_becomes_ready_refuses_before_any_power_action, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=92947 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_presentation_lost_after_readiness_stops_the_handoff, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=98794 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_presentation_lost_after_the_handoff_is_the_reported_cause, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=132731 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_sol_loss_mid_boot_is_reported_before_the_deadline, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=129808 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_two_socket_answer_is_a_truthful_topology_refusal, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=126897 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_listing_that_names_the_image_twice_starts_nothing, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=79511 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions the_right_filename_on_the_wrong_share_refuses_before_any_power_action, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=73872 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36474912729 of gunbc#12555, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, the interrupted-attempt cases twice (the killed run, then the next run over the world it left), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_live_holder_still_blocks_the_next_attempt: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36474912729 of gunbc#12555, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, the interrupted-attempt cases twice (the killed run, then the next run over the world it left), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unobservable_holder_is_refused_not_recovered: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36474912729 of gunbc#12555, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, the interrupted-attempt cases twice (the killed run, then the next run over the world it left), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_successor_in_another_pid_namespace_refuses_rather_than_recovering: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36474912729 of gunbc#12555, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, the interrupted-attempt cases twice (the killed run, then the next run over the world it left), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=180722 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions cd_error_appearing_with_readiness_refuses_before_the_handoff, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=109210 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=100418 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions cd_error_16_with_nothing_presented_refuses_before_the_handoff, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=94200 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=93588 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_jumping_forward_during_readiness_closes_the_window: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_wall_clock_jumping_forward_during_readiness_closes_the_window, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=93089 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_the_host_on_writes_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions cd_error_16_with_the_host_on_writes_nothing, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=77159 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_foreign_presented_image_is_not_stopped: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_foreign_presented_image_is_not_stopped, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=75353 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each of these identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. ### new-witness eval-step cost gate over six App Attest verifier claims -- the two real-path inhabitance claims over Apple's objects, three single structural steps priced by their own SHA-256s, and the wire-carrier join: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 @@ -356,7 +356,7 @@ the enrolment-margin decision over exactly two App Attest verifier claims whose ### the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided — declared 2026-09-30 -the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 396 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 394 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.pinned_a_presentation_lost_after_the_handoff_is_not_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 378 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 361 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 339 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 332 ms CPU, strictly above the 302 ms margin and under the 500 ms line. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. +the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 396 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 394 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648951356 of gunbc#12554 at 1cf19cf8ba observed 303 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 361 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 339 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 332 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one: the real boot entry end to end over the dry realization TWICE (the killed run up to StartMedia, then the next run over the world it left), each run's cost gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36649110326 of gunbc#12555 at b3bf1ff433 observed 366 ms CPU, strictly above the 302 ms margin and under the 500 ms line. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. ### new-witness eval-step cost gate over the one claim that inhabits the real byte-span argv with its really-serialized program: it still executes, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 From b907f7dc0c3553e1cdad624e6cd35cf865b50c39 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Wed, 30 Sep 2026 20:50:30 +0000 Subject: [PATCH 62/75] #12800 floor: build-job membership drop (operator option 1), matrix cost rows re-cited from CI, dead-band/cost-debt reclassified, seed-growth cache named (e) The workflow claim is three claims over three producers: - the_reset_observer_dispatch_admission_step_carries_its_gate_entry_and_inputs holds the step's gate, entry and dispatch inputs over the step's own producer, under budget with no drop (claim_batch: 16,102 eval steps including shared fill); - the_build_job_carries_the_reset_observer_dispatch_admission holds structural membership in the real fleet_converge_build_job_own_steps, and is the only claim that runs that producer; - the_host_reset_return_job_is_gated_by_the_admissions_gate holds the job's side of the gate. Only the membership claim is under the new declared drop gunbc.rung_drop fleet_build_job_membership_new_witness_eval_step_cost (eager-owl-205, escalation msg_00eaf0e6, option 1). Its trigger names the capability: fleet_workflow_steps constructs only the steps a consumer demands. Its measured_by cites run 36765162766 (155,333 marginal) and run 36743802719 (174,583), and records that the cost predates gunbc#12437. (d) Every matrix eval-step row now cites PR floor run 36765162766 at 6cac35eb1a6, and the two toolchain arms join that list. The dead-band rows cite that run's CPU, and the stop-clears case (473 ms) joins them. The interrupted-attempt case (523 ms, over the 500 ms line) leaves the band for a typed cost-debt admission, as the band's self-staling rule requires. v2.test.floor_enrolment_margin the_dead_band_authority_names_exactly_the_two_app_attest_claims went false when gunbc#12533 added the matrix list, and was never re-planned. It now holds the App Attest list at exactly its two claims, and the honoured identities at exactly the two declared lists. Review 73376: gunbc.modeled_operation_realization_seed_growth names the per-frame operation_handler_selection cache: its key, scope and retention. The ProcessArgvExpansion arm was already covered, and dispatch_file exists on main. docs/design-rung-drops.md regenerated by tools.generated_artifact_gate main_wet. Co-Authored-By: Claude Opus 5.5 (1M context) --- ...eled_operation_realization_seed_growth.dag | 2 +- ..._membership_new_witness_eval_step_cost.dag | 45 ++++++++++++ ...boot_matrix_new_witness_eval_step_cost.dag | 4 +- dag/gunbc/rung_drop/roster.dag | 2 + .../workflow_dispatch_input_witness_test.dag | 66 +++++++++-------- docs/design-rung-drops.md | 8 +- src/v2/test/floor_enrolment_margin_test.dag | 13 +++- src/v2/workflow/floor_cost_debt_admission.dag | 15 +++- src/v2/workflow/floor_enrolment_dead_band.dag | 18 ++--- src/v2/workflow/floor_eval_step_cost_drop.dag | 73 +++++++++++++------ 10 files changed, 173 insertions(+), 73 deletions(-) create mode 100644 dag/gunbc/rung_drop/fleet_build_job_membership_new_witness_eval_step_cost.dag diff --git a/dag/gunbc/modeled_operation_realization_seed_growth.dag b/dag/gunbc/modeled_operation_realization_seed_growth.dag index ce1fa8a5438..fdcb5528b02 100644 --- a/dag/gunbc/modeled_operation_realization_seed_growth.dag +++ b/dag/gunbc/modeled_operation_realization_seed_growth.dag @@ -54,7 +54,7 @@ data modeled_operation_realization_seed_growth_justification: SeedGrowthJustific DeclarationRef { module_path: "v1_compiler.v1_interpreter", decl_name: "file_result_of_observation", field: WholeDeclaration }, DeclarationRef { module_path: "v1_compiler.v1_interpreter", decl_name: "file_transport_path", field: WholeDeclaration }, ], - reason: "The seed interpreter is the only evaluator that runs the boot orchestrator, and the acceptance matrix (#12423, operator ruling 2026-09-27) must execute that orchestrator against controlled device histories. These items are the seed realization of a .dag contract: selection is v2.std.operation_realization operation_handler_selection over std.effect_grant covering_grant, admission is modeled_realization_admitted_in and operation_realization_duplicate, the virtual clock is virtual_clock_origin and virtual_clock_after over std.measure Second, and every scenario transition is gunbc.bmc_model. The Rust holds a state value, a clock value and the dispatch log, and dispatches; shell_result_projection is the existing wet shell projection extracted so the modeled observation reaches the same decoder path.", + reason: "The seed interpreter is the only evaluator that runs the boot orchestrator, and the acceptance matrix (#12423, operator ruling 2026-09-27) must execute that orchestrator against controlled device histories. These items are the seed realization of a .dag contract: selection is v2.std.operation_realization operation_handler_selection over std.effect_grant covering_grant, admission is modeled_realization_admitted_in and operation_realization_duplicate, the virtual clock is virtual_clock_origin and virtual_clock_after over std.measure Second, and every scenario transition is gunbc.bmc_model. The Rust holds a state value, a clock value and the dispatch log, and dispatches; shell_result_projection is the existing wet shell projection extracted so the modeled observation reaches the same decoder path. ModeledRealizationSlot.selections memoizes operation_handler_selection per frame (gunbc#12533): its key is the complete varying input of that selection (the operation's declaring file, service, operation and readonly flag), its scope and retention are the frame's extent, over which the envelope, the realization and its binding index are fixed, and it is written only from the selection's own answer, so a hit is the same decided value and never a substitute for it; it discharges recurrence the matrix pays once per dispatch across thousands of dispatches, and it dissolves with the frame stack under the same trigger.", owning_dissolution_lane: "v1-materialization-kernel" as RoadmapNodeId, trigger: "Witnesses emit to native code and the emitted runtime realizes the evaluation frame and its modeled operation realization; these items then delete with the WITNESS_EVALUATION_FRAMES stack while test.claim.operation_realization_witness_test stays green without them. That witness is the deletion's regression control.", current_boundary: "Shell and file transport observations (the file arm added by gunbc#12533 feeds the existing map_file_outputs; bound_operation_invocation_value records a ProcessArgvExpansion input as the words push_process_argv_expansion expands for a real spawn): a REST operation under a modeled frame refuses as a harness fault. Admitted only under Hermetic execution. No device logic in Rust. Nested frames inside an active realization are refused.", diff --git a/dag/gunbc/rung_drop/fleet_build_job_membership_new_witness_eval_step_cost.dag b/dag/gunbc/rung_drop/fleet_build_job_membership_new_witness_eval_step_cost.dag new file mode 100644 index 00000000000..0fa5ae5e731 --- /dev/null +++ b/dag/gunbc/rung_drop/fleet_build_job_membership_new_witness_eval_step_cost.dag @@ -0,0 +1,45 @@ +module gunbc.rung_drop.fleet_build_job_membership_new_witness_eval_step_cost + +import std.types { String, List, NonEmptyStr } +import gunbc.rung_drop { RungDrop, Standing, TypedDeclaration, ReplacementStaged } +import gunbc.guarantee_rung { Mitigatable, MechanicallyPreventable } +import v2.workflow.floor_eval_step_cost_drop { floor_eval_step_cost_drop_build_job_membership_rows } + +// DECLARED 4b(3) DROP, OPERATOR-ADMITTED (eager-owl-205, 2026-09-30, on gunbc#12800, escalation +// msg_00eaf0e6, option 1 with conditions). The DECLARATION lives here; the POPULATION's authority is +// `v2.workflow.floor_eval_step_cost_drop` `floor_eval_step_cost_drop_build_job_membership_rows`. +// +// EXACTLY ONE IDENTITY, THE MEMBERSHIP HALF. test.claim.workflow_dispatch_input_witness +// the_build_job_carries_the_reset_observer_dispatch_admission is the only claim that runs the real +// build-job producer, gunbc.fleet_converge_workflow fleet_converge_build_job_own_steps, and asserts +// the dispatch admission step is one of its steps. DESIGN section 3's pairing obligation forbids +// supplying that list, so the real producer runs. The step's CONTENT -- gate, entry, both dispatch +// inputs -- is held by the_reset_observer_dispatch_admission_step_carries_its_gate_entry_and_inputs +// over the step's own producer, under the budget and outside this drop. +// +// THE COST IS THE PRODUCER'S, AND IT PREDATES gunbc#12800. The admission step is cheap to build; +// the bill is gunbc.fleet_workflow_steps constructing every sibling release-bins step (key, lookup, +// outcome, pack) whenever the list is demanded, although this claim inspects none of them. It was +// paid before gunbc#12437 and first re-adjudicated when that change touched the claim. The +// measurement is named in the population row, not transcribed here. +data fleet_build_job_membership_new_witness_eval_step_cost_population: List = floor_eval_step_cost_drop_build_job_membership_rows |> map(m => concat(concat(m.identity, ": over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_build_job_membership_rows; measured by "), m.measured_by)) + +data fleet_build_job_membership_new_witness_eval_step_cost: RungDrop = RungDrop { + identity: "fleet_build_job_membership_new_witness_eval_step_cost" as NonEmptyStr, + + subject: "new-witness eval-step cost gate over the one claim that runs the real fleet-converge build-job step list to hold the reset-observer dispatch admission's membership: it still executes, eval_steps stay recorded, a semantic red still blocks; only the eval-step cost-gate rung is lowered", + + declared: "2026-09-30", + + standing: Standing, + + declaration: TypedDeclaration { + previous: MechanicallyPreventable, + temporary: Mitigatable, + reason: ReplacementStaged { + replacement: "gunbc.fleet_workflow_steps constructing only the steps a consumer demands, so demanding the build-job list does not construct the sibling release-bins steps at the cost it does today", + }, + population: fleet_build_job_membership_new_witness_eval_step_cost_population, + restoration_trigger: "THE CAPABILITY: gunbc.fleet_workflow_steps constructs only the steps a consumer demands -- building the build-job admission step and establishing its membership does not construct the sibling release-bins steps (key, lookup, outcome, pack). WHAT THAT MUST BE SUFFICIENT FOR: test.claim.workflow_dispatch_input_witness the_build_job_carries_the_reset_observer_dispatch_admission measures under the NewWitnessTier budget v2.workflow.required_floor claim_ceiling_eval_step_budget derives, on the acceptance path, still running the real fleet_converge_build_job_own_steps and still asserting structural membership. Supplying the list, narrowing the claim to the step's id, moving the bill to another claim, deleting the identity or raising the budget retires nothing.", + } +} diff --git a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag index f440bb9c815..8005e0e506d 100644 --- a/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag +++ b/dag/gunbc/rung_drop/mtcollins1_boot_matrix_new_witness_eval_step_cost.dag @@ -9,8 +9,8 @@ import v2.workflow.floor_eval_step_cost_drop { floor_eval_step_cost_drop_boot_ma // matrix, msg_83af891b). The DECLARATION lives here; the POPULATION's authority is // `v2.workflow.floor_eval_step_cost_drop` `floor_eval_step_cost_drop_boot_matrix_rows`. // -// WHAT IS LOST IS ONE WALL, AND THE CLAIMS ARE UNTOUCHED. The member identities (from gunbc#12533, gunbc#12556 and -// gunbc#12555, enumerated in the population authority above) are planned, executed +// WHAT IS LOST IS ONE WALL, AND THE CLAIMS ARE UNTOUCHED. The member identities (from gunbc#12533, gunbc#12556, +// gunbc#12555 and the two toolchain arms of gunbc#12800, enumerated in the population authority above) are planned, executed // and measured on every pull request that edits them; a semantic red and a wall-clock crossing still // block. Only the eval-step overrun is reported as `EvalStepsOverBudgetUnderDeclaredDrop` rather than // refusing. The budget is not raised. Their CPU stays under the enrolment margin, so they enrol diff --git a/dag/gunbc/rung_drop/roster.dag b/dag/gunbc/rung_drop/roster.dag index a1ad5cf79dd..ce7512bdcbe 100644 --- a/dag/gunbc/rung_drop/roster.dag +++ b/dag/gunbc/rung_drop/roster.dag @@ -93,6 +93,7 @@ import gunbc.rung_drop.roadmap_live_forecast_new_witness_eval_step_cost { roadma import gunbc.rung_drop.roadmap_page_style_new_witness_eval_step_cost { roadmap_page_style_new_witness_eval_step_cost } import gunbc.rung_drop.app_attest_interpreted_crypto_new_witness_eval_step_cost { app_attest_interpreted_crypto_new_witness_eval_step_cost } import gunbc.rung_drop.mtcollins1_boot_matrix_new_witness_eval_step_cost { mtcollins1_boot_matrix_new_witness_eval_step_cost } +import gunbc.rung_drop.fleet_build_job_membership_new_witness_eval_step_cost { fleet_build_job_membership_new_witness_eval_step_cost } import gunbc.rung_drop.app_attest_verifier_new_witness_eval_step_cost { app_attest_verifier_new_witness_eval_step_cost } import gunbc.rung_drop.app_attest_verifier_enrolment_dead_band_observed_only { app_attest_verifier_enrolment_dead_band_observed_only } import gunbc.rung_drop.mtcollins1_boot_matrix_enrolment_dead_band_observed_only { mtcollins1_boot_matrix_enrolment_dead_band_observed_only_drop } @@ -189,6 +190,7 @@ data rung_drop_roster: List = [ roadmap_page_style_new_witness_eval_step_cost, app_attest_interpreted_crypto_new_witness_eval_step_cost, mtcollins1_boot_matrix_new_witness_eval_step_cost, + fleet_build_job_membership_new_witness_eval_step_cost, app_attest_verifier_new_witness_eval_step_cost, app_attest_verifier_enrolment_dead_band_observed_only, mtcollins1_boot_matrix_enrolment_dead_band_observed_only_drop, diff --git a/dag/test/claim/workflow_dispatch_input_witness_test.dag b/dag/test/claim/workflow_dispatch_input_witness_test.dag index eb0e565800a..22e5c45d91e 100644 --- a/dag/test/claim/workflow_dispatch_input_witness_test.dag +++ b/dag/test/claim/workflow_dispatch_input_witness_test.dag @@ -10,7 +10,7 @@ import v2.std.collection { Present, Absent } import gunbc.fleet_converge_workflow { fleet_converge_fabric_writer_identity_observe_receipt_if, fleet_converge_fabric_writer_identity_observe_step_if, FleetConvergeWorkflowMode, fleet_converge_workflow_modes, fleet_converge_workflow_mode_wire, - fleet_converge_mode_step_if, fleet_converge_mode_scope, fleet_converge_host_reset_return_job, fleet_converge_host_reset_return_step_if, + fleet_converge_mode_step_if, fleet_converge_mode_scope, fleet_converge_host_reset_return_job, fleet_converge_host_reset_return_step_if, fleet_converge_reset_observer_dispatch_admission_step, ApprovalBrokerDarkInstall, fleet_converge_approval_broker_dark_install_step_if, FullHostPlan, LaunchEnvironmentPlan, AllocationStorePlan, DashboardDeploy, HostResetReturn, RunnerPasswordSessionToolConverge, @@ -494,41 +494,43 @@ test fn a_whitespace_only_observer_is_refused_as_unnamed() -> Bool { // budget (re-derive with claim_batch --entry on this file, its `[witness] ... eval_steps=` line). fleet_converge_build_job_steps() is prelude ++ own steps, and the job // and its backstop sum both consume it, so membership in the own list is membership in the job. // -// IT ASSERTS THE ROUTE, NOT ONLY THE ID. This is the one claim that runs the real producer, so an id +// IT ASSERTS THE ROUTE, NOT ONLY THE ID, over the admission step's own producer (its membership in the +// build job is the next claim's, which runs the real list). An id // match alone would stay green over a step whose env no longer hands the dispatch inputs to the // admission, or whose run invokes a different entry: it holds that the step reaches the modeled fold // (host_reset_return_dispatch_admission_wet reads both env names) with both inputs wired. Control: -// dropping fleet_converge_reset_observer_dispatch_admission_step() from the own list turns this red, -// and so does removing its own-mode gate (it once ran, for minutes, on every mode's dispatch), or -// letting that gate drift from fleet_converge_host_reset_return_step_if, the one gate the consuming -// host-reset-return job also reads (the_host_reset_return_job_is_gated_by_the_admissions_gate holds -// the job's side): the admission must run in exactly the mode whose job it protects, or the observer -// refusal is skipped where it applies. The two sides are two claims because they are two producers; -// joined in one, this claim built the whole job to read one field (gunbc#12437) and paid 2.4x its -// budget for it. +// removing its own-mode gate turns this red (it once ran, for minutes, on every mode's dispatch), and +// so does letting that gate drift from fleet_converge_host_reset_return_step_if, the one gate the +// consuming host-reset-return job also reads (the_host_reset_return_job_is_gated_by_the_admissions_gate +// holds the job's side): the admission must run in exactly the mode whose job it protects, or the +// observer refusal is skipped where it applies. Content, membership and the job's gate are three +// claims because they are three producers; joined in one, the claim built the whole job list and the +// whole host-reset-return job to read one step and one field. +test fn the_reset_observer_dispatch_admission_step_carries_its_gate_entry_and_inputs() -> Bool { + match fleet_converge_reset_observer_dispatch_admission_step() { + RunStep { name: _, id: i, run: r, shell: _, env: e, working_directory: _, if_condition: c, continue_on_error: _, timeout_minutes: _ } => + (match i { Present { value: v } => v == "reset_observer_dispatch_admission" Absent => false }) + && (match c { + Present { value: g } => g == fleet_converge_mode_step_if(mode: HostResetReturn) && g == fleet_converge_host_reset_return_step_if + Absent => false + }) + && string_contains(s: r, pattern: gunbc_ci_host_reset_dispatch_admission_target.entry) + && string_contains(s: r, pattern: gunbc_ci_host_reset_dispatch_admission_target.function) + && step_env_binds(env: e, key: host_reset_dispatch_mode_env as String, input: "${{ github.event.inputs.mode }}") + && step_env_binds(env: e, key: host_reset_observer_label_env as String, input: "${{ github.event.inputs.reset_observer }}") + UsesStep { name: _, id: _, uses: _, with: _, env: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => false + } +} + +// MEMBERSHIP, FROM THE REAL PRODUCER: the build job's own steps include EXACTLY the step the claim +// above holds -- structural equality, so a same-id step with another gate, entry or env is not it. +// This is the one claim that runs fleet_converge_build_job_own_steps, so it is the section 3 +// inhabitance half and cannot be supplied away; it is over the new-witness eval-step budget under +// the declared drop gunbc.rung_drop fleet_build_job_membership_new_witness_eval_step_cost, because +// demanding the list constructs every sibling release-bins step. Control: dropping the admission +// step from the own list turns this red. test fn the_build_job_carries_the_reset_observer_dispatch_admission() -> Bool { - any( - fleet_converge_build_job_own_steps(), - st => match st { - RunStep { name: _, id: i, run: r, shell: _, env: e, working_directory: _, if_condition: c, continue_on_error: _, timeout_minutes: _ } => - match i { - Present { value: v } => - v == "reset_observer_dispatch_admission" - && (match c { - Present { value: g } => - g == fleet_converge_mode_step_if(mode: HostResetReturn) - && g == fleet_converge_host_reset_return_step_if - Absent => false - }) - && string_contains(s: r, pattern: gunbc_ci_host_reset_dispatch_admission_target.entry) - && string_contains(s: r, pattern: gunbc_ci_host_reset_dispatch_admission_target.function) - && step_env_binds(env: e, key: host_reset_dispatch_mode_env as String, input: "${{ github.event.inputs.mode }}") - && step_env_binds(env: e, key: host_reset_observer_label_env as String, input: "${{ github.event.inputs.reset_observer }}") - Absent => false - } - UsesStep { name: _, id: _, uses: _, with: _, env: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => false - } - ) + any(fleet_converge_build_job_own_steps(), st => st == fleet_converge_reset_observer_dispatch_admission_step()) } // THE JOB'S SIDE OF THE SAME GATE, from the real job producer: the host-reset-return job is gated by diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index 26cfb449814..36d4c763dbf 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -344,7 +344,11 @@ new-witness eval-step cost gate over the ten interpreted P-256 and P-384 point a ### new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 -new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_host_that_never_prints_a_census_refuses_at_the_deadline, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=170048 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_healthy_census_completes_and_releases_its_collector, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=160637 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_already_presented_image_is_not_attached_again, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=137485 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions media_that_never_becomes_ready_refuses_before_any_power_action, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=92947 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_presentation_lost_after_readiness_stops_the_handoff, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=98794 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_presentation_lost_after_the_handoff_is_the_reported_cause, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=132731 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_sol_loss_mid_boot_is_reported_before_the_deadline, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=129808 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_two_socket_answer_is_a_truthful_topology_refusal, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=126897 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_listing_that_names_the_image_twice_starts_nothing, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=79511 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions the_right_filename_on_the_wrong_share_refuses_before_any_power_action, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=73872 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36474912729 of gunbc#12555, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, the interrupted-attempt cases twice (the killed run, then the next run over the world it left), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_live_holder_still_blocks_the_next_attempt: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36474912729 of gunbc#12555, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, the interrupted-attempt cases twice (the killed run, then the next run over the world it left), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unobservable_holder_is_refused_not_recovered: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36474912729 of gunbc#12555, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, the interrupted-attempt cases twice (the killed run, then the next run over the world it left), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_successor_in_another_pid_namespace_refuses_rather_than_recovering: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36474912729 of gunbc#12555, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, the interrupted-attempt cases twice (the killed run, then the next run over the world it left), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=180722 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions cd_error_appearing_with_readiness_refuses_before_the_handoff, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=109210 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=100418 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions cd_error_16_with_nothing_presented_refuses_before_the_handoff, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=94200 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=93588 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_jumping_forward_during_readiness_closes_the_window: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_wall_clock_jumping_forward_during_readiness_closes_the_window, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=93089 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_the_host_on_writes_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions cd_error_16_with_the_host_on_writes_nothing, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=77159 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_foreign_presented_image_is_not_stopped: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_foreign_presented_image_is_not_stopped, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=75353 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each of these identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. +new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=248288 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=237233 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=215502 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=140940 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146038 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=204469 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=202126 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=194599 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=122748 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=116804 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=276996 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_live_holder_still_blocks_the_next_attempt: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102436 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unobservable_holder_is_refused_not_recovered: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102525 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_successor_in_another_pid_namespace_refuses_rather_than_recovering: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102114 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=262400 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=154633 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146769 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=139739 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=138564 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_jumping_forward_during_readiness_closes_the_window: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=137976 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_the_host_on_writes_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=126998 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_foreign_presented_image_is_not_stopped: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=118325 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_toolchain_that_is_not_ready_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=112482 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unresolved_toolchain_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_unresolved_toolchain_starts_no_observer_and_no_power_action, over gunbc#12800 at 6cac35eb1a6, 2026-09-30: PASS, eval_steps=102990 against the 72,300 new-witness budget (eval_steps are host-independent; PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) printed no eval-step line for it before its cancel); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, up to the handoff gate's refusal. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each of these identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. + +### new-witness eval-step cost gate over the one claim that runs the real fleet-converge build-job step list to hold the reset-observer dispatch admission's membership: it still executes, eval_steps stay recorded, a semantic red still blocks; only the eval-step cost-gate rung is lowered — declared 2026-09-30 + +new-witness eval-step cost gate over the one claim that runs the real fleet-converge build-job step list to hold the reset-observer dispatch admission's membership: it still executes, eval_steps stay recorded, a semantic red still blocks; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: gunbc.fleet_workflow_steps constructing only the steps a consumer demands, so demanding the build-job list does not construct the sibling release-bins steps at the cost it does today). Population: test.claim.workflow_dispatch_input_witness.the_build_job_carries_the_reset_observer_dispatch_admission: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_build_job_membership_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6, floor-shared-fill line for this identity: verdict pass, marginal_eval_steps=155333 with the shared fill netted separately, against the 72,300 new-witness budget. The same claim read marginal_eval_steps=174583 on run 36743802719 at ec1b8190320, when gunbc#12437's job-gate equality built the whole host-reset-return job inside it; splitting that equality into its own claim removed about 19k, so the ~155k is the cost the claim carried before gunbc#12437, not one this change introduced. Restored when: THE CAPABILITY: gunbc.fleet_workflow_steps constructs only the steps a consumer demands -- building the build-job admission step and establishing its membership does not construct the sibling release-bins steps (key, lookup, outcome, pack). WHAT THAT MUST BE SUFFICIENT FOR: test.claim.workflow_dispatch_input_witness the_build_job_carries_the_reset_observer_dispatch_admission measures under the NewWitnessTier budget v2.workflow.required_floor claim_ceiling_eval_step_budget derives, on the acceptance path, still running the real fleet_converge_build_job_own_steps and still asserting structural membership. Supplying the list, narrowing the claim to the step's id, moving the bill to another claim, deleting the identity or raising the budget retires nothing. ### new-witness eval-step cost gate over six App Attest verifier claims -- the two real-path inhabitance claims over Apple's objects, three single structural steps priced by their own SHA-256s, and the wire-carrier join: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 @@ -356,7 +360,7 @@ the enrolment-margin decision over exactly two App Attest verifier claims whose ### the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided — declared 2026-09-30 -the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 396 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 394 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648951356 of gunbc#12554 at 1cf19cf8ba observed 303 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 361 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 339 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 332 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one: the real boot entry end to end over the dry realization TWICE (the killed run up to StartMedia, then the next run over the world it left), each run's cost gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36649110326 of gunbc#12555 at b3bf1ff433 observed 366 ms CPU, strictly above the 302 ms margin and under the 500 ms line. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. +the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 449 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 433 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 421 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 411 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 374 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 381 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: the real boot entry end to end over the dry realization through a stop, a replace and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 473 ms CPU, strictly above the 302 ms margin and under the 500 ms line. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. ### new-witness eval-step cost gate over the one claim that inhabits the real byte-span argv with its really-serialized program: it still executes, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 diff --git a/src/v2/test/floor_enrolment_margin_test.dag b/src/v2/test/floor_enrolment_margin_test.dag index 787ef48c00c..a167859e37c 100644 --- a/src/v2/test/floor_enrolment_margin_test.dag +++ b/src/v2/test/floor_enrolment_margin_test.dag @@ -29,6 +29,7 @@ import gunbc.floor_cost_distribution { implied_clean_run_budget, } import v2.std.collection { List } +import v2.workflow.floor_enrolment_dead_band { app_attest_verifier_enrolment_dead_band_observed_only, mtcollins1_boot_matrix_enrolment_dead_band_observed_only } import v2.std.logic { Bool } import v2.std.integer { Int } import std.measure { Millisecond, millisecond, millisecond_count, EvalStepCount, eval_step_count } @@ -660,10 +661,18 @@ test fn the_dead_band_ground_is_selected_only_by_its_own_authority() -> Bool { }) } -// THE AUTHORITY IS EXACTLY TWO IDENTITIES, not a growing roster. +// THE AUTHORITY IS EXACTLY ITS DECLARED LISTS, not a growing roster. The App Attest list is exactly +// its two claims, and the identities the gate honours are exactly the two declared lists in order -- +// app_attest_verifier_enrolment_dead_band_observed_only, then the mtcollins1 boot matrix's list, +// whose own drop (gunbc.rung_drop mtcollins1_boot_matrix_enrolment_dead_band_observed_only) derives +// its population from it. A third list, or an identity reaching the gate from anywhere else, is red. test fn the_dead_band_authority_names_exactly_the_two_app_attest_claims() -> Bool { - enrolment_dead_band_observed_identities() == [ + map(app_attest_verifier_enrolment_dead_band_observed_only(), o => o.identity) == [ "test.claim.app_attest_verifier_witness_test.the_key_id_step_admits_the_real_key_and_reds_on_another_key_id", "test.claim.app_attest_verifier_witness_test.the_sample_assertion_passes_rp_id_and_refuses_on_absent_extensions", ] + && enrolment_dead_band_observed_identities() == concat( + map(app_attest_verifier_enrolment_dead_band_observed_only(), o => o.identity), + map(mtcollins1_boot_matrix_enrolment_dead_band_observed_only(), o => o.identity), + ) } diff --git a/src/v2/workflow/floor_cost_debt_admission.dag b/src/v2/workflow/floor_cost_debt_admission.dag index ad0029f8426..01bf501ae1e 100644 --- a/src/v2/workflow/floor_cost_debt_admission.dag +++ b/src/v2/workflow/floor_cost_debt_admission.dag @@ -103,8 +103,21 @@ data app_attest_interpreted_crypto_typed_admissions: List = [ + FloorCostDebtTypedAdmission { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one", + reason: "the real boot entry end to end over the dry realization twice (the killed run, then the next run recovering its hold), measured above the per-subject line by the enrolment-margin line of PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication); owner: the mtcollins1 boot lane, discharged by the matrix running as natively emitted witnesses" as NonEmptyStr, + }, +] + fn floor_cost_debt_typed_admissions() -> List { - app_attest_interpreted_crypto_typed_admissions + concat(app_attest_interpreted_crypto_typed_admissions, mtcollins1_boot_matrix_typed_admissions) } fn floor_cost_debt_typed_admitted_identities() -> List { diff --git a/src/v2/workflow/floor_enrolment_dead_band.dag b/src/v2/workflow/floor_enrolment_dead_band.dag index cf9e6d65c8d..b3e5ce82aae 100644 --- a/src/v2/workflow/floor_enrolment_dead_band.dag +++ b/src/v2/workflow/floor_enrolment_dead_band.dag @@ -41,37 +41,37 @@ fn app_attest_verifier_enrolment_dead_band_observed_only() -> List List { [ EnrolmentDeadBandObservation { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline", - reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 396 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, + reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 449 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, }, EnrolmentDeadBandObservation { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector", - reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 394 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, + reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 433 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, }, EnrolmentDeadBandObservation { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause", - reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648951356 of gunbc#12554 at 1cf19cf8ba observed 303 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, + reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 421 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, }, EnrolmentDeadBandObservation { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again", - reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 361 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, + reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 411 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, }, EnrolmentDeadBandObservation { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal", - reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 339 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, + reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 374 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, }, EnrolmentDeadBandObservation { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline", - reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36648847499 of gunbc#12533 at bd99cbb4899 observed 332 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, + reason: "the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 381 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, }, EnrolmentDeadBandObservation { - identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one", - reason: "the real boot entry end to end over the dry realization TWICE (the killed run up to StartMedia, then the next run over the world it left), each run's cost gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36649110326 of gunbc#12555 at b3bf1ff433 observed 366 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted", + reason: "the real boot entry end to end over the dry realization through a stop, a replace and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 473 ms CPU, strictly above the 302 ms margin and under the 500 ms line" as NonEmptyStr, }, ] } diff --git a/src/v2/workflow/floor_eval_step_cost_drop.dag b/src/v2/workflow/floor_eval_step_cost_drop.dag index 59dd20336cc..9bd99b402be 100644 --- a/src/v2/workflow/floor_eval_step_cost_drop.dag +++ b/src/v2/workflow/floor_eval_step_cost_drop.dag @@ -30,6 +30,8 @@ import std.types { NonEmptyStr } // (`mtcollins1_boot_matrix_new_witness_eval_step_cost`). // - `floor_eval_step_cost_drop_dark_install_render_rows`: the first reader of the broker dark-install // script (`live_deploy_dark_install_render_new_witness_eval_step_cost`). +// - `floor_eval_step_cost_drop_build_job_membership_rows`: the one claim that runs the real fleet +// build-job step list (`fleet_build_job_membership_new_witness_eval_step_cost`). // The loss is a WORKFLOW fact -- which // identities the eval-step ceiling does not refuse -- so it lives beside the other two rosters the // ceiling consults (`v2.workflow.floor_grandfathered_roster`, `v2.workflow.floor_cost_debt`) and @@ -239,7 +241,7 @@ data floor_eval_step_cost_drop_python_to_typescript_inhabitance_rows: List = [ EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_host_that_never_prints_a_census_refuses_at_the_deadline, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=170048 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=248288 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_healthy_census_completes_and_releases_its_collector, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=160637 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=237233 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_already_presented_image_is_not_attached_again, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=137485 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=215502 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions media_that_never_becomes_ready_refuses_before_any_power_action, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=92947 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=140940 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_presentation_lost_after_readiness_stops_the_handoff, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=98794 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146038 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_presentation_lost_after_the_handoff_is_the_reported_cause, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=132731 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=204469 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_sol_loss_mid_boot_is_reported_before_the_deadline, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=129808 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=202126 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_two_socket_answer_is_a_truthful_topology_refusal, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=126897 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=194599 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_listing_that_names_the_image_twice_starts_nothing, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=79511 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=122748 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions the_right_filename_on_the_wrong_share_refuses_before_any_power_action, over gunbc#12533 merged with main after gunbc#12636 (tree d6c5146bce6 plus the file-transport path resolution), 2026-09-30: PASS, eval_steps=73872 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=116804 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one" as NonEmptyStr, - measured_by: "PR required floor run 36474912729 of gunbc#12555, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, the interrupted-attempt cases twice (the killed run, then the next run over the world it left)" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=276996 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_live_holder_still_blocks_the_next_attempt" as NonEmptyStr, - measured_by: "PR required floor run 36474912729 of gunbc#12555, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, the interrupted-attempt cases twice (the killed run, then the next run over the world it left)" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102436 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unobservable_holder_is_refused_not_recovered" as NonEmptyStr, - measured_by: "PR required floor run 36474912729 of gunbc#12555, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, the interrupted-attempt cases twice (the killed run, then the next run over the world it left)" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102525 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_successor_in_another_pid_namespace_refuses_rather_than_recovering" as NonEmptyStr, - measured_by: "PR required floor run 36474912729 of gunbc#12555, the [over-cost] and changed-witness lines for this identity (planned_as_changed_witness, verdict pass, wall under 500ms, over the new-witness eval-step budget); the billed work is the real gunbc.machine_intake_mtcollins1_boot_run mtcollins1_boot_wet_on_srv1 evaluated end to end in the seed interpreter over the dry realization, the interrupted-attempt cases twice (the killed run, then the next run over the world it left)" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102114 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=180722 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=262400 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_refuses_before_the_handoff" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions cd_error_appearing_with_readiness_refuses_before_the_handoff, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=109210 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=154633 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=100418 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146769 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_refuses_before_the_handoff" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions cd_error_16_with_nothing_presented_refuses_before_the_handoff, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=94200 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=139739 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=93588 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=138564 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_jumping_forward_during_readiness_closes_the_window" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_wall_clock_jumping_forward_during_readiness_closes_the_window, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=93089 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=137976 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_the_host_on_writes_nothing" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions cd_error_16_with_the_host_on_writes_nothing, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=77159 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=126998 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, }, EvalStepCostDropMeasurement { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_foreign_presented_image_is_not_stopped" as NonEmptyStr, - measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions a_foreign_presented_image_is_not_stopped, over gunbc#12556 merged with gunbc#12533 at 82ec7d4d605, 2026-09-30: PASS, eval_steps=75353 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=118325 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, + }, + EvalStepCostDropMeasurement { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_toolchain_that_is_not_ready_starts_no_observer_and_no_power_action" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=112482 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal" as NonEmptyStr, + }, + EvalStepCostDropMeasurement { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unresolved_toolchain_starts_no_observer_and_no_power_action" as NonEmptyStr, + measured_by: "claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_unresolved_toolchain_starts_no_observer_and_no_power_action, over gunbc#12800 at 6cac35eb1a6, 2026-09-30: PASS, eval_steps=102990 against the 72,300 new-witness budget (eval_steps are host-independent; PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) printed no eval-step line for it before its cancel); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, up to the handoff gate's refusal" as NonEmptyStr, }, ] @@ -349,8 +359,23 @@ data floor_eval_step_cost_drop_dark_install_render_rows: List = [ + EvalStepCostDropMeasurement { + identity: "test.claim.workflow_dispatch_input_witness.the_build_job_carries_the_reset_observer_dispatch_admission" as NonEmptyStr, + measured_by: "PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6, floor-shared-fill line for this identity: verdict pass, marginal_eval_steps=155333 with the shared fill netted separately, against the 72,300 new-witness budget. The same claim read marginal_eval_steps=174583 on run 36743802719 at ec1b8190320, when gunbc#12437's job-gate equality built the whole host-reset-return job inside it; splitting that equality into its own claim removed about 19k, so the ~155k is the cost the claim carried before gunbc#12437, not one this change introduced" as NonEmptyStr, + }, +] + fn floor_eval_step_cost_drop_all_rows() -> List { - concat(concat(concat(concat(concat(concat(concat(concat(concat(floor_eval_step_cost_drop_rows, floor_eval_step_cost_drop_apply_render_rows), floor_eval_step_cost_drop_live_forecast_rows), floor_eval_step_cost_drop_page_style_rows), floor_eval_step_cost_drop_interpreted_crypto_rows), floor_eval_step_cost_drop_app_attest_verifier_rows), floor_eval_step_cost_drop_span_program_rows), floor_eval_step_cost_drop_python_to_typescript_inhabitance_rows), floor_eval_step_cost_drop_boot_matrix_rows), floor_eval_step_cost_drop_dark_install_render_rows) + concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(floor_eval_step_cost_drop_rows, floor_eval_step_cost_drop_apply_render_rows), floor_eval_step_cost_drop_live_forecast_rows), floor_eval_step_cost_drop_page_style_rows), floor_eval_step_cost_drop_interpreted_crypto_rows), floor_eval_step_cost_drop_app_attest_verifier_rows), floor_eval_step_cost_drop_span_program_rows), floor_eval_step_cost_drop_python_to_typescript_inhabitance_rows), floor_eval_step_cost_drop_boot_matrix_rows), floor_eval_step_cost_drop_dark_install_render_rows), floor_eval_step_cost_drop_build_job_membership_rows) } // THE PROJECTION THE SEED RUNNER READS AND THE MODEL TESTS AGAINST. The runner refuses an empty or From bb497a1aad55b90d202e0035f60f7535014c587e Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Wed, 30 Sep 2026 21:41:42 +0000 Subject: [PATCH 63/75] Dry KVM observer: a pass that sees no new file neither scans nor takes an instant Co-Authored-By: Claude Opus 5.5 (1M context) --- .../mtcollins1_boot_dry_realization.dag | 44 ++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag index 2f5332a99dc..d94f731c5ae 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag @@ -433,6 +433,7 @@ type ModeledKvmObserver { pid: Int dir: String seq: Int + seen_files: Int } // printf '%s' '' | sha256sum @@ -519,7 +520,7 @@ fn owned_launch_handler(w: MtCollins1BootWorld, call: OperationCall) -> Operatio KvmModeledRefused { event_word: word, would_write: line } => OperationHarnessFault { reason: concat("kvm_journal_line refused the modeled ", concat(word, concat(" line: ", line))) as NonEmptyStr } KvmModeledRendered { text: t } => { let fs = appended(fs: fs_write(fs: w.fs, path: pid_path, content: process_identity(p: p), create_new: false).fs, path: concat(dir, "/journal"), text: t) - let screen = ModeledKvmViewer { session: w.screen.session, still_bytes: w.screen.still_bytes, still_sha256: w.screen.still_sha256, observers: list_append(w.screen.observers, ModeledKvmObserver { pid: p.pid, dir: dir, seq: 0 }) } + let screen = ModeledKvmViewer { session: w.screen.session, still_bytes: w.screen.still_bytes, still_sha256: w.screen.still_sha256, observers: list_append(w.screen.observers, ModeledKvmObserver { pid: p.pid, dir: dir, seq: 0, seen_files: 0 }) } exited_step(state: with_screen(w: started(w: w, p: p, fs: fs), screen: screen), stdout: "", exit_code: 0) } } @@ -541,14 +542,38 @@ fn kvm_observers_advance(w: MtCollins1BootWorld, now: Second) -> MtCollins1BootW } } +// A stop request and a trigger each arrive as a NEW file in the observer's directory, so a pass whose +// filesystem holds the same number of files as the last pass looked at has nothing to answer: nearly +// every dispatch of a boot is that pass, and it neither scans the files nor takes an instant. A pass +// that does look records the count it left behind. fn kvm_observer_pass(w: MtCollins1BootWorld, o: ModeledKvmObserver, now: Second) -> MtCollins1BootWorld { - match kvm_instant(w: w, now: now) { - Absent => w - Present { value: at } => - match fs_file(fs: w.fs, path: concat(o.dir, "/stop")) { - Present { value: _ } => kvm_observer_stopped(w: w, o: o, at: at) - Absent => kvm_observer_answer_triggers(w: w, o: o, at: at) + let n = count(w.fs.files) + if n == o.seen_files { w } else { + let answered = kvm_observer_look(w: w, o: o, now: now) + with_kvm_seen(w: answered, pid: o.pid, seen: count(answered.fs.files)) + } +} + +fn with_kvm_seen(w: MtCollins1BootWorld, pid: Int, seen: Int) -> MtCollins1BootWorld { + with_screen(w: w, screen: ModeledKvmViewer { session: w.screen.session, still_bytes: w.screen.still_bytes, still_sha256: w.screen.still_sha256, observers: map(w.screen.observers, o => if o.pid == pid { ModeledKvmObserver { pid: o.pid, dir: o.dir, seq: o.seq, seen_files: seen } } else { o }) }) +} + +// The instant is taken only when a line is written. +fn kvm_observer_look(w: MtCollins1BootWorld, o: ModeledKvmObserver, now: Second) -> MtCollins1BootWorld { + match fs_file(fs: w.fs, path: concat(o.dir, "/stop")) { + Present { value: _ } => match kvm_instant(w: w, now: now) { + Present { value: at } => kvm_observer_stopped(w: w, o: o, at: at) + Absent => w + } + Absent => { + let triggers = kvm_trigger_files(w: w, o: o) + if count(triggers) == 0 { w } else { + match kvm_instant(w: w, now: now) { + Present { value: at } => kvm_observer_answer_triggers(w: w, o: o, at: at, triggers: triggers) + Absent => w + } } + } } } @@ -573,8 +598,7 @@ fn kvm_trigger_files(w: MtCollins1BootWorld, o: ModeledKvmObserver) -> List starts_with(s: f.path, prefix: concat(o.dir, "/trigger-"))), f => f.path).sort_by(p => p) } -fn kvm_observer_answer_triggers(w: MtCollins1BootWorld, o: ModeledKvmObserver, at: KvmInstant) -> MtCollins1BootWorld { - let triggers = kvm_trigger_files(w: w, o: o) +fn kvm_observer_answer_triggers(w: MtCollins1BootWorld, o: ModeledKvmObserver, at: KvmInstant, triggers: List) -> MtCollins1BootWorld { if count(triggers) == 0 { w } else { let answered = fold(triggers, init: w, f: fn(acc, path) { let seq = kvm_observer_seq(w: acc, pid: o.pid) + 1 @@ -592,7 +616,7 @@ fn kvm_observer_seq(w: MtCollins1BootWorld, pid: Int) -> Int { } fn with_kvm_seq(w: MtCollins1BootWorld, pid: Int, seq: Int) -> MtCollins1BootWorld { - with_screen(w: w, screen: ModeledKvmViewer { session: w.screen.session, still_bytes: w.screen.still_bytes, still_sha256: w.screen.still_sha256, observers: map(w.screen.observers, o => if o.pid == pid { ModeledKvmObserver { pid: o.pid, dir: o.dir, seq: seq } } else { o }) }) + with_screen(w: w, screen: ModeledKvmViewer { session: w.screen.session, still_bytes: w.screen.still_bytes, still_sha256: w.screen.still_sha256, observers: map(w.screen.observers, o => if o.pid == pid { ModeledKvmObserver { pid: o.pid, dir: o.dir, seq: seq, seen_files: o.seen_files } } else { o }) }) } data owned_process_launch_operation: OperationRef = OperationRef { From a980fa6192e54375ec49b169af9fb7f9578733e0 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Wed, 30 Sep 2026 21:41:52 +0000 Subject: [PATCH 64/75] Drop gunbc#12795's UI-bundle mode from the integration (review 73415) Reverts the integration of gunbc#12795 (merge 7393c8edef8): the megarac.Ui.GetServedBundle operation, gunbc.machine_intake_mtcollins1_ui_bundle_observe and its witness, the MtCollins1UiBundleObserve fleet-converge mode row and its ci_spec invoke, the 2026-09-27 bundle digest row, and the fleet-converge.yml lines. Review 73415 found the mode's step is new string-concat shell under a Scaffold whose own marker names the modeled route (v2.workflow.bash_emit), which is in use today. The mode now lands only through eager-cat-463's lane, built on bash_emit nodes. Nothing else in the tree referenced it. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/fleet-converge.yml | 34 +--- dag/extdeps/bmc/megarac.dag | 28 --- dag/gunbc/ci/ci_spec.dag | 34 ---- dag/gunbc/fleet/fleet_converge_workflow.dag | 45 +---- .../megarac_served_ui_catalog_observation.dag | 7 - .../mtcollins1_ui_bundle_observe.dag | 163 ------------------ ...ollins1_ui_bundle_observe_witness_test.dag | 68 -------- 7 files changed, 2 insertions(+), 377 deletions(-) delete mode 100644 dag/gunbc/machine_intake/mtcollins1_ui_bundle_observe.dag delete mode 100644 dag/test/claim/machine_intake/mtcollins1_ui_bundle_observe_witness_test.dag diff --git a/.github/workflows/fleet-converge.yml b/.github/workflows/fleet-converge.yml index e4b7537965d..b1b491ee729 100644 --- a/.github/workflows/fleet-converge.yml +++ b/.github/workflows/fleet-converge.yml @@ -13,7 +13,7 @@ on: mode: description: plan shows membership hunks; apply executes a prior plan artifact; org_actions_observe validates the org credential and refuses on runner-group drift; org_runner_roster_observe reads the organization's self-hosted runner registrations to exhaustion under the same token and refuses unless the roster is complete; app_control_plane_observe reads the gunbai-ci App registration and webhook config with a short-lived App JWT and refuses on hook-config drift; app_key_version_verify reads the gunbai-ci App private key at the EXACT Secret Manager version named by app_key_version, mints an installation token with it, and refuses unless GitHub accepts it and the key's rotation deadline has not passed -- no add, disable or destroy; runner_browser_toolchain_converge installs the declared Playwright/Chromium toolchain (apt host libraries as the administrator, digest-pinned node, Playwright and Chromium archives into the job user's root) on the selected host, which must be in the pool that runs the floor job, and refuses unless every digest, version and host library reads back and headless Chromium renders a local page; microvm_host_converge installs the cited Firecracker release on the selected host and reads the kvm grant back, refusing by name when the grant has not landed (the grant itself is applied by the full-host apply spine); microvm_network_apply stages the slot and host network files the model renders at the named expected_revision as root:root 0600 in a root-only directory over the fleet SSH edge as the host's ADMINISTRATOR, installs them with the modeled operations, reloads networkd, systemd-sysctl and the nft loader unit, and reads the ruleset back -- the job user is granted none of it, because install plus systemctl over content that principal can write is arbitrary root for any pull request; guest_image_observe reports the micro-VM base artifacts and their measured digests on the selected host and builds nothing; guest_image_converge builds the runner guest image there; microvm_boot_probe boots that image and reads its serial console; spark_grants and spark_bootstrap prepare the selected Spark; spark_serving_apply applies the promoted fabric groups' pair vLLM units over the password session, workers before heads; spark_native_serving_apply relaunches group B's native four-rank arm as ONE BOUNDED TRANSACTION -- an all-host preflight that mutates nothing and refuses on any unresolved artifact from an earlier run, the incumbent UNIT preserved (plus a diagnostic inspect of the incumbent container -- the container itself cannot outlive its unit, because these run --rm in the foreground under systemd), the head applied BEFORE the workers so every rank joins the head's new rendezvous store, then a readback of the COMPLETE realization through each container's own inspect -- every field the create spec states, the effective --node-rank off that container's argv, and NCCL's typed transport verdict on that incarnation -- plus the head's front door answering with this arm's served model, and then commit or a rollback of the whole arm -- and it is a separate mode because it reloads a 328 GB arm and nobody should reach it by asking for the pair units; spark_runtime_image_probe pulls the pinned runtime image on the selected Spark and reads its capabilities from inside its own digest, changing nothing; spark_v41_checkpoint_materialize fetches the admitted published DeepSeek V4.1 files onto the selected Group A Spark (about 510 GB; spark_v41_row_store_encode encodes the eight Engram row stores from the verified shards on the selected Group A Spark and reads each store's sha256; spark_v41_row_store_readback reads those stores back at their header, first and last record and every rank seam, with the published source rows at the same rows, and writes nothing; spark_v41_engram_differential compares upstream's Engram lookup kernel with the design-B file-backed lookup over sampled real rows of every row store, byte for byte, and writes nothing; it states the requirement and refuses before fetching when the disk cannot hold it), publishes each only after its sha256 matches the manifest, leaves a present file with the right digest alone and refuses one with the wrong digest, and reads the storage-backed Engram spans from the verified shards; a transfer runs detached and a rerun reattaches; spark_v41_runtime_image_build PRODUCES the DeepSeek V4.1 image on the selected Spark -- it verifies the candidate's three FlashInfer wheels against the digests the candidate keys, converges the patched source tree, builds from it, reads the produced configuration digest back from inside the image through the probe route, and admits that digest against the candidate's own recipe, refusing a digest that does not recompute from it -- and it is a separate mode from the probe because it occupies one host for hours where the probe occupies it for minutes; spark_v41_runtime_image_distribute moves that produced image, named by the configuration digest its production receipt read back, from the host that receipt names to the selected Group A Spark -- save, scp through the executor, load -- after stating its size against every filesystem a copy lands on, leaves a target already holding the digest untouched, refuses a target holding a different image under the tag, and refuses unless the target's image inspect Id reads back as that digest; spark_v41_group_a_launch reads the production image back under its tag on every Group A host, reads its registry inside its digest and every host's occupancy, and only when Group A is suspended for this candidate with every host held and vacant stages the Engram manifest and applies the V4.1 four-rank arm as one transaction at the capacity measurement's shape -- the target names only the session host; host_reset_return drives a rostered reset subject through its controller and measures the return FROM A PEER, and takes reset_observer rather than host because the observer must not be the subject; runner_host_file_observe reads the runner teardown drop-in, the needrestart deferral and the loaded teardown on the selected host as its administrator and writes nothing; runner_host_file_converge writes whichever of those two files differs, reloads systemd only if the drop-in changed, and refuses unless the manager then reports the declared teardown; microvm_controller_install writes the microVM slot controller's root-owned release locus (gunbc + sources + Firecracker + jailer) and the gunbc-microvm-slot@ template unit and the gunbc-microvm-slot-reserve broker unit on srv1 and starts neither; microvm_slot_reserve starts that broker unit once on srv1, which reserves the shakedown cell through the fabric broker route from inside the root process (slot, demand and offer derived from the model, never inputs), and uploads that invocation's reservation receipt, failing unless the reservation committed; microvm_slot_start starts the shakedown slot's controller unit once on srv1 (the instance is derived from the model, never an input), waits for it bounded by the unit's own stop timeout, and uploads that invocation's controller receipt; microvm_runner_group_ensure (srv1 only) reads the organization's runner groups and, only when the microvm-shakedown group is absent, files ONE operator approval, creates it restricted to the shakedown workflow on the default branch, and refuses unless the readback holds that restriction required: true - options: [plan, launch_environment_plan, allocation_store_plan, apply, org_actions_observe, app_control_plane_observe, microvm_host_converge, microvm_network_observe, microvm_network_apply, guest_image_observe, guest_image_converge, microvm_boot_probe, spark_grants, spark_bootstrap, spark_serving_apply, spark_native_serving_apply, spark_runtime_image_probe, spark_v41_checkpoint_materialize, spark_v41_row_store_encode, spark_v41_row_store_readback, spark_v41_engram_differential, spark_v41_runtime_image_build, spark_v41_runtime_image_distribute, spark_v41_group_a_launch, dashboard_deploy, approval_broker_dark_install, microvm_controller_install, microvm_slot_reserve, microvm_slot_start, rlm_launch_deployment_receipt, host_reset_return, runner_host_file_observe, runner_host_file_converge, site_pxe_edge_observe, site_pxe_edge_converge, runner_password_session_tool_converge, runner_browser_toolchain_converge, r2_mint_preflight, r2_object_write_mint, org_runner_roster_observe, approval_keyring_converge, approval_device_enrolment_code_issue, mtcollins1_boot, mtcollins1_fan_observe, mtcollins1_ui_bundle_observe, mtcollins1_census_image_publish, mtcollins1_census_member_readback, host_credential_custody_converge, app_key_version_verify, r2_bucket_ensure, r2_bucket_admin_mint, fabric_writer_identity_observe, pair_serving_d0, microvm_runner_group_ensure, gcp_iam_converge, namecheap_observe] + options: [plan, launch_environment_plan, allocation_store_plan, apply, org_actions_observe, app_control_plane_observe, microvm_host_converge, microvm_network_observe, microvm_network_apply, guest_image_observe, guest_image_converge, microvm_boot_probe, spark_grants, spark_bootstrap, spark_serving_apply, spark_native_serving_apply, spark_runtime_image_probe, spark_v41_checkpoint_materialize, spark_v41_row_store_encode, spark_v41_row_store_readback, spark_v41_engram_differential, spark_v41_runtime_image_build, spark_v41_runtime_image_distribute, spark_v41_group_a_launch, dashboard_deploy, approval_broker_dark_install, microvm_controller_install, microvm_slot_reserve, microvm_slot_start, rlm_launch_deployment_receipt, host_reset_return, runner_host_file_observe, runner_host_file_converge, site_pxe_edge_observe, site_pxe_edge_converge, runner_password_session_tool_converge, runner_browser_toolchain_converge, r2_mint_preflight, r2_object_write_mint, org_runner_roster_observe, approval_keyring_converge, approval_device_enrolment_code_issue, mtcollins1_boot, mtcollins1_fan_observe, mtcollins1_census_image_publish, mtcollins1_census_member_readback, host_credential_custody_converge, app_key_version_verify, r2_bucket_ensure, r2_bucket_admin_mint, fabric_writer_identity_observe, pair_serving_d0, microvm_runner_group_ensure, gcp_iam_converge, namecheap_observe] type: choice target: description: "Spark target host for the spark_* modes, naming the administrator credential the run materializes (any rostered Spark: srv5, srv6, srv7, srv8, srv9, srv10, srv11, srv12); apply reads the subject off the plan artifact" @@ -858,38 +858,6 @@ jobs: retention-days: 30 if: github.event.inputs.mode == 'mtcollins1_fan_observe' timeout-minutes: 10 - - name: "Mt. Collins UI bundle: firmware revision, then the served source.min.js and its sha256 (reads only)" - id: mtcollins1_ui_bundle_observe - run: |- - # 🟡 dissolve-on: gunbc_ci_mtcollins1_fan_observe_invoke - orch-emitted foreign-executor (GitHub Actions run:) credential runner: WIF access token by env, ONE pinned BMC secret version fetched over curl through the shared gunbc_ci_mtcollins1_bmc_credential_fetch_steps, a 0600 file under RUNNER_TEMP with a trap armed BEFORE the credential touches disk. The pipeline steps are modeled but each step body is a shell string built by concat, so the transport itself remains hand-shell; DISSOLVES WHEN the runner is authored as v2.extdeps.languages.bash_build nodes (typed, grammar-quoted words; command substitution; assignment; pipe; if/test; redirect; || true) emitted by v2.workflow.bash_emit bash_emit_stmts -- a route AVAILABLE today (#12422 retired the sibling pack runner on it), so this migration is unauthored, not blocked on a missing capability; set -euo pipefail, umask, export and trap are ordinary commands on that route, and the trap body is itself built from nodes and passed as one grammar-quoted word, so no new orchestration intent is a prerequisite. - set -euo pipefail - umask 077 - HDR_FILE="$RUNNER_TEMP/mtcollins1-fan-auth-header" - RESP_FILE="$RUNNER_TEMP/mtcollins1-fan-sm.json" - DEST_FILE="$RUNNER_TEMP/mtcollins1-bmc-credential" - trap 'rm -f "$HDR_FILE" "$RESP_FILE" "$DEST_FILE"' EXIT - printf 'Authorization: Bearer %s\n' "$WIF_ACCESS_TOKEN" > "$HDR_FILE" - curl -sSf --connect-timeout 10 --max-time 60 -o "$RESP_FILE" -H @"$HDR_FILE" "https://secretmanager.googleapis.com/v1/projects/gunbai-secrets/secrets/bmc-mtcollins1-gunbc/versions/2:access" && python3 -c 'import sys,json,base64; sys.stdout.buffer.write(base64.b64decode(json.load(open(sys.argv[1]))["payload"]["data"]))' "$RESP_FILE" > "$DEST_FILE" - chmod 600 "$DEST_FILE" - export GUNBC_MTCOLLINS1_BMC_CREDENTIAL_FILE="$DEST_FILE" - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - "$ROOT/target/release/gunbc" run --source-root "$ROOT/dag" --source-root "$ROOT/src/v2" --entry dag/gunbc/machine_intake/mtcollins1_ui_bundle_observe.dag --function mtcollins1_ui_bundle_observe_wet - cat "$ROOT/target/mtcollins1-ui-bundle-receipt.txt" - env: - WIF_ACCESS_TOKEN: ${{ steps.wif_auth.outputs.access_token }} - if: github.event.inputs.mode == 'mtcollins1_ui_bundle_observe' - timeout-minutes: 5 - - name: Upload Mt. Collins UI bundle bytes and receipt - id: mtcollins1_ui_bundle_observe_upload - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f - with: - name: mtcollins1-ui-bundle - path: target/mtcollins1-ui-bundle-* - if-no-files-found: error - retention-days: 90 - compression-level: 0 - if: always() && github.event.inputs.mode == 'mtcollins1_ui_bundle_observe' - timeout-minutes: 10 - name: "Fabric writer identity: the login this host presents at the fabric DB's served door (reads only)" id: fabric_writer_identity_observe run: |- diff --git a/dag/extdeps/bmc/megarac.dag b/dag/extdeps/bmc/megarac.dag index f5b2b2ad756..79cb1eeed65 100644 --- a/dag/extdeps/bmc/megarac.dag +++ b/dag/extdeps/bmc/megarac.dag @@ -615,31 +615,3 @@ service megarac.Media { } } } - -// THE FIRMWARE'S OWN UI BUNDLE, SERVED AT A FIXED PATH. The SP-X web UI is one minified bundle the -// login page loads before any session exists, so the GET carries no cookie and no token and opens no -// session to release. The codes this module cites as "recovered from source.min.js" (start-media's -// 13410/13460, the served api/ surface, the KVM wire) were read from these bytes; the operation is the -// route that re-reads them instead of a hand-run probe. -// -// THE BYTES ARE WRITTEN AS SERVED. `Accept-Encoding: gzip` without --compressed asks for the encoding -// the 2026-09-27 read recorded (gzip) and leaves it undecoded, so a digest of dest_file is a digest of -// the served bytes, comparable with that read. stdout carries only the write-out: the HTTP status and -// the byte count, space-separated on one line. -data megarac_ui_bundle_path: NonEmptyStr = "/source.min.js" - -service megarac.Ui { - - operation GetServedBundle { - input { bmc_host: NonEmptyStr, bundle_path: NonEmptyStr, dest_file: NonEmptyStr, max_time: NonEmptyStr } - output { writeout: String from "stdout", stderr: String from "stderr", exit_code: Int from "exit_code", success: Bool from "exit_success" } - readonly - transport shell { - argv: ["curl", "--fail-with-body", "-sS", "-k", "--max-time", "{max_time}", "-H", "Accept-Encoding: gzip", "-o", "{dest_file}", "-w", "%\{http_code} %\{size_download}", "https://{bmc_host}{bundle_path}"] - } - exit { - 0 => Unit - nonzero => String "megarac UI bundle GET failed" - } - } -} diff --git a/dag/gunbc/ci/ci_spec.dag b/dag/gunbc/ci/ci_spec.dag index 50a6cf431f5..52ee807f5c4 100644 --- a/dag/gunbc/ci/ci_spec.dag +++ b/dag/gunbc/ci/ci_spec.dag @@ -75,7 +75,6 @@ import gunbc.machine_intake_mtcollins1_fan_observe { mtcollins1_fan_credential_p import gunbc.fabric_writer_identity_observe { fabric_writer_identity_receipt_path } import gunbc.machine_intake_mtcollins1_census_image_publish { mtcollins1_census_image_receipt_path } import gunbc.machine_intake_mtcollins1_census_member_readback { census_member_readback_receipt_path } -import gunbc.machine_intake_mtcollins1_ui_bundle_observe { mtcollins1_ui_bundle_receipt_path } import std.dissolution { DissolutionCondition, dissolution_description, unbound_dissolution } @@ -997,11 +996,6 @@ data gunbc_ci_mtcollins1_fan_observe_target: GunbcRunStepTarget = GunbcRunStepTa function: "mtcollins1_fan_observe_wet", } -data gunbc_ci_mtcollins1_ui_bundle_observe_target: GunbcRunStepTarget = GunbcRunStepTarget { - entry: "dag/gunbc/machine_intake/mtcollins1_ui_bundle_observe.dag", - function: "mtcollins1_ui_bundle_observe_wet", -} - data gunbc_ci_mtcollins1_census_image_publish_target: GunbcRunStepTarget = GunbcRunStepTarget { entry: "dag/gunbc/machine_intake/mtcollins1_census_image_publish.dag", function: "mtcollins1_census_image_publish_wet", @@ -1288,7 +1282,6 @@ fn gunbc_run_step_targets() -> List { gunbc_ci_host_reset_return_target, gunbc_ci_host_reset_dispatch_admission_target, gunbc_ci_mtcollins1_fan_observe_target, - gunbc_ci_mtcollins1_ui_bundle_observe_target, gunbc_ci_mtcollins1_census_image_publish_target, gunbc_ci_mtcollins1_census_member_readback_target, gunbc_ci_spark_grant_install_target, @@ -1834,33 +1827,6 @@ fn gunbc_ci_mtcollins1_fan_observe_invoke() -> String { ) } -// THE UI BUNDLE LANE RUNS ON THE FAN LANE'S PRELUDE, NOT A COPY OF IT. It needs exactly what the fan -// series needs -- the one IPMI credential, for `mc info` -- and the bundle GET itself carries none, so -// a second prelude would be a second authority for the same materialization. It is the same -// hand-shell transport and carries the same marker and trigger. -data gunbc_ci_mtcollins1_ui_bundle_observe_shell_emit_scaffold: Disposition = Scaffold { - dissolves_to: SingleAuthority, - bind: DeclarationRef { - module_path: "gunbc.ci_spec", - decl_name: "gunbc_ci_mtcollins1_ui_bundle_observe_invoke", - field: WholeDeclaration - } -} - -fn gunbc_ci_mtcollins1_ui_bundle_observe_invoke() -> String { - concat( - concat("# ", concat(dissolution_description(condition: gunbc_ci_mtcollins1_fan_observe_shell_emit_dissolution_trigger), "\n")), - gunbc_run_step_script_with_prelude( - prelude: gunbc_ci_mtcollins1_fan_observe_credential_prelude(), - source_roots: witness_layer_roots, - entry: gunbc_ci_mtcollins1_ui_bundle_observe_target.entry, - function: gunbc_ci_mtcollins1_ui_bundle_observe_target.function, - claim_run: false, - receipt_rel: mtcollins1_ui_bundle_receipt_path - ) - ) -} - // The in-run ssh-agent teardown — a FRESH per-job effect (each isolated job starts and must kill // its own agent; nothing is memoizable across jobs), named so the workflow step and the // materialization gate's fresh-effect list reference ONE authority (§3), rather than an inline diff --git a/dag/gunbc/fleet/fleet_converge_workflow.dag b/dag/gunbc/fleet/fleet_converge_workflow.dag index 66e621be2c4..1f5e905826f 100644 --- a/dag/gunbc/fleet/fleet_converge_workflow.dag +++ b/dag/gunbc/fleet/fleet_converge_workflow.dag @@ -27,7 +27,6 @@ import gunbc.fleet.organization_runner_roster_read { organization_runner_roster_ import gunbc.cloudflare.r2_permission_group_observe { r2_mint_preflight_receipt_path } import gunbc.cloudflare.r2_bucket_ensure { r2_bucket_ensure_receipt_path } import gunbc.machine_intake_mtcollins1_fan_observe { mtcollins1_fan_observation_receipt_path } -import gunbc.machine_intake_mtcollins1_ui_bundle_observe { mtcollins1_ui_bundle_bytes_path, mtcollins1_ui_bundle_receipt_path } import gunbc.fabric_writer_identity_observe { fabric_writer_identity_receipt_path } import gunbc.machine_intake_mtcollins1_census_image_publish { mtcollins1_census_image_receipt_path } import gunbc.machine_intake_mtcollins1_census_member_readback { census_member_readback_receipt_path } @@ -124,7 +123,6 @@ import gunbc.ci_spec { gunbc_ci_app_key_version_verify_mint_script, gunbc_ci_app_key_version_verify_verdict_invoke, gunbc_ci_mtcollins1_fan_observe_invoke, - gunbc_ci_mtcollins1_ui_bundle_observe_invoke, gunbc_ci_fabric_writer_identity_observe_invoke, gunbc_ci_mtcollins1_census_image_publish_invoke, gunbc_ci_mtcollins1_census_member_readback_invoke, @@ -298,7 +296,6 @@ type FleetConvergeWorkflowMode | MtCollins1Boot | PairServingD0 | MtCollins1FanObserve - | MtCollins1UiBundleObserve | FabricWriterIdentityObserve | MtCollins1CensusImagePublish | MtCollins1CensusMemberReadback @@ -359,7 +356,6 @@ fn fleet_converge_workflow_mode_wire(mode: FleetConvergeWorkflowMode) -> String NamecheapObserve => "namecheap_observe" PairServingD0 => "pair_serving_d0" MtCollins1FanObserve => "mtcollins1_fan_observe" - MtCollins1UiBundleObserve => "mtcollins1_ui_bundle_observe" FabricWriterIdentityObserve => "fabric_writer_identity_observe" MtCollins1CensusImagePublish => "mtcollins1_census_image_publish" MtCollins1CensusMemberReadback => "mtcollins1_census_member_readback" @@ -389,7 +385,7 @@ fn fleet_converge_spark_target_description() -> String { ], "") } -data fleet_converge_workflow_modes: List = [FullHostPlan, LaunchEnvironmentPlan, AllocationStorePlan, FleetApply, OrgActionsObserve, AppControlPlaneObserve, MicrovmHostConverge, MicrovmNetworkObserve, MicrovmNetworkApply, GuestImageObserve, GuestImageConverge, MicrovmBootProbe, SparkGrants, SparkBootstrap, SparkServingApply, SparkNativeServingApply, SparkRuntimeImageProbe, SparkV41CheckpointMaterialize, SparkV41RowStoreEncode, SparkV41RowStoreReadback, SparkV41EngramDifferential, SparkV41RuntimeImageBuild, SparkV41RuntimeImageDistribute, SparkV41GroupALaunch, DashboardDeploy, ApprovalBrokerDarkInstall, MicrovmControllerInstall, MicrovmSlotReserve, MicrovmSlotStart, RlmLaunchDeploymentReceipt, HostResetReturn, RunnerHostFileObserve, RunnerHostFileConverge, SitePxeEdgeObserve, SitePxeEdgeConverge, RunnerPasswordSessionToolConverge, RunnerBrowserToolchainConverge, R2MintPreflight, R2ObjectWriteMint, OrgRunnerRosterObserve, ApprovalKeyringConverge, ApprovalDeviceEnrolmentCodeIssue, MtCollins1Boot, MtCollins1FanObserve, MtCollins1UiBundleObserve, MtCollins1CensusImagePublish, MtCollins1CensusMemberReadback, HostCredentialCustodyConverge, AppKeyVersionVerify, R2BucketEnsure, R2BucketAdminMint, FabricWriterIdentityObserve, PairServingD0, MicrovmRunnerGroupEnsure, GcpIamConverge, NamecheapObserve] +data fleet_converge_workflow_modes: List = [FullHostPlan, LaunchEnvironmentPlan, AllocationStorePlan, FleetApply, OrgActionsObserve, AppControlPlaneObserve, MicrovmHostConverge, MicrovmNetworkObserve, MicrovmNetworkApply, GuestImageObserve, GuestImageConverge, MicrovmBootProbe, SparkGrants, SparkBootstrap, SparkServingApply, SparkNativeServingApply, SparkRuntimeImageProbe, SparkV41CheckpointMaterialize, SparkV41RowStoreEncode, SparkV41RowStoreReadback, SparkV41EngramDifferential, SparkV41RuntimeImageBuild, SparkV41RuntimeImageDistribute, SparkV41GroupALaunch, DashboardDeploy, ApprovalBrokerDarkInstall, MicrovmControllerInstall, MicrovmSlotReserve, MicrovmSlotStart, RlmLaunchDeploymentReceipt, HostResetReturn, RunnerHostFileObserve, RunnerHostFileConverge, SitePxeEdgeObserve, SitePxeEdgeConverge, RunnerPasswordSessionToolConverge, RunnerBrowserToolchainConverge, R2MintPreflight, R2ObjectWriteMint, OrgRunnerRosterObserve, ApprovalKeyringConverge, ApprovalDeviceEnrolmentCodeIssue, MtCollins1Boot, MtCollins1FanObserve, MtCollins1CensusImagePublish, MtCollins1CensusMemberReadback, HostCredentialCustodyConverge, AppKeyVersionVerify, R2BucketEnsure, R2BucketAdminMint, FabricWriterIdentityObserve, PairServingD0, MicrovmRunnerGroupEnsure, GcpIamConverge, NamecheapObserve] // WHICH SCOPE A MODE SELECTS, WHERE IT SELECTS ONE AT ALL. // // EVERY MODE IS NAMED, AND THE WILDCARD IS DELIBERATELY ABSENT. A `_ => none` would read the same @@ -462,7 +458,6 @@ fn fleet_converge_mode_scope(mode: FleetConvergeWorkflowMode) -> FleetConvergeSc NamecheapObserve => none PairServingD0 => none MtCollins1FanObserve => none - MtCollins1UiBundleObserve => none FabricWriterIdentityObserve => none MtCollins1CensusImagePublish => none MtCollins1CensusMemberReadback => none @@ -591,7 +586,6 @@ fn fleet_converge_mode_fleet_ssh_key_demand(mode: FleetConvergeWorkflowMode) -> MtCollins1Boot => FleetSshKeyConsumed PairServingD0 => FleetSshKeyConsumed MtCollins1FanObserve => FleetSshKeyNotConsumed - MtCollins1UiBundleObserve => FleetSshKeyNotConsumed FabricWriterIdentityObserve => FleetSshKeyNotConsumed MtCollins1CensusImagePublish => FleetSshKeyConsumed MtCollins1CensusMemberReadback => FleetSshKeyConsumed @@ -1214,7 +1208,6 @@ fn fleet_converge_mode_mutation_domain(mode: FleetConvergeWorkflowMode) -> Fleet MtCollins1Boot => ExecutorDomain PairServingD0 => ArmDomain { group: fleet_arm_mutation_group_deepseek_group_a } MtCollins1FanObserve => ExecutorDomain - MtCollins1UiBundleObserve => ExecutorDomain FabricWriterIdentityObserve => ExecutorDomain MtCollins1CensusImagePublish => ExecutorDomain MtCollins1CensusMemberReadback => ExecutorDomain @@ -2078,39 +2071,6 @@ fn fleet_converge_mtcollins1_fan_observe_step() -> Step { } } -// MT. COLLINS' OWN UI BUNDLE AND ITS DIGEST (gunbc.machine_intake_mtcollins1_ui_bundle_observe): the -// firmware revision over IPMI, then the served source.min.js bytes, only under revision 0.32. Reads -// only, no web session. The receipt and the bytes are uploaded whatever the outcome, because a refused -// run's receipt is the one that says why it holds no bytes; a step condition without a status -// function is implicitly success() and would drop exactly that receipt. -data fleet_converge_mtcollins1_ui_bundle_observe_step_if: String = fleet_converge_mode_step_if(mode: MtCollins1UiBundleObserve) - -fn fleet_converge_mtcollins1_ui_bundle_observe_step() -> Step { - RunStep { - name: Present { value: "Mt. Collins UI bundle: firmware revision, then the served source.min.js and its sha256 (reads only)" }, - id: Present { value: "mtcollins1_ui_bundle_observe" }, - run: gunbc_ci_mtcollins1_ui_bundle_observe_invoke(), - shell: none, - env: Present { value: [ - kv(key: "WIF_ACCESS_TOKEN", value: yaml_string(s: "${{ steps.wif_auth.outputs.access_token }}")), - ] }, - working_directory: none, - if_condition: Present { value: fleet_converge_mtcollins1_ui_bundle_observe_step_if }, - continue_on_error: none, - timeout_minutes: Present { value: gunbc_ci_aux_step_timeout_minutes } - } -} - -fn fleet_converge_mtcollins1_ui_bundle_observe_upload_step() -> Step { - fleet_converge_receipt_upload_step( - id: "mtcollins1_ui_bundle_observe_upload", - name: "Upload Mt. Collins UI bundle bytes and receipt", - artifact: "mtcollins1-ui-bundle", - path: "target/mtcollins1-ui-bundle-*", - if_condition: join(["always() && ", fleet_converge_mtcollins1_ui_bundle_observe_step_if], "") - ) -} - // THE READING THE WRITER-ROSTER WALL WAITS FOR (gunbc.fabric_writer_identity_observe): from the // fleet host the dispatch names, through tailscale serve, what Tailscale-User-Login the fabric DB's // door sees. Reads only; the receipt is the roster's ground. Dispatched once per fleet host. @@ -3463,8 +3423,6 @@ fn fleet_converge_job() -> Job { fleet_converge_app_key_version_verify_receipt_upload_step(), fleet_converge_mtcollins1_fan_observe_step(), fleet_converge_mtcollins1_fan_observe_receipt_upload_step(), - fleet_converge_mtcollins1_ui_bundle_observe_step(), - fleet_converge_mtcollins1_ui_bundle_observe_upload_step(), fleet_converge_fabric_writer_identity_observe_step(), fleet_converge_fabric_writer_identity_observe_receipt_upload_step(), fleet_converge_pair_serving_d0_step(), @@ -3709,7 +3667,6 @@ fn fleet_converge_mode_job_id(mode: FleetConvergeWorkflowMode) -> NonEmptyStr { ApprovalDeviceEnrolmentCodeIssue => fleet_converge_shared_job_id MtCollins1Boot => "mtcollins1-boot" as NonEmptyStr MtCollins1FanObserve => fleet_converge_shared_job_id - MtCollins1UiBundleObserve => fleet_converge_shared_job_id MtCollins1CensusImagePublish => fleet_converge_shared_job_id MtCollins1CensusMemberReadback => fleet_converge_shared_job_id HostCredentialCustodyConverge => fleet_converge_shared_job_id diff --git a/dag/gunbc/machine_intake/megarac_served_ui_catalog_observation.dag b/dag/gunbc/machine_intake/megarac_served_ui_catalog_observation.dag index 2bbb9e9c70a..95116b93386 100644 --- a/dag/gunbc/machine_intake/megarac_served_ui_catalog_observation.dag +++ b/dag/gunbc/machine_intake/megarac_served_ui_catalog_observation.dag @@ -11,10 +11,3 @@ import std.types { NonEmptyStr } data megarac_spx_ui_surface_path: NonEmptyStr = "artifacts/bmc/mtcollins1-megarac-api-surface.txt" as NonEmptyStr data megarac_spx_ui_surface_sha256: NonEmptyStr = "4fc53fea3fe49bc3ed3b967511654223578d59d963546117ab524df11b419bcd" as NonEmptyStr - -// THE 2026-09-27 READ OF THE BUNDLE ITSELF, as its digest. extdeps.bmc.megarac cites this read for the -// screen-capture surfaces and the KVM wire; the bytes were not committed, so the digest is the only -// thing a later read can be compared with. gunbc.machine_intake_mtcollins1_ui_bundle_observe reports -// match or drift against it and does not refuse on drift: a different digest is a finding about the -// firmware's served UI, not a failed read. -data megarac_source_min_js_sha256_2026_09_27: NonEmptyStr = "5029fae278f7fc8f4dd4ad5eb8e4457e49fa25d4d0158d4bf9fbab09f57d4bf3" as NonEmptyStr diff --git a/dag/gunbc/machine_intake/mtcollins1_ui_bundle_observe.dag b/dag/gunbc/machine_intake/mtcollins1_ui_bundle_observe.dag deleted file mode 100644 index 1e469bc5b32..00000000000 --- a/dag/gunbc/machine_intake/mtcollins1_ui_bundle_observe.dag +++ /dev/null @@ -1,163 +0,0 @@ -module gunbc.machine_intake_mtcollins1_ui_bundle_observe - -import extdeps.shell -import extdeps.bmc.ipmi -import extdeps.bmc.megarac -import extdeps.tools.sha256sum -import std.algebra { trim } -import std.types { Bool, Int, List, NonEmptyStr, String } -import std.process { ExitSuccess, ProcessExit, exit_failure } -import extdeps.filesystem.filesystem_io { Filesystem } -import extdeps.tools.gnu_coreutils { coreutils_duration_operand } -import extdeps.bmc.megarac { megarac_ui_bundle_path } -import gunbc.machine_intake_mtcollins1_access_observation { mtcollins1_endpoint, mtcollins1_firmware } -import gunbc.machine_intake_mtcollins1_bmc_secure_observation { mtcollins1_secured_account } -import gunbc.machine_intake_mtcollins1_fan_observe { FanCredentialPathReady, FanCredentialPathUnset, FanCredentialPathEmpty, mtcollins1_fan_credential_path, mtcollins1_fan_credential_path_env } -import gunbc.machine_intake_mtcollins1_boot_diagnostic_bundle { mtcollins1_boot_ipmi_read_deadline, mtcollins1_boot_ipmi_kill_after } -import gunbc.machine_intake_megarac_media_attach { megarac_media_read_max_time_operand } -import gunbc.machine_intake_megarac_served_ui_catalog_observation { megarac_source_min_js_sha256_2026_09_27 } - -// ONE READ OF MT. COLLINS' OWN UI BUNDLE, SO A VENDOR CODE IS INTERPRETED FROM THE VENDOR'S SOURCE -// (operator, amended brief msg_20e45239 and decision msg_b3c77f62, 2026-09-30). The settings route -// answers cd_error_code 16 and nothing in the tree says what 16 names; the firmware's UI names its -// own codes in source.min.js, which is how start-media's 13410/13460 were recovered. This mode is the -// modeled route to those bytes: the controller's firmware revision is read over IPMI (`mc info`, -// read-only), the bundle is fetched only when that revision is the one this unit's facts are keyed -// on, and the served bytes, their sha256 and the comparison with the 2026-09-27 read are the receipt. -// -// NOTHING IS WRITTEN TO THE CONTROLLER AND NO WEB SESSION IS OPENED. The bundle is what the login page -// loads before a session exists, so the GET carries no credential (extdeps.bmc.megarac -// megarac.Ui.GetServedBundle); the only credential this run materializes is the IPMI one `mc info` -// needs, through the same prelude the fan observation uses. No unit hold is taken: like the fan -// series, nothing here changes chassis, media or boot state. - -data mtcollins1_ui_bundle_bytes_path: String = "target/mtcollins1-ui-bundle-source.min.js" - -data mtcollins1_ui_bundle_receipt_path: String = "target/mtcollins1-ui-bundle-receipt.txt" - -// THE REVISION AS `mc info` PRINTS IT: the value after the colon on the `Firmware Revision` line. -fn firmware_revision_of_mc_info(stdout: String) -> String? { - let lines = filter(split(s: stdout, delimiter: "\n"), l => starts_with(s: trim(s: l), prefix: "Firmware Revision")) - match lines.first() { - Absent => none - Present { value: line } => { - let after = split(s: line, delimiter: ":").skip(n: 1) - let v = trim(s: join(after, ":")) - if v == "" { none } else { Present { value: v } } - } - } -} - -// THE BUNDLE IS FETCHED ONLY UNDER THE REVISION THE UNIT'S FACTS ARE KEYED ON. Every code this -// module exists to recover is a 0.32 fact (mtcollins1_firmware); bytes from another build would be -// read as 0.32's table. -type UiBundleFirmwareStanding - = UiBundleFirmwareExpected { revision: NonEmptyStr } - | UiBundleFirmwareDiffers { revision: NonEmptyStr, expected: NonEmptyStr } - | UiBundleFirmwareUnread { detail: String } - -fn ui_bundle_firmware_standing(success: Bool, stdout: String, exit_code: Int, stderr: String) -> UiBundleFirmwareStanding { - if !success { - UiBundleFirmwareUnread { detail: join(["ipmitool mc info exited ", to_string(exit_code), ": ", trim(s: stderr)], "") } - } else { - match firmware_revision_of_mc_info(stdout: stdout) { - Absent => UiBundleFirmwareUnread { detail: concat("mc info printed no Firmware Revision line: ", stdout) } - Present { value: r } => - if r == (mtcollins1_firmware.raw_version as String) { UiBundleFirmwareExpected { revision: r as NonEmptyStr } } - else { UiBundleFirmwareDiffers { revision: r as NonEmptyStr, expected: mtcollins1_firmware.raw_version } } - } - } -} - -// MATCH OR DRIFT AGAINST THE 2026-09-27 READ, REPORTED AND NEVER A REFUSAL: a different digest is a -// finding about the served UI, not a failed read. -type UiBundleDigestComparison - = UiBundleDigestMatches - | UiBundleDigestDrifted { cited: NonEmptyStr } - -fn ui_bundle_digest_comparison(observed: String) -> UiBundleDigestComparison { - if observed == (megarac_source_min_js_sha256_2026_09_27 as String) { UiBundleDigestMatches } - else { UiBundleDigestDrifted { cited: megarac_source_min_js_sha256_2026_09_27 } } -} - -fn ui_bundle_digest_comparison_text(c: UiBundleDigestComparison) -> String { - match c { - UiBundleDigestMatches => "MATCH with the 2026-09-27 read" - UiBundleDigestDrifted { cited: d } => concat("DRIFT from the 2026-09-27 read, which was ", d as String) - } -} - -fn ui_bundle_firmware_text(f: UiBundleFirmwareStanding) -> String { - match f { - UiBundleFirmwareExpected { revision: r } => concat("firmware revision ", concat(r as String, " (expected)")) - UiBundleFirmwareDiffers { revision: r, expected: e } => join(["firmware revision ", r as String, " is NOT the expected ", e as String, "; the bundle was not fetched"], "") - UiBundleFirmwareUnread { detail: d } => concat("firmware revision UNREAD, so the bundle was not fetched: ", d) - } -} - -// THE RECEIPT IS WRITTEN ON EVERY PATH THAT REACHED THE CONTROLLER, and the exit carries the same -// sentence, so a refused run's artifact says why it holds no bytes. -fn ui_bundle_conclude(lines: List, outcome: ProcessExit) -> ProcessExit { - let body = join(concat([concat("subject=", mtcollins1_endpoint.host as String), concat("bundle_path=", megarac_ui_bundle_path as String)], lines), "\n") - let kept = Filesystem.Write(path: mtcollins1_ui_bundle_receipt_path, content: concat(body, "\n")) - if kept.success { outcome } else { - match outcome { - ExitSuccess => exit_failure(reason: concat("mtcollins1 ui bundle: the bundle was read and its receipt could not be written: ", kept.error)) - other => other - } - } -} - -fn ui_bundle_firmware_refused(firmware: UiBundleFirmwareStanding) -> ProcessExit { - ui_bundle_conclude(lines: [concat("firmware=", ui_bundle_firmware_text(f: firmware))], outcome: exit_failure(reason: concat("mtcollins1 ui bundle: ", ui_bundle_firmware_text(f: firmware)))) -} - -fn mtcollins1_ui_bundle_observe_with(username: NonEmptyStr, password_file: NonEmptyStr) -> ProcessExit { - let mc = diagnostic.ipmi.Tool.McInfo( - bmc_host: mtcollins1_endpoint.host, - username: username, - password_file: password_file, - deadline: coreutils_duration_operand(d: mtcollins1_boot_ipmi_read_deadline) as NonEmptyStr, - kill_after: coreutils_duration_operand(d: mtcollins1_boot_ipmi_kill_after) as NonEmptyStr, - ) - let firmware = ui_bundle_firmware_standing(success: mc.success, stdout: mc.stdout, exit_code: mc.exit_code, stderr: mc.transport_stderr) - let fw_line = concat("firmware=", ui_bundle_firmware_text(f: firmware)) - match firmware { - UiBundleFirmwareExpected { revision: _ } => {} - UiBundleFirmwareDiffers { revision: _, expected: _ } => return ui_bundle_firmware_refused(firmware: firmware) - UiBundleFirmwareUnread { detail: _ } => return ui_bundle_firmware_refused(firmware: firmware) - } - let got = megarac.Ui.GetServedBundle( - bmc_host: mtcollins1_endpoint.host, - bundle_path: megarac_ui_bundle_path, - dest_file: mtcollins1_ui_bundle_bytes_path as NonEmptyStr, - max_time: megarac_media_read_max_time_operand(), - ) - let fetch_line = join(["fetch=exit ", to_string(got.exit_code), " writeout(http_code size_download)=", trim(s: got.writeout), if trim(s: got.stderr) == "" { "" } else { concat(" stderr=", trim(s: got.stderr)) }], "") - if !got.success { - return ui_bundle_conclude(lines: [fw_line, fetch_line], outcome: exit_failure(reason: concat("mtcollins1 ui bundle: the bundle GET did not succeed: ", fetch_line))) - } - let digest = sha256sum.Sha256.DigestFile(path: mtcollins1_ui_bundle_bytes_path as NonEmptyStr) - let observed = match split(s: trim(s: digest.line), delimiter: " ").first() { Present { value: d } => d Absent => "" } - if !digest.success || observed == "" { - return ui_bundle_conclude(lines: [fw_line, fetch_line], outcome: exit_failure(reason: concat("mtcollins1 ui bundle: the fetched bytes could not be digested: ", digest.line))) - } - ui_bundle_conclude( - lines: [fw_line, fetch_line, concat("sha256=", observed), concat("comparison=", ui_bundle_digest_comparison_text(c: ui_bundle_digest_comparison(observed: observed))), concat("bytes=", mtcollins1_ui_bundle_bytes_path)], - outcome: ExitSuccess, - ) -} - -// REFUSALS BEFORE THE FIRST REQUEST, EACH NAMING WHAT IS MISSING, exactly as the fan observation's. -fn mtcollins1_ui_bundle_observe_wet() -> ProcessExit -{ - match mtcollins1_secured_account() { - Absent => exit_failure(reason: "mtcollins1 ui bundle: the BMC is not BmcSecured, so this run holds no account to read the firmware revision with; contacting NO host") - Present { value: username } => - match mtcollins1_fan_credential_path() { - FanCredentialPathUnset => exit_failure(reason: join(["mtcollins1 ui bundle: no ", mtcollins1_fan_credential_path_env as String, " in the environment; contacting NO host"], "")) - FanCredentialPathEmpty => exit_failure(reason: join(["mtcollins1 ui bundle: ", mtcollins1_fan_credential_path_env as String, " is set but empty; contacting NO host"], "")) - FanCredentialPathReady { path: p } => mtcollins1_ui_bundle_observe_with(username: username, password_file: p) - } - } -} diff --git a/dag/test/claim/machine_intake/mtcollins1_ui_bundle_observe_witness_test.dag b/dag/test/claim/machine_intake/mtcollins1_ui_bundle_observe_witness_test.dag deleted file mode 100644 index e50d8a45a68..00000000000 --- a/dag/test/claim/machine_intake/mtcollins1_ui_bundle_observe_witness_test.dag +++ /dev/null @@ -1,68 +0,0 @@ -module test.claim.machine_intake.mtcollins1_ui_bundle_observe_witness_test - -import std.types { Bool, String } -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } -import gunbc.machine_intake_megarac_served_ui_catalog_observation { megarac_source_min_js_sha256_2026_09_27 } -import gunbc.machine_intake_mtcollins1_ui_bundle_observe { - UiBundleDigestDrifted, - UiBundleDigestMatches, - UiBundleFirmwareDiffers, - UiBundleFirmwareExpected, - UiBundleFirmwareUnread, - firmware_revision_of_mc_info, - ui_bundle_digest_comparison, - ui_bundle_firmware_standing, -} - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -// `ipmitool mc info` as it prints, with the revision a parameter so the pair differs in one value. -fn mc_info_with(revision: String) -> String { - join([ - "Device ID : 32", - "Device Revision : 1", - concat("Firmware Revision : ", revision), - "IPMI Version : 2.0", - "Manufacturer ID : 10876", - ], "\n") -} - -test fn the_revision_is_the_value_after_the_colon() -> Bool { - match firmware_revision_of_mc_info(stdout: mc_info_with(revision: "0.32")) { - Present { value: r } => r == "0.32" - Absent => false - } -} - -// THE DISCRIMINATING PAIR: one value differs, and only 0.32 admits the fetch. -test fn only_the_expected_revision_admits_the_fetch() -> Bool { - (match ui_bundle_firmware_standing(success: true, stdout: mc_info_with(revision: "0.32"), exit_code: 0, stderr: "") { - UiBundleFirmwareExpected { revision: r } => (r as String) == "0.32" - _ => false - }) - && (match ui_bundle_firmware_standing(success: true, stdout: mc_info_with(revision: "0.33"), exit_code: 0, stderr: "") { - UiBundleFirmwareDiffers { revision: r, expected: e } => (r as String) == "0.33" && (e as String) == "0.32" - _ => false - }) -} - -// An unanswered read and an answer with no revision are both unread, never a revision. -test fn an_unread_revision_never_admits_the_fetch() -> Bool { - (match ui_bundle_firmware_standing(success: false, stdout: "", exit_code: 124, stderr: "") { - UiBundleFirmwareUnread { detail: d } => string_contains(s: d, pattern: "124") - _ => false - }) - && (match ui_bundle_firmware_standing(success: true, stdout: "Device ID : 32", exit_code: 0, stderr: "") { - UiBundleFirmwareUnread { detail: _ } => true - _ => false - }) -} - -// DRIFT IS REPORTED, AND THE CITED DIGEST RIDES WITH IT. -test fn the_cited_digest_matches_and_any_other_drifts() -> Bool { - (match ui_bundle_digest_comparison(observed: megarac_source_min_js_sha256_2026_09_27 as String) { UiBundleDigestMatches => true _ => false }) - && (match ui_bundle_digest_comparison(observed: "0000000000000000000000000000000000000000000000000000000000000000") { - UiBundleDigestDrifted { cited: c } => c == megarac_source_min_js_sha256_2026_09_27 - _ => false - }) -} From 8042d175c2af3c900a87c7c5d964c9987ac1eb33 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Wed, 30 Sep 2026 22:03:20 +0000 Subject: [PATCH 65/75] Matrix dead band: the four cases that straddle the enrolment margin between runners PR floor run 36775473983 at b907f7dc0c3 (srv3) refused four matrix cases as measured over the 302 ms margin, at 303-318 ms. Run 36765162766 at 6cac35eb1a6 (srv1) had admitted the same four at 276-290 ms, at identical eval_steps. This is the margin-straddle form of gunbc.recurring_failure_mode enrolment_dead_band_has_no_representable_standing, which #12533 already repaired: a dead-band row whose fast-runner reading lies in (envelope floor, margin] is EnrolmentDeadBandWithinRunnerEnvelope, not stale. Each row cites both runs. docs/design-rung-drops.md regenerated. Co-Authored-By: Claude Opus 5.5 (1M context) --- docs/design-rung-drops.md | 2 +- src/v2/workflow/floor_enrolment_dead_band.dag | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index 36d4c763dbf..6ed279796bf 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -360,7 +360,7 @@ the enrolment-margin decision over exactly two App Attest verifier claims whose ### the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided — declared 2026-09-30 -the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 449 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 433 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 421 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 411 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 374 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 381 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: the real boot entry end to end over the dry realization through a stop, a replace and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 473 ms CPU, strictly above the 302 ms margin and under the 500 ms line. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. +the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 449 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 433 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 421 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 411 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 374 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 381 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: the real boot entry end to end over the dry realization through a stop, a replace and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 473 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 303 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 287 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 307 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_refuses_before_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 308 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 276 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_refuses_before_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 318 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope). Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. ### new-witness eval-step cost gate over the one claim that inhabits the real byte-span argv with its really-serialized program: it still executes, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 diff --git a/src/v2/workflow/floor_enrolment_dead_band.dag b/src/v2/workflow/floor_enrolment_dead_band.dag index b3e5ce82aae..c30ef927e43 100644 --- a/src/v2/workflow/floor_enrolment_dead_band.dag +++ b/src/v2/workflow/floor_enrolment_dead_band.dag @@ -73,6 +73,22 @@ fn mtcollins1_boot_matrix_enrolment_dead_band_observed_only() -> List Date: Wed, 30 Sep 2026 22:51:34 +0000 Subject: [PATCH 66/75] Matrix dead band: media_that_never_becomes_ready straddles the margin PR floor run 36783312538 at 8042d175c2a (srv3) refused it at 320 ms against the 302 ms margin; run 36765162766 (srv1) admitted it at 283 ms, at identical eval_steps. It is the same straddle form as the previous four. It was the only blocker on that run: 0 claims failed and 0 over-cost. docs/design-rung-drops.md regenerated. Co-Authored-By: Claude Opus 5.5 (1M context) --- docs/design-rung-drops.md | 2 +- src/v2/workflow/floor_enrolment_dead_band.dag | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index 6ed279796bf..dac6c847ba0 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -360,7 +360,7 @@ the enrolment-margin decision over exactly two App Attest verifier claims whose ### the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided — declared 2026-09-30 -the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 449 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 433 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 421 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 411 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 374 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 381 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: the real boot entry end to end over the dry realization through a stop, a replace and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 473 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 303 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 287 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 307 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_refuses_before_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 308 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 276 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_refuses_before_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 318 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope). Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. +the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 449 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 433 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 421 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 411 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 374 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 381 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: the real boot entry end to end over the dry realization through a stop, a replace and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 473 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 303 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 287 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 307 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_refuses_before_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 308 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 276 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_refuses_before_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 318 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: the real boot entry end to end over the dry realization through the whole readiness wait, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36783312538 of gunbc#12800 at 8042d175c2a (srv3) observed 320 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 283 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope). Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. ### new-witness eval-step cost gate over the one claim that inhabits the real byte-span argv with its really-serialized program: it still executes, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 diff --git a/src/v2/workflow/floor_enrolment_dead_band.dag b/src/v2/workflow/floor_enrolment_dead_band.dag index c30ef927e43..b7498877743 100644 --- a/src/v2/workflow/floor_enrolment_dead_band.dag +++ b/src/v2/workflow/floor_enrolment_dead_band.dag @@ -89,6 +89,10 @@ fn mtcollins1_boot_matrix_enrolment_dead_band_observed_only() -> List Date: Thu, 1 Oct 2026 04:28:56 +0000 Subject: [PATCH 67/75] mtcollins1 media: a Started row is ready whatever cd_error_code says (vendor UI reads it only when stopped); the code is recorded, an unread code still withholds Operator decision 2026-10-01 (boot-from-branch fast path). Grounded in the MegaRAC UI bundle source.min.js sha256 5029fae2 (rmedia changeInSingleImages): error_code is consulted only at redirection_status 0 and rendered as the stop reason (16 = Device Ejected). Stopped-row codes keep today's refusal; the per-code table is the separate policy lane. Matrix and convergence witnesses re-asserted; the three matrix cases that pinned '16 refuses' now assert the boot proceeds with the code recorded. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../machine_intake/megarac_media_attach.dag | 22 +++++++----- ...megarac_media_convergence_witness_test.dag | 23 +++++++------ ...mtcollins1_boot_acceptance_matrix_test.dag | 34 ++++++++++--------- docs/design-rung-drops.md | 4 +-- src/v2/workflow/floor_enrolment_dead_band.dag | 6 ++-- src/v2/workflow/floor_eval_step_cost_drop.dag | 6 ++-- 6 files changed, 53 insertions(+), 42 deletions(-) diff --git a/dag/gunbc/machine_intake/megarac_media_attach.dag b/dag/gunbc/machine_intake/megarac_media_attach.dag index 3cc6a6efde1..5a40e6ddb46 100644 --- a/dag/gunbc/machine_intake/megarac_media_attach.dag +++ b/dag/gunbc/machine_intake/megarac_media_attach.dag @@ -1867,6 +1867,12 @@ fn megarac_readiness_outcome( // PURE: the wait's answer as the attach outcome. Only a Started look reaches MegaRacPresentationReady, // and the evidence is read from that look's row, so the record a boot is gated on is the row that // satisfied the policy. +// A STARTED ROW IS READY WHATEVER cd_error_code SAYS (operator decision 2026-10-01). The vendor's own +// UI (source.min.js sha256 5029fae2, rmedia changeInSingleImages) consults error_code ONLY when +// redirection_status is 0 (stopped) and renders it as the stop reason ("Stopped - Device Ejected" +// for 16); at status 1/100 it never reads it. So a nonzero code beside a Started row is a latched +// last-stop reason, recorded in the evidence (cd_before_any_write, cd_at_ready), not a live fault. +// An UNREAD code still withholds: the look could not establish the general settings at all. fn readiness_wait_outcome( wait: ReadinessWait, image_name: NonEmptyStr, @@ -1885,10 +1891,8 @@ fn readiness_wait_outcome( let not_ready = MegaRacReadinessRefused { image_name: image_name, route: route, look: l, looks: n, cd_before_any_write: cd_before, cd_at_refusal: cd_at_end } let state_unestablished = MegaRacMediaStateUnestablished { image_name: image_name, route: route, look: l, looks: n, cd_before_any_write: cd_before, cd_at_ready: cd_at_end, general_at_ready: general_at_end } match l.reading { - ReadinessStarted { row: r } => - match cd_at_end { - CdErrorRead { code: CdErrorNone } => - MegaRacPresentationReady { + ReadinessStarted { row: r } => { + let started_ready = MegaRacPresentationReady { route: route, evidence: MegaRacPresentationEvidence { firmware: firmware, @@ -1903,9 +1907,12 @@ fn readiness_wait_outcome( general_at_ready: general_at_end, }, } - CdErrorRead { code: CdErrorUncatalogued { wire: _ } } => state_unestablished + match cd_at_end { + CdErrorRead { code: CdErrorNone } => started_ready + CdErrorRead { code: CdErrorUncatalogued { wire: _ } } => started_ready CdErrorUnread { detail: _ } => state_unestablished } + } ReadinessConnecting { row: _ } => not_ready ReadinessStartedUnbound { row: _ } => not_ready ReadinessNotPresented { configurations: _ } => not_ready @@ -1981,13 +1988,12 @@ fn presentation_still_served(result: MegaRacAttachResult) -> PresentationStillSe ReadinessUncatalogued { image_name: _, wire: _, configurations: _ } => PresentationUnobserved { reason: "a configurations row carries an uncatalogued status" } ReadinessStarted { row: _ } => match cd { - CdErrorRead { code: CdErrorNone } => + CdErrorUnread { detail: _ } => PresentationUnobserved { reason: "cd_error_code could not be read" } + CdErrorRead { code: _ } => match result.session_release { SessionReleased => PresentationStillReady other => PresentationReadyButSessionHeld { held: other } } - CdErrorUnread { detail: _ } => PresentationUnobserved { reason: "cd_error_code could not be read" } - other => PresentationStateUnestablished { cd_error: other } } ReadinessConnecting { row: _ } => no_longer_ready ReadinessStartedUnbound { row: _ } => no_longer_ready diff --git a/dag/test/claim/machine_intake/megarac_media_convergence_witness_test.dag b/dag/test/claim/machine_intake/megarac_media_convergence_witness_test.dag index 1a21ab723d1..18af13c7068 100644 --- a/dag/test/claim/machine_intake/megarac_media_convergence_witness_test.dag +++ b/dag/test/claim/machine_intake/megarac_media_convergence_witness_test.dag @@ -495,14 +495,17 @@ fn raw_at(body: String) -> MegaRacRawRead { MegaRacRawRead { answered: true, body: body, observed_at: Present { value: 13100 } } } -// OPTION A (operator decision on #12425): a nonzero or unread code withholds as a knowledge refusal. -test fn a_nonzero_code_beside_a_started_presentation_withholds_as_unestablished() -> Bool { - match readiness_wait_outcome(wait: ReadinessWaitReady { look: look(at: 13000, status: "1", session: "0"), looks: 4 }, image_name: desired_census, firmware: megarac_firmware_0_32, route: RouteAttached { image_list_index: "5", start: WriteAccepted { body: "{}" } }, cd_before: cd_16, general_at_end: raw_at(body: mtcollins1_media_general_2026_09_27)) { - MegaRacMediaStateUnestablished { image_name: _, route: _, look: _, looks: n, cd_before_any_write: _, cd_at_ready: CdErrorRead { code: CdErrorUncatalogued { wire: w } }, general_at_ready: _ } => - n == 4 && w == 16 - && (match mtcollins1_media_gate(record: attempted(result: MegaRacAttachResult { outcome: readiness_wait_outcome(wait: ReadinessWaitReady { look: look(at: 13000, status: "1", session: "0"), looks: 4 }, image_name: desired_census, firmware: megarac_firmware_0_32, route: RouteAttached { image_list_index: "5", start: WriteAccepted { body: "{}" } }, cd_before: cd_16, general_at_end: raw_at(body: mtcollins1_media_general_2026_09_27)), session_release: SessionReleased, baseline: none })) { - MediaGateWithheld { reason: r } => string_contains(s: r as String, pattern: "knowledge refusal") - MediaGateReady { evidence: _ } => false +// A STARTED ROW IS READY WHATEVER cd_error_code SAYS (operator decision 2026-10-01, superseding the #12425 +// option-A knowledge refusal): the vendor UI consults error_code only for a stopped row. The code is +// recorded in the evidence and the gate opens. +test fn a_nonzero_code_beside_a_started_presentation_is_ready_and_recorded() -> Bool { + let outcome = readiness_wait_outcome(wait: ReadinessWaitReady { look: look(at: 13000, status: "1", session: "0"), looks: 4 }, image_name: desired_census, firmware: megarac_firmware_0_32, route: RouteAttached { image_list_index: "5", start: WriteAccepted { body: "{}" } }, cd_before: cd_16, general_at_end: raw_at(body: mtcollins1_media_general_2026_09_27)) + match outcome { + MegaRacPresentationReady { route: _, evidence: e } => + (match e.cd_at_ready { CdErrorRead { code: CdErrorUncatalogued { wire: w } } => w == 16 _ => false }) + && (match mtcollins1_media_gate(record: attempted(result: MegaRacAttachResult { outcome: outcome, session_release: SessionReleased, baseline: none })) { + MediaGateReady { evidence: _ } => true + MediaGateWithheld { reason: _ } => false }) _ => false } @@ -623,9 +626,9 @@ test fn the_recheck_withholds_when_its_own_session_was_not_released() -> Bool { && (match presentation_still_served(result: served_look) { PresentationStillReady => true _ => false }) } -test fn a_started_look_with_code_16_is_unestablished_at_the_recheck() -> Bool { +test fn a_started_look_with_code_16_is_still_served_at_the_recheck() -> Bool { match presentation_still_served(result: observed(general: mtcollins1_media_general_2026_09_27, configurations: presenting_in(name: desired_census as String, status: "1", session: "0"))) { - PresentationStateUnestablished { cd_error: CdErrorRead { code: CdErrorUncatalogued { wire: w } } } => w == 16 + PresentationStillReady => true _ => false } } diff --git a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag index ae3d7f1b396..c1c845fcabc 100644 --- a/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag @@ -778,16 +778,16 @@ fn presenting(image_name: String) -> MegaRacCdRow { MegaRacCdRow { image_name: image_name, redirection_status: 1, media_index: 0, session_index: 0, ready_at: none } } -// CODE 16 WITH NOTHING PRESENTED AND THE HOST OFF -- the 2026-09-27 state. The attach proceeds and the -// presentation reaches Started, but the code is still 16 at readiness, so the attempt refuses as unable -// to establish the media state, with no handoff. -test fn cd_error_16_with_nothing_presented_refuses_before_the_handoff() -> Bool { +// CODE 16 WITH NOTHING PRESENTED AND THE HOST OFF -- the 2026-09-27 state. The attach proceeds, the +// presentation reaches Started, and the code 16 still read at readiness is the vendor's latched last-stop +// reason ("Device Ejected"; the UI consults it only when the row is stopped), so it is recorded and the +// attempt proceeds to the boot. +test fn cd_error_16_with_nothing_presented_attaches_and_boots_with_the_code_recorded() -> Bool { match run_attempt(world: media_varied(media: media_errored(code: 16, clears: true, after_ready: no_error_after_ready(), cd: megarac_cleared_cd()))) { WitnessReturned { value, route } => - string_contains(s: outcome_reason(a: value), pattern: "cannot establish the media state") - && string_contains(s: outcome_reason(a: value), pattern: "cd_error_code before any write was 16") - && count_named(route: route, name: "megarac.Media.StopMedia") == 0 - && reached_no_power_action(route: route) + string_contains(s: outcome_reason(a: value), pattern: "deadline reached without a host-capture terminal") + && first_ordinal(route: route, name: "megarac.Media.StartMedia") < first_ordinal(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") + && controller_writes_are_under_the_hold(route: route) _ => false } } @@ -806,12 +806,13 @@ test fn cd_error_16_with_the_host_on_writes_nothing() -> Bool { } // A CODE THAT APPEARS WITH READINESS. The presentation reads Started while the general route reports -// 16 at readiness; the attempt refuses before the handoff. -test fn cd_error_appearing_with_readiness_refuses_before_the_handoff() -> Bool { +// 16 at readiness: a Started row is ready whatever the code says, so the attempt proceeds to the boot. +test fn cd_error_appearing_with_readiness_is_recorded_and_booted() -> Bool { match run_attempt(world: media_varied(media: media_errored(code: 0, clears: true, after_ready: Present { value: 16 }, cd: megarac_cleared_cd()))) { WitnessReturned { value, route } => - string_contains(s: outcome_reason(a: value), pattern: "cd_error_code before any write was 0 and at readiness 16") - && reached_no_power_action(route: route) + string_contains(s: outcome_reason(a: value), pattern: "deadline reached without a host-capture terminal") + && first_ordinal(route: route, name: "megarac.Media.StartMedia") < first_ordinal(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") + && controller_writes_are_under_the_hold(route: route) _ => false } } @@ -832,12 +833,13 @@ test fn a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted() // THE SAME STALE IMAGE, BUT THE STOP DOES NOT CLEAR THE CODE. The replacement reaches Started with the // code still 16, and the attempt refuses before the handoff. -test fn a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace() -> Bool { +test fn a_stale_lane_image_with_a_code_the_stop_does_not_clear_is_replaced_and_booted() -> Bool { match run_attempt(world: media_varied(media: media_errored(code: 16, clears: false, after_ready: no_error_after_ready(), cd: presenting(image_name: stale_lane_image)))) { WitnessReturned { value, route } => - string_contains(s: outcome_reason(a: value), pattern: "cannot establish the media state") - && count_named(route: route, name: "megarac.Media.StopMedia") == 1 - && reached_no_power_action(route: route) + string_contains(s: outcome_reason(a: value), pattern: "deadline reached without a host-capture terminal") + && first_ordinal(route: route, name: "megarac.Media.StopMedia") < first_ordinal(route: route, name: "megarac.Media.StartMedia") + && first_ordinal(route: route, name: "megarac.Media.StartMedia") < first_ordinal(route: route, name: "diagnostic.ipmi.Tool.ChassisPowerControl") + && controller_writes_are_under_the_hold(route: route) _ => false } } diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index 453761092aa..e77aad1380c 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -348,7 +348,7 @@ new-witness eval-step cost gate over the ten interpreted P-256 and P-384 point a ### new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 -new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=248288 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=237233 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=215502 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=140940 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146038 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=204469 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=202126 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=194599 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=122748 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=116804 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=276996 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_live_holder_still_blocks_the_next_attempt: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102436 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unobservable_holder_is_refused_not_recovered: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102525 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_successor_in_another_pid_namespace_refuses_rather_than_recovering: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102114 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=262400 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=154633 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146769 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=139739 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=138564 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_jumping_forward_during_readiness_closes_the_window: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=137976 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_the_host_on_writes_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=126998 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_foreign_presented_image_is_not_stopped: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=118325 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_toolchain_that_is_not_ready_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=112482 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unresolved_toolchain_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_unresolved_toolchain_starts_no_observer_and_no_power_action, over gunbc#12800 at 6cac35eb1a6, 2026-09-30: PASS, eval_steps=102990 against the 72,300 new-witness budget (eval_steps are host-independent; PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) printed no eval-step line for it before its cancel); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, up to the handoff gate's refusal. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each of these identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. +new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=248288 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=237233 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=215502 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=140940 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146038 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=204469 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=202126 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=194599 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=122748 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=116804 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=276996 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_live_holder_still_blocks_the_next_attempt: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102436 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unobservable_holder_is_refused_not_recovered: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102525 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_successor_in_another_pid_namespace_refuses_rather_than_recovering: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102114 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=262400 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_is_recorded_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=154633 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_is_replaced_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146769 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_attaches_and_boots_with_the_code_recorded: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=139739 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=138564 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_jumping_forward_during_readiness_closes_the_window: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=137976 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_the_host_on_writes_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=126998 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_foreign_presented_image_is_not_stopped: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=118325 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_toolchain_that_is_not_ready_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=112482 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unresolved_toolchain_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_unresolved_toolchain_starts_no_observer_and_no_power_action, over gunbc#12800 at 6cac35eb1a6, 2026-09-30: PASS, eval_steps=102990 against the 72,300 new-witness budget (eval_steps are host-independent; PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) printed no eval-step line for it before its cancel); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, up to the handoff gate's refusal. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each of these identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. ### new-witness eval-step cost gate over the one claim that runs the real fleet-converge build-job step list to hold the reset-observer dispatch admission's membership: it still executes, eval_steps stay recorded, a semantic red still blocks; only the eval-step cost-gate rung is lowered — declared 2026-09-30 @@ -364,7 +364,7 @@ the enrolment-margin decision over exactly two App Attest verifier claims whose ### the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided — declared 2026-09-30 -the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 449 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 433 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 421 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 411 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 374 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 381 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: the real boot entry end to end over the dry realization through a stop, a replace and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 473 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 303 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 287 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 307 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_refuses_before_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 308 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 276 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_refuses_before_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 318 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: the real boot entry end to end over the dry realization through the whole readiness wait, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36783312538 of gunbc#12800 at 8042d175c2a (srv3) observed 320 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 283 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope). Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. +the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 449 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 433 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 421 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 411 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 374 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 381 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: the real boot entry end to end over the dry realization through a stop, a replace and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 473 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 303 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 287 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_is_replaced_and_booted: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 307 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_attaches_and_boots_with_the_code_recorded: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 308 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 276 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_is_recorded_and_booted: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 318 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: the real boot entry end to end over the dry realization through the whole readiness wait, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36783312538 of gunbc#12800 at 8042d175c2a (srv3) observed 320 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 283 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope). Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. ### new-witness eval-step cost gate over the one claim that inhabits the real byte-span argv with its really-serialized program: it still executes, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 diff --git a/src/v2/workflow/floor_enrolment_dead_band.dag b/src/v2/workflow/floor_enrolment_dead_band.dag index b7498877743..e8140edf514 100644 --- a/src/v2/workflow/floor_enrolment_dead_band.dag +++ b/src/v2/workflow/floor_enrolment_dead_band.dag @@ -78,15 +78,15 @@ fn mtcollins1_boot_matrix_enrolment_dead_band_observed_only() -> List Date: Thu, 1 Oct 2026 04:34:13 +0000 Subject: [PATCH 68/75] mtcollins1 KVM viewer: seed sessionStorage.features from the firmware-0.32 row (minimum from #12830 for the boot) Run 36788605665: the served viewer.min.js reads sessionStorage.features.indexOf(...) unguarded in its KVM view's initialize(), so with features unset it throws and never opens /kvm. - extdeps.bmc.megarac megarac_ui_features_0_32 (73 names), emitted by gunbc.machine_intake_megarac_ui_features megarac_ui_features_row_emit from the retained served source.min.js, refused unless it digests to the 2026-09-27 pin (row ported with it); megarac_ui_features(firmware) and the vendor storage shape; extdeps.tools.gzip for the decode. - kvm_still: no row for the firmware -> not started; the launch writes features.json and the init script seeds sessionStorage.features; features-unreadable cause. - loopback viewer reads sessionStorage.features.indexOf unguarded; enrolled wet red a_viewer_without_its_feature_list_never_opens_kvm; megarac_ui_features witness. Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/extdeps/bmc/megarac.dag | 97 ++++++++++++++- dag/extdeps/exec/program.dag | 1 + dag/extdeps/tools/gzip.dag | 60 ++++++++++ dag/gunbc/bmc_megarac_web_transport.dag | 5 +- .../megarac_served_ui_catalog_observation.dag | 6 + .../machine_intake/megarac_ui_features.dag | 112 ++++++++++++++++++ .../machine_intake/mtcollins1_kvm_still.dag | 29 ++++- .../megarac_ui_features_witness_test.dag | 66 +++++++++++ ...kvm_observer_protocol_wet_witness_test.dag | 31 ++++- src/v2/workflow/floor_route_gap.dag | 4 +- src/v2/workflow/local_repo_wet_terminal.dag | 6 + 11 files changed, 406 insertions(+), 11 deletions(-) create mode 100644 dag/extdeps/tools/gzip.dag create mode 100644 dag/gunbc/machine_intake/megarac_ui_features.dag create mode 100644 dag/test/claim/machine_intake/megarac_ui_features_witness_test.dag diff --git a/dag/extdeps/bmc/megarac.dag b/dag/extdeps/bmc/megarac.dag index 79cb1eeed65..ffe91294549 100644 --- a/dag/extdeps/bmc/megarac.dag +++ b/dag/extdeps/bmc/megarac.dag @@ -15,7 +15,8 @@ import extdeps.uri { Uri, Https } import extdeps.vendor { Vendor } import extdeps.hardware { Hardware } import extdeps.vendor.ami { ami } -import extdeps.languages.json.emit { JsonValue, json_object, json_array, json_kv, json_int, json_string } +import extdeps.languages.json.emit { JsonValue, json_object, json_array, json_kv, json_int, json_string, serialize_json_array } +import v2.std.optional { Present, Absent } data extdeps_external_authority_anchor: ExternalAuthority = ExternalAuthority { uri: Uri { @@ -615,3 +616,97 @@ service megarac.Media { } } } + +// THE FEATURE LIST THE UI HANDS ITS KVM VIEWER, PER FIRMWARE BUILD. The SP-X UI stores +// sessionStorage "features" = JSON.stringify of its project-configurations collection, seeded from the +// static `features` module compiled into source.min.js; the viewer's KVM view reads it with unguarded +// indexOf calls, so a viewer opened without it never opens /kvm. The 0.32 row is EMITTED, not typed: +// gunbc.machine_intake_megarac_ui_features megarac_ui_features_row_emit parses it out of the retained +// source.min.js of fleet-converge crawl run 36787375313 (mtcollins1-ui-bundle), refusing unless those +// bytes digest to the 2026-09-27 read's sha256 (5029fae2...). A build with no row has no list here. +// MEGARAC_UI_FEATURES_0_32_BEGIN +data megarac_ui_features_0_32: List = [ + "RMEDIA_MULTI_IMAGE_SUPPORT", + "BIOS_SUPPORT", + "KVM_SESSION_RECONNECT", + "SYSTEM_FIREWALL", + "OEM_PROPRIETARY_LEVEL_SUPPORT", + "HTML5_KVM", + "DUAL_BIOS_FLASH_SUPPORT", + "IPV6_SUPPORT", + "ALLOW_NON_SECURE_COMMUNICATION", + "SET_SENSOR_THRESHOLDS", + "REPLACE_OEM_LOGO", + "EXTENDEDLOG", + "AUTO_RESIZE_KVM_CLIENT_WINDOW", + "SERVICES", + "RMEDIA", + "AUTOVDORECORD_REMOTE", + "CAPTURE_BSOD_JPEG", + "RADIUS_SUPPORT", + "SYSTEM_FIREWALL_TIMEOUT", + "UARTLOG", + "RUNTIME_HOST_LOCK", + "SOL_SUPPORT", + "HPM_SUPPORT", + "ADVISER_SUPPORT", + "AD_SUPPORT", + "MULTIPLE_USER_VMEDIA", + "LDAP_SUPPORT", + "KVM_SESSION_TIMEOUT", + "FIRMWARE_FLASH_SUPPORT", + "CPLD_SUPPORT", + "PTP_SERVER_SUPPORT", + "BOOTFW_SUPPORT", + "HOST_LOCK_AUTO", + "BACKUP_CONFIG", + "SET_SENSOR_THRESHOLDS_RESET", + "SAVE_SELLOG", + "SESSION_MANAGEMENT", + "RMEDIA_MULTI_CD_SUPPORT", + "TSIG", + "IPV6_COMPLIANCE", + "CD_SERVER_APP", + "WEB_DASHBOARD_WIDGETS", + "FOLDER_REDIRECTION", + "CIRCULAR_SEL", + "FW_IMAGE", + "DISABLE_EMPTY_PASSWORD", + "KB_LANG_SELECT_SUPPORT", + "DYNAMIC_KCS_LAN_SUPPORT", + "LMEDIA", + "DUAL_BOOTFW_EEPROM_SUPPORT", + "BLOCK_ICMP_TIMESTAMP", + "SINGLE_PORT_APP", + "MDNS", + "NCSI_SUPPORT", + "IMG_REDIRECTION", + "HD_SERVER_APP", + "PAM_REORDERING", + "EXTENDED_PRIV", + "SNMP", + "WEB_APP_PROXY", + "LMEDIA_MULTI_IMAGE_SUPPORT", + "VMEDIA_MAX_COUNT_FOR_KVM", + "MEDIA_REDIR_READ_WRITE_ONLY", + "RMEDIA_SESSION_RECONNECT", + "PRESERVECONF", + "TIMEZONE_SUPPORT", + "RMEDIA_MULTI_HD_SUPPORT", + "AUTOVDORECORD", + "YES", + "VERSION_CMP_FLASH", + "BMC_RECOVERY", + "NWLINK", + "KVM_OR_MEDIA_AVAILABLE", +] +// MEGARAC_UI_FEATURES_0_32_END + +fn megarac_ui_features(firmware: BmcFirmwareReleaseIdentity) -> List? { + if bmc_firmware_release_identity_eq(a: firmware, b: megarac_firmware_0_32) { Present { value: megarac_ui_features_0_32 } } else { none } +} + +// THE VALUE THE VENDOR STORES: the JSON array of {"feature": NAME} objects its collection serialises to. +fn megarac_ui_features_json(names: List) -> String { + serialize_json_array(elements: map(names, n => json_object(members: [json_kv(key: "feature", value: json_string(s: n as String))]))) +} diff --git a/dag/extdeps/exec/program.dag b/dag/extdeps/exec/program.dag index bbadd453771..12985ddfb3e 100644 --- a/dag/extdeps/exec/program.dag +++ b/dag/extdeps/exec/program.dag @@ -75,6 +75,7 @@ fn cataloged_program(invocation: NonEmptyStr) -> ProgramIdentity decl_ref(module_path: "extdeps.tools.wc", decl_name: "wc_program"), decl_ref(module_path: "extdeps.tools.nbdkit", decl_name: "nbdkit_program"), decl_ref(module_path: "extdeps.tools.sha512sum", decl_name: "sha512sum_program"), + decl_ref(module_path: "extdeps.tools.gzip", decl_name: "gzip_program"), decl_ref(module_path: "extdeps.tools.rustfmt", decl_name: "rustfmt_program"), decl_ref(module_path: "extdeps.tools.npm", decl_name: "npm_program"), decl_ref(module_path: "extdeps.tools.node", decl_name: "node_program"), diff --git a/dag/extdeps/tools/gzip.dag b/dag/extdeps/tools/gzip.dag new file mode 100644 index 00000000000..69a461d08c4 --- /dev/null +++ b/dag/extdeps/tools/gzip.dag @@ -0,0 +1,60 @@ +module extdeps.tools.gzip + +import extdeps.exec.program { ProgramIdentity, cataloged_program } +import std.types { Bool, Int, NonEmptyStr, Unit } +import std.string_type { String } +import std.decl_ref { DeclarationRef, WholeDeclaration } +import extdeps.external_authority { ExternalAuthority, ExternalModelScope, ExternalSubjectRef } +import extdeps.uri { Uri, Https } +import extdeps.tools { CliTool, SourceApt } + +// GNU gzip, as its manual documents it. +data extdeps_external_authority_anchor: ExternalAuthority = ExternalAuthority { + uri: Uri { + scheme: Https + locator: "www.gnu.org/software/gzip/manual/gzip.html" + } +} + +fn gzip_program() -> ProgramIdentity = cataloged_program(invocation: "gzip") + +data gzip_cli_tool: CliTool = CliTool { + program: gzip_program(), + min_version: none, + installable_via: [SourceApt { package: "gzip", bin_dir: "/usr/bin" }], +} + +data extdeps_model_scope: ExternalModelScope = ExternalModelScope { + subject: ExternalSubjectRef { + declaration: DeclarationRef { + module_path: "extdeps.tools.gzip", + decl_name: "gzip_cli_tool", + field: WholeDeclaration + } + }, + first_citation: extdeps.tools.gzip.extdeps_external_authority_anchor, + further_citations: [] +} + +// THE FILE'S CONTENT, DECODED IF IT IS GZIP AND UNCHANGED IF IT IS NOT: `--decompress --stdout --force`. +// The manual's --force: "If the input data is not in a format recognized by gzip, and if the option +// --stdout is also given, copy the input data without change to the standard output: let zcat behave as +// cat." So one read answers for a served file whether or not the server compressed it, and the file on +// disk is never modified (--stdout). +service gzip.Gzip { + operation DecodeToStdout { + input { path: NonEmptyStr } + output { + text: String from "stdout" + stderr: String from "stderr" + exit_code: Int from "exit_code" + success: Bool from "exit_success" + } + readonly + transport shell { argv: ["gzip", "--decompress", "--stdout", "--force", "{path}"] } + exit { + 0 => Unit + nonzero => String "gzip decode failed" + } + } +} diff --git a/dag/gunbc/bmc_megarac_web_transport.dag b/dag/gunbc/bmc_megarac_web_transport.dag index 4d54c0cff66..920cd3cc0ee 100644 --- a/dag/gunbc/bmc_megarac_web_transport.dag +++ b/dag/gunbc/bmc_megarac_web_transport.dag @@ -27,6 +27,9 @@ import gunbc.owned_process { // // The stand-in viewer page is narrower than the vendor's: a canvas#kvm painted from the /kvm stream // once a frame arrives, drawn from a cross-origin image when the world's canvas_readable flag is false. +// The stand-in viewer reads sessionStorage.features.indexOf(...) UNGUARDED before it opens /kvm, as the +// served viewer.min.js does: a viewer opened without the feature list throws and never connects, which +// is what KVM probe run 36788605665 did on the hardware. // The stand-in root page replaces itself on DOMContentLoaded and the transport logs that it was served: // the shape that destroyed the observer's in-page login on fleet-converge run 36721915217. An observer // that loads "/" and then evaluates in it fails here exactly as it did there. @@ -44,7 +47,7 @@ data megarac_web_transport_scaffold: Disposition = Scaffold { data megarac_web_transport_dissolution_trigger: DissolutionCondition = unbound_dissolution(description: "🟡 dissolve-on: gunbc.bmc_megarac_web_transport megarac_web_transport_script -- the loopback HTTP+WebSocket transport is a node -e string that enforces a model-derived transition table. RETIRED BY THE CAPABILITY: gunbc serve WebSocket support SUFFICIENT TO SERVE THE gunbc.bmc_model KVM STREAM -- accept the /kvm upgrade, hold the connection across requests, deliver frames, and close it when a model transition leaves the stream closed, with every HTTP and upgrade request decoded, answered by the gunbc.bmc_model transition and encoded in .dag per request. HTTP-only serve support does not retire it. Admission: operator escalation msg_d5eebfff, default-approved on recommendation A, 2026-09-28") -data megarac_web_transport_script: String = "const http=require('http');const crypto=require('crypto');const fs=require('fs');const [tablePath,logPath]=process.argv.slice(1);function log(m)\{fs.appendFileSync(logPath,Date.now()+' pid='+process.pid+' '+m+'\\n')}const T=JSON.parse(fs.readFileSync(tablePath,'utf8'));let current=T.initial;const canvasReadable=T.canvas_readable===true;const kvmPath=T.kvm_path;function key(op,args)\{return JSON.stringify([op].concat(args))}const rows=new Map();const advances=new Set();for(const r of T.rows)\{const k=r.from+'\\u0000'+key(r.request.op,r.request.args);if(rows.has(k))\{log('refused: duplicate table row '+JSON.stringify(k));process.exit(3)}rows.set(k,\{status:r.status,stream:r.stream_open?'open':'none',to:r.to,body:r.body});if(r.request.op==='advance')advances.add(+r.request.args[0])}let selfStart='unknown';try\{const st=fs.readFileSync('/proc/self/stat','utf8');selfStart=st.slice(st.lastIndexOf(')')+2).split(' ')[19]}catch(e)\{}let socket=null;function apply(k)\{const r=rows.get(current+'\\u0000'+k);if(!r)\{log('unmodeled state='+JSON.stringify(current)+' request='+k);return null} log('transition request='+k+' status='+r.status+' to='+JSON.stringify(r.to));current=r.to; if(socket&&r.stream!=='open')\{log('stream closed by the model');const s=socket;socket=null;s.destroy()}return r}const png=Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==','base64');const img=http.createServer((q,r)=>\{r.writeHead(200,\{'Content-Type':'image/png'});r.end(png)});function viewer()\{const port2=img.address().port;const taint=canvasReadable?'':\"const i=new Image();i.onload=()=>x.drawImage(i,0,0);i.src='http://localhost:\"+port2+\"/x.png';\"; return \"\"}function refuse(r,key)\{r.writeHead(599,\{'Content-Type':'text/plain'});r.end('unmodeled request: '+key)}function answer(r,key)\{const t=apply(key);if(!t)return refuse(r,key);r.writeHead(t.status,\{'Content-Type':'application/json'});r.end(t.body)}const s=http.createServer((q,r)=>\{let body='';q.on('data',d=>body+=d);q.on('end',()=>\{ if(q.url==='/')\{log('spa-root served');r.writeHead(200,\{'Content-Type':'text/html'});r.end(\"\");return} if(q.url==='/login.html')\{r.writeHead(200,\{'Content-Type':'text/html'});r.end('');return} if(q.url==='/viewer.html')\{r.writeHead(200,\{'Content-Type':'text/html'});r.end(viewer());return} if(q.url==='/api/session'&&q.method==='POST')\{const p=new URLSearchParams(body);return answer(r,key('login',[p.get('username')||'',p.get('password')||'']))} if(q.url==='/api/session'&&q.method==='DELETE')\{return answer(r,key('logout',[q.headers['x-csrftoken']||'']))} if(q.url==='/api/settings/services')\{return answer(r,key('services',[]))} r.writeHead(404);r.end()})});s.on('upgrade',(q,sock)=>\{const u=new URL(q.url,'http://x');if(u.pathname!==kvmPath)\{sock.destroy();return} const t=apply(key('connect',[u.searchParams.get('token')||'']));if(!t||t.status!==101)\{log('kvm refused');sock.destroy();return} const k=crypto.createHash('sha1').update(q.headers['sec-websocket-key']+'258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest('base64'); sock.write('HTTP/1.1 101 Switching Protocols\\r\\nUpgrade: websocket\\r\\nConnection: Upgrade\\r\\nSec-WebSocket-Accept: '+k+'\\r\\n\\r\\n'); sock.write(Buffer.from([0x81,0x05,0x66,0x72,0x61,0x6d,0x65]));socket=sock;log('kvm-open');sock.on('close',()=>\{if(socket===sock)socket=null})});const started=Date.now();for(const a of advances)\{setTimeout(()=>apply(key('advance',[String(a)])),a*1000)}img.listen(0,'127.0.0.1',()=>s.listen(0,'127.0.0.1',()=>log('listening start='+selfStart+' port='+s.address().port)));" +data megarac_web_transport_script: String = "const http=require('http');const crypto=require('crypto');const fs=require('fs');const [tablePath,logPath]=process.argv.slice(1);function log(m)\{fs.appendFileSync(logPath,Date.now()+' pid='+process.pid+' '+m+'\\n')}const T=JSON.parse(fs.readFileSync(tablePath,'utf8'));let current=T.initial;const canvasReadable=T.canvas_readable===true;const kvmPath=T.kvm_path;function key(op,args)\{return JSON.stringify([op].concat(args))}const rows=new Map();const advances=new Set();for(const r of T.rows)\{const k=r.from+'\\u0000'+key(r.request.op,r.request.args);if(rows.has(k))\{log('refused: duplicate table row '+JSON.stringify(k));process.exit(3)}rows.set(k,\{status:r.status,stream:r.stream_open?'open':'none',to:r.to,body:r.body});if(r.request.op==='advance')advances.add(+r.request.args[0])}let selfStart='unknown';try\{const st=fs.readFileSync('/proc/self/stat','utf8');selfStart=st.slice(st.lastIndexOf(')')+2).split(' ')[19]}catch(e)\{}let socket=null;function apply(k)\{const r=rows.get(current+'\\u0000'+k);if(!r)\{log('unmodeled state='+JSON.stringify(current)+' request='+k);return null} log('transition request='+k+' status='+r.status+' to='+JSON.stringify(r.to));current=r.to; if(socket&&r.stream!=='open')\{log('stream closed by the model');const s=socket;socket=null;s.destroy()}return r}const png=Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==','base64');const img=http.createServer((q,r)=>\{r.writeHead(200,\{'Content-Type':'image/png'});r.end(png)});function viewer()\{const port2=img.address().port;const taint=canvasReadable?'':\"const i=new Image();i.onload=()=>x.drawImage(i,0,0);i.src='http://localhost:\"+port2+\"/x.png';\"; return \"\"}function refuse(r,key)\{r.writeHead(599,\{'Content-Type':'text/plain'});r.end('unmodeled request: '+key)}function answer(r,key)\{const t=apply(key);if(!t)return refuse(r,key);r.writeHead(t.status,\{'Content-Type':'application/json'});r.end(t.body)}const s=http.createServer((q,r)=>\{let body='';q.on('data',d=>body+=d);q.on('end',()=>\{ if(q.url==='/')\{log('spa-root served');r.writeHead(200,\{'Content-Type':'text/html'});r.end(\"\");return} if(q.url==='/login.html')\{r.writeHead(200,\{'Content-Type':'text/html'});r.end('');return} if(q.url==='/viewer.html')\{r.writeHead(200,\{'Content-Type':'text/html'});r.end(viewer());return} if(q.url==='/api/session'&&q.method==='POST')\{const p=new URLSearchParams(body);return answer(r,key('login',[p.get('username')||'',p.get('password')||'']))} if(q.url==='/api/session'&&q.method==='DELETE')\{return answer(r,key('logout',[q.headers['x-csrftoken']||'']))} if(q.url==='/api/settings/services')\{return answer(r,key('services',[]))} r.writeHead(404);r.end()})});s.on('upgrade',(q,sock)=>\{const u=new URL(q.url,'http://x');if(u.pathname!==kvmPath)\{sock.destroy();return} const t=apply(key('connect',[u.searchParams.get('token')||'']));if(!t||t.status!==101)\{log('kvm refused');sock.destroy();return} const k=crypto.createHash('sha1').update(q.headers['sec-websocket-key']+'258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest('base64'); sock.write('HTTP/1.1 101 Switching Protocols\\r\\nUpgrade: websocket\\r\\nConnection: Upgrade\\r\\nSec-WebSocket-Accept: '+k+'\\r\\n\\r\\n'); sock.write(Buffer.from([0x81,0x05,0x66,0x72,0x61,0x6d,0x65]));socket=sock;log('kvm-open');sock.on('close',()=>\{if(socket===sock)socket=null})});const started=Date.now();for(const a of advances)\{setTimeout(()=>apply(key('advance',[String(a)])),a*1000)}img.listen(0,'127.0.0.1',()=>s.listen(0,'127.0.0.1',()=>log('listening start='+selfStart+' port='+s.address().port)));" // WHETHER THE TRANSPORT IS SERVING, AND IF NOT WHY. Readiness is bound to the whole launch INSTANCE: // only a listening line carrying BOTH the pid and the start time the owned launch recorded counts, so a diff --git a/dag/gunbc/machine_intake/megarac_served_ui_catalog_observation.dag b/dag/gunbc/machine_intake/megarac_served_ui_catalog_observation.dag index 95116b93386..7ca4de82657 100644 --- a/dag/gunbc/machine_intake/megarac_served_ui_catalog_observation.dag +++ b/dag/gunbc/machine_intake/megarac_served_ui_catalog_observation.dag @@ -11,3 +11,9 @@ import std.types { NonEmptyStr } data megarac_spx_ui_surface_path: NonEmptyStr = "artifacts/bmc/mtcollins1-megarac-api-surface.txt" as NonEmptyStr data megarac_spx_ui_surface_sha256: NonEmptyStr = "4fc53fea3fe49bc3ed3b967511654223578d59d963546117ab524df11b419bcd" as NonEmptyStr + +// THE 2026-09-27 READ OF THE BUNDLE ITSELF, as its digest. extdeps.bmc.megarac cites this read for the +// screen-capture surfaces and the KVM wire; the bytes were not committed, so the digest is what a later +// read is compared with. gunbc.machine_intake_megarac_ui_features reads the viewer feature list only +// out of bytes that digest to it. +data megarac_source_min_js_sha256_2026_09_27: NonEmptyStr = "5029fae278f7fc8f4dd4ad5eb8e4457e49fa25d4d0158d4bf9fbab09f57d4bf3" as NonEmptyStr diff --git a/dag/gunbc/machine_intake/megarac_ui_features.dag b/dag/gunbc/machine_intake/megarac_ui_features.dag new file mode 100644 index 00000000000..7edffbaebb7 --- /dev/null +++ b/dag/gunbc/machine_intake/megarac_ui_features.dag @@ -0,0 +1,112 @@ +module gunbc.machine_intake_megarac_ui_features + +import extdeps.tools.sha256sum +import extdeps.tools.gzip +import std.algebra { trim } +import std.types { Bool, FilePath, Int, List, NonEmptyStr, String } +import v2.std.optional { Present, Absent } +import std.process { ExitSuccess, ProcessExit, exit_failure } +import extdeps.filesystem.filesystem_io { Filesystem } +import gunbc.machine_intake_megarac_served_ui_catalog_observation { megarac_source_min_js_sha256_2026_09_27 } + +// THE FEATURE LIST THE VENDOR UI HANDS ITS KVM VIEWER, READ FROM THE UI'S OWN BYTES (eager-owl-205, +// 2026-09-30; operator rule: derived, never hand-typed). The served viewer.min.js (fleet-converge crawl +// run 36787375313) initialises its KVM view with UNGUARDED sessionStorage.features.indexOf(...) reads +// (KVM_SESSION_RECONNECT, VMEDIA_MAX_COUNT_FOR_KVM, HOST_CURSOR_ENABLED_DEFAULT): with `features` unset +// it throws, the view never initialises, and /kvm is never opened -- KVM probe run 36788605665 journalled +// exactly that page error and no WebSocket. The real UI stores JSON.stringify of its +// project-configurations collection, which is seeded from the STATIC `features` module compiled into +// source.min.js: +// o("features",[],function(){var e=[{feature:"RMEDIA_MULTI_IMAGE_SUPPORT"},...];return e}) +// so the list is parsed out of those bytes, and only out of the build this unit's facts are keyed on: +// the served source.min.js must digest to the 2026-09-27 read's sha256, or nothing is read. +// +// THE LIST IS A COMMITTED FIRMWARE-0.32 FACT (extdeps.bmc.megarac megarac_ui_features_0_32), not read at +// run time: it is the vendor's compiled-in list for that build, so it is emitted ONCE from the retained +// bytes by megarac_ui_features_row_emit below, and the observer seeds from the row. + +data megarac_ui_features_module_open: String = "o(\"features\",[],function()\{var e=[" + +data megarac_ui_features_module_close: String = "];return e}" + +data megarac_ui_feature_key: String = "feature:\"" + +// THE NAMES IN THE MODULE, IN ITS ORDER: every `feature:"NAME"` between the module's opening and its +// `];return e}`. Absent when the module is not in the text, or holds no name. +fn megarac_ui_features_of_bundle(text: String) -> List? { + match split(s: text, delimiter: megarac_ui_features_module_open).skip(n: 1).first() { + Absent => none + Present { value: after } => { + let body = match split(s: after, delimiter: megarac_ui_features_module_close).first() { Present { value: b } => b Absent => "" } + let names = map(split(s: body, delimiter: megarac_ui_feature_key).skip(n: 1), rest => match split(s: rest, delimiter: "\"").first() { Present { value: n } => n Absent => "" }) + if count(names) == 0 { none } else { Present { value: names } } + } + } +} + +// A FEATURE NAME IS THE VENDOR'S IDENTIFIER SHAPE: upper-case letters, digits and underscores, nonempty. +// Anything else is refused rather than written into a JSON string it could escape from. +data megarac_ui_feature_name_characters: String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_" + +fn megarac_ui_feature_name_admitted(name: String) -> Bool { + name != "" && all(split(s: name, delimiter: ""), c => c == "" || string_contains(s: megarac_ui_feature_name_characters, pattern: c)) +} + + +type MegaRacUiFeatures + = MegaRacUiFeaturesRead { names: List, source_sha256: NonEmptyStr } + | MegaRacUiFeaturesUnread { cause: NonEmptyStr } + +// THE READING FROM ALREADY-DECODED BUNDLE TEXT AND ITS DIGEST: refused unless the digest is the pinned +// build's and the module yields only admitted names. +fn megarac_ui_features_reading(observed_sha256: String, text: String) -> MegaRacUiFeatures { + if observed_sha256 != (megarac_source_min_js_sha256_2026_09_27 as String) { + MegaRacUiFeaturesUnread { cause: concat(concat("source.min.js digests to ", observed_sha256), concat(", not the pinned ", megarac_source_min_js_sha256_2026_09_27 as String)) as NonEmptyStr } + } else { + match megarac_ui_features_of_bundle(text: text) { + Absent => MegaRacUiFeaturesUnread { cause: "the features module was not found in source.min.js, or holds no name" } + Present { value: names } => + if all(names, n => megarac_ui_feature_name_admitted(name: n)) { + MegaRacUiFeaturesRead { names: names, source_sha256: megarac_source_min_js_sha256_2026_09_27 } + } else { + MegaRacUiFeaturesUnread { cause: concat("the features module holds a name outside the vendor identifier shape: ", join(filter(names, n => !megarac_ui_feature_name_admitted(name: n)), " ")) as NonEmptyStr } + } + } + } +} + +// THE ROW'S EMITTER (the entry extdeps.bmc.megarac megarac_ui_features_0_32 names): read a RETAINED +// source.min.js as served -- the mtcollins1-ui-bundle artifact of a crawl run -- refuse unless it +// digests to the pinned 2026-09-27 build, decode it, parse the features module, and write the +// extdeps row's text to `out`. Run: +// gunbc run --source-root dag --source-root src/v2 --entry dag/gunbc/machine_intake/megarac_ui_features.dag +// --function megarac_ui_features_row_emit --arg bundle= --arg out= +fn megarac_ui_features_row_text(names: List) -> String { + concat(concat("data megarac_ui_features_0_32: List = [\n", join(map(names, n => concat(concat(" \"", n), "\",")), "\n")), "\n]\n") +} + +fn megarac_ui_features_row_emit(bundle: String, out: String) -> ProcessExit { + let digest = sha256sum.Sha256.DigestFile(path: bundle as NonEmptyStr) + let observed = match split(s: trim(s: digest.line), delimiter: " ").first() { Present { value: d } => d Absent => "" } + if !digest.success || observed == "" { + return exit_failure(reason: concat("megarac ui features: the retained bundle could not be digested: ", digest.line)) + } + let decoded = gzip.Gzip.DecodeToStdout(path: bundle as NonEmptyStr) + if !decoded.success { + return exit_failure(reason: concat("megarac ui features: the retained bundle could not be decoded: ", trim(s: decoded.stderr))) + } + match megarac_ui_features_reading(observed_sha256: observed, text: decoded.text) { + MegaRacUiFeaturesUnread { cause: c } => exit_failure(reason: concat("megarac ui features: ", c as String)) + MegaRacUiFeaturesRead { names: n, source_sha256: _ } => { + let w = Filesystem.Write(path: out, content: megarac_ui_features_row_text(names: n)) + if w.success { ExitSuccess } else { exit_failure(reason: concat("megarac ui features: the row could not be written: ", w.error)) } + } + } +} + +fn megarac_ui_features_text(f: MegaRacUiFeatures) -> String { + match f { + MegaRacUiFeaturesRead { names: n, source_sha256: s } => join([to_string(count(n)), " features read from source.min.js sha256 ", s as String], "") + MegaRacUiFeaturesUnread { cause: c } => concat("features UNREAD: ", c as String) + } +} diff --git a/dag/gunbc/machine_intake/mtcollins1_kvm_still.dag b/dag/gunbc/machine_intake/mtcollins1_kvm_still.dag index f7f7caf8bec..da28901249d 100644 --- a/dag/gunbc/machine_intake/mtcollins1_kvm_still.dag +++ b/dag/gunbc/machine_intake/mtcollins1_kvm_still.dag @@ -16,6 +16,7 @@ import gunbc.runner_browser_toolchain { RunnerBrowserToolchainLocation, runner_browser_toolchain_node_command, runner_browser_toolchain_standing_text, } import extdeps.bmc.megarac { + megarac_ui_features, megarac_ui_features_json, ScreenCaptureFactKnown, ScreenCaptureFirmwareUncatalogued, ScreenCaptureClientSideOnly, KvmClientCanvasJpeg, megarac_screen_capture_standing, megarac_firmware_0_32, } @@ -96,6 +97,12 @@ data mtcollins1_bmc_firmware: BmcFirmwareReleaseIdentity = megarac_firmware_0_32 // that exists but cannot be read (toDataURL throws) is acquisition-failed cause=canvas-unreadable. An // unchanged picture is never read as a stale one: the observer does not compare pixels at all. // +// THE VIEWER NEEDS ITS FEATURE LIST (KVM probe run 36788605665). The served viewer.min.js reads +// sessionStorage.features.indexOf(...) unguarded in its KVM view's initialize(); with features unset it +// throws and never opens /kvm. The list is the firmware's own (extdeps.bmc.megarac megarac_ui_features, +// emitted from the served source.min.js); the launch writes it as features.json and the init script +// seeds sessionStorage.features from it. A firmware with no catalogued list is not driven. +// // THE SEAT. A held seat (viewer_count > 0) refuses with its count -- an operator's session is never // evicted -- and every exit the process reaches (stop file, SIGTERM, refusal, failure) DELETEs its web // session and closes the browser, journalling stopped session=. The @@ -153,9 +160,10 @@ data kvm_cause_credential_unreadable: KvmJournalWord = KvmJournalWord { id: "cre data kvm_cause_not_connected: KvmJournalWord = KvmJournalWord { id: "notConnected", word: "not-connected" } data kvm_cause_connection_changed_during_acquisition: KvmJournalWord = KvmJournalWord { id: "connectionChangedDuringAcquisition", word: "connection-changed-during-acquisition" } data kvm_cause_canvas_unreadable: KvmJournalWord = KvmJournalWord { id: "canvasUnreadable", word: "canvas-unreadable" } +data kvm_cause_features_unreadable: KvmJournalWord = KvmJournalWord { id: "featuresUnreadable", word: "features-unreadable" } data kvm_journal_event_words: List = [kvm_event_established, kvm_event_connection_requested, kvm_event_connection_refused, kvm_event_connection_open, kvm_event_connection_lost, kvm_event_connection_error, kvm_event_still, kvm_event_acquisition_failed, kvm_event_session_release, kvm_event_browser_close, kvm_event_refused, kvm_event_failed, kvm_event_stop_requested, kvm_event_stopped, kvm_event_trigger_scan_failed] -data kvm_journal_cause_words: List = [kvm_cause_seat_busy, kvm_cause_login, kvm_cause_no_kvm_service, kvm_cause_no_frame, kvm_cause_no_kvm_frame, kvm_cause_no_kvm_websocket, kvm_cause_toolchain, kvm_cause_credential_unreadable, kvm_cause_not_connected, kvm_cause_connection_changed_during_acquisition, kvm_cause_canvas_unreadable] +data kvm_journal_cause_words: List = [kvm_cause_seat_busy, kvm_cause_login, kvm_cause_no_kvm_service, kvm_cause_no_frame, kvm_cause_no_kvm_frame, kvm_cause_no_kvm_websocket, kvm_cause_toolchain, kvm_cause_credential_unreadable, kvm_cause_not_connected, kvm_cause_connection_changed_during_acquisition, kvm_cause_canvas_unreadable, kvm_cause_features_unreadable] // THE LINE LAYOUT, DECLARED ONCE PER EVENT: the key=value fields an event word carries, in the order // the observer script writes them. kvm_journal_event reads its fields through these rows and @@ -207,7 +215,7 @@ fn mtcollins1_kvm_observer_vocabulary_js() -> String { concat(kvm_journal_words_js(name: "EV", words: kvm_journal_event_words), kvm_journal_words_js(name: "CA", words: kvm_journal_cause_words)) } -data mtcollins1_kvm_observer_script_body: String = "const fs=require('fs');const path=require('path');const [base,user,pwFile,dir,attempt,cadenceMs,frameMs,maxPeriodic,pwModule]=process.argv.slice(1);const J=path.join(dir,'journal');function j(ev,kv)\{const t=Date.now();try\{fs.appendFileSync(J,t+' '+new Date(t).toISOString()+' '+ev+(kv?' '+kv:'')+'\\n')}catch(e)\{try\{process.stderr.write('journal write failed: '+ev+' '+String(e&&e.message)+'\\n')}catch(e2)\{}}}function one(e)\{return String(e&&e.message||e).replace(/[^ -~]+/g,' ').replace(/ +/g,' ').slice(0,300)}let browser=null,page=null,api=null,stopping=false,login='not-attempted',token=null,seq=0,periodic=0;let gen=0,live=null;async function teardown(why,code)\{if(stopping)return;stopping=true; j(EV.stopRequested,'by='+why); let rel; if(login==='accepted'&&api&&token)\{try\{const r=await api.delete(base+'/api/session',\{headers:\{'X-CSRFTOKEN':token}});rel=r.ok()?'released':'http-'+r.status()}catch(e)\{rel='release-failed detail='+JSON.stringify(one(e))}} else if(login==='unobserved')\{rel='login-unobserved'} else\{rel='no-session'} j(EV.sessionRelease,'result='+rel); let closed='closed';try\{if(browser)await browser.close();else closed='no-browser'}catch(e)\{closed='close-failed detail='+JSON.stringify(one(e))} j(EV.browserClose,'result='+closed); j(EV.stopped,'session='+rel.split(' ')[0]+' browser='+closed.split(' ')[0]); process.exit(code)}process.on('SIGTERM',()=>teardown('sigterm',0));process.on('SIGINT',()=>teardown('sigint',0));async function still(reason)\{seq+=1;const n=seq;const g=gen;const startedMs=Date.now(); if(!live||live.gen!==g)\{j(EV.acquisitionFailed,'seq='+n+' reason='+reason+' gen='+g+' cause='+CA.notConnected+'');return} try\{const url=await page.evaluate(()=>\{const c=document.getElementById('kvm');if(!c)throw new Error('no canvas#kvm');return c.toDataURL('image/jpeg')}); if(!live||live.gen!==g)\{j(EV.acquisitionFailed,'seq='+n+' reason='+reason+' gen='+g+' started_ms='+startedMs+' cause='+CA.connectionChangedDuringAcquisition+'');return} if(!url.startsWith('data:image/jpeg;base64,'))throw new Error('toDataURL answered '+url.slice(0,40)); const b=Buffer.from(url.slice(url.indexOf(',')+1),'base64');const f='still-'+n+'.jpg';fs.writeFileSync(path.join(dir,f),b); j(EV.still,'seq='+n+' reason='+reason+' gen='+g+' started_ms='+startedMs+' file='+f+' bytes='+b.length)} catch(e)\{j(EV.acquisitionFailed,'seq='+n+' reason='+reason+' gen='+g+' started_ms='+startedMs+' cause='+CA.canvasUnreadable+' detail='+JSON.stringify(one(e)))}}(async()=>\{ let pw;try\{pw=fs.readFileSync(pwFile,'utf8')}catch(e)\{j(EV.refused,'cause='+CA.credentialUnreadable+' detail='+JSON.stringify(one(e)));return teardown('refused',14)} let chromium;try\{chromium=require(pwModule).chromium}catch(e)\{j(EV.refused,'cause='+CA.toolchain+' detail='+JSON.stringify(one(e)));return teardown('refused',13)} try\{browser=await chromium.launch(\{headless:true})}catch(e)\{j(EV.refused,'cause='+CA.toolchain+' detail='+JSON.stringify(one(e)));return teardown('refused',13)} try\{const ctx=await browser.newContext(\{ignoreHTTPSErrors:true,viewport:\{width:1280,height:1024}});api=ctx.request;page=await ctx.newPage(); const expectedHost=new URL(base).host; login='unobserved'; const lr=await api.post(base+'/api/session',\{form:\{username:user,password:pw}});let lb=null;try\{lb=await lr.json()}catch(e)\{}const reply=\{status:lr.status(),b:lb}; if(reply.status!==200||!reply.b||reply.b.ok!==0)\{login='refused';j(EV.refused,'cause='+CA.login+' http='+reply.status);return teardown('refused',11)} login='accepted';token=reply.b.CSRFToken; await ctx.addInitScript(([h,b,u])=>\{if(location.host!==h)return;sessionStorage.setItem('garc',b.CSRFToken);sessionStorage.setItem('privilege_id',String(b.privilege));sessionStorage.setItem('extended_privilege',String(b.extendedpriv));sessionStorage.setItem('session_id',String(b.racsession_id));sessionStorage.setItem('username',u);sessionStorage.setItem('kvm_access','1');sessionStorage.setItem('vmedia_access','1')},[expectedHost,reply.b,user]); const sa=await(await api.get(base+'/api/settings/services',\{headers:\{'X-CSRFTOKEN':token}})).json();const kr=Array.isArray(sa)?sa.find(s=>s.service_name==='kvm'):null;const seat=kr?kr.viewer_count:null; if(seat===null||seat===undefined)\{j(EV.refused,'cause='+CA.noKvmService+'');return teardown('refused',15)} if(seat!==0)\{j(EV.refused,'cause='+CA.seatBusy+' viewer_count='+seat);return teardown('refused',10)} page.on('websocket',ws=>\{let u;try\{u=new URL(ws.url())}catch(e)\{return} if(u.host!==expectedHost||u.pathname!=='/kvm')return; j(EV.connectionRequested,'url='+JSON.stringify(ws.url()));let mine=null; ws.on('framereceived',()=>\{if(!mine)\{gen+=1;mine=\{gen:gen};live=mine;j(EV.connectionOpen,'gen='+mine.gen+' url='+JSON.stringify(ws.url()))}}); ws.on('socketerror',e=>\{j(EV.connectionError,'gen='+(mine?mine.gen:0)+' detail='+JSON.stringify(one(e)));if(mine&&live===mine)live=null}); ws.on('close',()=>\{if(mine&&live===mine)\{live=null;j(EV.connectionLost,'gen='+mine.gen)}else if(!mine)\{j(EV.connectionRefused,'url='+JSON.stringify(ws.url()))}})}); await page.goto(base+'/viewer.html',\{waitUntil:'domcontentloaded'}); try\{await page.waitForFunction(()=>\{const c=document.getElementById('kvm');return !!c&&c.width>1&&c.height>1},null,\{timeout:Number(frameMs)})} catch(e)\{j(EV.refused,'cause='+CA.noFrame+' detail='+JSON.stringify(one(e)));return teardown('refused',12)} const deadline=Date.now()+Number(frameMs);while(!live&&Date.now()setTimeout(r,100))} if(!live)\{j(EV.refused,'cause='+CA.noKvmFrame+'');return teardown('refused',12)} j(EV.established,'host='+JSON.stringify(expectedHost)+' session='+String(reply.b.racsession_id)+' attempt='+attempt+' gen='+live.gen); let next=Date.now()+Number(cadenceMs); while(!stopping)\{ if(fs.existsSync(path.join(dir,'stop')))\{return teardown('stop-file',0)} let tf=[];try\{tf=fs.readdirSync(dir).filter(n=>n.startsWith('trigger-')).sort()}catch(e)\{j(EV.triggerScanFailed,'detail='+JSON.stringify(one(e)))} for(const n of tf)\{const p=path.join(dir,n);try\{fs.unlinkSync(p)}catch(e)\{continue}await still('trigger:'+n.slice(8))} if(Date.now()>=next&&periodicsetTimeout(r,250))} }catch(e)\{j(EV.failed,'detail='+JSON.stringify(one(e)));return teardown('failed',1)}})();" +data mtcollins1_kvm_observer_script_body: String = "const fs=require('fs');const path=require('path');const [base,user,pwFile,dir,attempt,cadenceMs,frameMs,maxPeriodic,pwModule,featuresFile]=process.argv.slice(1);const J=path.join(dir,'journal');function j(ev,kv)\{const t=Date.now();try\{fs.appendFileSync(J,t+' '+new Date(t).toISOString()+' '+ev+(kv?' '+kv:'')+'\\n')}catch(e)\{try\{process.stderr.write('journal write failed: '+ev+' '+String(e&&e.message)+'\\n')}catch(e2)\{}}}function one(e)\{return String(e&&e.message||e).replace(/[^ -~]+/g,' ').replace(/ +/g,' ').slice(0,300)}let browser=null,page=null,api=null,stopping=false,login='not-attempted',token=null,seq=0,periodic=0;let gen=0,live=null;async function teardown(why,code)\{if(stopping)return;stopping=true; j(EV.stopRequested,'by='+why); let rel; if(login==='accepted'&&api&&token)\{try\{const r=await api.delete(base+'/api/session',\{headers:\{'X-CSRFTOKEN':token}});rel=r.ok()?'released':'http-'+r.status()}catch(e)\{rel='release-failed detail='+JSON.stringify(one(e))}} else if(login==='unobserved')\{rel='login-unobserved'} else\{rel='no-session'} j(EV.sessionRelease,'result='+rel); let closed='closed';try\{if(browser)await browser.close();else closed='no-browser'}catch(e)\{closed='close-failed detail='+JSON.stringify(one(e))} j(EV.browserClose,'result='+closed); j(EV.stopped,'session='+rel.split(' ')[0]+' browser='+closed.split(' ')[0]); process.exit(code)}process.on('SIGTERM',()=>teardown('sigterm',0));process.on('SIGINT',()=>teardown('sigint',0));async function still(reason)\{seq+=1;const n=seq;const g=gen;const startedMs=Date.now(); if(!live||live.gen!==g)\{j(EV.acquisitionFailed,'seq='+n+' reason='+reason+' gen='+g+' cause='+CA.notConnected+'');return} try\{const url=await page.evaluate(()=>\{const c=document.getElementById('kvm');if(!c)throw new Error('no canvas#kvm');return c.toDataURL('image/jpeg')}); if(!live||live.gen!==g)\{j(EV.acquisitionFailed,'seq='+n+' reason='+reason+' gen='+g+' started_ms='+startedMs+' cause='+CA.connectionChangedDuringAcquisition+'');return} if(!url.startsWith('data:image/jpeg;base64,'))throw new Error('toDataURL answered '+url.slice(0,40)); const b=Buffer.from(url.slice(url.indexOf(',')+1),'base64');const f='still-'+n+'.jpg';fs.writeFileSync(path.join(dir,f),b); j(EV.still,'seq='+n+' reason='+reason+' gen='+g+' started_ms='+startedMs+' file='+f+' bytes='+b.length)} catch(e)\{j(EV.acquisitionFailed,'seq='+n+' reason='+reason+' gen='+g+' started_ms='+startedMs+' cause='+CA.canvasUnreadable+' detail='+JSON.stringify(one(e)))}}(async()=>\{ let pw;try\{pw=fs.readFileSync(pwFile,'utf8')}catch(e)\{j(EV.refused,'cause='+CA.credentialUnreadable+' detail='+JSON.stringify(one(e)));return teardown('refused',14)} let chromium;try\{chromium=require(pwModule).chromium}catch(e)\{j(EV.refused,'cause='+CA.toolchain+' detail='+JSON.stringify(one(e)));return teardown('refused',13)} try\{browser=await chromium.launch(\{headless:true})}catch(e)\{j(EV.refused,'cause='+CA.toolchain+' detail='+JSON.stringify(one(e)));return teardown('refused',13)} try\{const ctx=await browser.newContext(\{ignoreHTTPSErrors:true,viewport:\{width:1280,height:1024}});api=ctx.request;page=await ctx.newPage(); const expectedHost=new URL(base).host; login='unobserved'; const lr=await api.post(base+'/api/session',\{form:\{username:user,password:pw}});let lb=null;try\{lb=await lr.json()}catch(e)\{}const reply=\{status:lr.status(),b:lb}; if(reply.status!==200||!reply.b||reply.b.ok!==0)\{login='refused';j(EV.refused,'cause='+CA.login+' http='+reply.status);return teardown('refused',11)} login='accepted';token=reply.b.CSRFToken; let feats='';if(featuresFile)\{try\{feats=fs.readFileSync(featuresFile,'utf8')}catch(e)\{j(EV.refused,'cause='+CA.featuresUnreadable+' detail='+JSON.stringify(one(e)));return teardown('refused',14)}} await ctx.addInitScript(([h,b,u,f])=>\{if(location.host!==h)return;if(f)sessionStorage.setItem('features',f);sessionStorage.setItem('garc',b.CSRFToken);sessionStorage.setItem('privilege_id',String(b.privilege));sessionStorage.setItem('extended_privilege',String(b.extendedpriv));sessionStorage.setItem('session_id',String(b.racsession_id));sessionStorage.setItem('username',u);sessionStorage.setItem('kvm_access','1');sessionStorage.setItem('vmedia_access','1')},[expectedHost,reply.b,user,feats]); const sa=await(await api.get(base+'/api/settings/services',\{headers:\{'X-CSRFTOKEN':token}})).json();const kr=Array.isArray(sa)?sa.find(s=>s.service_name==='kvm'):null;const seat=kr?kr.viewer_count:null; if(seat===null||seat===undefined)\{j(EV.refused,'cause='+CA.noKvmService+'');return teardown('refused',15)} if(seat!==0)\{j(EV.refused,'cause='+CA.seatBusy+' viewer_count='+seat);return teardown('refused',10)} page.on('websocket',ws=>\{let u;try\{u=new URL(ws.url())}catch(e)\{return} if(u.host!==expectedHost||u.pathname!=='/kvm')return; j(EV.connectionRequested,'url='+JSON.stringify(ws.url()));let mine=null; ws.on('framereceived',()=>\{if(!mine)\{gen+=1;mine=\{gen:gen};live=mine;j(EV.connectionOpen,'gen='+mine.gen+' url='+JSON.stringify(ws.url()))}}); ws.on('socketerror',e=>\{j(EV.connectionError,'gen='+(mine?mine.gen:0)+' detail='+JSON.stringify(one(e)));if(mine&&live===mine)live=null}); ws.on('close',()=>\{if(mine&&live===mine)\{live=null;j(EV.connectionLost,'gen='+mine.gen)}else if(!mine)\{j(EV.connectionRefused,'url='+JSON.stringify(ws.url()))}})}); await page.goto(base+'/viewer.html',\{waitUntil:'domcontentloaded'}); try\{await page.waitForFunction(()=>\{const c=document.getElementById('kvm');return !!c&&c.width>1&&c.height>1},null,\{timeout:Number(frameMs)})} catch(e)\{j(EV.refused,'cause='+CA.noFrame+' detail='+JSON.stringify(one(e)));return teardown('refused',12)} const deadline=Date.now()+Number(frameMs);while(!live&&Date.now()setTimeout(r,100))} if(!live)\{j(EV.refused,'cause='+CA.noKvmFrame+'');return teardown('refused',12)} j(EV.established,'host='+JSON.stringify(expectedHost)+' session='+String(reply.b.racsession_id)+' attempt='+attempt+' gen='+live.gen); let next=Date.now()+Number(cadenceMs); while(!stopping)\{ if(fs.existsSync(path.join(dir,'stop')))\{return teardown('stop-file',0)} let tf=[];try\{tf=fs.readdirSync(dir).filter(n=>n.startsWith('trigger-')).sort()}catch(e)\{j(EV.triggerScanFailed,'detail='+JSON.stringify(one(e)))} for(const n of tf)\{const p=path.join(dir,n);try\{fs.unlinkSync(p)}catch(e)\{continue}await still('trigger:'+n.slice(8))} if(Date.now()>=next&&periodicsetTimeout(r,250))} }catch(e)\{j(EV.failed,'detail='+JSON.stringify(one(e)));return teardown('failed',1)}})();" data mtcollins1_kvm_observer_script: String = concat(mtcollins1_kvm_observer_vocabulary_js(), mtcollins1_kvm_observer_script_body) @@ -769,7 +777,11 @@ fn mtcollins1_kvm_observer_start( else if attempt == "" { KvmObserverNotStarted { reason: "no attempt identity is bound, so the observer could not be named for it" } } else { match toolchain { - BrowserToolchainReady { location: loc, standing: _ } => kvm_observer_launch(base_url: concat("https://", bmc_host as String), host: bmc_host as String, username: username, password_file: password_file, toolchain: loc, attempt: attempt) + BrowserToolchainReady { location: loc, standing: _ } => + match megarac_ui_features(firmware: firmware) { + Absent => KvmObserverNotStarted { reason: "no viewer feature list is catalogued for this firmware (extdeps.bmc.megarac megarac_ui_features), and the viewer's KVM view reads it unguarded; no viewer was driven" } + Present { value: names } => kvm_observer_launch(base_url: concat("https://", bmc_host as String), host: bmc_host as String, username: username, password_file: password_file, toolchain: loc, attempt: attempt, features_json: megarac_ui_features_json(names: names)) + } BrowserToolchainNotReady { standing: st } => KvmObserverNotStarted { reason: concat("the runner browser toolchain is not ready: ", runner_browser_toolchain_standing_text(s: st)) as NonEmptyStr } BrowserToolchainUnresolved { cause: c } => KvmObserverNotStarted { reason: concat("the runner browser toolchain is unresolved: ", c) as NonEmptyStr } } @@ -781,13 +793,13 @@ fn mtcollins1_kvm_observer_start( // THE LAUNCH OVER A BASE URL. The boot passes https://; the protocol controls pass a local // transport. `host` is the host:port the established line must name. -fn kvm_observer_launch(base_url: String, host: String, username: NonEmptyStr, password_file: String, toolchain: RunnerBrowserToolchainLocation, attempt: String) -> KvmObserverStart { +fn kvm_observer_launch(base_url: String, host: String, username: NonEmptyStr, password_file: String, toolchain: RunnerBrowserToolchainLocation, attempt: String, features_json: String) -> KvmObserverStart { let dir = mtcollins1_kvm_observer_dir(attempt: attempt) let made = shell.Mkdir.Parents(path: dir as FilePath) if !made.success { return KvmObserverNotStarted { reason: concat("the observer directory could not be made: ", dir) as NonEmptyStr } } - kvm_observer_launch_in(dir_given: dir, base_url: base_url, host: host, username: username, password_file: password_file, toolchain: toolchain, attempt: attempt) + kvm_observer_launch_in(dir_given: dir, base_url: base_url, host: host, username: username, password_file: password_file, toolchain: toolchain, attempt: attempt, features_json: features_json) } // ONE ABSOLUTE LOCATION (hold on gunbc#12492): the directory is canonicalised once, here, and that @@ -795,12 +807,16 @@ fn kvm_observer_launch(base_url: String, host: String, username: NonEmptyStr, pa // reads the journal, stills and triggers from and writes the stop request to. A relative directory // passed as both working directory and operand would be resolved twice -- //journal -- and the // boot and the observer would address different files. -fn kvm_observer_launch_in(dir_given: String, base_url: String, host: String, username: NonEmptyStr, password_file: String, toolchain: RunnerBrowserToolchainLocation, attempt: String) -> KvmObserverStart { +fn kvm_observer_launch_in(dir_given: String, base_url: String, host: String, username: NonEmptyStr, password_file: String, toolchain: RunnerBrowserToolchainLocation, attempt: String, features_json: String) -> KvmObserverStart { let resolved = shell.Path.Canonical(path: dir_given as FilePath) if !resolved.success { return KvmObserverNotStarted { reason: concat("the observer directory could not be resolved: ", concat(dir_given, concat(": ", trim(s: resolved.stderr)))) as NonEmptyStr } } let dir = trim(s: resolved.stdout) + let features_path = concat(dir, "/features.json") + if features_json != "" && !Filesystem.Write(path: features_path, content: features_json).success { + return KvmObserverNotStarted { reason: concat("the viewer feature list could not be written: ", features_path) as NonEmptyStr } + } let node = runner_browser_toolchain_node_command( location: toolchain, directory: dir, @@ -811,6 +827,7 @@ fn kvm_observer_launch_in(dir_given: String, base_url: String, host: String, use to_string(millisecond_count(m: second_to_millisecond(s: mtcollins1_kvm_observer_frame_wait)) as Int), to_string(mtcollins1_kvm_observer_periodic_limit), toolchain.playwright_module as String, + if features_json == "" { "" } else { features_path }, ], ) let launched = gunbc.owned_process.launch.LaunchOwned(pid_path: concat(dir, "/observer.pid") as NonEmptyStr, log_path: concat(dir, "/observer.log") as NonEmptyStr, command: argv_words(command: node)) diff --git a/dag/test/claim/machine_intake/megarac_ui_features_witness_test.dag b/dag/test/claim/machine_intake/megarac_ui_features_witness_test.dag new file mode 100644 index 00000000000..fdd74175b27 --- /dev/null +++ b/dag/test/claim/machine_intake/megarac_ui_features_witness_test.dag @@ -0,0 +1,66 @@ +module test.claim.machine_intake.megarac_ui_features_witness_test + +import std.types { Bool, List, NonEmptyStr, String } +import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } +import v2.std.optional { Present, Absent } +import v2.std.algebra { any } +import extdeps.bmc.megarac { megarac_ui_features_0_32, megarac_ui_features, megarac_ui_features_json, megarac_firmware_0_32 } +import extdeps.bmc.capability { bmc_firmware_release_identity_of_wire } +import extdeps.bmc.endpoint { AmiMegaRac } +import gunbc.machine_intake_megarac_served_ui_catalog_observation { megarac_source_min_js_sha256_2026_09_27 } +import gunbc.machine_intake_megarac_ui_features { + MegaRacUiFeatures, MegaRacUiFeaturesRead, MegaRacUiFeaturesUnread, + megarac_ui_features_of_bundle, megarac_ui_feature_name_admitted, megarac_ui_features_reading, megarac_ui_features_row_text, +} + +data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly + +// The module as source.min.js 0.32 spells it (run 36778446928's bytes), abbreviated to three entries, +// between the neighbouring modules so the parse is held to its own boundaries. +data bundle_fragment: String = "o(\"x\",[],function()\{return 1}),o(\"features\",[],function()\{var e=[\{feature:\"RMEDIA_MULTI_IMAGE_SUPPORT\"},\{feature:\"KVM_SESSION_RECONNECT\"},\{feature:\"HTML5_KVM\"}];return e}),o(\"collection/project-configurations\",[\"jquery\"],function()\{var q=\{feature:\"NOT_IN_THE_MODULE\"}})" + +test fn the_features_module_yields_its_names_in_order_and_nothing_outside_it() -> Bool { + match megarac_ui_features_of_bundle(text: bundle_fragment) { + Present { value: names } => names == ["RMEDIA_MULTI_IMAGE_SUPPORT", "KVM_SESSION_RECONNECT", "HTML5_KVM"] + Absent => false + } +} + +test fn a_bundle_without_the_module_yields_nothing() -> Bool { + match megarac_ui_features_of_bundle(text: "o(\"collection/project-configurations\",[],function()\{})") { Absent => true Present { value: _ } => false } +} + +// THE PIN: bytes that are not the 2026-09-27 build are not read, however well they parse. +test fn only_the_pinned_build_is_read() -> Bool { + (match megarac_ui_features_reading(observed_sha256: megarac_source_min_js_sha256_2026_09_27 as String, text: bundle_fragment) { MegaRacUiFeaturesRead { names: n, source_sha256: _ } => n == ["RMEDIA_MULTI_IMAGE_SUPPORT", "KVM_SESSION_RECONNECT", "HTML5_KVM"] _ => false }) + && (match megarac_ui_features_reading(observed_sha256: "0000000000000000000000000000000000000000000000000000000000000000", text: bundle_fragment) { MegaRacUiFeaturesUnread { cause: c } => string_contains(s: c as String, pattern: "not the pinned") _ => false }) +} + +// A NAME OUTSIDE THE VENDOR IDENTIFIER SHAPE IS REFUSED, so nothing can escape the JSON it is written into. +test fn a_name_outside_the_identifier_shape_is_refused() -> Bool { + megarac_ui_feature_name_admitted(name: "HTML5_KVM") + && !megarac_ui_feature_name_admitted(name: "") + && !megarac_ui_feature_name_admitted(name: "a\"b") + && !megarac_ui_feature_name_admitted(name: "lower") + && (match megarac_ui_features_reading(observed_sha256: megarac_source_min_js_sha256_2026_09_27 as String, text: "o(\"features\",[],function()\{var e=[\{feature:\"OK_ONE\"},\{feature:\"bad name\"}];return e}") { MegaRacUiFeaturesUnread { cause: c } => string_contains(s: c as String, pattern: "bad name") _ => false }) +} + +// THE EMITTED ROW IS THE FILE'S TEXT FOR THE NAMES, and the committed 0.32 row is that emission: every +// name in the vendor shape, the names the viewer reads among them. +test fn the_committed_row_holds_the_names_the_viewer_reads() -> Bool { + let names = map(megarac_ui_features_0_32, n => n as String) + count(names) > 0 + && all(names, n => megarac_ui_feature_name_admitted(name: n)) + && any(names, n => n == "KVM_SESSION_RECONNECT") + && any(names, n => n == "HTML5_KVM") + && string_contains(s: megarac_ui_features_row_text(names: ["A_B", "C"]), pattern: "data megarac_ui_features_0_32: List = [\n \"A_B\",\n \"C\",\n]") +} + +// THE STORED VALUE AND ITS FIRMWARE KEY: the vendor's JSON shape -- the same value JSON.stringify +// writes, in the canonical emitter's spacing, which the viewer's indexOf reads and any JSON reader are +// indifferent to -- and a list only for the 0.32 build. +test fn the_stored_value_is_the_vendor_shape_and_only_0_32_has_one() -> Bool { + megarac_ui_features_json(names: ["A_B" as NonEmptyStr, "C" as NonEmptyStr]) == "[\{\"feature\": \"A_B\"}, \{\"feature\": \"C\"}]" + && (match megarac_ui_features(firmware: megarac_firmware_0_32) { Present { value: l } => count(l) == count(megarac_ui_features_0_32) Absent => false }) + && (match megarac_ui_features(firmware: bmc_firmware_release_identity_of_wire(family: AmiMegaRac, wire: "0.33")) { Absent => true Present { value: _ } => false }) +} diff --git a/dag/test/claim/machine_intake/mtcollins1_kvm_observer_protocol_wet_witness_test.dag b/dag/test/claim/machine_intake/mtcollins1_kvm_observer_protocol_wet_witness_test.dag index 05d1b315f8f..dfe282ce224 100644 --- a/dag/test/claim/machine_intake/mtcollins1_kvm_observer_protocol_wet_witness_test.dag +++ b/dag/test/claim/machine_intake/mtcollins1_kvm_observer_protocol_wet_witness_test.dag @@ -32,6 +32,7 @@ import gunbc.machine_intake_mtcollins1_kvm_still { kvm_observer_launch_in, kvm_observer_trigger, kvm_handoff_admission, kvm_observer_standing_now, mtcollins1_kvm_observer_finish, } import gunbc.machine_intake_mtcollins1_boot_run { mtcollins1_boot_screen_boundary_report } +import extdeps.bmc.megarac { megarac_ui_features_json } // PROCESS-AND-PROTOCOL EVIDENCE, NOT HARDWARE EVIDENCE (eager-owl-205, 2026-09-28). Each control runs // the REAL held observer -- the same kvm_observer_launch_in, triggers, handoff admission and @@ -89,6 +90,16 @@ fn read_or_empty(path: String) -> String { // Serve the model's table on loopback, write the credential, and launch the real observer at it. fn rig(w: BmcWorld) -> Rig { + rig_with(w: w, features_json: loopback_features_json()) +} + +// THE FEATURE LIST THE LOOPBACK VIEWER NEEDS: the vendor shape (extdeps.bmc.megarac +// megarac_ui_features_json) over the one name the stand-in viewer reads. +fn loopback_features_json() -> String { + megarac_ui_features_json(names: ["KVM_SESSION_RECONNECT" as NonEmptyStr]) +} + +fn rig_with(w: BmcWorld, features_json: String) -> Rig { let dir = scratch_dir() let pw_path = concat(dir, "/credential") let _pw = Filesystem.Write(path: pw_path, content: "pw") @@ -101,7 +112,7 @@ fn rig(w: BmcWorld) -> Rig { TransportServing { port: port, pid: _ } => { let obs = concat(dir, "/observer") let _made = shell.Mkdir.Parents(path: obs as FilePath) - kvm_observer_launch_in(dir_given: obs, base_url: concat("http://127.0.0.1:", port), host: concat("127.0.0.1:", port), username: "admin", password_file: pw_path, toolchain: loc, attempt: "wet") + kvm_observer_launch_in(dir_given: obs, base_url: concat("http://127.0.0.1:", port), host: concat("127.0.0.1:", port), username: "admin", password_file: pw_path, toolchain: loc, attempt: "wet", features_json: features_json) } TransportNotServing { cause: _ } => KvmObserverNotStarted { reason: "the loopback transport is not serving" } } @@ -161,6 +172,22 @@ test fn a_root_page_that_navigates_cannot_destroy_the_login() -> Bool { && !string_contains(s: log, pattern: "spa-root served") } +// THE VIEWER NEEDS ITS FEATURE LIST (KVM probe run 36788605665): launched WITHOUT it, the viewer's +// unguarded sessionStorage.features.indexOf throws, /kvm is never requested, and the observer refuses +// for want of a frame -- never established. The route is asserted: the controller saw the login and +// no kvm connect. +test fn a_viewer_without_its_feature_list_never_opens_kvm() -> Bool { + let r = rig_with(w: world(other_viewers: 0, close_at: no_close(), canvas_readable: true), features_json: "") + let refused = match kvm_observer_standing_now(start: r.start) { KvmObserverRefused { at: _, refusal: _ } => true _ => false } + let rec = mtcollins1_kvm_observer_finish(start: r.start, attempt: "wet", terminal_order: 3) + let log = transport_log(r: r) + let closed = close_rig(r: r) + refused && released(rec: rec) && closed + && string_contains(s: log, pattern: "transition request=[\"login\",\"admin\",\"pw\"] status=200") + && !string_contains(s: log, pattern: "transition request=[\"connect\"") + && !string_contains(s: log, pattern: "kvm-open") +} + // VIEWER SLOT BUSY: the model's other viewer makes viewer_count 1; the observer refuses with that count, // never connects, releases its session -- and the handoff is refused with that standing. test fn a_busy_viewer_slot_refuses_the_observer_and_the_handoff() -> Bool { @@ -296,7 +323,7 @@ test fn a_relative_observer_directory_is_resolved_once() -> Bool { let dir = trim(s: made.path as String) match runner_browser_toolchain_here_wet() { BrowserToolchainReady { location: loc, standing: _ } => { - let start = kvm_observer_launch_in(dir_given: dir, base_url: "http://127.0.0.1:9", host: "127.0.0.1:9", username: "u", password_file: "/nonexistent/credential", toolchain: loc, attempt: "rel") + let start = kvm_observer_launch_in(dir_given: dir, base_url: "http://127.0.0.1:9", host: "127.0.0.1:9", username: "u", password_file: "/nonexistent/credential", toolchain: loc, attempt: "rel", features_json: "") let refused = match start { KvmObserverStarted { dir: d, subject: _, standing: st, checked_at: _ } => starts_with(s: d as String, prefix: "/") && match st { KvmObserverRefused { at: _, refusal: _ } => true _ => false } _ => false diff --git a/src/v2/workflow/floor_route_gap.dag b/src/v2/workflow/floor_route_gap.dag index 25fd3c2a1c2..1f2c918c69b 100644 --- a/src/v2/workflow/floor_route_gap.dag +++ b/src/v2/workflow/floor_route_gap.dag @@ -1938,8 +1938,10 @@ fn floor_route_gap_expectation_chunk_29() -> List { tail: Cons { head: FloorRouteGapExpectation { identity: "test.claim.machine_intake.mtcollins1_kvm_observer_protocol_wet_witness.a_root_page_that_navigates_cannot_destroy_the_login", operation: "Dir", ground: NoMockResponse {} }, tail: Cons { +head: FloorRouteGapExpectation { identity: "test.claim.machine_intake.mtcollins1_kvm_observer_protocol_wet_witness.a_viewer_without_its_feature_list_never_opens_kvm", operation: "Dir", ground: NoMockResponse {} }, + tail: Cons { head: FloorRouteGapExpectation { identity: "test.claim.machine_intake.sol_hold_stdin_wet_witness.a_channel_loss_asks_the_screen_and_the_ask_does_not_change_the_verdict", operation: "DirWithTemplate", ground: NoMockResponse {} }, - tail: Empty {} } } } } } } } } } } } } } + tail: Empty {} } } } } } } } } } } } } } } } fn floor_route_gap_expectation_chunks() -> List> { diff --git a/src/v2/workflow/local_repo_wet_terminal.dag b/src/v2/workflow/local_repo_wet_terminal.dag index ebbc1b38822..e950220a04f 100644 --- a/src/v2/workflow/local_repo_wet_terminal.dag +++ b/src/v2/workflow/local_repo_wet_terminal.dag @@ -2240,6 +2240,12 @@ fn local_repo_wet_schedule() -> List { function: "a_root_page_that_navigates_cannot_destroy_the_login", expectation: ExpectedToHold {} }, + WetScheduledClaim { + identity: WitnessIdentity { module_path: "test.claim.machine_intake.mtcollins1_kvm_observer_protocol_wet_witness", function: "a_viewer_without_its_feature_list_never_opens_kvm" }, + entry: "dag/test/claim/machine_intake/mtcollins1_kvm_observer_protocol_wet_witness_test.dag", + function: "a_viewer_without_its_feature_list_never_opens_kvm", + expectation: ExpectedToHold {} + }, WetScheduledClaim { identity: WitnessIdentity { module_path: "test.claim.machine_intake.mtcollins1_kvm_observer_protocol_wet_witness", function: "a_busy_viewer_slot_refuses_the_observer_and_the_handoff" }, entry: "dag/test/claim/machine_intake/mtcollins1_kvm_observer_protocol_wet_witness_test.dag", From 74399d0775152ba9578e8fec5d7d81b62790e868 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Thu, 1 Oct 2026 05:40:43 +0000 Subject: [PATCH 69/75] boot dry realization: the observer's command carries the viewer feature-list operand (10 operands); establish only over a seeded list The features port added a tenth operand; the dry worker read operands at a fixed count of 9 from the end, so every observer launch read the wrong dir/host/attempt and the matrix's observed boots failed. It now reads 10, and models the vendor viewer: without the feature list the launch wrote, the observer journals a no-frame refusal and is never established. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../mtcollins1_boot_dry_realization.dag | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag index d94f731c5ae..05945e3b829 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_dry_realization.dag @@ -36,6 +36,7 @@ import gunbc.machine_intake_mtcollins1_kvm_still { KvmInstant, KvmJournalEvent, KvmJournalRendered, KvmJournalRenderRefused, kvm_journal_line, KvmJournalConnectionRequested, KvmJournalConnectionOpen, KvmJournalEstablished, KvmJournalStill, KvmJournalStopRequested, KvmJournalSessionRelease, KvmJournalBrowserClose, KvmJournalStopped, + KvmJournalRefused, KvmNoFrame, } // THE DRY REALIZATION OF ONE mtcollins1 BOOT ATTEMPT'S WHOLE EFFECT DEMAND. The scenario world @@ -483,8 +484,14 @@ fn operation_input_list(call: OperationCall, name: String) -> List? { } // kvm_observer_launch_in's operands end the node command: base URL, user, credential path, dir, -// attempt, cadence, frame wait, periodic limit, playwright module. -data kvm_observer_operand_count: Int = 9 +// attempt, cadence, frame wait, periodic limit, playwright module, viewer feature-list path. +data kvm_observer_operand_count: Int = 10 + +// THE VIEWER READS ITS FEATURE LIST UNGUARDED (KVM probe run 36788605665): the healthy viewer reaches +// established only when the feature-list operand names a file the launch wrote; without one the vendor's +// viewer throws in its KVM view's initialize() and never opens /kvm, which the observer journals as a +// refusal for want of a frame. +data kvm_observer_features_operand: Int = 9 fn kvm_operand(command: List, i: Int) -> String { match command.skip(n: count(command) - kvm_observer_operand_count + i).first() { Present { value: v } => v Absent => "" } @@ -511,11 +518,17 @@ fn owned_launch_handler(w: MtCollins1BootWorld, call: OperationCall) -> Operatio Present { value: at } => { let dir = kvm_operand(command: command, i: 3) let p = ModeledProcess { pid: w.worker.next_pid, start_time: start_ticks(w: w, now: call.now), comm: "node", cmdline: join(command, " "), capture_path: "", diagnostic_path: "", alive: true } - let journal = kvm_lines(events: [ - KvmJournalConnectionRequested { at: at }, - KvmJournalConnectionOpen { at: at, gen: kvm_observer_generation }, - KvmJournalEstablished { at: at, host: concat("\"", concat(url_host(base_url: kvm_operand(command: command, i: 0)), "\"")), session: w.screen.session, attempt: kvm_operand(command: command, i: 4), gen: kvm_observer_generation }, - ]) + let features = kvm_operand(command: command, i: kvm_observer_features_operand) + let seeded = features != "" && match fs_file(fs: w.fs, path: features) { Present { value: _ } => true Absent => false } + let journal = if seeded { + kvm_lines(events: [ + KvmJournalConnectionRequested { at: at }, + KvmJournalConnectionOpen { at: at, gen: kvm_observer_generation }, + KvmJournalEstablished { at: at, host: concat("\"", concat(url_host(base_url: kvm_operand(command: command, i: 0)), "\"")), session: w.screen.session, attempt: kvm_operand(command: command, i: 4), gen: kvm_observer_generation }, + ]) + } else { + kvm_lines(events: [KvmJournalRefused { at: at, refusal: KvmNoFrame { detail: "\"the viewer was opened without its feature list\"" } }]) + } match journal { KvmModeledRefused { event_word: word, would_write: line } => OperationHarnessFault { reason: concat("kvm_journal_line refused the modeled ", concat(word, concat(" line: ", line))) as NonEmptyStr } KvmModeledRendered { text: t } => { From c158c04300a582f4f16b5f58d72857ba44883da5 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Thu, 1 Oct 2026 06:33:50 +0000 Subject: [PATCH 70/75] design-rung-drops.md: take main's projection per the generated-artifact repair route; heal regenerates it from the merged roster Co-Authored-By: Claude Opus 5.5 (1M context) --- docs/design-rung-drops.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index 49689469c27..8babf51fa60 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -350,7 +350,7 @@ new-witness eval-step cost gate over the ten interpreted P-256 and P-384 point a ### new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 -new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=248288 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=237233 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=215502 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=140940 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146038 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=204469 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=202126 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=194599 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=122748 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=116804 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=276996 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_live_holder_still_blocks_the_next_attempt: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102436 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unobservable_holder_is_refused_not_recovered: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102525 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_successor_in_another_pid_namespace_refuses_rather_than_recovering: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102114 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=262400 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_is_recorded_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=154633 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_is_replaced_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146769 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_attaches_and_boots_with_the_code_recorded: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=139739 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=138564 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_jumping_forward_during_readiness_closes_the_window: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=137976 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_the_host_on_writes_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=126998 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_foreign_presented_image_is_not_stopped: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=118325 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_toolchain_that_is_not_ready_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=112482 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unresolved_toolchain_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_unresolved_toolchain_starts_no_observer_and_no_power_action, over gunbc#12800 at 6cac35eb1a6, 2026-09-30: PASS, eval_steps=102990 against the 72,300 new-witness budget (eval_steps are host-independent; PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) printed no eval-step line for it before its cancel); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, up to the handoff gate's refusal. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each of these identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. +new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=248288 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=237233 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=215502 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=140940 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146038 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=204469 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=202126 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=194599 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=122748 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=116804 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=276996 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_live_holder_still_blocks_the_next_attempt: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102436 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unobservable_holder_is_refused_not_recovered: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102525 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_successor_in_another_pid_namespace_refuses_rather_than_recovering: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102114 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=262400 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=154633 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146769 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=139739 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=138564 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_jumping_forward_during_readiness_closes_the_window: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=137976 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_the_host_on_writes_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=126998 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_foreign_presented_image_is_not_stopped: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=118325 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_toolchain_that_is_not_ready_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=112482 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unresolved_toolchain_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_unresolved_toolchain_starts_no_observer_and_no_power_action, over gunbc#12800 at 6cac35eb1a6, 2026-09-30: PASS, eval_steps=102990 against the 72,300 new-witness budget (eval_steps are host-independent; PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) printed no eval-step line for it before its cancel); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, up to the handoff gate's refusal. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each of these identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. ### new-witness eval-step cost gate over the one claim that runs the real fleet-converge build-job step list to hold the reset-observer dispatch admission's membership: it still executes, eval_steps stay recorded, a semantic red still blocks; only the eval-step cost-gate rung is lowered — declared 2026-09-30 @@ -366,7 +366,7 @@ the enrolment-margin decision over exactly two App Attest verifier claims whose ### the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided — declared 2026-09-30 -the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 449 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 433 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 421 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 411 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 374 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 381 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: the real boot entry end to end over the dry realization through a stop, a replace and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 473 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 303 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 287 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_is_replaced_and_booted: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 307 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_attaches_and_boots_with_the_code_recorded: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 308 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 276 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_is_recorded_and_booted: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 318 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: the real boot entry end to end over the dry realization through the whole readiness wait, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36783312538 of gunbc#12800 at 8042d175c2a (srv3) observed 320 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 283 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope). Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. +the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 449 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 433 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 421 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 411 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 374 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 381 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: the real boot entry end to end over the dry realization through a stop, a replace and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 473 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 303 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 287 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 307 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_refuses_before_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 308 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 276 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_refuses_before_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 318 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: the real boot entry end to end over the dry realization through the whole readiness wait, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36783312538 of gunbc#12800 at 8042d175c2a (srv3) observed 320 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 283 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope). Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. ### new-witness eval-step cost gate over the one claim that inhabits the real byte-span argv with its really-serialized program: it still executes, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 From 82afbcc9f28861f51dcf48bdccbda566a1303d13 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Thu, 1 Oct 2026 07:36:46 +0000 Subject: [PATCH 71/75] Boot matrix: the three full-boot cd_error cases move from the dead band to typed cost debt Since the Started-row rule they boot instead of refusing at the handoff gate, and at identical eval_steps they read 415-423 ms (run 36820943484) and 583-652 ms (run 36825466924): above the envelope floor on a fast runner and above the per-subject line on a slow one, which only a typed cost-debt row grounds (enrolment_dead_band_wrong_ground otherwise). Co-Authored-By: Claude Opus 5.5 (1M context) --- src/v2/workflow/floor_cost_debt_admission.dag | 25 ++++++++++++++----- src/v2/workflow/floor_enrolment_dead_band.dag | 12 --------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/v2/workflow/floor_cost_debt_admission.dag b/src/v2/workflow/floor_cost_debt_admission.dag index a149f072ac0..8714993ea6a 100644 --- a/src/v2/workflow/floor_cost_debt_admission.dag +++ b/src/v2/workflow/floor_cost_debt_admission.dag @@ -103,18 +103,31 @@ data app_attest_interpreted_crypto_typed_admissions: List = [ FloorCostDebtTypedAdmission { identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one", reason: "the real boot entry end to end over the dry realization twice (the killed run, then the next run recovering its hold), measured above the per-subject line by the enrolment-margin lines of PR required floor runs 36765162766 (srv1, 523 ms), 36775473983 (srv3, 582 ms) and 36783312538 (srv3, 543 ms); merge-group run 36793281217 read it at 466 ms on srv4, under the line, which v2.workflow.floor_enrolment_margin now holds as EnrolmentRosterGroundWithinRunnerEnvelope (gunbc#12853) rather than staling the row; owner: the mtcollins1 boot lane, discharged by the matrix running as natively emitted witnesses" as NonEmptyStr, }, + FloorCostDebtTypedAdmission { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_is_replaced_and_booted", + reason: "the real boot entry end to end over the dry realization through a stop, a replace and a full boot (since the Started-row cd_error rule this case boots rather than refusing at the handoff gate), at 249812 eval_steps on both runs: PR required floor run 36820943484 of gunbc#12874 at 74399d07751 read 415 ms and run 36825466924 at c158c04300a read 583 ms, so it sits above the envelope floor on a fast runner and above the per-subject line on a slow one, which a dead-band row cannot ground; owner: the mtcollins1 boot lane, discharged by the matrix running as natively emitted witnesses" as NonEmptyStr, + }, + FloorCostDebtTypedAdmission { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_attaches_and_boots_with_the_code_recorded", + reason: "the real boot entry end to end over the dry realization through an attach and a full boot (since the Started-row cd_error rule this case boots rather than refusing at the handoff gate), at 239309 eval_steps on both runs: PR required floor run 36820943484 of gunbc#12874 at 74399d07751 read 419 ms and run 36825466924 at c158c04300a read 652 ms, so it sits above the envelope floor on a fast runner and above the per-subject line on a slow one, which a dead-band row cannot ground; owner: the mtcollins1 boot lane, discharged by the matrix running as natively emitted witnesses" as NonEmptyStr, + }, + FloorCostDebtTypedAdmission { + identity: "test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_is_recorded_and_booted", + reason: "the real boot entry end to end over the dry realization through an attach and a full boot (since the Started-row cd_error rule this case boots rather than refusing at the handoff gate), at 254859 eval_steps on both runs: PR required floor run 36820943484 of gunbc#12874 at 74399d07751 read 423 ms and run 36825466924 at c158c04300a read 643 ms, so it sits above the envelope floor on a fast runner and above the per-subject line on a slow one, which a dead-band row cannot ground; owner: the mtcollins1 boot lane, discharged by the matrix running as natively emitted witnesses" as NonEmptyStr, + }, ] fn floor_cost_debt_typed_admissions() -> List { diff --git a/src/v2/workflow/floor_enrolment_dead_band.dag b/src/v2/workflow/floor_enrolment_dead_band.dag index e8140edf514..ca61e5583ca 100644 --- a/src/v2/workflow/floor_enrolment_dead_band.dag +++ b/src/v2/workflow/floor_enrolment_dead_band.dag @@ -77,18 +77,6 @@ fn mtcollins1_boot_matrix_enrolment_dead_band_observed_only() -> List Date: Thu, 1 Oct 2026 08:41:27 +0000 Subject: [PATCH 72/75] chore: regenerate drifted generated artifacts (ci auto-heal) Ledger-Repair-Judged: docs/design-rung-drops.md Ledger-Rows-Repaired: docs/design-rung-drops.md mtcollins1_boot_matrix_new_witness_eval_step_cost Ledger-Rows-Repaired: docs/design-rung-drops.md mtcollins1_boot_matrix_enrolment_dead_band_observed_only Heal-Candidate-Run: 36831359503 --- docs/design-rung-drops.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index 8babf51fa60..0d76d1eebd8 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -350,7 +350,7 @@ new-witness eval-step cost gate over the ten interpreted P-256 and P-384 point a ### new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 -new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=248288 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=237233 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=215502 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=140940 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146038 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=204469 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=202126 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=194599 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=122748 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=116804 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=276996 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_live_holder_still_blocks_the_next_attempt: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102436 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unobservable_holder_is_refused_not_recovered: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102525 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_successor_in_another_pid_namespace_refuses_rather_than_recovering: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102114 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=262400 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=154633 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146769 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=139739 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=138564 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_jumping_forward_during_readiness_closes_the_window: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=137976 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_the_host_on_writes_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=126998 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_foreign_presented_image_is_not_stopped: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=118325 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_toolchain_that_is_not_ready_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=112482 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unresolved_toolchain_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_unresolved_toolchain_starts_no_observer_and_no_power_action, over gunbc#12800 at 6cac35eb1a6, 2026-09-30: PASS, eval_steps=102990 against the 72,300 new-witness budget (eval_steps are host-independent; PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) printed no eval-step line for it before its cancel); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, up to the handoff gate's refusal. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each of these identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. +new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=248288 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=237233 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=215502 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=140940 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146038 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=204469 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=202126 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=194599 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=122748 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=116804 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=276996 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_live_holder_still_blocks_the_next_attempt: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102436 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unobservable_holder_is_refused_not_recovered: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102525 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_successor_in_another_pid_namespace_refuses_rather_than_recovering: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102114 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=262400 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_is_recorded_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=154633 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_is_replaced_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146769 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_attaches_and_boots_with_the_code_recorded: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=139739 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=138564 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_jumping_forward_during_readiness_closes_the_window: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=137976 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_the_host_on_writes_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=126998 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_foreign_presented_image_is_not_stopped: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=118325 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_toolchain_that_is_not_ready_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=112482 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unresolved_toolchain_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_unresolved_toolchain_starts_no_observer_and_no_power_action, over gunbc#12800 at 6cac35eb1a6, 2026-09-30: PASS, eval_steps=102990 against the 72,300 new-witness budget (eval_steps are host-independent; PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) printed no eval-step line for it before its cancel); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, up to the handoff gate's refusal. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each of these identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. ### new-witness eval-step cost gate over the one claim that runs the real fleet-converge build-job step list to hold the reset-observer dispatch admission's membership: it still executes, eval_steps stay recorded, a semantic red still blocks; only the eval-step cost-gate rung is lowered — declared 2026-09-30 @@ -366,7 +366,7 @@ the enrolment-margin decision over exactly two App Attest verifier claims whose ### the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided — declared 2026-09-30 -the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 449 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 433 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 421 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 411 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 374 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 381 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: the real boot entry end to end over the dry realization through a stop, a replace and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 473 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 303 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 287 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 307 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_refuses_before_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 308 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 276 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_refuses_before_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 318 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: the real boot entry end to end over the dry realization through the whole readiness wait, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36783312538 of gunbc#12800 at 8042d175c2a (srv3) observed 320 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 283 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope). Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. +the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 449 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 433 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 421 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 411 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 374 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 381 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: the real boot entry end to end over the dry realization through a stop, a replace and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 473 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 303 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 287 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: the real boot entry end to end over the dry realization through the whole readiness wait, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36783312538 of gunbc#12800 at 8042d175c2a (srv3) observed 320 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 283 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope). Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. ### new-witness eval-step cost gate over the one claim that inhabits the real byte-span argv with its really-serialized program: it still executes, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 From 0992f3a8b216e2aefb84ab96e3b1dcf01bed867f Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Thu, 1 Oct 2026 10:04:06 +0000 Subject: [PATCH 73/75] Delete PresentationStateUnestablished: the Started-row rule left it with no constructor (review 73648) A Started row with a read cd_error_code is served whatever the code, so the recheck has no unestablished answer; an unread code is PresentationUnobserved. The recheck arm, both diagnostic-bundle texts and the witness import go with it. Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/gunbc/machine_intake/megarac_media_attach.dag | 11 +++++------ .../mtcollins1_boot_diagnostic_bundle.dag | 3 --- dag/gunbc/machine_intake/mtcollins1_boot_run.dag | 1 - .../megarac_media_convergence_witness_test.dag | 1 - 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/dag/gunbc/machine_intake/megarac_media_attach.dag b/dag/gunbc/machine_intake/megarac_media_attach.dag index 5a40e6ddb46..64a40440f9c 100644 --- a/dag/gunbc/machine_intake/megarac_media_attach.dag +++ b/dag/gunbc/machine_intake/megarac_media_attach.dag @@ -1958,12 +1958,12 @@ fn megarac_observe_with_token( } } -// FOUR ANSWERS, BECAUSE THEY ARE FOUR DIFFERENT FACTS (side-chat review 5331738657). Affirmed: +// DIFFERENT ANSWERS, BECAUSE THEY ARE DIFFERENT FACTS (side-chat review 5331738657). Affirmed: // the look was taken and the medium is not being served (a withdrawn or non-Started row, a share -// mismatch). Unobserved: the look itself failed (session, transport, an unread member), which says -// nothing about the medium. Unestablished: the look was taken and the medium looked healthy, but the -// general settings carry a nonzero cd_error_code whose meaning is unresolved, so this attempt cannot -// establish the media state (operator decision, option A: a knowledge refusal, not a BMC verdict). +// mismatch). Unobserved: the look itself failed (session, transport, an unread member, including an +// unread cd_error_code), which says nothing about the medium. A Started row with a READ cd_error_code +// is served whatever the code (the vendor UI reads it only when stopped; see readiness_wait_outcome), +// so there is no separate unestablished answer. // And the look's own session must be released: a ready medium observed through a session the // controller still holds is a cleanup obligation unmet, exactly as at the initial gate. Only // PresentationStillReady admits a handoff; each other answer withholds and says which it was. @@ -1971,7 +1971,6 @@ type PresentationStillServed = PresentationStillReady | PresentationReadyButSessionHeld { held: SessionRelease } | PresentationNoLongerReady { reason: NonEmptyStr } - | PresentationStateUnestablished { cd_error: CdErrorReading } | PresentationUnobserved { reason: NonEmptyStr } fn presentation_still_served(result: MegaRacAttachResult) -> PresentationStillServed { diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_diagnostic_bundle.dag b/dag/gunbc/machine_intake/mtcollins1_boot_diagnostic_bundle.dag index fe8f4db3705..830b86280d1 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_diagnostic_bundle.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_diagnostic_bundle.dag @@ -119,7 +119,6 @@ import gunbc.machine_intake_megarac_media_attach { MegaRacMediaStateUnestablishedBeforeWrite, MegaRacReadinessClockIncoherent, PresentationReadyButSessionHeld, - PresentationStateUnestablished, PresentationUnobserved, MegaRacNotEnumeratedAfterRefresh, ReadinessStarted, @@ -692,7 +691,6 @@ fn recheck_text(v: PresentationStillServed) -> String { PresentationStillReady => "served" PresentationReadyButSessionHeld { held: r } => concat("served, but the look's own session was ", session_release_text(standing: r)) PresentationNoLongerReady { reason: why } => concat("AFFIRMED not served: ", why as String) - PresentationStateUnestablished { cd_error: c } => concat("UNESTABLISHED: cd_error_code ", cd_reading_text(r: c)) PresentationUnobserved { reason: why } => concat("UNOBSERVED (indeterminate, not a withdrawal): ", why as String) } } @@ -711,7 +709,6 @@ fn handoff_media_findings(h: MtCollins1HandoffMedia) -> List { PresentationStillReady => [] PresentationNoLongerReady { reason: why } => [concat("the presentation was LOST at or after the boot-device and power handoff (", concat(why as String, concat("): ", observation_text(r: a))))] PresentationUnobserved { reason: why } => [concat("the post-handoff look was UNOBSERVED, so whether the presentation survived the handoff is INDETERMINATE (", concat(why as String, concat("): ", observation_text(r: a))))] - PresentationStateUnestablished { cd_error: c } => [concat("after the handoff the presentation read Started but cd_error_code was ", concat(cd_reading_text(r: c), concat(", so its state is unestablished: ", observation_text(r: a))))] PresentationReadyButSessionHeld { held: r } => [concat("after the handoff the presentation was served, but the look's own session was ", session_release_text(standing: r))] } ) diff --git a/dag/gunbc/machine_intake/mtcollins1_boot_run.dag b/dag/gunbc/machine_intake/mtcollins1_boot_run.dag index 38df1e95d15..1067e2a44b2 100644 --- a/dag/gunbc/machine_intake/mtcollins1_boot_run.dag +++ b/dag/gunbc/machine_intake/mtcollins1_boot_run.dag @@ -2224,7 +2224,6 @@ fn mtcollins1_boot_handoff_when_media_ready( } PresentationReadyButSessionHeld { held: _ } => handoff_withheld_at_recheck(before: before, live_at: last_live_at) PresentationNoLongerReady { reason: _ } => handoff_withheld_at_recheck(before: before, live_at: last_live_at) - PresentationStateUnestablished { cd_error: _ } => handoff_withheld_at_recheck(before: before, live_at: last_live_at) PresentationUnobserved { reason: _ } => handoff_withheld_at_recheck(before: before, live_at: last_live_at) } } diff --git a/dag/test/claim/machine_intake/megarac_media_convergence_witness_test.dag b/dag/test/claim/machine_intake/megarac_media_convergence_witness_test.dag index 18af13c7068..9873cf20a0f 100644 --- a/dag/test/claim/machine_intake/megarac_media_convergence_witness_test.dag +++ b/dag/test/claim/machine_intake/megarac_media_convergence_witness_test.dag @@ -91,7 +91,6 @@ import gunbc.machine_intake_megarac_media_attach { ReadinessMalformed, PresentationUnobserved, PresentationReadyButSessionHeld, - PresentationStateUnestablished, CdErrorUncatalogued, share_binding_standing, ShareBound, From 42b363693f01ef9b87e6f2fb9335f18aeb835752 Mon Sep 17 00:00:00 2001 From: "gunbai-bot[bot]" <289086189+gunbai-bot[bot]@users.noreply.github.com> Date: Thu, 1 Oct 2026 11:10:20 +0000 Subject: [PATCH 74/75] chore: regenerate drifted generated artifacts (ci auto-heal) Ledger-Repair-Judged: docs/design-rung-drops.md Ledger-Rows-Repaired: docs/design-rung-drops.md mtcollins1_boot_matrix_new_witness_eval_step_cost Ledger-Rows-Repaired: docs/design-rung-drops.md mtcollins1_boot_matrix_enrolment_dead_band_observed_only Heal-Candidate-Run: 36846857547 --- docs/design-rung-drops.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index 6391430bfac..08f49bbe974 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -350,7 +350,7 @@ new-witness eval-step cost gate over the ten interpreted P-256 and P-384 point a ### new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-28 -new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=248288 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=237233 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=215502 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=140940 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146038 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=204469 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=202126 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=194599 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=122748 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=116804 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=276996 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_live_holder_still_blocks_the_next_attempt: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102436 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unobservable_holder_is_refused_not_recovered: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102525 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_successor_in_another_pid_namespace_refuses_rather_than_recovering: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102114 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=262400 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=154633 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146769 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_refuses_before_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=139739 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=138564 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_jumping_forward_during_readiness_closes_the_window: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=137976 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_the_host_on_writes_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=126998 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_foreign_presented_image_is_not_stopped: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=118325 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_toolchain_that_is_not_ready_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=112482 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unresolved_toolchain_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_unresolved_toolchain_starts_no_observer_and_no_power_action, over gunbc#12800 at 6cac35eb1a6, 2026-09-30: PASS, eval_steps=102990 against the 72,300 new-witness budget (eval_steps are host-independent; PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) printed no eval-step line for it before its cancel); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, up to the handoff gate's refusal. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each of these identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. +new-witness eval-step cost gate over the mtcollins1 boot acceptance matrix cases that run the real boot entry end to end over the dry operation realization: they still execute, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the evaluation frame and its modeled operation realization realized by the natively emitted runtime, so the boot entry runs as emitted code rather than in the seed interpreter). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=248288 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=237233 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=215502 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=140940 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146038 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=204469 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=202126 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=194599 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_listing_that_names_the_image_twice_starts_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=122748 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.the_right_filename_on_the_wrong_share_refuses_before_any_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=116804 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_interrupted_attempts_dead_hold_is_recovered_by_the_next_one: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=276996 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_live_holder_still_blocks_the_next_attempt: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102436 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unobservable_holder_is_refused_not_recovered: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102525 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_successor_in_another_pid_namespace_refuses_rather_than_recovering: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=102114 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=262400 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_is_recorded_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=154633 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_is_replaced_and_booted: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=146769 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_attaches_and_boots_with_the_code_recorded: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=139739 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_stepping_back_during_readiness_refuses_as_unbounded: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=138564 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_wall_clock_jumping_forward_during_readiness_closes_the_window: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=137976 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_the_host_on_writes_nothing: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=126998 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_foreign_presented_image_is_not_stopped: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=118325 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_toolchain_that_is_not_ready_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication), the [over-cost] line for this identity: planned_as_changed_witness, verdict pass, eval_steps=112482 against the 72,300 new-witness budget (eval_steps are host-independent); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, now including the dry KVM observer's launch and journal, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_unresolved_toolchain_starts_no_observer_and_no_power_action: over the new-witness eval-step budget, rostered in v2.workflow.floor_eval_step_cost_drop floor_eval_step_cost_drop_boot_matrix_rows; measured by claim_batch --entry dag/test/claim/machine_intake/mtcollins1_boot_acceptance_matrix_test.dag --functions an_unresolved_toolchain_starts_no_observer_and_no_power_action, over gunbc#12800 at 6cac35eb1a6, 2026-09-30: PASS, eval_steps=102990 against the 72,300 new-witness budget (eval_steps are host-independent; PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) printed no eval-step line for it before its cancel); the billed work is the real boot entry executed end to end in the seed interpreter over the dry realization, up to the handoff gate's refusal. Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each of these identities measures under the NewWitnessTier budget that v2.workflow.required_floor claim_ceiling_eval_step_budget derives, with its route and outcome assertions unchanged. Hoisting the shared world construction or the route prefix lowers the bill and retires nothing on its own; supplying a decided value in place of the entry, or deleting the identities, satisfies neither. ### new-witness eval-step cost gate over the one claim that runs the real fleet-converge build-job step list to hold the reset-observer dispatch admission's membership: it still executes, eval_steps stay recorded, a semantic red still blocks; only the eval-step cost-gate rung is lowered — declared 2026-09-30 @@ -366,7 +366,7 @@ the enrolment-margin decision over exactly two App Attest verifier claims whose ### the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided — declared 2026-09-30 -the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 449 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 433 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 421 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 411 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 374 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 381 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: the real boot entry end to end over the dry realization through a stop, a replace and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 473 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 303 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 287 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_refuses_after_the_replace: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 307 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_refuses_before_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 308 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 276 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_refuses_before_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 318 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 290 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: the real boot entry end to end over the dry realization through the whole readiness wait, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36783312538 of gunbc#12800 at 8042d175c2a (srv3) observed 320 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 283 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope). Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. +the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 449 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 433 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 421 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 411 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 374 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 381 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: the real boot entry end to end over the dry realization through a stop, a replace and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 473 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 303 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 287 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: the real boot entry end to end over the dry realization through the whole readiness wait, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36783312538 of gunbc#12800 at 8042d175c2a (srv3) observed 320 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 283 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope). Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. ### new-witness eval-step cost gate over the one claim that inhabits the real byte-span argv with its really-serialized program: it still executes, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22 From 3347cd12c3ac531d0cd1a8017f9dba7b42e4de89 Mon Sep 17 00:00:00 2001 From: "gunbai-bot[bot]" <289086189+gunbai-bot[bot]@users.noreply.github.com> Date: Thu, 1 Oct 2026 13:37:27 +0000 Subject: [PATCH 75/75] chore: regenerate drifted generated artifacts (ci auto-heal) Ledger-Repair-Judged: docs/design-rung-drops.md Ledger-Rows-Repaired: docs/design-rung-drops.md mtcollins1_boot_matrix_enrolment_dead_band_observed_only Heal-Candidate-Run: 36862331086 --- docs/design-rung-drops.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index 9228086af60..a689d541c3b 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -368,7 +368,7 @@ the enrolment-margin decision over exactly two App Attest verifier claims whose ### the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided — declared 2026-09-30 -the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 449 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 433 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 421 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 411 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 374 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 381 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: the real boot entry end to end over the dry realization through a stop, a replace and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 473 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 303 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 287 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_does_not_clear_is_replaced_and_booted: the real boot entry end to end over the dry realization through a stop, a replace and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36846505084 of gunbc#12889 at 0b436b6 (job floor) observed 444 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_16_with_nothing_presented_attaches_and_boots_with_the_code_recorded: the real boot entry end to end over the dry realization through readiness and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36846505084 of gunbc#12889 at 0b436b6 (job floor) observed 429 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.cd_error_appearing_with_readiness_is_recorded_and_booted: the real boot entry end to end over the dry realization through readiness and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36846505084 of gunbc#12889 at 0b436b6 (job floor) observed 434 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_start_that_stops_with_mount_error_refuses_by_name: the real boot entry end to end over the dry realization through an accepted start whose row falls back to Stopped and the whole readiness wait, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it sits at the margin as media_that_never_becomes_ready_refuses_before_any_power_action does -- PR required floor run 36846505084 of gunbc#12889 at 0b436b6 (job floor) observed 288 ms CPU, inside the runner envelope below the 302 ms margin (EnrolmentDeadBandWithinRunnerEnvelope), and a slower runner reads it above, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_start_that_stops_with_device_ejected_refuses_by_name_as_no_fault: the real boot entry end to end over the dry realization through an accepted start whose row falls back to Stopped and the whole readiness wait, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it sits at the margin as media_that_never_becomes_ready_refuses_before_any_power_action does -- PR required floor run 36846505084 of gunbc#12889 at 0b436b6 (job floor) observed 291 ms CPU, inside the runner envelope below the 302 ms margin (EnrolmentDeadBandWithinRunnerEnvelope), and a slower runner reads it above, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: the real boot entry end to end over the dry realization through the whole readiness wait, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36783312538 of gunbc#12800 at 8042d175c2a (srv3) observed 320 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 283 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope). Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. +the enrolment-margin decision over the mtcollins1 boot acceptance matrix cases whose honest CPU lies in (margin, per-subject line]: they execute, and an exact reading inside the band is reported rather than decided: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the matrix cases executing as natively emitted witnesses, the same replacement the eval-step drop mtcollins1_boot_matrix_new_witness_eval_step_cost waits on). Population: test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_host_that_never_prints_a_census_refuses_at_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 449 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_healthy_census_completes_and_releases_its_collector: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 433 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_the_handoff_is_the_reported_cause: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 421 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.an_already_presented_image_is_not_attached_again: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 411 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_two_socket_answer_is_a_truthful_topology_refusal: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 374 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_sol_loss_mid_boot_is_reported_before_the_deadline: the real boot entry end to end over the dry realization, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 381 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_stale_lane_image_with_a_code_the_stop_clears_is_replaced_and_booted: the real boot entry end to end over the dry realization through a stop, a replace and a full boot, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); PR required floor run 36765162766 of gunbc#12800 at 6cac35eb1a6 (job floor, cancelled after adjudication) observed 473 ms CPU, strictly above the 302 ms margin and under the 500 ms line, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_presentation_lost_after_readiness_stops_the_handoff: the real boot entry end to end over the dry realization up to the handoff gate, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36775473983 of gunbc#12800 at b907f7dc0c3 (srv3) observed 303 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 287 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope), test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_start_that_stops_with_mount_error_refuses_by_name: the real boot entry end to end over the dry realization through an accepted start whose row falls back to Stopped and the whole readiness wait, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it sits at the margin as media_that_never_becomes_ready_refuses_before_any_power_action does -- PR required floor run 36846505084 of gunbc#12889 at 0b436b6 (job floor) observed 288 ms CPU, inside the runner envelope below the 302 ms margin (EnrolmentDeadBandWithinRunnerEnvelope), and a slower runner reads it above, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.a_start_that_stops_with_device_ejected_refuses_by_name_as_no_fault: the real boot entry end to end over the dry realization through an accepted start whose row falls back to Stopped and the whole readiness wait, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it sits at the margin as media_that_never_becomes_ready_refuses_before_any_power_action does -- PR required floor run 36846505084 of gunbc#12889 at 0b436b6 (job floor) observed 291 ms CPU, inside the runner envelope below the 302 ms margin (EnrolmentDeadBandWithinRunnerEnvelope), and a slower runner reads it above, test.claim.machine_intake.mtcollins1_boot_acceptance_matrix_test.media_that_never_becomes_ready_refuses_before_any_power_action: the real boot entry end to end over the dry realization through the whole readiness wait, whose cost is gunbc#12434's own SOL polling route run faithfully (the subject gunbc#12423 requires); it straddles the margin between runners at identical eval_steps -- PR required floor run 36783312538 of gunbc#12800 at 8042d175c2a (srv3) observed 320 ms CPU, strictly above the 302 ms margin and under the 500 ms line, and run 36765162766 at 6cac35eb1a6 (srv1) observed 283 ms, inside the runner envelope below the margin (EnrolmentDeadBandWithinRunnerEnvelope). Restored when: THE CAPABILITY: witnesses emitted to native code with the emitted runtime realizing v2.std.witness_evaluation evaluate_in_witness_frame and its v2.std.operation_realization modeled realization, EXECUTING ON THE MERGE PATH as a phase of a required lane whose red blocks a merge, running the mtcollins1 boot acceptance matrix with the real mtcollins1_boot_wet_on_srv1 entry; WHAT THAT MUST BE SUFFICIENT FOR: each dead-band identity reaches its verdict with stable headroom under the enrolment margin v2.workflow.floor_enrolment_margin derives, with its route and outcome assertions unchanged -- at which point every row stales and deletes. Cutting the polling route the cases assert, or supplying a decided value in place of the entry, satisfies neither. ### new-witness eval-step cost gate over the one claim that inhabits the real byte-span argv with its really-serialized program: it still executes, eval_steps stay recorded, a semantic red and a wall-clock crossing still block; only the eval-step cost-gate rung is lowered — declared 2026-09-22