Skip to content

Record the enforced witness clock; seed half of the clock-basis ruling (7820A) - #7820

Merged
briansrls merged 10 commits into
mainfrom
session/merry-raven-690-witness-cost-clock
Aug 5, 2026
Merged

briansrls merged 10 commits into
mainfrom
session/merry-raven-690-witness-cost-clock

Conversation

@briansrls

@briansrls briansrls commented Aug 5, 2026 •

Copy link
Copy Markdown
Contributor

The fast-lane witness budget is enforced on thread CPU, but every cost artifact in the tree recorded wall. run_claim_measured computed cpu_nanos, spent it on the budget decision, and dropped it — so the cap was compared against a number no receipt carried, and any threshold built on a cost receipt selects a different population than the cap kills.

Found by still-bat-561. I verified all three claims at source before building: cpu_nanos computed and dropped, PerformanceReceipt carrying no CPU field, and the TSV's eval_ms tracing back through the .dag projection to performance_receipts[index].wall_nanos.

What landed

The enforced quantity is now recorded. PerformanceReceipt carries cpu_nanos beside wall_nanos, and run_claim_measured feeds the same binding to budget_completion_outcome and to the receipt, so enforced and recorded cannot drift apart. Both clocks are required parameters — a defaulted cpu_nanos would silently record zero for the enforced quantity, which reads as "measured, and free" rather than "not measured".

Each clock is named at its carrier. EvalBudgetExceeded.elapsed_ms → cpu_ms (it is thread CPU); WitnessWallBudgetExceeded.elapsed_ms → wall_ms. One shared elapsed_ms spelling let a CPU figure be read as wall at every downstream consumer.

The refusal message no longer recommends the retired move. It told authors a slow witness "lives in a long/ test dir and runs via its dedicated lane" — the exact relocation the 2026-08-04 admission ruling retired, which deletes the coverage while retaining the source. ci_floor_plan already records this message misleading a real lane (seven rows killed at 5001–5013ms "by a refusal whose own text says the row lives in a long/ test dir"). The stable eval budget exceeded prefix is unchanged, so falsifier_failure_mode's classification is untouched.

floor-witness-row-cost-receipt.tsv can now say what it means. Worth naming precisely: the .dag model was never wrong here — WitnessCostReceiptRow already carries outcome, and the projection witness already matches on it. Only the seed writer discarded the field. So this is the model/realization fork DESIGN names as a recurring mode, not a modeling gap: the fix realigns the realization with a model that already said the right thing. eval_ms → eval_wall_ms (it was always wall), and outcome/detail are emitted rather than dropped. The row tuple always carried them. Because discovery_claim_result pushes selection-skipped rows into this same receipt with zero timings, a 0 in the eval column meant "never executed" or "ran in under a millisecond" with no way to tell — the empty-observation narrow, in an artifact whose entire purpose is per-row cost. A census taken from a selection-applied per-PR run would have counted skipped rows as fast ones.

And the number itself is no longer fabricated. Emitting outcome made the two cases decidable, but a selection-skipped row still wrote 0 into all three timing cells for a measurement that does not exist. std.observation's observation_measured_note rules on exactly this shape, in the module these rows project through: "Absence of a measurement is a NAMED state carrying its cause, never a fabricated zero... A renderer projecting MeasuredUnavailable prints the cause; it never prints 0 and never omits the field." So an absent measurement renders as unmeasured, deliberately non-numeric, and the cause rides in outcome/detail. Both facts survive: an executed witness may legitimately measure 0 ms, and those rows keep their 0. Absence is keyed on the selection-skipped outcome spelling the seed already dispatches on — never inferred from the numbers, since inferring absence from a zero is the conflation being closed. Caught by royal-raven-604 via still-bat-561 before merge.

Consumer note: on a selection-applied run, the timing cells of skipped rows now fail an integer parse instead of reading 0. That is the point — a census reaching for a number fails loudly rather than silently counting an unexecuted row as a fast one.

The bound that keeps this honest

From wise-ram-22, verified: eval is single-threaded, so cpu ≤ wall. A wall figure under the cap proves cpu under it — so existing "lands under the fast-lane budget" dissolve triggers were always decidable on the wall number and are not blocked on this. What wall cannot answer is the other direction: how near the cap a row sits, or whether an over-cap wall figure reflects CPU at all. That ranking direction is exactly what the per-witness cost-envelope lane needs.

The clock question is now DECIDED — this PR is the seed half

Operator ruling, 2026-08-05. Recording both clocks is correct and is not the defect. What a second bare field would introduce is a duration whose meaning lives only in its field name. The ruled model carries the basis on the measurement itself:

type ClockBasis = CpuClock | WallClock
type TimedMeasurement { basis: ClockBasis, elapsed: Nanosecond }
TimedOut { basis: ClockBasis, budget: Nanosecond, elapsed: Nanosecond }

Under that model a receipt may legitimately hold both a cpu and a wall observation, because neither is relying on its name to say what it is.

Consequence applied here: the earlier "add cpu as a third measured quantity beside wall and rss" framing was the exact thing ruled against, and it has been removed from WITNESS_COST_CLOCK_BASIS_NOTE and from the PerformanceReceipt field docs. (It was also already refuted on the merits: wall is Measured<Nanosecond> and rss is Measured<ByteSize> — two magnitudes, not two clocks on one magnitude.)

The work splits, and this is 7820A — seed instrumentation, landing independently:

7820A (this PR) cpu + wall observations · required non-defaulted fields · outcome/detail emission · unmeasured for absent measurements · claim_executor test-target repair · seed disposition + dissolution trigger
7820B (separate) ClockBasis · basis-carrying elapsed measurement · basis on TimedOut · migrate the affected .dag construction sites · row-cost consumer projects cpu and wall without confusing them

The seed fields here say which clock they are only by name — that is the provisional part, and it is stated as such rather than presented as the end state. WITNESS_COST_CLOCK_BASIS_NOTE carries the disposition and the dissolution trigger: when ClockBasis lands in the std.observation authority and the declaration-grain receipt projects both clocks through it, these two bare fields are replaced by basis-carrying measurements and the note is deleted with them.

