# os-backlog — component detail _Leaf file of [../implementation-status.md](../implementation-status.md). Read on demand._ **Global os-backlog plugin** — `cc-os/plugins/os-backlog/` (git-tracked, 2026-07-10); symlinked into `~/.claude/plugins/os-backlog`; PRD Forgejo issue #9 (state pointer: Planka card `1816234194716592051`), slices #10–#17. Decision records: ADR-0023 (own plugin, not an os-vault extension), ADR-0025 (standard Ruby plugin structure), ADR-0029 (card-move + column ownership). ## Component inventory - Purpose: the AI's process-management surface over Planka — deterministic tracker routing (Planka = task state by default; git issues = implementation specs only), mid-session capture, pull-only listing, board lifecycle, and the three-value autonomy convention (`hitl`/`semi`/`afk-ready`; amended per ADR-0029: afk-ready ships straight to Done, semi stops at Review). - Lib (Ruby, os-adr `lib/`+`bin/` pattern, installed planka-api gem only — no source coupling): `board_spec.rb` (uniform lists/labels contract), `board_ensurer.rb` (idempotent create/repair; Planka 2.1.1 `type` fields, shared-project + owner-manager visibility fix, label color candidates with fallback; `archived--` rename convention), `config.rb` (`.cc-os/config` parser), `resolver.rb` (pure repo→board decision: `use`/`activate`/`stop-and-discuss`; no network), `cards.rb` (add-at-Backlog, snapshot, attach_label, comment, move with ownership rules), `tracker.rb` + `inspector.rb` (2026-07-12, issue #14 — tracker-format validation/remote classification + in-repo issue-file discovery; `Config.merge` preserves other keys). - CLI: `bin/os-backlog` — `board-ensure`, `activate`, `archive`, `resolve`, `card-add`, `cards`, `snapshot`, `card-label`, `card-comment`, `card-move` (2026-07-12, ADR-0029), `inspect`, `config-write`; every path fails soft (one-line error, exit 1) when the gem/Planka is unavailable. - Skills: `/os-backlog:capture`, `/os-backlog:list` (pull-only per notification policy v2), `/os-backlog:route` (2026-07-12, issue #14 — tracker onboarding conversation; destination choice + live-history migration are named human gates) — carry the column-ownership rules (AI creates at Backlog, Doing→Review at most, never Next, never self-assigns `hitl`; "working a card means moving it" contract added 2026-07-12). - Agents: `agents/card-triage.md` (priority + autonomy labels only; ambiguity → `hitl`), `agents/board-audit.md` (four drift classes; writes at most comments). - Tests: `tests/` — 68 runs/153 assertions as of 2026-07-12 (35 → 54 → 58 → 68 across the slices) against an in-memory `FakePlankaClient`; no live API. Companion os-status check `tracker-configured` (issue #11) validates the `tracker` key grammar and nudges unconfigured git projects (daily-snoozed). ## Build and verification history - **AFK slices shipped (2026-07-10):** #10 plugin scaffold + `board-ensure` (uniform lists/labels incl. new `semi` autonomy label), #11 `tracker` key in `.cc-os/config` + os-status check, #12 pure routing resolver CLI, #13 capture/list skills + card CLI, #15 `card-triage` + `board-audit` named agents. Live verification same day: planka-api gem 0.1.0 installed locally (`rake install`, rbenv 4.0.2; publish/versioning parked behind gem issue 13); `snapshot`, `board-ensure` (created the missing `semi` label on the cc-os board), `card-add` + `card-label` all succeeded against production Planka with bot credentials sourced from ovh-vps (`~/services/planka/bot-credentials.env`) in a subshell. Follow-up captured as a `hitl` Backlog card: get planka_bot into credvault (no import path — rotate vs. add import capability is a human decision). - **planka-api 0.2.0 typed-returns migration (2026-07-10, commit `8df0cb7`):** 0.2.0 returns `Planka::Types` value objects instead of parsed-JSON hashes. `board_ensurer.rb` and `cards.rb` rewritten on typed accessors; `Cards#snapshot` builds explicit string-keyed hashes from `BoardDetail#lists`/`#cards`/`#labels`/`#card_labels`. Test fakes rebuilt to return real `Planka::Types` records. JSON output stays byte-compatible, so skill/agent contracts are unchanged. Follow-up fix (issue #18, same day): the migration had silently dropped one field from the per-card snapshot hash; restored the full 19-key camelCase card key set plus `labels`, with a regression test pinning the key set including `listChangedAt`. - **Live verification 0.2.0 (2026-07-10, issue #20):** local machine had no `PLANKA_*` env/credvault entry, so the plugin tree was rsynced to `ovh-vps:/tmp/os-backlog-verify` and exercised there with bot credentials sourced in a subshell (contents never read or printed). Results: tests 35 runs/0 failures on ovh-vps; `board-ensure cc-os` idempotent (twice `(existing)`, nothing created); card-add/card-label/card-comment/snapshot all correct with the full 20-key set; test card deleted via `Planka::Client#cards.delete` (the CLI has no delete subcommand) and confirmed gone; verification tree removed. No regressions vs. pre-0.2.0. - **Slice 7 (2026-07-13, issue #16):** SessionStart injection note shipped (`hooks/session_start.py` + `hooks/hooks.json`, os-adr-style plugin-local hook): WHEN→THEN rules for capture / routing / promotion / column ownership / autonomy labels, ADR-0029 semantics (the issue body's "afk-ready → Review" was wrong — caught in Codex review), rules only, zero board state, ~447 tokens. `/to-issues` (global skill, `~/.agents/skills/to-issues/`) gained a destination-tracker step reading the `.cc-os/config` tracker key; the `planka:`/unset default publishes slices as git issues on the repo remote + one Planka pointer card (spec/state boundary preserved — human gate decided 2026-07-13). `Backlog::Tracker.issues_destination` + 6 routing tests. - **Board-id cache (2026-07-13, issue #22):** `Backlog::BoardResolver` with injected config read/write lambdas; `board_id=` cached in `.cc-os/config` beside `tracker=` (name stays source of truth; id honored only for `planka:` trackers and validated against the returned board name; 404/mismatch/any cache failure degrades to name lookup and rewrites the cache; write failures never fail the command). Comment-preserving `Config.set` mirrors os-status's writer. 14 new tests; suite 90 runs / 198 assertions / 0 failures. - **Outstanding:** slice #17 (ops board + rubric category + routing ADR; blocked-by #16 now cleared) awaits its human decision gates; #14 routing-skill rollout (onboard cc-os itself, then one more project) pending.