feat(runtime): enforce governed mutation boundaries

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a06ba0-10aa-7ea0-b20a-4f3fac39efe9
This commit is contained in:
tegwick 2026-09-04 11:25:07 +02:00
parent e3c6124e22
commit 20e6f381f6
28 changed files with 1068 additions and 154 deletions

View file

@ -2,10 +2,10 @@
Flow: lock target repo → resolve tool profile / budget from instance
manifest → snapshot HEAD → persona bundle → prompt → agentic session →
verify a new commit exists → kaizen metrics + hub progress event
(+ task close). The run *fails* if the session pushed anywhere or left
the repo dirty in a way it should not — the worker never pushes;
publishing is a separate, explicitly-granted lane.
validate an explicit repository grant when present → metrics + hub progress
event (+ task close). Granted runs use durable external metrics so repository
acceptance remains clean. The worker never pushes; publishing is a separate,
explicitly-granted lane.
"""
from __future__ import annotations
@ -24,6 +24,7 @@ from rein_aharness.profiles import UnknownToolProfileError, get_profile
from rein_aharness.repository_transaction import (
DirtyRepositoryError,
GitRepositoryError,
RepositoryAcceptanceError,
RepositoryBusyError,
RepositoryTransaction,
RepositoryTransactionError,
@ -116,11 +117,11 @@ def run_task(
budget_tokens_override: int | None = None,
transaction: RepositoryTransaction | None = None,
) -> RunResult:
if spec.repository_grant is not None:
if spec.repository_grant is not None and not write_metrics:
return _refused_run(
reason=(
"refused: repository_grant enforcement is not enabled; "
"no adapter was dispatched"
"refused: repository_grant runs require durable external metrics; "
"--no-metrics is incompatible"
),
model=model,
)
@ -255,11 +256,62 @@ def _execute_locked_task(
head_after = _git(spec.target_repo, "rev-parse", "HEAD")
committed = head_after != head_before
if session_ok and spec.repository_grant is not None:
try:
tx.validate_acceptance(spec.repository_grant.acceptance_policy())
except RepositoryAcceptanceError as exc:
session_ok = False
reason = str(exc)
ok = session_ok and committed
if session_ok and not committed:
if session_ok and not committed and spec.repository_grant is None:
reason = "session completed without committing"
tokens_spent = budget_tracker.spent if budget_tracker is not None else None
transaction_evidence = tx.evidence()
if spec.repository_grant is not None:
transaction_evidence["repository_grant"] = spec.repository_grant.evidence()
metric_metadata = {
"task_title": spec.title,
"tool_profile": profile.name,
"labels": list(spec.labels),
"completion_event_type": spec.completion_event_type,
}
if spec.repository_grant is not None:
metric_metadata["repository_grant_id"] = spec.repository_grant.grant_id
if write_metrics:
try:
recorder = (
metrics.record_external_execution
if spec.repository_grant is not None
else metrics.record_execution
)
recorder(
spec.target_repo,
spec.agent,
success=ok,
execution_time_s=execution_time_s,
tokens=tokens_spent,
committed=committed,
head_after=head_after,
reason=reason or None,
metadata=metric_metadata,
session_id=tx.transaction_id,
)
if spec.repository_grant is not None:
transaction_evidence["metrics"] = {
"storage": "external",
"session_id": tx.transaction_id,
"projection_ready": True,
}
except OSError as exc:
if spec.repository_grant is not None:
ok = False
reason = (
"required external metrics persistence failed "
f"({type(exc).__name__})"
)
result = RunResult(
ok=ok,
@ -275,30 +327,9 @@ def _execute_locked_task(
tokens_spent=tokens_spent,
execution_time_s=execution_time_s,
tool_events=collected_events,
transaction=tx.evidence(),
transaction=transaction_evidence,
)
if write_metrics:
try:
metrics.record_execution(
spec.target_repo,
spec.agent,
success=ok,
execution_time_s=execution_time_s,
tokens=tokens_spent,
committed=committed,
head_after=head_after,
reason=reason or None,
metadata={
"task_title": spec.title,
"tool_profile": profile.name,
"labels": list(spec.labels),
"completion_event_type": spec.completion_event_type,
},
)
except OSError:
pass # metrics must not block run completion reporting
if report_to_hub:
detail = {
"repo": spec.target_repo.name,
@ -314,6 +345,7 @@ def _execute_locked_task(
"budget_tokens": budget_tokens,
"tokens_spent": tokens_spent,
"execution_time_s": round(execution_time_s, 3),
"repository_transaction": transaction_evidence,
}
hub.post_progress_event(
summary=f"executor run: {spec.title} ({'ok' if ok else 'failed'})",