Pārlūkot izejas kodu

docs: close benchmark reporting follow-ups

Problem: Benchmark reporting follow-up todos remained in progress after their implementation, integration fixes, and repeated specification/code-quality reviews passed.

Risk: The report layout is now a timestamped bundle directory rather than flat sibling files; final user documentation must describe the new paths clearly.
zhenyu.hu 2 nedēļas atpakaļ
vecāks
revīzija
efc37872ce

+ 21 - 21
docs/plans/todo-52-agent-benchmark-runner.md

@@ -17,12 +17,12 @@
 - Create: `tests/test_benchmark_config.py`
 - Modify: `tests/test_tool_invocation_comparison.py`
 
-- [ ] Write failing tests for strict schema version, URL validation, known case/mode IDs, positive runs, and rejection of secret fields.
-- [ ] Verify RED with `uv run pytest tests/test_benchmark_config.py -q`.
-- [ ] Implement strict Pydantic models `BenchmarkConfig`, `BenchmarkTarget`, `BenchmarkCase`, `BenchmarkExpectation`, and immutable built-in case catalog.
-- [ ] Implement `build_benchmark_request(case, mode, model)` using the existing `DebugRunRequest`, identical params, and built-in enabled tools.
-- [ ] Expose deterministic mock rounds from the production case catalog and refactor the existing comparison test to reuse the catalog instead of duplicating prompts/expectations.
-- [ ] Run config and comparison tests, then commit with `feat: add benchmark case catalog`.
+- [x] Write failing tests for strict schema version, URL validation, known case/mode IDs, positive runs, and rejection of secret fields.
+- [x] Verify RED with `uv run pytest tests/test_benchmark_config.py -q`.
+- [x] Implement strict Pydantic models `BenchmarkConfig`, `BenchmarkTarget`, `BenchmarkCase`, `BenchmarkExpectation`, and immutable built-in case catalog.
+- [x] Implement `build_benchmark_request(case, mode, model)` using the existing `DebugRunRequest`, identical params, and built-in enabled tools.
+- [x] Expose deterministic mock rounds from the production case catalog and refactor the existing comparison test to reuse the catalog instead of duplicating prompts/expectations.
+- [x] Run config and comparison tests, then commit with `feat: add benchmark case catalog`.
 
 ### Task 2: Timing wrapper and isolated benchmark runner
 
@@ -30,13 +30,13 @@
 - Modify: `src/agent_lab/application/benchmark.py`
 - Create: `tests/test_benchmark_runner.py`
 
-- [ ] Write failing tests for provider TTFT versus visible TTFT, per-call elapsed/usage, persisted wall time, detected events/sources, tool/fallback counts, semantic failures, partial-failure continuation, and temporary-database isolation.
-- [ ] Verify RED with `uv run pytest tests/test_benchmark_runner.py -q`.
-- [ ] Implement `TimingChatClient` around the existing stream protocol, recording first item, first message delta, usage, elapsed, and fallback classification.
-- [ ] Implement deterministic `MockBenchmarkChatClient` that never constructs HTTP transport and emits mode-correct streams for the six cases.
-- [ ] Implement `BenchmarkRunner.run()` over case → mode → iteration, creating/closing one runtime, chat client, and temporary SQLite store per run.
-- [ ] Implement semantic evaluation from output, audit, and usage ledgers and return ordered `BenchmarkRunResult` records without stopping after an individual failure.
-- [ ] Run runner/config/comparison tests, then commit with `feat: run isolated agent benchmarks`.
+- [x] Write failing tests for provider TTFT versus visible TTFT, per-call elapsed/usage, persisted wall time, detected events/sources, tool/fallback counts, semantic failures, partial-failure continuation, and temporary-database isolation.
+- [x] Verify RED with `uv run pytest tests/test_benchmark_runner.py -q`.
+- [x] Implement `TimingChatClient` around the existing stream protocol, recording first item, first message delta, usage, elapsed, and fallback classification.
+- [x] Implement deterministic `MockBenchmarkChatClient` that never constructs HTTP transport and emits mode-correct streams for the six cases.
+- [x] Implement `BenchmarkRunner.run()` over case → mode → iteration, creating/closing one runtime, chat client, and temporary SQLite store per run.
+- [x] Implement semantic evaluation from output, audit, and usage ledgers and return ordered `BenchmarkRunResult` records without stopping after an individual failure.
+- [x] Run runner/config/comparison tests, then commit with `feat: run isolated agent benchmarks`.
 
 ### Task 3: Aggregation, reporting, and CLI
 
@@ -47,14 +47,14 @@
 - Create: `tests/test_benchmark_cli.py`
 - Modify: `pyproject.toml`
 
