AGENT SKILL

kspec-writing-specs

Create and maintain specification items — modules, features, requirements, acceptance criteria, and traits. The source of truth for what to build.

适用职业内容创作者
使用场景写作与文案
License 许可
MIT
最近更新
2026-07-22
Stars
★ 1
Forks
2

01 前言 Front Matter

name
kspec-writing-specs
description
Create and maintain specification items — modules, features, requirements, acceptance criteria, and traits. The source of truth for what to build.

02 资源文件 9

03 SKILL.md 正文

<!-- kspec-managed -->

Writing Specs

Create and maintain specification items — the source of truth for what to build. This skill covers spec structure, writing good acceptance criteria, using traits, and organizing specs in the hierarchy.

When to Use

  • Creating a new feature, requirement, or constraint spec
  • Adding or refining acceptance criteria
  • Applying traits for cross-cutting behaviors
  • Organizing specs under the right module/parent
  • Reviewing spec quality before deriving tasks

Not for: Task management (use $kspec-task-work), plan-to-spec translation (use $kspec-plan), or triage (use $kspec-triage).

Finding Things

Use CLI commands to discover and inspect specs. Do NOT search .kspec/ YAML files manually.

Need Command
View spec + all ACs kspec item get @ref
Search by keyword kspec search "keyword"
List by type kspec item list --type feature
All modules kspec item list --type module
All traits kspec trait list
Trait details + ACs kspec item get @trait-slug
Items under a parent kspec item list --under @parent

Core Principles

  1. Spec defines WHAT, not HOW — Describe the desired behavior, not the implementation
  2. Every spec needs AC — A spec without acceptance criteria is incomplete
  3. Given/When/Then is testable — Each AC should map to at least one test
  4. Traits eliminate duplication — Cross-cutting concerns belong in traits, not copied across specs
  5. Use CLI, not YAML — All changes through kspec commands for auto-commit

Spec Hierarchy

Specs live in modules and form a tree:

module (organizational grouping)
├── feature (user-facing capability)
│   ├── requirement (specific testable behavior)
│   └── constraint (limitation or boundary)
├── feature
│   └── requirement
└── decision (architectural choice, ADR-style)

Choosing the Right Type

Type Use when Example
module Grouping related features "CLI Commands", "Web UI", "Schema"
feature User-facing capability "JSON Export", "Inbox Triage", "Shadow Sync"
requirement Specific testable behavior within a feature "Export validates output format", "Triage records audit trail"
constraint Non-functional limit or boundary "Response time < 200ms", "Max 1000 items per module"
decision Architectural choice with rationale "Use YAML over JSON for spec files"
trait Reusable AC bundle for cross-cutting behaviors "JSON output mode", "Confirmation prompts"

Rule of thumb: If it has acceptance criteria that a user could verify, it's a feature or requirement. If it constrains how something works, it's a constraint. If multiple specs need the same behavior, extract a trait.

Writing Acceptance Criteria

AC are the heart of a spec. They define what "done" means.

Format

Given: precondition (state before the action)
When:  action (what triggers the behavior)
Then:  outcome (observable, verifiable result)

Good AC Patterns

Specific and testable:

kspec item ac add @json-export \
  --given "user has 3 tasks in project" \
  --when "user runs 'kspec tasks list --json'" \
  --then "stdout contains valid JSON array with 3 task objects"

Covers error cases:

kspec item ac add @json-export \
  --given "project has no tasks" \
  --when "user runs 'kspec tasks list --json'" \
  --then "stdout contains empty JSON array []"

Boundary behavior:

kspec item ac add @bulk-delete \
  --given "user passes 50 refs (maximum supported)" \
  --when "user runs bulk delete" \
  --then "all 50 items deleted in single operation"

AC Anti-patterns

Anti-pattern Problem Better
"System works correctly" Not testable Describe specific observable outcome
"User is happy" Subjective Describe what they can do or see
"Fast performance" Not measurable "Response returns within 200ms"
"Handles errors" Vague Specific error scenario + expected behavior
Duplicating trait AC Maintenance burden Apply the trait instead
Implementation details Not behavioral Describe observable outcome, not internal mechanism
Rationale or commentary Not testable Move to description or implementation notes

