Repository navigation
fix(unwired): wire ClaimVerifier, FailurePatternDetector, self-improvement loop, NPU events #10602
Copy link
Copy link
Closed
Labels
agentsenhancementNew feature or requestNew feature or requestknowledgeKnowledge base systemKnowledge base systemnot-wiredImplemented but not connected to appImplemented but not connected to apppriority: medium
Description
Task 6 — Wire in unwired services & the self-improvement loop
Theme: Built-but-unwired. Whole services and the self-improvement write-path are implemented but have zero production callers (matches the prior Ornith-1.0 "read wires disconnected" finding). Per project policy these are wire-in, never deletion.
Problem & subtasks
- 6.1 Wire
ClaimVerifierinto grounding/agent flow —services/claim_verifier.py:121(zero non-test callers)- Step: invoke from
GroundedAgent/knowledge_grounding; surfacerequires_human_review - Step: dedup with
services/claim_classifier.py:59(also unused;GroundedAgent._extract_claims:338reimplements it inline)
- Step: invoke from
- 6.2 (DONE — get_pattern_detector() wired into workflow_runner failure path) Wire
FailurePatternDetectorinto error/task-completion flow —services/failure_pattern_detector.py:78,361(singleton never accessed)- Step: call
detect_pattern/learn_patternfrom a central error handler or task-completion hook
- Step: call
- 6.3 Reconnect the self-improvement WRITE path —
judges/task_outcome_judge.py:41,agents/task_pattern_learner.py:51- Step: the read side (
agents/agent_orchestration/routing.py:_check_learned_strategy) reads learned strategies from Redis, but nothing writes them. Both writers are dead:phase_progression_manager.py:748(callersexecute_automated_progression/trigger_manual_progressionhave zero callers) andllc/kb/diary_writer.py:248(nothing ever setscontext_snapshot["outcomes"]) - Step: feed real outcome dicts into diary
context_snapshot["outcomes"], OR scheduleexecute_automated_progression - Step: verify learned strategies now appear in Redis and influence routing
- Step: the read side (
- 6.4 (DONE via feat(npu): publish worker added/status/metrics events + avg_response_time_ms (#10602 6.4, #10698) #10951) Publish missing NPU worker events —
services/npu_worker_manager.py:991- Step: subscribers exist (
api/websockets.py:978,services/npu_pipeline/invalidation.py:57) fornpu.worker.added/status.changed/metrics.updatedbut onlyremovedis published — emit the other three at the manager mutation sites so cache invalidation + live frontend updates fire
- Step: subscribers exist (
- 6.5 Consolidate dual subagent systems / enable reflection —
enhanced_orchestration/subagent_dispatcher.py:71,129,232vsservices/agents/subagent_spawner.py:88- Step:
get_subagent_dispatcher()has zero callers andenable_reflectiondefaults False & is never set; converge onto the live spawner and passenable_reflection=Truewhere valuable
- Step:
- 6.6 Stop discarding agent-recommendation scores —
enhanced_orchestration/agent_router.py:42-57- Step: return scores so callers can threshold-gate/audit; feed
orchestration/performance_tracker.pyupdates back into the recommender at runtime
- Step: return scores so callers can threshold-gate/audit; feed
- 6.7 Use
lightweight_mode_usedto short-circuit heavy path —llm_shared/models.py:138,chat_workflow/manager.py:576- Step: when trivial-tier, skip expensive RAG fetch/rerank/validation instead of only tagging metadata
Verification
- Each subtask: add a test proving the previously-dead path now executes (e.g. learned strategy written→read; NPU event received by subscriber)
Notes
ABSOLUTE: never delete this code — wire it in. Several items are independently shippable; split into separate PRs if a single PR grows too large.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
agentsenhancementNew feature or requestNew feature or requestknowledgeKnowledge base systemKnowledge base systemnot-wiredImplemented but not connected to appImplemented but not connected to apppriority: medium
Activity
mrveiss commentedon Jun 28, 2026
Part of umbrella #10603 (AutoBot Efficiency & Precision).
mrveiss commentedon Jun 28, 2026
Premise re-verification (2026-06-28, current base after py3.14 + 19 merged PRs)
Re-checked each claim against the current code before implementing. The base moved — several claims are now stale or deeper than originally recorded:
services/claim_verifier.py:121,claim_classifier.py:482zero prod callers)get_pattern_detector:364no callers; no reader either)learn_patternon failure, e.g.workflow_runner._handle_workflow_execution_failure:315) and a READER (detect_patternat retry, or stats API) — writer alone = orphan dataexecute_automated_progression/trigger_manual_progressionzero callers; nothing setscontext_snapshot["outcomes"])added/status.changed/removednow published (npu_worker_manager.py:893/775/991). Onlymetrics.updatedmissing, and there is no metrics producer at all (npu:worker:{id}:metricsis only read/deleted)get_subagent_dispatcherANDsubagent_spawnerhave zero prod callers)agent_router.py:57), path is live (/agents/recommend)lightweight_mode_usedlightweight_modebool (chat_workflow/manager.py:2864→llm_handler.py:760/788). The flagged field is a legitimate write-only UI cost indicator.Net: #7 drops out; #4 is deeper (needs a producer); #1/#2/#3/#5/#6 are genuine but each is a small feature (consumer + writer, sometimes a product call), not a one-line wire. Recommend tackling one at a time, each with its consumer, rather than a bulk PR.
feat(reliability): wire FailurePatternDetector into workflow failure …
feat(orchestration): surface agent recommendation scores (#10660) (#1…
mrveiss commentedon Jun 29, 2026
Decision doc — §6.5 dual subagent systems (needs a canonical-choice decision)
There are two parallel-subagent implementations, both currently unwired in production (only test references). They have complementary strengths, so wiring requires picking the canonical one first.
SubagentDispatcher(enhanced_orchestration/subagent_dispatcher.py)SubagentSpawner(services/agents/subagent_spawner.py)enable_reflection)MAX_SUBAGENT_DEPTH+MAX_SUBAGENTS_PER_PARENTpending_tasks/active_subagents)spawn_parallel_tasks(awaits all)wait_for_allflag (fire-and-forget option)tests/orchestration/test_subagent_dispatcher_reflection.pyYour decision (pick one)
Once you pick, the wire-in (into the orchestrator's parallel-workstream execution path) is a follow-up PR. Until then this stays blocked — I won't guess the architecture.
mrveiss commentedon Jun 29, 2026
Decision docs — remaining §6.1 / §6.3 / §6.4 (need a design choice each)
(§6.2 FailurePatternDetector shipped in #10631; §6.6 agent scores shipped in #10661; §6.5 dual-subagent decision doc posted above; §6.7 lightweight_mode = non-issue.)
§6.1 — Wire ClaimVerifier into grounding
Gap:
services/claim_verifier.py+claim_classifier.pyhave zero production callers;GroundedAgentreimplements claim extraction inline. But GroundedAgent itself isn't on the chat path (see §3.5), so wiring ClaimVerifier into GroundedAgent improves an unused component.Options: A — replace GroundedAgent's inline logic with ClaimVerifier/ClaimClassifier (dedups; readies it for §3.5). B — defer until §3.5 decides whether GroundedAgent goes on the chat path.
Recommendation: A as a prep refactor (low user-visible risk, dedups), OR bundle with §3.5. Risk: low-med. Sequence with §3.5.
§6.3 — Reconnect the self-improvement write-path
Gap:
TaskPatternLearner.learn_from_outcomes(the WRITE side of the learning loop) has two dead feeders:phase_progression_manager.execute_automated_progression/trigger_manual_progression(zero callers) anddiary_writerreadingcontext_snapshot["outcomes"](never set). The READ side (routing reads learned strategies from Redis) works but nothing writes.Options: A — set
context_snapshot["outcomes"]at the point task outcomes are recorded, sodiary_writerruns the learner (event-driven). B — scheduleexecute_automated_progressionon a Celery beat cadence (batch). C — both.Recommendation: A (event-driven, closes the loop at the natural write point) — but needs care to feed real outcome dicts. Risk: med-high (touches the agent outcome-recording path). Your call on trigger.
§6.4 — NPU
metrics.updatedeventGap: subscriber exists (
api/websockets.py), butnpu.worker.metrics.updatedis never published — and there is no metrics producer at all (npu:worker:{id}:metricsis only read/deleted;NPUWorkerMetricsis never written). Onlyavg_response_timeis derivable from existing pulse data;success_rate/requests_per_minuteneed new request/error counters.Options: A — build the producer: add request/error counters in the worker dispatch path, compute+store
NPUWorkerMetricson the health/pulse loop, then emitmetrics.updated. B — emit partial metrics (only avg_response_time from pulse p95) now, fill the rest later.Recommendation: A (do it properly) — but it's an instrumentation feature, and its runtime value depends on active NPU workers + a frontend consumer. Risk: med. Lowest priority of the three.
All await your pick before I implement.
feat(npu): produce + emit worker metrics (#10697) (#10699)
feat(npu): publish worker added/status/metrics events + avg_response_…
feat(agent): wire ClaimVerifier + self-improvement write-path + subag…
mrveiss commentedon Jul 6, 2026
Delivered via PR #10990 — ClaimVerifier + self-improvement write-path + subagent reflection wired into hot paths (config-gated); FailurePatternDetector/NPU/scores/lightweight-mode confirmed already wired. 17 tests.