diff --git a/.aider.conventions.md b/.aider.conventions.md index 7b43b74..01003be 100644 --- a/.aider.conventions.md +++ b/.aider.conventions.md @@ -232,6 +232,12 @@ The brain HTTP REST API (`/query`, `/write`, `/ingest`, `/ingest-raw`, `/ingest-path`, `/backfill-refs`) remains available on the same port (3300) for shell scripts and non-MCP clients. +The brain HTTP REST API also serves a read-only `GET /pass-rate?skill=X&window=Y` +endpoint that aggregates `final_status` counts from session logs and returns +`{skill, window, pass, fail, skip, total, pass_rate}`. Plan 6 (routing pod) +reads this to decide whether to route skill calls to local models. Pass rate +is `null` when no logged invocations are in the window. + ## Agent instructions When acting as a coding agent on this project: diff --git a/.context/PROJECT.md b/.context/PROJECT.md index 5ebfa1f..7a4dab2 100644 --- a/.context/PROJECT.md +++ b/.context/PROJECT.md @@ -61,6 +61,12 @@ The brain HTTP REST API (`/query`, `/write`, `/ingest`, `/ingest-raw`, `/ingest-path`, `/backfill-refs`) remains available on the same port (3300) for shell scripts and non-MCP clients. +The brain HTTP REST API also serves a read-only `GET /pass-rate?skill=X&window=Y` +endpoint that aggregates `final_status` counts from session logs and returns +`{skill, window, pass, fail, skip, total, pass_rate}`. Plan 6 (routing pod) +reads this to decide whether to route skill calls to local models. Pass rate +is `null` when no logged invocations are in the window. + ## Agent instructions When acting as a coding agent on this project: diff --git a/.context/system-prompt.txt b/.context/system-prompt.txt index 1f8bd4c..10e407a 100644 --- a/.context/system-prompt.txt +++ b/.context/system-prompt.txt @@ -237,6 +237,12 @@ The brain HTTP REST API (`/query`, `/write`, `/ingest`, `/ingest-raw`, `/ingest-path`, `/backfill-refs`) remains available on the same port (3300) for shell scripts and non-MCP clients. +The brain HTTP REST API also serves a read-only `GET /pass-rate?skill=X&window=Y` +endpoint that aggregates `final_status` counts from session logs and returns +`{skill, window, pass, fail, skip, total, pass_rate}`. Plan 6 (routing pod) +reads this to decide whether to route skill calls to local models. Pass rate +is `null` when no logged invocations are in the window. + ## Agent instructions When acting as a coding agent on this project: diff --git a/.cursorrules b/.cursorrules index 8717e56..33efd99 100644 --- a/.cursorrules +++ b/.cursorrules @@ -235,6 +235,12 @@ The brain HTTP REST API (`/query`, `/write`, `/ingest`, `/ingest-raw`, `/ingest-path`, `/backfill-refs`) remains available on the same port (3300) for shell scripts and non-MCP clients. +The brain HTTP REST API also serves a read-only `GET /pass-rate?skill=X&window=Y` +endpoint that aggregates `final_status` counts from session logs and returns +`{skill, window, pass, fail, skip, total, pass_rate}`. Plan 6 (routing pod) +reads this to decide whether to route skill calls to local models. Pass rate +is `null` when no logged invocations are in the window. + ## Agent instructions When acting as a coding agent on this project: diff --git a/AGENTS.md b/AGENTS.md index 7b43b74..01003be 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -232,6 +232,12 @@ The brain HTTP REST API (`/query`, `/write`, `/ingest`, `/ingest-raw`, `/ingest-path`, `/backfill-refs`) remains available on the same port (3300) for shell scripts and non-MCP clients. +The brain HTTP REST API also serves a read-only `GET /pass-rate?skill=X&window=Y` +endpoint that aggregates `final_status` counts from session logs and returns +`{skill, window, pass, fail, skip, total, pass_rate}`. Plan 6 (routing pod) +reads this to decide whether to route skill calls to local models. Pass rate +is `null` when no logged invocations are in the window. + ## Agent instructions When acting as a coding agent on this project: diff --git a/CLAUDE.md b/CLAUDE.md index 5ebfa1f..7a4dab2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -61,6 +61,12 @@ The brain HTTP REST API (`/query`, `/write`, `/ingest`, `/ingest-raw`, `/ingest-path`, `/backfill-refs`) remains available on the same port (3300) for shell scripts and non-MCP clients. +The brain HTTP REST API also serves a read-only `GET /pass-rate?skill=X&window=Y` +endpoint that aggregates `final_status` counts from session logs and returns +`{skill, window, pass, fail, skip, total, pass_rate}`. Plan 6 (routing pod) +reads this to decide whether to route skill calls to local models. Pass rate +is `null` when no logged invocations are in the window. + ## Agent instructions When acting as a coding agent on this project: diff --git a/cmd/hyperguild/README.md b/cmd/hyperguild/README.md index a27d56d..7fdf59b 100644 --- a/cmd/hyperguild/README.md +++ b/cmd/hyperguild/README.md @@ -69,6 +69,35 @@ EOF knowledge/example-lesson.md ``` +### `hyperguild brain pass-rate ` + +Returns the pass rate for a skill over a lookback window. Computed +on-demand from `brain/sessions/*.jsonl`. + +```bash +$ hyperguild brain pass-rate tdd +tdd: 47 / 50 = 94% (window: 7d) + +$ hyperguild brain pass-rate tdd --window 30d --json +{ + "skill": "tdd", + "window": "30d", + "pass": 142, + "fail": 8, + "skip": 5, + "total": 155, + "pass_rate": 0.9467 +} +``` + +Flags: + +- `--window` — lookback window (default `7d`; accepts `Nh`, `Nd`) +- `--json` — emit the raw response envelope + +Skills with no logged invocations return zero counts and `pass_rate: null` +(indicating "no data", distinct from "always passes"). + ### `hyperguild mode ` Writes a `.mcp.json` template for the chosen operating mode. diff --git a/ingestion/internal/mcp/handlers.go b/ingestion/internal/mcp/handlers.go index 9c01bbb..1d3fa9d 100644 --- a/ingestion/internal/mcp/handlers.go +++ b/ingestion/internal/mcp/handlers.go @@ -77,7 +77,7 @@ func (s *Server) tools() []map[string]any { "skill": str("skill name"), "phase": str("phase within the skill"), "project_root": str("absolute project root"), - "final_status": str("ok | error | skipped"), + "final_status": str("pass | fail | skip (legacy: ok | error | skipped also accepted)"), "file_path": str("optional file produced"), "model_used": str("optional model identifier"), "duration_ms": int_("optional duration in ms"),