Design notes landed in the cost authority

Two notes on dag/gunbc/witness_row_cost.dag, at operator request:

  • witness_decomposition_does_not_reduce_entry_cost_note — do not split a witness expecting entry startup to get cheaper. Per-witness eval and per-entry resolve are different terms; splitting amortizes one expensive resolve across more rows rather than dividing it, so a fall in per-row eval is an artifact of the split itself. Measured on falsifier run 30824310833: 682 of 930 entries resolve at ≥1000ms (max 11223ms); corpus totals 1638s resolve against 3987s eval. The repeated-resolve term belongs to the shared-floor / materialization lane, not to witness decomposition. Witness decomposition is justified by what a witness proves, never by a startup saving it cannot deliver.
  • witness_row_cost_clock_basis_note — the two-clock fact, the cpu ≤ wall bound and its one-directional consequence, and the fact that a row at or past the cap is a censored measurement rather than a cost (its value is where the kill landed; the true figure is unbounded above).

Evidence

  • performance_receipt_carries_the_enforced_cpu_clock_beside_wall — asserts the two clocks are carried independently (a receipt aliasing one value under both names would pass a weaker test), and that the same occurrence passes on CPU while crossing on wall, so the bases genuinely disagree.
  • witness_row_cost_receipt_distinguishes_unexecuted_from_sub_millisecond — the fixture's executed row (500,000ns) and never-run row (0ns) collide on every cost column, asserted as a premise, and are separated only by outcome.
  • RED control proven by execution: reverting the writer to drop the outcome column turns that test red, with the panic showing the collision verbatim — ran_in_under_a_millisecond → 0 0 0.

Also: the claim_executor unit suite was not running at all

Its test target did not compile on main — two ClaimResult initializers missing selection_degradation — so all 65 tests were unrunnable, and CI does not run nextest. Verified against a clean origin/main worktree rather than assumed.

Fixing compilation exposed one stale fixture: discovery() built a batch with empty scan_dirs and empty explicit_entries and asserted it yields a discovery unit, which contradicts the documented "empty entries AND empty discovery dirs = zero witness-corpus nodes" rule. Production was correct; the fixture had been frozen since the target stopped compiling. Suite is now 66/66 (65 restored, plus the new drift-comparator control), verified by execution on the post-merge tree.

Open question, raised not answered: whether an executable does-the-test-target-compile check belongs on the floor. That is a much cheaper question than putting the whole suite back in CI (nextest was removed 2026-07-11 by operator ruling, and I am not proposing to reverse that) — it would catch this exact rot, where the failure mode is not a test passing wrongly but a test that was never a consumer at all. The floor is load-bearing and under the five-minute-gate program, so this is flagged for the operator rather than added here.

Brian Searls and others added 4 commits August 5, 2026 00:29
…k at its carrier

The fast-lane witness budget is enforced on THREAD CPU, but every cost artifact in
the tree recorded WALL. run_claim_measured computed cpu_nanos, spent it on the budget
decision, and dropped it, so the cap was compared against a number no receipt carried
and any threshold built on a cost receipt selected a different population than the cap
kills. Found by still-bat-561; verified at both producers before acting.

- PerformanceReceipt carries cpu_nanos beside wall_nanos, and run_claim_measured feeds
  the SAME binding to budget_completion_outcome and to the receipt, so the enforced and
  the recorded quantity cannot drift apart. Both clocks are required parameters: a
  defaulted cpu_nanos would record zero for the enforced quantity, which reads as
  "measured, and free" rather than "not measured".

- InterpError names each clock at its carrier: EvalBudgetExceeded.elapsed_ms -> cpu_ms
  (it is thread CPU) and WitnessWallBudgetExceeded.elapsed_ms -> wall_ms. A shared
  "elapsed_ms" spelling let a CPU figure be read as wall at every consumer.

- The EvalBudgetExceeded message no longer instructs authors to relocate the file. It
  told them a slow witness "lives in a long/ test dir and runs via its dedicated lane" —
  the exact move the 2026-08-04 admission ruling retired, and one that deletes the
  coverage while retaining the source. ci_floor_plan already records this message
  misleading a real lane. The stable "eval budget exceeded" prefix is unchanged, so
  falsifier_failure_mode's classification is untouched.

- floor-witness-row-cost-receipt.tsv: eval_ms -> eval_wall_ms (it was always wall), and
  outcome/detail are emitted rather than dropped. The row tuple always carried them, and
  because selection-skipped rows are pushed into this receipt with zero timings, a 0 in
  the eval column meant "never executed" OR "ran in under a millisecond" with no way to
  tell — the empty-observation narrow, in an artifact whose purpose is per-row cost.

The bound that keeps this honest (wise-ram-22, verified): eval is single-threaded, so
cpu <= wall. A wall figure under the cap PROVES cpu under it, so existing "lands under
the fast-lane budget" triggers were always decidable on the wall number. What wall
cannot answer is the ranking direction — how near the cap a row sits — which is what
the per-witness cost-envelope lane needs.

NOT improvised here: declaration-grain rows project through std.observation
ObservationEvent, which carries wall and rss but no cpu, so discovery-grain rows still
record wall only. Closing that is a load-bearing std.observation change (a third measured
quantity, plus a clock basis on TimedOut) and is raised rather than built.

Also restores the claim_executor unit suite to executable: its test target did not
compile on main (two ClaimResult initializers missing selection_degradation), so all 65
tests were unrunnable, and CI does not run nextest. Fixing compilation exposed one stale
fixture — discovery() built a batch with empty scan_dirs AND empty explicit_entries and
asserted it yields a discovery unit, which contradicts the documented empty-and-empty
means zero-nodes rule.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot changed the title Witness cost/purpose/admission: retire long/ as authority Record the quantity the witness cap actually enforces; name each clock at its carrier Aug 5, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review August 5, 2026 01:33
@cursor

cursor Bot commented Aug 5, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

Brian Searls and others added 2 commits August 5, 2026 02:30
…ated zero

Emitting the outcome column made "never executed" and "ran in under a millisecond"
DECIDABLE, but the number itself was still fabricated: a selection-skipped row wrote 0
into the timing columns for a measurement that does not exist.