Behavioral Language Rules

Specs are standalone behavioral contracts. They must read as timeless descriptions of what the system does, not how it's built. A spec should make sense to someone who has never seen the codebase.

ACs describe observable behavior, not implementation: ACs should describe what happens from the outside — what a user or consumer observes. They should not reveal how the system achieves the behavior internally. This includes internal field/variable names, protocol details, internal function calls, file formats, library names, and architectural terms. Use natural language to describe the same concept.

Examples of implementation leaking into ACs:

  • Internal field names (e.g. record_id, event_count) → "record identifier", "event count"
  • Protocol or transport names (e.g. specific RPC, message-bus, or socket protocol names) → describe the behavior they enable
  • Internal function or method calls (e.g. client.action(), session.close()) → "the action is delivered", "the session closes"
  • Internal file paths (e.g. events.jsonl) → "the recorded event history"

ACs contain only assertions, not rationale: Each AC should state what happens, not why it happens or how it relates to other concerns. Rationale, design context, backward compatibility notes, and cross-references to other specs belong in the description or implementation notes — not in the given/when/then.

Examples of commentary leaking into ACs:

  • "the request completes; this preserves backward compatibility" → "the request completes"
  • "per @other-spec" → use depends_on or relates_to fields
  • "unlike the previous behavior" → just state the current behavior

Descriptions follow the same principles — describe behavior and purpose, not implementation approach. Implementation guidance belongs in task descriptions or implementation notes.

Good:

Given: A user has an existing record
When: The user runs the delete command
Then: The record is removed and the deletion is confirmed

Bad:

Given: store.records[id].state === "active" and no pending writes target it
When: deleteRecord() resolves
Then: store.records[id] is removed via the standard teardown sequence; this preserves backward compatibility

AC Naming Convention

AC IDs are auto-generated (ac-1, ac-2, ...) or can be explicit:

# Auto-generated
kspec item ac add @feature --given "..." --when "..." --then "..."

# Explicit ID for clarity
kspec item ac add @feature --id ac-json-valid --given "..." --when "..." --then "..."

How Many ACs?

  • Minimum 1 — Every spec needs at least one
  • Typical: 2-5 — Happy path + key error cases
  • If 8+ — Consider splitting the spec into smaller requirements
  • Each AC = one behavior — Don't combine multiple verifiable outcomes

Working with Traits

Traits are reusable bundles of acceptance criteria. When a spec implements a trait, it inherits all the trait's ACs.

Traits are not shipped by kspec init — each project defines its own trait catalog. Always start by listing the project's traits before applying or extracting one.

When to Use Traits

Apply a trait when a spec needs a cross-cutting behavior that is already represented in the project's catalog:

# Discover the project's trait catalog
kspec trait list

# View trait details (shows ACs that will be inherited)
kspec trait get @<trait-slug>

# Apply trait to spec
kspec item trait add @my-spec @<trait-slug>

# Apply multiple traits
kspec item trait add @my-spec @<trait-slug-a> @<trait-slug-b>

Picking Traits

Scan the catalog returned by kspec trait list and look for traits whose cross-cutting behavior the spec implements. Typical categories you might see in a project's catalog include things like output formatting, destructive-operation prompts, filterable lists, error guidance, batch references, or shadow-state mutation. Use whatever traits the project defines — the catalog is project-specific.

Creating New Traits

If 3+ specs need the same cross-cutting behavior and no existing trait covers it, consider extracting a trait:

# Create the trait
kspec trait add "Trait Name" --description "Brief description of the cross-cutting behavior" --slug <trait-slug>

# Add ACs to the trait
kspec item ac add @<trait-slug> --given "..." --when "..." --then "..."

Trait AC Coverage

When implementing specs with traits, all inherited ACs must be covered by tests:

// AC: @<trait-slug> ac-1
it('exhibits the trait-defined behavior', () => { ... });

Run kspec validate to check for uncovered trait ACs.

Creating Specs

New Feature Under a Module

# 1. Find the right parent module
kspec item list --type module

# 2. Create the feature
kspec item add --under @cli-module --title "Bulk Operations" --type feature --slug bulk-ops

# 3. Add description
kspec item set @bulk-ops --description "Support batch operations on multiple items in a single command"

