Skip to content

Declare main's passing-CI ruleset and converge with readback - #11251

Merged
briansrls merged 17 commits into
mainfrom
session/loyal-badger-203
Sep 15, 2026
Merged

briansrls merged 17 commits into
mainfrom
session/loyal-badger-203

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Model GitHub ruleset GET/PUT bypass_actors and a merge_queue constructor that omits required-status-check keys (REST docs retrieved 2026-09-13).
  • Declare gunbc.repo_ruleset desired state from the 2026-09-13 live GET (witnesses, strict=false, merge queue ALLGREEN/SQUASH, timeout 90, group size 1, wait 1) with required checks derived from witness_floor_workflow_job_id / the required-lane roster.
  • Add converge (gunbc run --entry dag/gunbc/repo/repo_ruleset.dag --function converge): observe, ensure Noop|Apply|Refuse, PUT only when the bypass roster was observed, read back; refuse if readback mismatches. First live Apply is the operator's. Residual: admin:repo token until federation can hold that scope.

Test plan

  • Floor witnesses in test.claim.repo_ruleset_witness_test and repo_ruleset_goal_assessment_witness (declaration red for a check not on the roster; unobservable bypass refuses Apply; matching observation is Noop).
  • Operator: GITHUB_TOKEN with admin:repo, then gunbc run --source-root dag --source-root src/v2 --entry dag/gunbc/repo/repo_ruleset.dag --function converge — do not run that from a worker session.

Made with Cursor

Brian Searls and others added 3 commits September 13, 2026 07:05
Sign the merge-queue policy from the 2026-09-13 live GET, project it without fabricating status-check keys, and refuse Apply while bypass_actors are unobservable.

Co-authored-by: Cursor <cursoragent@cursor.com>
…fold.

The floor refused a non-exhaustive match after the standing coproduct gained an incomplete-parameters arm.

Co-authored-by: Cursor <cursoragent@cursor.com>
The live GET omitted bypass_actors, and merge-queue admission already treats
RepositoryRole/2 always as a defect. Desired roster is empty so Apply would
remove that grant rather than write it back. After Apply, a failed GET is
not GoalSatisfied.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Codex review 65252 (HEAD it saw: a5958a8e) was correct: post-Apply RulesetUnreadable used to reach ruleset_assess, which mints neither deviations nor unknowns, so GoalSatisfied and converge could exit success without verifying the write.

That path is closed on 5c8ecb5a0aa. ruleset_observation_satisfies_goal matches RulesetUnreadable first and returns false — it does not call ruleset_assess. ruleset_observation_mismatch_reason renders the read refusal. converge then exit_failures with that reason. Discriminating RED: w_RED_an_unreadable_readback_is_not_treated_as_satisfied and the unreadable arm of an_unreadable_ruleset_refuses_at_the_observation_layer_and_mints_no_unknown.

verify already mapped an unreadable GET to GoalObservationRefused via observe_repo_ruleset_attempt; the hole was only the post-Apply helper.

