Skip to content

Model the GitHub ruleset as a converged .dag authority: desired ruleset -> apply -> READ BACK -> verify, following gunbc.repo_local_git_config's binding pattern, so 'witnesses is the one required context' stops being a hand-maintained web setting invisible to the tree - #9449

Closed
gunbai-bot[bot] wants to merge 3 commits into
mainfrom
session/wise-swift-875

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Auto-opened by session-dashboard for session wise-swift-875.
Pushing to session/wise-swift-875 advances this PR.

Worker attestation

Before flipping this PR to ready for review, confirm each item:

  • Title describes the change (not the session id or branch).
  • PR body summarises what and why (replace the TODO below).
  • Tests run: name the command (e.g. npm test, cargo test) and the result.
  • If this closes a work item, the body contains a Closes #N directive.
  • No commits on this branch are surprises (no fork/cherry-pick I did not make).
  • No secrets / credentials / large binaries staged.

Summary

TODO: replace this paragraph with one or two sentences naming the change and its motivation. Reviewers read this first.

Test plan

  • TODO: list the commands that ran (or "no tests changed; relied on CI") and the outcome.

gunbc-ci-auto-heal and others added 3 commits August 27, 2026 04:29
….dag authority

DESIGN's Building & checks bullet states, as the fact the whole two-lane
split turns on, that this repository's `passing CI` ruleset is active,
carries no bypass actors, and names exactly ONE required status check --
`witnesses`. Until now that sentence was the only place the fact lived on
our side of the boundary. Nothing declared it, nothing read it back, and
nothing in the tree went red if it changed: specification without
execution, at the outermost boundary the project has.

`extdeps.github.rulesets` models the upstream interface -- rulesets,
enforcement, targets, rule types, bypass standing, and the whole-ruleset
PUT -- and nothing about what this repository wants. `gunbc.repo_ruleset`
owns the policy and follows `gunbc.repo_local_git_config`'s binding
pattern exactly: desired -> observe -> reconcile -> apply -> READ BACK ->
verify, with convergence claimed only from the post-apply read and never
from the apply's own 200.

The §3 win is that the required context's name is IMPORTED from
`gunbc.witness_floor_workflow` `witness_floor_workflow_job_id` -- the row
the emitted workflow names its aggregation job with -- so renaming the job
can no longer leave the ruleset naming a context nothing publishes, which
is the failure that shows up as a check stuck pending rather than red.

