cc-os/plugins/os-backlog/skills/route/SKILL.md

62 lines
8.2 KiB
Markdown

---
description: Onboard a project's issue tracker — inspect what tracking already exists, propose a destination per the Planka-state/git-issues-spec boundary rule, migrate existing open items with back-links, and write the tracker key to .cc-os/config. Use unprompted WHEN a project has no tracker key configured and process/backlog work surfaces, or when the user explicitly asks to set up or change how a repo's issues/backlog are tracked. Invoked by `/os-backlog:route`.
---
Register a project's issue tracker: figure out what already exists, propose where issue/backlog tracking should live, and — with the human's confirmation at each decision gate — migrate and record it.
## The boundary rule (what you're deciding between)
Planka = state, git issues = specs (ADR-0033, `docs/adr/0033-tracker-routing-planka-is-state-git-issues-are-specs.md`) — the ADR is the canonical statement; the operative routing rules are:
- **WHEN** the project's work is mostly ephemeral tasks, small fixes, or process/coordination (state: backlog/next/doing/review/done, nothing needing a durable written spec) → `planka:<board>`.
- **WHEN** work is specified as text that must survive and be referenced (features, migrations, architecture-level changes, tracer-bullet slices from `/to-issues`, PRDs from `/to-prd`) → `forgejo:<owner>/<repo>` or `github:<owner>/<repo>`.
- **WHEN** a project already tracks issues in-repo (`docs/issues/`, `ISSUES.md`) and wants to stay there → `repo:<path>` (the escape hatch).
- **WHEN** a code effort needs both state tracking and a durable spec → card-as-pointer + issue-chain-as-spec: the Planka card is a pointer (title + link) into the git issue chain holding the spec; never duplicate spec text into the card description.
- **WHEN** a Planka-tracked effort accretes significant code/design decisions in card comments → flag promotion to the user (open a git issue chain for the spec, turn the card into a pointer); never promote silently.
Valid tracker key formats (exactly one, written to `.cc-os/config`'s `tracker` key): `planka:<board>` | `forgejo:<owner>/<repo>` | `github:<owner>/<repo>` | `repo:<path>`.
## Procedure
All commands use the plugin CLI at `${CLAUDE_PLUGIN_ROOT}/bin/os-backlog`.
1. **Inspect (autonomous, mechanical).** Run:
```bash
${CLAUDE_PLUGIN_ROOT}/bin/os-backlog inspect
```
This is read-only and safe to run without asking. It reports, as JSON:
- `tracker_configured` — an existing `tracker` key in `.cc-os/config`, if any. If this is already set, tell the user the project is already routed to it and confirm they want to re-route before continuing (re-routing is itself a decision gate — treat it as step 2).
- `planka` — whether a Planka board already resolves for this repo (via the same resolver `/os-backlog:capture` uses), or why that check couldn't run (gem/credentials unavailable — fail-soft, not blocking).
- `git_remote` — the parsed `git remote -v`, classified as `forgejo` (the user's self-hosted instance) / `github` / `unknown`, plus the open-issue count via `tea` or `gh` if that CLI is available (`null` with a `reason` if not — fail-soft, not blocking).
- `issue_shape` — a classification of the open git issues' shape: `sequential-chain` (most issues carry dependency labels or blocked-by/depends-on cross-references), `flat-adhoc` (no dependency structure), `mixed` (some), or `null` (no metadata, or fewer than 3 open issues — no evidence either way).
- `in_repo_issue_files``docs/issues/` and/or `ISSUES.md` if present.
2. **Synthesize and propose (NAMED DECISION GATE).** Exactly ONE tracker key is ever written to `.cc-os/config` — the branches below differ in *which* key and *what happens to existing issues*, never in how many keys. Branch on the findings:
- **(a) No existing tracker found** (no open git issues, no in-repo issue files, no live board): propose one destination key with a short rationale grounded in the boundary rule — e.g. "no existing tracking found, work here is small ad hoc fixes; `planka:<repo-name>` fits Planka-as-state; a board will be created on first capture, not by this skill."
- **(b) Existing git issues that are spec-shaped** (`issue_shape` is `sequential-chain` or `mixed`): recommend the **SPLIT as the default**. Write `planka:<board>` as the single declared tracker — it governs new/ephemeral capture only. The existing git issues are specs per ADR-0033: they stay exactly where they are, unmigrated, and remain the durable spec surface; skip migration entirely (step 3 does not apply to them). This is still exactly one tracker key — the split is a division of labor (state vs specs), not two destinations.
- **(c) Existing git issues that are flat-adhoc** (`issue_shape` is `flat-adhoc`): migration to Planka is on the table — propose the destination key, and if confirmed, existing open issues go through the step-3 migration gate as usual. If `issue_shape` is `null` (no metadata or too few issues to tell), treat shape as unknown: ask the user which shape fits rather than assuming.
**Stop here and wait for the user to confirm or override the destination before writing anything or moving anything.** If findings are ambiguous (e.g. both a live Planka board AND an active issue tracker with open items, and it's unclear which is authoritative), say so plainly and ask rather than guessing.
3. **If migration is needed (SECOND NAMED DECISION GATE).** Only applies when the confirmed destination differs from where open items currently live (e.g. moving from ad hoc `ISSUES.md` entries to Planka, or from an unrouted Planka board to git issues). **Exception — never re-trigger on the split:** a `planka:` tracker alongside by-design git spec issues (branch 2b, or any project whose git issues are specs per ADR-0033) is the intended end state, not a discrepancy; do not propose migrating those issues, now or on any later re-run of this skill. Before touching any live project history:
- Tell the user exactly what will move (list the items) and ask for explicit go-ahead. This gate is separate from the destination gate in step 2 — confirming the destination is not confirming the migration.
- Once confirmed, migrate mechanically using **existing machinery, not new code paths**: `card-add`/`cards` (via `/os-backlog:capture`'s CLI calls) for items moving into Planka; `tea`/`gh` issue-create commands for items moving into git issues. Do not invent bespoke migration scripts.
- **Back-link both ways so nothing is double-tracked**: the old item (closed Planka card comment, closed in-repo issue entry, or a note in the git-host issue if migrating away from it) gets a pointer to its new home; the new item (card description or issue body) links back to the source. Close/archive the old item once the back-link is in place — don't leave both open.
4. **Write the tracker key (autonomous, mechanical, once destination is confirmed).**
```bash
${CLAUDE_PLUGIN_ROOT}/bin/os-backlog config-write <tracker-value>
```
The CLI validates the format and rejects anything malformed — if it fails, relay the error verbatim and re-ask rather than hand-editing `.cc-os/config`.
5. **Close out.** Tell the user the tracker is set and that the os-status tracker warning (ADR-022/ADR-026) goes silent starting next session.
## Decision gates (non-negotiable)
- **Destination gate (step 2):** never call `config-write` or move anything before the human has confirmed which tracker to use.
- **Migration gate (step 3):** even after the destination is confirmed, migrating *existing open items* (live project history) needs its own explicit go-ahead — a destination choice for new work is not consent to move old work.
- Inspection (step 1) and the final `config-write` (step 4) are mechanical and run without a gate — they don't change or move anything you haven't already been told to.
## Failure behavior
Fail soft, per the plugin convention. `inspect`'s individual checks (Planka, tea/gh) degrade gracefully and are reported as unavailable rather than aborting the whole command — relay those as informational, not blocking, unless the missing signal is the only way to make the destination decision (in which case say what's missing and ask the human directly). `config-write` fails loudly on an invalid tracker value — relay the CLI's error verbatim.