From agent-toolkit
Negotiate, anchor, verify, and amend a project-local SPEC against a Notion 기획문서. Four-mode lifecycle (DRAFT / VERIFY / DRIFT-CHECK / AMEND) on top of an LLM-wiki-inspired INDEX (`<spec.dir>/<spec.indexFile>`, default `.agent/specs/INDEX.md`) and per-page SPEC files (`<spec.dir>/<slug>.md` slug mode, default `.agent/specs/<slug>.md`, or `**/SPEC.md` directory mode). Conducted by the `grace` sub-agent. Auto-trigger when a Notion URL / page id appears together with phrases like "스펙 합의" / "SPEC 작성" / "SPEC 검증" / "SPEC drift" / "기획문서 변경 반영".
How this skill is triggered — by the user, by Claude, or both
Slash command
/agent-toolkit:spec-pactThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
* Own the agreement lifecycle between a Notion 기획문서 and a project-local SPEC.
Mode bodies live under
./fragments/. This SKILL.md is the router — it carries the shared rules (Role / Mental model / journal kinds / Tool / Writing / Do-NOT / Failure). The per-mode steps + output formats sit inskills/spec-pact/fragments/{draft,verify,drift-check,amend}.md. After grace picks the mode, it calls thespec_pact_fragment(mode)plugin tool (NOT a workspace-relativeread) so the plugin resolves the fragment path against its own install location — works even when the toolkit is installed externally asagent-toolkit@git+.... Phase 6.A foundation — see ROADMAP.
agent (grace)
├── 0. read INDEX ← <spec.dir>/<spec.indexFile> (default .agent/specs/INDEX.md, entry point)
├── 0'. glob '**/SPEC.md'← directory-mode discovery (only when spec.scanDirectorySpec=true)
├── 1. journal_read ← cite spec_anchor / spec_drift / spec_amendment / spec_verify_result for the same pageId
├── 2. notion_get/extract← cache-first; extract for long docs / action candidates
├── 3. read / write/edit ← SPEC body + INDEX update (slug or directory mode)
└── 4. journal_append ← exactly one append per mode (mode → kind / tags table below)
INDEX is the wiki TOC, SPEC bodies are the wiki pages. With the INDEX alone, the user can see at a glance which Notion page is anchored where.
| Mode | kind | tags | content shape | pageId |
|---|---|---|---|---|
| DRAFT | spec_anchor | ["spec-pact","v1"] (add "delegated:<agent>" when negotiation was delegated) | <slug> v1 anchored | Notion page id |
| VERIFY | spec_verify_result | ["spec-pact","verify"] | <slug> verify: <pass>/<fail>/<defer> | Notion page id |
| DRIFT-CHECK (drift found) | spec_drift | ["spec-pact","drift"] | <slug> drift detected | Notion page id |
| DRIFT-CHECK (clean) | note (reuses the existing kind — see "Do NOT" below) | ["spec-pact","drift-clear"] | <slug> drift-clear | Notion page id |
| AMEND | spec_amendment | ["spec-pact","v<n+1>"] | <slug> v<n+1> amended | Notion page id |
The four spec_* kinds are the new reserved kinds introduced by this skill. drift-clear deliberately reuses the existing note kind plus a distinguishing tag — so kind-only filters miss it; use journal_search "spec-pact" (tag-shaped recall) to recover the full lifecycle history in one call.
notion_get (the tool normalizes it).slugify(notionPageTitle) (lowercase, non-word → -). On collision with the INDEX, append -2, -3, …apps/web/orders/SPEC.md, write to that path; the INDEX records the same logical entry with that path.notion_* follows the notion-context skill's cache-first policy — never fetch the same page twice in one turn. Use notion_extract for long documents / 기능 단위 TODO 후보. Call notion_refresh only when the user explicitly says "최신화".journal_read / journal_append / journal_search only — journal_status is not needed in this skill's flow.read / write / edit only. Never write back to Notion — Notion is the source of truth, the SPEC is the surface grace owns.glob only for directory-mode discovery — only the **/SPEC.md pattern.Each mode lives in its own fragment, fetched via the spec_pact_fragment(mode) plugin tool. After picking the mode, call the tool exactly once and follow the returned content (its Steps + Output format) verbatim. Never call the tool more than once per turn — that defeats the whole point of the split.
| Mode | Tool call | Trigger phrases (caller intent) |
|---|---|---|
| DRAFT | spec_pact_fragment({ mode: "draft" }) | "스펙 합의" / "SPEC 작성" — first time the page is seen |
| VERIFY | spec_pact_fragment({ mode: "verify" }) | "SPEC 검증" / "체크리스트" / "코드와 대조" |
| DRIFT-CHECK | spec_pact_fragment({ mode: "drift-check" }) | "drift" / "노션 변경" / "기획 바뀜" / "동기화" / "기획문서 변경 반영" — first half of the lifecycle hand-off (drift 확인 → AMEND) |
| AMEND | spec_pact_fragment({ mode: "amend" }) | "AMEND" / "drift 반영" / "patch" / "기획문서 변경 반영" 의 두 번째 turn — DRIFT-CHECK 결과를 본 후 항목별 합의를 적용할 때 |
"기획문서 변경 반영" 같은 양 모드를 걸치는 trigger 는 항상 DRIFT-CHECK 부터 시작 — 같은 turn 에 AMEND 까지 진입하지 말고, drift 결과를 caller 에게 surface 한 뒤 follow-up turn 에서 명시적으로 AMEND 로 진입한다 (Tool usage rules 5 와 같은 정신).
The fragments contain the per-mode Steps and Output format. The journal kind / tag table above stays in this SKILL.md core — it is shared across modes.
보류된 이슈 / 확인 필요 사항 only.agreed_sections.locked / drifted / verified. (DRAFT writes locked directly; there is no "drafted" intermediate.)notion_refresh automatically. Only call it once when the drift result is suspect, on user request.spec_anchor / spec_drift / spec_amendment / spec_verify_result). drift-clear reuses the existing note kind plus a distinguishing tag — that is intentional, not a fifth reserved kind.notion_get timeout / auth failure → name the relevant env vars (AGENT_TOOLKIT_NOTION_MCP_URL etc.) on a single line and stop.source_page_id extraction fails → quote the input verbatim, ask once, stop.source_page_id at two paths (slug + directory) → emit both paths on a single line and wait for the caller to decide. No automatic cleanup.보류된 이슈 only and do not extend agreed_sections.Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub minjun0219/agent-toolkit