Every observation and verdict is typed rather than a Bool: three ways a
read can fail (status refusal / transport refusal / undecodable body,
never collapsed into an empty ruleset), three states for the status-check
rule (absent / exactly these / more than one, so "no rule" and "no
contexts" cannot render alike), and fourteen named divergences.
Ownership is Owned rather than Ensured -- the opposite of
repo_local_git_config's choice -- because "witnesses is the ONE required
context" is a claim about the roster, so an extra context must plan a
removal rather than be refused.

EXECUTED, not typechecked. `verify` runs green against the live ruleset,
and RED with a planted extra desired context (`required context missing:
a-context-nothing-publishes`, exit 1). All ten witness bodies execute
true, including a positive control that a desired-shaped observation
diverges in nothing. `converge` was NOT executed: it writes to GitHub and
the live ruleset already converges, so there was nothing to apply.

NOT CLAIMED: neither entry point is enrolled in CI. `verify` is a route
somebody runs, so the class climbs from unobservable to *mitigatable* --
drift is detectable, not detected. Enrolling it as a required phase is a
separate change under its own operator agreement, and is named as this
row's next-rung trigger.

The DESIGN bullet and two notes in `gunbc.witness_floor_workflow` said
the ruleset is not a `.dag` fact. It is one now, so those are corrected in
place rather than left as knowingly-false recitals -- while keeping what
did not change: a converged authority actuates and detects, it does not
gate, so the aggregation job's window argument stands untouched.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
review 56496, and it is right. `bypass_divergences` matched `BypassNever`
and collapsed everything else into one `_` arm emitting a single static
sentence -- total over the type and blind one level down, the exact
pattern the rest of this module is written to avoid.

Three facts sat under that wildcard with three different remedies.
`pull_requests_only` and `always` are real, DIFFERENT bypass grants, and
which one it is decides which role to revoke. `UnrecognizedBypassStanding`
is not a permissive ruleset at all -- it means GitHub's vocabulary moved
and this module's reading is no longer established, whose remedy is to
extend the parser. Its `raw` payload was discarded, which is the only
thing that says what to extend the parser WITH.

So: `RulesetBypassStandingUnrecognized { raw }` is its own divergence, the
two grants are named arms carrying the observed label the way the
neighbouring `RulesetEnforcementDrift` / `RulesetTargetDrift` arms already
did, and `ruleset_bypass_standing_wire_label` lands beside the other
wire-label projections in extdeps rather than being spelled here.

MUTATION RECEIPT, because the existing witness did not catch this and it
is worth recording why. `w_RED_a_reader_that_may_bypass_is_a_divergence`
COUNTED divergences, and a wildcard defeats counting -- it stayed true
under both shapes. The new
`w_RED_the_three_non_never_bypass_standings_render_differently`
DISCRIMINATES: executed against the pre-fix collapsed form it returns
false, against the split form true. All 11 witness bodies execute true on
the fixed tree; live `verify` still exits 0 against the real ruleset.

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

#9404 merged at 13:15:42Z. The three files it added -- gunbc.repo_ruleset,
extdeps.github.rulesets and the witness module -- are on main and are
BYTE-IDENTICAL to this branch's copies. Because the merge was a squash,
the branch kept its own two commits, which is the only reason GitHub
renders a diff for #9449 at all.

The real content delta ran the other way: main was 25 commits ahead, so
 was 125 files and 17,238 deletions --
src/v2/std/effect_reach.dag, src/v2/workflow/required_floor.dag,
src/v2/std/text.dag and others. Merging that PR would have DELETED 25
commits of landed work from main. The conflict was the symptom; a rebase
would have preserved the hazard rather than removing it.

So this merge resolves every path to main. That is not picking a side over
authority-derived bytes: main's content is a strict superset of this
branch's here, since this branch's own contribution is already in it
unchanged. The check is exact rather than argued -- the resulting tree is
identical to origin/main, whole-tree, so #9449's diff is now empty and it
can neither revert anything nor land anything.

DESIGN.md reached the generated-artifact merge driver, which correctly
REFUSED rather than answering true. Its regeneration recipe is the right
remedy when both sides carry distinct authority-derived content; it does
not apply when one side is a subset of the other and the result is proven
equal to main byte-for-byte.

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

gunbai-bot Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

Conflict resolved by merging main — but the resolution is not the one the request assumed, so here is what was actually wrong.

This branch had no content left to land. #9404 merged at 13:15:42Z; this PR was opened ~10 minutes later from the same branch. Its three files — gunbc.repo_ruleset, extdeps.github.rulesets, and the witness module — are already on main and were byte-identical to this branch's copies. Because #9404 was squash-merged, the branch kept its own two commits, and that is the only reason GitHub rendered a diff here at all.

The real delta ran the other way. main was 25 commits ahead, so git diff origin/main <branch> was 125 files, 17,238 deletions — src/v2/std/effect_reach.dag, src/v2/workflow/required_floor.dag, src/v2/std/text.dag and others. Merging this PR would have deleted 25 commits of landed work from main. The conflict was the symptom of that, not an independent problem: a rebase would have made the PR mergeable while preserving the hazard.

So every path resolves to main. That is not picking a side over authority-derived bytes — main's content is a strict superset here, since this branch's own contribution is in it unchanged. The check is exact rather than argued: the resulting tree is identical to origin/main whole-tree, so this PR is now 0 files / +0 / −0 and can neither revert anything nor land anything.

DESIGN.md reached the generated-artifact merge driver, which correctly refused rather than answering true. Its regeneration recipe is right when both sides carry distinct authority-derived content; it does not apply when one side is a subset of the other and the result is proven equal to main byte-for-byte.

Recommendation: close this PR as a duplicate of the merged #9404. I have left it in draft rather than closing it, since it is bot-created and closing it is yours to call. It is now empty, so it is harmless either way. (One clause of the merge commit message was eaten by shell backtick substitution — the numbers in it are correct; the missing fragment is the git diff invocation quoted above.)

— sent from wise-swift-875

@gunbai-bot

gunbai-bot Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

Investigated. There is no fix to push, and I recommend against a re-run.

The check did not fail — the run was cancelled. Run 33092943293 has conclusion: cancelled, run_attempt: 1. required-witnesses-build passed (49m24s). required-witnesses-floor was cancelled at 51m07s, mid-fold at floor: evaluating 10000 / 11821 — well under its 180-minute limit, so not a job timeout. The aggregator then reports red in 5s, which is correct behaviour, not a second failure: it runs under always(), reads both lane results, and refuses unless both are success. DESIGN records exactly this — "a lawfully superseded run now reports this context red rather than cancelled, which is the correct reading rather than a regression."

Nothing in this PR can be the cause, and that is checkable rather than argued: the PR is 0 files / +0 / −0. Its tree was made identical to main. There is no line of content here that CI could be failing on, so any "fix" would be a no-op commit pushed solely to trigger a re-run — which is the change-detector move, not a repair.

Two observations from the run worth recording, neither actionable here: the floor heartbeat before cancellation showed rss_kb=13719600 (~13 GiB, against the ~9.4 GiB peak DESIGN cites) with pswpin=3236545 and pgmajfault=2061669 — heavy swap on srv4-12; and cleanup logged Terminate orphan process: pid (3142024) (claim_executor). That points at host memory pressure rather than at any authored change. It is a real signal about the floor's cost on a shared runner, and it belongs to whoever owns that lane, not to an empty PR.

Why I am not re-running either. The floor lane costs ~50 minutes of runner time, and main currently has five-plus runs in progress or queued. Spending two lanes' worth of a starved runner pool to turn a cancelled check green on a PR that must never merge anything buys zero information and delays main.

The standing recommendation is unchanged and now firmer: close this PR as a duplicate of the merged #9404. The branch has already drifted 16 commits behind main again since the merge commit, so keeping it green is an open-ended cost against a PR with nothing to land.

— sent from wise-swift-875

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