std.observation observation_measured_note already rules on exactly this shape, in the
module this receipt's rows project through: "Absence of a measurement is a NAMED state
carrying its cause, never a fabricated zero. A renderer projecting MeasuredUnavailable
prints the cause; it never prints 0 and never omits the field, because a silently omitted
number is the same fabrication one layer up."

So the timing cells of a row that never ran render as `unmeasured` and the cause rides in
outcome/detail. The cell is deliberately non-numeric: a consumer reaching for a number
fails loudly instead of counting an unexecuted row as a fast one, which is the failure
mode this receipt had while the cell said 0.

The two cases are genuinely different facts and both are preserved: an executed witness
may legitimately measure 0 ms (sub-millisecond), and those rows keep their 0. Absence is
keyed on the same selection-skipped outcome spelling discovery_claim_result writes and
wet_witness_row_outcome_label already dispatches on -- never inferred from the numbers,
since inferring absence from a zero is the conflation being closed.

Test strengthened accordingly: the two rows now differ in the cost columns THEMSELVES
rather than only in the outcome column, and every absent cell is asserted to fail
u128::parse. Proven RED by reverting the absence detection -- the failure prints the
fabricated zero row verbatim.

Found by royal-raven-604 via still-bat-561, before merge.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ty design notes

Operator ruling 2026-08-05 on the clock question, plus the review follow-up.

THE RULING. Recording BOTH clocks is correct and is not the defect. What a second bare
field would introduce is a duration whose meaning lives only in its field NAME. The ruled
model carries the basis on the measurement itself -- ClockBasis = CpuClock | WallClock, a
basis-carrying elapsed measurement, and a basis on TimedOut so a crossing names its cap --
under which a receipt may legitimately hold both a cpu and a wall observation because
neither relies on its name to say what it is.

So the "third measured quantity beside wall and rss" framing is REMOVED from
WITNESS_COST_CLOCK_BASIS_NOTE and from the PerformanceReceipt field docs; it contradicts
the basis model and is the exact framing ruled against. The note now states the seed
disposition plainly: these u128 fields are seed instrumentation that says which clock it is
only by name, retained because the enforced quantity had to stop being dropped before the
authority lands, with the dissolution trigger named (ClockBasis lands in std.observation and
the declaration-grain receipt projects both clocks through it).

This PR is the seed half (7820A) and lands independently of the observation authority.

DESIGN NOTE THE OPERATOR ASKED BE LANDED IN THE COST AUTHORITY:
witness_decomposition_does_not_reduce_entry_cost_note. Do not split a witness expecting
entry startup to get cheaper -- per-witness eval and per-entry resolve are different terms,
and splitting AMORTIZES one expensive resolve across more rows rather than dividing it, so
a fall in per-row eval is an artifact of the split. Measured on falsifier run 30824310833:
682 of 930 entries resolve at 1000ms or more (max 11223ms); corpus 1638s resolve vs 3987s
eval. The repeated-resolve term belongs to the shared-floor / materialization lane.
witness_row_cost_clock_basis_note records the two-clock fact and the bound on the same
carrier the columns live on.

REVIEW FOLLOW-UP (review 48405, REQUEST_CHANGES). The finding claims the header guard
asserts !contains("\teval_ms") against a header containing "\teval_wall_ms" and therefore
fails. That is not correct -- after "\teval_" comes "wall_ms", so "\teval_ms" does not occur,
and the test passes (verified by execution both ways). But the suggestion is right on the
merits: a substring test answers a question about column NAMES with a question about
characters, and the two coincide only by accident, which is exactly why it could be misread.
The guard now splits on tabs and compares at column grain, and its failure prints the parsed
columns. Proven RED by reverting the column name.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Addressed in 29d52ee — but the finding's factual claim doesn't hold, and it's worth correcting the record since it was the stated blocker.

The claim: !header.contains("\teval_ms") fails because \teval_wall_ms contains \teval_ms.

Checked by execution, both ways:

header: 'batch\tentry\tfunction\teval_wall_ms\tresolve_ms\twarm_ms\toutcome\tdetail'
contains \teval_ms ?  False
index:                -1

After \teval_ the header has wall_ms, not ms, so \teval_ms never occurs. The test was passing before this commit and would not have blocked CI:

test tests::witness_row_cost_receipt_distinguishes_unexecuted_from_sub_millisecond ... ok

That said, the suggestion is right on the merits and I've taken it. A substring test answers a question about column names with a question about characters, and the two coincide only by accident here — which is precisely why it was misreadable. The guard now splits on tabs and compares at column grain:

let header: Vec<&str> = body.lines().next().expect("header").split('\t').collect();
assert!(header.contains(&"eval_wall_ms"), ...);
assert!(!header.contains(&"eval_ms"), ...);

Proven RED by reverting the column name to eval_ms — and the failure now prints parsed columns rather than a raw string, so a future reader can see the answer directly:

eval column must name its clock: ["batch", "entry", "function", "eval_ms", "resolve_ms", "warm_ms", "outcome", "detail"]

Same commit also carries the operator's clock-basis ruling: the "third measured quantity beside wall and rss" framing is removed (it contradicts the ruled basis model), the seed disposition and dissolution trigger are stated, and the two design notes the operator asked be landed in the cost authority are in dag/gunbc/witness_row_cost.dag.

@gunbai-bot gunbai-bot Bot changed the title Record the quantity the witness cap actually enforces; name each clock at its carrier Record the enforced witness clock; seed half of the clock-basis ruling (7820A) Aug 5, 2026
Brian Searls and others added 3 commits August 5, 2026 03:21
…before comparing

Follow-up from review 48447, which flagged that the drift comparator still floored
selection-skipped rows to observed_eval_ms=0. Verified, and it is worse than a cosmetic
mismatch with the sibling receipt: with a basis present, a skipped row compared as
0 <= basis and reported WithinBasis -- a POSITIVE verdict that the row met its cost basis,
derived from a measurement that does not exist, and one that could never fail because 0
never exceeds anything. The drift wire silently passed unexecuted rows.

