Repository navigation
Description
SPX-AI-017 — Deliver a source-defined live repair agent through a supported bounded CLI workflow
Priority: P1 | Workstream: agent-runtime | Import action: New implementation issue
Planning baseline: wavect/semaprax@ae25c6a49dc09ec4613c7a6f52a27daa69dcd3f3 (11 September 2026).
Implementation prerequisites: SPX-AI-013, SPX-AI-014, SPX-AI-015
Important: prerequisites mean the required implementation/evidence is accepted, not merely that its GitHub issue exists.
Outcome
Demonstrate the intended semantic loop end to end: a source-defined agent observes a real failed check/test, obtains a model repair proposal, previews a checked candidate, and produces reviewable evidence. The model must not publish its own change automatically.
Current evidence and distinction from existing work
The repository has source Agent declarations, typed iterative stages, semantic candidate/query/review APIs and explicit publication boundaries. SPX-AI-009–015 connect the missing live path. This issue assembles those components into a user-visible vertical slice, rather than another configuration-only demonstration.
Read these owners first
- src/agent_runtime_v2.rs
- src/cli_driver.rs
- src/semantic_service_mcp.rs
- src/project/candidate
- docs/AGENT-RUNTIME-V2.md
- docs/PROJECT-GRAPH-OPERATIONAL-GIT-WORKFLOW-V1.md
- examples
Directory pointers are navigation roots. Resolve current files with rg --files; proposed new files must follow the current module ownership. The referenced snapshot may be older than the implementing branch.
Bounded scope and non-goals
Use one synthetic repair task in a host-selected temporary project, one provider and bounded semantic tools. Source defines the roles and decision logic; the host supplies explicit provider and publication authority. Default mode stops at a reviewed candidate. Real provider execution and publication remain separately authorized.
Implementation steps
- Write the minimal .spx Agent using the existing source-owned roles and the new rich interaction profile. Keep prompts/schemas generated or selected from checked source facts, not duplicate host JSON files with independent semantics.
- Expose a narrow CLI/embedding route using the same live runtime entry point. Host-select the project, tools, provider and budget before processing model output. Print clear selected profile/version and prerequisites.
- Provide semantic inspection, candidate preview and explicit validation tools using existing owners. Return compact revision-bound feedback; the model cannot execute arbitrary shell commands, alter the oracle or select paths outside the project.
- Use a fixture provider to propose an initially incorrect candidate, consume the actual diagnostic and then produce a corrected one. Add a branch where the test result differs so the second request demonstrably uses feedback.
- Execute an explicit live smoke on the same task with operator-approved credentials/budget. Keep actual outcome and usage; failure is a valid recorded result, not a reason to substitute fixture evidence.
- Interrupt and resume the demonstration around at least one recorded model response and one effect observation. Show unchanged dispatch counts for replayed work and preserved budgets.
- Export source diff, semantic impact, validation results, blind spots and journal binding for review. Publish only through a new independently approved session bound to the exact candidate; default execution must make no canonical source/Git change.
Required tests and failure cases
- The fixture agent repairs using actual feedback and fails when the required observation is withheld.
- Live mode makes a real provider call and records its true success/failure; offline mode needs no credentials.
- Malformed proposal, denied operation and failed test yield bounded feedback without unauthorized effects.
- Interrupted/resumed operation preserves prior observations and produces no duplicate external work.
- Default run leaves authoritative source untouched, and approval for candidate A cannot publish candidate B.
Test discovery and integration
Use rg --files src tests scripts and the owning harness command cargo test --locked -p semaprax --test <existing-harness> -- --list or its existing library selector. Replace <existing-harness> with the owner established from the references. Register new focused tests in that harness, prove they execute, then run the documented full profile. Do not copy a guessed selector into CI and accept a zero-test success.
Definition of done
- A fresh operator can run the documented offline vertical slice and an opt-in live smoke.
- Source Agent, runtime, semantic candidate and evidence refer to the same checked program/context.
- The result is a real feedback workflow, not an embedded prerecorded response array.
Guardrails for the implementing agent
- Read the current
AGENTS.md, affected RFC/specification, completion rows and architecture owners before implementation. This pack is pinned planning input, not permission to ignore newer code or decisions. - Use a private worktree and a private
CARGO_TARGET_DIRinside it. Do not usegit stash, overwrite sibling worktrees, or share compiler/test scratch output. Add tests to the existing owning harness, not a new compiler-linking top-level test binary unless repository rules require it. - Preserve source/graph/schema compatibility where contracted, left-to-right evaluation, lazy operands, ownership transfer, canonical cleanup order and sticky failure. Do not weaken tests, diagnostics, range checks or authority checks to get green.
- A proposed new shape/API below is a design target, not a claim that syntax or a command already exists. Run
--helpand discover exact test selectors. Zero selected tests, unavailable tools and skipped required rows are not execution evidence. - Keep model output as untrusted data; compiler facts and evidence never mint capabilities. Human support/publication decisions, paid model calls and real registry/Git writes require their own explicit authority.
- Reuse implemented Agent v2, migrations, iterators, closures, semantic candidates, persistent HIR cache and hosted PG grammar/metadata work. If the requested slice already landed, verify its gate and close only the residual gap rather than building a competitor implementation inside this repo.
Evidence to attach before closing
For the implementation handoff, include: exact starting and finishing commit; changed files and their owning invariants; the pre-fix failure or negative-control result; exact commands, exit status and nonzero selected test counts; target/toolchain/provider identity; artifact/log locations; and remaining limitations. Run the repository's complete required quality profile (scripts/quality.sh full on supported Unix, or the documented platform equivalent) before merge. A local focused pass is not hosted evidence and a green framework is not a completed model experiment. For architecture/ABI/ownership changes, obtain independent semantic review before promotion. Do not mark an execution issue complete using authored tests or documentation alone.
Activity
test(live-invocation): prove the model.invoke boundary is provider-ne…
wsdt commentedon Sep 12, 2026
Audited, not implemented.
HUMAN_BLOCKED— and the reasons are structural, not effort.Two of three prerequisites are open, not accepted.
gh issue viewshows #112 (SPX-AI-013, live provider adapter) OPEN and #113 (SPX-AI-014, live budget/cancellation enforcement) OPEN; only #114 is closed. This issue's own text defines a prerequisite as "implementation/evidence accepted", not merely filed. That condition is not met.No
.spxsource syntax reaches any of this.docs/LIVE-INVOCATION-CONTRACT-V1.md:528states it plainly: "No parser/HIR/source syntax.model.invokeis not yet a declarable […]". Verified independently —rg -n "model.invoke" src/parser* src/lexer*finds nothing, and the onlymodelkeyword in the parser is an unrelatedself.keyword("model")?insrc/parser/agents.rs:113.src/agent_interaction_schema/live_bridge.rsdid land since the audit baseline, binding the real compiled Agent Interaction Schema tolive_invocation::model_invoke::ProposalDecoder. But its own doc comment says it does not editsrc/live_invocation/orsrc/agent_runtime_v2/, and it does not touchagent_lifecycleeither — so a source-declared Agent still cannot reach a live model call through it.Both halves of the title are therefore blocked, and faking either is explicitly out of bounds. "Source-defined" cannot be faked with hand-authored host JSON — this issue's own non-goal forbids "duplicate host JSON files with independent semantics" in place of prompts and schemas generated from checked source facts. "Live" needs a real provider adapter that does not exist (#112 open), plus network egress and credentials this environment does not have.
The remaining assembly — CLI entry point, semantic-candidate preview and diff export, interrupt/resume, publication-gate separation — sits behind all of that. Landing a partial version would mean bolting a host loop around the checked reducers and describing fixture wiring as more than it is. Nothing in
src/agent_runtime_v2.rs,src/cli_driver.rs,src/semantic_service_mcp.rs, orsrc/project/candidate/**was touched.Related work that did land today: #111 is closed — the iterative driver now has a feedback-driven proposal source whose request carries the actual prior effect result, with a bounded decode-retry path and evidence-bearing budget exhaustion. That is the piece of #116's machinery that is reachable offline. What remains genuinely needs the live half.
HUMAN_BLOCKED: needs #112 and #113 accepted,model.invokesource syntax (parser/HIR work), and an operator-approved live provider credential and budget.test(agent-lifecycle): cross-engine parity for deterministic stage bo…
Add private durable source CLI and catalog batch gates (Refs #113, #116…
wsdt commentedon Sep 13, 2026
Accepted 70e3ce9 → bbf9a95 on main.
Added a checked private-host offline repair loop and actual
semaprax-full source-live offline-repaircommand. Two scripted model calls first produce a rejected candidate, then consume checked diagnostic feedback and produce a corrected ephemeral candidate. The report includes exact candidate review/delta/impact and the retained journal. Source bytes stay unchanged; terminal recovery starts no provider and dispatches no effect. The scalar feedback uses an SPX-G suffix or generic 583, not the full diagnostic namespace/message.Actual operator execution: .agent-logs/0913-final-private-cli.json, schema semaprax.private-offline-repair-demo.v1, 2 provider/model/effect dispatches, 1 rejection, 25 journal generations, source_mutation=false. Focused durable-replay regression .agent-logs/0913-final2-repair.log (1 pass).
#116 stays open for a supported general bounded CLI workflow and real-provider repair evidence. This fixed checkout demo has no persistent CLI repair-resume interface or source publication authority; no full/hosted/live-provider claim.
feat(source-live): surface the compiled reducer's evidence in run rec…
wsdt commentedon Sep 17, 2026
Progress —
1409bc7c— not closing, and three corrections to this issue's recorded stateVerified against the tree before building. Three things this issue currently says are stale:
model.invokeblocker was resolved by design, not left as a gap.docs/LIVE-INVOCATION-CONTRACT-V1.md:19-24already states a literalmodel.invokesource expression is not required; thepropose-role source lowering plus typed live driver is the intended route.semaprax-full source-live run|resume|migrate(crates/semaprax-toolchain/src/source_live_cli/, landed inea330594). It is project/agent/task-agnostic (arbitrarymanifest/source_path/agent_id/step_id/task_path), checkpoint-backed with zero redispatch on resume, budget/pricing/IO-bounded, and drives a real live subprocess provider viaProcessOpenCodeRunner(free "contributor" tier, credential-free). The recorded residual "no supported general provider-repair workflow or persistent CLI repair-resume interface" conflated this with the separate fixedoffline-repairdemo.What was actually missing, and is now fixed
The general route computed
SourceLiveOutcome.checked_run(src/agent_lifecycle/iterative.rs:51) and then silently dropped it in the CLI'sreceipt(), so the compiled reducer's own evidence never reached the receipt a caller reads.receipt()now embedsiterative_evidencein all three receipt schemas: thesemaprax.agent-iterative-evidence.v2document (status, iteration and effect counts, per-stage rows, authorization bindings, terminal-value digest) on any dispatching attempt, andnullon a pure terminal-checkpoint replay — so a replay cannot be misread as a run that dispatched.Evidence:
cargo test --locked -p semaprax-toolchain --lib source_live_cli::→ 22 passed, 0 failed, including the new assertions.Precise residual scope
Generalize the candidate-preview / source-diff / semantic-impact / blind-spots evidence that only the fixed
offline-repairdemo produces today (viaagent_runtime_v2::OfflineRepairEnvelope/OfflineRepairHandler) so the generalrun/resumeroute can drive an arbitrary host-selected repair project through the same candidate-preview machinery. Plus an actual operator-approved live smoke run recorded against the real endpoint — explicitly outside this worker's authorization and not attempted.The owning files for that remaining work are
src/agent_runtime_v2.rsandsrc/agent_lifecycle/iterative/source_live/**, notsource_live_cli— a future worker should scope there.wsdt commentedon Sep 18, 2026
Closure audit @
e9ab9242— NOT CLOSEABLE.Prerequisites are done and the general CLI exists, but candidate-preview/diff evidence has not been generalized to it, and the definition of done additionally requires an operator-approved live smoke run with real credentials.
Two distinct gaps: one engineering (generalize the evidence path), one requiring an operator with credentials.
feat(cli): generalize candidate-preview repair evidence into a config…
fix(doc): unbreak `cargo doc -D warnings`, and cover #116's withheld-…
wsdt commentedon Sep 19, 2026
The thread here is stale in a way worth correcting: the last comment (2026-09-18 11:48 UTC) says NOT CLOSEABLE over two gaps, and one of them was closed the same day.
Gap 1 — "generalize candidate-preview/source-diff/impact evidence off the fixed demo onto the general route" — is already closed by
81031817("feat(cli): generalize candidate-preview repair evidence into a config-driven durable CLI route",Refs #116), which landed after that comment was written and was never reported back here. It addscrates/semaprax-toolchain/src/source_live_cli/repair.rs(788 lines), exposingsemaprax-full source-live repair run|resume <config.json> <checkpoint-dir>— wired atsource_live_cli.rs:47, catalogued insrc/cli/help.rs:158. It reusesOfflineRepairEnvelope,OfflineRepairHandlerandrun_live_bound_model_durablefromsrc/agent_runtime_v2.rsunchanged, driven off an arbitrary host-selected manifest/source/target/effect-contract JSON config rather than the one hardcoded demo.One required failure case was genuinely untested, and
cf0967e0closes it. This issue's list includes "The fixture agent repairs using actual feedback and fails when the required observation is withheld."FeedbackGuardedAdapter::start(repair.rs) is the sole production enforcement point, and only its success path was exercised — neitherrepair_tests.rsnoroffline_repair_cli.rscovered the refusal.repair_run_fails_when_the_required_prior_feedback_observation_is_withheldflipsrequires_prior_feedbackonto the first scripted turn, which runs before any effect has been dispatched, so the prompt the runtime really builds carries no prior observation. The guard must read the actual prompt bytes and refuse rather than let the agent proceed on a fabricated one. It drives the realrun_live_bound_model_durablepath rather than calling the adapter directly. Negative control: disabling the guard's condition makes the run succeed with a full candidate receipt and the test fail;repair.rswas restored byte-identical afterwards.Status of the scope, honestly:
source_mutation: false,publication_authority: false) should be read as live-provider or production evidence.Verified:
-p semaprax-toolchain --lib source_live_cli::28 passed, 0 failed. No hosted run has coveredcf0967e0yet.feat(source-live): add provider-backed repair adapter (Refs #116)
wsdt commentedon Sep 19, 2026
Progress pushed in 051682b (Refs #116).
Added the explicit OpenCode Provider-Adapter repair route and additive V2 receipt while preserving the V1 receipt key set. Adversarial review led to three hardenings before push: V2 now uses restart-stable Unix epoch time instead of the fixture clock, the process timeout is bounded by remaining absolute-deadline time, and checkpoint model identity commits to the selected executable and canonical scratch path. The OpenCode route performs no candidate preview while preparing its durable handler.
Verified locally: source_live_cli unit slice (29 passed), OpenCode repair-adapter slice (3 passed), cargo fmt, and diff checks. No live provider call or publication/test authority is claimed. Remaining: operator-approved live smoke, V2 settled-wire/resume hostile coverage, and the inherited V1 fixture pre-replay diagnostic derivation.
fix(repair): replay settled provider responses exactly (Refs #116)
feat(repair): bind candidate-test feedback (Refs #116)
feat(source-live): project checked repair evidence
fix(source-live): preflight retained V2 repair state
fix(cli): harden durable repair recovery
wsdt commentedon Sep 21, 2026
Current-main reconciliation: 32ace2e already closed the advertised offline V2 hostile settled-wire/resume recovery cases and the V1 terminal pre-replay diagnostic refusal in crates/semaprax-toolchain/src/source_live_cli/repair_tests/recovery.rs. The remaining blocker is the authorized live-provider smoke/evidence route; this update does not claim that external run.
fix(agent): bind repair runs to checked source bytes
wsdt commentedon Sep 21, 2026
Pushed
f7014670to main (Refs #116). The general durable repair route now binds its execution to the exact source bytes retained by the authenticated Project, with a bounded exact raw-path recheck before checkpoint/provider construction and again after provider execution. Source growth after authentication refuses before checkpoint creation; same-length substitution during the recorded two-turn provider flow refuses the receipt, preserves the external source edit, and retains the completed journal for review.An adversarial review found the first helper-only test did not prove production placement; it was replaced with two production-path mutation tests. Focused result:
cargo test --locked -p semaprax-toolchain --lib source_changed -- --nocapture→ 2 passed, 111 filtered. #116 remains open solely for the separately authorized real-provider smoke/evidence; no paid/live call was attempted.