Install
$ agentstack add skill-michelkerkmeester-skilled-harness-spec-driven-agent-loops-sk-create-command ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Create Command
create-command is the command-authoring workflow packet of the sk-doc parent hub. It creates and improves OpenCode slash commands under .opencode/commands/ with executable workflows, precise frontmatter, required input gates, least-privilege tools, and router/presentation separation when needed.
This SKILL.md contains the core creation workflow. Use the references/ route map (references/README.md), assets/command-template.md, assets/command-router-template.md, assets/command-presentation-template.md, and ../shared/ only for exhaustive examples, edge cases, and validator implementation detail.
This packet is lean and self-contained. The advisor identity lives at the sk-doc hub root; do not add packet-local graph-metadata.json.
1. WHEN TO USE
Activation Triggers
Use this packet when the request involves:
- Creating a new OpenCode slash command.
- Refactoring a command into a thin router plus owned presentation asset.
- Adding or fixing command frontmatter, especially
argument-hintandallowed-tools. - Designing command argument handling with
$ARGUMENTS. - Authoring a namespace command such as
/namespace:action. - Separating visible prompts, dashboards, result templates, or next-step wording into a presentation contract.
- Checking whether a workflow should be a command instead of a skill, agent, or one-off task.
Keyword triggers: create command, /create:command, slash command, OpenCode command, argument-hint, allowed-tools, command template, router presentation split, thin router, presentation contract, paired /create, $ARGUMENTS.
When NOT to Use
Use another sk-doc packet when:
- The request is to create a skill or parent hub. Use
create-skill. - The request is to create an agent. Use
create-agent. - The task is a README, install guide, feature catalog, manual testing playbook, benchmark package, flowchart, or changelog. Use
create-readme,create-feature-catalog,create-manual-testing-playbook,create-benchmark,create-flowchart, orcreate-changelog. - The task audits, validates, scores, or optimizes an existing command document. Use
create-quality-control. - The task is one-time work that does not need a reusable slash command.
- The command already exists and the user only wants runtime debugging.
- The requested workflow is destructive or externally privileged but lacks confirmation and rollback requirements.
2. SMART ROUTING
These triggers route a request into this command-authoring packet. Execution-mode suffixes are command syntax, not packet-selection triggers. When the surface is a slash command, stay in this packet and continue to the creation workflow below.
Router Resilience
This packet routes by command-authoring intent and the requested component surface. It does not use runtime keyed resource discovery through references// because its references are flat.
- Load optional markdown resources only after resolving them under this packet and confirming they exist.
- Treat
references/README.mdas the fallback route map when command intent or component surface is unclear. - Ask for the missing command purpose, invocation shape, or component type instead of silently loading no resources.
- Do not add a full
references//orassets//runtime-key router unless this packet gains real keyed resource subdirectories.
Resource Loading Sequence
The packet keeps its existing flat-resource routing while using the shared resilience call sequence:
def discover_markdown_resources():
return flat markdown resources under this packet's `references/` and `assets/` folders
def _guard_in_skill(relative_path):
# Keep packet-local markdown paths in scope; retain explicitly documented shared routes.
confirm the path is an allowed markdown resource for this packet
def load_if_available(relative_path, inventory, seen):
guarded = _guard_in_skill(relative_path)
if guarded in inventory and guarded not in seen:
load(guarded)
seen.add(guarded)
def route_create_command_request(request):
inventory = discover_markdown_resources()
intents = score_intents(request) # command-authoring intent and component surface
selected = select_intents(intents)
routing_key = get_routing_key(request, selected)
if not selected or the command purpose or component surface is unclear:
load_if_available("references/README.md", inventory, seen)
return UNKNOWN_FALLBACK
return route by the existing command-authoring intent and component-surface rules
UNKNOWN_FALLBACK asks for the command purpose, invocation shape, or component type. The sequence discovers the current flat resources at routing time, guards and loads only available resources without duplicates, then applies the activation triggers and command-type rules already defined below.
3. HOW IT WORKS: CREATION WORKFLOW
Follow these steps in order.
Step 1: Decide Whether A Command Is Correct
Create a command only when the workflow is repeatable and has defined steps.
Use a command when the workflow:
- Automates a multi-step process.
- Needs repeatable execution across sessions.
- Needs
$ARGUMENTSparsing or mode routing. - Needs user-controlled execution pace such as
:autoor:confirm. - Needs confirmation gates for destructive or privileged actions.
- Benefits from explicit tool restrictions.
Use a skill instead when the content is reusable reference knowledge, domain guidance, standards, or patterns shared by multiple workflows. Do not create a command for one-off work.
Step 2: Resolve Invocation And Path
Determine the command invocation before writing:
- Root command:
.opencode/commands/.mdbecomes/. - Namespace command:
.opencode/commands//.mdbecomes/:. - Namespace and action names use lowercase hyphen-case.
- Each command, namespace and action segment matches
^[a-z0-9]+(?:-[a-z0-9]+)*$. Reject underscores, empty segments and ambiguous normalization; the emitted.mdstem must equal the validated action name.
For grouped related actions, prefer a namespace directory:
.opencode/commands/
└── /
├── .md
├── .md
└── .md
Step 3: Read Existing Files First
Before editing an existing command or owned asset, read it completely enough to understand current behavior. Preserve behavior unless the user explicitly asks to change it.
For new commands, inspect nearby commands in the same namespace when available so structure and vocabulary match the command family.
Step 4: Classify The Command Type
Choose the smallest command type that fits:
| Type | Use When | Typical Shape | | --- | --- | --- | | Simple | Single action, few arguments | One .md file, direct steps | | Workflow | Multi-step process with checkpoints | One .md file with overview, instructions, recovery | | Mode-based | Supports :auto / :confirm | Thin router plus owned assets when complex | | Router | Thin dispatcher: verify agent, resolve mode/args, hand off to owned assets | Router .md plus owned presentation .txt and optional workflow YAML or scripts | | Argument dispatch | Multiple action keywords or query forms | ASCII routing tree plus handlers | | Destructive | Deletes data or irreversible changes | Explicit confirmation, affected-state display, recovery guidance | | Namespace | Related commands grouped together | Directory under .opencode/commands/ |
If the command combines patterns, parse mode first, then dispatch remaining arguments.
Step 5: Choose The Output Package Shape
For a simple or medium command, create or update:
.opencode/commands/.md
For a namespace command, create or update:
.opencode/commands//.md
For a split mode-based workflow command, create or update:
.opencode/commands//.md
.opencode/commands//assets/__presentation.txt
.opencode/commands//assets/__auto.yaml
.opencode/commands//assets/__confirm.yaml
Use _auto.yaml and _confirm.yaml only for workflow-backed families that route execution into workflow assets. Direct-router families dispatch directly to tools/scripts and do not need workflow YAML.
For a compiled-stub router, the .md is a generated thin stub carrying the render-command-contract marker; its section shape is rendered from a compiled source at invocation, not authored in the file. Do not hand-write section headings into a compiled stub, and keep its owned presentation/workflow assets alongside it:
.opencode/commands//.md # compiled stub (render-command-contract marker)
.opencode/commands//assets/__presentation.txt
Step 6: Author Frontmatter First
Every command starts with YAML frontmatter.
Required:
---
description: Action-oriented single-line description
---
Recommended when applicable:
argument-hint: " [optional] [--flag]"
allowed-tools: Read, Write, Edit, Bash
Rules:
- Keep
descriptionsingle-line, action-oriented, and concise. - Target descriptions at or under 110 characters.
- Do not use YAML block scalars for
description. - Use
argument-hintwhenever the command expects user input. - Use `` only for required arguments.
- Use
[square-brackets]for optional arguments. - Keep
argument-hintat or under 140 characters: the hint summarizes the invocation shape while the router's EXECUTION TARGETS section enumerates the full flag surface. Over-budget hints warn (never block); move the exhaustive flag list into the router body. - List every tool the command actually uses in
allowed-tools. - Do not add broad tools just in case.
- For MCP tools in
allowed-tools, use fully qualified names such asmcp____. - Bare tool names such as
memory_contextbelong in prose only, notallowed-tools.
Step 7: Add Mandatory Input Gates
If argument-hint contains any required ``, add the mandatory gate immediately after frontmatter, before all other content.
The gate must:
- Check whether
$ARGUMENTSis empty, undefined, or whitespace-only. - Ignore mode suffixes when determining whether required content exists.
- Stop immediately when required input is missing.
- Ask a context-specific question with clear options or expected reply format.
- Wait for the user response.
- Use only
$ARGUMENTSor the user's explicit answer as the input. - Forbid inference from context, screenshots, conversation history, or open files.
For multi-input commands, use a blocking phase pattern:
- Phase 1: input collection.
- Phase 2: prerequisite/context verification.
- Phase status verification table.
- Violation self-detection block.
Every workflow command with blocking phases must include violation self-detection: if a required phase was skipped, stop, state the violation, return to the phase, and complete it properly.
Step 8: Write The Command Body
Use executable, instruction-oriented sections. Commands are workflows, not long reference manuals.
Common section order:
- Title and purpose.
- Contract.
- Workflow overview or argument routing.
- Instructions.
- Failure recovery and error handling when needed.
- Examples.
- Status output patterns or completion report.
Use these conventions:
- H1: plain command title, or a blocking semantic title for mandatory gates.
- H2:
## N. SECTION-NAME, using full integers only. - H3 steps:
### Step N: Description. - Do not use decimal steps such as
1.5or2.5. - Put sub-activities in bullets under a numbered step.
- Use dividers between major sections when they improve scanability.
- Return structured statuses such as
STATUS=OK,STATUS=FAIL ERROR="", orSTATUS=CANCELLED ACTION=cancelled. - Keep the body behavioral — routing, gates, contracts, and executable steps only. Do NOT embed design rationale, prose-register or prompt-framework labels (e.g. "written objective-first", "(COSTAR)"), development notes (benchmark timings, spec/packet cross-references), maintainer chores ("keep AGENTS/skills synchronized to this entrypoint"), or defensive self-attestations ("no workflow-asset gap exists"). That context belongs in the decision-record, changelog, or presentation asset — never in the shipped command a user sees rendered.
Approved common H2 section names include:
PURPOSECONTRACTWORKFLOW OVERVIEWINSTRUCTIONSARGUMENT ROUTINGREFERENCEEXAMPLESRELATED COMMANDSTOOL SIGNATURESUSER INPUT
Approved canonical H2 section names for router commands (see Step 11):
ROUTER CONTRACTOWNED ASSETSMODE ROUTINGEXECUTION TARGETSPRESENTATION BOUNDARYWORKFLOW SUMMARY
Step 9: Implement Argument Dispatch When Needed
For commands with multiple entry points, include an ASCII routing tree based on $ARGUMENTS.
Route by:
- Empty arguments.
- First-word action keywords, case-insensitive.
- Natural-language query patterns.
- Single ambiguous words.
- Flags and options.
Then define one handler section per action. Show example routing in a table so future maintainers can verify behavior quickly.
Argument-echo deprecation. Do not end a command with a bare User request: $ARGUMENTS line. The command already receives $ARGUMENTS; echoing it verbatim adds no routing behavior and duplicates the argument surface the router resolves. Resolve arguments in the router body — the validator warns on the raw-echo idiom.
Loader gating. Frontmatter is the load gate: allowed-tools authorizes exactly the tools and MCP surfaces a command may use, and any agent the router dispatches must both be admitted by that gate and resolve to a real agent definition in the active runtime's agent directory. Do not dispatch a handle the frontmatter does not admit or that does not exist.
Step 10: Implement Mode Routing When Needed
For commands supporting :auto and :confirm, document mode detection:
| Pattern | Mode | Behavior | | --- | --- | --- | | /command:auto | Autonomous | Execute without user approval gates | | /command:confirm | Interactive | Pause at each step for user approval | | /command | Prompt | Ask user to choose execution mode |
Autonomous mode self-validates at checkpoints, makes informed decisions, and records significant decisions.
Interactive mode pauses after each step for approval, presents options such as approve, review details, modify, skip, or abort, and records user decisions.
If the mode-based command is large or has visible dashboards/prompts/results, use the router/presentation split.
Mode completeness. Every mode a command advertises must be fully realized, not merely reachable. For each mode in the argument hint (:auto, :confirm), the command must have both its workflow asset (the _auto.yaml / _confirm.yaml) and an EXECUTION TARGETS row that resolves the mode to that asset. A hint that lists :auto with no _auto.yaml or no :auto execution row is incomplete — a reader cannot route the advertised mode — so declare only the modes you have wired end to end.
Step 11: Author The Router As A First-Class Command Type
A router is a first-class command type, not a loose refactor. Its .md is a thin dispatcher: verify the orchestrating agent, resolve mode and arguments, then hand off to owned assets (a presentation .txt, optional _auto.yaml / _confirm.yaml, or scripts). It carries no inline dashboards, prompts, or result templates.
Detection signature. The validator treats a command as a router when any of:
- a
render-command-contractmarker is present (the compiled-stub variant, which has no authored section requirements); or - a
Presentation Boundarysection is present; or - two or more of
{Router Contract, Owned Assets, Mode Routing, Execution Targets}co-occur.
Minimal core vs recommended. A router must include the blocking core only: Owned Assets and Presentation Boundary. The remaining canonical sections — Router Contract, Mode Routing, `Exe
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: MichelKerkmeester
- Source: MichelKerkmeester/skilled-harness_spec-driven-agent-loops
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.