[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71F9NEGA1A1Z8CKY82NEK5R":3,"skill-same:01M71F9NEGA1A1Z8CKY82NEK5R":71},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":48,"commitSha":49,"skillDirectory":50,"forksCount":51,"repositoryHtmlUrl":52,"repositoryHomepageUrl":6,"ownerHtmlUrl":53,"ownerBlogUrl":54,"ownerDescription":55,"updatedAt":56,"install":57,"resources":70},"01M71F9NEGA1A1Z8CKY82NEK5R","dev-flow",null,"Orchestrate the canonical task↔PR↔release flow end-to-end. Two modes — `\u002Fdev-flow start \u003Cdescription>` scaffolds an OpenSpec change + branch + (optional) worktree + git hook ready for commits; `\u002Fdev-flow ship` validates the current branch + pushes + opens PR + monitors CI. Use whenever you start any non-trivial change in a playbook-consuming project. LLM-agnostic — works for Claude Code, Cursor, Antigravity, Gemini CLI, OpenCode, and humans.","Wizarck\u002Fai-playbook","Wizarck","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F23051550?v=4","01M71B3AAVR67GRWFV5ZXXZP31","arturo6ramirez","01M71F5FHXDSX3G2F52R1YS77J",6,"Apache-2.0","https:\u002F\u002Fgithub.com\u002FWizarck\u002Fai-playbook\u002Fblob\u002Fmain\u002Fskills\u002Fdev-flow\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"dev","dev flow","flow","start","git","playbook","release","worktree","opencode","cli","change","code","you","ci","end","project","release flow","branch","orchestrate","ready","2026-11-10 10:12:30",false,"---\nname: dev-flow\ndescription: Orchestrate the canonical task↔PR↔release flow end-to-end. Two modes — `\u002Fdev-flow start \u003Cdescription>` scaffolds an OpenSpec change + branch + (optional) worktree + git hook ready for commits; `\u002Fdev-flow ship` validates the current branch + pushes + opens PR + monitors CI. Use whenever you start any non-trivial change in a playbook-consuming project. LLM-agnostic — works for Claude Code, Cursor, Antigravity, Gemini CLI, OpenCode, and humans.\nlicense: Apache-2.0\nmetadata:\n  author: ai-playbook\n  version: \"1.0\"\n  spec: docs\u002Fconcepts\u002Fdevelopment-flow.md\n---\n\nOrchestrate the playbook's canonical developer flow: from \"I want to make a change\" to \"PR is open and CI is green\" without re-reading 5+ specs each time.\n\n**Input**:\n- `start \u003Cdescription>` — start a new change. Description should name the capability (e.g. \"add Telegram retry-with-backoff to notification queue\"). Optional flags: `--type \u003Cfeat|fix|chore|...>` (default `feat`), `--change-id \u003Cslug>` (default derived from description), `--no-worktree` (default: auto-detects N≥3 concurrent slices), `--no-hook` (skip auto-tick git hook install).\n- `ship` — push current branch + open PR + verify CI. No args. Optional: `--draft` to open as draft, `--auto-merge` to enable auto-merge once CI passes.\n\n## When to use this skill\n\n**Use `\u002Fdev-flow start`** when starting any non-trivial change:\n- Anything that creates new files OR touches > 50 lines OR spans > 5 commits → use this skill.\n- Trivial 1-line fixes (typo, version bump) — bypass with a regular `fix\u002F\u003Cshort-id>` branch + manual PR. The skill is overhead at that scale.\n\n**Use `\u002Fdev-flow ship`** when your branch is implementation-complete:\n- All tests pass locally\n- All `tasks.md` boxes ticked (or auto-tick git hook handled it)\n- Pre-commit clean\n- You're ready to open the PR\n\nFor sequential implementation **inside** the change: standard `\u002Fopsx:apply`. For multi-group parallel implementation: `\u002Fopsx:apply-parallel`. The dev-flow skill is the OUTER orchestrator; opsx skills are inner.\n\n## Steps — `\u002Fdev-flow start \u003Cdescription>`\n\n### 1. Resolve change-id\n\nIf `--change-id` provided, use it. Otherwise derive from the description:\n- Lowercase, replace spaces with `-`, strip non-`[a-z0-9-]` chars.\n- Strip leading\u002Ftrailing dashes; collapse double-dashes.\n- Truncate to 50 chars max.\n\nReject if: change-id matches an existing `openspec\u002Fchanges\u002F\u003Cid>\u002F` AND that change is not in archive (= still in flight). Print: \"change-id `\u003Cid>` is already in flight; pick a new one or `cd openspec\u002Fchanges\u002F\u003Cid>` to extend it.\"\n\n### 2. Confirm or scaffold the OpenSpec change\n\nIf `openspec\u002Fchanges\u002F\u003Cchange-id>\u002F` does not exist:\n\n```\n\u002Fopsx:propose --no-slice \u003Cchange-id>\n```\n\nThis creates `proposal.md` + `tasks.md` + `specs\u002F` skeleton. The user fills in the proposal body before committing.\n\nIf it exists and has `archive\u002F` child: refuse — change is already shipped.\nIf it exists without `archive\u002F`: warn \"extending an in-flight change; confirm intent\" + proceed.\n\n### 3. Branch + worktree\n\nRead the type flag (default `feat`). Branch name: `\u003Ctype>\u002F\u003Cchange-id>`.\n\n**Worktree decision** (per docs\u002Fconcepts\u002Fdevelopment-flow.md §2 + git-worktree-bare-layout.md):\n- Count branches with `git worktree list`. If `--no-worktree` is set OR count \u003C 3 → simple branch:\n  ```\n  git checkout -b \u003Ctype>\u002F\u003Cchange-id>\n  ```\n- Otherwise (≥ 3 worktrees, parallelism in flight) → use `wt_add.py`:\n  ```\n  python .ai-playbook\u002Fscripts\u002Fwt_add.py \u003Cchange-id> --branch-type \u003Ctype>\n  ```\n  This creates a worktree at `worktrees\u002F\u003Cchange-id>\u002F` with submodules + ecosystem deps installed (per PR #32 in v0.9.3).\n\n### 4. Install the auto-tick git hook (idempotent)\n\nUnless `--no-hook` is set, ensure the prepare-commit-msg hook is installed:\n\n```bash\nHOOK_SRC=\".ai-playbook\u002Ftemplates\u002Fgit-hooks\u002Fprepare-commit-msg\"\nHOOK_DST=\".git\u002Fhooks\u002Fprepare-commit-msg\"\nif [ ! -f \"$HOOK_DST\" ] || ! cmp -s \"$HOOK_SRC\" \"$HOOK_DST\"; then\n  cp \"$HOOK_SRC\" \"$HOOK_DST\"\n  chmod +x \"$HOOK_DST\"\n  echo \"✅ Installed auto-tick git hook\"\nfi\n```\n\nThe hook is local to each developer's checkout (git does not version `.git\u002Fhooks\u002F`); the skill installs it once per branch creation. After install, every `git commit` parses the conventional-commit subject and ticks matching `tasks.md` boxes (per Followup #4 \u002F scripts\u002Fauto_tick_tasks.py).\n\n### 5. Print the canonical entry\n\n```\n✅ dev-flow: \u003Cchange-id> scaffolded\n\nBranch:    \u003Ctype>\u002F\u003Cchange-id>\nWorktree:  \u003Cpath or \"main working tree\">\nTasks:     openspec\u002Fchanges\u002F\u003Cchange-id>\u002Ftasks.md\nHook:      installed (auto-ticks boxes from conventional-commit subject)\n\nNext steps:\n  1. Edit proposal.md → fill in problem + approach + decisions\n  2. Edit tasks.md   → expand the task list\n  3. Implement: standard commits with conventional-commit subjects\n       feat(\u003Cchange-id>): groups 1-3\n       chore: §2.1 + §2.2\n       fix: task 5\n     The hook will auto-tick matching boxes.\n  4. When implementation-complete, run \u002Fdev-flow ship to open the PR.\n\nReferences:\n  - docs\u002Fconcepts\u002Fdevelopment-flow.md  (canonical end-to-end flow)\n  - docs\u002Fconcepts\u002Frelease-management.md §4 §6.5 (PR shape, pre-flight rebase)\n  - docs\u002Fconcepts\u002Fmerge-policy.md (squash vs merge-commit decision)\n```\n\n## Steps — `\u002Fdev-flow ship`\n\n### 1. Pre-flight checks\n\n```bash\n# Branch shape\nBRANCH=$(git rev-parse --abbrev-ref HEAD)\nif ! [[ \"$BRANCH\" =~ ^(feat|fix|chore|docs|refactor|test|release)\u002F[a-z0-9][a-z0-9-]*$ ]]; then\n  echo \"❌ Branch '$BRANCH' does not match canonical pattern \u003Ctype>\u002F\u003Cchange-id>.\"\n  echo \"   FIX: rename via 'git branch -m \u003Cnew-name>' or use a chore\u002F* prefix for hot-fixes.\"\n  exit 1\nfi\n\nCHANGE_ID=\"${BRANCH#*\u002F}\"\n\n# OpenSpec change exists?\ncase \"$BRANCH\" in\n  chore\u002F*) ;; # exempt — chore branches don't need an OpenSpec dir\n  *)\n    if [ ! -d \"openspec\u002Fchanges\u002F$CHANGE_ID\" ]; then\n      echo \"❌ openspec\u002Fchanges\u002F$CHANGE_ID\u002F does not exist.\"\n      echo \"   FIX: create proposal first via \u002Fopsx:propose --no-slice $CHANGE_ID\"\n      exit 1\n    fi\n    ;;\nesac\n```\n\n### 2. Local validation\n\nIn order — abort on first failure:\n\n```bash\n# Working tree clean\ngit diff --quiet && git diff --cached --quiet || {\n  echo \"❌ Uncommitted changes. Commit or stash first.\"\n  exit 1\n}\n\n# Pre-commit (run on the branch's diff)\npython -m pre_commit run --from-ref main --to-ref HEAD || exit 1\n\n# Targeted tests (heuristic: discover changed test files OR fall back to full)\nCHANGED_TESTS=$(git diff --name-only main..HEAD | grep -E '^tests\u002F' || true)\nif [ -n \"$CHANGED_TESTS\" ]; then\n  python -m pytest -p no:asyncio $CHANGED_TESTS -q || exit 1\nelse\n  python -m pytest -p no:asyncio -q || exit 1\nfi\n\n# Ruff\npython -m ruff check . || exit 1\n```\n\n### 3. tasks.md completeness check\n\n```bash\nTASKS_FILE=\"openspec\u002Fchanges\u002F$CHANGE_ID\u002Ftasks.md\"\nif [ -f \"$TASKS_FILE\" ]; then\n  TOTAL=$(grep -cE '^\\s*-\\s*\\[[ xX]\\]' \"$TASKS_FILE\")\n  UNCHECKED=$(grep -cE '^\\s*-\\s*\\[ \\]' \"$TASKS_FILE\")\n  if [ \"$UNCHECKED\" -gt 0 ]; then\n    PCT=$(( (TOTAL - UNCHECKED) * 100 \u002F TOTAL ))\n    echo \"⚠️  tasks.md: ${PCT}% ticked, $UNCHECKED unchecked. Continue? [y\u002FN]\"\n    read -r REPLY\n    [ \"$REPLY\" = \"y\" ] || exit 1\n  fi\nfi\n```\n\n### 4. Push branch\n\n```bash\ngit push -u origin \"$BRANCH\"\n```\n\nIf the branch already exists on remote: `git push` (no `-u`).\n\n### 5. Open PR\n\nPR title: derived from the LAST commit subject (or first commit if branch has 1 commit).\n\nPR body template (auto-generated from commit log):\n\n```\n## Summary\n\n\u003Cauto-generated from `git log main..HEAD --pretty=%s` — bullet per commit>\n\n## Test plan\n\n- [x] Pre-commit clean\n- [x] Targeted tests green (\u003CN> passed)\n- [x] Ruff clean\n- [ ] CI green\n- [ ] CodeRabbit review pass\n- [ ] Reviewer signoff\n\n## Cross-references\n\n- `openspec\u002Fchanges\u002F\u003Cchange-id>\u002Fproposal.md`\n\nEOF\n```\n\n```bash\ngh pr create --base main \\\n  --title \"$(git log -1 --pretty=%s)\" \\\n  --body \"$(cat \u003C\u003CEOF\n## Summary\n\n$(git log main..HEAD --pretty='- %s')\n\n## Test plan\n\n- [x] Pre-commit clean\n- [x] Targeted tests green\n- [x] Ruff clean\n- [ ] CI green\n- [ ] CodeRabbit review pass\n- [ ] Reviewer signoff\n\n## Cross-references\n\n- \\`openspec\u002Fchanges\u002F$CHANGE_ID\u002Fproposal.md\\`\nEOF\n)\" \\\n  ${DRAFT_FLAG:+--draft}\n```\n\n### 6. Monitor CI (optional, depends on user preference)\n\n```bash\nPR_NUM=$(gh pr view --json number --jq .number)\necho \"✅ PR #$PR_NUM opened. Waiting for CI...\"\ngh pr checks \"$PR_NUM\" --watch\n```\n\nIf `--auto-merge` flag was passed, enable it:\n\n```bash\ngh pr merge \"$PR_NUM\" --auto --merge\n```\n\n### 7. Print next steps\n\n```\n✅ dev-flow: shipped\n\nPR:        https:\u002F\u002Fgithub.com\u002F...\u002Fpull\u002F\u003CN>\nBranch:    \u003Ctype>\u002F\u003Cchange-id>\nCommits:   \u003CN> commits ahead of main\nDiff:      \u003Cadded> +\u002F\u003Cdeleted> -\n\nNext steps:\n  1. Address review feedback (CodeRabbit + 3-layer review per parallel-review.md).\n  2. Once approved, merge:\n       gh pr merge \u003CN> --merge --delete-branch    # (multi-commit, semantic — D2.1)\n       gh pr merge \u003CN> --squash --delete-branch   # (single-commit \u002F trivial — D2.2)\n     (See docs\u002Fconcepts\u002Fmerge-policy.md for the decision rule.)\n  3. After merge, archive the OpenSpec change:\n       openspec archive \u003Cchange-id>\n     (Verifies tasks.md is N\u002FN ticked per Followup #4.)\n  4. If this is the last PR for the next release, see docs\u002Frunbooks\u002Frelease.md\n     for the release-cut PR + tag procedure.\n```\n\n## Decisions\n\n- **D1.1** Two modes (`start`, `ship`) cover the lifecycle endpoints; the middle (implementation) is delegated to `\u002Fopsx:apply` (sequential) or `\u002Fopsx:apply-parallel` (multi-group). Rationale: the skill is an orchestrator, not a code generator.\n- **D1.2** Conventional-commit subjects auto-tick `tasks.md` via the pre-installed git hook. Rationale: per Followup #4, manual ticking drifts; auto-tick from commit subject is the only reliable channel.\n- **D1.3** Pre-flight runs `pre-commit + pytest + ruff` in order. Rationale: the cheapest checks first; a ruff failure is a 10s fix, a test failure may be 30 min — fail-fast cascades.\n- **D1.4** PR body is auto-generated from commit log. Rationale: encourages good commit messages by making them visible in the PR description.\n- **D1.5** The skill suggests but does NOT decide merge style. Rationale: per merge-policy.md D2.3, the maintainer always has final decision; the advisor (`pr-merge-style.yml` workflow) provides the recommendation.\n- **D1.6** No automatic `openspec archive` — the maintainer drives archive after merge. Rationale: archive depends on confirming the merge actually shipped without revert; automating it would be premature.\n\n## Anti-patterns\n\n- **Bypassing `\u002Fdev-flow start` for \"I'll just commit directly\"**: ends up with a branch named `my-changes` that fails branch-name-validator at PR-open time. The 30-second cost of running the skill saves the rename + force-push later.\n- **`\u002Fdev-flow ship` before all tasks ticked**: the skill warns; if you `y` past it, `check-tasks-checkboxes.yml` will comment on the PR with the gap. Tick honestly OR file a `tasks.md` amendment first.\n- **Running `\u002Fdev-flow start` inside an existing in-flight change directory**: refused — the skill won't extend an in-flight change without `--extend` (not yet implemented; manual `cd` required for now).\n\n## Cross-references\n\n- [`docs\u002Fconcepts\u002Fdevelopment-flow.md`](..\u002F..\u002Fdocs\u002Fconcepts\u002Fdevelopment-flow.md) — the canonical doc this skill operationalises.\n- [`docs\u002Fconcepts\u002Frelease-management.md`](..\u002F..\u002Fdocs\u002Fconcepts\u002Frelease-management.md) — release process the skill respects.\n- [`docs\u002Fconcepts\u002Fmerge-policy.md`](..\u002F..\u002Fdocs\u002Fconcepts\u002Fmerge-policy.md) — squash vs merge-commit (skill suggests, doesn't decide).\n- [`docs\u002Frules\u002Fconflict-resolution-policy.rule.md`](..\u002F..\u002Fdocs\u002Frules\u002Fconflict-resolution-policy.rule.md) — what happens when 2 ships collide.\n- [`scripts\u002Fauto_tick_tasks.py`](..\u002F..\u002Fscripts\u002Fauto_tick_tasks.py) — the auto-tick implementation triggered by the hook.\n- [`templates\u002Fgit-hooks\u002Fprepare-commit-msg`](..\u002F..\u002Ftemplates\u002Fgit-hooks\u002Fprepare-commit-msg) — the hook this skill installs.\n- [`scripts\u002Fwt_add.py`](..\u002F..\u002Fscripts\u002Fwt_add.py) — worktree creation (when ≥ 3 concurrent slices).\n- [`skills\u002Fopenspec-propose\u002FSKILL.md`](..\u002Fopenspec-propose\u002FSKILL.md) — used internally by `start` to scaffold the proposal.\n- [`skills\u002Fopenspec-apply-change\u002FSKILL.md`](..\u002Fopenspec-apply-change\u002FSKILL.md) — sequential implementation (called between `start` and `ship`).\n- [`skills\u002Fopenspec-apply-parallel\u002FSKILL.md`](..\u002Fopenspec-apply-parallel\u002FSKILL.md) — parallel implementation when tasks.md has disjoint groups.\n","Orchestrate the playbook's canonical developer flow: from \"I want to make a change\" to \"PR is open and CI is green\" without re-reading 5+ specs each time.\n\n**Input**:\n- `start \u003Cdescription>` — start a new change. Description should name the capability (e.g. \"add Telegram retry-with-backoff to notification queue\"). Optional flags: `--type \u003Cfeat|fix|chore|...>` (default `feat`), `--change-id \u003Cslug>` (default derived from description), `--no-worktree` (default: auto-detects N≥3 concurrent slices), `--no-hook` (skip auto-tick git hook install).\n- `ship` — push current branch + open PR + verify CI. No args. Optional: `--draft` to open as draft, `--auto-merge` to enable auto-merge once CI passes.\n\n## When to use this skill\n\n**Use `\u002Fdev-flow start`** when starting any non-trivial change:\n- Anything that creates new files OR touches > 50 lines OR spans > 5 commits → use this skill.\n- Trivial 1-line fixes (typo, version bump) — bypass with a regular `fix\u002F\u003Cshort-id>` branch + manual PR. The skill is overhead at that scale.\n\n**Use `\u002Fdev-flow ship`** when your branch is implementation-complete:\n- All tests pass locally\n- All `tasks.md` boxes ticked (or auto-tick git hook handled it)\n- Pre-commit clean\n- You're ready to open the PR\n\nFor sequential implementation **inside** the change: standard `\u002Fopsx:apply`. For multi-group parallel implementation: `\u002Fopsx:apply-parallel`. The dev-flow skill is the OUTER orchestrator; opsx skills are inner.\n\n## Steps — `\u002Fdev-flow start \u003Cdescription>`\n\n### 1. Resolve change-id\n\nIf `--change-id` provided, use it. Otherwise derive from the description:\n- Lowercase, replace spaces with `-`, strip non-`[a-z0-9-]` chars.\n- Strip leading\u002Ftrailing dashes; collapse double-dashes.\n- Truncate to 50 chars max.\n\nReject if: change-id matches an existing `openspec\u002Fchanges\u002F\u003Cid>\u002F` AND that change is not in archive (= still in flight). Print: \"change-id `\u003Cid>` is already in flight; pick a new one or `cd openspec\u002Fchanges\u002F\u003Cid>` to extend it.\"\n\n### 2. Confirm or scaffold the OpenSpec change\n\nIf `openspec\u002Fchanges\u002F\u003Cchange-id>\u002F` does not exist:\n\n```\n\u002Fopsx:propose --no-slice \u003Cchange-id>\n```\n\nThis creates `proposal.md` + `tasks.md` + `specs\u002F` skeleton. The user fills in the proposal body before committing.\n\nIf it exists and has `archive\u002F` child: refuse — change is already shipped.\nIf it exists without `archive\u002F`: warn \"extending an in-flight change; confirm intent\" + proceed.\n\n### 3. Branch + worktree\n\nRead the type flag (default `feat`). Branch name: `\u003Ctype>\u002F\u003Cchange-id>`.\n\n**Worktree decision** (per docs\u002Fconcepts\u002Fdevelopment-flow.md §2 + git-worktree-bare-layout.md):\n- Count branches with `git worktree list`. If `--no-worktree` is set OR count \u003C 3 → simple branch:\n  ```\n  git checkout -b \u003Ctype>\u002F\u003Cchange-id>\n  ```\n- Otherwise (≥ 3 worktrees, parallelism in flight) → use `wt_add.py`:\n  ```\n  python .ai-playbook\u002Fscripts\u002Fwt_add.py \u003Cchange-id> --branch-type \u003Ctype>\n  ```\n  This creates a worktree at `worktrees\u002F\u003Cchange-id>\u002F` with submodules + ecosystem deps installed (per PR #32 in v0.9.3).\n\n### 4. Install the auto-tick git hook (idempotent)\n\nUnless `--no-hook` is set, ensure the prepare-commit-msg hook is installed:\n\n```bash\nHOOK_SRC=\".ai-playbook\u002Ftemplates\u002Fgit-hooks\u002Fprepare-commit-msg\"\nHOOK_DST=\".git\u002Fhooks\u002Fprepare-commit-msg\"\nif [ ! -f \"$HOOK_DST\" ] || ! cmp -s \"$HOOK_SRC\" \"$HOOK_DST\"; then\n  cp \"$HOOK_SRC\" \"$HOOK_DST\"\n  chmod +x \"$HOOK_DST\"\n  echo \"✅ Installed auto-tick git hook\"\nfi\n```\n\nThe hook is local to each developer's checkout (git does not version `.git\u002Fhooks\u002F`); the skill installs it once per branch creation. After install, every `git commit` parses the conventional-commit subject and ticks matching `tasks.md` boxes (per Followup #4 \u002F scripts\u002Fauto_tick_tasks.py).\n\n### 5. Print the canonical entry\n\n```\n✅ dev-flow: \u003Cchange-id> scaffolded\n\nBranch:    \u003Ctype>\u002F\u003Cchange-id>\nWorktree:  \u003Cpath or \"main working tree\">\nTasks:     openspec\u002Fchanges\u002F\u003Cchange-id>\u002Ftasks.md\nHook:      installed (auto-ticks boxes from conventional-commit subject)\n\nNext steps:\n  1. Edit proposal.md → fill in problem + approach + decisions\n  2. Edit tasks.md   → expand the task list\n  3. Implement: standard commits with conventional-commit subjects\n       feat(\u003Cchange-id>): groups 1-3\n       chore: §2.1 + §2.2\n       fix: task 5\n     The hook will auto-tick matching boxes.\n  4. When implementation-complete, run \u002Fdev-flow ship to open the PR.\n\nReferences:\n  - docs\u002Fconcepts\u002Fdevelopment-flow.md  (canonical end-to-end flow)\n  - docs\u002Fconcepts\u002Frelease-management.md §4 §6.5 (PR shape, pre-flight rebase)\n  - docs\u002Fconcepts\u002Fmerge-policy.md (squash vs merge-commit decision)\n```\n\n## Steps — `\u002Fdev-flow ship`\n\n### 1. Pre-flight checks\n\n```bash\n# Branch shape\nBRANCH=$(git rev-parse --abbrev-ref HEAD)\nif ! [[ \"$BRANCH\" =~ ^(feat|fix|chore|docs|refactor|test|release)\u002F[a-z0-9][a-z0-9-]*$ ]]; then\n  echo \"❌ Branch '$BRANCH' does not match canonical pattern \u003Ctype>\u002F\u003Cchange-id>.\"\n  echo \"   FIX: rename via 'git branch -m \u003Cnew-name>' or use a chore\u002F* prefix for hot-fixes.\"\n  exit 1\nfi\n\nCHANGE_ID=\"${BRANCH#*\u002F}\"\n\n# OpenSpec change exists?\ncase \"$BRANCH\" in\n  chore\u002F*) ;; # exempt — chore branches don't need an OpenSpec dir\n  *)\n    if [ ! -d \"openspec\u002Fchanges\u002F$CHANGE_ID\" ]; then\n      echo \"❌ openspec\u002Fchanges\u002F$CHANGE_ID\u002F does not exist.\"\n      echo \"   FIX: create proposal first via \u002Fopsx:propose --no-slice $CHANGE_ID\"\n      exit 1\n    fi\n    ;;\nesac\n```\n\n### 2. Local validation\n\nIn order — abort on first failure:\n\n```bash\n# Working tree clean\ngit diff --quiet && git diff --cached --quiet || {\n  echo \"❌ Uncommitted changes. Commit or stash first.\"\n  exit 1\n}\n\n# Pre-commit (run on the branch's diff)\npython -m pre_commit run --from-ref main --to-ref HEAD || exit 1\n\n# Targeted tests (heuristic: discover changed test files OR fall back to full)\nCHANGED_TESTS=$(git diff --name-only main..HEAD | grep -E '^tests\u002F' || true)\nif [ -n \"$CHANGED_TESTS\" ]; then\n  python -m pytest -p no:asyncio $CHANGED_TESTS -q || exit 1\nelse\n  python -m pytest -p no:asyncio -q || exit 1\nfi\n\n# Ruff\npython -m ruff check . || exit 1\n```\n\n### 3. tasks.md completeness check\n\n```bash\nTASKS_FILE=\"openspec\u002Fchanges\u002F$CHANGE_ID\u002Ftasks.md\"\nif [ -f \"$TASKS_FILE\" ]; then\n  TOTAL=$(grep -cE '^\\s*-\\s*\\[[ xX]\\]' \"$TASKS_FILE\")\n  UNCHECKED=$(grep -cE '^\\s*-\\s*\\[ \\]' \"$TASKS_FILE\")\n  if [ \"$UNCHECKED\" -gt 0 ]; then\n    PCT=$(( (TOTAL - UNCHECKED) * 100 \u002F TOTAL ))\n    echo \"⚠️  tasks.md: ${PCT}% ticked, $UNCHECKED unchecked. Continue? [y\u002FN]\"\n    read -r REPLY\n    [ \"$REPLY\" = \"y\" ] || exit 1\n  fi\nfi\n```\n\n### 4. Push branch\n\n```bash\ngit push -u origin \"$BRANCH\"\n```\n\nIf the branch already exists on remote: `git push` (no `-u`).\n\n### 5. Open PR\n\nPR title: derived from the LAST commit subject (or first commit if branch has 1 commit).\n\nPR body template (auto-generated from commit log):\n\n```\n## Summary\n\n\u003Cauto-generated from `git log main..HEAD --pretty=%s` — bullet per commit>\n\n## Test plan\n\n- [x] Pre-commit clean\n- [x] Targeted tests green (\u003CN> passed)\n- [x] Ruff clean\n- [ ] CI green\n- [ ] CodeRabbit review pass\n- [ ] Reviewer signoff\n\n## Cross-references\n\n- `openspec\u002Fchanges\u002F\u003Cchange-id>\u002Fproposal.md`\n\nEOF\n```\n\n```bash\ngh pr create --base main \\\n  --title \"$(git log -1 --pretty=%s)\" \\\n  --body \"$(cat \u003C\u003CEOF\n## Summary\n\n$(git log main..HEAD --pretty='- %s')\n\n## Test plan\n\n- [x] Pre-commit clean\n- [x] Targeted tests green\n- [x] Ruff clean\n- [ ] CI green\n- [ ] CodeRabbit review pass\n- [ ] Reviewer signoff\n\n## Cross-references\n\n- \\`openspec\u002Fchanges\u002F$CHANGE_ID\u002Fproposal.md\\`\nEOF\n)\" \\\n  ${DRAFT_FLAG:+--draft}\n```\n\n### 6. Monitor CI (optional, depends on user preference)\n\n```bash\nPR_NUM=$(gh pr view --json number --jq .number)\necho \"✅ PR #$PR_NUM opened. Waiting for CI...\"\ngh pr checks \"$PR_NUM\" --watch\n```\n\nIf `--auto-merge` flag was passed, enable it:\n\n```bash\ngh pr merge \"$PR_NUM\" --auto --merge\n```\n\n### 7. Print next steps\n\n```\n✅ dev-flow: shipped\n\nPR:        https:\u002F\u002Fgithub.com\u002F...\u002Fpull\u002F\u003CN>\nBranch:    \u003Ctype>\u002F\u003Cchange-id>\nCommits:   \u003CN> commits ahead of main\nDiff:      \u003Cadded> +\u002F\u003Cdeleted> -\n\nNext steps:\n  1. Address review feedback (CodeRabbit + 3-layer review per parallel-review.md).\n  2. Once approved, merge:\n       gh pr merge \u003CN> --merge --delete-branch    # (multi-commit, semantic — D2.1)\n       gh pr merge \u003CN> --squash --delete-branch   # (single-commit \u002F trivial — D2.2)\n     (See docs\u002Fconcepts\u002Fmerge-policy.md for the decision rule.)\n  3. After merge, archive the OpenSpec change:\n       openspec archive \u003Cchange-id>\n     (Verifies tasks.md is N\u002FN ticked per Followup #4.)\n  4. If this is the last PR for the next release, see docs\u002Frunbooks\u002Frelease.md\n     for the release-cut PR + tag procedure.\n```\n\n## Decisions\n\n- **D1.1** Two modes (`start`, `ship`) cover the lifecycle endpoints; the middle (implementation) is delegated to `\u002Fopsx:apply` (sequential) or `\u002Fopsx:apply-parallel` (multi-group). Rationale: the skill is an orchestrator, not a code generator.\n- **D1.2** Conventional-commit subjects auto-tick `tasks.md` via the pre-installed git hook. Rationale: per Followup #4, manual ticking drifts; auto-tick from commit subject is the only reliable channel.\n- **D1.3** Pre-flight runs `pre-commit + pytest + ruff` in order. Rationale: the cheapest checks first; a ruff failure is a 10s fix, a test failure may be 30 min — fail-fast cascades.\n- **D1.4** PR body is auto-generated from commit log. Rationale: encourages good commit messages by making them visible in the PR description.\n- **D1.5** The skill suggests but does NOT decide merge style. Rationale: per merge-policy.md D2.3, the maintainer always has final decision; the advisor (`pr-merge-style.yml` workflow) provides the recommendation.\n- **D1.6** No automatic `openspec archive` — the maintainer drives archive after merge. Rationale: archive depends on confirming the merge actually shipped without revert; automating it would be premature.\n\n## Anti-patterns\n\n- **Bypassing `\u002Fdev-flow start` for \"I'll just commit directly\"**: ends up with a branch named `my-changes` that fails branch-name-validator at PR-open time. The 30-second cost of running the skill saves the rename + force-push later.\n- **`\u002Fdev-flow ship` before all tasks ticked**: the skill warns; if you `y` past it, `check-tasks-checkboxes.yml` will comment on the PR with the gap. Tick honestly OR file a `tasks.md` amendment first.\n- **Running `\u002Fdev-flow start` inside an existing in-flight change directory**: refused — the skill won't extend an in-flight change without `--extend` (not yet implemented; manual `cd` required for now).\n\n## Cross-references\n\n- [`docs\u002Fconcepts\u002Fdevelopment-flow.md`](..\u002F..\u002Fdocs\u002Fconcepts\u002Fdevelopment-flow.md) — the canonical doc this skill operationalises.\n- [`docs\u002Fconcepts\u002Frelease-management.md`](..\u002F..\u002Fdocs\u002Fconcepts\u002Frelease-management.md) — release process the skill respects.\n- [`docs\u002Fconcepts\u002Fmerge-policy.md`](..\u002F..\u002Fdocs\u002Fconcepts\u002Fmerge-policy.md) — squash vs merge-commit (skill suggests, doesn't decide).\n- [`docs\u002Frules\u002Fconflict-resolution-policy.rule.md`](..\u002F..\u002Fdocs\u002Frules\u002Fconflict-resolution-policy.rule.md) — what happens when 2 ships collide.\n- [`scripts\u002Fauto_tick_tasks.py`](..\u002F..\u002Fscripts\u002Fauto_tick_tasks.py) — the auto-tick implementation triggered by the hook.\n- [`templates\u002Fgit-hooks\u002Fprepare-commit-msg`](..\u002F..\u002Ftemplates\u002Fgit-hooks\u002Fprepare-commit-msg) — the hook this skill installs.\n- [`scripts\u002Fwt_add.py`](..\u002F..\u002Fscripts\u002Fwt_add.py) — worktree creation (when ≥ 3 concurrent slices).\n- [`skills\u002Fopenspec-propose\u002FSKILL.md`](..\u002Fopenspec-propose\u002FSKILL.md) — used internally by `start` to scaffold the proposal.\n- [`skills\u002Fopenspec-apply-change\u002FSKILL.md`](..\u002Fopenspec-apply-change\u002FSKILL.md) — sequential implementation (called between `start` and `ship`).\n- [`skills\u002Fopenspec-apply-parallel\u002FSKILL.md`](..\u002Fopenspec-apply-parallel\u002FSKILL.md) — parallel implementation when tasks.md has disjoint groups.\n",{"name":5,"license":15,"metadata":44,"description":7},{"spec":45,"author":46,"version":47},"docs\u002Fconcepts\u002Fdevelopment-flow.md","ai-playbook","1.0","main","08fe7aa0f06bc1a3f592ec82360e46b854846968","skills\u002Fdev-flow",1,"https:\u002F\u002Fgithub.com\u002FWizarck\u002Fai-playbook","https:\u002F\u002Fgithub.com\u002FWizarck","https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Framirezarturo\u002F","Geek by birth, with not much to say but plenty to talk about.","2026-11-09 19:34:21",{"source":8,"skillName":5,"commands":58,"prompt":68,"zipAvailable":69},[59,62,65],{"tool":60,"command":61},"npx","npx skills add Wizarck\u002Fai-playbook --skill dev-flow",{"tool":63,"command":64},"bunx","bunx skills add Wizarck\u002Fai-playbook --skill dev-flow",{"tool":66,"command":67},"pnpm","pnpm dlx skills add Wizarck\u002Fai-playbook --skill dev-flow","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FWizarck\u002Fai-playbook\u002Fblob\u002Fmain\u002Fskills\u002Fdev-flow\u002FSKILL.md",true,[],[72,98,117,141,160,173],{"skillNo":73,"name":74,"nameZh":6,"description":75,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":76,"licenseFileUrl":6,"sourceHtmlUrl":77,"categories":78,"keywords":79,"publishedAt":39},"01M71FATTWS9W3BME3S94SA1QR","sweep","Use when the user wants to find code that has quietly stopped being used — types \u002Fsweep, asks for a \"dead code sweep\", \"repo entropy\", \"what can we delete\", \"orphan files\", \"unused code\", or asks to review a sweep ledger. Adjudicates candidates a deterministic scanner already produced; it never deletes anything and never re-derives findings from raw source. Pairs with ponytail, which gates what gets written rather than what rots.","MIT","https:\u002F\u002Fgithub.com\u002FWizarck\u002Fai-playbook\u002Fblob\u002Fmain\u002Fskills\u002Fsweep\u002FSKILL.md",[],[74,80,81,82,83,84,85,86,87,88,89,90,91,92,93,30,94,95,96,97],"deterministic","which","never","entropy","types","for","repo","re","ponytail","orphan","files","unused","use","when","can","gates","review","candidates",{"skillNo":99,"name":88,"nameZh":6,"description":100,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":76,"licenseFileUrl":6,"sourceHtmlUrl":101,"categories":102,"keywords":103,"publishedAt":39},"01M71FAQKVDA209G7G5NMY9H1E","Use when the user wants the laziest solution that actually works — types \u002Fponytail, says \"be lazy\", \"lazy mode\", \"simplest solution\", \"minimal solution\", \"yagni\", \"do less\", or \"shortest path\", or complains about over-engineering, bloat, boilerplate, or unnecessary dependencies. Supports intensity levels lite, full, ultra (default). Pairs with caveman, which compresses prose, not code.","https:\u002F\u002Fgithub.com\u002FWizarck\u002Fai-playbook\u002Fblob\u002Fmain\u002Fskills\u002Fponytail\u002FSKILL.md",[],[88,104,105,81,106,84,107,108,109,110,92,93,30,111,112,113,114,115,24,116],"notice","do","lazy","mode","default","minimal","intensity","with","yagni","about","dependencies","2026","boilerplate",{"skillNo":118,"name":119,"nameZh":6,"description":120,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":76,"licenseFileUrl":6,"sourceHtmlUrl":121,"categories":122,"keywords":128,"publishedAt":39},"01M71FAMS250NKNF1PET9KNBBV","ponytail-review","Use when the user wants a code review focused exclusively on over-engineering — says \"review for over-engineering\", \"what can we delete\", \"is this over-engineered\", \"simplify review\", or invokes \u002Fponytail-review. Complements correctness\u002Fsecurity review; this one only hunts complexity in the current diff. Gated by the ponytail review_ponytail component.","https:\u002F\u002Fgithub.com\u002FWizarck\u002Fai-playbook\u002Fblob\u002Fmain\u002Fskills\u002Fponytail-review\u002FSKILL.md",[123],{"categoryNo":124,"categoryName":125,"taxonomyType":126,"taxonomyTypeDesc":127},"01JBSEEDCAT000000000000007","代码审查","SCENARIO","使用场景",[129,88,96,130,131,85,132,133,92,93,134,135,30,136,94,137,138,139,140,24],"ponytail review","complexity","diff","code review","only","simplify","correctness","one","delete","component","security review","gated",{"skillNo":142,"name":143,"nameZh":6,"description":144,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":76,"licenseFileUrl":6,"sourceHtmlUrl":145,"categories":146,"keywords":147,"publishedAt":39},"01M71FAG53ZPCSWE272P6S9JFN","ponytail-debt","Use when the user wants to harvest every `ponytail:` comment in the codebase into a tracked debt ledger — says \"ponytail debt\", \"\u002Fponytail-debt\", \"what did ponytail defer\", \"list the shortcuts\", \"ponytail ledger\", or \"what did we mark to do later\". One-shot report, changes nothing. Gated by the ponytail debt_ponytail component.","https:\u002F\u002Fgithub.com\u002FWizarck\u002Fai-playbook\u002Fblob\u002Fmain\u002Fskills\u002Fponytail-debt\u002FSKILL.md",[],[148,88,149,150,105,151,152,138,153,154,140,155,156,24,157,158,92,93,159,136],"ponytail debt","debt","shortcuts","mark","to do","changes","later","report","codebase","harvest","list","ledger",{"skillNo":161,"name":162,"nameZh":6,"description":163,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":76,"licenseFileUrl":6,"sourceHtmlUrl":164,"categories":165,"keywords":166,"publishedAt":39},"01M71FACJW88WCS2JGX3MQ3KV9","ponytail-audit","Use when the user wants a whole-repo audit for over-engineering — says \"audit this codebase\", \"audit for over-engineering\", \"what can I delete from this repo\", \"find bloat\", or invokes \u002Fponytail-audit. Like ponytail-review but scans the entire tree, not a diff. One-shot report, applies no fixes. Gated by the ponytail audit_ponytail component.","https:\u002F\u002Fgithub.com\u002FWizarck\u002Fai-playbook\u002Fblob\u002Fmain\u002Fskills\u002Fponytail-audit\u002FSKILL.md",[],[167,88,168,169,131,170,85,86,92,93,171,136,94,96,137,138,140,172,155,156],"ponytail audit","audit","tree","fixes","entire","find",{"skillNo":174,"name":175,"nameZh":6,"description":176,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":76,"licenseFileUrl":6,"sourceHtmlUrl":177,"categories":178,"keywords":179,"publishedAt":39},"01M71FA9THHXDX79PQTJ9CZX9E","openspec-propose","Propose a new change with all artifacts generated in one step. Use when the user wants to quickly describe what they want to build and get a complete proposal with design, specs, and tasks ready for implementation.","https:\u002F\u002Fgithub.com\u002FWizarck\u002Fai-playbook\u002Fblob\u002Fmain\u002Fskills\u002Fopenspec-propose\u002FSKILL.md",[],[180,181,111,38,182,29,28,183,184,85,185,186,187,188,189,190,92,93,191,192],"openspec","openspec propose","proposal","get","build","complete","design","new","implementation","generated","describe","artifacts","tasks"]