AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Spec Workflow

skill-ramboz-jig-spec-workflow · by ramboz

>

No reviews yet
0 installs
35 views
0.0% view→install

Install

$ agentstack add skill-ramboz-jig-spec-workflow

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No 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.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-ramboz-jig-spec-workflow)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

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 →
Are you the author of Spec Workflow? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

> Spec 003 promoted this skill from stub to active. The deterministic state > mutations live in workflow.py; this SKILL.md drives the judgment layer.

What this skill does

  • Guides SPIDR-splitting a new spec into vertical slices (Spike last, not first —

try Rules / Data / Interface / Path first).

  • Flags slices that look like horizontal phasing (no user-facing layer touched).
  • Drives the spec lifecycle state transitions via workflow.py.
  • Coordinates implementer + reviewer subagent invocations at the right points.
  • Enforces the reconciliation checklist before a slice goes DONE.
  • Consults docs/memory/glossary.md when drafting ACs to surface unknown domain terms.
  • Surfaces skill-routing observability via workflow.py routing-stats [--days N]

a read-only histogram of which skills fired (jig baseline vs. richer/"other" skill per category) from .codex/skill-usage.jsonl (slice 041-02).

  • Surfaces use-case coverage via workflow.py coverage [--project-dir DIR] — a

read-only, advisory (non-blocking), project-wide bidirectional check (slice 068-03): a deterministic set-difference over the use_cases: trace links that reports use cases with no implementing spec (coverage gap) and specs citing no parent use case (scope creep). No-op when the project has no ## Use cases section.

  • Surfaces gate-bypass telemetry via workflow.py gate-stats [--days N] — a

read-only per-gate histogram of how often each gate honored its env-var override (an override-frequency audit trail, not a gate-value verdict) from .codex/skill-usage.jsonl (slice 078-02).

SPIDR splitting

All non-trivial specs are SPIDR-split into vertical slices before implementation begins. Spike is the last resort — try Path / Interface / Data / Rules first.

  • S — Spike: research/learning activity. Only when none of P/I/D/R

apply. AI agents default to spiking too eagerly — resist.

  • P — Path: split by alternative paths through the story (happy

path first, edge paths later).

  • I — Interface: split by UI / platform / channel (minimal first,

polish later).

  • D — Data: split by data subset or format (less data first).
  • R — Rules: split by business rules (simple first, edge cases later).

Anti-horizontal-phasing rule: every slice must touch the user-facing layer and deliver end-to-end value. A slice that touches only the DB or only the parser is horizontal phasing — re-split.

See [worked-example-spidr-split.md](worked-example-spidr-split.md) for one applied example per axis plus a jig-native dogfood case (spec 017's three-axis split). The canonical primer for all five axes lives at [docs/spec-workflow/spidr-primer.md](../../docs/spec-workflow/spidr-primer.md).

Spike slices

When SPIDR's S axis fires during decomposition (none of P / I / D / R apply because the team doesn't yet know enough to pick), the resulting slice is marked kind: spike in its frontmatter — the typed enum that spec_lint.py validates.

When to introduce a spike during decomposition. Reach for S only after trying R / D / I / P. The bias to resist is "let me research this first" as a prelude to "now let me build it as one big slab" — that is horizontal phasing in a trench coat. If the spike would conclude with "now ship the implementation," the implementation IS the slice, and the research goes inside it.

Body shape (four labelled blocks). A kind: spike slice carries four blocks alongside the standard Goal / DoR / AC / DoD scaffolding. Each label must be written with the trailing colon (**Question:**, etc.) — that is what spec_lint.py matches against.

  • Question: — one sentence stating the open question. Set at DRAFT.
  • Time-box: — explicit budget (e.g., "1 day", "4 hours"). Set at DRAFT.
  • Findings: — bullet evidence collected during the spike. Filled

during IN_PROGRESS.

  • Outcome: — one of ADR-NNNN created / spec NNN-NN unblocked /

abandoned (reason). Multiple outcomes separated by ; (e.g., ADR-0007 created; spec 030-02 unblocked). Set at DONE.

spec_lint.py soft-warns when a kind: spike slice is missing any of the four labels — mid-flight spikes legitimately have empty Findings / Outcome, so this is a warning, not a hard error.

Always nested, never standalone. Spike slices live inside a real spec — never as a standalone docs/spikes/ artifact. The 1-slice-spec case (no clear downstream spec yet, just an investigation) collapses to "spawn a normal spec where the only slice is kind: spike." This forces the investigator to articulate the downstream change up front and keeps jig at two numbered families (specs+slices, ADRs).

Abandoned-spike manual-reshape failure mode. When a spike's Outcome is abandoned (reason), dependents are NOT automatically cascade-flagged. The human (or the next session) audits each dependent slice and decides whether the original design still holds. Automation here over-fires: "approach A abandoned" often means "approach B from the same findings still satisfies the dependents." workflow.py deliberately stays out of the cascade business; the SKILL.md hand-off is the documented gate.

How to use

Creating a new spec

  1. Step 0 — confirm the project is scaffolded (spec 063 / ADR-0011).

BEFORE reserving a number or drafting ANY docs/specs/ or slice structure, confirm this project is a scaffolded jig project. If it isn't, route — do not hand-roll directories:

  • Greenfield (no jig structure yet) → tell the user to run

/jig:scaffold-init. It lays down conventions, templates, hooks, the status board, and a seed reference spec.

  • Existing spec/slices/ layout, but not jig-scaffolded (no

scaffold.json) → tell the user to run /jig:migrate. It adopts the existing layout into jig structure.

You don't have to decide the state yourself: workflow.py new (step 2) classifies and routes for you (spec 063-01) — a scaffold.json-bearing project proceeds; a greenfield project is refused naming /jig:scaffold-init; an adoptable spec-driven project is refused naming /jig:migrate. The deterministic gate and this human-readable precondition agree by construction, so don't restate the detection heuristic here — run the helper and let it route. (Bypass for a deliberate out-of-band flow: JIG_SCAFFOLD_PRECONDITION=0.)

The anti-pattern this step exists to kill: an auto-triggered spec-workflow run improvising a loose slices/ folder (or any ad-hoc docs/specs/ skeleton) because /jig:scaffold-init was skipped. That produces a non-jig layout that then needs migrating — exactly the reported failure. When in doubt, route to setup first; never invent the structure by hand.

  1. Confirm the work needs a spec. Trivial fixes don't.
  • Reference moved? Reframe first. If a load-bearing reference changed

from outside the system (a design system, vendor / API contract, test infra, compliance regime, platform, or product-positioning / strategic-vision shift), reach for /jig:reframe before drafting — re-baseline the corpus onto the new reference so you draft against it, not the dead premise (spec 067 / [ADR-0024](../../docs/decisions/adr-0024-reference-reframe.md)). 1a. Read the vision ## Use cases section as framing — before drafting (spec 068-02 / [ADR-0025](../../docs/decisions/adr-0025-use-cases-breadth-layer.md)). If the project's docs/product-vision.md carries a ## Use cases section (the breadth-layer behaviors captured at init), read it first as framing context for this spec — which captured behavior does this work serve? The section is the shared frame specs anchor against; reading it before you draft is what keeps behavior-dense projects from each spec inventing its own slice of the world. (If there is no ## Use cases section, the layer isn't adopted for this project — skip this step; nothing here applies.) You record the answer as a trace link in the spec's use_cases: frontmatter (step 2a). 1b. Cross-check tracked bugs before drafting ACs. For feedback/triage specs, read docs/bugs/README.md and any overlapping docs/bugs/NNN-*.md record before turning reported symptoms into acceptance criteria. If an item is a tracked defect with a bug record, route it through bug-fix (or link to that bug as an explicit dependency) instead of copying the defect into the spec as a second owner. Keep polish/design/new-behaviour items in the spec.

  1. Reserve the next free number on origin/main:

``bash python3 "${PLUGIN_ROOT}/skills/spec-workflow/workflow.py" new ``

The helper computes max(NNN) + 1 across docs/specs/, writes a minimum stub docs/specs/NNN-/spec.md (frontmatter + Overview

  • SPIDR-analysis headers), commits it as

docs(specs): reserve NNN-, and pushes to origin/main. If the push is refused by branch protection / permissions, the helper automatically falls back to a reserve/NNN- branch + gh pr create. This locks the number team-wide before any drafting begins, killing the parallel-worktree spec-number-collision failure mode logged across specs 014/015/016/017.

Works from any branch or worktree (ADR-0015 / spec 051). The helper routes on the current branch: on main it runs the proven in-place flow (clean tree required, since the commit lands on local main); off main — a feature branch or a linked .codex/worktrees/* worktree — it builds the reservation commit in an ephemeral detached worktree checked out at origin/main and pushes it by SHA, never touching your branch, cwd, or working tree. You no longer need to switch to main (and a linked worktree can't, anyway).

Flags: --no-push for solo machines without a remote, or for an off-main provisional reservation committed on the current branch (the number is local-view and may collide at merge — treat it as provisional); --pr to skip the direct-push attempt on protection-locked main. 2a. Record the use-case trace link — and grow the vision on discovery (spec 068-02 / [ADR-0025](../../docs/decisions/adr-0025-use-cases-breadth-layer.md)). The stub seeds an empty use_cases: frontmatter list. Fill it with the UC-N id(s) (from the vision ## Use cases section, step 1a) this spec serves — the dependencies:-style flow-list shape, e.g. use_cases: [UC-1, UC-3]. This is the machine-resolvable trace link the reconcile-phase coverage check (slice 03) reads.

The discipline is soft — an empty/absent use_cases: never blocks a transition (AC4 / [ADR-0011](../../docs/decisions/adr-0011-spec-gate-model.md)). But it is not silent. The trigger is mechanical and deterministic — the classify_spec predicate in [skills/_common/use_cases.py](../common/usecases.py) computes one of no_section / empty / resolved / unresolvable for this spec — not a voluntary "is this new?" self-report. Whenever classify_spec returns empty or unresolvable (the spec cites nothing, or cites a UC-N with no match in the vision) at draft/framing, surface a three-path prompt — every path is one step and none blocks drafting:

  • (a) cite an existing use case — this spec serves a behavior already in

the vision: put its UC-N id(s) in use_cases:. Done.

  • (b) grow the vision — this spec serves a behavior not yet captured:

reuse vision-elicitation's capture loop, seeded with the existing entries (so the author sees the current set), → normalize → confirm, then write additively (append, never discard-and-replace) and assign the next free UC-N (use_cases.next_use_case_id allocates max + 1; retired numbers are never reused). The confirm step guards grow quality so a reachable trigger can't silently bloat the section: (i) enforce goal-level grain — reject spec-shaped / requirements-level phrasing, re-running slice 01's normalize ("[actor] can [goal]"); (ii) run a near-duplicate check against the seeded existing entries (use_cases.is_near_duplicate) — on an apparent match, route back to path (a)-cite rather than minting a duplicate. Then record the new id in use_cases:.

  • (c) decline — legitimately untraced (infra / refactor / no user-facing

behavior) or defer: leave use_cases: []. The vision is unchanged, and any resulting gap is slice 03's advisory coverage backstop. No-op.

CRITICAL — the no-section no-op. When classify_spec returns no_section (the project has no ## Use cases section — the breadth layer is not adopted, e.g. jig's own repo), the prompt is suppressed entirely: nothing prompts and nothing errors. A project with specs but no use-case layer is wholly unaffected. The trigger fires only on empty / unresolvable, which presuppose the section exists.

  1. Create docs/specs/NNN-/{spec.md,plan.md,tasks.md} with the conventional

structure: status frontmatter, overview, SPIDR analysis, ordered slices.

  1. SPIDR-split: for each slice, the goal is one vertical piece that delivers

end-to-end value. Spike is the last resort, not the first reach.

  1. For each new slice, use the template at

templates/docs/specs/slice-template.md — it ships the canonical frontmatter shape (status, dependencies, last_verified) plus DoR / AC / DoD / Close-out sections. Set status: DRAFT in the frontmatter. Legacy slices that use prose **STATUS: DRAFT** markers still work (lazy migration); no need to rewrite them.

  1. Ground your factual claims (spec 064-02 / ADR-0020 §1–§2). Any

load-bearing factual claim about a runnable surface — library/API capability, version/perf behavior, behavior of existing code — must be backed by an executed probe (run the command, read the source / node_modules) or a citation. Everything you cannot verify goes in the spec stub's risk-gated ## Assumptions section, marked explicitly — never asserted as fact. This makes mandatory + derived the existing informal "Current state (verified …)" discipline that the 064-01 retro found jig already half-practices by hand: it was grounding-by-probe all along, just reliant on author diligence. The ## Assumptions you surface here has downstream value — slice 064-04 derives the frame_review trigger mechanically from it, so honest framing now is what decides later whether the adversarial frame-critique pass fires. The section is risk-gated: write "None" / omit when there are no unverified load-bearing assumptions; don't pad with boilerplate. (For a worked example of marked assumptions plus probe-grounded claims, see [ADR-0020](../../docs/decisions/adr-0020-spec-frame-hardening.md) ## Assumptions A1–A4 + ## Kill criteria, and the [spec 064-01 retro](../../docs/specs/064-spec-frame-hardening/retro.md), which probe-verified its three most load-bearing claims before recording them.)

  1. Let the assumptions decide frame_review (spec 064-04 / ADR-0020).

You are not asked "is frame-review needed?" — the ## Assumptions you just surfaced decide it, mechanically. Set the slice's frame_review flag from workflow.py frame-review-needed:

``bash python3 "${PLUGIN_ROOT}/skills/spec-workflow/workflow.py" \ frame-review-needed "docs/specs/NNN-/spec.md" "" ``

The rule is a derivation, not a judgment call: true iff the slice's ## Assumptions section carries ≥1 real (non-placeholder) assumption — so honest framing in step 6 is exactly what fires (or silences) the adversarial frame-critique pass. An inline-mirror / refactor slice with no unverified assumptions (`#

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.