8.2 KiB
| 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>orgithub:<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.
-
Inspect (autonomous, mechanical). Run:
${CLAUDE_PLUGIN_ROOT}/bin/os-backlog inspectThis is read-only and safe to run without asking. It reports, as JSON:
tracker_configured— an existingtrackerkey 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:captureuses), or why that check couldn't run (gem/credentials unavailable — fail-soft, not blocking).git_remote— the parsedgit remote -v, classified asforgejo(the user's self-hosted instance) /github/unknown, plus the open-issue count viateaorghif that CLI is available (nullwith areasonif 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), ornull(no metadata, or fewer than 3 open issues — no evidence either way).in_repo_issue_files—docs/issues/and/orISSUES.mdif present.
-
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_shapeissequential-chainormixed): recommend the SPLIT as the default. Writeplanka:<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_shapeisflat-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. Ifissue_shapeisnull(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.
- (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;
-
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.mdentries to Planka, or from an unrouted Planka board to git issues). Exception — never re-trigger on the split: aplanka: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/ghissue-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.
-
Write the tracker key (autonomous, mechanical, once destination is confirmed).
${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. -
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-writeor 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.