Skip to content

feat(ci): enforce changed-scope behavior mutation - #287

Merged
abiorh-claw merged 1 commit into
mainfrom
codex/ws-qual-001-05m-blocking-mutation-gate
Aug 5, 2026
Merged

feat(ci): enforce changed-scope behavior mutation#287
abiorh-claw merged 1 commit into
mainfrom
codex/ws-qual-001-05m-blocking-mutation-gate

Conversation

@Abiorh001

@Abiorh001 Abiorh001 commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

WS-QUAL-001-05M PR Trust Bundle

Chunk

WS-QUAL-001-05M — Blocking Changed-Scope Behavior Mutation Gate (L1).

Goal and human-approved intent

Turn the accepted 04M observational calibration into a bounded required gate:
eligible changed behavior must have exact ownership, owning tests, and no
meaningful surviving selected mutant. The user explicitly accepted calibration
and started this chunk.

What changed and why

  • Replaced mutable static mutation configuration with exact selection-derived
    disposable configuration.
  • Added exact claim discovery, merge-base callable mapping, AST existence, and
    fail-closed status reconciliation.
  • Made the stable pilot check always emit and block meaningful survivors.
  • Kept evaluator, helper, mutation toolchain, and backend dependency authority
    at protected base after the explicit one-time bootstrap.
  • Added contributor claim/schema/example guidance, local discovery, evidence
    interpretation, focused tests, and 90-percent subsystem coverage proof.

Coverage alone does not prove assertions detect wrong behavior. This gate adds
that proof only for the changed, explicitly owned callable scope; it does not
introduce a global mutation score.

Design chosen and alternatives rejected

The protected evaluator derives every eligible changed target and callable.
One exact claim supplies owning tests, observable outcomes, and real boundaries
but cannot narrow the derived scope. Mutmut runs in an archived disposable tree
with a hash-locked runner and runtime/test dependencies resolved from the
protected backend lock. Exact policy-owned strong/weak controls calibrate the
engine. All meaningful selected survivors and unsafe/incomplete statuses block.

Rejected: full-repository mutation, score thresholds, PR-head evaluator or
dependencies, free-form survivor exemptions, workflow path filters, and
running candidate tests with repository/CI credentials.

Scope control and product behavior

No application behavior, migration, Workstream product lifecycle,
authorization, payment, reputation, Backend lane, or coverage threshold
changed. Review decisions remain accept, needs_revision, and reject;
mutation findings are engineering evidence only. Existing global 78-percent
and protected 90-percent floors remain blocking.

Acceptance proof and test delta

  • Exact discovery: applicable 05M, one claim, exact changed-callable ownership.
  • Mutation policy: 54 passed; 91.39-percent focused coverage.
  • Policy/CI/coverage contract suites: 258 passed.
  • Repository workflow invariants: 11 passed.
  • Locked disposable environment replay: backend imports and policy suite passed.
  • Ruff, Markdown links, stale wording, and diff checks passed.
  • No test was removed, skipped, xfailed, deselected, or weakened.
  • Enforced selected-survivor failure and the complete generated mutmut table
    now have behavioral regression tests.

CI integrity and reviewer results

The workflow retains stable job id pilot, read-only permissions, pinned
Actions, no path filters, preflight before installation, protected-base
authority, 15-minute job/720-second command/700-second engine limits, and
exact-head evidence. Architecture, senior engineering, QA, security,
product/ops, CI integrity, docs, reuse/dedup, and test-delta tracks pass after
valid findings were fixed. Detailed results are in the internal review evidence.

External review

GitHub Actions and CodeRabbit are pending publication and must pass on the exact
PR head. The bootstrap PR is nonblocking for mutation outcomes because merged
04M lacks the new evaluator and locked uv runner; the first protected-main
run establishes 05M authority for later PRs.

Remaining risks and follow-up

Hosted dependency/runtime timing must remain within the accepted limits. The
stable internal job id pilot is retained to avoid breaking required-check
configuration. Shared diff-line parsing may be deduplicated later; neither is a
merge blocker. Do not start another QUAL chunk from this PR.

Human review focus and merge ownership

  • Confirm protected-base evaluator and dependency custody after bootstrap.
  • Confirm exact callable ownership cannot omit changed behavior.
  • Inspect hosted selection.json, executed-selection.json, and
    evidence.json, especially calibration and verdict.blockers.
  • Confirm Backend, Agent Gates, CodeRabbit, and this required gate pass on the
    exact final head.

Only the user may approve and merge this specific PR.

Summary by CodeRabbit

  • New Features

    • Added a required behavior mutation gate for eligible backend changes.
    • Added behavior-claim metadata and validation for changed callables and owning tests.
    • Added fail-closed handling for incomplete, invalid, or meaningful mutation survivors.
    • Added protected evaluator execution, evidence generation, and stable pull-request results.
  • Documentation

    • Updated contributor, operations, and behavior-claim guidance for the new gate.
    • Added examples and expanded supported behavior-claim entries.
  • Tests

    • Expanded coverage for discovery, validation, calibration, enforcement, evidence, and workflow security.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Abiorh001, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 40 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d812a896-3602-40e1-910b-1c8f26cfd069

📥 Commits

Reviewing files that changed from the base of the PR and between 7f395d4 and ae0f7ba.

📒 Files selected for processing (19)
  • .agent-loop/initiatives/WS-QUAL-001-backend-coverage-floor/CHUNK_MAP.md
  • .agent-loop/initiatives/WS-QUAL-001-backend-coverage-floor/STATUS.md
  • .agent-loop/initiatives/WS-QUAL-001-backend-coverage-floor/chunks/WS-QUAL-001-05M-blocking-behavior-mutation-gate.md
  • .agent-loop/initiatives/WS-QUAL-001-backend-coverage-floor/reviews/WS-QUAL-001-05M-external-review-response.md
  • .agent-loop/initiatives/WS-QUAL-001-backend-coverage-floor/reviews/WS-QUAL-001-05M-internal-review-evidence.md
  • .agent-loop/initiatives/WS-QUAL-001-backend-coverage-floor/reviews/WS-QUAL-001-05M-pr-trust-bundle.md
  • .ci/behavior-claims/README.md
  • .ci/behavior-claims/WS-QUAL-001-05M.json
  • .ci/behavior-claims/example.behavior-claim.json
  • .github/workflows/mutation-pilot.yml
  • CONTRIBUTING.md
  • backend/pyproject.toml
  • backend/scripts/mutation_policy.py
  • backend/tests/test_mutation_policy.py
  • docs/operations_backend_testing.md
  • scripts/behavior-claim.schema.json
  • scripts/mutation-requirements.in
  • scripts/mutation-requirements.txt
  • scripts/test_lightweight_agent_gates.py
📝 Walkthrough

Walkthrough

The PR replaces the observational mutation pilot with a protected, claim-driven blocking gate. It adds callable ownership discovery, generated mutation configuration, fail-closed outcome classification, protected CI execution, expanded tests, documentation, dependency custody, and updated initiative records.

Changes

Behavior Mutation Gate

