feat(agent): dynamic, anomaly-derived diagnostic hypotheses + adaptive fork count#93
Merged
Merged
Conversation
…e fork count Closes #91. Fork hypotheses were a hard-coded generic list, and the coordinator took the first N regardless of what the anomaly was. Now they are derived from the anomaly and the fork count adapts to how many causes it warrants. - config.agent_hypothesis_mode (static | map | llm, default map), validated at startup via a Literal. Only takes effect when agent_diagnostic_forks > 1. - ANOMALY_HYPOTHESES: per-anomaly_type candidate causes (latency_spike, throughput_drop, backpressure, checkpoint_failure, memory_pressure, error_burst); unknown/unmapped types fall back to the generic angles. - _plan_hypotheses picks the pool per mode and bounds it by the cap; the resulting length is the fork count, so a clear-cut anomaly runs one agent even when the cap is higher (adaptive). llm mode calls the model once pre-fan-out and falls back to the map on any failure, so a diagnosis never hinges on it. - _run_diagnostics fans out over the planned hypotheses (single-agent when 0/1, seeded with the one hypothesis if present). agent_diagnostic_forks default 1 still preserves single-agent behavior. Also refreshes the fork runbook (mode config, adaptive count, type-specific log example). Tests: cap<=1 -> single, map type-specific + unknown fallback, static generic, cap bounding, llm parse + failure fallback, fork seeding with type hypotheses, adaptive count below cap, and config default/override/invalid-rejected. Full suite 255 passed; ruff + mypy clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #91.
Problem
Fork hypotheses (#67) were a hard-coded generic list, and the coordinator took the first N regardless of what the anomaly actually was, the cert-video limitation. The forks should be derived from this anomaly, and the fork count should adapt to how ambiguous it is.
Fix
config.agent_hypothesis_mode(static|map|llm, defaultmap), validated at startup via aLiteral. Only matters whenagent_diagnostic_forks > 1.ANOMALY_HYPOTHESES: per-anomaly_typecandidate causes (latency_spike, throughput_drop, backpressure, checkpoint_failure, memory_pressure, error_burst); unknown/unmapped types fall back to the generic angles._plan_hypothesespicks the pool per mode and bounds it by the cap; the resulting length is the fork count, so a clear-cut anomaly runs one agent even when the cap is higher (adaptive).llmmode calls the model once pre-fan-out and falls back to the map on any failure, so a diagnosis never hinges on the optional pre-step._run_diagnosticsfans out over the planned hypotheses (single-agent when 0/1, seeded with the one hypothesis if present).agent_diagnostic_forksdefault1still preserves single-agent behavior. Also refreshes the fork runbook (mode config, adaptive count, type-specific log example).Tests
cap<=1-> single; map type-specific + unknown fallback; static generic; cap bounding; llm parse + failure-fallback-to-map; fork seeding with type hypotheses; adaptive count below cap; config default/override/invalid-rejected.Full suite 255 passed; ruff + mypy clean.
Related: builds on #67; complements #77 (cross-cycle change awareness).
https://claude.ai/code/session_01R5VygSzbGTggW7mHd3PVwE