-- [ ] Write failing tests for linear-interpolated p50/p95, failed-sample exclusion, low-sample warnings, redaction, JSON/Markdown consistency, atomic writes, CLI overrides, mock/live API-key requirements, exit codes 0/1/2, and continued report writing after run failures.
-- [ ] Verify RED with `uv run pytest tests/test_benchmark_reporting.py tests/test_benchmark_cli.py -q`.
-- [ ] Implement aggregation into one typed `BenchmarkReport` model shared by JSON and Markdown.
-- [ ] Implement centralized redaction and 2 KiB error truncation before any rendered output.
-- [ ] Implement atomic matching `.json`/`.md` writes under the configured output directory.
-- [ ] Implement argparse with `--config`, `--base-url`, `--model`, repeatable `--case`/`--mode`, `--runs`, `--output-dir`, and `--mock`; apply `CLI > JSON` and environment-only API key.
-- [ ] Register `agent-lab-benchmark = agent_lab.presentation.benchmark_cli:main` and verify `--help`.
-- [ ] Run reporting/CLI/runner tests, then commit with `feat: add benchmark reports and cli`.
+- [x] Write failing tests for linear-interpolated p50/p95, failed-sample exclusion, low-sample warnings, redaction, JSON/Markdown consistency, atomic writes, CLI overrides, mock/live API-key requirements, exit codes 0/1/2, and continued report writing after run failures.
+- [x] Verify RED with `uv run pytest tests/test_benchmark_reporting.py tests/test_benchmark_cli.py -q`.
+- [x] Implement aggregation into one typed `BenchmarkReport` model shared by JSON and Markdown.
+- [x] Implement centralized redaction and 2 KiB error truncation before any rendered output.
+- [x] Implement one atomically published report bundle containing matching `report.json` and `report.md` files.
+- [x] Implement argparse with `--config`, `--base-url`, `--model`, repeatable `--case`/`--mode`, `--runs`, `--output-dir`, and `--mock`; apply `CLI > JSON` and environment-only API key.
+- [x] Register `agent-lab-benchmark = agent_lab.presentation.benchmark_cli:main` and verify `--help`.
+- [x] Run reporting/CLI/runner tests, then commit with `feat: add benchmark reports and cli`.
 
 ### Task 4: Examples, documentation, and final verification
 

+ 1 - 2
docs/plans/todo-52.10-benchmark-bundle-cli-contract.md

@@ -1,6 +1,6 @@
 # Todo 52.10 Benchmark Bundle CLI Contract Plan
 
-**Status:** in_progress
+**Status:** done
 
 ## Goal
 
@@ -27,4 +27,3 @@ The CLI still returns the report paths supplied by `write_benchmark_report()`, b
 - `uv run pytest tests/test_benchmark_reporting.py tests/test_benchmark_cli.py -q`
 - `uv run pytest`
 - `git diff --check`
-

+ 1 - 2
docs/plans/todo-52.11-bundle-interrupt-and-path-safety.md

@@ -1,6 +1,6 @@
 # Todo 52.11 Bundle Interrupt and Path Safety Plan
 
-**Status:** in_progress
+**Status:** done
 
 ## Goal
 
@@ -30,4 +30,3 @@ Close the post-symlink interruption window and constrain report bundle names to
 - `uv run pytest tests/test_benchmark_reporting.py tests/test_benchmark_cli.py -q`
 - `uv run pytest`
 - `git diff --check`
-

+ 1 - 1
docs/plans/todo-52.6-benchmark-report-auditability.md

@@ -1,6 +1,6 @@
 # Todo 52.6 Benchmark Report Auditability Plan
 
-**Status:** in_progress
+**Status:** done
 
 ## Goal
 

+ 1 - 1
docs/plans/todo-52.7-benchmark-output-reservation-and-cardinality.md

@@ -1,6 +1,6 @@
 # Todo 52.7 Benchmark Output Reservation and Cardinality Plan
 
-**Status:** in_progress
+**Status:** done
 
 ## Goal
 

+ 1 - 1
docs/plans/todo-52.8-benchmark-no-overwrite-publication.md

@@ -1,6 +1,6 @@
 # Todo 52.8 Benchmark No-Overwrite Publication Plan
 
-**Status:** in_progress
+**Status:** done
 
 ## Goal
 

+ 1 - 2
docs/plans/todo-52.9-atomic-report-bundles-and-audit-parity.md

@@ -1,6 +1,6 @@
 # Todo 52.9 Atomic Report Bundles and Audit Parity Plan
 
-**Status:** in_progress
+**Status:** done
 
 ## Goal
 
@@ -34,4 +34,3 @@ Publishing flat JSON and Markdown paths requires two independent filesystem oper
 - concurrent process/thread bundle publication and collision stress tests
 - `uv run pytest`
 - `git diff --check`
-

+ 6 - 6
docs/plans/todos.md

