| name | beadcraft |
| description | Use when decomposing a spec, design, or feature description into a task dependency graph with self-evaluating acceptance criteria |
Task Craft
Overview
Unified skill for task quality. Defines task anatomy, quality standards, and size heuristics ONCE, serving three modes:
- Decompose: Spec/design → task dependency graph (replaces spec-to-tasks)
- Create: Ad-hoc single task with full quality applied
- Review: Audit existing tasks, flag smells
Core principle: Every task must answer "how do I know this is done?" with a test command. Every task passes the Rule of Five before being emitted.
Task Quality Core
All three modes apply this shared quality standard.
Task Anatomy — Required Fields
Every task must include:
Test: path:FnName | Cmd: test_cmd | Assert: expected
Read: file1.go:Symbol1, file2.go:Symbol2
Signature: func Name(ctx context.Context, arg Type) (Result, error)
Edges: nil input → ErrInvalid; timeout → context.DeadlineExceeded
| Field | Purpose | Required? |
|---|
Test: | Test file path and function name | Always |
Cmd: | Command to run verification | Always |
Assert: | What "pass" looks like | Always |
Read: | Exact files and symbols the worker must read | Always |
Signature: | Function/method signatures being implemented | When adding functions |
Edges: | Error conditions and boundary behavior | When non-trivial |
Rule of Five — Critique Loop
Run 5 passes on every task before emitting. Each pass asks one question:
| Pass | Name | Question |
|---|
| P1 | Zero Ambiguity | Are signatures, types, and error conditions exact? No "should handle errors appropriately." |
| P2 | TDD Inputs/Outputs | Does acceptance have concrete test data — specific inputs and expected outputs — not vague assertions? |
| P3 | Context Minimization | Does Read: list the exact files and symbols the worker must look at? Nothing more, nothing less? |
| P4 | Boundary Check | If this crosses IPC/RPC/package boundaries, are protocol details and both sides specified? |
| P5 | Adversarial | What would a zero-context worker misunderstand? Fix it. |
If any pass fails, revise the task and re-run from P1.
Size Heuristics
A task is too large if ANY of these apply:
- Estimate >7 minutes
- Needs >1 test file or >4 source files
- Title contains "and" (doing two things)
- Acceptance needs multiple unrelated assertions
A task is small enough when ALL of these apply:
- One test function in acceptance criteria
- <=7 min estimate
- 1-3 source files
- Single-purpose title
Smell Catalog
Used by Review mode, but also as a checklist for Decompose and Create:
| Smell | Description |
|---|
| No acceptance | Task has no Test: / Cmd: / Assert: |
| Vague title | "improve X", "handle edge cases", "clean up" |
Missing Read: | Worker doesn't know what files to look at |
| Stale in_progress | >3 days in in_progress without activity |
| Missing estimate | No time estimate attached |
| Stale dependency | Depends on a closed task (dep should be removed) |
| Oversized | Fails size heuristics but hasn't been decomposed |
Missing Edges: | Non-trivial logic with no error conditions specified |
Mode: Decompose
Takes a spec (markdown doc, user description, or design output from brainstorming) and decomposes it into a task dependency graph.
Step 1: Parse Spec
Extract from the spec:
- Goal — what the feature does
- Components — distinct modules/packages/files
- Seams — boundaries between components (APIs, interfaces, data contracts)
- Constraints — tech choices, performance requirements, compatibility
If spec is vague: ask the user to clarify before decomposing. Don't guess.
Step 2: Create Epic Task
oro task create "<feature name>" --type epic \
--acceptance "All child tasks closed. Full quality gate passes." \
--description "<goal from spec>"
Step 3: Decompose to Task Tasks
For each seam/component, create a task. Apply the full Task Anatomy format:
oro task create "<specific task>" \
--type task \
--parent <epic-id> \
--acceptance "Test: <path>:<FnName> | Cmd: <test_cmd> | Assert: <expected>
Read: <file1>:<Symbol1>, <file2>:<Symbol2>
Signature: <func signature if applicable>
Edges: <error conditions if applicable>" \
--estimate <minutes>
oro task dep add <epic-id> <child-id>
oro task create --parent does not add dependency edges. Keep the explicit oro task dep add <epic-id> <child-id> edge so the epic waits for its children to close.
Step 4: Rule of Five (Apply to Each Task)
Run all 5 passes (P1-P5) on every task before emitting. Revise until all pass.
Step 5: Size Test (Recursive)
Check every task against size heuristics. If too large, decompose:
- Promote:
oro task update <id> --type epic
- Create child tasks with
oro task create --parent <id>, then oro task dep add <id> <child> for each child the epic must wait for
- Re-apply size test + Rule of Five to children
Step 6: Wire Dependencies
oro task dep add <later-task> <earlier-task>
Common patterns:
- Types/interfaces before implementations
- Core logic before integration
- Setup/config before features
- Lower layers before higher layers
Step 7: Present Tree
oro task show <epic-id>
Present the full tree: epic → children, dependencies, estimates, acceptance criteria.
Proceed to execution automatically. Do not ask for confirmation — the user invoked decompose expecting action, not a gate.
Example Decomposition
Spec: "Add JWT authentication to the API"
Epic: Implement JWT authentication (oro-001)
├── Task: Define auth types and interfaces (oro-002, 5min)
│ Test: internal/auth/types_test.go:TestTokenClaims | Cmd: go test ./internal/auth/... | Assert: Claims struct has required fields
│ Read: internal/auth/types.go:TokenClaims
│ Signature: type TokenClaims struct { Sub string; Exp time.Time; Iss string }
├── Task: Implement token generation (oro-003, 7min, depends: oro-002)
│ Test: internal/auth/token_test.go:TestGenerateToken | Cmd: go test ./internal/auth/... -run TestGenerateToken | Assert: returns signed JWT with correct claims
│ Read: internal/auth/token.go:GenerateToken, internal/auth/types.go:TokenClaims
│ Signature: func GenerateToken(claims TokenClaims, secret []byte) (string, error)
│ Edges: nil secret → ErrNoSecret; expired claims → ErrExpiredClaims
├── Task: Implement token validation (oro-004, 7min, depends: oro-002)
│ Test: internal/auth/token_test.go:TestValidateToken | Cmd: go test ./internal/auth/... -run TestValidateToken | Assert: validates signature, expiry, issuer
│ Read: internal/auth/token.go:ValidateToken
│ Signature: func ValidateToken(tokenStr string, secret []byte) (*TokenClaims, error)
│ Edges: invalid signature → ErrInvalidSignature; expired → ErrExpired
├── Task: Add auth middleware (oro-005, 7min, depends: oro-003, oro-004)
│ Test: internal/middleware/auth_test.go:TestAuthMiddleware | Cmd: go test ./internal/middleware/... | Assert: rejects invalid tokens with 401, passes valid tokens
│ Read: internal/middleware/auth.go:AuthMiddleware, internal/auth/token.go:ValidateToken
│ Signature: func AuthMiddleware(secret []byte) func(http.Handler) http.Handler
└── Task: Wire middleware to routes (oro-006, 5min, depends: oro-005)
Test: internal/api/routes_test.go:TestProtectedRoutes | Cmd: go test ./internal/api/... | Assert: protected endpoints require valid JWT
Read: internal/api/routes.go:SetupRoutes
Mode: Create
For creating a single ad-hoc task with full quality applied.
Step 1: Gather Context
From the user request, extract:
- What needs to be done (title)
- Where in the codebase (files/packages)
- What type (task, bug, feature)
- Priority
Step 2: Draft Task
Write the full Task Anatomy:
- Title (single-purpose, imperative)
- Acceptance with all fields (Test, Cmd, Assert, Read, Signature, Edges)
- Estimate
- Dependencies (check
oro task list for related work)
Step 3: Rule of Five
Run all 5 passes. Revise until clean.
Step 4: Size Check
If too large → switch to Decompose mode.
Step 5: Create
oro task create "<title>" --type <type> --priority <0-4> \
--acceptance "<full anatomy>" \
--estimate <minutes>
Wire dependencies if needed:
oro task dep add <this-task> <depends-on>
Mode: Review
Audit existing tasks for quality issues.
Step 1: Gather Tasks
oro task list --status=open
oro task list --status=in_progress
Step 2: Audit Each Task
For each task, check against:
- Smell Catalog — flag any matching smells
- Task Anatomy — are required fields present?
- Rule of Five — would it pass all 5 passes?
- Size Heuristics — is it too large?
Step 3: Report
Present findings grouped by severity:
Critical (blocks execution):
- No acceptance criteria
- Oversized without decomposition
Warning (reduces quality):
- Missing
Read: field
- Vague title
- Missing estimate
Info (housekeeping):
- Stale in_progress
- Stale dependencies
Step 4: Fix
For each finding, suggest the fix command:
oro task update <id> --acceptance "Test: ... | Cmd: ... | Assert: ..."
oro task update <id> --type epic
oro task create "<child1>" --type task ...
oro task update <child1-id> --parent <id>
oro task dep add <id> <child1-id>
oro task dep rm <id> <stale-dep>
Red Flags
- Creating tasks without running Rule of Five
- Acceptance criteria that can't be verified by a command
- Tasks with estimates >7min that haven't been decomposed
- Missing dependencies (later task assumes earlier task's output)
- Vague titles like "implement feature" or "handle edge cases"
- Skipping
Read: field — workers waste time exploring
- Emitting tasks after only 1-2 Rule of Five passes