opsx-ext:task — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited opsx-ext:task (Agent Skill) and scored it 92/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 2 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 2 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Drives a single OpenSpec change end-to-end. The whole autonomous pipeline — explore, generate artifacts, self-review, implement, test, verify — runs inside ONE deterministic Workflow. This skill does only what a workflow physically cannot: check preconditions, and handle the parts that need a human or that spawn subagents (the review gate, and archive + commit).
An A/B on this design measured it ~1.8× faster wall-clock-to-done than driving each phase from the main thread, because it collapses the many main-thread round-trips (one per phase, plus one per self-review and verify loop iteration) into a single hand-off. The gap widens with the number of phases and loop iterations.
A Workflow runs in the background, returns one result, and its leaf subagents have the Skill tool but NOT the Agent/Task tool. That fixes the boundary:
openspec-explore, openspec-ff-change, and openspec-verify-change skills directly — all three run non-interactively (explore has no mandatory prompt; ff/verify are given the change name/description so they never ask). It does NOT use openspec-new-change (halts for the user) or openspec-apply-change (serial) — new is subsumed by ff, and apply is replaced by script-driven wave fan-out.openspec-archive-change — which prompts the user repeatedly and itself spawns a subagent, so it cannot run inside a workflow leaf.OpenSpec must be initialized: openspec/ must exist in the project. If it does not, stop and tell the user to run openspec init and openspec update first.
Confirm openspec/ exists (Bash). Abort with the message above if not. That is the only thing the main thread does before the gate — everything else is the workflow.
Calling the Workflow tool from this skill is sanctioned (these instructions are the opt-in). Invoke the bundled script:
Workflow({
scriptPath: "<this skill's base directory>/scripts/opsx-task-full.js",
args: {
description: "<the user's request, verbatim>",
root: "<absolute path of the project>",
schema: "<optional openspec schema name, omit for default>"
// omit `test` — the workflow detects the suite itself. Pass
// test:{enabled,runCmd,coverageCmd} only to override that detection.
}
})The workflow returns one of:
{ stopped: "should-split", exploration } — the request is really several independent changes. Stop and recommend opsx-ext:task-queue; do not implement.{ changeName, summary, openQuestions, artifactFiles, completed, errors, testStatus, verifyClean, verifyPasses, residualConcerns, minorConcerns } — the pipeline ran to verification.If errors is non-empty or verifyClean is false, surface that — those are the seams the pipeline could not close on its own. residualConcerns is non-empty when self-review stopped with unresolved cross-artifact blockers (it escalates rather than looping forever) — present those to the user at the gate so they can decide, since the pipeline judged it couldn't reconcile them automatically. minorConcerns are review notes the loop did NOT act on (severity is the reviewer's subjective call) — list them at the gate too: severity can be under-rated, so a real regression can hide here. Don't bury them.
Present a one-paragraph summary: change name, file count, verifyClean state, any openQuestions, any residualConcerns (unresolved self-review blockers), any minorConcerns (review notes the loop skipped — scan them for under-rated regressions), and a smoke test the user can run. Then:
Do not proceed until the user confirms. If they report issues, fix them (re-running openspec-verify-change until clean), then return and wait again.
Once approved:
openspec-archive-change skill for <changeName> (it runs here, in the main thread, because it prompts the user and spawns its own subagent).git add ..Present: "<change-name> is committed and ready."
openspec-explore is invoked non-interactively, so it investigates and reports once instead of having a back-and-forth about scope. Open questions it raises are surfaced at the gate rather than resolved mid-run.openspec-ff-change / openspec-verify-change, that leaf cannot spawn subagents, so if those skills would normally parallelize internally they run serially here.openspec-* step that would normally ask the user a question proceeds on reasonable defaults (we pass the change name/description so they don't ask). Genuinely ambiguous calls surface as openQuestions at the gate, not as a mid-run prompt.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.