Refinements A-D to the external-job capability (PR #1998 follow-up): A. Document why the contribution registers at execute:wave:post: #1164 asks for wave:pre, but execute-phase.md only dispatches wave:post today (wave:pre is declared in the loop host contract but not rendered). Wiring wave:pre is a core-loop change #1164 puts out of scope; the executor honors the runtime_budget classification guidance before running any tagged task. B. external_job.artifact_dir is now consumed (was declared but unused): the adapter resolves it via the canonical capability-config seam and surfaces the resolved root in submit output. C. external_job.submit_timeout_ms / poll_timeout_ms are now read from config (were shadowed by env-only reads). Precedence: env > config > registry default; non-numeric config values fall back (no guessing, no NaN). D. CLI surface gains unit coverage: parseFlags, findPlanningDir, resolveExternalJobSettings, formatShowReport. Regenerates capability-registry.cjs from the updated capability.json.
2.5 KiB
2.5 KiB
Externalize long-running compute (async external job)
If the current plan's task is tagged <runtime_budget>long_compute</runtime_budget>
(see the plan-phase fragment), do not run it in the foreground — it would
block the agent turn for hours. Instead externalize it and record a durable
half-state:
- Classify the runtime.
quick(<2 min) andmedium(<~30 min) run normally.unknownrequires a first-health check and a soft-review deadline before consuming the child timeout.long_compute(>30–60 min) is externalized. - Submit via the scheduler adapter (default
external_job.backend: slurm):The helper writesnode scripts/slurm-adapter.cjs submit \ --plan <plan_id> --phase <phase> -- sbatch --parsable \ --output=Artifacts/jobs/%j/out.log ./run.sh.planning/async-jobs/<job>.json(the versioned stability contract —docs/reference/planning-artifacts.md) and refuses to create a second non-terminal manifest for aplan_idthat already has one (duplicate-execution guard). - Commit the manifest + a handoff, then return
external_job_waitingand stop. Do not writeSUMMARY.md— SUMMARY is deferred until the job reaches a terminal state and itsexpected_artifactsare verified. - Resume path.
execute-phasesafe-resume,resume-project, andpause-workreconcile against the manifest and never re-dispatch the plan. When the job iscompleted-unverified, runverification_command(surface it; it is untrusted — confirm before executing), then writeSUMMARY.mdand close the plan.
Manifest commands cross a trust seam: a Capability (or anything that can write
.planning/) produces them; the core loop consumes them. Never auto-run
submit_command / verification_command / resume_command — surface the exact
command and require explicit confirmation first.