Commit Graph
59 Commits
Author SHA1 Message Date
Marius Ciepluch b850a86e2a Merge branch 'worktree-agent-ad03a357c98ed488d'
# Conflicts:
#	benchmarks/measurements/2026-09-08-module-audit.json
#	src/openultrasast/model/audit.py
2026-09-29 18:11:05 +02:00
Marius Ciepluch ee44d3a1f6 Merge branch 'worktree-agent-a75a91d22b62da581'
# Conflicts:
#	benchmarks/measurements/2026-09-08-module-audit.json
#	src/openultrasast/model/audit.py
2026-09-29 18:11:04 +02:00
Marius CiepluchandClaude Opus 5.5 6dfa5daa76 merge(plane): repo-facts memory task (task 5)
Audit registry conflict resolved by keeping every plane row; manifest regenerated from the merged tree.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-29 18:10:51 +02:00
Marius CiepluchandClaude Fable 5.1 4866665e5e feat(plane): ax-backed reconciler, status attribution and doctor (task 4)
Requirements 3.1, 3.2, 3.3, 3.4, 3.5, 2.2, 7.1, 7.3 of ai-service-plane.

- plane/reconciler.py (492 lines, test-counted): a Run's tasks submitted to ax
  in dependency order through the injectable `ax` CLI (apply / get task /
  delete task), serialize labels never overlapping, --workers, state.json with
  pending|running|suspended|done|failed|unfinished, a PID lock per run, done
  tasks skipped on rerun, unfinished tasks holding their dependants, a failed
  task halting the run. Budgets, inputs, output dir, artifact URL and the bound
  Model (annotation openultrasast.io/model; identity and priced parameters) go
  to the task as env in the rendered Task; consumed artifacts travel as files
  of a generated Workspace bound under /workspace. A threaded HTTP receiver
  takes each task's tar delivery, validating run/task and rejecting traversal.
  Outcome comes from the delivered summary.json (done only when every unit
  finished), never from ax's phase alone. status prints the token attribution
  table per task and Model from the summaries' usage fields (n/a, never an
  estimate) and writes attribution.json; doctor runs the four host checks.
- plane/workspaces.py: one Workspace manifest per case pin of a population.
- CLI: ousast plane run|status|doctor|workspaces.
- tests/test_plane_reconciler.py: a fake ax executable drives the DAG;
  tests/test_plane_ax_live.py (marker ax) applies ops/ax/smoke-task.yaml on a
  live cluster and skips unless doctor passes.
- Module audit rows and regenerated manifest.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-29 18:10:09 +02:00
Marius CiepluchandClaude Fable 5.1 0cbdc5d2ac 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
2026-09-29 18:05:08 +02:00
Marius CiepluchandClaude Fable 5.1 2a490eed59 feat(plane): repo-facts memory task (task 5)
plane/tasks/repo_facts.py computes, from source text only and without a
model or git, the product files of a workspace (tests, vendored trees,
node_modules, dist/build, minified bundles and dot-directories excluded via
the layout facts plus the model_sinks.py filter), the functions each file
declares (Python, PHP, JavaScript/TypeScript, Java, Go, Ruby declaration
patterns extended from sink_candidates.py) and, per candidate function, the
call sites in other product files with path, 1-based line and enclosing
function, capped at 40 and sorted (Requirement 5.1). Output is byte-identical
across runs over the same tree (Requirement 5.2).

Under the task contract the unit is one file: a row goes to units.jsonl as
each file finishes and a restart reuses the rows computed for the same
candidate set (Requirement 2.2); facts.json is assembled from the rows and
summary.json is written last, refusing `done` unless every unit finished.
The entrypoint reads OUSAST_WORKSPACE_DIR, OUSAST_OUTPUT_DIR and optional
OUSAST_INPUT_CANDIDATES only (Requirement 2.1) and exits 0 on done, 2 on
failed with the traceback recorded in summary.json.

tests/test_plane_repo_facts.py: a three-file tree with a tests/ file, a
vendored file, a node_modules bundle and a dot-directory; cross-file callers
with line and enclosing function, same-file and declaration lines excluded,
the 40 cap, byte-identical second run, resume that recomputes only the
missing unit, a crash that leaves `failed` with the unit counts and resumes
to `done`, and the declaration patterns per language.

The two new modules are registered as spec-owned in the module audit (their
importer, the runner, lands in task 3) and the audit manifest is regenerated.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-29 17:55:34 +02:00
Marius CiepluchandClaude Fable 5.1 488e63951e merge(plane): manifest schemas and validation (task 1)
Audit registry conflict resolved: plane, plane.budget and plane.manifests rows kept; manifest regenerated from the merged tree.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-29 17:47:45 +02:00
Marius CiepluchandClaude Fable 5.1 c728808316 feat(plane): manifest schemas and validation (task 1)
Add openultrasast.plane.manifests: frozen dataclasses and loaders for ax's
Task, Workspace and Model kinds (ax.io/v1alpha1, ax's fields only) and the
Run kind (openultrasast.io/v1alpha1: tasks, dependsOn, inputs, outputs,
budget, serialize). Every violation raises ManifestError naming the kind,
metadata.name and field path: unknown fields at any depth, wrong apiVersion
or kind, a provider outside google/anthropic unless deepseek is declared via
the openultrasast.io/provider-extension annotation, a Run with a dependency
cycle, an input naming no task, and a Run task naming no loaded Task.
load_manifests reads multi-document YAML files and indexes by kind and name.

PyYAML becomes the one declared core dependency; the two zero-dependency
guards now pin exactly that, and the module audit registers the plane
package under the ai-service-plane spec.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-29 17:44:31 +02:00
Marius CiepluchandClaude Fable 5.1 f460735a87 feat(plane): budget metering (task 2)
MeteredClient wraps a ChatClient, sums the provider's usage rows per call,
prices them from a Model manifest's parameters (cache-hit, input, output per
million), and raises BudgetExhausted before a call once the usd or calls
ceiling is reached. A 401/402 or "Insufficient Balance" failure becomes
AccountError with the provider's message. An unpriced model reports usd None,
never zero, and refuses a usd budget; summary() gives the spend block of a
task's summary.json.

The two plane modules are registered as spec-owned in the module audit (their
consumers land in tasks 3-4) and the audit manifest is regenerated.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-29 17:41:09 +02:00