Skip to content

chore: wire dormant rules.injected emit + gitignore S105 orphans#88

Merged
Gradata merged 1 commit intomainfrom
claude/gracious-euclid
Apr 15, 2026
Merged

chore: wire dormant rules.injected emit + gitignore S105 orphans#88
Gradata merged 1 commit intomainfrom
claude/gracious-euclid

Conversation

@Gradata
Copy link
Copy Markdown
Owner

@Gradata Gradata commented Apr 15, 2026

Follow-ups to the Railway fix (gradata-cloud#1, #2, 54f2841 direct-to-main) — the (b) and (c) in our audit plan.

(c) Wire dormant rules.injected emit

integrations/session_history.py subscribes to three events:

  • correction.created — emitted at _core.py:138, 574
  • session.ended — emitted at _core.py:854
  • rules.injected — zero emitters anywhere in the tree

Result: SessionHistory.compute_effectiveness() is silently dead. Rules get injected every call but nothing records which ones, so per-session effectiveness tracking never runs.

Fix: brain.apply_brain_rules() now emits rules.injected on the in-memory bus after format_rules_for_prompt(applied). Cache hits skip intentionally — SessionHistory dedups via a set, the rule cache is per-scope, fresh scopes hit the compute path.

(b) Gitignore on-disk orphans

Tests

  • tests/test_session_history.py — 7 pass (1 new)
  • test_loop_and_security, test_integrations, test_nervous_system_integration — 64 pass

Follow-ups not here

  • Publish gradata 0.5.0 to PyPI so gradata-cloud can drop the SHA-tarball pin
  • ~2000 LOC dead-code prune — deferred as its own initiative
  • Physically delete the three orphan dirs on disk (gitignore only stops them recurring)

🤖 Generated with Claude Code

(c) Wire dormant emitter
------------------------
SessionHistory in integrations/session_history.py subscribes to
`rules.injected` but nothing in the codebase ever emits it — grep of
the whole tree shows only the subscriber. That leaves its per-session
rule effectiveness tracking (compute_effectiveness / on_session_ended)
silently dead.

brain.apply_brain_rules() now fires the event on the in-memory bus
after format_rules_for_prompt(applied). Cache hits skip the emit
intentionally: SessionHistory dedups via a set, the cache is per
scope, and every fresh scope hits the compute path.

The other two events SessionHistory subscribes to (correction.created,
session.ended) already have emitters — checked at _core.py:138, 574,
854. So this is the one missing wire.

Regression test: test_apply_brain_rules_emits_rules_injected — seeds
a graduated TONE rule through a real correct() loop, subscribes a
SessionHistory to the brain's bus, calls apply_brain_rules, asserts
the injected set is populated.

(b) Gitignore on-disk orphans
-----------------------------
Three untracked leftovers from the S105 repo splits keep showing up
in `git status` and sometimes get accidentally re-added:

  - /cloud/           moved to private Gradata/gradata-cloud (#76)
  - /sdk/             superseded by the flattened layout (#65)
  - /railway.toml     now lives in gradata-cloud/cloud/railway.toml

Also added apollo-leads-*.csv since sales exports have leaked into
the repo root before and belong in brain/leads/, not the SDK tree.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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 ca63494 into main Apr 15, 2026
14 of 16 checks passed
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 15, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4629a465-397a-4911-9b1f-23774bc3f9a8

📥 Commits

Reviewing files that changed from the base of the PR and between 81743f2 and 3ad836b.

📒 Files selected for processing (3)
  • .gitignore
  • src/gradata/brain.py
  • tests/test_session_history.py

📝 Walkthrough
  • Wire dormant rules.injected emit: brain.apply_brain_rules() now emits a rules.injected event on the in-memory bus after formatting applied rules; cache hits intentionally skip the emit, enabling proper rule-effectiveness tracking in SessionHistory
  • Add regression test: New test test_apply_brain_rules_emits_rules_injected verifies that SessionHistory observes injected rules when apply_brain_rules() is called with real corrections
  • Gitignore orphaned artifacts: Added entries to .gitignore for /cloud/, /sdk/, /railway.toml, and apollo-leads-*.csv to prevent recurring on-disk remnants from repository splits
  • No breaking changes, public API additions, or security fixes included
  • All tests passing: 7 tests in test_session_history.py (including 1 new) and 64 tests across other test groups

Walkthrough

The changes add event emission to rule application in the Brain class when rules are successfully applied, update gitignore to exclude additional orphaned artifacts and stale config files, and introduce a regression test to verify the new event is properly emitted and observed by SessionHistory.

Changes

Cohort / File(s) Summary
Gitignore Configuration
.gitignore
Added ignore rules for orphaned directories (cloud/, sdk/), stale configuration (railway.toml), and sales export files (apollo-leads-*.csv).
Event Emission on Rule Application
src/gradata/brain.py
apply_brain_rules() now emits a "rules.injected" event to the in-memory bus with rule IDs and task context when rules are successfully applied, excluding cached rule hits.
Regression Test
tests/test_session_history.py
Added test verifying that SessionHistory correctly observes the "rules.injected" event emitted by Brain when apply_brain_rules() is called, confirming end-to-end event integration.

Sequence Diagram

sequenceDiagram
    participant Test
    participant Brain
    participant Bus
    participant SessionHistory
    
    Test->>Brain: apply_brain_rules("write an email")
    activate Brain
    Brain->>Brain: format & apply rules
    Note over Brain: applied is non-empty
    Brain->>Bus: emit("rules.injected",<br/>{"rules": [...], "task": ...})
    deactivate Brain
    Bus->>SessionHistory: rules.injected event
    activate SessionHistory
    SessionHistory->>SessionHistory: update injected_this_session
    deactivate SessionHistory
    Test->>SessionHistory: assert injected_this_session<br/>has rule IDs
    SessionHistory-->>Test: ✓ verified
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested labels

bug

✨ 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 claude/gracious-euclid

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

@coderabbitai coderabbitai Bot added the bug Something isn't working label Apr 15, 2026
Gradata added a commit that referenced this pull request Apr 15, 2026
#88 landed at the same time as #86 and #87 shipping from a parallel
session. The merges didn't conflict line-wise, but the diffs overlap:

- brain.py:apply_brain_rules — #86 already wired `rules.injected`
  with a richer payload (id + category + confidence + state + scope)
  and try/except guard. #88 added a second thinner emit after the
  cache.put. Result: double-fire on fresh compute. Harmless in
  practice — SessionHistory dedups via a set — but clearly wrong.
  Removing #88's emit, keeping #86's.

- .gitignore — #87 already added `/cloud/` and `/sdk/`. #88's re-adds
  are duplicates. Removing; keeping `/railway.toml` and
  `apollo-leads-*.csv` which are genuinely new from #88.

The regression test in tests/test_session_history.py stays — it
asserts the emit fires end-to-end from a real Brain + correct() loop,
complementing #86's test_wiring_compound.py coverage of payload shape.
Both pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Gradata added a commit that referenced this pull request Apr 15, 2026
#88 landed at the same time as #86 and #87 shipping from a parallel
session. The merges didn't conflict line-wise, but the diffs overlap:

- brain.py:apply_brain_rules — #86 already wired `rules.injected`
  with a richer payload (id + category + confidence + state + scope)
  and try/except guard. #88 added a second thinner emit after the
  cache.put. Result: double-fire on fresh compute. Harmless in
  practice — SessionHistory dedups via a set — but clearly wrong.
  Removing #88's emit, keeping #86's.

- .gitignore — #87 already added `/cloud/` and `/sdk/`. #88's re-adds
  are duplicates. Removing; keeping `/railway.toml` and
  `apollo-leads-*.csv` which are genuinely new from #88.

The regression test in tests/test_session_history.py stays — it
asserts the emit fires end-to-end from a real Brain + correct() loop,
complementing #86's test_wiring_compound.py coverage of payload shape.
Both pass.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Gradata Gradata deleted the claude/gracious-euclid branch April 17, 2026 19:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant