Skip to content

feat(learning): reduce maintenance signal noise#239

Merged
xinhuagu merged 2 commits into
mainfrom
codex/issue-230-learning-noise-control
Mar 13, 2026
Merged

feat(learning): reduce maintenance signal noise#239
xinhuagu merged 2 commits into
mainfrom
codex/issue-230-learning-noise-control

Conversation

@xinhuagu

@xinhuagu xinhuagu commented Mar 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • add source-based upsert for maintenance-derived learning signals
  • prune low-value maintenance signals more aggressively with aging-aware consolidation
  • suppress repeated maintenance candidate observations for recently seen source refs

Testing

  • ./gradlew :aceclaw-memory:test --tests dev.aceclaw.memory.AutoMemoryStoreTest --tests dev.aceclaw.memory.MemoryConsolidatorTest --tests dev.aceclaw.memory.CrossSessionPatternMinerTest --tests dev.aceclaw.memory.TrendDetectorTest --no-daemon
  • ./gradlew :aceclaw-daemon:test --tests dev.aceclaw.daemon.LearningMaintenanceCandidateBridgeTest --no-daemon
  • ./gradlew :aceclaw-memory:test :aceclaw-daemon:test --no-daemon

Closes #230

Summary by CodeRabbit

Release Notes

  • New Features

    • Added 24-hour suppression window to prevent duplicate observations from the same source.
    • Implemented smart upsert logic for maintenance signals and patterns, replacing duplicates instead of accumulating copies.
    • Introduced age-based memory cleanup with differentiated retention periods for maintenance signals (30 days) and session analysis (45 days).
  • Tests

    • Added validation tests for suppression, upsert behavior, and aggressive pruning of low-value signals.

@greptile-apps greptile-apps 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.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai

coderabbitai Bot commented Mar 13, 2026

Copy link
Copy Markdown

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

Implements noise control and aging for learned signals by: (1) suppressing repeated candidate observations within a 24-hour window in the learning bridge, (2) introducing source-keyed upsert operations in AutoMemoryStore to replace stale entries, (3) updating pattern and trend miners to use upsert-by-source persistence, and (4) implementing source/category-specific aging thresholds to prune low-value maintenance signals more aggressively.

Changes

Cohort / File(s) Summary
Suppression Window & Bridge
aceclaw-daemon/src/main/java/.../LearningMaintenanceCandidateBridge.java, aceclaw-daemon/src/test/.../LearningMaintenanceCandidateBridgeTest.java
Adds 24-hour SOURCE_SUPPRESSION_WINDOW and suppression logic via shouldSuppress() and recentSourceRefs() helpers to prevent upserting observations from recently-seen sources. Test validates suppression behavior.
AutoMemoryStore Upsert-by-Source
aceclaw-memory/src/main/java/.../AutoMemoryStore.java, aceclaw-memory/src/test/.../AutoMemoryStoreTest.java
Introduces upsertBySource() public method to replace or insert memory entries by category+source key, and private rewriteEntriesForFile() helper for atomic file rewrites. Test verifies replacement of existing entries and persistence across reloads.
Pattern & Trend Persistence Updates
aceclaw-memory/src/main/java/.../CrossSessionPatternMiner.java, aceclaw-memory/src/main/java/.../TrendDetector.java, aceclaw-memory/src/test/.../CrossSessionPatternMinerTest.java, aceclaw-memory/src/test/.../TrendDetectorTest.java
Replaces addIfAbsent() with upsertBySource() calls in four memory entry categories (ANTI_PATTERN, WORKFLOW, SUCCESSFUL_STRATEGY, FAILURE_SIGNAL) and trends. Tests confirm upsert-based deduplication prevents accumulation of duplicate signals.
Source/Category-Specific Aging & Pruning
aceclaw-memory/src/main/java/.../MemoryConsolidator.java, aceclaw-memory/src/test/.../MemoryConsolidatorTest.java
Adds MAINTENANCE_SIGNAL_AGE_THRESHOLD (30 days) and SESSION_ANALYSIS_AGE_THRESHOLD (45 days), reworks Pass 3 pruning with shouldArchive(), ageThreshold(), and isMaintenanceDerived() helpers to apply source-specific retention policies. Test validates aggressive pruning of low-value maintenance signals.

