fix(run): S10 del 2 — post-mortem: stopp-artefakt, SDK-isolasjon, raw-JSON-direktiv
Transkript-analyse av den stoppede live-kjøringen (10 kall, 162 250 tokens, $0.331506): konfig-lekkasjen (setting_sources=None laster ALLE filsystem- settings) injiserte operatørens Claude-konfig i hvert kall — ~10-15k uncachede tokens, en påtvunget bekreftelses-preamble som gjorde ren-JSON-svar umulige, og en checker kapret av lekkede instrukser (debatt konvergerte aldri). - persist_stop_artifacts: stopp-event verbatim + usage/kost persisteres ALLTID ved BudgetExceeded (delt usage-shape med fullført-run-stien) - build_call_options: setting_sources=[] (SDK isolation mode, verifisert mot installert 0.2.110-kilde), system_prompt=None → tom system-prompt; detach- bevis via monkeypatchet query - _generation_prompt: krever ONLY the raw JSON object (fence-innpakning ga 4 fullpris parse-retries) 187/187 uten nøkkel · ruff + mypy --strict rene · tre detach-bevis RØDE → grønn Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QdSfQdND84oeq2mbjueLTS
This commit is contained in:
parent
0238507df4
commit
7637c6feae
7 changed files with 253 additions and 25 deletions
|
|
@ -18,6 +18,7 @@ import json
|
|||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from portfolio_optimiser_claude.budget import BudgetExceeded
|
||||
from portfolio_optimiser_claude.contracts import TerminationContract
|
||||
from portfolio_optimiser_claude.loop import RunResult
|
||||
from portfolio_optimiser_claude.okf import ConceptFile
|
||||
|
|
@ -62,6 +63,23 @@ def _dump_json(path: Path, payload: dict[str, Any]) -> None:
|
|||
path.write_text(json.dumps(payload, sort_keys=True, indent=2) + "\n", encoding="utf-8")
|
||||
|
||||
|
||||
def _usage_payload(
|
||||
termination: TerminationContract,
|
||||
tokens_used: int,
|
||||
rounds_used: int,
|
||||
cost_usd: float | None,
|
||||
) -> dict[str, Any]:
|
||||
# ONE usage shape for both outcomes (completed run and budget stop) —
|
||||
# S11 must never branch on which path wrote the artifact.
|
||||
return {
|
||||
"tokens_used": tokens_used,
|
||||
"rounds_used": rounds_used,
|
||||
"max_tokens": termination.max_tokens,
|
||||
"max_rounds": termination.max_rounds,
|
||||
"cost_usd": cost_usd,
|
||||
}
|
||||
|
||||
|
||||
def persist_run_artifacts(
|
||||
out_dir: Path,
|
||||
*,
|
||||
|
|
@ -101,14 +119,34 @@ def persist_run_artifacts(
|
|||
},
|
||||
)
|
||||
_dump_json(paths["provenance"], provenance.model_dump())
|
||||
_dump_json(
|
||||
paths["usage"],
|
||||
{
|
||||
"tokens_used": tokens_used,
|
||||
"rounds_used": rounds_used,
|
||||
"max_tokens": termination.max_tokens,
|
||||
"max_rounds": termination.max_rounds,
|
||||
"cost_usd": cost_usd,
|
||||
},
|
||||
)
|
||||
_dump_json(paths["usage"], _usage_payload(termination, tokens_used, rounds_used, cost_usd))
|
||||
return paths
|
||||
|
||||
|
||||
def persist_stop_artifacts(
|
||||
out_dir: Path,
|
||||
*,
|
||||
stop: BudgetExceeded,
|
||||
termination: TerminationContract,
|
||||
tokens_used: int,
|
||||
rounds_used: int,
|
||||
cost_usd: float | None,
|
||||
) -> dict[str, Path]:
|
||||
"""Persist a budget-stopped run: the stop event verbatim + usage-vs-caps.
|
||||
|
||||
A budget stop is a run outcome, not an absence of one (§8): the S10 live
|
||||
run stopped structurally on the token cap and persisted NOTHING — real
|
||||
spend without a record. The stop event mirrors the raised ``BudgetExceeded``
|
||||
fields exactly; the usage artifact keeps the completed-run shape.
|
||||
"""
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
paths = {
|
||||
"stop": out_dir / "stop.json",
|
||||
"usage": out_dir / "usage.json",
|
||||
}
|
||||
_dump_json(
|
||||
paths["stop"],
|
||||
{"kind": stop.kind, "limit": stop.limit, "observed": stop.observed},
|
||||
)
|
||||
_dump_json(paths["usage"], _usage_payload(termination, tokens_used, rounds_used, cost_usd))
|
||||
return paths
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue