6.3 KiB
Design: retire-planka-git-issues-only
Context
os-backlog today (post-slice-8, 2026-07-13): Ruby lib + CLI over both a Planka board model
(board-ensure/resolve/card-*) and tracker inspection (inspect, tracker.rb,
project_index.rb), skills (capture/list/route), two Planka agents, a SessionStart
rules note (~447 tokens), an os-status grammar check, and a wakeup poller that already
reads git issues. ADR-0042 retires the Planka half. The issue-side plumbing (tea for
Forgejo, gh for GitHub, in-repo files for repo:) already exists and is what real work
has used. Constraint: the plugin is globally installed and ambient on every machine — the
rework must land whole (no half-migrated grammar), and source edits require
bin/refresh-plugins to reach sessions.
Goals / Non-Goals
Goals:
- One tracker per project holds both state and specs;
planka:gone from the grammar. - Preserve the durable process contracts: mid-session capture, pull-only listing, priority + autonomy labels, human-only curation gate, cross-project filing.
- Leave zero dormant Planka infrastructure: cards migrated, server down, gem archived, credentials revoked.
Non-Goals:
- A unified dashboard over git issues (explicitly deferred until it is a felt pain point).
- Reworking the wakeup poller (already issue-based; only its label reads are re-checked).
- Bulk re-onboarding of projects beyond rewriting their
tracker=values. - Any new home for client management (Invoice Ninja et al. own that; out of scope).
Decisions
- State model = open/closed + labels, no status-label state machine. Columns
Backlog/Next/Doing/Waiting/Review/Done collapse to: open issue (backlog),
nextlabel (human-curated), assignee/linked-branch activity (doing — no label to maintain),waitinglabel + a blocker comment,reviewlabel (semi work shipped), closed (done). Rationale: every label the AI must maintain is a compliance cost the incentives review flagged; keep only labels that carry information a human filters on. Alternative rejected: full column-equivalent label set (doing,done) — duplicates what issue state and assignment already express. - Curation gate:
nextis human-only in skill/hook prose, not CLI-enforced. ADR-0029's CLI enforcement existed because Planka moves were CLI-mediated; issue labels are set via tea/gh which os-backlog does not proxy. The rule lives in the SessionStart note + skills, and the session-audit rubric (os-context category 8) measures compliance. Alternative rejected: wrapping tea/gh in an enforcing CLI — rebuilds the proxy layer the retirement is deleting. - Non-repo/ops work: a private
opsForgejo repo,tracker=forgejo:jared/ops. The recurring Operations card becomes a recurring-convention issue there (comment + reopen/leave-open, never close — mirrors the existing recurrence contract). Alternative rejected:repo:<path>files — loses labels and the wakeup/query surface for the one place recurring process work lives. - Migration before demolition, human gate on client data. Card migration runs while
Planka is still up; philly-search-engine-marketing (23 cards, real client backlog) is
migrated only after per-card human sign-off (destination: the client project's tracker
or the ops repo). cc-os non-Done cards → Forgejo
jared/cc-osissues. Done cards are not migrated (history stays in a final JSON snapshot archived to the ops repo before decommission). Rollback: the snapshot + a Postgres dump taken before server teardown. - Code removal is deletion, not deprecation.
board_ensurer/board_resolver/ board_spec/cards(Planka transport), both agents, and gem wiring are deleted with their tests;tracker.rb/inspector.rb/config.rb/project_index.rb/wakeup.rbsurvive.Config#planka_boardandResolverboard logic go. Grammar validation rejectsplanka:with a pointer to ADR-0042. Alternative rejected: feature-flagging Planka off — dormant-code variant of the dormant-server trap. - planka-api gem: archive the repo, keep no dependency. The gem is user-authored and unpublished; archival (read-only, README pointer to ADR-0042) preserves the reverse-engineering knowledge without implying maintenance. The vault gotchas note stays — it documents the API, not our use of it.
Risks / Trade-offs
- [Untested non-repo workload loses its designated surface] → ops-repo issues are the cheap test ADR-0042 calls for; revisit via a new ADR if it chafes in practice.
- [AI label discipline unenforced] → session-audit rubric already measures tracker-routing compliance; the label contract is smaller than the column contract it replaces (fewer states, fewer rules).
- [Client board migration loses nuance (comments, label history)] → per-card human gate; full JSON snapshot archived first.
- [Stragglers:
.cc-os/configfiles on other machines still sayingplanka:] → config-write/os-status check rejects the value with a one-line re-route instruction; fail-soft, never blocks a session. - [Forgejo becomes a single point of failure for process state] → it already was for specs and wakeup; repos sync to it from every machine and it is backed up with the VPS.
Migration Plan
- Land the plugin rework + spec deltas (tests green,
bin/refresh-plugins). - Snapshot all boards to JSON; archive snapshot in the ops repo; Postgres dump on ovh-vps.
- Create
jared/opsrepo + label set; move the recurring audit issue there. - Migrate cc-os non-Done cards →
jared/cc-osissues (labels carried over). - Human-gated pass over philly-search-engine-marketing cards.
- Rewrite
tracker=in onboarded projects'.cc-os/config. - Revoke bot credentials; decommission Planka on ovh-vps; archive the gem repo.
- Update docs: implementation-status leaf + index line, CLAUDE.md inventory line, backlog-pilot vault note.
Rollback (any step before 7): Planka is still running; restore config values. After 7: restore from Postgres dump — accepted as effectively one-way once step 7 runs.
Open Questions
- Whether
philly-search-engine-marketingcards land in a client repo tracker or the ops repo (human decision during step 5). - Which machine's cron (if any) hosts the wakeup poller — pre-existing open item, not blocked by this change.