Task to Code
Overview
Autonomously implement a code task using TDD principles: Explore the codebase and requirements, Plan tests and implementation, Code following the RED → GREEN → REFACTOR cycle, and commit the result as a new jj change. The agent works independently, documenting decisions in a scratchpad, and escalates only when blocked. Repository inspection and mutation MUST use jj; do not use Git commands.
Parameters
- agents_dir (optional, default:
.agents): Base directory for all structured-spec-to-code workflow artifacts - task (required): Path to a
.code-task.mdfile, or a direct task description. If a file, its Reference Documentation section (if present) points to design and research documents that MUST be read - scratchpad_dir (optional): Base directory for working documents (context, plan, progress). Defaults to
{agents_dir}/scratchpad/. The scratchpad for a task is created by mirroring the task file's directory structure relative to the tasks directory. For example:- Task at
{agents_dir}/tasks/template-feature/step02/task-01-create-data-models.code-task.md→ scratchpad at{agents_dir}/scratchpad/template-feature/step02/task-01-create-data-models/ - Task at
{agents_dir}/tasks/2026-03-23-auth-rate-limit/task-01-add-login-rate-limiting.code-task.md→ scratchpad at{agents_dir}/scratchpad/2026-03-23-auth-rate-limit/task-01-add-login-rate-limiting/ - If task is provided as text (no file), generate a subdirectory name from the current date and a short slug inferred from the description
- Task at
Constraints for parameter acquisition:
- You MUST ask for all parameters upfront in a single prompt
- You MUST validate that the task file exists and is readable (if a file path)
- You MUST confirm successful acquisition of all parameters before proceeding
Escalation Policy
This workflow runs autonomously. Escalate ONLY when:
- The task cannot be satisfied as written — a logical inconsistency prevents implementation. This covers the task being inconsistent with the actual codebase (references non-existent code, assumes wrong architecture) and the task being internally inconsistent (two requirements contradict, or a criterion demands behavior another criterion or the stated design forbids). Escalate with
reason: spec_defect. - The task is ambiguous in a way that admits materially different implementations, so choosing one would be a guess at intent. Escalate with
reason: spec_ambiguity. This includes a design decision with significant trade-offs the task does not address. - A prerequisite outside this task's scope is missing — an earlier task's artifact, an external service, a library that does not exist. Escalate with
reason: blocked_dependency. - Required information is missing and cannot be reasonably inferred
- Tests or builds fail repeatedly and you cannot resolve the root cause
You MUST NOT silently work around a defective or ambiguous task — do not patch the spec's intent in code, and do not pick one reading of a contradiction and implement it. The escalation is what lets the orchestrator correct the specification with an auditable record; an inline workaround leaves spec and code divergent.
When escalating, emit result.yaml with status: escalated and a populated escalation block: a reason from the shared taxonomy below, plus details clearly describing the blocker, what you tried, and what decision or correction you need.
Shared escalation reason taxonomy
These tags are shared with the code-task-review reviewer (see ../code-task-review/report-schema.md), so an orchestrator can route both producers with one rule. They are a documented convention — not enum-enforced.
| Reason | Use when |
|---|---|
spec_defect |
The task as written is logically inconsistent or unsatisfiable — internally, or against the codebase |
spec_ambiguity |
The task is under-specified such that materially different implementations would all be defensible |
unrecoverable_state |
The change under work cannot be trusted as a base for further work (primarily a reviewer-side reason) |
blocked_dependency |
A prerequisite outside this task's scope is missing |
Steps
1. Setup
Initialize the scratchpad and read all referenced documentation.
Constraints:
- You MUST determine the scratchpad path (
{scratchpad}) by mirroring the task file's path structure as described in Parameters - You MUST create the scratchpad directory
- You MUST read the task file and extract all requirements, acceptance criteria, and references
- If the task has a Reference Documentation section, you MUST read the design document and any listed research documents
- You MUST create a
context.mdfile in the scratchpad for recording findings throughout the workflow - You MUST create a
progress.mdfile using markdown checklists to track implementation progress - You MUST create an empty
work.logfile — this is the append-only TDD evidence log, populated during the Code phase - All documentation goes in the scratchpad; all code goes in the repository. Never mix them
2. Explore
Analyze requirements and research existing patterns in the codebase.
Constraints:
- You MUST create a clear list of functional requirements and acceptance criteria from the task
- You MUST determine the appropriate file paths and programming language, aligned with the existing project structure
- You MUST search the repository for relevant code, patterns, and conventions related to the task
- You MUST identify interfaces, libraries, and components the implementation will interact with
- You SHOULD create a dependency map showing how the new code will integrate, when the task involves multiple components
- You MUST update context.md with requirements, patterns, dependencies, and implementation paths
- If you discover that the task cannot be satisfied as written — whether inconsistent with the actual codebase or internally contradictory — you MUST escalate per the Escalation Policy (
reason: spec_defect), rather than reinterpreting the requirement - You SHOULD identify similar implementations in the codebase to follow established patterns
- You SHOULD consult the codebase summary at
{agents_dir}/summary/if available, to understand broader system context — especially useful for tasks without a design document - You SHOULD read
{agents_dir}/summary/coding_style.mdif it exists, and record the applicable conventions and representative examples in context.md — this is the primary style reference for the GREEN and REFACTOR phases
3. Plan
Design the test strategy and outline the implementation approach.
3.1 Test Strategy
Not every acceptance criterion is behavioral, and not everything is best verified by a mechanical test. Before designing tests, classify each criterion:
- Behavioral / functional — verifiable by executing code and asserting on observable output, state, or error paths. These MUST be covered by automated tests.
- Non-behavioral — documentation content or currency, presence/shape of configuration, file/directory structure, prose quality, or any other property with no runtime behavior to exercise. These are verified by artifact inspection (Step 4.2), not by a mechanical test. Do not fabricate a test to manufacture "coverage" for them.
Constraints:
- You MUST classify each acceptance criterion as behavioral or non-behavioral and record the classification in
{scratchpad}/plan.md - You MUST cover every behavioral acceptance criterion with at least one test scenario
- You MUST define explicit input/output pairs for each behavioral test case
- You MUST design behavioral tests that will initially fail when run against non-existent implementations
- You MUST NOT write brittle tests (see "Avoid brittle tests" below)
- You MUST save test scenarios and the criterion classification to
{scratchpad}/plan.md
Avoid brittle tests. A brittle test pins incidental details — exact wording, formatting, or ordering — instead of a contract or an observable behavior, so it fails on benign edits while catching no real defect. The canonical anti-pattern is a change-detector: asserting that a file (README, generated doc, config) contains literal strings copied from that same file. Do not write these; verify such properties by artifact inspection instead. Two narrow exceptions ARE legitimate, because each asserts something stable and externally meaningful rather than incidental prose:
- Asserting the absence of a specific deprecated/stale token (e.g., an old env-var name or flag that must no longer appear).
- Asserting the presence of a genuine contract string that an external consumer copies verbatim — a public env-var name, CLI flag, or API identifier — not the surrounding prose.
When in doubt, prefer artifact inspection recorded in work.log over an assertion that merely restates the artifact.
3.2 Implementation Plan
Constraints:
- You MUST append the implementation plan to
{scratchpad}/plan.md - You MUST include all key implementation tasks with a markdown checklist
- You MUST keep planning concise — focus on architecture and approach, not detailed code
- You SHOULD consider performance, security, and maintainability implications
4. Code
Implement tests and code following the TDD cycle. For each requirement or acceptance criterion, repeat the RED → GREEN → REFACTOR cycle before moving to the next.
4.1 Per-Requirement TDD Cycle
For each requirement, in the order defined by the implementation plan:
RED — Write a failing test:
- You MUST write a test (or small group of related tests) for the current requirement
- You MUST place test files in the appropriate test directories in the repository
- You MUST follow the testing framework conventions used in the existing codebase
- You MUST execute the test to verify it fails as expected
- You MUST document the failure in progress.md
- You MUST append the following to
{scratchpad}/work.log, capturing both the command and its output:echo >> {scratchpad}/work.log "## Requirement <name>: RED - repo state" bash -x -c "jj log -s --limit=4" >> {scratchpad}/work.log 2>&1 echo >> {scratchpad}/work.log "## Requirement <name>: RED - failing tests" bash -x -c "<test command>" >> {scratchpad}/work.log 2>&1
GREEN — Implement just enough code to pass:
- You MUST implement only what is needed to make the current test(s) pass
- You MUST follow the coding style and conventions of the existing codebase (consult coding_style.md conventions recorded in context.md)
- You MUST place all implementation code in the appropriate repository directories
- You MUST follow YAGNI, KISS, and SOLID principles
- You MUST execute tests to verify the new test passes and no existing tests broke
- You MUST append the following to
{scratchpad}/work.log:echo >> {scratchpad}/work.log "## Requirement <name>: GREEN - repo state" bash -x -c "jj log -s --limit=4" >> {scratchpad}/work.log 2>&1 echo >> {scratchpad}/work.log "## Requirement <name>: GREEN - passing tests" bash -x -c "<test command>" >> {scratchpad}/work.log 2>&1 - If an acceptance criterion specifies running an ad-hoc command (e.g. a CLI smoke test), append its output too:
echo >> {scratchpad}/work.log "## Requirement <name>: acceptance - <criterion summary>" bash -x -c "<ad-hoc command>" >> {scratchpad}/work.log 2>&1
REFACTOR — Clean up while green:
- You MUST examine the code just written and refactor for clarity, removing duplication
- You MUST ensure alignment with surrounding codebase conventions (naming, error handling, imports, etc.) — use coding_style.md representative examples as the reference standard
- You MUST prioritize readability and maintainability over clever optimizations
- You MUST execute tests after refactoring to verify nothing broke
Then move to the next requirement. Update the implementation checklist in progress.md after each cycle.
4.2 Verify Non-Behavioral Criteria
For each acceptance criterion classified as non-behavioral in Step 3.1, verify it by inspecting the artifact directly rather than by adding a test.
Constraints:
- You MUST inspect the relevant artifact (doc, config, directory layout) and confirm it satisfies the criterion
- You MUST record the inspection in
{scratchpad}/work.logwith the criterion name, what you inspected, and the concrete evidence (file:line, a quoted excerpt, or a directory listing):echo >> {scratchpad}/work.log "## Criterion <name>: inspection - <what was checked>" bash -x -c "<inspection command, e.g. sed -n / ls / a stale-token grep>" >> {scratchpad}/work.log 2>&1 - You MAY add a narrow, non-brittle guard where one is genuinely stable and valuable per the "Avoid brittle tests" rules in Step 3.1 (e.g., a stale-token absence check, or a contract-string presence check) — but inspection evidence alone is sufficient to satisfy a non-behavioral criterion
- You MUST NOT add a change-detector test to manufacture "coverage" for a non-behavioral criterion
4.3 Validate
Constraints:
- You MUST execute all tests and verify they pass
- You MUST execute the relevant build command and verify it succeeds
- You MUST verify all items in the implementation checklist are complete
- You MUST NOT proceed to commit if any tests are failing
- If validation fails and you cannot resolve it, you MUST escalate to the user
5. Commit
Create one fresh, unbookmarked jj change for the completed implementation.
Constraints:
- You MUST NOT commit until both builds and tests pass
- You MUST use
jj commit -mfor the implementation change. The message MUST contain a conventional-commit subject and a detailed body describing the specific implementation behavior and tests run; a terse subject alone is insufficient. - After
jj commit -m, you MUST probe the produced task change at@-(for example,jj log -r @- --no-graph -T 'change_id ++ "\n"') and setresult.change_idexactly to that stable@-change ID. Do not report the empty working-copy@change ID. You MUST leave an empty working-copy@with no direct descendants after committing. - You MUST NOT create or move bookmarks, rewrite an earlier task/base change, amend, or squash another change.
- All repository inspection and mutation in this workflow MUST use jj, never Git.
- You MUST commit all relevant files (implementation code, tests, and any necessary configuration changes)
- You MUST NOT commit scratchpad files
- You MUST NOT push to remote repositories
- You MUST document the resulting
change_idin progress.md. - You MUST verify all checklist items are marked complete before committing
- You MUST NOT modify the implementation plan's progress checklist. Marking a step complete is the orchestrator's responsibility, in its own separate commit — a task change must contain only that task's work. This keeps
@-identical to theresult.change_idyou report, and keeps plan progress owned by one actor (which also allows plan progress to move to an external tracker without touching this skill)
6. Emit Structured Result
After committing, write a canonical result.yaml to the scratchpad and close the conversation with a fenced completion-metadata block.
Constraints:
- You MUST write
{scratchpad}/result.yamlconforming to the v2 schema inresult-schema.md(sibling file). Required fields:result.task_file,result.change_id,result.status,result.schema_version: 2,result.produced_atas ISO 8601 UTC;acceptance_criterialist withtext/addressed/evidenceper criterion;artifacts.scratchpad_dirandartifacts.files;escalationblock iffstatus == escalated;failureblock iffstatus == failed;notesalways present. A completed result MUST contain a valid jj change ID matching^[k-z]+$; failed/escalated results may use a null change ID. The authoritative field definitions, status semantics, and examples are inresult-schema.md. - You MUST set
result.statusas follows:completed— implementation done, tests pass, a fresh jj change was produced, andresult.change_idis populated with its valid stable change IDescalated— you escalated per the Escalation Policy;escalationblock populated withdetailsand areasonfrom the shared taxonomy (spec_defect|spec_ambiguity|unrecoverable_state|blocked_dependency)failed— you attempted but cannot produce a working change;failureblock populated withcategoryanddetails
- You MUST populate
acceptance_criteriawith one entry per criterion in the task file, settingaddressed: yes | partial | noand citing specific evidence inevidence. For behavioral criteria cite the test (file:line or test name) and implementation; for non-behavioral criteria cite the artifact-inspection evidence (a file:line or quoted excerpt) rather than a test name — a non-behavioral criterion isaddressed: yeswhen the artifact demonstrably satisfies it, with no test required. - You MUST include a
notesfield (always present) with a 2–4 sentence prose summary of the iteration. - After writing
result.yaml, you MUST emit a complete fenced block whose info string is exactlyspec-workflow-meta(not bareyaml) carrying the keysstatus,result_path, andschema_version: 1. The complete fence may appear anywhere in the response, with prose before or after it; if multiple complete fences appear, the parser selects the last complete one. The format and parser rules are inresult-schema.md.
Example closing block:
status: completed
result_path: .agents/scratchpad/feat-templates-task-01/result.yaml
schema_version: 1
Note: human-driven invocations. When a human invokes this skill directly (outside an orchestrator context), writing result.yaml and emitting the inline metadata block are non-disruptive — they produce a useful artifact and a visible completion signal. Both behaviors MUST be preserved across future edits to this skill; removing either would silently break orchestrator-driven workflows.
7. Rework Round
When invoked for a rework round — a fresh session whose kickoff prompt indicates the prior implementation needs revision and names the on-disk paths to the prior result.yaml and the reviewer's review.yaml — re-enter the implementation cycle to address every identified finding.
Each rework round runs in a fresh session: prior context is reloaded from on-disk artifacts, not carried over in conversation history. This keeps state management simple, makes recovery from crashes straightforward (just restart the round), and avoids prompt-cache expiry costs that would accrue over long-lived sessions where the other agent's turn typically takes longer than the cache TTL.
7.1 Recognizing a Rework Round
Constraints:
- You MUST recognize a rework round by the kickoff prompt: it explicitly identifies the invocation as rework round N and names the filesystem paths to the prior
result.yamlandreview.yaml. Both files are conventionally located in the task's scratchpad. - If the kickoff names these paths, you MUST read both files in full before doing any work. The
review.yamlconforms to the schema incode-task-review/report-schema.md(sibling skill in this repo); theresult.yamlconforms to the schema inresult-schema.md(sibling file). - If neither file is named (or the named files are missing), treat the invocation as an initial implementation round per Steps 1–6.
7.2 Addressing Findings
Constraints:
- You MUST parse the prior
review.yamland enumerate every finding with severitycriticalorimportant, plus every acceptance criterion whosestatusisfail,partial, ornot_verified. - You MUST address every enumerated item. For each change made, cite in
progress.mdwhich finding or AC it addresses. - Re-enter Step 4 (Code) to address findings. If the findings imply a planning rethink (e.g., the approach in
plan.mdrequires revision), re-enter Step 3 (Plan) first. - You MUST update
work.logwith RED→GREEN cycles for any new or modified tests, following the Step 4.1 conventions. - You MUST produce a fresh child jj change for the rework changes with
jj commit -m, including a detailed implementation/test body. You MUST leave an empty@, create no bookmark, and MUST NOT amend, squash, rewrite, or otherwise mutate the prior implementation or task/base change. Every round is an additional ordered produced change.
Note on jj topology. The fresh-child rule preserves the orchestrator's ordered task-change series: each rework is a new unbookmarked child of the current task tip, while the prior task/base changes remain untouched.
7.3 Re-emitting Results
After producing the fresh commit, re-emit the structured result per Step 6:
- You MUST overwrite
{scratchpad}/result.yamlwith the new jjchange_idinresult.change_id, refreshedacceptance_criteriaevidence reflecting the rework, and an updatednotesparagraph describing what changed between rounds. - You MUST emit a fresh
spec-workflow-metablock per Step 6's v1 locator contract. Theresult_pathis unchanged; the orchestrator archives the prior round's copy before launching the next round.
7.4 Escalation During Rework
If you cannot address a critical finding — for example, the finding contradicts the task's stated intent, or fixing it requires design changes outside your scope — you MUST escalate per the Escalation Policy. Emit result.yaml with status: escalated and the escalation block populated, choosing the reason that fits: spec_defect when the finding and the task cannot both be satisfied, spec_ambiguity when the correct resolution depends on unstated intent, blocked_dependency when the fix needs something outside this task's scope.
Do NOT silently approve a finding you cannot fix, do NOT strip findings from the rework round's evidence, and do NOT resolve a spec contradiction by quietly changing what the code does relative to the task — that divergence is exactly what the escalation exists to prevent.
Examples
Example Input
task: ".agents/tasks/template-feature/step02/task-01-create-data-models.code-task.md"
Example Process
1. Read task file → read referenced design document and research
2. Explore: Identify existing ORM patterns, database conventions in the repo
3. Plan: Design test scenarios for model creation, validation, persistence
4. Code (per-requirement TDD cycles):
- RED: Write failing test for Template model creation
- GREEN: Implement Template model to pass
- REFACTOR: Align with existing model naming conventions
- RED: Write failing test for Field model with validation
- GREEN: Implement Field model and validation logic
- REFACTOR: Extract shared validation patterns
- ... (continue for remaining requirements)
- Validate: All tests pass, build succeeds
5. Commit with `jj commit -m` using a conventional subject plus a detailed body
describing the implementation behavior and tests: "feat(models): add data
models with validation\n\nAdds Template and Field models, validates required
fields, and records the passing test commands."
Troubleshooting
Build Issues
If builds fail during implementation:
- You SHOULD verify you're in the correct directory for the build system
- You SHOULD try clean builds when encountering stale cache issues
- You SHOULD check for missing dependencies and resolve them
- Review build/test output for specific error messages
Multi-Package Coordination
If changes span multiple packages:
- You SHOULD verify package dependency order and build dependencies first
- You SHOULD validate each package builds before proceeding to dependents
- You SHOULD still aim for a single commit per task. If the changes are too large or loosely coupled to fit in one commit, escalate — the task may need to be split
Implementation Challenges
If the implementation encounters unexpected challenges:
- You MUST document the challenge in progress.md
- You MUST attempt alternative approaches before escalating
- If blocked, escalate with a clear description of the issue and what you've tried
Artifacts
{scratchpad}/
├── context.md — Requirements, patterns, dependencies, implementation paths
├── plan.md — Test scenarios and implementation plan
├── progress.md — TDD cycle tracking, decisions, checklist, commit status
├── work.log — Append-only TDD evidence: repo state + test output per RED/GREEN cycle
└── result.yaml — Structured implementation result (schema in result-schema.md)