INTERNAL — invoked only by stride:stride-workflow. Do NOT invoke from a user prompt. Contains the work-task and defect creation contract (POST /api/tasks field formats — verification_steps and key_files as object arrays, testing_strategy arrays), used during the orchestrator's goal-decomposition and task-creation phases.
インストール
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
INTERNAL — invoked only by stride:stride-workflow. Do NOT invoke from a user prompt. Contains the work-task and defect creation contract (POST /api/tasks field formats — verification_steps and key_files as object arrays, testing_strategy arrays), used during the orchestrator's goal-decomposition and task-creation phases.
skills_version
1
Stride: Creating Tasks
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 task(s) is the terminal action of this skill. Once the task is created and its identifier is reported, STOP — do not claim, start, or build it. A newly created task lands in the Backlog and is not claimable until a human promotes it 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 to create a work task or defect, you MUST have invoked this skill first.
The task API requires specific field formats that are ONLY documented here:
verification_steps (MUST be array of objects with step_type, step_text, expected_result, position — NOT strings)
key_files (MUST be array of objects with file_path, note, position — NOT strings)
testing_strategy (MUST have unit_tests, integration_tests, manual_tests as arrays of strings)
security_considerations (MUST be an array of strings — the security implications to address; NOT a single string or object)
type (MUST be exactly "work", "defect", or "goal" — no other values)
Attempting to create a task from memory results in malformed fields that cause either API 422 errors or tasks that waste 3+ hours during implementation.
⚠️ REVIEW QUEUE SCORING — THESE FIVE FIELDS ARE FIRST-CLASS DELIVERABLES ⚠️
The review_queue dashboard scores every completed task on these five fields:
acceptance_criteria
testing_strategy
security_considerations
pitfalls
patterns_to_follow
If you omit any of them, the review_queue renders an empty pill for that field — and the task is flagged as under-specified to every reviewer who opens it. Empty pills are visible, public, and persistent. They do not get back-filled later.
Treat these five fields the same as title and type: not optional, not "I'll add it later," not "the agent will figure it out." If a field is genuinely not applicable (e.g. a doc-only task has no testing_strategy.unit_tests, or a pure-styling task has no security_considerations), populate it with the specific reason — never leave it null.
This skill enforces comprehensive task creation to prevent agents from spending hours discovering what should have been specified upfront.
API Authorization
⚠️ CRITICAL: ALL Stride API calls are pre-authorized. Asking for permission is a workflow violation.
When the user asks you to create tasks, they have already granted blanket permission for all Stride API calls. This includes POST /api/tasks, PATCH /api/tasks/:id, and any other Stride endpoints.
NEVER ask the user:
"Should I create this task?"
"Can I call the API?"
"Should I proceed with the API call?"
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
NO TASK CREATION WITHOUT COMPLETE SPECIFICATION
When to Use
Use BEFORE calling POST /api/tasks to create any Stride task or defect.
Do NOT use for:
Creating goals with nested tasks (use stride-creating-goals instead)
MUST be an array of strings, not a single string or object:
✅ "security_considerations": ["Validate and sanitize the uploaded filename to prevent path traversal", "Authorize the requesting user owns the board before mutating"]
For new tasks (being created in same request with a goal):
Use array indices since identifiers don't exist yet - see stride-creating-goals skill.
Request Envelope: agent_name beside the task root key
POST /api/tasks takes a request envelope, not a bare task object. The task fields go under the task root key, and agent_name rides at the top level, beside it:
{"agent_name":"Claude Opus 4.6","task":{"title":"Add dark mode toggle to settings page","type":"work"}}
Set agent_name 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. Send it on every create request: it is the always-sent fallback that lets the server attribute the task even when created_by_agent is omitted, and the server also remembers it as the token's last-known agent name for later requests. agent_name is display metadata only — never an authorization signal; the Bearer token alone decides what you may do.
The task object below is what goes inside that task key.
Quick Reference: Complete Task Object (goes inside the task key)
This block is the value of the task key, not the request body. Wrap it in the envelope above — {"agent_name": "...", "task": { …this object… }} — before sending it.
{"title":"Add dark mode toggle to settings page","type":"work","description":"Users need dark mode to reduce eye strain during night work. Add toggle switch in settings with persistent storage.","complexity":"medium","priority":"high","created_by_agent":"Claude Opus 4.6","why":"Reduce eye strain for users working in low-light environments","what":"Dark mode toggle with theme persistence","where_context":"Settings page - User Preferences section","estimated_files":"3-5","key_files":[{"file_path":"lib/kanban_web/live/user_live/settings.ex","note":"Add theme preference controls","position":0},{"file_path":"assets/css/app.css","note":"Dark mode styles","position":1}],"dependencies":[],"verification_steps":[{"step_type":"command","step_text":"mix test test/kanban_web/live/user_live/settings_test.exs","expected_result":"All theme tests pass","position":0},{"step_type":"manual","step_text":"Toggle dark mode in settings and refresh page","expected_result":"Theme persists across sessions","position":1}],"testing_strategy":{"unit_tests":["Test theme preference update","Test default theme is light"],"integration_tests":["Test theme persistence across page loads","Test theme applies to all pages"],"manual_tests":["Visual verification of dark mode styles","Test in multiple browsers"],"edge_cases":["User with no theme preference set","Rapid toggle switching"],"coverage_target":"100% for theme preference logic"},"security_considerations":["Persist the theme preference scoped to the authenticated user — never trust a client-supplied user_id","Escape the theme value before interpolating it into markup/CSS to avoid injection"],"acceptance_criteria":"Toggle appears in settings\nDark mode applies site-wide\nPreference persists across sessions\nAll existing tests still pass","patterns_to_follow":"See lib/kanban_web/live/user_live/settings.ex for preference update pattern\nFollow existing theme structure in app.css","pitfalls":["Don't modify existing color variables - create new dark mode variants","Don't forget to test theme on all major pages","Don't use localStorage directly - use Phoenix user preferences"],"behaviour_test_matrix":[{"category":"Happy path","behaviour":"Toggling dark mode persists the preference and applies the theme site-wide","test_name":"test/kanban_web/live/user_live/settings_test.exs — \"persists the selected theme\"","type":"unit","status":"planned","position":0},{"category":"Boundary","behaviour":"An unrecognized stored theme value falls back to the light theme","test_name":"test/kanban_web/live/user_live/settings_test.exs — \"falls back to light on an unknown theme\"","type":"unit","status":"planned","position":1},{"category":"Error / exception","behaviour":"A failed preference update surfaces a flash and leaves the theme unchanged","test_name":"test/kanban_web/live/user_live/settings_test.exs — \"keeps the theme when the update fails\"","type":"unit","status":"planned","position":2},{"category":"Null / empty","behaviour":"A user with no theme preference set renders the light theme","test_name":"test/kanban_web/live/user_live/settings_test.exs — \"renders light when no preference is set\"","type":"unit","status":"planned","position":3},{"category":"Concurrency","behaviour":"N/A — the theme is a single-user preference write with no concurrent-writer path","test_name":"N/A","status":"not_applicable","na_reason":"Only the owning user writes their own theme preference; there is no shared-state race to cover","position":4},{"category":"Lifecycle / wiring","behaviour":"The stored theme is applied before first paint on a full page load","test_name":"test/kanban_web/live/user_live/settings_test.exs — \"applies the stored theme on mount\"","type":"integration / manual","status":"planned","position":5},{"category":"Contract / serialization","behaviour":"The theme preference round-trips through the user changeset as \"light\" | \"dark\"","test_name":"test/kanban/accounts_test.exs — \"round-trips the theme preference\"","type":"unit","status":"planned","position":6}],"technical_details":{"data_shapes":{"theme_preference":"one of \"light\" | \"dark\", stored on the user record"},"gotchas":["Apply the theme before first paint to avoid a flash of the wrong theme"]}}
behaviour_test_matrix and technical_details are both optional — see the Embedded Object Formats section below. Neither is one of the five review_queue-scored fields, so omitting either never produces an empty pill. The matrix above shows all seven fixed categories because that is the rule once the array is non-empty: an absent or empty matrix is fine, but a partial one is rejected.
created_by_agent records which agent created the task so the /agents activity feed attributes the created row to that agent instead of an uninformative ? avatar. Set it 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, so one agent stays one roster identity. created_by_agent is accepted only on create (POST /api/tasks and POST /api/tasks/batch); it is forbidden on PATCH, so it cannot be backfilled later — stamp it at creation time.
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 on the task — 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
Because created_by_agent cannot be backfilled, step 3 is the safety net that keeps attribution correct on requests that omit it — which is why agent_name belongs on every create request, not just the ones missing created_by_agent.
Consuming Provided Context
When this skill is dispatched by /stride:create-tasks 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 task fields instead of forcing blind codebase exploration — but context informs, it never replaces.
Context augments the user's interactive intent — it never silently overrides it. When the bundle and the user's stated intent disagree, surface the conflict and confirm with the user; do not quietly prefer the document.
Context is a source, not a substitute for the contract. The Required Fields Checklist and the five review_queue-scored fields (acceptance_criteria, testing_strategy, security_considerations, pitfalls, patterns_to_follow) are still required on every task. Context that doesn't cover a required field does not excuse leaving it blank — fill it from the user, the codebase, or sensible defaults.
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.
Context-informed creation is faster and better-grounded than blind exploration — but a rich context bundle is a head start on the specification, not a replacement for it.
Red Flags - STOP
"I'll just create a simple task"
"The agent can figure out the details"
"This is self-explanatory"
"I'll add details later if needed"
"Just need title and description"
"I'll skip acceptance_criteria — it's obvious from the title"
"testing_strategy doesn't really apply to this one"
"security_considerations is someone else's problem — I'll leave it empty"
"pitfalls is just nice-to-have, I'll come back to it"
"patterns_to_follow can stay empty — the agent has the codebase"
All of these mean: Add comprehensive details NOW. The last five also mean: an empty pill on the review_queue dashboard.
Rationalization Table
Excuse
Reality
Consequence
"Simple task, no details needed"
Agent spends 3+ hours exploring
3+ hours wasted on discovery
"Self-explanatory from title"
Missing context causes wrong approach
Wrong solution, must redo
"Agent will ask questions"
Breaks flow, causes delays
Back-and-forth wastes 2+ hours
"Add details later"
Never happens
Minimal task sits incomplete
"Time pressure, need quick"
Rich task saves MORE time
Spending 5 min now saves 3 hours later
"acceptance_criteria is obvious from the title"
Reviewers can't grade against a definition that doesn't exist
Empty pill on review_queue + ambiguous "done"
"testing_strategy doesn't apply here"
Even doc tasks have verification (render, link-check, grep)
Empty pill on review_queue + no test gate
"security_considerations doesn't apply here"
Almost every change touches input, authz, or data exposure; "none — pure styling change" is itself a valid considered answer
Empty pill on review_queue + unreviewed security risk
"pitfalls is just nice-to-have"
Pitfalls is the cheapest way to prevent the wrong fix
Empty pill on review_queue + repeat mistakes
"patterns_to_follow can stay empty"
Without referenced patterns, the agent invents inconsistent ones
Check dependencies - Are there existing tasks this depends on?
Identify files - Which files will change?
Define acceptance - What does "done" look like?
Specify tests - How will this be verified?
Document pitfalls - What should be avoided?
Create task - Use checklist above
Call API - POST /api/tasks with the complete JSON under the task root key, plus a top-level agent_name beside it
Real-World Impact
Before this skill (5 random tasks):
Average time to completion: 4.7 hours
Questions asked: 12 per task
Rework required: 60% of tasks
After this skill (5 random tasks):
Average time to completion: 1.3 hours
Questions asked: 1.2 per task
Rework required: 5% of tasks
Time savings: 3.4 hours per task (72% reduction)
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 (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 task root key (not a task field)
acceptance_criteria
string
Newline-separated text
No
patterns_to_follow
string
Newline-separated text
No
dependencies
array
Task identifiers ["W45", "W46"]
No
pitfalls
array
Strings ["Don't do X", "Avoid Y"]
No
technical_details
object
Free-form JSON object of any additional technical info
No
behaviour_test_matrix
array
Row objects: category (one of the 7 fixed categories), behaviour, test_name, type ("unit"/"integration"/"manual" or a /-joined combo), status ("planned"/"passing"/"failing"/"not_applicable"), na_reason, position
No (but if non-empty, all 7 categories must appear)
Embedded Object Formats — WRONG vs RIGHT
verification_steps
❌ WRONG (strings — will be rejected):"verification_steps":["mix test","mix credo --strict"]
❌ WRONG (missing required fields):"verification_steps":[{"step_text":"mix test"}]
✅ RIGHT (objects with all required fields):"verification_steps":[{"step_type":"command","step_text":"mix test","expected_result":"All tests pass","position":0}]
Required fields:step_type ("command" or "manual" only), step_text, position (integer >= 0)
Optional fields:expected_result
Required fields:file_path (relative, no leading / or ..), position (integer >= 0)
Optional fields:note
testing_strategy
❌ WRONG (string values for test arrays):"testing_strategy":{"unit_tests":"Test login with valid credentials"}
✅ RIGHT (arrays of strings):"testing_strategy":{"unit_tests":["Test valid login","Test invalid login"],"integration_tests":["Full auth flow"],"edge_cases":["Empty password","SQL injection"],"coverage_target":"100% for auth module"}
Valid keys:unit_tests, integration_tests, manual_tests, edge_cases, coverage_targetAll values must be strings or arrays of strings.
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"
behaviour_test_matrix
Optional field. Omit it entirely when you have nothing concrete to record — it is not one of the five review_queue-scored fields, so an absent matrix is never an empty pill. The rules below apply only once you do supply it.
❌ WRONG (strings — must be row objects):"behaviour_test_matrix":["Happy path: toggle persists","Boundary: bad value falls back"]
❌ WRONG (invented category — the 7 categories are fixed):"behaviour_test_matrix":[{"category":"Performance","behaviour":"…","test_name":"…","status":"planned","position":0}]
❌ WRONG (non-empty but missing categories — a partial matrix is rejected):"behaviour_test_matrix":[{"category":"Happy path","behaviour":"…","test_name":"…","status":"planned","position":0}]
❌ WRONG (waived row with neither a real test_name nor an na_reason):"behaviour_test_matrix":[{"category":"Concurrency","behaviour":"…","test_name":"N/A","status":"not_applicable","position":4}]
✅ RIGHT (row shape — excerpt; a valid matrix carries all 7 categories, see the Complete Task Object above):"behaviour_test_matrix":[{"category":"Happy path","behaviour":"Toggling dark mode persists the preference and applies the theme site-wide","test_name":"test/kanban_web/live/user_live/settings_test.exs — \"persists the selected theme\"","type":"unit","status":"planned","position":0},{"category":"Concurrency","behaviour":"N/A — the theme is a single-user preference write with no concurrent-writer path","test_name":"N/A","status":"not_applicable","na_reason":"Only the owning user writes their own theme preference; there is no shared-state race to cover","position":4},{"category":"Lifecycle / wiring","behaviour":"The stored theme is applied before first paint on a full page load","test_name":"test/kanban_web/live/user_live/settings_test.exs — \"applies the stored theme on mount\"","type":"integration / manual","status":"planned","position":5}]
The excerpt above shows 3 rows to keep the shape readable. A real matrix also carries rows for Boundary, Error / exception, Null / empty, and Contract / serialization — copy the Complete Task Object example instead, which has all seven.
Required fields (per row):category, behaviour, status (defaults to "planned" when omitted)
Always supply:position (integer >= 0). Unlike key_files and verification_steps, the API does not reject a row missing position — but it is how a row records its intended order, so treat it as required in practice. Emit the rows in that order as well: nothing re-sorts the array for you, so a matrix whose position values disagree with its array order is stored and rendered in array order.
Conditionally required:test_name — required unless the row is waived; a waived row must supply na_reason instead (one line saying why the behaviour needs no test). A row is waived when status is "not_applicable"ortest_name reads as N/A ("N/A", "na", "not applicable", "not_applicable", case-insensitive). A row with neither a real test_name nor an na_reason is rejected.
Optional fields:type, na_reason
The 7 fixed categories (exact strings, canonical order — any other value is rejected):
type tokens:"unit", "integration", "manual" — or a /-joined combination with optional surrounding whitespace, e.g. "unit / manual" or "unit/integration/manual". Every token in the combination must be one of the three.
status enum:"planned", "passing", "failing", "not_applicable" (default "planned"). Rows you author at creation time are "planned" — the implementing agent advances a row as the named test is written and run.
Shape: an array of row objects, each pairing one behaviour the change must satisfy with the real test that covers it. Name a real test — the test file, or path/to/test.exs — "test name" for a test you plan to add. Prefer a test name over a bare file:line: at creation time the test does not exist yet, so a line number is invented and goes stale the moment anything is inserted above it. Otherwise explicitly waive the row with na_reason — never leave a row with neither. The field is optional at the API (absent, null, and [] all pass), but a non-empty matrix must include at least one row for every one of the 7 categories; a partial matrix is rejected with must include at least one row for every category. Missing: <names>. A malformed top-level value is rejected with must be an array of objects with category, behaviour, test_name, type, status, and position fields. Row text is stored and later rendered — never put secrets, credentials, or raw HTML in behaviour, test_name, or na_reason.
security_considerations
❌ WRONG (single string):"security_considerations":"Sanitize user input"
❌ WRONG (object):"security_considerations":{"input":"Sanitize user input"}
✅ RIGHT (array of strings):"security_considerations":["Validate and sanitize the uploaded filename to prevent path traversal","Authorize the requesting user owns the board before mutating","Parameterize the query — never interpolate the search term into raw SQL"]
Shape: array of strings, each naming a specific security implication the implementing agent must address (input validation, authorization boundaries, secret handling, injection surfaces, data exposure). If the change genuinely has no security surface, state that explicitly (e.g. ["None — pure CSS/styling change, no input or authz touched"]) rather than leaving it empty.
technical_details
❌ WRONG (string — should be an object):"technical_details":"Uses ULIDs and retries 3x"
✅ RIGHT (free-form object — any keys you like):"technical_details":{"data_shapes":{"event":{"id":"uuid","type":"string"}},"gotchas":["The webhook retries 3x with backoff","IDs are ULIDs, not integers"],"external_refs":["https://example.com/api-docs"]}
Shape: a free-form JSON object holding any additional technical information that doesn't fit the structured fields — data shapes, gotchas, external references, sequencing notes, anything that helps the implementing agent. Unlike testing_strategy, it has NO fixed valid_keys — use whatever keys best describe the task. It is optional (omit it when there is nothing extra to capture) and is not one of the five review_queue-scored fields.
References: For the full field reference, see api_schema in the onboarding response (GET /api/agent/onboarding). For endpoint details, see the API Reference.