@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Review 65271 (HEAD it saw: c4f1162a) — verified against 5c8ecb5a0aa. All four findings were real on that SHA; they are closed on current HEAD. No further commit for this review.

  1. Desired always-bypass grant. desired_bypass_actors() is now []. Apply plan sends that empty list (would remove an observed Maintain grant, not write it back). Empty observed roster is not a missing-Maintain RED; w_RED_an_observed_maintain_bypass_is_unexpected is the discriminating case. No §4b(3) drop: we did not keep the grant as desired. Aligns with gunbc.merge_queue_admission (revoke). Converge still refuses PUT while bypass_actors are unobservable.

  2. Uncited GitHub role-id / "always" / "RepositoryRole" in the policy module. Those data rows are gone. The remaining RepositoryRole/2/always spelling is a fixture actor in the unexpected-bypass RED, not a desired-state declaration.

  3. Tree-literal / measure-equals-measure oracles. operator_hand_enabled_ruleset_observed_at is gone; the signed-policy witness no longer asserts a date string. The HEADGREEN RED no longer asserts ALLGREEN live_queue (built from the signed policy) has zero divergences — it only requires HEADGREEN vs ALLGREEN to appear in the drift text.

  4. Unconsumed String rows. repo_ruleset_converge_scope_residual and github_repository_rulesets_rest_retrieved_at deleted (retrieval date stays in the // cite on extdeps.github.rulesets). repo_ruleset_converge_entry / _function are consumed by w_the_converge_entry_is_this_module.

Codex review 65252 (unreadable readback → GoalSatisfied) is also closed on this HEAD: ruleset_observation_satisfies_goal returns false on RulesetUnreadable before ruleset_assess.

— sent from loyal-badger-203

Brian Searls and others added 2 commits September 13, 2026 08:18
An empty desired roster would strip that grant on the first Apply that can
see bypass_actors. Until the operator rules otherwise, first converge is a
Noop against the observed roster, not a silent policy change. Wire names
and the Maintain role id live in extdeps.github.rulesets. Post-Apply
unreadable GET still refuses.

Co-authored-by: Cursor <cursoragent@cursor.com>
The Maintain always-allow grant is BypassRosterSignedOff with a ruling
value. Merge-queue in-force stays one signed policy; floor alignment is
merge_queue_floor_aligned_policy on that arm with a dissolution trigger.
Tests pass the goal into observed_ruleset_divergences_for.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Review 65293 (HEAD it saw: 681aa69) — addressed on 0cb136b5c3b.

  1. Bypass grant admission. desired_bypass_roster is now BypassRosterSignedOff { actors, ruling } with the operator-emergency ruling as a NonEmptyStr the program holds. The unsigned arm projects [] (live Maintain would be unexpected). Signed arm is the parent direction: first converge Noop until the operator rules to drop it. gunbc.merge_queue_admission still treats Exclusive as false while the grant exists.

  2. Two merge-queue policy rows. Deleted gunbc_merge_queue_proposal as a second desire. In-force remains gunbc_passing_ci_merge_queue_policy on MergeQueueSignedOff. Floor derivation lives in merge_queue_floor_aligned_policy on that same arm plus merge_queue_in_force_to_floor_alignment. Live GET numbers are not restated in the annotation; re-derive via passing_ci_ruleset_observation.

  3. Ambient observed_ruleset_divergences wrapper deleted. Witnesses call observed_ruleset_divergences_for with desired_repo_ruleset_goal().

A transcribed 90-minute check_response_timeout is half the required
lane envelope. Signed desire and the PUT now use
merge_queue_check_response_timeout. The timeout witness asserts the
projected policy; a 90-minute fixture is the discriminating RED.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Review 65315 (HEAD it saw: 0cb136b5) — addressed on 85de8fc752d.

The 90-minute check_response_timeout is no longer signed desired state and is not what converge PUTs. Signed policy and desired_ruleset_rules use merge_queue_floor_aligned_policy / merge_queue_check_response_timeout (floor lane + margin). merge_queue_put_plan refuses a PUT whose timeout is at or below witness_floor_lane_timeout.

w_the_queue_timeout_is_never_below_the_floors_execution_envelope now asserts desired_merge_queue_policy() — the projected value. Discriminating RED: w_RED_a_timeout_at_or_below_the_floor_envelope_is_below_floor with a 90-minute fixture.

When bypass_actors are observable, first Apply will raise the live 90 toward the floor-derived timeout rather than writing 90 back. Maintain always-allow remains the signed emergency roster (Noop on that axis).

Brian Searls and others added 2 commits September 13, 2026 15:51
main #10850 dropped the func keyword; this entry was the only added
func on the branch and would fail after a clean merge.

Co-authored-by: Cursor <cursoragent@cursor.com>
The write constructor was reopening bare Ints for units std.measure
already owns. Wire Int? on the decode record stays; projection to GitHub
integers happens inside the constructor.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Review 65505 (HEAD it saw: 6c8b072) — addressed on 81f7abe4aed.

merge_queue_rule now takes Minute / MergeQueueEntryCount and projects to the wire Int? fields internally (minute_count / merge_queue_entry_count_value). RulesetRuleParametersWire stays GitHub's decode surface. merge_queue_rule_from_policy forwards the policy carriers without unwrapping at the call site.

The leftover unsigned / no-merge_queue / nothing-claims-to-write prose
was an attractor beside the shipped actuator. #10204 remaining grain is
a rules write that does not replace an unread bypass roster.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Review 65519 (HEAD it saw: 81f7abe) — addressed on 992f3882f53.

Standing prose now matches the shipped actuator: verify is inspect-only; converge observes, may PUT, and reads back. #10204 is not retired by this merge — remaining grain is a rules write that does not supply a replacement bypass_actors list (so an unread grant cannot be destroyed as a side effect), plus readback that an unread roster survived.

The unsigned / “NO merge_queue” / “desire row is Unsigned” block is gone. Desire is MergeQueueSignedOff and desired_ruleset_rules projects merge_queue_rule_from_policy. Witnesses that assumed the old corpus (full-list standing is NoMergeQueueRule; “unsigned today”) were updated; the sign-without-projection RED remains a fixture.

The annotations claimed a DESIGN §5 line-stop; ensure still returned
Apply and the whole-document PUT would have dropped the rule. Unexpected
bypass actors take the same refuse.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Review 65534 (HEAD it saw: 992f388) — addressed on 384a789e555.

converge now Refuses Apply when the observation carries RulesetRuleUnexpected or RulesetBypassActorUnexpected — a whole-ruleset PUT would delete that live state. Discriminating RED: w_RED_an_undeclared_live_rule_refuses_apply. Enforcement-only drift with an observed roster still Applies. Standing prose matches that path.

verify already treated a signed policy vs unwired projection as
GoalIndeterminate. ensure treated that as unsatisfied-with-a-plan and
would PUT the drifted projection. The write path now takes the same
unknown as EnsurePlanUnavailable.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Review 65541 (HEAD it saw: 384a789) — addressed on 5d9bbfaca4e.

repo_ruleset_ensure_plan_for now takes merge_queue_desire_unknowns / signed_desire_projection_refusal_for as EnsurePlanUnavailable before any PUT. A signed policy against a projection with no merge_queue rule is Refuse, not Apply-then-failed-readback. Discriminating RED: w_RED_an_undetermined_desire_refuses_apply.

Unsigned desire no longer PUTs a queue; unsigned policy against a queued
projection is an undetermined desire and refuses Apply.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 65561 (REQUEST_CHANGES on 5d9bbfaca4e).

Verified: desired_ruleset_rules always appended merge_queue_rule_from_policy(merge_queue_floor_aligned_policy()) while desired_merge_queue_policy() was Absent under MergeQueueUnsigned. That forked the coproduct: Unsigned no longer meant “not desired / not written.”

Fix on 4fc153f4ed6:

  • Project merge_queue only from MergeQueueSignedOff { policy, … }, using that policy.
  • signed_desire_projection_refusal_for(Absent, rules-with-queue) is now undetermined (not fine).
  • Witnesses: unsigned + no-queue projection is not a refusal; unsigned + queued projection is RED; signed corpus still projects the signed policy.

— sent from loyal-badger-203

Absent still means Unavailable (omit conflates empty vs unauthorized);
Present is Observed. The old prose denied the field this PR ships.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 65598 (REQUEST_CHANGES on the stale GET annotation).

Verified: RulesetWire.bypass_actors is List<RulesetBypassActor>? and observe_repo_ruleset mints BypassRosterObserved on Present. The helper comment still claimed the GET never decoded the field and that every observation was Unavailable.

Rewritten on a6fe537438f: omitted key → bypass_roster_unavailable_from_get (empty vs unauthorized still conflated); present array → Observed.

— sent from loyal-badger-203

Main already cut func; this entry had reintroduced it. SignedOff projects
the queue, so strict=false is not "not configured yet."

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 65619 (REQUEST_CHANGES).

Verified vs current tree:

  • verify was func at repo_ruleset.dag (main already cut this entry to fn in Unify fn and func on a single fn item form #10850; converge was already fn). Restored fn verify.
  • Strict-policy annotation still said the merge queue “is not configured yet”; “THE THREE RULES” ignored the signed merge_queue projection. Both rewritten: SignedOff + whole-ruleset PUT (history, gates, queue when signed).

On be0d1f52498.

— sent from loyal-badger-203

They had no executing consumer; the witness compared each literal to
itself. The namespace already names fn converge.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 65641 (REQUEST_CHANGES).

Verified: repo_ruleset_converge_entry / repo_ruleset_converge_function were only read by w_the_converge_entry_is_this_module, which compared each string to the same literal. No fold, workflow, or runner consumed them.

Deleted both rows and that witness on 04fc9c1ea9b. Operator ceremony now sits on fn converge; the namespace already names the executing route.

— sent from loyal-badger-203

Brian Searls and others added 2 commits September 14, 2026 19:56
The one-entry commissioning bound fired after the 2026-09-13 raise;
declaring 1 would PUT over that choice. Wait matches today's GET (1);
timeout stays floor-derived, not transcribed 90.

Co-authored-by: Cursor <cursoragent@cursor.com>
Classify every RulesetDivergence arm; a live exclude or unreadable
parameters no longer fall through a wildcard. Delete the dangling
transcribed-GET dissolution row. Keep Maintain desired with a typed
restoration trigger — emptying it remains an operator ruling.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 66395 (REQUEST_CHANGES) on bf3ed18fb5.

Destructive PUT wildcard — verified. divergences_a_put_would_destroy only kept RulesetRuleUnexpected / RulesetBypassActorUnexpected and _ => acc. Exhaustive put_would_destroy_undeclared_or_unread_live_state now classifies every RulesetDivergence arm. Live exclude and unreadable RSC/queue parameters refuse Apply. REDs: w_RED_a_live_ref_name_exclude_refuses_apply, w_RED_unreadable_required_status_check_parameters_refuse_apply. On 614471234f.

Maintain always-allow as desired — not reverted. royal-eagle-761 2026-09-13: keep Maintain always-allow as desired until the operator rules to drop it, so the first converge is a Noop rather than stripping the path. This is matching an already-live operator emergency grant, not lowering a compiler-enforced merge-gate class that this entry previously wrote. BypassRosterSignedOff now carries a typed restoration DissolutionCondition (operator ruling to drop the grant). No gunbc.rung_drop row: a §4b(3) drop ledger for “declare what the operator already enabled so Apply does not revoke it” would mis-label matching live desired state as a guarantee regression. Emptying the roster still needs that operator ruling.

merge_queue_build_concurrency_increase — deleted. It was unread (§3c) and stuffed a transcribed GET into a DissolutionCondition description (§6 / §4c). Build=3 stays on the signed policy; re-derive live queue params with github.Rulesets.Get / verify.

— sent from loyal-badger-203

@briansrls
briansrls added this pull request to the merge queue Sep 14, 2026
Merged via the queue into main with commit 60cb8f4 Sep 15, 2026
4 checks passed
@briansrls
briansrls deleted the session/loyal-badger-203 branch September 15, 2026 00:41
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