fix(review): complete cost reporting and dependency inventory

This commit is contained in:
Ouroboros 2026-10-09 16:08:12 +03:00
parent 2779b6f8b8
commit bc480c0431
4 changed files with 21 additions and 10 deletions

View file

@ -2,7 +2,7 @@
AST-derived inventory of compatibility facades, regenerated by `python scripts/regenerate_inventories.py`. Do not edit. A facade row is any runtime module whose top-level `from <population module> import ...` statements carry the `noqa: F401` re-export marker — the codebase's declared "this binding exists for its binding, not for this module's own use" convention (reference FACADE_CONSUMERS method). Leaf domains come from `ouroboros/domains.toml`; a leaf outside the facade's domain is marked ✗ (that edge also appears in the manifest's pinned direction matrix). `tests/test_generated_inventories.py` pins byte-identity, so any re-export surface change must regenerate this file.
- facade modules: **64**; marked re-export bindings: **2330**; cross-domain facade→leaf pairs: **129**
- facade modules: **64**; marked re-export bindings: **2333**; cross-domain facade→leaf pairs: **129**
| facade | domain | bindings | leaves |
|---|---|---:|---|
@ -34,7 +34,7 @@ AST-derived inventory of compatibility facades, regenerated by `python scripts/r
| `ouroboros/review_cycles.py` | D06 | 1 | `ouroboros/outcomes.py` (1 ✗D01) |
| `ouroboros/review_evidence.py` | D06 | 37 | `ouroboros/review_evidence_sections.py` (34)<br>`ouroboros/tool_capabilities.py` (1 ✗D04)<br>`ouroboros/utils.py` (2 ✗D18) |
| `ouroboros/review_execution.py` | D06 | 11 | `ouroboros/review_slot_cancel.py` (5)<br>`ouroboros/review_verdict_extraction.py` (6) |
| `ouroboros/review_state.py` | D06 | 54 | `ouroboros/review_state_custody.py` (9)<br>`ouroboros/review_state_model.py` (1)<br>`ouroboros/review_state_records.py` (44) |
| `ouroboros/review_state.py` | D06 | 57 | `ouroboros/review_state_custody.py` (9)<br>`ouroboros/review_state_model.py` (1)<br>`ouroboros/review_state_records.py` (47) |
| `ouroboros/review_substrate.py` | D06 | 74 | `ouroboros/_outcome_receipts.py` (1 ✗D01)<br>`ouroboros/observability.py` (3 ✗D16)<br>`ouroboros/outcomes.py` (3 ✗D01)<br>`ouroboros/provider_models.py` (1 ✗D02)<br>`ouroboros/review_dispatch.py` (9)<br>`ouroboros/review_execution.py` (15)<br>`ouroboros/review_execution_projection.py` (3)<br>`ouroboros/review_projection.py` (8)<br>`ouroboros/review_records.py` (9)<br>`ouroboros/review_verdict.py` (20)<br>`ouroboros/reviewer_slot_config.py` (1)<br>`ouroboros/task_results.py` (1 ✗D17) |
| `ouroboros/skill_loader.py` | D14 | 3 | `ouroboros/skill_conflicts.py` (3) |
| `ouroboros/skill_review.py` | D14 | 59 | `ouroboros/skill_review_cycles.py` (8)<br>`ouroboros/skill_review_history.py` (5)<br>`ouroboros/skill_review_output.py` (4)<br>`ouroboros/skill_review_packs.py` (8)<br>`ouroboros/skill_review_prompt.py` (7)<br>`ouroboros/skill_review_rebuttals.py` (4)<br>`ouroboros/skill_review_status.py` (8)<br>`ouroboros/tools/review_helpers.py` (8 ✗D06)<br>`ouroboros/triad_review.py` (3 ✗D06)<br>`ouroboros/utils.py` (4 ✗D18) |

View file

@ -718,8 +718,8 @@ def _contributor_execution_receipts(
def _review_evidence_and_cost(actors: list[tuple[str, dict]]) -> tuple[list[dict], dict]:
"""A neutral seat-level evidence/cost report.
A zero or missing seat cost is never presented as proof that the call was
free: every dispatched seat without a reported positive cost is unreported.
Reported zero and positive amounts stay known independently of lifecycle;
missing amounts stay unknown. The report does not establish billing finality.
"""
evidence: list[dict] = []
reported_cost = 0.0
@ -735,7 +735,7 @@ def _review_evidence_and_cost(actors: list[tuple[str, dict]]) -> tuple[list[dict
"response_ref": actor["response_ref"],
})
cost = actor.get("usd")
if isinstance(cost, (int, float)) and not isinstance(cost, bool) and cost > 0:
if isinstance(cost, (int, float)) and not isinstance(cost, bool) and cost >= 0:
reported_cost += float(cost)
reported_slots.append(slot)
else:

View file

@ -1045,14 +1045,25 @@ def test_external_review_cost_report_never_turns_unknown_into_zero():
assert [(surface, actor["slot_id"]) for surface, actor in actors][-1] == ("pool", "scope_slot_1")
assert evidence[0]["prompt_ref"] == {"manifest_ref": "prompt-1"}
assert report["reported_actor_cost_usd"] == 0.03
assert report["unreported_or_unknown_cost_slots"] == ["scope_slot_1"]
assert report["reported_cost_slots"] == ["slot_1", "slot_2", "slot_3", "scope_slot_1"]
assert report["unreported_or_unknown_cost_slots"] == []
assert "not treated as $0" in report["note"]
# An open seat has no cost yet (unknown, never $0); a seat never dispatched is no actor.
pending = _actors([{**triad[0], "status": "pending"}])
assert _review_evidence_and_cost(pending)[1]["unreported_or_unknown_cost_slots"] == ["slot_1"]
# A seat never dispatched remains outside the actor report.
assert _record_actors({"rows": [{"seat_id": "x", "status": "not_dispatched"}]}) == []
@pytest.mark.parametrize("status", ["pending", "responded"])
@pytest.mark.parametrize("cost", [0.01, 0.0, None])
def test_external_review_cost_report_keeps_amount_knowledge_separate_from_lifecycle(status, cost):
actors = _actors([{"slot_id": "slot_1", "model_id": "reviewer", "status": status, "cost_usd": cost}])
evidence, report = _review_evidence_and_cost(actors)
assert evidence[0]["status"] == status
assert report["reported_actor_cost_usd"] == (cost if cost is not None else 0.0)
assert report["reported_cost_slots"] == (["slot_1"] if cost is not None else [])
assert report["unreported_or_unknown_cost_slots"] == ([] if cost is not None else ["slot_1"])
assert "core usage ledger remains the monetary authority" in report["note"]
def test_exit_classification_separates_infra_from_genuine_blocks():
assert _classify_exit({"status": "passed"}) == 0
assert _classify_exit({"status": "blocked", "block_reason": "critical_findings"}) == 1

View file

@ -387,7 +387,7 @@ LEAVES: dict[str, tuple[str, str, frozenset[str]]] = {
"ouroboros/review_projection.py": ("ouroboros/review_substrate.py", "_sub", frozenset({
"DIALOGUE_STATUS_VALUES", "HARDNESS_ADVISORY_VISIBLE", "HARDNESS_HARD_GATE",
"MAX_PROJECTED_ACTOR_FINDINGS", "OUTCOME_TIER_BEST_EFFORT", "OUTCOME_TIER_BLOCKED",
"OUTCOME_TIER_SOLVED", "disclosed_list_projection", "panel_reason",
"OUTCOME_TIER_SOLVED", "TYPED_FAILURE_FACT_KEYS", "disclosed_list_projection", "panel_reason",
"projected_finding_row", "provider_for_model", "redact_projection",
"review_binding_hash", "review_executions_from_actor_usage",
})),