Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
git clone --depth 1 https://github.com/rhuss/cc-spexWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/commands/rhuss/cc-spex/speckit.spex.finish)<a href="https://agentmods.dev/commands/rhuss/cc-spex/speckit.spex.finish"><img src="https://agentmods.dev/badge/commands/rhuss/cc-spex/speckit.spex.finish/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/commands/rhuss/cc-spex/speckit.spex.finish"><img src="https://agentmods.dev/badge/commands/rhuss/cc-spex/speckit.spex.finish.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00015 | $0.04135 |
| Opus 5 | $0.00008 | $0.02067 |
| Sonnet 5 | $0.00003 | $0.00827 |
| Haiku 4.5 | $0.00002 | $0.00413 |
Grade A, and why
speckit.spex.finish scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 9d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 462 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Finish - Smoke Test, Squash, and Land the Code
Ship Pipeline Guard
If .specify/.spex-state exists and its status is running, this command is part of an autonomous pipeline. Check the ask field:
AUTONOMOUS_MODE=false
if [ -f ".specify/.spex-state" ]; then
STATUS=$(jq -r '.status // empty' .specify/.spex-state 2>/dev/null)
ASK=$(jq -r '.ask // "always"' .specify/.spex-state 2>/dev/null)
if [ "$STATUS" = "running" ] && [ "$ASK" != "always" ]; then
AUTONOMOUS_MODE=true
fi
fi
In autonomous mode: suppress all interactive prompts, UNLESS running inside a worktree (IN_WORKTREE is true, detected in Phase 2). When in a worktree, always present the user with the action prompt (Phase 4) regardless of autonomous mode. Never auto-merge or auto-delete a worktree.
Argument Parsing
Parse the following flags from arguments:
- If
--no-smoke-testis passed, setSKIP_SMOKE_TEST=true. This bypasses the smoke test gate unconditionally.
SKIP_SMOKE_TEST=false
for arg in "$@"; do
case "$arg" in
--no-smoke-test) SKIP_SMOKE_TEST=true ;;
esac
done
Pre-Execution Checks
Check for extension hooks (before finish):
- Check if
.specify/extensions.ymlexists in the project root. - If it exists, read it and look for entries under the
hooks.before_finishkey - If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally
- Filter out hooks where
enabledis explicitlyfalse. Treat hooks without anenabledfield as enabled by default. - For each remaining hook, do not attempt to interpret or evaluate hook
conditionexpressions:- If the hook has no
conditionfield, or it is null/empty, treat the hook as executable - If the hook defines a non-empty
condition, skip the hook and leave condition evaluation to the HookExecutor implementation
- If the hook has no
- Convert hook command names from dot notation to hyphen notation for slash command invocation (e.g.,
speckit.spex.smoke-testbecomes/speckit-spex-smoke-test) - Determine prompt behavior based on autonomous mode: when
.specify/.spex-stateexists withaskofsmartornever, optional hooks execute without prompting (treated as mandatory). Whenaskis"always"or no state file exists, optional hooks prompt as normal. - For each executable hook, output the following based on its
optionalflag:- Optional hook (
optional: true) in interactive mode:## Extension Hooks **Optional Pre-Hook**: {extension} Command: `/{command}` Description: {description} Prompt: {prompt} To execute: `/{command}` - Optional hook (
optional: true) in autonomous mode (askissmartornever): Treat as mandatory (auto-execute without prompting). - Mandatory hook (
optional: false):## Extension Hooks **Automatic Pre-Hook**: {extension} Executing: `/{command}` EXECUTE_COMMAND: {command} Wait for the result of the hook command before proceeding to Phase 1. - If a mandatory hook fails or is declined by the user, STOP. Output an error message indicating which hook failed and do NOT proceed to Phase 1.
- Optional hook (
- If no hooks are registered or
.specify/extensions.ymldoes not exist, skip silently
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 9d ago First seen · 462 lines · 15 tokens per session scan A 52dd30a23e7b
speckit.spex.finish is a command published in the GitHub repository rhuss/cc-spex (116 stars, last pushed 21d ago), licensed Apache-2.0. It adds 15 tokens to every session and 4,135 once invoked, about $0.0001 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other commands, from other repositories
4-close-project
Name: 4-close-project Purpose: Apply an OpenSpec change through TDD, verify it, prepare or update the PR, and leave archive for after merge.
explore-release
This legacy command is a rename notice only. Its workflow is now rpi-explore-release.
FinishQa
Release sign-off — verifies all TC outcomes recorded, no P0/P1 defects open, drafts plain-language release notes. Transitions ADO to Done.
publish-gate
Pre-publish smoke verification — pack, install into a tmpdir, run the configured smoke command, assert expected output. Catches the "code worked locally but the published tarball is broken" class of bug.
qa-ship
Run Phase 5 QA validation, acceptance testing, and release preparation.
release-gate
Score a release GO / NO-GO / CONDITIONAL against an auditable checklist — open bugs by priority + aging, pass rate, coverage vs the team's gate criteria in release-gate.config.yml. Hard gate fail => NO-GO; soft gate fail => CONDITIONAL (ship with sign-off). Reads the bug board + results/ (read-only), writes…