Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b1f4852
fix(watcher): reap finished issue-processing task handles
claudear Aug 10, 2026
1585c44
Merge remote-tracking branch 'origin/feat/fix-discord-untrusted-bound…
ArnabChatterjee20k Aug 16, 2026
2ec80ea
fix(watcher): close shutdown race recording spawned tasks
ArnabChatterjee20k Aug 16, 2026
e4d295f
empty
ArnabChatterjee20k Aug 16, 2026
7b76708
fix(watcher): make shutdown drain cancel-safe
ArnabChatterjee20k Aug 16, 2026
c2e028c
fix(watcher): drain to completion instead of a fixed budget
ArnabChatterjee20k Aug 16, 2026
daa8c23
fix(watcher): bound shutdown drain, abort stragglers
ArnabChatterjee20k Aug 16, 2026
1ae5bc7
added sentry issue classify as error
ArnabChatterjee20k Aug 19, 2026
16c8010
fix(watcher): track retry/review processing in spawn_handles
ArnabChatterjee20k Aug 19, 2026
6b310e3
fix(cli): mark one-shot trigger watchers running
ArnabChatterjee20k Aug 19, 2026
1f31780
fix(watcher): bound the post-abort join in shutdown drain
ArnabChatterjee20k Aug 19, 2026
4937e76
fix(cli): bound tokio runtime teardown on shutdown
ArnabChatterjee20k Aug 19, 2026
764b8c2
test(e2e): make harness watcher Arc and mark it running
ArnabChatterjee20k Aug 19, 2026
fa8f724
fix(watcher): skip finished handles in post-abort drain join
ArnabChatterjee20k Aug 19, 2026
ca2acba
chore(scripts): add claudear resource footprint monitor
ArnabChatterjee20k Aug 20, 2026
8ba53a0
feat(scripts): auto-restart claudear from the monitor when it dies
ArnabChatterjee20k Aug 20, 2026
9e48e1d
revert(scripts): keep monitor pure-observation, decoupled from daemon…
ArnabChatterjee20k Aug 20, 2026
5322c85
feat(monitor): add auto-restart functionality for claudear daemon wit…
ArnabChatterjee20k Aug 20, 2026
1ba31d3
added comments for running
ArnabChatterjee20k Aug 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions crates/claudear-engine/src/processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2522,6 +2522,12 @@ impl IssueProcessor {
/// else (routes to Reply). Uses the LLM classifier when available, falling
/// back to the label/source heuristic (matching `FixAttempt::is_bug`).
async fn classify_is_bug_or_security(&self, issue: &Issue) -> bool {
// Sentry issues are genuine errors and always route to the fix pipeline;
// enforce that before the classifier, which could otherwise misroute them
// to the QA/reply path (matches heuristic_is_bug / FixAttempt::is_bug).
if issue.source == "sentry" {
return true;
}
if let Some(classifier) = self.intent_classifier.as_ref() {
// Classify against the reply thread so a follow-up is judged in context,
// but only Claudear's own answers — never untrusted user text — feed the
Expand Down Expand Up @@ -5927,8 +5933,51 @@ mod tests {
.is_none());
}

// Reproduces: a Sentry issue reaching classify_is_bug_or_security with an
// active LLM classifier is routed by the classifier verdict, bypassing the
// "sentry is always a bug" invariant that heuristic_is_bug enforces. If the
// classifier calls it a Question, the genuine Sentry error lands on the QA
// (reply) path instead of the fix pipeline.
#[tokio::test]
async fn test_classify_sentry_never_routed_to_qa() {
let tracker: Arc<dyn FixAttemptTracker> =
Arc::new(claudear_storage::SqliteTracker::in_memory().unwrap());
let mut processor = make_reply_chain_processor(tracker);
processor.intent_classifier = Some(Arc::new(StubIntentClassifier(Some(Intent::Question))));

// No reply_to_message_id metadata, so assemble_reply_chain short-circuits
// to None (no network) and the classifier verdict alone decides routing.
let issue = Issue::new(
"id-1",
"S-1",
"NullPointerException",
"https://s/1",
"sentry",
);

assert!(
processor.classify_is_bug_or_security(&issue).await,
"sentry errors are genuine bugs and must route to the fix pipeline, \
never QA, even when the classifier calls them a Question"
);
}

// --- Dummy test helpers ---

/// Intent classifier stub returning a fixed verdict (for routing tests).
struct StubIntentClassifier(Option<Intent>);

#[async_trait]
impl IntentClassifier for StubIntentClassifier {
async fn classify_intent(
&self,
_issue: &Issue,
_conversation: Option<&str>,
) -> Option<Intent> {
self.0
}
}

/// Dummy agent runner that does nothing (for IssueProcessor tests).
struct DummyAgent;

Expand Down
Loading
Loading