feat(plane): verify and agree tasks with metered hunts (task 6)

Requirements 5.3, 2.1, 2.2, 2.3, 7.2 of ai-service-plane.

- plane/tasks/verify.py: the batched hunt of verify_batched.py moved into
  the package (system prompt, one hunt per file, up to 6 candidates, 6
  steps, candidate-anchored sites). New against the reference: each
  candidate's known callers from facts.json in the prompt (capped at 8),
  tool turns and usage per hunt in units.jsonl, per-unit resume (rows
  with "error" are re-asked), pass label from env, MeteredClient wrapper:
  BudgetExhausted -> unfinished (exit 3), AccountError -> failed with the
  provider message (exit 2); summary.json is written last, names the bound
  Model and the summed usage, and is done only when every unit finished.
- plane/tasks/agree.py: verify_batched.agreement over two pass outputs,
  agreed.json / disputed.json, per-candidate cost and turns, declared-site
  match via benchmarks/independent/evaluate.matches_v2 loaded by file;
  metrics block in summary.json; no model calls.
- tests/test_plane_verify.py: a scripted usage-recording hunter client;
  callers line, resume, 402, budget stop and resume, model and summed
  usage, unpriced usd None, both main() env contracts, agreement metrics.
- model/audit.py + module-audit manifest: SPEC_OWNED rows for plane.tasks,
  plane.tasks.verify, plane.tasks.agree; manifest regenerated.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
This commit is contained in:
Marius Ciepluch
2026-09-29 18:05:08 +02:00
co-authored by Claude Fable 5.1
parent 488e63951e
commit 0cbdc5d2ac
6 changed files with 891 additions and 5 deletions
@@ -1,7 +1,7 @@
{
"modules": 121,
"modules": 124,
"counts": {
"load_bearing": 112,
"load_bearing": 115,
"standalone_capability": 9
},
"orphaned": [],
@@ -56,6 +56,7 @@
"complexity.ledger",
"complexity.map",
"map_gate",
"plane.tasks.verify",
"regress.candidate",
"semantic.prove_filter",
"tool_hunter"
@@ -90,6 +91,7 @@
"complexity.hints",
"complexity.ledger",
"map_gate",
"plane.tasks.verify",
"regress.candidate",
"semantic.prove_filter",
"tool_hunter"
@@ -653,13 +655,17 @@
"module": "plane",
"classification": "load_bearing",
"reason": "ai-service-plane Req 1-4: the service plane package; runner and reconciler integration in tasks 3-4",
"importers": []
"importers": [
"plane.tasks.verify"
]
},
{
"module": "plane.budget",
"classification": "load_bearing",
"reason": "ai-service-plane Req 2.3/2.4: metered chat client with usd and calls ceilings; task integration in tasks 3, 6",
"importers": []
"importers": [
"plane.tasks.verify"
]
},
{
"module": "plane.manifests",
@@ -667,6 +673,28 @@
"reason": "ai-service-plane Req 1.1-1.4: ax-shaped Task/Workspace/Model and the Run kind, validated before anything runs",
"importers": []
},
{
"module": "plane.tasks",
"classification": "load_bearing",
"reason": "ai-service-plane Req 2.1: the tasks package, each a main() under the OUSAST_* env contract; runner wiring in task 3",
"importers": [
"plane.tasks.agree"
]
},
{
"module": "plane.tasks.agree",
"classification": "load_bearing",
"reason": "ai-service-plane Req 5.3/2.1: agreement across two verify passes with per-candidate cost, turns and site match",
"importers": []
},
{
"module": "plane.tasks.verify",
"classification": "load_bearing",
"reason": "ai-service-plane Req 5.3/2.1-2.3/7.2: the batched hunt with known callers, metered and resumable per file hunt",
"importers": [
"plane.tasks.agree"
]
},
{
"module": "policy",
"classification": "load_bearing",
@@ -1320,7 +1348,8 @@
"reason": "reachable from gate, map_gate, pair_gate or the CLI",
"importers": [
"model.endpoint",
"plane.budget"
"plane.budget",
"plane.tasks.verify"
]
},
{