Execute task
Implement one task (or a cohesion bundle) from a signed-off spec (Ready or Active): recompute the execution freshness gate, write the verifying test first, implement to green, run the project's full CI with adaptive retry, converge via the configured review_sequence (default /polish --nested), then open a draft PR referencing the brief, tasks, REQs, and tests. The execution workhorse of the planwright pipeline. Assumes the worktree already exists; never creates worktrees, never merges, never marks a PR ready.From its SKILL.md
npx -y skills add inkatze/planwright --skill execute-taskAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
- runs commandsInstructs the agent to run 7 commands, including `scripts/resolve-rule-doc.sh <doc-name>` and 6 more.
SKILL.md
26.1 KB, ~6.7k tokens by cl100k_base, as published. Nobody here has run it
/execute-task
The execution layer of the planwright pipeline (REQ-E1.1–REQ-E1.5): take one
ready unit (a single task or a cohesion bundle) from a Ready or Active spec with
a signed-off kickoff brief and carry it from a failing test to a draft PR.
/orchestrate dispatches it into a prepared worktree; a human may also run it
inside one. It works from the kickoff
brief, the durable contract (D-3), not by re-reading the spec, and never
creates worktrees (D-37, D-44), never merges, and never marks a PR
ready — sign-off and merge are the human's two reserved controls.
Doctrine
This skill is procedure, not doctrine. Read the manifest's rule docs via
scripts/resolve-rule-doc.sh <doc-name> (under the resolved planwright root);
their definitions govern the concepts this skill names. Per
doctrine/instruction-hygiene.md, run-start entries load before work begins,
point-of-use entries at the named step or branch.
Invoking plugin scripts (REQ-D1.1, D-7). Call scripts/<name>.sh by the
resolved literal absolute path, never $VAR/scripts/<name>.sh —
doctrine/plugin-script-invocation.md.
If a manifest doc does not resolve — at run start or its point of use — halt
naming the missing doc and the chain consulted (REQ-K1.7). decision-domains
degrades gracefully instead: absent, note it in one line, skip the drift check,
and use engineering judgment.
Doctrine: run-start spec-format (status lifecycle, anchors, freshness gate) Doctrine: run-start proportionality Doctrine: point-of-use research-rigor Doctrine: point-of-use security-posture Doctrine: point-of-use validation-rigor Doctrine: point-of-use finding-categorization Doctrine: point-of-use gate-wiring Doctrine: point-of-use decision-domains
Pre-flight
Run once per invocation, in order. Any halt records the unit to the spec's
tasks.md ## Awaiting input section with the reason — on a format-version 2
bundle as a committed reference bullet, **Task <id>** — <reason>, the block
staying in ## Tasks (a halting-skill human-payload write, D-3) — and ends the
step (the gate-wiring pause protocol's dispatched arm); attended, present and
wait instead.
- Parse
$ARGUMENTS. Extract one or more task IDs (5,3.5, or5 6for a bundle) and an optional spec path, given as eitherspecs/<spec>or the bare<spec>. Validate each<id>against^[0-9]+(\.[0-9]+)?$, and the extracted<spec>against the anchored identifier pattern^[a-z0-9][a-z0-9-]*$(≤64 chars, REQ-A1.8) before it appears in any path or command; a failing token is never interpolated. No task ID: halt and ask which task to execute. - Resolve the spec path, in order: (a) an explicit spec-path argument
(
specs/<spec>or bare<spec>, validated in step 1); (b) the branch name parsed againstplanwright/<spec>/task-<ids>(D-36); (c) the current checkout when it holds exactly onespecs/*/bundle whoseStatus:isReadyorActive; (d) ask, listing the available bundles (underscore-prefixed accumulators are not bundles). Verify the directory holdsrequirements.md,design.md,tasks.md, andtest-spec.md. - Resolve the run-start doctrine docs (above); halt on a resolution failure. Point-of-use docs resolve at their named steps.
- Verify the spec is Ready or Active (REQ-C1.1, superseding the bootstrap
non-Active refusal REQ-J1.2, D-33; kickoff-lifecycle D-2, D-3). Read the
**Status:**line inrequirements.md.Ready(signed off, no work started) andActive(work in flight) are both executable; refuse Draft, Done, Retired, and Superseded. The spec file staysReadyduring execution: Ready↔Active is derived, not stored (D-2), written only byorchestration-concurrency's single reconcile writer (D-3), so a task normally runs against aReadyspec, not the stored-Activedemand this gate must not reintroduce. On Draft, halt and suggest/spec-kickoff; a terminal (Retired/Superseded) or Done spec has nothing to execute. AReadyspec runs on the same terms as Active: the freshness gate (step 7) still applies (REQ-C1.3); the two gates compose. There is no bypass flag. - Run the validator.
scripts/spec-validate.sh specs/<spec>. On this dispatch path a missing or non-executable validator fails closed and halts (REQ-K1.7). A Ready or Active bundle's findings are errors: surface them and halt. - Verify the kickoff brief.
specs/<spec>/kickoff-brief.mdmust exist and carry a final sign-off record with an anchor line (D-36). Absent, or partial (sections signed but no sign-off record, or a record without its anchor line — anchor-written-last makes a killed kickoff look absent, by design): halt and prompt/spec-kickoff. - Run the execution freshness gate (REQ-F1.9, REQ-F1.10, D-45; the
spec-formatanchor rules; fleet-hardening D-9). It stops execution against content changed since sign-off and against a stale localmain:- Fetch-before-gate (D-9, REQ-D1.1). Run
scripts/dispatch-fetch.sh --spec specs/<spec> <primary-checkout>: it fetchesorigin(bounded, no local-mainadvance) and prints the fetchedorigin/mainanchor (re-pointingspec-anchor.sh). Exit 0 → gate vsorigin/main; 3 (no-remote, offline) → gate vs localmain; 4 (stale-transient) or any other nonzero → do not silently proceed: park to Awaiting input. - Validate the entry (brief's most recent, from the resolved ref): it
parses, uses a sanctioned command form (
scripts/spec-anchor.sh <spec-dir>or the interim whole-file form), a sanctioned writer (a/spec-kickoffsign-off or the markedClass: expression-onlyritual), and — meaning-class — a dispositionedLens-pass:. - Compare the recorded anchor against the one
dispatch-fetch.shrecomputed. Match → proceed. Mismatch → halt (remedy: a/spec-kickoffdelta re-walkthrough). No / unparseable / non-sanctioned / wrong-writer entry → halt (repair the record per REQ-F1.10). Halts go to Awaiting input; no bypass flag.
- Fetch-before-gate (D-9, REQ-D1.1). Run
- Read the brief slice and task block(s). From the brief: the signed-off
goal restatement, the task graph, and the unit's risk entries. From
tasks.md: each block'sDeliverables,Done when,Dependencies, andCitations. Confirm every dependency is completed — on a v1 bundle it sits in## Completed; on a v2 bundle it derives Completed via the derivation engine (scripts/orchestrate-state.sh); if one is not, halt naming it. - Derive the full-CI command (D-19). Pick the most comprehensive guard the
repo ships, checking in order: a
mise.tomlaggregate task (planwright's own ismise run check); apackage.jsonci/testscript; aMakefileci/testtarget; alefthook.ymlpre-commitstack; a language toolchain's check. Prefer the aggregate over a bare test run. If none can be derived, ask. - Resolve
dispatch_isolation(D-5, REQ-C1.3). Runscripts/resolve-dispatch-isolation.sh(under the resolved planwright root) to read the knob through the four-layer overlay; it printsper-step(the assigned-decision default) orper-unitand applies the REQ-E1.4 by-layer malformed policy. A hard-fail (exit 4 — a malformed team-shared value or config; exit 5 — a broken install whose core default is unresolvable) is a stop condition: record totasks.mdAwaiting input and halt. A warn+degrade (an adopter/machine-local value degraded to the core default, exit 0) proceeds. Record the mode; it governs how Implementation and Convergence host this unit's steps (see Step isolation). - Update Last activity (v1); write no placement or
Status. On a format-version 2 bundle this step writes nothing — a v2 block carries no annotations, and derived execution state never produces commits (version keying, here and throughout this skill, reads the declaredFormat-version:as the scripts do; unparseable fails closed, never the v1 arm — D-7). On v1: the dispatch record (task branch + runtime marker) already makes the unit derivable as In progress, so write no section placement and noStatusline (REQ-B1.1, D-1); a block still in## Forward planwhile its branch is in flight is intentional snapshot lag, not corruption (REQ-B1.2). The only edit is the block's- **Last activity:** <today>annotation, anchor-excluded (spec-formatcanonical extraction) and not aStatusline, so it trips neither corruption guard (full race rationale at PR step 3). Commit it whencommit_on_state_moveis true (readconfig/defaults.ymloverridden by<repo>/.claude/planwright.local.yml, local wins; absent/malformed falls back to the default with a one-line warning).
Implementation
Step isolation (dispatch_isolation, REQ-C1.3, REQ-C1.4, D-5)
The mode resolved in pre-flight step 10 governs how this unit's steps — the
implementation phase (test-first loop, research, security pass, CI), then each
review_sequence skill — are hosted. It changes only the hosting, not the
work or order.
per-unit(strictly preserved): the whole unit runs in one session — implement, run CI, invoke eachreview_sequenceskill inline with--nested, then push and open the PR. Context carries across steps.per-step(the assigned-decision default): each step runs in its own fresh/resume-seeded session, so context stays bounded and each review's perspective is uncontaminated by prior steps. The order is unchanged; each step is seeded from durable state alone (brief,tasks.mdsnapshot, git log, open PR) and commits its work with thePlanwright-Task:trailer. Realization is the backend's job (D-2): a session-grade backend spawns a session per step; the terminal rung (D-3) approximates it with a context clear +/resumereseed; a backend that can do neither degrades toper-unit(degrade capability, never safety).
State-safety holds in both modes (REQ-C1.4): every tasks.md placement move
goes only through the sibling reconcile under the per-spec lock, no per-step
session writes dispatch/progress state or opens a PR — push and PR creation
remain this skill's single terminal step (see Invariants).
Commit convention (REQ-C1.4, D-2)
Every commit this skill authors for the unit (test-first action commits, the
observation chore commit, any expression-only amendment commit) carries a
Planwright-Task: <spec>/<id> footer trailer: the durable completion anchor the
orchestration-state derivation reads by scanning the whole commit message, so it
survives a squash/rebase merge, branch deletion, and direct-to-main commits.
Stamp it through the shared helper, not by hand, so it is grammar-validated and
identical everywhere:
printf '%s\n' "$message" \
| scripts/planwright-commit-trailers.sh <spec>/<id> \
| git commit -F -
For a bundle, pass one ref per task (… <spec>/<id1> <spec>/<id2> …); the
helper emits one trailer per task. The trailer is footer-only and additive — no
subject-line change, no Claude/co-author attribution — so the no-attribution
rule is unaffected.
Test-first development (REQ-E1.1, validation-rigor)
Read test-spec.md for the unit's cited REQs first: each entry describes the
verification path — what to test and which edge cases matter. Then, for every
piece of new behavior or bug fix the unit introduces:
- Write the test, grounded in the
test-spec.mdentry and theDone when:conditions. It must be specific enough to fail for the intended reason and pass only when the implementation is correct. - Run it and confirm it fails for the right reason — the failure message corresponds to the behavior being implemented, not a syntax, import, or unrelated error. A test that passes immediately, or fails for the wrong reason and cannot be isolated, is a stop condition.
- Implement to make the test pass, consulting the brief's goal restatement and risk register.
- Confirm the test passes — the same test, unchanged. Iterate on the implementation, never the test.
Validate the solution per validation-rigor: the targeted test, the wider
project suite (the CI step below), and the altitude check (fix the cause at the
right layer, not the symptom). A unit that is purely configuration,
documentation, or infrastructure with no testable behavior per test-spec.md
skips the loop; note in the PR body why no test was added.
Research Rigor (REQ-D1.5, research-rigor)
Research fires before implementation when a trigger holds — a new
dependency, an unfamiliar domain, a security-touching pattern, a
version-sensitive API, or a "how do mature projects do this" question. Consult
current sources in order (official docs for the pinned version, then the
library's own source and tests, then issues/RFCs), honor recency over model
memory, and run the antipattern check before adopting a pattern. Record the
findings, tradeoffs, and sources in the brief's risk register, appended to a
named section — never overwriting existing rows, never as an anchor entry.
Declare the research depth's scoping per proportionality. A significant risk
the brief did not anticipate is a stop condition: record it and hand off.
Write-time security pass (REQ-D1.6, security-posture)
When the diff touches a write-time trigger class — untrusted input, subprocess
or shell construction, path handling, authorization, crypto, or serialization —
run a focused security pass on that risk class before opening the PR, distinct
from the general review lens, with Research Rigor consulted. Apply artifact
data-hygiene to everything committed (brief, risk register, observations log, PR
body): no secrets, credentials, internal hostnames, or sensitive detail. Work in
a hard-disqualifier zone (security-sensitive code, migrations or destructive
ops, CI config, lockfiles, secrets files) follows the gate-wiring pause
protocol rather than landing autonomously.
Decision-domains drift triggers (REQ-G1.8, decision-domains)
When implementation is about to cross a catalogued decision domain the brief did
not decide, the drift trigger fires: if the brief or spec already decides it,
proceed citing that decision; otherwise research per stake, then recommend (a
low-stake, reversible call, considerations recorded) or escalate (a
load-bearing or hard-disqualifier-adjacent call) rather than auto-defaulting. A
decision in an uncatalogued domain writes an observation (the catalog grows
through the drain loop). The catalogued domains are the prose seed unioned with
adopter/team/machine-local additions via scripts/resolve-catalog.sh decision-domains (REQ-D1.1), so overlay domains trigger drift too. If
decision-domains did not resolve, note the skipped check and use engineering
judgment.
Run the full project CI (REQ-E1.2)
Run the command derived in pre-flight step 9. The full suite must pass before convergence; capture its output.
Adaptive CI-failure handling (REQ-E1.2, D-25)
On a CI failure, classify it with scripts/classify-ci-failure.sh over the
captured output (it prints transient or logic; unknown patterns default to
logic):
transient(network/DNS errors, registry failures, rate limits, timeouts): retry up to twice, waiting 30s before the first retry and 90s before the second. A retry that goes green proceeds; if both still fail, reclassify as logic and escalate.logic(assertion mismatches, type/compile/syntax errors, lint/format violations, test-runner failures): escalate immediately, never retried. Record the failure with the full CI output totasks.mdAwaiting input and halt (attended: surface and wait).
Convergence (REQ-E1.4, REQ-D1.3, D-39, D-6)
After CI passes, run the review sequence. The sequence is the
review_sequence config knob (D-6, REQ-D1.3): an ordered list of nestable
review-skill names, resolved through the four-layer config overlay. The default
is polish (today's /polish --nested convergence); an overlay can reorder or
extend it.
Resolve the sequence. Run scripts/resolve-review-sequence.sh (under the
resolved planwright root). It reads review_sequence through config-get
(REQ-D1.1), validates each name against the nestable-review-skill predicate,
applies the REQ-E1.4 by-layer malformed policy, and prints the validated ordered
names. By exit code:
- 0 — the printed names are the review sequence, in order. A stderr warning may note an overlay was degraded to the core default; surface it but proceed.
- 4 — a repo-tracked overlay set a malformed value, or the repo-tracked
config is structurally malformed: a hard-fail stop condition — record to
tasks.mdAwaiting input and halt. - 5 — broken install (the core default is unresolvable): a stop condition — halt and hand off.
Run each named skill in order, with --nested. Every review skill runs
--nested — it drains every action disposition per act-then-review and returns
its audit record without pushing or creating a PR (this skill's job, which is
why --nested is mandatory). The dispatch_isolation mode sets only where each
--nested call is hosted — per-unit in-session composition (REQ-E2.2,
D-13) or a fresh /resume-seeded per-step session — never the --nested
contract.
After each returns:
- Normal exit (converged, or handed off with queued forks): continue to the
next skill; once the sequence has run, proceed to PR creation, folding each
skill's audit record — the four bucket tables (per
finding-categorization), the declined log, the pending-sign-off checklist, and any queued Needs-human-judgment forks — into the PR body. - Safety stop (wider-suite failure, loop detection, iteration cap): the branch may be known-broken. Surface the stop reason and halt; do not run later review-sequence skills or open a PR over a broken branch.
- Hard-disqualifier finding a review-sequence skill surfaced but could not resolve autonomously: a stop condition — hand off for human direction.
In-flight amendments (D-19, REQ-A3.3, REQ-F1.10)
If implementation reveals the spec itself needs an edit, classify it on the
amendment axis (the spec-format amendment ritual):
- Expression-only (a typo, ambiguity, or gap-fill consistent with the
accepted decisions): fix it in place with a dated
## Changelogentry riding this task's PR, and write a marked self-re-anchor entry to the brief's amendment log —Class: expression-only, citing the changelog line, anchor byscripts/spec-anchor.sh specs/<spec>written last. This is the one anchor entry an execution skill may write. - Meaning-class (contradicts an accepted decision, alters a REQ's meaning,
or adds a REQ/D-ID): contract drift — do not edit the contract from
execution. Halt, surface the drift with the conflicting reading, and route the
human to a
/spec-kickoffdelta re-walkthrough. There is no silent proceed.
PR creation (REQ-E1.5, D-21)
-
Push the branch:
git push origin <branch>(with-uon first push). New commits only — never force-push, amend, squash, or rebase (REQ-J1.4). On push orghauth failure, degrade gracefully (REQ-K1.6, REQ-K1.7): the local work is committed; record an Awaiting-input note intasks.mdnaming the pending step and the failure, surface it, and stop. Never retry into an opaque failure. -
Open or update a draft PR. If a PR already exists for the branch, update its body in place; otherwise
gh pr create --draftwith an explicit--titleand--body(headlessghprompts or fails without them). The title is conventional and passes the PR-title lint (scripts/check-commit-msgs.sh):feat(<scope>): <task title>or the fitting type. Assemble the body per the PR-body assembly section of thegate-wiringdoctrine — the single normative home for the layout (D-2). This skill supplies the summary inputs: the kickoff brief path (specs/<spec>/kickoff-brief.md), the task IDs, the REQs satisfied (from the taskCitations:), the test additions and what they verify, and implementation notes (key decisions). The audit record is the review sequence's output: the four tables, declined log, pending-sign-off checklist, and any queued forks. At PR review the human approves each checklist item by leaving its commit, or rejects it with the named revert.The PR is always a draft. Never mark it ready and never merge.
-
Annotate the unit (v1 bundles only). On a format-version 2 bundle no annotation exists to write — skip this step. Update only the task block's
- **Last activity:** <today>annotation; write noStatusline. Section placement is thetasks-pr-syncreconcile's sole job (REQ-B1.1, D-1); the reconcile preserves annotations untouched and does not author theStatustext. Writing aPR #<N> draftStatus here would race the reconcile: the hook is fail-soft on a busy lock (a clean no-op), so the block can still sit in## Forward plan, an in-progressStatusthere being exactly the section/status contradictionscripts/check-ledger.shflags (REQ-E1.1, REQ-E1.2).
Hand off. Report: the unit and spec, the freshness-gate result, tests written and CI outcome, the convergence summary, the verified anchor, the push/PR outcome (or degradation note), and what the human decides at PR review — the pending-sign-off checklist and any queued forks. Apply artifact data-hygiene to everything surfaced.
Stop conditions (mandatory human handoff)
Halt and hand back when any of these fires, recording the unit to tasks.md
Awaiting input with the reason (the pre-flight halt protocol above). Each is
described in full at its point of use:
- Spec not Ready or Active: pre-flight step 4 (Draft/Done/Retired/Superseded;
suggest
/spec-kickofffor Draft). - Missing or erroring validator: pre-flight step 5.
- No or partial kickoff brief: pre-flight step 6.
- Freshness-gate halt: pre-flight step 7 (anchor mismatch, or an absent/unparseable/non-sanctioned/wrong-writer entry).
- Dependency not completed: pre-flight step 8.
- Malformed
dispatch_isolation: pre-flight step 10 (exit 4/5). - Test cannot fail for the right reason: test-first step 2.
- CI logic failure: a logic-classified failure, or transient retries exhausted then reclassified.
- Research reveals an uncovered risk: one the brief did not anticipate.
- Contract drift: a meaning-class spec change is needed; route to
/spec-kickoff. - Ambiguity in the task definition:
Done when:orDeliverables:admit multiple valid interpretations. - Hard-disqualifier finding in convergence: a review-sequence skill could not resolve it.
ghnot authenticated or push rejected: the PR step cannot reach GitHub; local work is complete.
Invariants
These hold at every step:
- Never act on a spec whose status is neither Ready nor Active, and never bypass the execution freshness gate that composes with it — no bypass flag for either (REQ-C1.1, superseding REQ-J1.2, D-33; D-2, D-3, REQ-F1.9, REQ-C1.3).
- Never create a non-draft PR, mark a PR ready, or merge — the draft→ready flip and merge are the human's (D-21, REQ-J1.1).
- Never create a worktree; this skill runs inside one (D-37, D-44).
- Never invoke a
review_sequenceskill (/polishby default) without--nested: this skill owns push and PR creation (D-39, REQ-E1.4, REQ-D1.3). - Never let
per-stepisolation weaken state-safety: everytasks.mdplacement move goes through the sibling reconcile under the per-spec lock, and no step session opens a PR (REQ-C1.4). - Never skip the test-first loop for a behavior-introducing unit with a
test-spec.mdverification path (REQ-E1.1). - Never retry a logic CI failure; transient retries cap at two; unknown classifications default to logic (REQ-E1.2).
- Never silently proceed past a meaning-class contract drift; route to
/spec-kickoff(REQ-A3.3). - Never write a meaning-class anchor entry; the only one this skill writes
is the marked
Class: expression-onlyself-re-anchor (REQ-F1.10). - Never force-push, amend, squash, or rebase; new commits only (REQ-J1.4).
Observations
When something outside the unit's scope surfaces during implementation or
convergence (complexity growth, an outdated pattern, a newly available
dependency feature, an uncatalogued decision domain), record it as its own
fragment through the shared helper: scripts/obs-record.sh --slug <topic> --scope <repo> --text '<observation>' (resolved under the planwright root; it
writes one file under specs/_observations/entries/). Commit the fragment
within the iteration that produced it so the tree returns to clean; on a
non-zero helper exit, surface the failure rather than dropping it. Do not act on
observations during the unit; they are seed material for /spec-draft
(REQ-E2.1, REQ-H1.6).
Maintenance
After the run completes (or halts), compare these instructions against the
resolved doctrine docs (REQ-B3.2, D-42) — especially spec-format and
gate-wiring. If a concept this skill names changed meaning, gained or lost a
step, or moved between docs, record a drift observation via the shared helper
(scripts/obs-record.sh --slug skill-drift --scope <repo> --text 'skill-drift(execute-task): <what>', keeping the skill-drift(...) prefix),
commit it as its own chore commit, and tell the user. Do not edit this skill or
the doctrine docs to resolve the drift; /spec-draft owns folding drift into
spec amendments.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.