Sequence Diagram

sequenceDiagram
    actor Learner as Learning Pipeline
    participant Bridge as LearningMaintenanceCandidateBridge
    participant Store as AutoMemoryStore
    participant Consolidator as MemoryConsolidator
    
    Learner->>Bridge: observe(miningResult)
    
    alt Suppression Check
        Bridge->>Bridge: recentSourceRefs() from candidates
        Bridge->>Bridge: shouldSuppress(observation, recentSources)?
        alt Source Recently Seen (< 24h)
            Bridge-->>Learner: skip upsert
        else New Source
            Bridge->>Store: upsertBySource(category, content, source)
            Store->>Store: replace existing or insert new
            Store-->>Bridge: MemoryEntry
            Bridge-->>Learner: upsert complete
        end
    end
    
    note over Store: Later: Consolidation Pass
    Consolidator->>Store: consolidate(archiveDir)
    Consolidator->>Consolidator: for each entry: shouldArchive(entry, now)?
    
    alt Archive Decision
        Consolidator->>Consolidator: isMaintenanceDerived(entry)?
        alt Maintenance Signal (source: maintenance:, trend:, etc.)
            alt Age > 30 days
                Consolidator->>Consolidator: archive (aggressive)
            else Age < 30 days
                Consolidator->>Store: keep entry
            end
        else Session Analysis (source: session-analysis:)
            alt Age > 45 days
                Consolidator->>Consolidator: archive
            else Age < 45 days
                Consolidator->>Store: keep entry
            end
        else Other Entry
            alt Age > 90 days
                Consolidator->>Consolidator: archive
            else Age < 90 days
                Consolidator->>Store: keep entry
            end
        end
    end
    
    Consolidator-->>Consolidator: purge archived entries
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Block Major Correctness And Security Risks ❌ Error PR introduces multiple major data integrity risks: upsertBySource() swallows IOException when persisting changes to disk, silently failing while reporting success and causing data loss on restart. trackAccess() updates are never persisted, allowing accessed entries to be incorrectly pruned as unused after restart. Source deduplication is incomplete, leaving stale variants in the store. Critical error handling and persistence gaps exist. Return boolean/exception from rewriteEntriesForFile() to propagate write failures and return Optional.empty() on failure. Persist access metadata to disk after trackAccess() updates. Complete source deduplication during upsert. Add tests for disk failures, metadata persistence across restarts, and deduplication.
Docstring Coverage ⚠️ Warning Docstring coverage is 15.63% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(learning): reduce maintenance signal noise' accurately summarizes the main objective of the PR: implementing noise control mechanisms for learning signals.
Linked Issues check ✅ Passed The PR implementation comprehensively addresses all key requirements from issue #230: source-based upsert deduplicates signals [AutoMemoryStore], aging thresholds prune low-value maintenance signals [MemoryConsolidator], 24-hour suppression prevents noisy observations [LearningMaintenanceCandidateBridge], and TrendDetector/CrossSessionPatternMiner use upsertBySource to avoid accumulation.
Out of Scope Changes check ✅ Passed All changes are directly scoped to noise control objectives: suppression logic, aging policies, upsert mechanisms, and consolidation rules. No unrelated refactoring, dependency upgrades, or functional changes outside the noise reduction scope are present.
✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/issue-230-learning-noise-control
📝 Coding Plan
  • Generate coding plan for human review comments

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 and usage tips.

@xinhuagu xinhuagu merged commit e805e6d into main Mar 13, 2026
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.

feat(learning): noise control and aging for memories, patterns, and trends

1 participant