用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/me2resh/apexyard --skill spike-close命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Audit dependencies for vulnerabilities, outdated packages, and license compliance.
Make a technical decision with structured reasoning and create an Agent Decision Record (AgDR).
DFD with trust boundaries + data classifications (Mermaid + optional Threat Dragon JSON). Source-of-truth for /threat-model.
基于 SOC 职业分类
正在显示 SKILL.md
| name | spike-close |
| description | Close a spike via the disposition gate — `--promote` files a [Feature] follow-up, `--discard` writes a memo. |
| argument-hint | --promote | --discard [<spike-ticket-number>] |
| allowed-tools | Bash, Read, Write |
The disposition gate prevents the worst-of-both case: a spike that "succeeded" but never decides what to do with the code, leaving half-shipped exploration in main. Every spike must close with one of two paths:
[Feature] ticket so the work goes through the full production SDLC. The spike branch itself is NOT lifted into production — the new feature work re-implements based on the spike's findings.docs/spike-memos/<slug>.md so future-us doesn't re-explore the same ground.Read the registry path via portfolio_registry, the per-project docs dir via portfolio_projects_dir, and the ideas backlog via portfolio_ideas_backlog — all from .claude/hooks/_lib-portfolio-paths.sh. Source the helper at the top of any bash block that touches those paths:
source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-read-config.sh"
source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-portfolio-paths.sh"
registry=$(portfolio_registry)
Defaults match today's single-fork layout. See docs/multi-project.md.
/spike-close --promote 142
/spike-close --discard 142
/spike-close --promote # uses the active-ticket marker
/spike-close --discard
Two paths:
$ARGUMENTS includes a number (e.g. --promote 142 or --discard owner/repo#142), use that..claude/session/current-ticket or .claude/session/tickets/<project>) and use the ticket recorded there. If neither resolves, ask:Which spike are you closing? Pass --promote <number> or --discard <number>,
or run /start-ticket first.
Run gh issue view <number> --repo <owner/repo> --json title,labels,state,body. The skill proceeds if:
[Spike], ORspikeIf the ticket is neither, refuse:
Issue {owner/repo}#{number} doesn't look like a spike (no [Spike] prefix,
no `spike` label). /spike-close is for spike disposition only — close
production-shaped tickets via the normal QA → Done flow.
If the ticket is already CLOSED, warn and ask whether to continue (the user may want to retroactively record disposition):
{owner/repo}#{number} is already closed. Continue and (a) file the follow-
up artefact only, or (b) abort? (continue / abort)
--promote vs --discardAsk one at a time:
i) Production-shaped feature title
The spike confirmed the hypothesis. What's the title of the production-
shaped feature ticket we're filing as the follow-up?
ii) Production-shaped scope
What's the scope for the production version? This is the user-facing
capability, not the spike's exploration goal.
(One paragraph or bullets.)
iii) What's NOT being carried over
What did the spike try that's NOT being lifted into production? (e.g.
"the prototype used in-memory storage; production needs Postgres",
"the spike skipped error handling — we'll add it in the feature".)
Then preview the [Feature] ticket and confirm. The body MUST include a "Spike findings" section that links back to the spike:
**[Feature] {title}**
## User Story
{prompted from the operator — same as /feature step 3a}
## Acceptance Criteria
- [ ] {prompted from the operator}
## Spike findings
This feature was promoted from {owner/repo}#{spike-number}.
The spike confirmed: {one-sentence summary of what the spike proved}.
What is NOT being carried over from the spike branch:
- {item 1}
- {item 2}
## Out of Scope
{or "—"}
After confirmation, create the follow-up feature via the tracker abstraction
(tracker_create, #670 / AgDR-0072, extended by the #709 creator sweep) so it
lands in this project's tracker. For a GitHub adopter this runs
gh issue create exactly as before.
# Resolve the tracker lib (it lives in the ops fork's hooks dir) by walking up
# from the cwd; source it.
tracker_lib="$(r="$PWD"; while [ -n "$r" ] && [ "$r" != / ]; do \
[ -f "$r/.claude/hooks/_lib-tracker.sh" ] && { echo "$r/.claude/hooks/_lib-tracker.sh"; break; }; \
r="${r%/*}"; done)"
# shellcheck source=/dev/null
. "$tracker_lib"
body_file="$(mktemp)"
cat > "$body_file" <<'BODY'
{body}
BODY
# tracker_create <owner/repo> <title> <body_file> [<labels_csv>] → {"ref","url"}.
result="$(tracker_create "{owner/repo}" "[Feature] {title}" "$body_file" "enhancement")"
rc=$?
rm -f "$body_file"
if [ "$rc" -eq 3 ]; then
echo "Tracker is 'none' (shape-only) — nothing was created in a tracker." >&2
printf '%s\n' "$result"
exit 0
elif [ "$rc" -ne 0 ] || [ -z "" ];
>&2
1
ref=
url=
Then close the spike with a cross-ref comment. (Closing stays on gh here —
issue state transitions are out of scope for the #709 creation sweep; a
tracker-agnostic close/state primitive is separate follow-up work. On a
non-GitHub project, close the spike manually.)
gh issue close {spike-number} --repo {owner/repo} \
--comment "Spike disposition: PROMOTE. Follow-up filed as #${ref} — {feature-title}. Spike branch is NOT being lifted into production; the new feature work re-implements based on the findings recorded above."
Return both URLs:
Spike closed: {owner/repo}#{spike-number}
Follow-up: {owner/repo}#${ref} — {feature-title}
${url}
What did we learn? One paragraph — enough that a future engineer who
asks the same question (or revisits the same library / approach) finds
this memo and doesn't re-explore the same ground. Be concrete:
- what was the hypothesis?
- what did the experiment show?
- why is the answer no? (or "we shouldn't do this", or "X first")
- what would change the answer? (under what conditions might we revisit?)
Then derive a slug from the spike title (lowercase, kebab-case, max 40 chars, stopwords trimmed) and write the memo:
mkdir -p docs/spike-memos
cat > docs/spike-memos/{slug}.md <<'EOF'
# Spike memo: {title}
> **Disposition: DISCARD** — hypothesis rejected; not pursuing further.
- **Spike ticket**: {owner/repo}#{number}
- **Author**: {git config user.name}
- **Closed**: {ISO-8601 date}
## Hypothesis (from the spike ticket)
{hypothesis from the original ticket body}
## Findings
{the one-paragraph answer the operator wrote}
## Why we're not pursuing
{extracted from the operator's answer — the "answer is no" part}
## What would change the answer
{conditions under which we might revisit — extracted from the operator's
answer, or "—" if not specified}
## Artefacts
- Original spike ticket: {owner/repo}#{number}
- Spike branch: spike/<TICKET-ID>-<slug> (delete after merge of this memo)
EOF
The memo is committed in a separate PR (the spike's PR may or may not have merged — the memo PR is the disposition artefact, separate from any code).
After writing the memo, close the spike with a cross-ref:
gh issue close {spike-number} --repo {owner/repo} \
--comment "Spike disposition: DISCARD. Memo at docs/spike-memos/{slug}.md (commit in follow-up PR). Spike branch can be deleted; nothing is being lifted into production."
Return:
Spike closed: {owner/repo}#{spike-number}
Memo path: docs/spike-memos/{slug}.md
Next steps:
1. Stage the memo: git add docs/spike-memos/{slug}.md
2. Commit: git commit -m "docs: spike memo for #{spike-number}"
3. Push + PR — the memo is the disposition artefact.
4. Delete the spike branch once the memo PR merges.
docs/spike-memos/<slug>.md is the artefact — no memo, no DISCARD./spike and /feature.Part of ApexYard — multi-project SDLC framework for Claude Code · MIT.