@@ -106,9 +106,9 @@
 | 52.3 | done | `docs/plans/todo-52.3-benchmark-case-mode-single-source.md` | Make benchmark case IDs and invocation modes single-source enums shared by config, catalog, runner, and tests. | Adding or removing an enum member cannot leave config literals, exported choices, and catalog keys silently inconsistent. |
 | 52.4 | done | `docs/plans/todo-52.4-benchmark-visible-ttft-and-call-counts.md` | Measure the first non-whitespace visible content and enforce each case's expected ChatAgent/fallback call counts. | Blank deltas cannot reduce visible TTFT; extra or missing model/fallback calls produce semantic failures even when timing and ledger agree. |
 | 52.5 | done | `docs/plans/todo-52.5-benchmark-ledger-event-identity.md` | Cross-check detected, batch-result, and tool-metric event identities and preserve attempted model counts on failed runs. | A successful result from the wrong event cannot pass; failed streams still report started ChatAgent/fallback attempts from timing records. |
-| 52.6 | in_progress | `docs/plans/todo-52.6-benchmark-report-auditability.md` | Complete report latency coverage, concurrent pair reservation, runner-level error auditability, and byte-bounded errors. | Reports aggregate model/tool latency, concurrent writers cannot mix pairs, catastrophic runner errors appear in report totals/details, zero samples warn, and errors stay within 2 KiB UTF-8. |
-| 52.7 | in_progress | `docs/plans/todo-52.7-benchmark-output-reservation-and-cardinality.md` | Prevent report overwrite/stale reservations, suppress argparse value echoes, and reject missing or extra benchmark results. | Final paths are atomically reserved without lock files, malformed CLI values are not echoed, and actual run cardinality must equal cases × modes × iterations. |
-| 52.8 | in_progress | `docs/plans/todo-52.8-benchmark-no-overwrite-publication.md` | Publish completed report files with atomic no-overwrite hard links instead of check-then-replace ownership logic. | A destination created at any point wins without being overwritten; the writer retries another suffix or fails cleanly with no mixed pair. |
-| 52.9 | in_progress | `docs/plans/todo-52.9-atomic-report-bundles-and-audit-parity.md` | Replace two-path report publication with one atomic bundle boundary and close report/CLI audit parity gaps. | Concurrent writers publish complete bundles without rollback deletion races; Markdown preserves all failure facts and output errors map to exit code 2. |
-| 52.10 | in_progress | `docs/plans/todo-52.10-benchmark-bundle-cli-contract.md` | Align CLI report discovery tests with the atomically published bundle layout. | CLI tests consume the reported bundle paths without restoring root-level compatibility copies or weakening redaction, exit-code, and cardinality checks. |
-| 52.11 | in_progress | `docs/plans/todo-52.11-bundle-interrupt-and-path-safety.md` | Preserve complete bundles across post-symlink interrupts and reject unsafe report timestamp path components. | Interruptions cannot leave dangling public bundles; explicit timestamps stay inside output_dir; fsync tests verify both files and both directories. |
+| 52.6 | done | `docs/plans/todo-52.6-benchmark-report-auditability.md` | Complete report latency coverage, concurrent pair reservation, runner-level error auditability, and byte-bounded errors. | Reports aggregate model/tool latency, concurrent writers cannot mix pairs, catastrophic runner errors appear in report totals/details, zero samples warn, and errors stay within 2 KiB UTF-8. |
+| 52.7 | done | `docs/plans/todo-52.7-benchmark-output-reservation-and-cardinality.md` | Prevent report overwrite/stale reservations, suppress argparse value echoes, and reject missing or extra benchmark results. | Final paths are atomically reserved without lock files, malformed CLI values are not echoed, and actual run cardinality must equal cases × modes × iterations. |
+| 52.8 | done | `docs/plans/todo-52.8-benchmark-no-overwrite-publication.md` | Publish completed report files with atomic no-overwrite hard links instead of check-then-replace ownership logic. | A destination created at any point wins without being overwritten; the writer retries another suffix or fails cleanly with no mixed pair. |
+| 52.9 | done | `docs/plans/todo-52.9-atomic-report-bundles-and-audit-parity.md` | Replace two-path report publication with one atomic bundle boundary and close report/CLI audit parity gaps. | Concurrent writers publish complete bundles without rollback deletion races; Markdown preserves all failure facts and output errors map to exit code 2. |
+| 52.10 | done | `docs/plans/todo-52.10-benchmark-bundle-cli-contract.md` | Align CLI report discovery tests with the atomically published bundle layout. | CLI tests consume the reported bundle paths without restoring root-level compatibility copies or weakening redaction, exit-code, and cardinality checks. |
+| 52.11 | done | `docs/plans/todo-52.11-bundle-interrupt-and-path-safety.md` | Preserve complete bundles across post-symlink interrupts and reject unsafe report timestamp path components. | Interruptions cannot leave dangling public bundles; explicit timestamps stay inside output_dir; fsync tests verify both files and both directories. |