That is the fabricated zero of the previous commit promoted into a verdict, so it gets the
same treatment one layer up. The observed column renders unmeasured, the verdict is
ObservationAbsent, and the row is counted into a new observation_absent tally reported on
both the summary and the receipt line -- typed, located, counted, never absorbed.

ObservationAbsent is deliberately the mirror of the BasisAbsent arm this writer already
had: there a measurement exists with no basis to judge it, here a basis exists with no
measurement to judge. Neither is a comparison and neither is now reported as one.

MECHANISM: the fail-open was not a bad comparison, it was comparing AT ALL, so the fix
decides comparability BEFORE any comparison runs. drift_row_disposition returns
ObservationAbsent | BasisAbsent | Comparable, with observation-absence outranking
basis-presence -- precisely the case that was broken. Extracting it also makes the property
testable without resolving the .dag authority the writer needs, so the test is a fast pure
check rather than a filesystem fixture.

Discriminating test asserts the sharp case -- a skipped row WITH a basis present must still
refuse -- plus that the two meaningful states stay reachable, so this is not a blanket
refusal. An executed row that genuinely measured 0 ms remains comparable, which is the
distinction the whole change rests on. Proven RED by disabling the absence arm.

Also replaces the previous filesystem-fixture version of this test, which the dashboard's
mid-edit auto-commit pushed unformatted and which redded the fmt gate on 450690c.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@briansrls
briansrls merged commit 4b7a13d into main Aug 5, 2026
5 checks passed
@briansrls
briansrls deleted the session/merry-raven-690-witness-cost-clock branch August 5, 2026 06:05
gunbai-bot Bot pushed a commit that referenced this pull request Aug 5, 2026
Author-commit-required (GitHub App lacks workflows write): regen
picked up main's advance to 4b7a13d (#7820) after the merge.
gunbai-bot Bot pushed a commit that referenced this pull request Aug 5, 2026
The operator's 2026-08-05 ruling: recording both clocks is correct; the
defect is a duration whose meaning lives only in its field NAME. This is
the observation-authority half of that ruling (7820A landed the seed half
in #7820).

std.observation gains ClockBasis = CpuClock | WallClock and
TimedMeasurement { basis, elapsed }, and two carriers stop naming their
clock in prose:

  ObservationOutcome.TimedOut  now carries `basis`, so a kill says WHICH
    cap it crossed — a 5000ms thread-CPU fail-stop and a 600000ms wall
    receipt ceiling were previously indistinguishable, and the CI line
    now renders the clock beside both figures.
  ObservationEvent.wall        becomes `durations: List<TimedMeasurement>`.
    A list rather than one tagged duration because the seed already holds
    both clocks for every occurrence (run_claim_measured), and because
    the operator ruled thread CPU is the REMEDY DISCRIMINATOR beside a
    wall threshold: high wall + high CPU is algorithm or repeated
    evaluation, high wall + low CPU is waiting, I/O or scheduling. One
    clock cannot make that call.

A record with `cpu` and `wall` fields would have been the nickname twice,
which is what the operator refused when 7820A's first draft proposed cpu
as a third measured quantity beside wall and rss.

The payoff is a construction wall, not a rename: witness_row_cost_verdict
now takes the observed clock, WitnessRowCostDatedBasis carries its own,
and a cross-clock comparison answers BasisClockMismatch — a fourth arm,
not a Bool collapse, on the same reasoning std.content_hash refuses
cross-family comparison. Comparing a CPU figure against a wall baseline
used to typecheck and answer confidently; four sessions spent an evening
doing exactly that.

Not walled, and said so on the carrier: two entries may share one basis.
The construction that would forbid it is a total function from a closed
sum, which this substrate lacks (Map is a closure, not wire-serializable,
and refused by the determinism gate). So observation_duration_of REFUSES
an ambiguous read with the duplicate as its cause rather than silently
picking the first — rung mechanically preventable, ceiling structurally
impossible, trigger named.

Green by execution with discriminating REDs, all run locally:
  witness_row_cost_projection_holds     PASS; RED when the basis filter
    is removed from observation_clock_lookup (the silent first-match pick)
  witness_row_cost_drift_comparator_holds PASS incl. two new cross-clock
    controls on BOTH sides of the 2x ratio, so the refusal is proven to
    be decided by the clock and not by the magnitude; RED when the
    comparator stops checking it
  floor_component_receipt (15), observation_model (36), ci_render (19),
  tty_render (16), seed_scoped_run (10), crawl_replay (3)  all PASS

ClockBasis is exported vocabulary: gunbc#7831 states WallClock in its own
policy carrier and rebases onto this.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 5, 2026
The last piece of the 2026-08-05 clock-basis ruling with a real consumer
gap. #7820 renamed eval_ms to eval_wall_ms and #7837 made the row carry
both clocks; nothing yet printed the second one, so the remedy that second
clock exists to discriminate could not be read from the artifact at all.

The seven-wide anonymous tuple becomes WitnessRowCost. That is not tidying:
a positional tuple is how `eval` came to mean "wall" by index and nothing
else — the same defect one layer below the ObservationEvent.wall field name
this lane retired — and it is exactly what would have made a second clock
"the third u128".

eval_cpu_ms sits immediately beside eval_wall_ms, asserted by the test
rather than left to convention, so an author reads the remedy from one file
without joining another: high wall with high CPU is algorithm or repeated
evaluation, high wall with low CPU is waiting, I/O, subprocess or
scheduling. It is not a second threshold — the witness threshold is stated
on wall.

An unsampled clock renders `unmeasured`, never 0. A `0` there would claim
the witness used no CPU at all, which reads as the strongest possible
remedy signal — pure waiting — about a row for which nothing was measured.
That is the fabricated zero the outcome column already closed, one column
over.

Green by execution, with the discrimination proven rather than assumed:

  witness_row_cost_receipt_distinguishes_unexecuted_from_sub_millisecond
    gains a wall-only fixture, and goes RED when the renderer is changed
    to `unwrap_or(0)` — failing on the exact fabricated cell:
      cpu_clock_not_sampled  4  0  0  0  Done
    It also asserts the two clocks are independent carriers (500us wall
    against 300us cpu, so a producer filling both from one figure would
    be caught) and that the two columns are adjacent in the header.
  cargo test --bin claim_executor  68 passed, 0 failed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Aug 5, 2026
* WIP: Witness cost/purpose/admission: retire long/ as authority

* WIP: Witness cost/purpose/admission: retire long/ as authority

* WIP: Witness cost/purpose/admission: retire long/ as authority

* Retire the wall nickname: durations carry their clock (7820B)

The operator's 2026-08-05 ruling: recording both clocks is correct; the
defect is a duration whose meaning lives only in its field NAME. This is
the observation-authority half of that ruling (7820A landed the seed half
in #7820).

std.observation gains ClockBasis = CpuClock | WallClock and
TimedMeasurement { basis, elapsed }, and two carriers stop naming their
clock in prose:

  ObservationOutcome.TimedOut  now carries `basis`, so a kill says WHICH
    cap it crossed — a 5000ms thread-CPU fail-stop and a 600000ms wall
    receipt ceiling were previously indistinguishable, and the CI line
    now renders the clock beside both figures.
  ObservationEvent.wall        becomes `durations: List<TimedMeasurement>`.
    A list rather than one tagged duration because the seed already holds
    both clocks for every occurrence (run_claim_measured), and because
    the operator ruled thread CPU is the REMEDY DISCRIMINATOR beside a
    wall threshold: high wall + high CPU is algorithm or repeated
    evaluation, high wall + low CPU is waiting, I/O or scheduling. One
    clock cannot make that call.

A record with `cpu` and `wall` fields would have been the nickname twice,
which is what the operator refused when 7820A's first draft proposed cpu
as a third measured quantity beside wall and rss.

The payoff is a construction wall, not a rename: witness_row_cost_verdict
now takes the observed clock, WitnessRowCostDatedBasis carries its own,
and a cross-clock comparison answers BasisClockMismatch — a fourth arm,
not a Bool collapse, on the same reasoning std.content_hash refuses
cross-family comparison. Comparing a CPU figure against a wall baseline
used to typecheck and answer confidently; four sessions spent an evening
doing exactly that.

Not walled, and said so on the carrier: two entries may share one basis.
The construction that would forbid it is a total function from a closed
sum, which this substrate lacks (Map is a closure, not wire-serializable,
and refused by the determinism gate). So observation_duration_of REFUSES
an ambiguous read with the duplicate as its cause rather than silently
picking the first — rung mechanically preventable, ceiling structurally
impossible, trigger named.

Green by execution with discriminating REDs, all run locally:
  witness_row_cost_projection_holds     PASS; RED when the basis filter
    is removed from observation_clock_lookup (the silent first-match pick)
  witness_row_cost_drift_comparator_holds PASS incl. two new cross-clock
    controls on BOTH sides of the 2x ratio, so the refusal is proven to
    be decided by the clock and not by the magnitude; RED when the
    comparator stops checking it
  floor_component_receipt (15), observation_model (36), ci_render (19),
  tty_render (16), seed_scoped_run (10), crawl_replay (3)  all PASS

ClockBasis is exported vocabulary: gunbc#7831 states WallClock in its own
policy carrier and rebases onto this.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* State where the clock wall runs and where it does not

The .dag verdict authority now refuses a cross-clock comparison, but the
production falsifier receipt does not reach it: the seed calls only
witness_row_cost_exceeds_basis and rebuilds the verdict arms in Rust, so
the clock never crosses that seam.

That comparison is still correct today — both sides are wall — but for a
reason about the current producers rather than about the mechanism, which
is exactly the state this ruling exists to end. Said on the carrier with
its next trigger, so the rung is not inflated to cover a path the wall
does not stand on.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* WIP: Witness cost/purpose/admission: retire long/ as authority

* Fix the seed decode path for the tagged eval durations

The row's eval term became List<TimedMeasurement>, and the seed's
extractor still called nanosecond_count on it — so production
project_witness_cost_receipt refused with "cannot access field 'count' on
List" while every .dag witness stayed green, because none of them cross
that Rust seam.

Found two ways, independently: by running the existing
production_witness_cost_projection_* Rust tests (2 of 3 failed), and by
review 48651, which prescribed the same remedy. Worth naming why CI would
not have: nextest was removed from CI in 2026-07-11, so those tests run
locally only, and the witness corpus proves the .dag projection rather
than the transport that reads it.

The fix reads ONE clock through the authored projection rather than
walking the list in Rust: witness_cost_clock_nanos calls
std.observation.observation_duration_of, the same accessor every .dag
consumer uses, so the seed cannot grow a second copy of the lookup or of
its ambiguity refusal. Which clock it wants is now a thing it has to say,
and it says wall — the clock the witness threshold is stated on.

An unsampled clock comes back None, never 0, matching the unmeasured-cell
discipline the sibling receipt already keeps. Wall coming back None
refuses: the authored projection already guarantees a wall figure, so its
absence here means the row reached the transport without the one
measurement the receipt exists to carry.

  production_witness_cost_projection_preserves_exact_nanoseconds_and_ordering  ok
  production_witness_cost_projection_preserves_failed_and_refused              ok
  production_witness_cost_projection_refuses_missing_and_duplicate_parent      ok

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot added a commit that referenced this pull request Aug 5, 2026
…econstruction (#7844)

* WIP: Witness cost/purpose/admission: retire long/ as authority

* WIP: Witness cost/purpose/admission: retire long/ as authority

* WIP: Witness cost/purpose/admission: retire long/ as authority

* Retire the wall nickname: durations carry their clock (7820B)

The operator's 2026-08-05 ruling: recording both clocks is correct; the
defect is a duration whose meaning lives only in its field NAME. This is
the observation-authority half of that ruling (7820A landed the seed half
in #7820).

std.observation gains ClockBasis = CpuClock | WallClock and
TimedMeasurement { basis, elapsed }, and two carriers stop naming their
clock in prose:

  ObservationOutcome.TimedOut  now carries `basis`, so a kill says WHICH
    cap it crossed — a 5000ms thread-CPU fail-stop and a 600000ms wall
    receipt ceiling were previously indistinguishable, and the CI line
    now renders the clock beside both figures.
  ObservationEvent.wall        becomes `durations: List<TimedMeasurement>`.
    A list rather than one tagged duration because the seed already holds
    both clocks for every occurrence (run_claim_measured), and because
    the operator ruled thread CPU is the REMEDY DISCRIMINATOR beside a
    wall threshold: high wall + high CPU is algorithm or repeated
    evaluation, high wall + low CPU is waiting, I/O or scheduling. One
    clock cannot make that call.

A record with `cpu` and `wall` fields would have been the nickname twice,
which is what the operator refused when 7820A's first draft proposed cpu
as a third measured quantity beside wall and rss.

The payoff is a construction wall, not a rename: witness_row_cost_verdict
now takes the observed clock, WitnessRowCostDatedBasis carries its own,
and a cross-clock comparison answers BasisClockMismatch — a fourth arm,
not a Bool collapse, on the same reasoning std.content_hash refuses
cross-family comparison. Comparing a CPU figure against a wall baseline
used to typecheck and answer confidently; four sessions spent an evening
doing exactly that.

Not walled, and said so on the carrier: two entries may share one basis.
The construction that would forbid it is a total function from a closed
sum, which this substrate lacks (Map is a closure, not wire-serializable,
and refused by the determinism gate). So observation_duration_of REFUSES
an ambiguous read with the duplicate as its cause rather than silently
picking the first — rung mechanically preventable, ceiling structurally
impossible, trigger named.

Green by execution with discriminating REDs, all run locally:
  witness_row_cost_projection_holds     PASS; RED when the basis filter
    is removed from observation_clock_lookup (the silent first-match pick)
  witness_row_cost_drift_comparator_holds PASS incl. two new cross-clock
    controls on BOTH sides of the 2x ratio, so the refusal is proven to
    be decided by the clock and not by the magnitude; RED when the
    comparator stops checking it
  floor_component_receipt (15), observation_model (36), ci_render (19),
  tty_render (16), seed_scoped_run (10), crawl_replay (3)  all PASS

ClockBasis is exported vocabulary: gunbc#7831 states WallClock in its own
policy carrier and rebases onto this.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* State where the clock wall runs and where it does not

The .dag verdict authority now refuses a cross-clock comparison, but the
production falsifier receipt does not reach it: the seed calls only
witness_row_cost_exceeds_basis and rebuilds the verdict arms in Rust, so
the clock never crosses that seam.

That comparison is still correct today — both sides are wall — but for a
reason about the current producers rather than about the mechanism, which
is exactly the state this ruling exists to end. Said on the carrier with
its next trigger, so the rung is not inflated to cover a path the wall
does not stand on.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* WIP: Witness cost/purpose/admission: retire long/ as authority

* Fix the seed decode path for the tagged eval durations

The row's eval term became List<TimedMeasurement>, and the seed's
extractor still called nanosecond_count on it — so production
project_witness_cost_receipt refused with "cannot access field 'count' on
List" while every .dag witness stayed green, because none of them cross
that Rust seam.

Found two ways, independently: by running the existing
production_witness_cost_projection_* Rust tests (2 of 3 failed), and by
review 48651, which prescribed the same remedy. Worth naming why CI would
not have: nextest was removed from CI in 2026-07-11, so those tests run
locally only, and the witness corpus proves the .dag projection rather
than the transport that reads it.

The fix reads ONE clock through the authored projection rather than
walking the list in Rust: witness_cost_clock_nanos calls
std.observation.observation_duration_of, the same accessor every .dag
consumer uses, so the seed cannot grow a second copy of the lookup or of
its ambiguity refusal. Which clock it wants is now a thing it has to say,
and it says wall — the clock the witness threshold is stated on.

An unsampled clock comes back None, never 0, matching the unmeasured-cell
discipline the sibling receipt already keeps. Wall coming back None
refuses: the authored projection already guarantees a wall figure, so its
absence here means the row reached the transport without the one
measurement the receipt exists to carry.

  production_witness_cost_projection_preserves_exact_nanoseconds_and_ordering  ok
  production_witness_cost_projection_preserves_failed_and_refused              ok
  production_witness_cost_projection_refuses_missing_and_duplicate_parent      ok

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Put the drift comparator on the clock wall, and delete the Rust arm reconstruction

The follow-up gunbc#7837's witness_row_cost_clock_mismatch_note declared,
now dissolved in place rather than left as a note.

That PR grew a cross-clock refusal on the .dag comparator, and the
production falsifier cadence could not reach it: the seed called only
witness_row_cost_exceeds_basis, the bare ratio predicate, and rebuilt
DriftExceeded / WithinBasis / BasisAbsent as Rust string literals. Two
defects in one shape — a second representation of WitnessRowCostVerdict,
and a seam the clock never crossed, so a CPU figure against a wall basis
would still have answered confidently. It was correct only because both
sides happened to be wall, which is a fact about the producers and not a
property of the mechanism.

Three parts, and the third is the load-bearing one:

  Both basis files carry a REQUIRED per-row clock cell. An unstated clock
  refuses at parse and an unmodelled one refuses too — never a default to
  wall, which would be right for every row today and silently wrong the
  first time someone seeds from a CPU receipt. The 1176 existing rows are
  stamped wall because that is what they ARE: before the ruling the seed's
  PerformanceReceipt held only wall_nanos.

  The seed calls witness_row_cost_seed_verdict_dated / _undated and
  renders the arm the AUTHORITY named. It constructs no carrier — the
  Optional stays inside .dag and whether a dated basis exists is the map
  lookup the seed already had, which is data presence, not judgement.

  The Rust arm reconstruction is DELETED, not kept beside the carrier. An
  arm added to WitnessRowCostVerdict now reaches the cadence receipt with
  no Rust edit, and BasisClockMismatch is counted on its own line because
  its remedy differs from BasisAbsent's: fix the producer handing over the
  wrong clock, versus seed the missing row.

Both comparators move together — the compile-clean cost drift shares this
parser and authority by design, so leaving it on the old predicate would
have forked what it was built to share.

Green by execution, with the discrimination named:

  drift_verdicts_come_from_the_authority_and_a_cross_clock_basis_refuses
    asserts the cross-clock refusal on BOTH sides of the 2x ratio (21ms
    and 20ms against a 10ms basis), so it is proven decided by the clock
    and not by the magnitude. This is the ONLY test that crosses this Rust
    seam — the .dag witnesses cannot reach it and the parser tests only
    show the cell is read.
  parse_witness_row_cost_basis_line_requires_srv_fleet_arm64  gains a
    cpu-clock positive, a missing-clock refusal, and an unknown-clock
    refusal.
  committed_witness_row_cost_basis_loads_and_excludes_the_censored_row  ok
    over all 1176 migrated rows.

ObservationAbsent stays decided seed-side, deliberately: an absent
observation has no counterpart in the sum, and giving it one would let a
row with no measurement reach a comparator at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Count clock_mismatch on the compile-clean receipt line too

review 48672, correctly: the sibling witness-row-cost path reports
clock_mismatch on its [receipt] summary and the compile-clean path did
not, so the two receipts disagreed about whether the state this change
exists to expose is worth surfacing.

The summary line is where a reader looks to see whether a state fired.
A degradation that is counted internally but omitted from the line
someone actually reads is the counting half-done: its frequency is
observable in principle and invisible in practice.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Merge main (#7837 squash-merged) into the drift lane

One conflict, in witness_row_cost_clock_mismatch_note, and it is the note
this PR exists to rewrite: main carries #7837's version declaring the
production drift path as not-yet-covered with its trigger named, and this
branch carries the version saying the wall now runs there. Resolved to
ours, because this PR is what makes that true — the seed calls the
authored verdict and the Rust arm reconstruction is gone.

Green by execution on the resolved tree: witness_row_cost_projection_holds
and witness_row_cost_drift_comparator_holds both PASS, cargo check clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Aug 5, 2026
* WIP: Witness cost/purpose/admission: retire long/ as authority

* WIP: Witness cost/purpose/admission: retire long/ as authority

* WIP: Witness cost/purpose/admission: retire long/ as authority

* Retire the wall nickname: durations carry their clock (7820B)

The operator's 2026-08-05 ruling: recording both clocks is correct; the
defect is a duration whose meaning lives only in its field NAME. This is
the observation-authority half of that ruling (7820A landed the seed half
in #7820).

std.observation gains ClockBasis = CpuClock | WallClock and
TimedMeasurement { basis, elapsed }, and two carriers stop naming their
clock in prose:

  ObservationOutcome.TimedOut  now carries `basis`, so a kill says WHICH
    cap it crossed — a 5000ms thread-CPU fail-stop and a 600000ms wall
    receipt ceiling were previously indistinguishable, and the CI line
    now renders the clock beside both figures.
  ObservationEvent.wall        becomes `durations: List<TimedMeasurement>`.
    A list rather than one tagged duration because the seed already holds
    both clocks for every occurrence (run_claim_measured), and because
    the operator ruled thread CPU is the REMEDY DISCRIMINATOR beside a
    wall threshold: high wall + high CPU is algorithm or repeated
    evaluation, high wall + low CPU is waiting, I/O or scheduling. One
    clock cannot make that call.

A record with `cpu` and `wall` fields would have been the nickname twice,
which is what the operator refused when 7820A's first draft proposed cpu
as a third measured quantity beside wall and rss.

The payoff is a construction wall, not a rename: witness_row_cost_verdict
now takes the observed clock, WitnessRowCostDatedBasis carries its own,
and a cross-clock comparison answers BasisClockMismatch — a fourth arm,
not a Bool collapse, on the same reasoning std.content_hash refuses
cross-family comparison. Comparing a CPU figure against a wall baseline
used to typecheck and answer confidently; four sessions spent an evening
doing exactly that.

Not walled, and said so on the carrier: two entries may share one basis.
The construction that would forbid it is a total function from a closed
sum, which this substrate lacks (Map is a closure, not wire-serializable,
and refused by the determinism gate). So observation_duration_of REFUSES
an ambiguous read with the duplicate as its cause rather than silently
picking the first — rung mechanically preventable, ceiling structurally
impossible, trigger named.

Green by execution with discriminating REDs, all run locally:
  witness_row_cost_projection_holds     PASS; RED when the basis filter
    is removed from observation_clock_lookup (the silent first-match pick)
  witness_row_cost_drift_comparator_holds PASS incl. two new cross-clock
    controls on BOTH sides of the 2x ratio, so the refusal is proven to
    be decided by the clock and not by the magnitude; RED when the
    comparator stops checking it
  floor_component_receipt (15), observation_model (36), ci_render (19),
  tty_render (16), seed_scoped_run (10), crawl_replay (3)  all PASS

ClockBasis is exported vocabulary: gunbc#7831 states WallClock in its own
policy carrier and rebases onto this.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* State where the clock wall runs and where it does not

The .dag verdict authority now refuses a cross-clock comparison, but the
production falsifier receipt does not reach it: the seed calls only
witness_row_cost_exceeds_basis and rebuilds the verdict arms in Rust, so
the clock never crosses that seam.

That comparison is still correct today — both sides are wall — but for a
reason about the current producers rather than about the mechanism, which
is exactly the state this ruling exists to end. Said on the carrier with
its next trigger, so the rung is not inflated to cover a path the wall
does not stand on.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* WIP: Witness cost/purpose/admission: retire long/ as authority

* Fix the seed decode path for the tagged eval durations

The row's eval term became List<TimedMeasurement>, and the seed's
extractor still called nanosecond_count on it — so production
project_witness_cost_receipt refused with "cannot access field 'count' on
List" while every .dag witness stayed green, because none of them cross
that Rust seam.

Found two ways, independently: by running the existing
production_witness_cost_projection_* Rust tests (2 of 3 failed), and by
review 48651, which prescribed the same remedy. Worth naming why CI would
not have: nextest was removed from CI in 2026-07-11, so those tests run
locally only, and the witness corpus proves the .dag projection rather
than the transport that reads it.

The fix reads ONE clock through the authored projection rather than
walking the list in Rust: witness_cost_clock_nanos calls
std.observation.observation_duration_of, the same accessor every .dag
consumer uses, so the seed cannot grow a second copy of the lookup or of
its ambiguity refusal. Which clock it wants is now a thing it has to say,
and it says wall — the clock the witness threshold is stated on.

An unsampled clock comes back None, never 0, matching the unmeasured-cell
discipline the sibling receipt already keeps. Wall coming back None
refuses: the authored projection already guarantees a wall figure, so its
absence here means the row reached the transport without the one
measurement the receipt exists to carry.

  production_witness_cost_projection_preserves_exact_nanoseconds_and_ordering  ok
  production_witness_cost_projection_preserves_failed_and_refused              ok
  production_witness_cost_projection_refuses_missing_and_duplicate_parent      ok

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Put the drift comparator on the clock wall, and delete the Rust arm reconstruction

The follow-up gunbc#7837's witness_row_cost_clock_mismatch_note declared,
now dissolved in place rather than left as a note.

That PR grew a cross-clock refusal on the .dag comparator, and the
production falsifier cadence could not reach it: the seed called only
witness_row_cost_exceeds_basis, the bare ratio predicate, and rebuilt
DriftExceeded / WithinBasis / BasisAbsent as Rust string literals. Two
defects in one shape — a second representation of WitnessRowCostVerdict,
and a seam the clock never crossed, so a CPU figure against a wall basis
would still have answered confidently. It was correct only because both
sides happened to be wall, which is a fact about the producers and not a
property of the mechanism.

Three parts, and the third is the load-bearing one:

  Both basis files carry a REQUIRED per-row clock cell. An unstated clock
  refuses at parse and an unmodelled one refuses too — never a default to
  wall, which would be right for every row today and silently wrong the
  first time someone seeds from a CPU receipt. The 1176 existing rows are
  stamped wall because that is what they ARE: before the ruling the seed's
  PerformanceReceipt held only wall_nanos.

  The seed calls witness_row_cost_seed_verdict_dated / _undated and
  renders the arm the AUTHORITY named. It constructs no carrier — the
  Optional stays inside .dag and whether a dated basis exists is the map
  lookup the seed already had, which is data presence, not judgement.

  The Rust arm reconstruction is DELETED, not kept beside the carrier. An
  arm added to WitnessRowCostVerdict now reaches the cadence receipt with
  no Rust edit, and BasisClockMismatch is counted on its own line because
  its remedy differs from BasisAbsent's: fix the producer handing over the
  wrong clock, versus seed the missing row.

Both comparators move together — the compile-clean cost drift shares this
parser and authority by design, so leaving it on the old predicate would
have forked what it was built to share.

Green by execution, with the discrimination named:

  drift_verdicts_come_from_the_authority_and_a_cross_clock_basis_refuses
    asserts the cross-clock refusal on BOTH sides of the 2x ratio (21ms
    and 20ms against a 10ms basis), so it is proven decided by the clock
    and not by the magnitude. This is the ONLY test that crosses this Rust
    seam — the .dag witnesses cannot reach it and the parser tests only
    show the cell is read.
  parse_witness_row_cost_basis_line_requires_srv_fleet_arm64  gains a
    cpu-clock positive, a missing-clock refusal, and an unknown-clock
    refusal.
  committed_witness_row_cost_basis_loads_and_excludes_the_censored_row  ok
    over all 1176 migrated rows.

ObservationAbsent stays decided seed-side, deliberately: an absent
observation has no counterpart in the sum, and giving it one would let a
row with no measurement reach a comparator at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Count clock_mismatch on the compile-clean receipt line too

review 48672, correctly: the sibling witness-row-cost path reports
clock_mismatch on its [receipt] summary and the compile-clean path did
not, so the two receipts disagreed about whether the state this change
exists to expose is worth surfacing.

The summary line is where a reader looks to see whether a state fired.
A degradation that is counted internally but omitted from the line
someone actually reads is the counting half-done: its frequency is
observable in principle and invisible in practice.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Give the row-cost receipt its CPU column, beside the wall one

The last piece of the 2026-08-05 clock-basis ruling with a real consumer
gap. #7820 renamed eval_ms to eval_wall_ms and #7837 made the row carry
both clocks; nothing yet printed the second one, so the remedy that second
clock exists to discriminate could not be read from the artifact at all.

The seven-wide anonymous tuple becomes WitnessRowCost. That is not tidying:
a positional tuple is how `eval` came to mean "wall" by index and nothing
else — the same defect one layer below the ObservationEvent.wall field name
this lane retired — and it is exactly what would have made a second clock
"the third u128".

eval_cpu_ms sits immediately beside eval_wall_ms, asserted by the test
rather than left to convention, so an author reads the remedy from one file
without joining another: high wall with high CPU is algorithm or repeated
evaluation, high wall with low CPU is waiting, I/O, subprocess or
scheduling. It is not a second threshold — the witness threshold is stated
on wall.

An unsampled clock renders `unmeasured`, never 0. A `0` there would claim
the witness used no CPU at all, which reads as the strongest possible
remedy signal — pure waiting — about a row for which nothing was measured.
That is the fabricated zero the outcome column already closed, one column
over.

Green by execution, with the discrimination proven rather than assumed:

  witness_row_cost_receipt_distinguishes_unexecuted_from_sub_millisecond
    gains a wall-only fixture, and goes RED when the renderer is changed
    to `unwrap_or(0)` — failing on the exact fabricated cell:
      cpu_clock_not_sampled  4  0  0  0  Done
    It also asserts the two clocks are independent carriers (500us wall
    against 300us cpu, so a producer filling both from one figure would
    be caught) and that the two columns are adjacent in the header.
  cargo test --bin claim_executor  68 passed, 0 failed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Merge main (#7844 squash-merged) into the cpu-column lane

Three conflicts, all one shape: main's claim_executor.rs reads the row
positionally (row.0 / row.1 / row.2) because #7844 landed without cli_run.rs,
where this branch defines the named WitnessRowCost. Resolved to ours at all
three, which is the only consistent resolution -- our cli_run.rs is what
declares the struct those field names read.

Verified: zero conflict markers tree-wide; cargo check --workspace
--all-targets clean.

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant