Skip to content

feat(self-healing): close the auto-heal loop, wire into brain.correct() (Phase 1)#77

Merged
Gradata merged 6 commits intomainfrom
wt-phase1-self-healing
Apr 15, 2026
Merged

feat(self-healing): close the auto-heal loop, wire into brain.correct() (Phase 1)#77
Gradata merged 6 commits intomainfrom
wt-phase1-self-healing

Conversation

@Gradata
Copy link
Copy Markdown
Owner

@Gradata Gradata commented Apr 15, 2026

Summary

PR #21 shipped 8 self-healing helpers; only detect_rule_failure was wired. brain.correct() emitted RULE_FAILURE events into a void. This PR closes the loop, then applies the polyclaude council verdict: default off, loud when it fires.

Audit finding

PR #21 helpers (detect_rule_failure, apply_patch, retroactive_test, review_rule_failures, check_nudge_threshold, suggest_scope_narrowing, narrow_rule_scope, _generate_deterministic_patch) all existed but only detect_rule_failure ran. PR #74's demote_stale_rules is wired. The headline gap: no code path joined RULE_FAILURE emission to review_rule_failures + brain.patch_rule. Even the E2E test called them by hand.

What this PR ships

  • auto_heal_failures(brain, ...) orchestrator: reads RULE_FAILURE events, gates each candidate through retroactive_test, applies survivors via brain.patch_rule (which preserves confidence + emits RULE_PATCHED). Caps at max_patches=5, dedups by (category, original). Returns PatchReceipt dicts (rule_id, old_confidence, new_confidence, patch_diff, revert_command) so auto-edits are inspectable.
  • Brain.auto_heal() public API.
  • brain.correct(auto_heal=False) (default, per council). When opted in (auto_heal=True), inline-calls the orchestrator with max_patches=1 when a fresh RULE_FAILURE is detected. Skipped in dry_run, approval_required, renter modes. Every successful patch prints one stderr line: [gradata] auto-healed R-{id}: confidence X -> Y, revert with gradata rule revert {id}`` so silent rewrites cannot sneak through.

Polyclaude council (4/4 FALSE)

The council vetoed auto_heal=True as the default. This PR applies the verdict:

  • Default is now auto_heal=False. The orchestrator + inline wiring ship, but are opt-in per call.
  • Any auto-heal that does fire produces a PatchReceipt and a stderr line, so the edit is never silent.
  • Flip to True is deferred until both (a) a pending_patches review queue exists and (b) ablation shows rule-quality lift on a held-out broken-rule corpus.

Deferred (not in this PR)

  • Flip default to auto_heal=True (pending queue + ablation)
  • pending_patches review queue
  • Broken-rule ablation corpus + lift measurement
  • Auto-trigger of check_nudge_threshold / narrow_rule_scope (failure-context dict in _core.py does not carry domain/active_memories yet)
  • Contradiction gate at INSTINCT->PATTERN transition
  • Auto-retire after repeated unfixable failures
  • Long-window event re-patching (mooted by inline call)

Tests

2412 pass (+2 new: test_default_off_no_patch, test_patch_receipt_shape). Ruff clean on touched src files (3 pre-existing F841 in PR #21 test code untouched).

Commits

  • caea3c2 feat(self-healing): close the auto-heal loop
  • 5ce5f80 feat(self-healing): wire auto_heal into brain.correct() by default
  • e268f14 fix(self-healing): default auto_heal=False per council; add PatchReceipt for visibility

Co-Authored-By: Gradata noreply@gradata.ai

Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

Gradata has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 15, 2026

Caution

Review failed

Pull request was closed or merged during review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: a3071111-6596-4b96-8d77-5833b631ff13

📥 Commits

Reviewing files that changed from the base of the PR and between 2b75fea and 4a1fff8.

📒 Files selected for processing (1)
  • src/gradata/brain.py
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Python 3.11
  • GitHub Check: Python 3.12
  • GitHub Check: test (3.13)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.11)
  • GitHub Check: Cloudflare Pages
  • GitHub Check: Python 3.12
🧰 Additional context used
📓 Path-based instructions (1)
src/gradata/**/*.py

⚙️ CodeRabbit configuration file

src/gradata/**/*.py: This is the core SDK. Check for: type safety (from future import annotations required), no print()
statements (use logging), all functions accepting BrainContext where DB access occurs, no hardcoded paths. Severity
scoring must clamp to [0,1]. Confidence values must be in [0.0, 1.0].

Files:

  • src/gradata/brain.py
🔇 Additional comments (4)
src/gradata/brain.py (4)

377-377: LGTM!

Safe default (False) aligns with the opt-in design mentioned in PR objectives. Type hint is correct.


386-394: LGTM!

Docstring accurately documents the auto_heal parameter behavior and skip conditions. The skip logic delegation to brain_correct() is correctly abstracted.


412-412: LGTM!

Clean pass-through to brain_correct().


516-551: LGTM!

Both past review concerns have been properly addressed:

  1. Cache invalidation now occurs when patches are applied (line 548-550)
  2. Defensive exception handling uses contextlib.suppress(Exception) (line 549)

The lazy import pattern and delegation to auto_heal_failures() are consistent with the rest of the file.


📝 Walkthrough
  • New public API: Brain.auto_heal(failure_events: list[dict] | None = None, *, max_patches: int = 5) -> dict — orchestrator wrapper that applies automatic patches for RULE_FAILURE events and invalidates in-memory rule cache when changes occur.
  • Enhanced public API: Brain.correct(..., auto_heal: bool = False) — when enabled runs inline self-healing (max_patches=1) on freshly detected RULE_FAILUREs; default is off and auto-heal is skipped for dry_run=True, approval_required=True, and renter mode.
  • New orchestrator: auto_heal_failures(brain, failure_events=None, *, max_patches=5) — queries or consumes RULE_FAILURE events, runs retroactive_test, deduplicates by (category, original_description), enforces a max_patches cap, applies surviving patches via brain.patch_rule, and returns an aggregated result with PatchReceipt entries (rule_id, old_confidence, new_confidence, patch_diff, revert_command) plus skipped reasons.
  • Visibility & auditability: successful auto-heals emit RULE_PATCHED with a reason prefixed "auto_heal:", the API returns patch receipts (including a revert command), and each successful auto-patch writes one stderr line with rule id, confidence delta, and revert command to avoid silent edits.
  • Cloud-routing behavior change: when auto_heal=True the flow falls through to the local pipeline instead of delegating to cloud.correct(), preventing the auto_heal flag from being dropped when cloud-connected.
  • Error handling & safeguards: auto-heal exceptions are caught and logged (debug); individual patch failures are recorded as skipped with explanatory reasons; auto-heal remains opt-in and is disabled in dry_run/approval_required/renter modes.
  • Tests & quality: +2 new tests added (test_default_off_no_patch, test_patch_receipt_shape); test suite passes (2412 tests). One commit refactors an exception-swallowing block to use contextlib.suppress(Exception) (style change only).
  • Breaking change: public API change to Brain.correct signature (added auto_heal parameter) and behavioral change in correction routing — callers and integrations (especially cloud routing consumers) should review compatibility.

Walkthrough

Adds optional automatic self-healing for detected rule failures. brain_correct() and Brain.correct() gain auto_heal: bool = False; when enabled and conditions permit, the code invokes auto_heal_failures() to select, deduplicate, and apply rule patches and return a structured summary.

Changes

Cohort / File(s) Summary
Core API
src/gradata/_core.py, src/gradata/brain.py
Added auto_heal: bool = False to brain_correct() and Brain.correct() signatures; brain_correct may call auto_heal_failures() when enabled and conditions (not dry_run, not approval_required, not renter mode, cloud not used for auto-heal) are met; cloud routing avoids dropping the flag. Brain adds auto_heal() helper and invalidates rule cache after patches.
Self‑Healing Orchestration
src/gradata/enhancements/self_healing.py
New exported auto_heal_failures(brain, failure_events=None, *, max_patches=5) that optionally reads RULE_FAILURE events, builds candidates, enforces max_patches, runs retroactive tests, deduplicates, applies brain.patch_rule() with auto_heal: reason, records receipts and skip reasons, and returns an aggregated summary.
Tests
tests/test_self_healing.py
Consolidated fixture and new/updated tests (TestAutoHeal, TestCorrectAutoHealIntegration, adjusted E2E) covering empty events, successful patching and RULE_PATCHED emission (reason prefix auto_heal:), retroactive-test failures, batching deduplication, max_patches cap, integration of brain.correct(auto_heal=...), and dry-run suppression.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Brain
    participant Core as brain_correct()
    participant AutoHeal as auto_heal_failures()
    participant Events as brain.query_events()
    participant Reviewer as review_rule_failures()
    participant Patcher as brain.patch_rule()

    Client->>Brain: Brain.correct(auto_heal=True)
    Brain->>Core: invoke with auto_heal
    Core->>Core: detect RULE_FAILURE(s)
    alt auto_heal enabled and conditions permit
        Core->>AutoHeal: auto_heal_failures(failure_events?)
        AutoHeal->>Events: fetch RULE_FAILURE events (if needed)
        Events-->>AutoHeal: events
        AutoHeal->>Reviewer: review_rule_failures(events)
        Reviewer-->>AutoHeal: candidates
        loop candidates (up to max_patches)
            alt passes retroactive test & not duplicate
                AutoHeal->>Patcher: patch_rule(category, old, new, reason="auto_heal: ...")
                Patcher-->>AutoHeal: result (patched / skipped)
                alt patched
                    AutoHeal-->>Core: patch receipt appended
                else
                    AutoHeal-->>Core: record skip reason
                end
            else
                AutoHeal-->>Core: record skip reason
            end
        end
        AutoHeal-->>Core: aggregated summary
        Core->>Core: annotate event with auto_healed summary
    end
    Core-->>Brain: correction result (may include auto_healed)
    Brain-->>Client: return
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 56.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main feature: closing the auto-heal loop and wiring it into brain.correct() with Phase 1 scope indicator.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, explaining the audit finding, what ships, the council decision, and what is deferred.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch wt-phase1-self-healing

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/gradata/brain.py (1)

377-388: 🧹 Nitpick | 🔵 Trivial

Document the auto_heal parameter in the docstring.

The new auto_heal parameter isn't mentioned in the method's docstring. Users may not discover this opt-out mechanism.

📝 Suggested docstring addition
         ``applies_to`` is an optional free-form scope token (e.g.
         ``"client:acme"``, ``"task:emails"``, ``"global"``) that binds the
         correction to a specific context. When set, it is persisted on the
         event and propagated to any lesson that graduates from this
         correction's lineage. Injection-time filtering by ``applies_to``
         is a follow-up — persistence only for now. A ``None`` value preserves
         the existing global behaviour.
+
+        ``auto_heal`` controls whether detected RULE_FAILURE events trigger
+        automatic patching via the self-healing loop. Defaults to ``True``.
+        Set to ``False`` to detect failures without applying patches. Auto-heal
+        is also skipped when ``dry_run=True``, ``approval_required=True``, or
+        when the brain is in renter mode.
         """
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/gradata/brain.py` around lines 377 - 388, Add a docstring entry
describing the auto_heal parameter for the "Record a correction" method (the
function whose signature includes auto_heal: bool = True) explaining that
auto_heal is a boolean opt-out for automatic healing of related lessons/events,
its default value (True), what setting it to False does (disable automatic
lineage-based healing/propagation), and any side-effects or persistence behavior
(e.g., no change to applies_to persistence). Update the parameter list in the
docstring to include ":param auto_heal: bool — default True; when False, disable
automatic healing of related lessons/records; when True, allow automatic
propagation/healing as part of correction processing."
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/gradata/enhancements/self_healing.py`:
- Around line 492-497: Add a type annotation for the brain parameter in
auto_heal_failures to improve IDE/static analysis: use a forward reference
string (e.g., brain: "Brain") or guard an import with a TYPE_CHECKING block and
annotate brain with Brain; also ensure the file has from __future__ import
annotations at the top to allow postponed evaluation of annotations and avoid
circular import issues.

In `@tests/test_self_healing.py`:
- Around line 438-453: Consolidate the duplicated brain_with_rule fixture by
moving its definition to module scope as a single
`@pytest.fixture`(scope="function") named brain_with_rule and import the same
symbols used in the duplicated versions (Brain.init, write_lessons_safe,
format_lessons, Lesson, LessonState, tmp_path fixture). Keep the logic that
creates the brain, constructs the RULE lesson (date "2026-04-01", state
LessonState.RULE, confidence 0.92, category "TONE", description "Never use
exclamation marks", fire_count 8), writes lessons via
brain._find_lessons_path(create=True) and
write_lessons_safe(format_lessons([...])) and return the brain; then remove the
identical class-level fixture definitions so tests simply reference the single
module-level brain_with_rule fixture.
- Around line 585-602: The test test_auto_heal_triggers_on_rule_failure weakly
asserts patching by gating assertions with "if patched:"; remove the conditional
and make the patching deterministic or split into two tests: one that only
asserts rule_failure_detected from brain_with_rule.correct(draft=..., final=...,
category="TONE") and a second test that uses a known-good input which guarantees
a RULE_PATCHED event (call
brain_with_rule.query_events(event_type="RULE_PATCHED", limit=10) and assert
patched non-empty, patched[0]['data']['reason'].startswith("auto_heal:"), and
"auto_healed" in the correct() result); update test names accordingly (e.g.,
test_detects_rule_failure and test_auto_heal_emits_rule_patched) and remove the
conditional branch so assertions always run against concrete expected outputs.

---

Outside diff comments:
In `@src/gradata/brain.py`:
- Around line 377-388: Add a docstring entry describing the auto_heal parameter
for the "Record a correction" method (the function whose signature includes
auto_heal: bool = True) explaining that auto_heal is a boolean opt-out for
automatic healing of related lessons/events, its default value (True), what
setting it to False does (disable automatic lineage-based healing/propagation),
and any side-effects or persistence behavior (e.g., no change to applies_to
persistence). Update the parameter list in the docstring to include ":param
auto_heal: bool — default True; when False, disable automatic healing of related
lessons/records; when True, allow automatic propagation/healing as part of
correction processing."
🪄 Autofix (Beta)

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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 53cc7d8a-a9d9-4575-af2c-1c2027171194

📥 Commits

Reviewing files that changed from the base of the PR and between a100a3a and 5ce5f80.

📒 Files selected for processing (4)
  • src/gradata/_core.py
  • src/gradata/brain.py
  • src/gradata/enhancements/self_healing.py
  • tests/test_self_healing.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Test (Python 3.12)
  • GitHub Check: Test (Python 3.13)
  • GitHub Check: test (3.11)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.13)
  • GitHub Check: Cloudflare Pages
🧰 Additional context used
📓 Path-based instructions (2)
src/gradata/**/*.py

⚙️ CodeRabbit configuration file

src/gradata/**/*.py: This is the core SDK. Check for: type safety (from future import annotations required), no print()
statements (use logging), all functions accepting BrainContext where DB access occurs, no hardcoded paths. Severity
scoring must clamp to [0,1]. Confidence values must be in [0.0, 1.0].

Files:

  • src/gradata/brain.py
  • src/gradata/_core.py
  • src/gradata/enhancements/self_healing.py
tests/**

⚙️ CodeRabbit configuration file

tests/**: Test files. Verify: no hardcoded paths, assertions check specific values not just truthiness,
parametrized tests preferred for boundary conditions, floating point comparisons use pytest.approx.

Files:

  • tests/test_self_healing.py
🪛 GitHub Actions: SDK CI
src/gradata/brain.py

[warning] 1378-1378: pyright: Import "gradata.enhancements.memory_extraction" could not be resolved (reportMissingImports)

🔇 Additional comments (7)
src/gradata/enhancements/self_healing.py (2)

523-530: LGTM: Resilient exception handling for orchestration.

The broad exception handler ensures the auto-heal loop doesn't crash on transient DB issues. This is appropriate for a best-effort healing orchestrator.


547-596: LGTM: Well-structured orchestration loop.

The logic correctly sequences: max_patches cap → retroactive test gate → deduplication → patch application. The dedup key normalization (.upper(), .strip()) ensures consistent matching.

src/gradata/_core.py (2)

429-450: LGTM: Auto-heal integration is correctly guarded.

The skip conditions (dry_run, approval_required, _renter_mode) appropriately prevent automatic patching in sensitive contexts. The failure event is correctly wrapped in the format expected by auto_heal_failures.


442-448: LGTM: Inline healing correctly capped.

Using max_patches=1 for inline healing during correct() prevents runaway patching while still closing the loop for the immediate failure. The conditional addition of auto_healed to the event only when a patch succeeds is correct.

src/gradata/brain.py (1)

509-537: LGTM: Clean public API for auto-healing.

The auto_heal() method correctly delegates to auto_heal_failures with proper parameter forwarding. The docstring accurately describes the behavior and return value.

tests/test_self_healing.py (2)

455-463: LGTM: Precise assertion on empty input behavior.

The test correctly asserts the exact expected return structure rather than just checking truthiness. This follows the coding guidelines for tests.


604-626: LGTM: Good coverage of opt-out and dry_run behavior.

These tests verify the critical guardrails: auto_heal=False prevents patching while still detecting failures, and dry_run=True prevents patching entirely. Assertions are specific and check exact counts.

Comment thread src/gradata/enhancements/self_healing.py
Comment thread tests/test_self_healing.py Outdated
Comment thread tests/test_self_healing.py Outdated
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Apr 15, 2026

Deploying gradata-dashboard with  Cloudflare Pages  Cloudflare Pages

Latest commit: 4a1fff8
Status:🚫  Build failed.

View logs

Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

Gradata has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.

Gradata added a commit that referenced this pull request Apr 15, 2026
… ann + test fixture)

- Document auto_heal parameter on Brain.correct (defaults to False post-council)
- Add forward-ref Brain type annotation on auto_heal_failures via TYPE_CHECKING
- Hoist brain_with_rule to module-scope fixture and remove 5 duplicated class-level copies
- Split weak test_auto_heal_triggers_on_rule_failure into two deterministic tests: one asserts rule_failure_detected only, the second drives auto_heal_failures with known-good delta words and asserts patched==1 plus auto_heal: reason prefix

Co-Authored-By: Gradata <noreply@gradata.ai>
Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

Gradata has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.

Gradata added a commit that referenced this pull request Apr 15, 2026
… ann + test fixture)

- Document auto_heal parameter on Brain.correct (defaults to False post-council)
- Add forward-ref Brain type annotation on auto_heal_failures via TYPE_CHECKING
- Hoist brain_with_rule to module-scope fixture and remove 5 duplicated class-level copies
- Split weak test_auto_heal_triggers_on_rule_failure into two deterministic tests: one asserts rule_failure_detected only, the second drives auto_heal_failures with known-good delta words and asserts patched==1 plus auto_heal: reason prefix

Co-Authored-By: Gradata <noreply@gradata.ai>
@Gradata Gradata force-pushed the wt-phase1-self-healing branch from 6dee3e9 to 1feae5c Compare April 15, 2026 09:49
Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

Gradata has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/test_self_healing.py (1)

651-677: ⚠️ Potential issue | 🟡 Minor

This E2E test can mask a broken inline auto-heal path.

After opting into brain.correct(..., auto_heal=True), the test still runs review_rule_failures() and brain.patch_rule() manually. That fallback can create RULE_PATCHED even if the new inline orchestration regresses, so this no longer proves the behavior introduced by the PR.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_self_healing.py` around lines 651 - 677, The E2E test currently
masks inline auto-heal by calling review_rule_failures() and brain.patch_rule()
after brain.correct(..., auto_heal=True); update the test to verify the inline
path directly by checking for a RULE_PATCHED event emitted by the brain after
brain.correct(...) (e.g., query_events(event_type="RULE_PATCHED") and assert at
least one), and remove or conditionally skip the manual review_rule_failures() +
brain.patch_rule() loop so the test only passes when the inline auto_heal
orchestration itself produces RULE_PATCHED; alternatively, if keeping manual
fallback, add an explicit assertion that a RULE_PATCHED event already existed
before invoking review_rule_failures()/brain.patch_rule() to ensure the inline
path is validated.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/gradata/_core.py`:
- Around line 449-468: Replace the print-based stderr writes in the auto-heal
loop with the module logger `_log`: remove the `import sys as _sys` and the
`print(..., file=_sys.stderr)` call and instead call `_log.warning(...)` (or
`_log.info(...)` if preferred) with the exact same formatted message built from
`heal_summary` patches (`_patch.get("rule_id")`, `_patch.get("old_confidence")`,
`_patch.get("new_confidence")`, `_patch.get("revert_command")`) so the message
flows through the SDK logging pipeline; keep the surrounding try/except
defensive guard and otherwise preserve the same message format and variables.
- Line 85: The cloud branch currently calls _cloud.correct(...) and ignores the
auto_heal flag; update the cloud call in the method that defines
applies_to/auto_heal (the code path around _cloud.correct at lines referenced)
to forward the auto_heal boolean (and applies_to) into _cloud.correct so the
cloud can honor the request, and add a fallback: if the cloud client either
lacks support or returns a sentinel/raises NotImplementedError, invoke the local
correction path (e.g., self._correct or brain._local_correct) with
auto_heal=True so the self-healing loop runs locally; ensure you reference and
pass the same applies_to and auto_heal parameters through when calling
_cloud.correct and the local fallback.

In `@src/gradata/brain.py`:
- Around line 516-544: The auto_heal wrapper should clear the brain's in-memory
rule cache after applying standalone patches so callers don't keep a stale
prompt; update the auto_heal method (which calls auto_heal_failures) to inspect
the returned summary dict (e.g., check "patched" or length of "patches") and, if
any patches were applied, invalidate or clear the instance cache `_rule_cache`
(or set it to None) so subsequent calls to `apply_brain_rules` or prompt
generation use the updated lessons written via `patch_rule`.

In `@src/gradata/enhancements/self_healing.py`:
- Around line 581-598: The rule_id generation uses Python's process-randomized
hash(candidate['original_description']), producing unstable IDs; replace that
with the stable digest used elsewhere by calling the existing _make_rule_id
helper from src/gradata/rules/rule_engine.py (or compute a SHA-256 hex prefix
deterministically from f"{category}:{original_description}"), then set rule_id =
f"{candidate['category'].upper()}:{digest}" and keep the rest of the receipt
construction the same; also search for the same incorrect hash() pattern in
rule_engine.py (~line 1063) and replace it with the same stable digest approach
so revert commands are deterministic across processes.

---

Outside diff comments:
In `@tests/test_self_healing.py`:
- Around line 651-677: The E2E test currently masks inline auto-heal by calling
review_rule_failures() and brain.patch_rule() after brain.correct(...,
auto_heal=True); update the test to verify the inline path directly by checking
for a RULE_PATCHED event emitted by the brain after brain.correct(...) (e.g.,
query_events(event_type="RULE_PATCHED") and assert at least one), and remove or
conditionally skip the manual review_rule_failures() + brain.patch_rule() loop
so the test only passes when the inline auto_heal orchestration itself produces
RULE_PATCHED; alternatively, if keeping manual fallback, add an explicit
assertion that a RULE_PATCHED event already existed before invoking
review_rule_failures()/brain.patch_rule() to ensure the inline path is
validated.
🪄 Autofix (Beta)

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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6fac4f42-ff0f-4066-900e-ae0c66852e14

📥 Commits

Reviewing files that changed from the base of the PR and between 5ce5f80 and 1feae5c.

📒 Files selected for processing (4)
  • src/gradata/_core.py
  • src/gradata/brain.py
  • src/gradata/enhancements/self_healing.py
  • tests/test_self_healing.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
  • GitHub Check: Test (Python 3.13)
  • GitHub Check: test (3.13)
  • GitHub Check: Test (Python 3.12)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.11)
  • GitHub Check: Python 3.11
  • GitHub Check: Python 3.12
  • GitHub Check: Test (Python 3.11)
  • GitHub Check: Test (Python 3.12)
  • GitHub Check: Test (Python 3.13)
  • GitHub Check: Python 3.12
  • GitHub Check: Python 3.11
  • GitHub Check: Cloudflare Pages
🧰 Additional context used
📓 Path-based instructions (2)
src/gradata/**/*.py

⚙️ CodeRabbit configuration file

src/gradata/**/*.py: This is the core SDK. Check for: type safety (from future import annotations required), no print()
statements (use logging), all functions accepting BrainContext where DB access occurs, no hardcoded paths. Severity
scoring must clamp to [0,1]. Confidence values must be in [0.0, 1.0].

Files:

  • src/gradata/_core.py
  • src/gradata/brain.py
  • src/gradata/enhancements/self_healing.py
tests/**

⚙️ CodeRabbit configuration file

tests/**: Test files. Verify: no hardcoded paths, assertions check specific values not just truthiness,
parametrized tests preferred for boundary conditions, floating point comparisons use pytest.approx.

Files:

  • tests/test_self_healing.py

Comment thread src/gradata/_core.py
approval_required: bool = False, dry_run: bool = False,
min_severity: str = "as-is", scope: str | None = None,
applies_to: str | None = None,
applies_to: str | None = None, auto_heal: bool = False,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

auto_heal is silently ignored for connected cloud brains.

Lines 115-119 still short-circuit into _cloud.correct(...) without forwarding the new flag or forcing a local fallback. A caller can opt into brain.correct(..., auto_heal=True) and never execute the self-healing loop when cloud mode is active.

Also applies to: 115-119

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/gradata/_core.py` at line 85, The cloud branch currently calls
_cloud.correct(...) and ignores the auto_heal flag; update the cloud call in the
method that defines applies_to/auto_heal (the code path around _cloud.correct at
lines referenced) to forward the auto_heal boolean (and applies_to) into
_cloud.correct so the cloud can honor the request, and add a fallback: if the
cloud client either lacks support or returns a sentinel/raises
NotImplementedError, invoke the local correction path (e.g., self._correct or
brain._local_correct) with auto_heal=True so the self-healing loop runs locally;
ensure you reference and pass the same applies_to and auto_heal parameters
through when calling _cloud.correct and the local fallback.

Comment thread src/gradata/_core.py Outdated
Comment on lines +449 to +468
# Make auto-heal visible: one stderr line per patch so
# silent rule edits can't sneak through. Guarded so a
# printing bug can never break the learning loop.
try:
import sys as _sys
for _patch in heal_summary.get("patches", []) or []:
_rid = _patch.get("rule_id", "?")
_old = _patch.get("old_confidence")
_new = _patch.get("new_confidence")
_revert = _patch.get(
"revert_command", f"gradata rule revert {_rid}"
)
print(
f"[gradata] auto-healed R-{_rid}: "
f"confidence {_old} -> {_new}, "
f"revert with `{_revert}`",
file=_sys.stderr,
)
except Exception: # pragma: no cover — defensive
pass
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use logging for the auto-heal notice instead of print().

This puts a raw stderr write on the core correction path and bypasses the SDK’s logging pipeline. Emit the same message through _log so handlers can still route it to stderr without sidestepping logging controls. As per coding guidelines, src/gradata/**/*.py: no print() statements (use logging).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/gradata/_core.py` around lines 449 - 468, Replace the print-based stderr
writes in the auto-heal loop with the module logger `_log`: remove the `import
sys as _sys` and the `print(..., file=_sys.stderr)` call and instead call
`_log.warning(...)` (or `_log.info(...)` if preferred) with the exact same
formatted message built from `heal_summary` patches (`_patch.get("rule_id")`,
`_patch.get("old_confidence")`, `_patch.get("new_confidence")`,
`_patch.get("revert_command")`) so the message flows through the SDK logging
pipeline; keep the surrounding try/except defensive guard and otherwise preserve
the same message format and variables.

Comment thread src/gradata/brain.py
Comment on lines +581 to +598
if result.get("patched"):
# Stable, deterministic rule id derived from category + original
# description. Mirrors the convention used elsewhere in the
# graph layer so `gradata rule revert {id}` can round-trip.
rule_id = (
f"{candidate['category'].upper()}:"
f"{hash(candidate['original_description']) % 10000:04d}"
)
preserved = result.get("confidence_preserved")
old_desc = candidate["original_description"]
new_desc = candidate["proposed_description"]
patch_diff = f"- {old_desc}\n+ {new_desc}"
receipt = {
"rule_id": rule_id,
"old_confidence": preserved,
"new_confidence": preserved,
"patch_diff": patch_diff,
"revert_command": f"gradata rule revert {rule_id}",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
python - <<'PY'
import subprocess
import sys

expr = "print(hash('Never use exclamation marks') % 10000)"
first = subprocess.check_output([sys.executable, "-c", expr], text=True).strip()
second = subprocess.check_output([sys.executable, "-c", expr], text=True).strip()

print({"first_process": first, "second_process": second, "stable": first == second})
PY

Repository: Gradata/gradata

Length of output: 127


🏁 Script executed:

# First, check the exact content at the specified lines
head -598 src/gradata/enhancements/self_healing.py | tail -18

Repository: Gradata/gradata

Length of output: 964


🏁 Script executed:

# Search for any existing rule-id generation utilities or helpers
rg -i "rule.id|stable.*hash|digest" src/gradata/ -A 2 -B 2

Repository: Gradata/gradata

Length of output: 50497


🏁 Script executed:

# Check if there are any hash utilities or stable ID generation functions
fd -e py . src/gradata | xargs grep -l "stable\|deterministic" | head -10

Repository: Gradata/gradata

Length of output: 389


Use stable digest instead of hash() for rule_id generation.

The current code derives rule_id from hash(candidate['original_description']) % 10000, but Python salts hash(str) per interpreter process. This means the receipt's rule_id and revert_command will differ between the process that patched the rule and a later gradata rule revert ... invocation, breaking the round-trip contract claimed in the comment.

Use the existing _make_rule_id() helper from src/gradata/rules/rule_engine.py (which applies SHA-256), or apply the same stable digest pattern directly:

digest = hashlib.sha256(f"{candidate['category']}:{candidate['original_description']}".encode()).hexdigest()[:8]
rule_id = f"{candidate['category'].upper()}:{digest}"

Also check src/gradata/rules/rule_engine.py line ~1063 for the same incorrect pattern.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/gradata/enhancements/self_healing.py` around lines 581 - 598, The rule_id
generation uses Python's process-randomized
hash(candidate['original_description']), producing unstable IDs; replace that
with the stable digest used elsewhere by calling the existing _make_rule_id
helper from src/gradata/rules/rule_engine.py (or compute a SHA-256 hex prefix
deterministically from f"{category}:{original_description}"), then set rule_id =
f"{candidate['category'].upper()}:{digest}" and keep the rest of the receipt
construction the same; also search for the same incorrect hash() pattern in
rule_engine.py (~line 1063) and replace it with the same stable digest approach
so revert commands are deterministic across processes.

Gradata and others added 5 commits April 15, 2026 03:27
brain.auto_heal() reads recent RULE_FAILURE events, runs
review_rule_failures, gates each candidate through retroactive_test,
and applies the survivors via brain.patch_rule. Batches are
deduped by (category, original_description) and hard-capped at
max_patches (default 5) so a single session can't rewrite a rule
multiple times.

Before this commit, PR #21 emitted RULE_FAILURE but nothing
consumed it. The full flow required the caller to manually call
review_rule_failures + brain.patch_rule as the E2E test does.

Adds auto_heal_failures(brain, ...) orchestrator in self_healing.py
and Brain.auto_heal public method that delegates to it. 6 new
tests covering empty input, passing candidate, retro-test failure,
in-batch dedup, max_patches cap, and event-log read when no
events are passed.
When brain.correct() detects a RULE_FAILURE it now invokes
auto_heal_failures inline, capped at one patch per call so a
single correction can rewrite at most the rule it just failed.
Skipped in dry_run, approval_required, and renter modes; opt-out
via correct(auto_heal=False).

Adds auto_heal kwarg to brain.correct + brain_correct in _core.py
and surfaces the heal summary on event["auto_healed"] when a
patch lands. 3 new tests covering the default-on path, the
opt-out path, and the dry_run skip.

Closes the diagnose-then-do-nothing gap that PR #21 left open.
…ipt for visibility

Polyclaude council verdict (4/4 FALSE) on Phase 1: default auto_heal=True
is too hot. Ship False default plus a visible PatchReceipt so any auto-heal
that does fire is loud, not silent. Flip to True deferred until (a) a
pending_patches review queue and (b) ablation showing rule-quality lift on
a held-out broken-rule corpus.

- brain.correct() and _core.brain_correct() default auto_heal to False
- auto_heal_failures() returns PatchReceipt dicts: rule_id, old/new
  confidence, patch_diff, revert_command (legacy fields kept for BC)
- _core emits one stderr line per successful auto-heal patch so silent
  rule edits cannot sneak through
- tests: opt-in explicit auto_heal=True on existing integration tests,
  plus new test_default_off_no_patch and test_patch_receipt_shape

Co-Authored-By: Gradata <noreply@gradata.ai>
… ann + test fixture)

- Document auto_heal parameter on Brain.correct (defaults to False post-council)
- Add forward-ref Brain type annotation on auto_heal_failures via TYPE_CHECKING
- Hoist brain_with_rule to module-scope fixture and remove 5 duplicated class-level copies
- Split weak test_auto_heal_triggers_on_rule_failure into two deterministic tests: one asserts rule_failure_detected only, the second drives auto_heal_failures with known-good delta words and asserts patched==1 plus auto_heal: reason prefix

Co-Authored-By: Gradata <noreply@gradata.ai>
…ebase onto main

Rewrite TestSelfHealingE2E::test_inline_auto_heal_emits_rule_patched and
TestCorrectAutoHealIntegration::test_auto_heal_emits_patch_when_retroactive_test_passes
to exercise ONLY the inline `brain.correct(auto_heal=True)` path. Remove
the manual `review_rule_failures()` + `brain.patch_rule()` fallback so a
regression in the inline orchestration fails the test instead of being
masked by the fallback emitting RULE_PATCHED on its own.

Also address three smaller CR items:
- `_core.py`: forward `auto_heal` through the cloud branch by falling
  back to the local pipeline when the flag is set (cloud client does
  not yet carry the flag), so `auto_heal=True` is no longer silently
  dropped in cloud-connected brains.
- `_core.py`: route the auto-heal notice through `_log.warning` instead
  of `print(..., file=sys.stderr)` to keep the SDK logging pipeline
  consistent.
- `brain.py`: invalidate `_rule_cache` after `Brain.auto_heal()` applies
  patches, so later `apply_brain_rules()` calls see the patched prompt.

Rebased onto origin/main (includes #76 cloud split, #80 distribution,
#81 rule-to-hook auto-promotion). Rebase was conflict-free -- zero file
overlap between this branch and the three landed PRs.

Co-Authored-By: Gradata <noreply@gradata.ai>
@Gradata Gradata force-pushed the wt-phase1-self-healing branch from 1feae5c to 2b75fea Compare April 15, 2026 10:39
Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

Gradata has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/gradata/brain.py`:
- Around line 548-552: The try/except/pass around self._rule_cache.invalidate()
should be replaced with contextlib.suppress(Exception) to satisfy Ruff SIM105;
import contextlib if not already imported, then wrap the call to
self._rule_cache.invalidate() inside a contextlib.suppress(Exception) block
(condition remains result.get("patched")) so exceptions are suppressed without
an empty except.
🪄 Autofix (Beta)

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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: fc0e6ee0-d216-418f-abba-6802f1caf080

📥 Commits

Reviewing files that changed from the base of the PR and between 1feae5c and 2b75fea.

📒 Files selected for processing (4)
  • src/gradata/_core.py
  • src/gradata/brain.py
  • src/gradata/enhancements/self_healing.py
  • tests/test_self_healing.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: test (3.13)
  • GitHub Check: Test (Python 3.11)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.11)
  • GitHub Check: Test (Python 3.11)
  • GitHub Check: Cloudflare Pages
🧰 Additional context used
📓 Path-based instructions (2)
src/gradata/**/*.py

⚙️ CodeRabbit configuration file

src/gradata/**/*.py: This is the core SDK. Check for: type safety (from future import annotations required), no print()
statements (use logging), all functions accepting BrainContext where DB access occurs, no hardcoded paths. Severity
scoring must clamp to [0,1]. Confidence values must be in [0.0, 1.0].

Files:

  • src/gradata/brain.py
  • src/gradata/_core.py
  • src/gradata/enhancements/self_healing.py
tests/**

⚙️ CodeRabbit configuration file

tests/**: Test files. Verify: no hardcoded paths, assertions check specific values not just truthiness,
parametrized tests preferred for boundary conditions, floating point comparisons use pytest.approx.

Files:

  • tests/test_self_healing.py
🪛 GitHub Actions: SDK CI
src/gradata/brain.py

[error] 549-552: Ruff (SIM105) reported: Use contextlib.suppress(Exception) instead of try-except-pass for cache invalidation. Replace the try/except/pass block as suggested.

🔇 Additional comments (10)
src/gradata/enhancements/self_healing.py (2)

585-588: Unstable rule_id due to Python's randomized hash().

Python salts hash(str) per interpreter process, so the rule_id and revert_command will differ between the process that patched the rule and a later gradata rule revert ... invocation. This breaks the round-trip contract.

Use a stable digest (SHA-256) instead:

🔒 Proposed fix
+import hashlib
+
 def auto_heal_failures(
     ...
         if result.get("patched"):
-            rule_id = (
-                f"{candidate['category'].upper()}:"
-                f"{hash(candidate['original_description']) % 10000:04d}"
-            )
+            digest = hashlib.sha256(
+                f"{candidate['category']}:{candidate['original_description']}".encode()
+            ).hexdigest()[:8]
+            rule_id = f"{candidate['category'].upper()}:{digest}"

[raise_major_issue, duplicate_comment]


493-621: LGTM on the orchestration logic.

The auto_heal_failures function correctly implements the closed-loop flow: fetching events, generating candidates, gating with retroactive test, deduplicating, and applying patches. The defensive exception handling and cap enforcement are appropriate.

src/gradata/_core.py (2)

114-118: LGTM on the cloud routing fix.

The condition correctly skips cloud routing when auto_heal=True, ensuring the self-healing flag isn't silently dropped. The comment explains the rationale clearly.


436-471: LGTM on the inline auto-heal integration.

The gating conditions (auto_heal and not dry_run and not approval_required and not renter_mode) are correct. The defensive logging ensures visibility while never breaking the learning loop.

src/gradata/brain.py (2)

516-547: LGTM on the auto_heal() method.

The method correctly delegates to auto_heal_failures, and the cache invalidation when patches are applied addresses the stale rule cache concern from the prior review.


377-412: LGTM on the correct() signature update.

The auto_heal parameter is properly documented and forwarded to brain_correct. The docstring clearly explains the behavior and gating conditions.

tests/test_self_healing.py (4)

9-28: LGTM on the consolidated fixture.

The module-level brain_with_rule fixture eliminates the duplication flagged in the prior review while maintaining test isolation via scope="function".


422-532: LGTM on TestAutoHeal coverage.

The tests comprehensively cover the orchestrator: empty input, successful patching, retroactive test failures, deduplication, max_patches cap, and implicit event reading. Assertions are specific and check concrete values.


535-651: LGTM on TestCorrectAutoHealIntegration coverage.

The split between detection (test_auto_heal_detects_rule_failure) and patching (test_auto_heal_emits_patch_when_retroactive_test_passes) addresses the prior review concern about conditional assertions. The opt-out and dry_run tests ensure the gating logic is exercised.


654-710: LGTM on the E2E test.

The test explicitly verifies the inline path without fallback masking, ensuring regressions in the orchestration are caught. The on-disk rule rewrite assertion at line 708 confirms persistence.

Comment thread src/gradata/brain.py Outdated
…ff SIM105)

CodeRabbit's 3rd review on PR #77 + CI Ruff job both flagged the
try/except/pass block at brain.py:548-552 as SIM105 violation. Replaced
with contextlib.suppress(Exception) (contextlib already imported at
line 51). Behavior unchanged.

Co-Authored-By: Gradata <noreply@gradata.ai>
Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

Gradata has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@Gradata Gradata merged commit 8b4b10f into main Apr 15, 2026
16 of 18 checks passed
Gradata added a commit that referenced this pull request Apr 15, 2026
…test LOC)

Deletes dead code flagged in the autoresearch leanness audit after
grep-verifying that no runtime import path exists. All 2453 tests pass.

Source files removed (2101 LOC):
- src/gradata/contrib/enhancements/outcome_feedback.py (1 LOC, docstring stub)
- src/gradata/enhancements/super_meta_rules.py (197 LOC, no importers;
  SuperMetaRule dataclass + SQL table live in meta_rules.py /
  meta_rules_storage.py and remain wired)
- src/gradata/enhancements/pubsub_pipeline.py (49 LOC, test-only)
- src/gradata/rules/budget.py (43 LOC, test-only)
- src/gradata/rules/rw_lock.py (54 LOC, test-only)
- src/gradata/cloud/wiki_store.py (451 LOC, only cloud/__init__.py
  re-export + test)
- src/gradata/enhancements/rule_verifier.py (243 LOC, only manifest
  string + test reference)
- src/gradata/enhancements/rule_evolution.py (434 LOC, only manifest
  string + test references; contradiction_detector.py covers the live
  path via self_improvement.py:545)
- src/gradata/security/privacy_model.py (113 LOC, test + docs only;
  _core.py / brain.py / _export_brain.py grep-clean)
- src/gradata/benchmarks/swe_bench.py (516 LOC, docstring example +
  test only, no CLI/docs runtime reference)

Test files removed (1042 LOC): matching tests for each module plus
targeted pruning of rule_evolution test classes (TestRuleConflicts,
TestRuleRelationEnum, rule_evolution imports in TestIntegration) from
tests/test_steals.py and the TestRuleABTesting block in
tests/test_adaptations.py.

Registry + docstring updates:
- contrib/enhancements/install_manifest.py: drop rule_verifier from
  rule-integrity module components
- _manifest_helpers.py: drop rule_evolution from _core_modules
- enhancements/__init__.py: drop rule_verifier docstring line
- cloud/__init__.py: drop WikiStore lazy re-export
- enhancements/meta_rules_storage.py: docstring no longer points at
  the deleted super_meta_rules.py

NOT DELETED (verified live via PRs #77/#81/#86):
- enhancements/rule_ranker.py, self_healing.py, rule_canary.py,
  rule_to_hook.py (all have runtime callers)
- middleware/ (flagged empty in the audit but actually contains
  _core.py + 4 adapters — kept)
- src/gradata/graphify-out/ (did not exist in this tree)

Tests: 2453 passed, 24 skipped (test_integration_full.py ignored per
task spec).

Co-Authored-By: Gradata <noreply@gradata.ai>
Gradata added a commit that referenced this pull request Apr 15, 2026
…test LOC) (#90)

Deletes dead code flagged in the autoresearch leanness audit after
grep-verifying that no runtime import path exists. All 2453 tests pass.

Source files removed (2101 LOC):
- src/gradata/contrib/enhancements/outcome_feedback.py (1 LOC, docstring stub)
- src/gradata/enhancements/super_meta_rules.py (197 LOC, no importers;
  SuperMetaRule dataclass + SQL table live in meta_rules.py /
  meta_rules_storage.py and remain wired)
- src/gradata/enhancements/pubsub_pipeline.py (49 LOC, test-only)
- src/gradata/rules/budget.py (43 LOC, test-only)
- src/gradata/rules/rw_lock.py (54 LOC, test-only)
- src/gradata/cloud/wiki_store.py (451 LOC, only cloud/__init__.py
  re-export + test)
- src/gradata/enhancements/rule_verifier.py (243 LOC, only manifest
  string + test reference)
- src/gradata/enhancements/rule_evolution.py (434 LOC, only manifest
  string + test references; contradiction_detector.py covers the live
  path via self_improvement.py:545)
- src/gradata/security/privacy_model.py (113 LOC, test + docs only;
  _core.py / brain.py / _export_brain.py grep-clean)
- src/gradata/benchmarks/swe_bench.py (516 LOC, docstring example +
  test only, no CLI/docs runtime reference)

Test files removed (1042 LOC): matching tests for each module plus
targeted pruning of rule_evolution test classes (TestRuleConflicts,
TestRuleRelationEnum, rule_evolution imports in TestIntegration) from
tests/test_steals.py and the TestRuleABTesting block in
tests/test_adaptations.py.

Registry + docstring updates:
- contrib/enhancements/install_manifest.py: drop rule_verifier from
  rule-integrity module components
- _manifest_helpers.py: drop rule_evolution from _core_modules
- enhancements/__init__.py: drop rule_verifier docstring line
- cloud/__init__.py: drop WikiStore lazy re-export
- enhancements/meta_rules_storage.py: docstring no longer points at
  the deleted super_meta_rules.py

NOT DELETED (verified live via PRs #77/#81/#86):
- enhancements/rule_ranker.py, self_healing.py, rule_canary.py,
  rule_to_hook.py (all have runtime callers)
- middleware/ (flagged empty in the audit but actually contains
  _core.py + 4 adapters — kept)
- src/gradata/graphify-out/ (did not exist in this tree)

Tests: 2453 passed, 24 skipped (test_integration_full.py ignored per
task spec).

Co-authored-by: Gradata <noreply@gradata.ai>
@Gradata Gradata deleted the wt-phase1-self-healing branch April 17, 2026 19:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant