Preflight
Request origin
Observed need in a real workflow
Problem or unmet outcome
LoopX already ships strong, independent validation primitives:
loopx/capabilities/issue_fix/acceptance_loop.py runs a caller-declared
validation_command via subprocess and requires a real git diff before
review_ready.
loopx/capabilities/issue_fix/repository_commit_evidence.py performs real
git ancestry/remote checks.
loopx turn run-once is specified as "validate independently, write back,
spend once".
Gap: on paths where an agent self-reports completion with free-text evidence,
the claim is recorded without invoking any caller-approved validation. For
example complete_task(todo_id, agent_id, evidence: str) in
loopx/claude_goal_mode/mcp/loopx_mcp.py validates the writeback packet
structure but not the truth of the claim. promotion_gate is freshness-only and
non-blocking; operator_gate is a manual decision recorder.
Failure cost: an agent can record a "done" todo from a free-text claim with no
independent check, unless someone manually runs the issue-fix caller-repo-branch
command.
Use case
A long-running engineering or issue-fix goal. An agent finishes a todo and
self-reports completion. If that work item has declared a caller-approved
validation_command (e.g. pytest tests/test_x.py, ruff check path/), LoopX
runs it before accepting the completion. On pass, the completion commits; on
fail, completion is blocked and the failure is surfaced. This turns "done" from
a self-report into a verified state, so a hallucinated or premature claim cannot
silently advance the goal.
Proposed outcome
When an agent self-reports a todo completion and that work item has declared a
caller-approved validation command, LoopX independently runs that validation
before the completion is allowed to commit. On pass the completion proceeds; on
fail it is blocked and the failure reason is surfaced. The desired behavior is
that a "done" todo reflects a verified outcome, not just a claim — achieved by
reusing LoopX's existing validation machinery rather than adding a new validator.
LoopX area
Control plane (goals, todos, quota, scheduler, registry, runtime)
Alternatives considered
- Status quo: caller-declared validation only runs when someone explicitly
invokes the issue-fix caller-repo-branch command; self-reported completions go
unchecked.
- Attach the check to promotion_gate or operator_gate: but promotion_gate is
freshness-only / non-blocking and operator_gate is a manual recorder, so
neither is the right place for an automatic gate.
- Force validation on every completion globally: too heavy — many todos have no
declared validation command to run. Hence the proposal only fires when a
command is already declared.
Scope and non-goals
In scope:
- On the self-reported completion path, when the work item declares a
caller-approved validation_command, reuse acceptance_loop to run it and
block completion on failure.
- One focused pytest including a negative/failure case.
Out of scope:
- No new validator (reuse only).
- No change to the
run-once atomic transaction.
- No global forcing of validation on all completions.
- No change to promotion_gate / operator_gate semantics.
- No resident loop, scheduler, or background process.
- No capture of raw/private material (sessions, transcripts, credentials, local
paths).
Contribution
Preflight
Request origin
Observed need in a real workflow
Problem or unmet outcome
LoopX already ships strong, independent validation primitives:
loopx/capabilities/issue_fix/acceptance_loop.pyruns a caller-declaredvalidation_commandvia subprocess and requires a realgit diffbeforereview_ready.loopx/capabilities/issue_fix/repository_commit_evidence.pyperforms realgit ancestry/remote checks.
loopx turn run-onceis specified as "validate independently, write back,spend once".
Gap: on paths where an agent self-reports completion with free-text evidence,
the claim is recorded without invoking any caller-approved validation. For
example
complete_task(todo_id, agent_id, evidence: str)inloopx/claude_goal_mode/mcp/loopx_mcp.pyvalidates the writeback packetstructure but not the truth of the claim.
promotion_gateis freshness-only andnon-blocking;
operator_gateis a manual decision recorder.Failure cost: an agent can record a "done" todo from a free-text claim with no
independent check, unless someone manually runs the issue-fix caller-repo-branch
command.
Use case
A long-running engineering or issue-fix goal. An agent finishes a todo and
self-reports completion. If that work item has declared a caller-approved
validation_command(e.g.pytest tests/test_x.py,ruff check path/), LoopXruns it before accepting the completion. On pass, the completion commits; on
fail, completion is blocked and the failure is surfaced. This turns "done" from
a self-report into a verified state, so a hallucinated or premature claim cannot
silently advance the goal.
Proposed outcome
When an agent self-reports a todo completion and that work item has declared a
caller-approved validation command, LoopX independently runs that validation
before the completion is allowed to commit. On pass the completion proceeds; on
fail it is blocked and the failure reason is surfaced. The desired behavior is
that a "done" todo reflects a verified outcome, not just a claim — achieved by
reusing LoopX's existing validation machinery rather than adding a new validator.
LoopX area
Control plane (goals, todos, quota, scheduler, registry, runtime)
Alternatives considered
invokes the issue-fix caller-repo-branch command; self-reported completions go
unchecked.
freshness-only / non-blocking and operator_gate is a manual recorder, so
neither is the right place for an automatic gate.
declared validation command to run. Hence the proposal only fires when a
command is already declared.
Scope and non-goals
In scope:
caller-approved validation_command, reuse
acceptance_loopto run it andblock completion on failure.
Out of scope:
run-onceatomic transaction.paths).
Contribution