cc-os/docs/implementation-status/os-backlog.md

7.6 KiB
Raw Blame History

os-backlog — component detail

Leaf file of ../implementation-status.md. Read on demand.

Global os-backlog plugincc-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-backlogboard-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.
  • Slice 8 (2026-07-13, issue #17): Operations board created in the Dev project (board 1818308120145822783) with uniform lists/labels; recurring card "Biweekly orchestration IRL audit (recurring)" (card 1818310715438531668, P2 + semi, first progress comment 1818310889929966683; recurrence contract: comment + move back to Backlog, never Done). Tracker-routing convention canonized as ADR-0033 (Planka = state / git issues = specs, tracker key grammar, pointer + promotion rules; cites route/to-issues/session-start rather than restating). os-context audit rubric gained category 8 tracker-routing (capture/route/promote compliance only). Bug found live and fixed: label color fallback only rescued Planka::ValidationError, but Planka rejects unknown colors as HTTP 400 Planka::BadRequestError — fallback now rescues both (regression test; suite 91 runs / 0 failures). os-status /os-status:fix step d reworded: invoke /os-backlog:route directly, never pre-ask "forgejo or planka?" (boundary rule uses both — surfaced by the servers-repo onboarding, cf. issue #26).
  • Outstanding: #14 routing-skill rollout (onboard cc-os itself, then one more project); #26 route-inspect issue-shape classification; #27 cross-project filing index; #28 wakeup design spike.