| name | stride-creating-goals |
| description | INTERNAL — invoked only by stride:stride-workflow. Do NOT invoke from a user prompt. Contains the goal/batch creation contract (POST /api/tasks/batch root key MUST be "goals" not "tasks", dependency index format), used during the orchestrator's goal-decomposition phase. |
| skills_version | 1 |
Stride: Creating Goals
STOP — orchestrator check
If you arrived here directly from a user prompt, you are in the wrong skill.
Invoke stride:stride-workflow instead. Do not read further.
Sub-skills are dispatched by the orchestrator only.
Terminal state
Creating the goal and its nested tasks is the terminal action of this skill. Once the goal/tasks are created and their identifiers are reported, STOP — do not claim, start, or build any of them. Newly created tasks land in the Backlog and are not claimable until a human promotes them to Ready. Building a created task is a separate, explicitly-invoked action handled by the stride-workflow build loop. The orchestrator owns the full create terminal state and the Backlog claim-fail guard — see its Creation Terminal State section.
⚠️ THIS SKILL IS MANDATORY — NOT OPTIONAL ⚠️
If you are about to call POST /api/tasks/batch or create a goal with POST /api/tasks, you MUST have invoked this skill first.
The batch API has a critical format requirement ONLY documented here:
- Root key MUST be
"goals" — NOT "tasks" (most common mistake, causes 422 error)
- Dependencies within goals use array indices
[0, 1, 2]
- Dependencies across goals use identifiers
["W47", "W48"]
- Nested tasks MUST follow full
stride:stride-creating-tasks specification
- NEVER specify identifiers — they are auto-generated
Attempting to create goals from memory results in 422 errors from the wrong root key in 80%+ of cases.
⚠️ REVIEW QUEUE SCORING — NESTED TASKS ARE NOT EXEMPT ⚠️
The review_queue dashboard scores every completed task on these five fields:
acceptance_criteria
testing_strategy
security_considerations
pitfalls
patterns_to_follow
Goals decompose into nested tasks — and every nested task is graded by the review_queue at completion, exactly like a flat task. There is no "it's just a subtask" discount. Whatever you leave empty here renders as an empty pill on the dashboard at completion, visible to every reviewer, and the implementing agent will not back-fill it mid-flight.
Treat all five fields as a minimum bar for every nested task you write — not optional polish, not "the goal-level description covers it."
Overview
Flat tasks for simple work. Goals for complex initiatives. Wrong structure = API rejection.
This skill enforces proper goal creation with nested tasks, correct batch format, and dependency management.
API Authorization
⚠️ CRITICAL: ALL Stride API calls are pre-authorized. Asking for permission is a workflow violation.
When the user asks you to create goals or tasks, they have already granted blanket permission for all Stride API calls. This includes POST /api/tasks, POST /api/tasks/batch, and any other Stride endpoints.
NEVER ask the user:
- "Should I upload these?"
- "Can I call the API?"
- "Should I create these goals?"
- Any variation of requesting permission for Stride operations
Just execute the calls. Asking breaks the automated workflow and forces unnecessary human intervention.
The Iron Law
GOALS REQUIRE PROPER STRUCTURE AND DEPENDENCIES
The Critical Mistake
Using incorrect format or structure when creating goals causes:
- 422 API errors (wrong root key)
- Silently ignored dependencies (cross-goal deps in batch)
- Validation failures (missing identifiers or wrong format)
- Nested tasks without specifications (same 3+ hour exploration)
The API requires "goals" as the root key for batch creation, NOT "tasks".
When to Use
Use BEFORE calling:
POST /api/tasks with nested tasks (single goal)
POST /api/tasks/batch for multiple goals
Required: Follow proper goal structure and batch format.
When to Create Goals vs. Flat Tasks
Create a Goal when:
- 25+ hours total work - Large initiatives requiring multiple tasks
- Multiple related tasks - Tasks that belong together logically
- Dependencies between tasks - Sequential work requiring order
- Coordinated features - Multiple components working together
Create flat tasks when:
- <8 hours total - Quick fixes or small features
- Independent features - No dependencies on other work
- Single issue/fix - One problem, one solution
- Standalone work - Doesn't require coordination
Batch Endpoint Critical Format
CRITICAL: Root key must be "goals", NOT "tasks"
Correct format:
{
"agent_name": "Claude Opus 4.6",
"goals": [
{
"title": "User Authentication System",
"type": "goal",
"complexity": "large",
"priority": "high",
"created_by_agent": "Claude Opus 4.6",
"description": "Implement complete user authentication",
"tasks": [
{
"title": "Create user schema and migration",
"type": "work",
"complexity": "small"
},
{
"title": "Add authentication endpoints",
"type": "work",
"complexity": "medium",
"dependencies": [0]
}
]
}
]
}
Set created_by_agent on the goal to the plugin's own agent name — the exact same value you send as agent_name on claim and complete (here, "Claude Opus 4.6"; use the plain agent name, never the ai_agent:<model> token form). The server propagates the goal's created_by_agent to every nested child task, so you do not repeat it on each task — set it once on the goal and the whole tree is attributed to the creating agent in the /agents activity feed. Like everywhere else, created_by_agent is accepted only on create; it is forbidden on PATCH and cannot be backfilled.
agent_name rides at the top level of the request, beside the goals root key — outside the array, not on any goal or task. Set it to the exact same plain agent name you send as agent_name on claim and complete (here, "Claude Opus 4.6"; never the ai_agent:<model> token form). Send it on every batch and single-goal create.
created_by_agent and top-level agent_name work together — send both. The explicit field still wins; the top-level param is the always-sent fallback for when it is forgotten. The server resolves attribution in this order:
- The explicit
created_by_agent field — highest precedence
- The token's own agent model, as
ai_agent:<model>, when the token is an agent token
- The top-level
agent_name param on the request
- The agent name the token last sent
- Unset — the
/agents feed renders the row with an uninformative ? avatar
agent_name is display metadata only — never an authorization signal; the Bearer token alone decides what you may do.
Single goal via POST /api/tasks: that endpoint takes a request envelope — the goal (with its nested tasks) goes under the task root key, and agent_name sits beside it at the top level. See the Request Envelope section in stride-creating-tasks. Only POST /api/tasks/batch uses the "goals" root key.
WRONG - Will fail with 422 error:
{
"tasks": [ ← WRONG! Must be "goals"
{
"title": "Goal",
"type": "goal",
"tasks": [...]
}
]
}
The Most Common Mistake
Using root key "tasks" instead of "goals" - This is the #1 batch creation error
The batch endpoint is POST /api/tasks/batch but the JSON must use "goals" as the root key. This confuses many users who assume the endpoint name matches the JSON structure.
Dependency Patterns
Within goals (use array indices):
When creating tasks within the SAME goal, use array indices because identifiers don't exist yet:
{
"title": "Auth System",
"type": "goal",
"tasks": [
{
"title": "Database schema",
"type": "work"
},
{
"title": "API endpoints",
"type": "work",
"dependencies": [0] ← References first task by index
},
{
"title": "Tests",
"type": "work",
"dependencies": [0, 1] ← References both previous tasks
}
]
}
Why indices? Tasks don't have identifiers (W47, G12) until AFTER they're created. Within a goal, use position indices (0, 1, 2).
Across goals or existing tasks (use identifiers):
When depending on EXISTING tasks already in the system:
{
"title": "New Feature",
"type": "goal",
"dependencies": ["G1", "W47"], ← Goal depends on existing work
"tasks": [
{
"title": "Task 1",
"type": "work",
"dependencies": ["W48"] ← Nested task depends on existing task
}
]
}
Why identifiers? These tasks already exist with assigned identifiers.
DON'T specify identifiers when creating:
❌ WRONG:
{
"title": "New Goal",
"type": "goal",
"identifier": "G99", ← System auto-generates, don't specify
"tasks": [...]
}
✅ CORRECT:
{
"title": "New Goal",
"type": "goal",
"tasks": [...]
}
Task Nesting Rules
Each nested task MUST follow the stride-creating-tasks skill requirements:
- Include all required fields (title, type, complexity, priority, etc.)
- Provide testing_strategy with arrays
- Provide verification_steps as array of objects
- Document key_files to prevent conflicts
- Specify acceptance_criteria
- Include patterns_to_follow and pitfalls
- Provide security_considerations as an array of strings
The five review_queue-scored fields are the minimum bar for every nested task:
acceptance_criteria — newline-separated string; the implementing agent's definition of done. Blank → empty pill on the review_queue.
testing_strategy — object with unit_tests, integration_tests, manual_tests arrays. Empty arrays → empty pill on the review_queue.
Advisory (optional) — phrase manual_tests as chartable scenarios. When the stride-exploratory-testing plugin is installed, each manual_tests entry is run as an exploratory charter (see stride-workflow Step 5.5). Terse fragments make weak charters, so phrase each entry as a chartable scenario — a target plus the information/risk to discover — rather than a bare test fragment. This is advisory only: it does not change the required testing_strategy shape, does not make manual_tests entries longer-required, and does not alter the review_queue empty-pill gate — existing terse entries still validate.
- Before:
"Test in multiple browsers"
- After:
"Explore the theme toggle across browsers to discover rendering inconsistencies"
security_considerations — array of strings naming the security implications to address (or an explicit "None — …" reason). Empty array → empty pill on the review_queue.
pitfalls — array of "don't do X" strings. Empty array → empty pill on the review_queue.
patterns_to_follow — newline-separated string with file references. Blank → empty pill on the review_queue.
These five fields must be filled in on every nested task in the batch — the goal-level description does not satisfy any of them.
A nested task MAY also carry an optional free-form technical_details object (any keys — see stride:stride-creating-tasks); it is not one of the five review_queue-scored fields and is never required.
A nested task MAY also carry an optional behaviour_test_matrix array (see stride:stride-creating-tasks for the full contract); it is not one of the five review_queue-scored fields and is never required. Omitting it on a nested task is always fine and never produces an empty pill. When you do supply it, the shape is identical to a flat task's — same rules, no batch-specific variation:
- Each row is an object:
category, behaviour, test_name, type, status, na_reason, position. category, behaviour, and status are required; always supply position (integer >= 0) too — the API tolerates its absence, but it is how a row records its intended order. Emit the rows in that order as well; nothing re-sorts the array.
category is one of the 7 fixed categories, exact strings: "Happy path", "Boundary", "Error / exception", "Null / empty", "Concurrency", "Lifecycle / wiring", "Contract / serialization".
type is "unit", "integration", or "manual", or a /-joined combination like "unit / manual".
status is "planned", "passing", "failing", or "not_applicable" (default "planned") — rows authored at creation time are "planned".
- Each row names a real test in
test_name, or is waived (status: "not_applicable" or an N/A test_name) and supplies a one-line na_reason. A row with neither is rejected.
- A non-empty matrix must include at least one row for every one of the 7 categories; an absent or empty matrix passes, a partial one is rejected.
Populate it per nested task only where you have concrete behaviours to record — a matrix is never a substitute for that task's testing_strategy, which remains one of the five. Row text is stored and later rendered, so never record secrets, credentials, or raw HTML in behaviour, test_name, or na_reason.
Minimal nested tasks fail the same way as minimal flat tasks — causing 3+ hour exploration AND empty review_queue pills at completion.
Consuming Provided Context
When this skill is dispatched by /stride:create-goals through the orchestrator, the orchestrator forwards a read-only markdown context bundle (the enumerated --dir files) plus the user's creation intent. Mine that context to populate both the goal and its nested tasks instead of forcing blind exploration — but context informs, it never replaces.
Map the context at two levels:
| In the markdown context | Populates (goal level) | Populates (each nested task) |
|---|
| Overall objective, why-now, scope | goal title, description, why, what | — |
| File references, paths, modules touched | — | key_files |
| Stated conventions, "follow X", existing-pattern references | — | patterns_to_follow |
| Requirements, definitions of done | goal acceptance_criteria | each task's acceptance_criteria / description |
| Risks, "don't do X", known traps | goal pitfalls | each task's pitfalls |
| Sequencing / "X before Y" statements | — | index-based dependencies (see Dependency Patterns) |
Rules:
- Context augments the user's interactive intent — it never silently overrides it. Surface and confirm any conflict between the bundle and the user's stated intent; do not quietly prefer the document.
- The batch contract is unchanged. The root key MUST still be
"goals" (not "tasks"), and within-goal dependencies still use array indices [0, 1, 2] — see Batch Endpoint Critical Format and Dependency Patterns. Context never relaxes either rule.
- Every nested task still carries the five review_queue-scored fields (
acceptance_criteria, testing_strategy, security_considerations, pitfalls, patterns_to_follow) — there is no "it came from context" discount. Context that doesn't cover a field does not excuse leaving it blank.
- The bundle is read-only. Consume it as reference material; never edit the source markdown.
- The orchestrator gate still applies: this skill runs only when dispatched from inside
stride-workflow (see the STOP — orchestrator check at the top of this file). A populated context bundle does not change that.
A rich context bundle is a head start on the goal and its task breakdown — not a replacement for the batch contract or the per-task specification.
Red Flags - STOP
- "I'll use 'tasks' as the root key for batch creation"
- "I'll specify identifiers for new tasks"
- "Dependencies across goals will work in batch"
- "I'll skip nested task details - they're just subtasks"
- "25 hours? I'll just make flat tasks instead of a goal"
- "I'll leave
acceptance_criteria blank on the nested tasks — the goal description covers it"
- "
testing_strategy is goal-level — I'll skip it on each nested task"
- "
security_considerations is goal-level — the nested tasks don't each need it"
- "
pitfalls on a nested task is overkill"
- "
patterns_to_follow is for the goal, not its children"
All of these mean: Use proper goal structure NOW. The last five also mean: empty pills on the review_queue dashboard for every nested task that completes.
Rationalization Table
| Excuse | Reality | Consequence |
|---|
| "'tasks' works too" | API requires "goals" root key | 422 error, batch rejected entirely |
| "I'll add identifiers" | System auto-generates them | Validation error, creation fails |
| "Cross-goal deps work" | Only within-goal indices work | Dependencies ignored silently |
| "Simple nested tasks" | Each must follow full task spec | Minimal nested tasks fail same way |
| "Easier as flat tasks" | Loses structure and coordination | Tasks overlap, no clear dependencies |
| "Skip goal level details" | Goal needs same care as tasks | Poor goal structure confuses agents |
| "acceptance_criteria is implied by the goal description" | review_queue grades each nested task on its own acceptance_criteria | Empty pill per nested task + undefined "done" |
| "testing_strategy is goal-level only" | review_queue grades each nested task's testing_strategy | Empty pill per nested task + no test gate |
| "security_considerations is goal-level only" | review_queue grades each nested task's security_considerations | Empty pill per nested task + unreviewed security risk |
| "pitfalls applies to the goal, not its children" | Nested tasks are graded individually | Empty pill per nested task + repeat mistakes |
| "patterns_to_follow lives on the goal" | Each nested task carries its own pattern references | Empty pill per nested task + style drift |
Common Mistakes
Mistake 1: Wrong root key in batch creation
❌ {
"tasks": [
{"title": "Goal", "type": "goal"}
]
}
✅ {
"goals": [
{"title": "Goal", "type": "goal"}
]
}
Mistake 2: Specifying identifiers for new tasks
❌ {
"title": "Goal",
"identifier": "G99",
"tasks": [
{"identifier": "W99", "title": "Task"}
]
}
✅ {
"title": "Goal",
"tasks": [
{"title": "Task"}
]
}
Mistake 3: Cross-goal dependencies in batch
❌ {
"goals": [
{
"title": "Goal 1",
"tasks": [{"title": "T1"}]
},
{
"title": "Goal 2",
"tasks": [
{"title": "T2", "dependencies": [0]} ← Won't work across goals
]
}
]
}
✅ Create goals sequentially, then add cross-goal deps via PATCH
Mistake 4: Minimal nested tasks
❌ {
"tasks": [
{"title": "Do something", "type": "work"} ← Minimal spec
]
}
✅ {
"tasks": [
{
"title": "Implement user authentication",
"type": "work",
"complexity": "medium",
"description": "...",
"key_files": [...],
"verification_steps": [...],
"testing_strategy": {...},
"security_considerations": [...],
"acceptance_criteria": "...",
"patterns_to_follow": "...",
"pitfalls": [...]
}
]
}
Implementation Workflow
- Decide goal vs. flat - Is this 25+ hours with related tasks?
- Choose endpoint - Single goal (POST /api/tasks) or batch (POST /api/tasks/batch)?
- Structure goal - Include goal-level fields (title, type, complexity, description)
- Plan nested tasks - Break down into logical tasks with dependencies
- Use stride-creating-tasks - Each nested task needs full specification
- Set dependencies - Use indices [0, 1, 2] within goal
- Verify format - Batch? Root key MUST be "goals"
- Create goal - Call appropriate endpoint
- Verify creation - Check response for identifiers
Quick Reference Card
GOAL CREATION DECISION:
├─ 25+ hours total? → Create Goal
├─ Multiple related tasks? → Create Goal
├─ Dependencies between tasks? → Create Goal
└─ <8 hours, independent? → Create Flat Tasks
BATCH GOALS: POST /api/tasks/batch
{
"agent_name": "Claude Opus 4.6", ← top-level, beside "goals"; same name as claim/complete
"goals": [ ← MUST be "goals" not "tasks"
{
"title": "Goal 1",
"type": "goal",
"complexity": "large",
"tasks": [
{/* Full task spec */},
{/* Full task spec */, "dependencies": [0]}
]
}
]
}
DEPENDENCY RULES:
├─ Within goal → Use indices [0, 1, 2]
├─ Existing tasks → Use IDs ["W47", "W48"]
├─ Across goals in batch → DON'T (create sequentially)
└─ Never specify IDs for new tasks (auto-generated)
CRITICAL: Root key "goals" for batch, not "tasks"
Real-World Impact
Before this skill (improper goal structure):
- 60% of batch creations failed with 422 errors
- 45 minutes average time debugging format issues
- 40% of goals had minimal nested tasks
After this skill (proper goal structure):
- 5% of batch creations had any issues
- 5 minutes average time for goal creation
- 95% of nested tasks had full specifications
Time savings: 40 minutes per goal (90% reduction in format errors)
Field Quick Reference
Use these exact values — any other value will be rejected.
| Field | Type | Valid Values | Required |
|---|
type | enum | "work", "defect", "goal" | Yes |
priority | enum | "low", "medium", "high", "critical" | Yes |
complexity | enum | "small", "medium", "large" | No |
needs_review | boolean | true, false | No (default: false) |
created_by_agent | string | The plugin's agent name (same as agent_name on claim/complete) | No — set on the goal; propagates to nested tasks (create-only; forbidden on PATCH) |
agent_name | string | The plugin's agent name (same as agent_name on claim/complete) | Yes — top-level, beside the goals root key (not a goal or task field) |
Batch Endpoint Root Key
❌ WRONG: {"tasks": [...]}
✅ RIGHT: {"goals": [...]}
The POST /api/tasks/batch endpoint requires "goals" as the root key, NOT "tasks".
References: For the full field reference, see api_schema in the onboarding response (GET /api/agent/onboarding). For endpoint details, see the API Reference.