Skip to content

Allow exact recent protected-main rollback rewinds in validate-rulespec - #141

Merged
MaxGhenis merged 8 commits into
mainfrom
hub/rollback-rewind-verifier
Oct 19, 2026
Merged

MaxGhenis merged 8 commits into
mainfrom
hub/rollback-rewind-verifier

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Why

An exact revert of a waiver-retiring re-encode can fail the decrement-only waiver gates. This first step admits an exact whole-tree restoration of a recent merged PR landing on the default branch. It supports modification-only windows: real reverts touching companion .test.yaml files, test files, or file additions still use the ordinary base today. Admitting those windows is the planned next step.

Changes

The proof requires an exact first-parent tree match within 20 commits and verified merged-PR metadata. The window may modify RuleSpec modules, any .json under .axiom/encoding-manifests/, the waiver ledger, and its toolchain digest. Every added, removed, or changed waiver key must name a module changed both in its own transition and across the net X..B window. Toolchain bytes beyond the digest remain fixed; manifest signing-key equality is checked between X and B only.

The authenticated metadata step uses only Python's standard library with site packages disabled. The separate PyYAML proof receives no token. Consumer jobs recompute the immutable checks using trusted proof outputs. Ledger parses are cached by blob ID within each proof run. The proof timeout is 15 minutes, over eight times the review's uncached 20-PR, 80-transition measurement; a job timeout skips dependent validation and makes the aggregate fail.

Dependency-input validation is pinned at step index 3, with all preceding steps checked. Every dependency checkout with a repository input must use validated shard outputs. Behavioral coverage also pins the waiver comparison base's lowercase 40-hex validation.

Only pull_request, push, schedule, and workflow_dispatch may consume the rewound base; other events retain their previous comparison-base behavior. A rewind changes the freeze, waiver ratchets, supervised audit baseline, and generated guard comparisons. Selection and audit changed paths retain the ordinary base, so restored modules are revalidated. Callers' pinned supervised audit enforces expiry; shared CI skips the expiry regression without an encoder loader. Ordinary proof refusals retain the ordinary base.

Callers must grant contents: read and pull-requests: read, retaining independently required read scopes. Without PR lookup access, the proof keeps the ordinary base. Only the job running no candidate code inherits caller permissions; candidate jobs retain their contents: read cap. The unused proof in shards remains removed.

Validation

  • Full workflow validation entrypoint: 117 selector regressions (115 import-selection and 2 validation-target cases), 29 rollback regression groups (0 skipped), 13 waiver CLI compatibility cases, and 13 lane-registry tests passed.
  • The test file collects 192 pytest items. The rollback and dependency-checkout selection passed 31 tests, with 161 deselected and no skips.
  • Verification used GNU Bash 5.3 and only validation_waivers.py and constants.py exported from encoder commit 85845da38; the restored-waiver expiry check passed.
  • All 14 round-3 mutants were caught: ordering and checkout coverage (2), net-window binding (1), cache and timeout/aggregate behavior (3), token isolation (3), the waiver base guard (1), and README wording (4). The review's early candidate-install and three-PR cancellation probes are regressions.
  • The cache regression makes 82 requests for 21 ledger blobs and observes 21 parses and 61 hits, independently in two fresh proof runs.
  • actionlint 1.7.12 and git diff --check: clean.

🤖 Generated with Claude Code

MaxGhenis and others added 8 commits October 18, 2026 19:11
Recompute a bounded whole-tree proof before candidate code and use its
effective base only for freeze, waiver/companion ratchets, supervised audit
comparison and generated guard. Keep selection, audit changed paths,
configuration and dependency adoption on the real event base.

An isolated proof job inherits optional PR-read permissions; candidate jobs
retain contents-only tokens and recompute Git checks against its immutable
outputs. API errors and all failed proofs preserve the ordinary base.

Invariants:
I1. Admit only an exact tree of a merged default-branch PR landing within
20 first-parent steps. Extra/missing bytes, modes or files fall back to B.
I2. No authorization artifact exists. Every event recomputes the proof;
only step/job outputs from candidate-free steps select effective_base.
I3. Head-waiver expiry remains enforced against today. Restored modules
still validate and receive the original B-to-head fingerprint audit.
I4. Configuration, pins, CODEOWNERS and inventories remain byte-identical
throughout the window, except the permitted waiver-ledger digest field.
I5. Restored waiver growth requires I1; existing pending-approval paths
remain unchanged.

Exercise accepted suffixes/events, refusal cases, real extracted ratchets,
frozen-date expiry through the encoder loader, and trusted-output wiring.

Validation: 235 pytest tests passed (89 validation workflow, 124 pin-bump
and encoder-guard, 22 other workflow tests). The full script entry point
also passed, including 16 rollback groups and 13 lane-registry tests.
actionlint, Python compilation and diff whitespace checks passed.
…ists

Review round 1 nit: without an installed encoder or AXIOM_ENCODE_SOURCE the
expiry test returned before either frozen-date assertion, and shared CI
(which installs only PyYAML) counted it among "16 regression groups passed".
It now raises unittest.SkipTest, which pytest reports as skipped, and the
standalone runner prints passed and skipped counts separately. With a loader
present (the encoder's validation_waivers.py and constants.py at 85845da38)
it still runs both dates and passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review round 4: an 'if: ${{ !cancelled() }}' on validate passed the timeout
and wiring tests, although after a timed-out proof it would run validation on
the ordinary base and the aggregate would not fail. The test now requires
validate to carry no condition (the mutant fails it).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis marked this pull request as ready for review October 19, 2026 03:17
@MaxGhenis
MaxGhenis merged commit 9496de7 into main Oct 19, 2026
5 checks passed
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Merged (merge commit 9496de7) at head 56ea4ca69 on the gates: gh pr checks exited 0 on the latest run, and the PR was MERGEABLE and CLEAN. Independent reviews ran four rounds (bb99018, 174e27d, e4e5144, e47841c). Each round's findings were fixed. The last round approved e47841c with nits; its test gap (a condition on validate) is fixed in 56ea4ca69, test-only. Callers pin this workflow by SHA, so nothing changes for them until they bump and grant pull-requests: read. That adoption, admitting real revert windows (companion tests, additions) and the remaining hardening are tracked in #142.

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