Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions loopx/capabilities/benchmark_toolkit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,27 @@ only public progress; they must not disclose verifier output or hidden evaluatio
The runner remains responsible for invoking the next agent segment, measuring the
shared total budget, preserving containment, and collecting evidence.

Before accepting each segment's adapter receipt, bind it to a runner-generated
nonce and the observed segment window:

```bash
loopx benchmark segment-receipt \
--expected-segment-nonce "$SEGMENT_NONCE" \
--receipt-segment-nonce "$RECEIPT_NONCE" \
--segment-started-at "$SEGMENT_STARTED_AT" \
--receipt-written-at "$RECEIPT_WRITTEN_AT" \
--segment-ended-at "$SEGMENT_ENDED_AT" \
--prior-receipt-nonce "$PRIOR_RECEIPT_NONCE" \
--require-qualified --format json
```

The runner must remove or rotate fixed-path transient artifacts before launch,
pass the fresh nonce into the agent process, and retain prior segment nonces for
replay detection. Missing, wrong-segment, outside-window, and replayed receipts
fail closed; they must not be promoted into terminal evidence. The reducer records
none of the nonces, timestamps, receipt content, paths, or run identity and grants
no process, retry, score, or verifier authority.

## Source revision admission

A long-running campaign can keep launching from an old installed checkout after
Expand Down
10 changes: 10 additions & 0 deletions loopx/capabilities/benchmark_toolkit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,12 @@
BenchmarkRuntimeTransition,
build_benchmark_runtime_observation,
)
from .segment_receipt import (
BENCHMARK_SEGMENT_RECEIPT_SCHEMA_VERSION,
BenchmarkSegmentReceiptClassification,
BenchmarkSegmentReceiptTransition,
build_benchmark_segment_receipt,
)
from .source_revision_fence import (
BENCHMARK_SOURCE_REVISION_FENCE_SCHEMA_VERSION,
BenchmarkSourceRevisionFence,
Expand Down Expand Up @@ -243,6 +249,7 @@
"BENCHMARK_RUNTIME_CONTINUITY_SCHEMA_VERSION",
"BENCHMARK_RUNTIME_INTEGRITY_ATTESTATION_SCHEMA_VERSION",
"BENCHMARK_RUNTIME_OBSERVATION_SCHEMA_VERSION",
"BENCHMARK_SEGMENT_RECEIPT_SCHEMA_VERSION",
"BENCHMARK_SOURCE_REVISION_FENCE_SCHEMA_VERSION",
"BENCHMARK_STUDY_DASHBOARD_SCHEMA_VERSION",
"BENCHMARK_STUDY_MANIFEST_SCHEMA_VERSION",
Expand Down Expand Up @@ -271,6 +278,8 @@
"BenchmarkRuntimeContinuityClassification",
"BenchmarkRuntimeContinuityTransition",
"BenchmarkRuntimeTransition",
"BenchmarkSegmentReceiptClassification",
"BenchmarkSegmentReceiptTransition",
"BenchmarkSourceRevisionFence",
"BenchmarkSourceRevisionFenceError",
"DockerContainerBinding",
Expand Down Expand Up @@ -311,6 +320,7 @@
"build_benchmark_integrity_qualification",
"build_benchmark_runtime_continuity",
"build_benchmark_runtime_observation",
"build_benchmark_segment_receipt",
"build_benchmark_study_dashboard",
"build_benchmark_treatment_continuation_receipt",
"build_benchmark_upload_envelope",
Expand Down
1 change: 1 addition & 0 deletions loopx/capabilities/benchmark_toolkit/catalog_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@
"upsert_preregistered_or_running_row_when_a_run_starts",
"classify_exact_runtime_observation_during_active_monitor_cycles",
"require_runtime_continuity_before_terminal_closeout_write",
"qualify_each_agent_segment_receipt_before_using_its_result",
"adjudicate_restricted_access_suspicion_after_solver_and_score_terminal",
"upsert_terminal_score_countability_effort_and_insight_status",
"release_case_slot_after_terminal_or_runner_invalid_transition",
Expand Down
119 changes: 119 additions & 0 deletions loopx/capabilities/benchmark_toolkit/segment_receipt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
"""Fail-closed identity and freshness checks for benchmark agent segments."""

from __future__ import annotations

import re
from collections.abc import Sequence
from datetime import datetime
from enum import Enum
from typing import Any

BENCHMARK_SEGMENT_RECEIPT_SCHEMA_VERSION = "benchmark_segment_receipt_v0"
_NONCE = re.compile(r"[A-Za-z0-9][A-Za-z0-9_.:@+-]{15,127}\Z")


class BenchmarkSegmentReceiptClassification(str, Enum):
"""Why one agent-segment receipt is or is not attributable."""

INPUT_INVALID = "segment_receipt_input_invalid"
QUALIFIED = "qualified"
IDENTITY_MISMATCH = "segment_identity_mismatch"
OUTSIDE_SEGMENT_WINDOW = "receipt_outside_segment_window"
REPLAYED = "segment_receipt_replayed"


class BenchmarkSegmentReceiptTransition(str, Enum):
"""Runner-owned transition selected by the receipt gate."""

REPAIR_RECEIPT_EVIDENCE = "repair_segment_receipt_evidence"
ACCEPT_SEGMENT = "accept_segment_receipt"
DISCARD_AND_RERUN = "discard_and_rerun_segment"


def _nonce(value: Any, *, field: str) -> str:
text = str(value or "").strip()
if not _NONCE.fullmatch(text):
raise ValueError(f"{field} must be a compact opaque nonce")
return text


def _timestamp(value: Any, *, field: str) -> datetime:
text = str(value or "").strip().replace("Z", "+00:00")
try:
parsed = datetime.fromisoformat(text)
except ValueError as exc:
raise ValueError(f"{field} must be an ISO-8601 timestamp") from exc
if parsed.tzinfo is None:
raise ValueError(f"{field} must include a timezone")
return parsed


def build_benchmark_segment_receipt(
*,
expected_segment_nonce: str,
receipt_segment_nonce: str,
segment_started_at: str,
receipt_written_at: str,
segment_ended_at: str,
prior_receipt_nonces: Sequence[str] = (),
) -> dict[str, Any]:
"""Qualify one receipt without retaining its identity or timestamps.

The runner owns nonce generation, file cleanup, process execution, timestamp
observation, and any retry. This reducer only rejects a receipt copied from a
different segment, written outside the observed segment window, or replayed
from an earlier segment.
"""

expected = _nonce(expected_segment_nonce, field="expected_segment_nonce")
observed = _nonce(receipt_segment_nonce, field="receipt_segment_nonce")
started = _timestamp(segment_started_at, field="segment_started_at")
written = _timestamp(receipt_written_at, field="receipt_written_at")
ended = _timestamp(segment_ended_at, field="segment_ended_at")
prior = [
_nonce(value, field="prior_receipt_nonce")
for value in prior_receipt_nonces
]
if ended < started:
raise ValueError("segment_ended_at cannot precede segment_started_at")

identity_matches = expected == observed
within_window = started <= written <= ended
receipt_unique = observed not in prior

if not identity_matches:
classification = BenchmarkSegmentReceiptClassification.IDENTITY_MISMATCH
elif not receipt_unique:
classification = BenchmarkSegmentReceiptClassification.REPLAYED
elif not within_window:
classification = (
BenchmarkSegmentReceiptClassification.OUTSIDE_SEGMENT_WINDOW
)
else:
classification = BenchmarkSegmentReceiptClassification.QUALIFIED

qualified = classification is BenchmarkSegmentReceiptClassification.QUALIFIED
transition = (
BenchmarkSegmentReceiptTransition.ACCEPT_SEGMENT
if qualified
else BenchmarkSegmentReceiptTransition.DISCARD_AND_RERUN
)
return {
"schema_version": BENCHMARK_SEGMENT_RECEIPT_SCHEMA_VERSION,
"classification": classification.value,
"qualified": qualified,
"segment_result_usable": qualified,
"segment_identity_matches": identity_matches,
"receipt_within_segment_window": within_window,
"receipt_unique": receipt_unique,
"prior_receipt_count": len(prior),
"recommended_transition": transition.value,
"public_boundary": {
"nonce_recorded": False,
"timestamps_recorded": False,
"receipt_content_recorded": False,
"run_identity_recorded": False,
"path_recorded": False,
},
"write_performed": False,
}
69 changes: 69 additions & 0 deletions loopx/cli_commands/benchmark_boundary.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
BENCHMARK_INTEGRITY_QUALIFICATION_SCHEMA_VERSION,
BENCHMARK_MODEL_ROUTE_RECEIPT_SCHEMA_VERSION,
BENCHMARK_RUNTIME_CONTINUITY_SCHEMA_VERSION,
BENCHMARK_SEGMENT_RECEIPT_SCHEMA_VERSION,
BENCHMARK_SOURCE_REVISION_FENCE_SCHEMA_VERSION,
BENCHMARK_TREATMENT_CONTINUATION_RECEIPT_SCHEMA_VERSION,
TRAE_BENCHMARK_EVIDENCE_SCHEMA_VERSION,
Expand All @@ -22,12 +23,15 @@
BenchmarkRunnerOwnerState,
BenchmarkRuntimeContinuityClassification,
BenchmarkRuntimeContinuityTransition,
BenchmarkSegmentReceiptClassification,
BenchmarkSegmentReceiptTransition,
BenchmarkSourceRevisionFenceError,
build_benchmark_candidate_source_boundary,
build_benchmark_four_arm_contract_from_spec,
build_benchmark_integrity_qualification,
build_benchmark_runtime_continuity,
build_benchmark_runtime_observation,
build_benchmark_segment_receipt,
build_benchmark_treatment_continuation_receipt,
capture_traex_benchmark_evidence,
compact_benchmark_four_arm_contract,
Expand All @@ -50,6 +54,7 @@
"four-arm-contract",
"runtime-continuity",
"runtime-observation",
"segment-receipt",
"source-revision-fence",
"traex-evidence",
"treatment-continuation-receipt",
Expand Down Expand Up @@ -158,6 +163,16 @@ def _render_runtime_continuity(payload: dict[str, object]) -> str:
)


def _render_segment_receipt(payload: dict[str, object]) -> str:
return (
"# Benchmark Segment Receipt\n\n"
f"- Classification: `{payload.get('classification')}`\n"
f"- Qualified: `{payload.get('qualified')}`\n"
f"- Segment result usable: `{payload.get('segment_result_usable')}`\n"
f"- Recommended transition: `{payload.get('recommended_transition')}`\n"
)


def _render_treatment_continuation(payload: dict[str, object]) -> str:
return (
"# Benchmark Treatment Continuation Receipt\n\n"
Expand Down Expand Up @@ -267,6 +282,21 @@ def register_benchmark_boundary_commands(
)
continuity_parser.add_argument("--require-qualified", action="store_true")

segment_parser = benchmark_subparsers.add_parser(
"segment-receipt",
help="Reject stale, replayed, or wrong-segment benchmark receipts.",
)
add_subcommand_format(segment_parser)
segment_parser.add_argument("--expected-segment-nonce", required=True)
segment_parser.add_argument("--receipt-segment-nonce", required=True)
segment_parser.add_argument("--segment-started-at", required=True)
segment_parser.add_argument("--receipt-written-at", required=True)
segment_parser.add_argument("--segment-ended-at", required=True)
segment_parser.add_argument(
"--prior-receipt-nonce", action="append", default=[]
)
segment_parser.add_argument("--require-qualified", action="store_true")

integrity_parser = benchmark_subparsers.add_parser(
"integrity-qualification",
help="Reduce private trajectory and runner attestations to a compact receipt.",
Expand Down Expand Up @@ -400,6 +430,30 @@ def _invalid_runtime_continuity_input() -> dict[str, object]:
}


def _invalid_segment_receipt_input() -> dict[str, object]:
return {
"schema_version": BENCHMARK_SEGMENT_RECEIPT_SCHEMA_VERSION,
"classification": BenchmarkSegmentReceiptClassification.INPUT_INVALID.value,
"qualified": False,
"segment_result_usable": False,
"segment_identity_matches": False,
"receipt_within_segment_window": False,
"receipt_unique": False,
"prior_receipt_count": 0,
"recommended_transition": (
BenchmarkSegmentReceiptTransition.REPAIR_RECEIPT_EVIDENCE.value
),
"public_boundary": {
"nonce_recorded": False,
"timestamps_recorded": False,
"receipt_content_recorded": False,
"run_identity_recorded": False,
"path_recorded": False,
},
"write_performed": False,
}


def _invalid_treatment_continuation_input() -> dict[str, object]:
return {
"schema_version": BENCHMARK_TREATMENT_CONTINUATION_RECEIPT_SCHEMA_VERSION,
Expand Down Expand Up @@ -543,6 +597,21 @@ def handle_benchmark_boundary_command(
print_payload(payload, output_format(args), _render_runtime_continuity)
return 1 if args.require_qualified and not payload.get("qualified") else 0

if args.benchmark_command == "segment-receipt":
try:
payload = build_benchmark_segment_receipt(
expected_segment_nonce=args.expected_segment_nonce,
receipt_segment_nonce=args.receipt_segment_nonce,
segment_started_at=args.segment_started_at,
receipt_written_at=args.receipt_written_at,
segment_ended_at=args.segment_ended_at,
prior_receipt_nonces=args.prior_receipt_nonce,
)
except (TypeError, ValueError):
payload = _invalid_segment_receipt_input()
print_payload(payload, output_format(args), _render_segment_receipt)
return 1 if args.require_qualified and not payload.get("qualified") else 0

if args.benchmark_command == "treatment-continuation-receipt":
try:
observation = _read_json_object(
Expand Down
20 changes: 20 additions & 0 deletions skills/loopx-benchmark/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,26 @@ the task's normal tools instead of imposing this workflow.
The fence fails closed unless the clean pinned source matches the observed
reference head.

For runners that invoke multiple agent segments, also rotate fixed-path
transient artifacts before every segment, mint a fresh opaque nonce, and
qualify the returned receipt against that nonce and the observed segment
time window before accepting its result:

```bash
loopx benchmark segment-receipt \
--expected-segment-nonce <RUNNER_NONCE> \
--receipt-segment-nonce <RECEIPT_NONCE> \
--segment-started-at <ISO_TIME> \
--receipt-written-at <ISO_TIME> \
--segment-ended-at <ISO_TIME> \
--prior-receipt-nonce <PRIOR_NONCE> \
--require-qualified --format json
```

Missing, wrong-segment, outside-window, or replayed receipts fail closed.
The runner still owns cleanup, nonce generation, process execution, retries,
and the decision to launch another segment.

3. **Preview, then preregister or mark the run row when it starts.**
```bash
loopx benchmark experiment-board-upsert --goal-id <GOAL_ID> \
Expand Down
1 change: 1 addition & 0 deletions skills/loopx-self-repair/references/repair-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ teaches a reusable control-plane lesson.
| `benchmark_launcher_sandbox_mode_drift` | A host-Codex benchmark exits before case materialization with a sandbox-probe failure even though the same runner and credential worked in a prior batch. | launcher dry-run, requested/effective host Codex sandbox mode, preflight category, runner source fingerprint. | The public launcher did not forward the sandbox mode used by the validated runner profile, so the runner fell back to an unsupported host sandbox probe. | Expose and forward the host Codex sandbox setting without weakening its default; make dedicated runners opt into any broader mode explicitly and record only the mode label in public prerequisites. |
| `user_reward_lesson_projection_gap` | The user explicitly corrects a high-value product route, priority, or operating rule, but later turns follow an older todo/recommended_action as if the correction never happened. A recurring form is an owner granting a broad operating permission, then a later agent asks for the same approval because the earlier decision was stored as chat prose or a completed `user_action`. | recent user correction, completed user decisions, latest quota/status, active-state `Next Action`, open todos, recent run history, interaction pattern catalog, and projected standing decision authority. | The correction stayed in chat/model belief instead of becoming a durable human-reward/operating-lesson constraint, successor todo, or state projection; or a standing permission was encoded in a non-authoritative reminder lane that quota intentionally ignores. | Promote route and priority corrections into active goal state and runnable todos. When the correction is a reusable product policy, encode it in the capability-owned typed contract and keep Todo or monitor prose from becoming a competing authority. For recurring authority, author a completed broad `user_gate` with explicit approve/reject/cancel, exact decision scope, and agent/global ownership; make privileged agent todos declare the matching required scope; project the latest typed receipt before quota consistency; retain it through archive compaction. Never infer authority from chat or `user_action` prose. Then refresh state so `quota should-run` selects the corrected rule, and validate the hot path before continuing. |
| `reward_feedback_leak` | Later benchmark rounds receive verifier tail, pass/fail, or reward details that one arm should not see. | benchmark prompt/continuation logs, compact ledger, verifier wrapper. | Evaluation loop leaked reward signal. | Record per-round reward privately for metrics, but do not feed it to agents unless the experiment explicitly studies feedback. |
| `benchmark_segment_receipt_replay` | A later outer-loop segment terminates immediately or reports the same timeout/result as an earlier segment, while a fixed receipt path survives across invocations. Aggregate completion may look valid even though no fresh continuation ran. | Segment-scoped logging directories, runner-generated segment nonce, receipt nonce and write time, prior receipt nonces, outer-loop history, and total-budget allocation. | The adapter reused one fixed transient receipt without clearing it or binding it to the current segment, so a stale receipt was accepted after the new process failed before writing evidence. | Before each segment, rotate fixed transient artifacts and mint a fresh opaque nonce. Pass it to the solver, require the receipt to echo it with a write timestamp inside the observed segment window, and reject any prior nonce. Keep this fail-closed gate separate from launch-to-closeout runtime continuity, require paper- or protocol-aligned total budgets, and cover true second-segment execution plus replay rejection with a focused smoke. |
| `candidate_preflight_negative_evidence_gap` | Issue-fix candidate screening accepts empty PR evidence and starts implementation even though the caller used a capped aggregate index or did not prove a direct all-state search. | Candidate preflight input, issue-specific numeric and semantic query receipts, truncation/completeness metadata, current issue body and comments. | Capability admission treated key presence or a naked empty list as proof that prior work was absent. | Keep provider queries outside the LoopX core, but require issue-specific complete, non-truncated receipts before a negative result can yield `proceed`; aggregate indexes remain candidate generators only. Do not add capability fields to generic Todos. |
| `commit_hygiene_drift` | Broad commit includes temporary smokes, raw logs, local state, or unrelated docs. | `git status`, `git diff --stat`, `git ls-files --others --exclude-standard`, AGENTS.md. | Worktree was staged by chronology rather than reviewer logic. | Use explicit pathspecs, split commits, keep only durable smokes, and update AGENTS/skill if the failure mode recurs. |
| `migration_terminal_receipt_replay_gap` | A migrated transaction succeeds once, then an idempotent legacy retry is rejected as receipt corruption or times out on a lock that the first response lost. | Versioned operation receipt, persisted state, lock owner/token, exact caller retry identity, pre-migration replay behavior, and focused native plus compatibility tests. | The new owner modeled only held/committed receipts and treated a closed no-op receipt as incomplete, or generated retry identity inside the callee after the caller's retry boundary. | Model terminal no-op receipts separately from held authority proofs, replay them without retired private tokens, and generate one stable operation id outside any transport retry while minting a new id for independent calls. Cover direct native replay and the compatibility adapter's response-loss boundary. |
Expand Down
Loading
Loading