Record every harness run in ai_runs with redaction and purge
CI / ci (push) Successful in 1m35s
CI / ci (pull_request) Successful in 1m32s

harness.Run now writes one ai_runs row per run that reaches the provider,
covering the repair turn: skill, version, provider, model, temperature,
status (ok, repaired, bad_output, provider_error), latency, summed token
counts when reported, error text and the per-turn request and response
bodies. Every stored string is redacted first: the decrypted API key,
Authorization and API-key header values, Google Chat webhook URLs and
URLs with key-like query or fragment parameters or user info. JSON is
decoded and its strings redacted, so escapes cannot hide a credential.
A row that cannot be written fails the run.

Purge deletes rows created before a cutoff (RunRetention is 30 days),
clearing suggestion_batches and week_plans references in the same
transaction.

Migration 0006 rebuilds ai_runs with the new status CHECK and a
created_at index; a pre-harness running or error row stops it.

Maestro task 53e382d8-1db3-4555-a31d-e44cf55cc98d.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-05 09:32:20 -04:00
co-authored by Claude Opus 5.5
parent 5d5404b3cb
commit b0cf6fb951
13 changed files with 1141 additions and 37 deletions
+8 -1
View File
@@ -150,7 +150,14 @@ automatic** (D-021).
Anthropic and Ollama endpoints, called over plain HTTP — no vendor SDKs.
- **Skill harness** (`ai/harness`): prompt layering, validation of the
structured output, and **one repair retry**; if the repair also fails the
run fails — no silent fallback. Every call is recorded in `ai_runs`.
run fails — no silent fallback. Every run that reaches the provider writes
one `ai_runs` row when it ends, covering the repair turn too, with status
`ok`, `repaired`, `bad_output` or `provider_error`. Request and response
bodies are redacted before they are stored: the decrypted API key,
Authorization and API-key header values, Google Chat webhook URLs and URLs
with key-like query parameters are removed, inside JSON strings too.
`harness.Purge` deletes rows older than `harness.RunRetention` (30 days),
clearing the `suggestion_batches` and `week_plans` references first.
- **Prompt layering** (D-007): each skill version's prompt is a
`text/template` file embedded from `ai/skills/prompts/`
(`<skill>.v<version>.tmpl`). The system prompt is always, in order: