Skip to content
Back to skills

To Spec

ASecurity

Turn the current conversation into a spec and publish it to the project issue tracker. No interview, just synthesis of what you've already discussed.

  • 3 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 19, 2026
businessgoshelltestinggitapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 19, 2026

npx -y skills add PVMalove/claude-agent-harness --skill to-spec --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of To Spec?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for To Spec
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/pvmalove-to-spec/badge)](https://www.skillsdirectory.com/skills/pvmalove-to-spec)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: to-spec
description: Turn the current conversation into a spec and publish it to the project issue tracker. No interview, just synthesis of what you've already discussed.
disable-model-invocation: true
---

**Objective:** Synthesize the current conversation context and codebase understanding into a final specification.
**Strict Rule:** Do NOT interview the user or start a new grilling round. If information feels missing, it means the previous grilling was incomplete; synthesize the spec using only the known facts and explicit assumptions.

The issue tracker and triage label vocabulary should have been provided to you in `docs/agents/issue-tracker.md` and `docs/agents/triage-labels.md`. If either file is missing, tell the user to run `harness update`, which seeds both from the harness templates.

## Execution in Two Phases

You must execute this skill in two distinct phases to ensure the user agrees with the testing strategy before you write the final document.

### Phase 1: Exploration & Seam Proposal
1. **Explore the Codebase:** Use the project's domain glossary (`CONTEXT.md`) and respect any ADRs in the touched area.
2. **Define Seams:** Sketch out the seams at which the feature will be tested.
    - Prefer existing seams over new ones.
    - Use the highest seam possible.
    - Ideal state: exactly *one* seam for the whole feature.
3. **STOP AND ASK:** Present your proposed seams and one integration branch name in the form
   `integration/<service-or-team>`. Derive the slug from explicit project/domain language; never
   guess it. Ask the user to approve both. **Do not proceed to Phase 2 until the user confirms.**

### Phase 2: Drafting & Publishing (After User Approval)
1. **Draft the File:** Write the spec using the `<spec-template>` below, at the root of its own folder under `docs/tasks/` — that folder also reserves `tickets/` (one file per child ticket, filled in later by `/to-tickets`) and `artifacts/` (the `/grilling` Live Artifact).
    - *Naming convention:* If the issue ID is known, use it. If not, use a descriptive slug (e.g., `docs/tasks/add-user-auth/add-user-auth.md`) and rename both the folder and file later once the ID is generated — see `docs/agents/artifacts.md` for the full convention, including the epic-folder grouping and the `tickets/`/`artifacts/` subfolders.
    - Take the final Discovery Context file list from that same folder's `artifacts/discovery-context.md` (written by `/grilling`'s Persisted List step); if that file doesn't exist because artifact tracking never ran, take the approved-paths list from the final Trunk summary instead. Append it in the template's final `## Relevant Files (Discovery Context)` section. Preserve every path and any supplied context; do not rediscover or replace that list while drafting.
2. **Publish to Tracker:** Publish the issue with the configured tracker's CLI:
    - **GitHub:** `gh issue create --body-file <path>`.
    - **GitLab:** `glab issue create -R <project-url> --title '<title>' --description-file <path> --yes`. Keep `<title>` in single quotes and write each apostrophe in it as `'\''` in a POSIX shell or as `''` in PowerShell. `<project-url>` and the other GitLab placeholders (`<host>`, `<project-id>`) are defined in `docs/agents/issue-tracker.md` → GitLab → Conventions. The epic's number is the last segment of the issue URL the command prints.
    - Do not pass the body inline with `--body`/`--description` or a heredoc: spec bodies contain nested quotes and backticks that break shell quoting.
3. **Apply Labels:** This published issue acts as the feature's **epic**. Apply the following labels (see `docs/agents/triage-labels.md` for the full taxonomy):
    - `type::bug` OR `type::feature`
    - `status::specs` (Do NOT use `status::ready` as it requires decomposition first).
    - `task-report::required` (unless told to skip).
    - **GitLab:** `glab issue update <epic> -R <project-url> --label 'type::feature,status::specs,task-report::required'` (`type::bug` for a bug; drop `task-report::required` when told to skip it). A label the project doesn't have yet is silently created with GitLab's default color instead of failing, so run `/setup-labels` before the first epic.
    - *Note:* Do NOT create ad-hoc `epic::<slug>` labels. `/to-tickets` links the tickets to this epic later through the tracker's parent link — GitHub sub-issues, or on GitLab a `## Parent: #<epic>` section plus a `relates_to` issue link — see `docs/agents/issue-tracker.md#wayfinding-operations` for the mechanism.
4. **Ensure the selected integration branch exists after the epic issue succeeds:**
    - Read the required `base_branch` from `.harness/project.json`; if it is absent, stop and report
      the invalid project config. This is the release/base branch from which the epic integration
      branch starts.
    - Record the grill docs that changed in the current worktree:
      `git status --porcelain --untracked-files=all -- CONTEXT-MAP.md ':(glob)**/CONTEXT.md' ':(glob)**/docs/adr/**'`.
      `/grill-with-docs` and `/domain-modeling` write these files. Record each path; for a
      rename (`old -> new`), record both paths. The list can be empty.
    - Fetch the base ref. Create `integration/<service-or-team>` with `git branch` from
      `origin/<base_branch>` when a remote exists, otherwise from the local base branch. Do not
      use `git switch -c` or `git checkout -b`: the branch-name hook allows them only for names
      that match `branch_pattern`.
    - If the integration branch already exists locally or remotely, reuse it without resetting,
      force-updating, or deleting it. If publication succeeds but branch creation fails, report
      the partial state and the exact recovery action; do not recreate the epic issue.
    - If the branch already exists on the remote, do not commit to it and do not switch the
      current worktree. If the grill docs list is not empty, report that these docs stay
      uncommitted in the current worktree. Give the recovery action: commit them on an issue
      branch from `integration/<service-or-team>`, for example the first child ticket's branch,
      and merge them through its PR.
    - If the branch is absent on the remote and the grill docs list is empty, do not switch the
      current worktree; it may contain unrelated changes.
    - If the branch is absent on the remote and the grill docs list is not empty, commit the docs
      to the branch before you push it. Do not create a separate worktree:
        1. Switch the current worktree with `git switch integration/<service-or-team>`.
           Uncommitted changes move with the worktree. If `git switch` refuses because of a
           conflict with uncommitted changes, stop. Do not use `--force`, `--discard-changes`,
           `--merge`, or a reset: they can overwrite changes. Report the git error and the
           recovery action: put the changes aside with `git stash push --include-untracked`, run
           `git switch integration/<service-or-team>`, restore them with `git stash pop`, resolve
           any conflict, and continue from sub-step 2.
        2. Stage only the recorded grill docs, each path named explicitly:
           `git add -- <path>...`. Do not use `git add -A`, `git add .`, or `git commit -a`. Other
           changes stay uncommitted in the working tree.
        3. Run the commit as a standalone command, without `&&`, `;`, a pipe, or a variable:
           `git commit -m 'docs: <short epic summary>'`. Write the message by the commit rules in
           `docs/agents/git-workflow.md`. The `block-direct-master` hook allows a commit on an
           `integration/*` branch only in this form, only when the index contains only grill docs
           paths, and only when the branch is absent on `origin`.
        4. If the hook blocks the commit, stop and do not push. Report the hook message and that
           the docs stay staged in the current worktree. Give the recovery action: remove the
           cause, for example a staged path outside the grill docs or no access to `origin`, and
           repeat sub-step 3.
    - Push a branch that is absent on the remote with
      `git push -u origin integration/<service-or-team>`. After a grill docs commit, the current
      worktree stays on the integration branch, with unrelated changes uncommitted.
    - For a local tracker, make the grill docs commit as above, but do not push; report that the
      branch was not pushed. In a repository without a remote, create the local branch and do not
      commit or push. Report that the branch was not pushed and that the grill docs stay
      uncommitted.

---

<spec-template>

## Problem Statement
The problem that the user is facing, from the user's perspective.

## Solution
The solution to the problem, from the user's perspective.

## User Stories
A numbered list of user stories that covers every behavior of the feature.
Format: `1. As an <actor>, I want a <feature>, so that <benefit>`
*(Example: As a bank customer, I want to see my balance, so that I can make informed spending decisions).*

## Implementation Decisions
A list of modules to build/modify, interface changes, technical clarifications, architectural decisions, schema changes, API contracts, and specific interactions.
- **DO NOT** include specific file paths or generic code snippets (they outdate quickly).
- **Exception:** If a prototype produced a snippet that encodes a decision perfectly (state machine, schema, type shape), inline it and note it came from a prototype. Trim it to the decision-rich parts only.

## Testing Decisions
- Description of what makes a good test here (test external behavior, not implementation details).
- Which modules will be tested.
- Prior art (similar existing tests in the codebase).

## Out of Scope
A strict list of things that will NOT be done. This is your insurance policy against over-engineering. Be explicit about boundaries so future agents do not build more than requested.

## Integration Branch

- Branch: `integration/<service-or-team>`
- Created from: `base_branch` in `.harness/project.json`
- Child issue branches start from this integration branch and open PRs back to it.

## Further Notes
Any remaining context or constraints.

## Relevant Files (Discovery Context)
The final Discovery Context file list captured in the session's `Live Artifact`, or in the final Trunk summary when artifact publishing is unavailable, including each path and any supplied context.

</spec-template>

Files in this skill

  • SKILL.md10.3 KB
  • agents/openai.yaml135 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.