Layer / File(s) Summary
Claim contracts and evaluator policy
.ci/behavior-claims/*, scripts/behavior-claim.schema.json, CONTRIBUTING.md, backend/scripts/mutation_policy.py
Behavior claims now define changed callable ownership and owning tests. The evaluator discovers applicable deltas, validates claims, generates exact mutmut configuration, restricts runtime variables, and classifies survivors fail-closed.
Execution evidence and policy validation
backend/scripts/mutation_policy.py, backend/tests/test_mutation_policy.py
Execution now supports self-tests, optional enforcement, configuration digests, verdict evidence, and typed not_applicable results. Tests cover claim errors, callable mapping, calibration, outcomes, environment restrictions, and blocking survivors.
Protected CI workflow
.github/workflows/mutation-pilot.yml, scripts/mutation-requirements.*, scripts/test_lightweight_agent_gates.py
The workflow runs without path filters, retrieves protected-base evaluator inputs, installs locked dependencies conditionally, executes the evaluator, and uploads selection and evidence artifacts. Workflow tests enforce custody and ordering rules.
Operational policy and initiative records
docs/operations_backend_testing.md, .agent-loop/initiatives/WS-QUAL-001-backend-coverage-floor/*
Documentation and contributor guidance describe the required gate. Initiative records mark 04M accepted and 05M active, with updated verification, review, and stop conditions.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PullRequest
  participant GitHubActions
  participant ProtectedEvaluator
  participant DisposableBackendEnvironment
  participant Mutmut
  PullRequest->>GitHubActions: trigger behavior mutation gate
  GitHubActions->>ProtectedEvaluator: retrieve base evaluator and discover applicability
  ProtectedEvaluator->>GitHubActions: return selection
  GitHubActions->>DisposableBackendEnvironment: install locked mutation dependencies
  GitHubActions->>ProtectedEvaluator: execute selected policy with enforcement
  ProtectedEvaluator->>Mutmut: run generated mutation configuration
  Mutmut->>ProtectedEvaluator: return mutation outcomes
  ProtectedEvaluator->>GitHubActions: write verdict and evidence artifacts
Loading

Possibly related PRs

Suggested reviewers: abiorh-claw

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.77% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: enforcing changed-scope behavior mutation in CI.
Description check ✅ Passed The description covers intent, scope, design, evidence, tests, risks, reviewer focus, and external review, but omits several template sections and checklist details.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/ws-qual-001-05m-blocking-mutation-gate

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (4)
backend/tests/test_mutation_policy.py (2)

404-416: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert that non-mutmut TOML content survives the rewrite.

_write_mutmut_config is documented to preserve every table other than [tool.mutmut]. This test reads only ["tool"]["mutmut"], so a regression that drops the retained [project] table would still pass.

The fixture already writes [project] at line 400. Assert it is still present.

💚 Proposed addition
             digest = _write_mutmut_config(backend, selection)
-            rendered = tomllib.loads(pyproject.read_text(encoding="utf-8"))["tool"]["mutmut"]
+            document = tomllib.loads(pyproject.read_text(encoding="utf-8"))
+            assert document["project"] == {"name": "example", "version": "0.1.0"}
+            rendered = document["tool"]["mutmut"]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/tests/test_mutation_policy.py` around lines 404 - 416, Update the
_write_mutmut_config test to verify that rewriting the mutmut section preserves
the existing non-mutmut TOML tables, especially the [project] table already
written by the fixture. Keep the current assertions on tomllib.loads(...
)["tool"]["mutmut"], and add a check against the parsed pyproject content that
[project] is still present after _write_mutmut_config runs.

505-544: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a nested-function case, and separate the two fail-closed guards.

Two coverage gaps.

First, test_changed_callable_mapping_covers_decorated_async_and_nested_methods covers only a decorated async method inside a class. It does not cover a function defined inside another function. .ci/behavior-claims/WS-QUAL-001-05M.json claims scripts.mutation_policy._callable_spans.visit, which is exactly that shape. Add a case that changes only the inner function body and asserts the derived owner is the inner qualified name, not the enclosing one.

Second, test_module_level_and_deleted_callable_changes_fail_closed replaces def claimed() with SETTING = True in one write. That triggers current_unmapped and removed at the same time, and both raise unmappable_changed_logic. The test cannot prove that the removed-callable guard works on its own. Split it into one case that adds a module-level assignment while keeping every callable, and one case that deletes a callable while changing nothing else.

New or materially changed backend subsystems must maintain at least 90% test coverage.

💚 Proposed nested-function case
+    def test_changed_callable_mapping_covers_functions_nested_in_functions(self) -> None:
+        with tempfile.TemporaryDirectory() as temporary:
+            root = Path(temporary)
+            self._initialize(root)
+            target = root / "backend/scripts/claimed.py"
+            body = "def outer():\n    def inner():\n        return {0}\n    return inner\n"
+            target.write_text(body.format("True"), encoding="utf-8")
+            self._git(root, "add", ".")
+            self._git(root, "commit", "-m", "nested base")
+            self.base = self._git(root, "rev-parse", "HEAD")
+            target.write_text(body.format("False"), encoding="utf-8")
+            self._git(root, "add", ".")
+            self._git(root, "commit", "-m", "nested change")
+            head = self._git(root, "rev-parse", "HEAD")
+            assert changed_callables(root, self.base, head, "backend/scripts/claimed.py") == [
+                "scripts.claimed.outer.inner"
+            ]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/tests/test_mutation_policy.py` around lines 505 - 544, Add a test
alongside
test_changed_callable_mapping_covers_decorated_async_and_nested_methods that
defines an outer function containing an inner function, changes only the inner
body between commits, and asserts changed_callables returns the inner qualified
name (including the enclosing function) rather than the outer name. Split
test_module_level_and_deleted_callable_changes_fail_closed into independent
cases: one preserves all callables while adding a module-level assignment to
exercise current_unmapped, and the other removes a callable without unrelated
changes to exercise the removed-callable guard; keep each case asserting
unmappable_changed_logic.

Source: Coding guidelines

backend/scripts/mutation_policy.py (2)

596-604: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Require target on owner records instead of falling back to rsplit.

The fallback at lines 602-603 derives the module by removing the last dotted segment of the callable name. For a method such as scripts.mutation_policy.Service.claimed, that produces the module scripts.mutation_policy.Service and the relative name claimed. The resulting glob scripts.mutation_policy.Service.x_claimed__mutmut_* matches no mutant, so the callable is never mutated and the gate still reports pass.

Every selection built by build_selection sets target. Only the test fixture at backend/tests/test_mutation_policy.py lines 450-465 omits it. Make the absence a typed error and update that fixture.

♻️ Proposed change
     for owner in selection["target_owners"]:
+        target = owner.get("target")
+        if not target:
+            raise MutationPolicyError("missing_owner_target")
+        target_module = target.removeprefix("backend/").removesuffix(".py").replace("/", ".")
         for callable_name in owner["callables"]:
-            target_module = (
-                owner.get("target", "")
-                .removeprefix("backend/")
-                .removesuffix(".py")
-                .replace("/", ".")
-            )
-            if not target_module:
-                target_module = callable_name.rsplit(".", 1)[0]
             relative = callable_name.removeprefix(f"{target_module}.")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/scripts/mutation_policy.py` around lines 596 - 604, Require every
owner record processed by the target-module logic in build_selection to provide
a non-empty target; remove the callable_name.rsplit fallback and raise the
established typed error when target is absent. Update the owner fixture in
test_mutation_policy.py to include the appropriate target value so it remains
valid.

467-508: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Extract the owner record into a helper and drop the redundant dict unpacking.

The **({...}) wrapper around a dict literal has no effect. The nested conditional expressions inside four sorted(...) calls repeat the same blocking_policy and target == CALIBRATION_TARGET guard.

A small helper reduces the nesting and states the calibration augmentation once.

♻️ Proposed refactor
+def _owner_record(
+    target: str,
+    claim: dict[str, Any],
+    *,
+    calibrated: bool,
+) -> dict[str, Any]:
+    extra_callables = set(CALIBRATION_CALLABLES) if calibrated else set()
+    extra_tests = set(CALIBRATION_TESTS) if calibrated else set()
+    extra_outcomes = {"return"} if calibrated else set()
+    return {
+        "target": target,
+        "callables": sorted(set(claim.get("callables", [])) | extra_callables),
+        "tests": sorted(set(claim.get("tests", [])) | extra_tests),
+        "outcomes": sorted(set(claim.get("outcomes", [])) | extra_outcomes),
+        "boundaries": claim.get("boundaries", []),
+    }

Then build each entry with _owner_record(...) plus the selection_reason key.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/scripts/mutation_policy.py` around lines 467 - 508, Extract the
owner-data construction from the target comprehension into a helper such as
_owner_record, passing the target, claims_by_target, and calibration-policy
state it needs. In that helper, compute the blocking calibration condition once
and apply it to the callables, tests, and outcomes augmentations, while
preserving boundaries and sorting behavior. Replace the redundant **({...})
wrapper in the target_owners construction with the helper result plus the
existing selection_reason field.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/scripts/mutation_policy.py`:
- Around line 245-249: Update the ClassDef handling in mutation_policy.py so the
class header line is always added to executable spans, even for undecorated,
base-free classes like the ClassDef branch. Keep the existing
decorator/base/keyword span logic, but append an additional span for the class
header unconditionally so _map_changed_lines can classify changes on plain class
declarations instead of silently passing them through changed_callables.
- Around line 431-439: Replace the fragile '"--discover"' source substring
checks in the blocking_policy and bootstrap logic with a dedicated
POLICY_CAPABILITY_MARKER emitted in a module-level comment or docstring, and
probe for that marker in base_policy. Preserve the one-shot WS-QUAL-001-05M
bootstrap behavior, and add a follow-up note to remove that chunk_id special
case after merge.
- Around line 551-577: Update the generated-TOML validation in the function
containing the rendered config and _sha256 call: wrap
tomllib.loads(rendered)["tool"]["mutmut"] in a tomllib.TOMLDecodeError handler
and raise the module’s typed MutationPolicyError so _main emits
mutation_policy_error instead of a traceback. Also replace the line-based
skipping rewrite with a parsed TOML rewrite that removes the existing
tool.mutmut configuration while preserving unrelated sections, then appends the
generated config and computes the digest from the parsed mutmut table.
- Around line 440-446: Handle deleted eligible targets before constructing or
consuming changed_targets: filter out deleted Python targets or assign them an
explicit deletion outcome so they cannot trigger missing_claim_target or
changed_target_without_behavior_claim. Update the target-discovery flow that
feeds derived_callables and preserve existing behavior for files still present
at HEAD.

---

Nitpick comments:
In `@backend/scripts/mutation_policy.py`:
- Around line 596-604: Require every owner record processed by the target-module
logic in build_selection to provide a non-empty target; remove the
callable_name.rsplit fallback and raise the established typed error when target
is absent. Update the owner fixture in test_mutation_policy.py to include the
appropriate target value so it remains valid.
- Around line 467-508: Extract the owner-data construction from the target
comprehension into a helper such as _owner_record, passing the target,
claims_by_target, and calibration-policy state it needs. In that helper, compute
the blocking calibration condition once and apply it to the callables, tests,
and outcomes augmentations, while preserving boundaries and sorting behavior.
Replace the redundant **({...}) wrapper in the target_owners construction with
the helper result plus the existing selection_reason field.

In `@backend/tests/test_mutation_policy.py`:
- Around line 404-416: Update the _write_mutmut_config test to verify that
rewriting the mutmut section preserves the existing non-mutmut TOML tables,
especially the [project] table already written by the fixture. Keep the current
assertions on tomllib.loads(... )["tool"]["mutmut"], and add a check against the
parsed pyproject content that [project] is still present after
_write_mutmut_config runs.
- Around line 505-544: Add a test alongside
test_changed_callable_mapping_covers_decorated_async_and_nested_methods that
defines an outer function containing an inner function, changes only the inner
body between commits, and asserts changed_callables returns the inner qualified
name (including the enclosing function) rather than the outer name. Split
test_module_level_and_deleted_callable_changes_fail_closed into independent
cases: one preserves all callables while adding a module-level assignment to
exercise current_unmapped, and the other removes a callable without unrelated
changes to exercise the removed-callable guard; keep each case asserting
unmappable_changed_logic.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 707541a9-4505-4568-9a54-5a2b012ec97c

📥 Commits

Reviewing files that changed from the base of the PR and between 7f395d4 and 12bb1d9.

📒 Files selected for processing (18)
  • .agent-loop/initiatives/WS-QUAL-001-backend-coverage-floor/CHUNK_MAP.md
  • .agent-loop/initiatives/WS-QUAL-001-backend-coverage-floor/STATUS.md
  • .agent-loop/initiatives/WS-QUAL-001-backend-coverage-floor/chunks/WS-QUAL-001-05M-blocking-behavior-mutation-gate.md
  • .agent-loop/initiatives/WS-QUAL-001-backend-coverage-floor/reviews/WS-QUAL-001-05M-internal-review-evidence.md
  • .agent-loop/initiatives/WS-QUAL-001-backend-coverage-floor/reviews/WS-QUAL-001-05M-pr-trust-bundle.md
  • .ci/behavior-claims/README.md
  • .ci/behavior-claims/WS-QUAL-001-05M.json
  • .ci/behavior-claims/example.behavior-claim.json
  • .github/workflows/mutation-pilot.yml
  • CONTRIBUTING.md
  • backend/pyproject.toml
  • backend/scripts/mutation_policy.py
  • backend/tests/test_mutation_policy.py
  • docs/operations_backend_testing.md
  • scripts/behavior-claim.schema.json
  • scripts/mutation-requirements.in
  • scripts/mutation-requirements.txt
  • scripts/test_lightweight_agent_gates.py
💤 Files with no reviewable changes (1)
  • backend/pyproject.toml

Comment thread backend/scripts/mutation_policy.py
Comment thread backend/scripts/mutation_policy.py Outdated
Comment thread backend/scripts/mutation_policy.py
Comment thread backend/scripts/mutation_policy.py
@Abiorh001
Abiorh001 force-pushed the codex/ws-qual-001-05m-blocking-mutation-gate branch from 12bb1d9 to 722be2c Compare August 5, 2026 13:44
@Abiorh001
Abiorh001 force-pushed the codex/ws-qual-001-05m-blocking-mutation-gate branch from 722be2c to ae0f7ba Compare August 5, 2026 13:48
@abiorh-claw
abiorh-claw self-requested a review August 5, 2026 15:28
@abiorh-claw
abiorh-claw merged commit 0ddc0f0 into main Aug 5, 2026
10 checks passed
@abiorh-claw
abiorh-claw deleted the codex/ws-qual-001-05m-blocking-mutation-gate branch August 5, 2026 15:31
@coderabbitai coderabbitai Bot mentioned this pull request Aug 5, 2026
19 tasks
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.

2 participants