# 4. Add acceptance criteria
kspec item ac add @bulk-ops \
  --given "user provides 3 item refs" \
  --when "user runs bulk delete" \
  --then "all 3 items deleted and confirmation shown"

kspec item ac add @bulk-ops \
  --given "one of 3 refs is invalid" \
  --when "user runs bulk delete" \
  --then "error reported for invalid ref, valid refs still processed"

# 5. Apply relevant traits from the project's catalog (kspec trait list)
kspec item trait add @bulk-ops @<trait-slug-a> @<trait-slug-b>

# 6. Validate
kspec validate

Requirement Under a Feature

kspec item add --under @bulk-ops --title "Ref validation in batch mode" --type requirement --slug bulk-ref-validation
kspec item ac add @bulk-ref-validation \
  --given "batch contains mix of valid and invalid refs" \
  --when "batch executes" \
  --then "report lists each ref with success/failure status"

Updating Existing Specs

# View current state
kspec item get @feature-slug

# Update description
kspec item set @feature-slug --description "Updated description"

# Add missing AC
kspec item ac add @feature-slug --given "..." --when "..." --then "..."

# Update existing AC
kspec item ac set @feature-slug ac-2 --then "updated expected outcome"

# Mark implementation status
kspec item set @feature-slug --status implemented

# Add relationships
kspec item set @feature-slug --depends-on @other-feature
kspec item set @feature-slug --relates-to @related-item

Spec Quality Checklist

Before deriving a task from a spec, verify:

  • [ ] Description — Explains what and why (not how)
  • [ ] AC coverage — At least happy path + primary error case
  • [ ] AC testability — Each AC maps to a concrete test
  • [ ] Traits applied — Cross-cutting behaviors use traits, not duplicated AC
  • [ ] Correct parent — Placed under the right module/feature
  • [ ] No implementation details — AC describes behavior, not code structure
  • [ ] Validation passes — kspec validate reports no errors for this item

Validation

# Full validation
kspec validate

# Completeness check
kspec validate --completeness

# Spec-task alignment
kspec validate --alignment

# Strict mode (warnings → errors)
kspec validate --strict

Exit codes: 0 = success, 4 = errors, 6 = warnings only.

Validation catches:

  • Missing acceptance criteria
  • Broken references (@slug pointing to nonexistent items)
  • Missing descriptions
  • Orphaned specs (no linked tasks)
  • Uncovered trait ACs

Command Reference

Item Management

kspec item list [--type <type>]        # List items
kspec item get <ref>                   # Get item details with ACs and traits
kspec item add --under <parent> --title "..." --type <type> [--slug <slug>]
kspec item set <ref> --title "..."     # Update fields
kspec item set <ref> --description "..."
kspec item set <ref> --status <status> # implementation status
kspec item set <ref> --depends-on <ref>
kspec item set <ref> --relates-to <ref>
kspec item patch <ref> --data '{...}'  # Complex updates
kspec item delete <ref> [--force]

Acceptance Criteria

kspec item ac list <ref>               # List ACs for item
kspec item ac add <ref> --given "..." --when "..." --then "..."
kspec item ac add <ref> --id <id> --given "..." --when "..." --then "..."
kspec item ac set <ref> <ac-id> --then "updated"
kspec item ac remove <ref> <id> [--force]

Traits

kspec trait list                       # All traits with AC counts
kspec trait get <ref>                  # Trait details
kspec trait add "Name" --description "..." [--slug <slug>]
kspec item trait add <spec> <trait> [<trait2> ...]
kspec item trait remove <spec> <trait> [<trait2> ...]

Deriving Tasks

Once a spec is ready, derive a task to track implementation:

kspec derive @feature-slug             # Create task linked to spec
kspec derive @feature-slug --priority 2

The derived task gets spec_ref: @feature-slug automatically.

Integration

  • $kspec-plan — Plans create specs via import or manual creation
  • $kspec-task-work — Tasks reference specs; AC guides implementation
  • $kspec-triage — Inbox items may reveal spec gaps
  • $kspec-observe — Friction may indicate missing specs
  • $kspec-review — Reviews check AC coverage

04 同仓库更多 Skills