Conversation
Two artifacts, because they answer two questions. Qualification: does this one environment satisfy the T0-7 predicate. Execution binding: which Linux and Windows environments, which candidates and which instrument form THIS campaign. A utility that checks a CPU governor must not become the root of campaign identity, so `hostqual.py` neither issues nor owns the binding. `hostqual.py` splits evidence into the two classes that are not the same thing. DECLARED provisioning — dedication, absence of other users, hypervisor configuration — is content-addressed, shape-checked and never called machine proof: a guest OS cannot establish what the hypervisor is doing. MACHINE-OBSERVED is what a checker actually asserts: `manifest.provenance.ci == false` (the field is always present, so a predicate demanding its absence could never be met), `performance` governor on every applicable CPU plus an identified turbo mechanism, the Windows active plan with AC processor state pinned at 100/100, and the stratum's memory mechanism actually existing on the host. Quiesce is implemented exactly, not approximately: twelve 5 s intervals over the final minute, `/proc/stat` on Linux and `GetSystemTimes` on Windows, mean below 5 % and no interval above 20 %. A missing sample, a counter that went backwards or a zero denominator is NOT_ELIGIBLE rather than a skipped interval — an unreadable machine is not a quiet machine. A quiesce failure starts no clock, so it is not INVALID and costs no retry budget. A qualification is not a certificate of perpetual quiet. Session eligibility is proved again per session, against a fresh manifest, and the record names the execution binding, the qualification and that manifest — so a qualified host that this campaign never bound cannot be substituted into the middle of it. `execbinding.py` carries references and identity, never copies: duplicating the governor or the provisioning blob would create two copies of one fact, and two copies drift. It requires both strata, refuses an unqualified or mislabelled host, refuses a binding whose strata share one memory metric, and refuses to overwrite an existing binding — a rebuild before the first clock is legitimate but never silent. Both platform branches were driven live, not only by fixture. On Windows the first live run found a defect in this tool's own powercfg parse: it read the range's minimum as the current setting and reported 0 % on a machine pinned at 100 %. The block ends with the two current indices, AC then DC, and everything before them describes the possible range. Fixed here, with the labels never parsed — on this Russian Windows every one of them is localized. On Linux the tool correctly refuses WSL, where no cpufreq governor exists. step 7 host qualification controls: 10 passed, 0 failed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018xhcg5opoFbSTdYHpkSXCh
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The mini-review found a hole in the middle of a chain that was otherwise content-addressed end to end: a qualification said "this host satisfies T0-7" without naming WHICH T0. SHAs everywhere and the causation missing anyway. Q1 — `--qualify` now requires the T0 path and commit, proves the commit exists, that `blob_sha` really is `commit:path`, that the bytes hash to the recorded sha256, and that the document declares FROZEN. A qualification against a NOT_FROZEN T0 is refused, so today's reconnaissance cannot become campaign evidence by reuse. `execbinding` refuses a host qualified under a different T0 than the campaign binds. Q2 — `--environment-id` is gone. The id is the manifest's own observed value and the provisioning declaration must agree with it: one identity, not three strings that agree while everyone behaves. Q3 — provisioning is checked by VALUE, not only by shape. `dedicated_to_p022` and `no_concurrent_user_workload` must be true, `hosted_ci_runner` false, `is_vm` a real boolean; a VM must promise fixed vCPU, fixed RAM, no live migration and no dynamic memory, with `n/a` unavailable to it, and a physical host must answer those four with an explicit `n/a: <reason>` rather than bare booleans. A VM declaring `fixed_vcpu: false` could previously qualify. Q4 — per-session operator facts left the host record. "No campaign workload", "no interactive user", "no prohibited background job" are properties of a moment, and now live in a session declaration bound by sha256 into eligibility. Q5 — the 120 s window is waited, not asserted. The quiet minute really elapses before the twelve 5 s intervals; a control drives an injected clock and requires 60 + 60. A constant nobody waits for is documentation. Q6 — identity is compared as a whole. The qualification records a canonical hash of the manifest's identity block and the session must reproduce it, so a changed kernel, CPU count, RAM or toolchain can no longer walk past a matching fingerprint. Q7/Q8 — the candidate is hashed against the binding before the clock, and a new `--session-postflight` pass re-checks identity, power and candidate afterwards and requires closing-probe evidence. Preflight may not certify what a session did after it started. Q9 — power is a structured snapshot, compared by equality through the session. Owner ruling applied: Windows requires 100% on AC *and* DC, so a machine cannot be compliant while plugged in and change policy when the power source does. Q10/Q11 — the binding proves its inputs instead of trusting strings. The harness digest is recomputed from the instrument sources at the bound commit by the frozen formula without importing the harness; the workload manifest comes from that commit's git object; `--verify` re-proves T0, instrument, manifest, both qualifications and both candidates. Q12 — a preflight and a postflight carrying two different `execution_binding_sha256` values cannot meet in one session. Q13 — a provisioning template lands in `scripts/step7/examples/`, outside any evidence directory, marked EXAMPLE / NOT EVIDENCE, with no real identity in it, and a control keeps it valid under the rules it teaches. step 7 host qualification controls: 18 passed, 0 failed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018xhcg5opoFbSTdYHpkSXCh
…e campaign Two findings from the second Phase-2 review, both reproduced before repair. S-A — machine-produced artifacts were consumed as ordinary dicts. A document whose kind was "NOT A BINDING AT ALL" was accepted as the execution binding, and an arbitrary object carrying `identity` and `provenance` was accepted as an environment manifest: the probe returned an ELIGIBLE session from two handwritten files. The asymmetry was exactly backwards — the two DECLARED artifacts were validated by kind and schema, and the three machine ones were not. There is now one boundary. `load_artifact()` parses, proves the artifact by its own validator, and only then hands it over; no consumer reads a field before the type is established, and a refusal raises rather than becoming "not eligible" — an input that is not what it claims is an operator error, not a session that failed a predicate, so it exits 2. The envcapture schema string is duplicated rather than imported, with `hostqual-producer-schema` proving the copy still equals what the capture tool emits. One validator per artifact type, not five call sites: `validate_qualification` now lives in `execbinding` — the module that binds campaigns is the lower one, so `hostqual` reuses it without an import cycle. That immediately paid: the required A4 attack found that binding never checked a qualification's SCHEMA, only its kind. A wrong-schema qualification could be bound. It cannot now. S-B — `--verify` narrowed silently to whatever it was handed. Called without the strata it skipped the qualification and candidate checks and still printed "binding verified". Owner ruling applied: no partial mode under that name. The function refuses incomplete input maps — not only argparse, because the next caller may be a script — and the command line refuses before running anything. The string "binding verified" is now unreachable unless the full set was attempted and passed. P-A — the control inventory is checked by a control. The docstring list and the executed set must be the same set, because this class of defect has now been found twice and a third discovery wearing a new hat is not a surprise worth paying for. step 7 host qualification controls: 22 passed, 0 failed. Regression: envcapture 11/11, perf instrument 16/16, calibration freeze 7/7, training prereg 9/9. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018xhcg5opoFbSTdYHpkSXCh
S-C, found by the review of the previous repair — and introduced by it. Closing
the artifact-boundary hole, I folded value judgements into the shape validator,
so `dedicated_to_p022: false` was refused exactly like a forged document. The
honest case that used to produce a record with `qualified: false` and
`single_tenant: fail` produced nothing at all: one line on stderr and no
artifact.
That erases negative attempts, which is how a laboratory ends up with machines
that pass on the first try because the other tries were never artifacts.
The boundary now separates the two questions it had merged:
artifact validity is this the artifact it claims to be — kind, schema,
types, applicability shape. Malformed is refused before
any record exists.
predicate outcome do the declared values satisfy the predicate. Every
failure reaches a real record.
So the string "false" is malformed, a missing key is malformed, `is_vm` answered
with "n/a" is malformed, a VM omitting a VM-only field is malformed, and a
physical host answering those with bare booleans is malformed — while the
boolean `false`, anywhere it is allowed, is a valid declaration that this host
does not qualify.
Exit codes now say which class occurred, and are written down rather than
implied:
0 valid artifact, positive outcome
1 valid artifact, NEGATIVE outcome — the record exists and says why
2 malformed input or operational misuse — no record is produced
The same split applies to the session declaration: an operator who truthfully
records that a prohibited job is running gets `eligible: false` with the reason,
not an error message and no evidence.
Three controls added, driven through the command line so the exit codes are
part of the proof: an honest provisioning negative, an honest VM negative and an
honest session negative each leave an artifact naming the failed check, while
`"false"` as a string leaves none and exits 2.
step 7 host qualification controls: 24 passed, 0 failed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018xhcg5opoFbSTdYHpkSXCh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 2 of the S8 repair chain. Stacked on #355 (the instrument's memory-metric repair), which it needs for the closed memory vocabulary.
Three artifacts, three questions, never merged:
and, separately, the execution binding: which Linux and Windows environments, which candidates and which instrument form this campaign.
hostqual.pyneither issues nor owns it — a utility that checks a CPU governor must not become the root of campaign identity. D7 later bindsexecution_binding_sha256rather than restating the machines.Qualification is versioned by T0
A qualification claims "this host satisfies T0-7", so it cannot float free of T0.
--qualifyrequires the T0 path and commit and proves: the commit exists,blob_shareally iscommit:path, the bytes hash to the recorded sha256, and the document declares FROZEN. A qualification against aNOT_FROZENT0 is refused — today's reconnaissance cannot become campaign evidence by reuse — and the binding refuses a host qualified under a different T0 than it binds.Every consumed artifact is proved before it is read
One boundary, one validator per artifact type: parse → prove kind/schema/shape → only then read semantics. Binding, qualification, environment manifest, preflight record, provisioning and session declaration all go through it.
Artifact validity is not predicate outcome. Malformed input — wrong kind, wrong schema, the string
"false"where a boolean belongs, a VM omitting a VM-only field — is refused before any record exists. A declared booleanfalseis not malformed: it is a perfectly good declaration that this host does not qualify, and it reaches a real artifact. The exit codes say which happened:The envcapture schema string is duplicated rather than imported (neither tool imports the instrument or the capture tool), with a control proving the copy still equals what the producer emits.
Evidence classes stay apart
Declared — provisioning and the per-session operator declaration. Content-addressed, checked by shape and value, never called machine proof: a guest OS cannot establish that no neighbour arrived on the same hypervisor.
dedicated_to_p022andno_concurrent_user_workloadmust be true,hosted_ci_runnerfalse,is_vma real boolean; a VM must promise fixed vCPU, fixed RAM, no live migration and no dynamic memory, withn/aunavailable to it, while a physical host answers those four with an explicitn/a: <reason>.Machine-observed —
manifest.provenance.ci == false(the field always exists, so demanding its absence could never be satisfied);performancegovernor on every applicable CPU plus an identified turbo mechanism; on Windows an accepted plan with processor state pinned at 100% on AC and DC, read by GUID and by position because every label on a non-English machine is localized; and the stratum's memory mechanism actually existing here.Identity, candidate, quiesce
/proc/statorGetSystemTimes, mean below 5 %, no interval above 20 %. A missing sample, a rewound counter or a zero denominator isNOT_ELIGIBLErather than a skipped interval. A quiesce failure starts no clock, so it is notINVALIDand costs no retry budget.execution_binding_sha256values cannot meet in one session.The binding proves its inputs, and
--verifyis totalThe harness digest is recomputed from the instrument sources at the bound commit by the frozen formula, without importing the harness; because the workload manifest is one of those sources, proving the digest at a commit also proves the manifest there.
--verifyre-proves T0, instrument, manifest, both qualifications and both candidates — and there is no partial mode under that name: incomplete inputs are refused by the function and by the command line, so the stringbinding verifiedcannot appear over a skipped component.Driven live, not only by fixture
The first live Windows run found a defect in this tool's own parser: it read the possible-range minimum as the current setting and reported
0%on a machine pinned at100%. Fixed — the block ends with the two current indices, AC then DC.Exploratory witness, not qualification evidence: on the development machine
processor_min_dc = 5. Under the AC+DC rule that host does not qualify, which is the point of the rule — a machine can look perfect on its current power source and carry a different profile the moment the source changes.Both refusals are correct, and both leave evidence: neither environment is a measurement host, the tool says so for the right reason, and the attempt is recorded rather than discarded.
step 7 host qualification controls: 24 passed, 0 failed.Regression: envcapture 11/11, perf instrument 16/16, calibration freeze 7/7, training preregistration 9/9.No real campaign qualification or binding has been created. T0 remains NOT_FROZEN;
collection_authorized: false.🤖 Generated with Claude Code
https://claude.ai/code/session_018xhcg5opoFbSTdYHpkSXCh