A machine-readable task specification format for AI coding agents, with a Go CLI validator (taskval) that ensures tasks are structurally complete and semantically consistent before execution.
Natural language task descriptions are ambiguous. "Implement search" leaves scope, constraints, acceptance criteria, and dependencies implicit. AI coding agents interpret these gaps with assumptions that diverge from intent, causing rework, scope creep, and defects.
A structured task format (defined in STRUCTURED_TEMPLATE_SPEC.md) with a two-tier validation pipeline:
TASK (natural language)
-> LLM compiles to JSON
-> Tier 1: JSON Schema (structural)
-> Tier 2: Semantic checks (cross-node)
-> PASS: ready for execution
-> FAIL: LLM reads errors, refines, re-validates
- Go 1.21 or later
Run this from your project's root directory. It installs the taskval and bd binaries, creates the /taskify Claude Code skill, and initialises issue tracking:
curl -sL https://raw.githubusercontent.com/nixlim/task_templating/main/scripts/install-taskify.sh | bashTo target a different directory:
curl -sL https://raw.githubusercontent.com/nixlim/task_templating/main/scripts/install-taskify.sh | bash -s -- --target /path/to/projectgit clone https://github.com/nixlim/task_templating.git
cd task_templating
# Build taskval locally
go build -o taskval ./cmd/taskval/
# Install into another project
bash scripts/install-taskify.sh --target /path/to/projectIf you just want the CLI tools without the Claude Code skill:
go install github.com/nixlim/task_templating/cmd/taskval@latest
go install github.com/steveyegge/beads/cmd/bd@latest| Flag | Default | Description |
|---|---|---|
--target DIR |
. |
Target project directory |
--force |
off | Overwrite existing skill files (upgrade path) |
--skip-beads |
off | Skip bd installation and bd init |
--dry-run |
off | Print actions without executing |
--help |
- | Show usage information |
The installer creates the following in your target project:
<your-project>/
.claude/
agents/
taskify-agent.md # Subagent definition (opus model)
skills/
taskify/
SKILL.md # /taskify slash command
spec-reference.md # Task spec quick reference
task-writing-guide.md # Guide for writing good tasks
examples/
single-task.json # Single task example
task-graph.json # Multi-task graph example
AGENTS.md # Created or appended with taskify section
CLAUDE.md # Created or appended with taskify section
.beads/ # Issue tracking (via bd init)
The installer is idempotent: safe to run multiple times. Existing files are skipped unless --force is set. AGENTS.md/CLAUDE.md use markers to prevent duplicate sections even with --force.
# Re-run with --force to update skill files
curl -sL https://raw.githubusercontent.com/nixlim/task_templating/main/scripts/install-taskify.sh | bash -s -- --force
# Update taskval binary
go install github.com/nixlim/task_templating/cmd/taskval@latest- Two-tier validation: JSON Schema structural checks + semantic analysis (cycles, goal quality, acceptance vagueness)
- Beads integration:
--create-beadsflag automatically creates tracked issues from validated tasks via Beads (bd) - Dry-run mode:
--dry-runpreviews bd commands without executing /taskifyskill: Claude Code slash command that reads a spec, decomposes it into tasks, validates, and records as beads
task_templating/
├── STRUCTURED_TEMPLATE_SPEC.md # The specification (authoritative)
├── CLI_COMMAND_REFERENCE.md # Full CLI reference with examples
├── TASK_CREATION_INSTRUCTIONS_AGENTS.md # Agent workflow guide for taskval + bd
├── BD_INTEGRATION_PLAN.md # Integration design document
├── schemas/
│ ├── task_node.schema.json # JSON Schema for a single task
│ └── task_graph.schema.json # JSON Schema for a task graph
├── cmd/taskval/
│ └── main.go # CLI entry point
├── internal/
│ ├── validator/ # Validation engine
│ │ ├── types.go # ValidationError, ValidationResult
│ │ ├── models.go # TaskGraph, TaskNode, InputSpec, etc.
│ │ ├── schema.go # Tier 1: JSON Schema validation
│ │ ├── semantic.go # Tier 2: DAG, references, goal quality
│ │ ├── validate.go # Orchestrator (Tier 1 then Tier 2)
│ │ └── validate_test.go # Unit tests
│ └── beads/ # Beads (bd) integration
│ ├── beads.go # Creator, command construction, output formatting
│ ├── exec.go # Command execution, pre-flight checks
│ ├── mapping.go # Field mapping, description composition
│ └── beads_test.go # Unit tests
├── scripts/
│ └── install-taskify.sh # Self-contained installer for /taskify skill
├── .claude/
│ ├── skills/
│ │ ├── taskify/ # /taskify Claude Code skill
│ │ │ ├── SKILL.md # Skill definition and instructions
│ │ │ ├── spec-reference.md # Condensed spec reference
│ │ │ ├── task-writing-guide.md # Task writing guide
│ │ │ └── examples/ # Reference examples
│ │ └── init/ # /init skill — invokes installer
│ │ └── SKILL.md
│ └── agents/
│ └── taskify-agent.md # Custom subagent for /taskify
└── examples/
├── valid_single_task.json # Passes both tiers
├── valid_task_graph.json # Multi-task graph, passes both tiers
├── invalid_task.json # Fails Tier 1 (schema errors)
└── invalid_semantic.json # Passes Tier 1, fails Tier 2
$ taskval --mode=task examples/valid_single_task.json
VALIDATION PASSED
Tasks validated: 1
No errors or warnings.$ taskval examples/valid_task_graph.json
VALIDATION PASSED
Tasks validated: 3
No errors or warnings.$ taskval --mode=task examples/invalid_task.json
VALIDATION FAILED
Summary: 9 error(s), 0 warning(s), 0 info(s) across 0 task(s)
--- ERRORS (must fix) ---
1. [ERROR] Rule SCHEMA
Path: /task_id/pattern
Problem: Value does not match the required pattern ^[a-z0-9]+(-[a-z0-9]+)*$
Fix: Add the missing required field at '/task_id/pattern'. Check the
spec's Quick Reference (Appendix A) for the expected format.
2. [ERROR] Rule SCHEMA
Path: /task_name/maxLength
Problem: Value should be at most 80 characters
3. [ERROR] Rule SCHEMA
Path: /priority/enum
Problem: Value urgent should be one of the allowed values: critical, high,
medium, low
4. [ERROR] Rule SCHEMA
Path: /inputs/minItems
Problem: Value should have at least 1 items
...$ taskval examples/invalid_semantic.json
VALIDATION FAILED
Summary: 5 error(s), 7 warning(s), 0 info(s) across 3 task(s)
--- ERRORS (must fix) ---
1. [ERROR] Rule V4
Path: tasks[2].depends_on
Problem: Task 'task-c' depends on 'nonexistent-task', but no task with that
task_id exists in the graph.
Fix: Either add a task with task_id 'nonexistent-task' to the graph, or
remove 'nonexistent-task' from the depends_on list of task
'task-c'.
2. [ERROR] Rule V5
Path: tasks
Problem: Dependency graph contains a cycle. 2 task(s) are involved:
[task-a, task-b]. A valid task graph must be a DAG (Directed
Acyclic Graph).
Fix: Review the depends_on fields of the listed tasks. Break the cycle
by removing one dependency or decomposing a task into sub-tasks.
3. [ERROR] Rule V6
Path: tasks[0].goal
Problem: Goal contains the forbidden word/phrase 'try'. Goals must describe
testable outcomes, not activities or explorations.
Fix: Rewrite the goal as a concrete, testable outcome. Instead of 'try
...', describe what the system does when the task is complete.
...
--- WARNINGS (should fix) ---
6. [WARNING] Rule V7
Path: tasks[0].acceptance[0]
Problem: Acceptance criterion contains the vague phrase 'works correctly'.
Criteria must be independently verifiable with concrete expected
values.
Fix: Replace with a specific assertion. Example: Instead of 'it works
correctly', write 'Given input "test", the function returns
["result1", "result2"] with status 200.'
...$ taskval --mode=task --output=json examples/valid_single_task.json
{
"valid": true,
"stats": {
"total_tasks": 1,
"error_count": 0,
"warning_count": 0,
"info_count": 0
}
}cat my_task.json | taskval --mode=task -# Preview what would be created
$ taskval --create-beads --dry-run examples/valid_task_graph.json
# Create issues
$ taskval --create-beads examples/valid_task_graph.json
VALIDATION PASSED
Tasks validated: 3
No errors or warnings.
BEADS CREATION
Epic created: bd-a1b2 "Task Graph: M1 - Core Infrastructure"
Task created: bd-c3d4 "Implement discount calculation..." (calculate-discounted-total)
Task created: bd-e5f6 "Add --format flag..." (cli-export-format-flag)
Task created: bd-g7h8 "Implement hybrid BM25..." (weaviate-hybrid-search)
.../taskify docs/oauth-spec.md
/taskify "Add OAuth2 support with Google and GitHub providers"Deterministic checks enforced by JSON Schema Draft 2020-12 via kaptinlin/jsonschema:
- Required fields present (
task_id,task_name,goal,inputs,outputs,acceptance) - Field types correct (string, array, object)
task_idmatches kebab-case pattern^[a-z0-9]+(-[a-z0-9]+)*$task_namelength between 5-80 characterspriorityis one of:critical,high,medium,lowestimateis one of:trivial,small,medium,large,unknowninputsandoutputsarrays are non-empty- Each
InputSpechasname,type,constraints,source - Each
OutputSpechasname,type,constraints,destination - Contextual fields accept either an array or
{"status": "N/A", "reason": "..."} effectsaccepts either an array ofEffectSpecor the string"None"
Cross-node and content-quality checks that JSON Schema cannot express. Tier 2 runs only if Tier 1 passes.
| Rule | Check | Severity |
|---|---|---|
| V2 | Duplicate task_id detection |
ERROR |
| V4 | Dangling depends_on references |
ERROR |
| V5 | Self-dependencies | ERROR |
| V5 | Dependency graph cycle detection (Kahn's algorithm) | ERROR |
| V6 | Goal contains forbidden words: "try", "explore", "investigate", "look into" | ERROR |
| V6 | Goal starts with "To ..." (activity phrasing) | WARNING |
| V7 | Acceptance criteria contain vague phrases: "works correctly", "is correct", "is good", "looks right", "properly", "as expected", "should work", "is fine" | WARNING |
| V9 | Contextual fields (depends_on, constraints, files_scope) missing without N/A |
WARNING |
| V10 | Implementation tasks missing files_scope |
WARNING |
| MILESTONE | Duplicate milestone names, dangling task/milestone references | ERROR |
A single task node in JSON:
{
"task_id": "calculate-discounted-total",
"task_name": "Implement discount calculation for order totals",
"goal": "Given a price and a discount, return the discounted total, guaranteed non-negative.",
"inputs": [
{
"name": "price",
"type": "f64",
"constraints": "price > 0",
"source": "Order record from database"
}
],
"outputs": [
{
"name": "total",
"type": "f64",
"constraints": "total >= 0",
"destination": "Return value"
}
],
"acceptance": [
"CalculateTotal(100.0, Fixed(10.0)) == 90.0",
"CalculateTotal(50.0, Fixed(60.0)) == 0.0 (clamped, not negative)"
],
"depends_on": {"status": "N/A", "reason": "Pure function, no external dependencies"},
"constraints": ["Pure function: no side effects, no I/O"],
"files_scope": ["internal/pricing/discount.go", "internal/pricing/discount_test.go"],
"priority": "medium",
"estimate": "trivial"
}A task graph wraps multiple tasks with optional metadata:
{
"version": "0.1.0",
"types": {
"ChunkResult": {"chunk_id": "int", "text": "string", "score": "f64"}
},
"defaults": {
"constraints": ["All code must pass go vet and go fmt"],
"acceptance": ["go test ./... passes"]
},
"milestones": [
{
"name": "M1 - Core",
"task_ids": ["task-a", "task-b"]
},
{
"name": "M2 - Features",
"depends_on_milestones": ["M1 - Core"],
"task_ids": ["task-c"]
}
],
"tasks": [ ... ]
}See STRUCTURED_TEMPLATE_SPEC.md for the full specification with field definitions, type vocabulary, constraint language, and complete examples.
The intended workflow for LLM-compiled tasks:
- Agent receives a natural language task description.
- Agent compiles it to the JSON format defined by the spec.
- Agent runs
taskval --mode=task --output=json task.json. - If valid: the task is ready for execution.
- If invalid: the agent reads the structured error output (each error includes
rule,path,message,suggestion) and revises the identified fields. - Agent re-runs
taskval. Repeat until validation passes. - Maximum 3 refinement attempts. If the task still fails, escalate to the user.
go test ./... -vTests cover:
- Validator: Schema validation, cycle detection, goal quality, acceptance vagueness, dependency references, Graph field population
- Beads: Priority/estimate mapping, description composition, command construction, dry-run output, text/JSON formatting
| Dependency | Purpose |
|---|---|
| kaptinlin/jsonschema v0.6.9 | JSON Schema Draft 2020-12 validation |
No other direct dependencies. The Go standard library provides everything else (JSON parsing, regex, embedded filesystem).
See repository for license details.
