20 KiB
| summary | tags | status | last_reviewed | |||||
|---|---|---|---|---|---|---|---|---|
| Backlog decision + pilot plan (Planka CE on OVH, live 2026-07-08, phone gate passed 2026-07-09) — Dev + Clients Planka projects with per-repo/per-client boards, kanban WIP flow with human/AI column ownership, thin Ruby gem/CLI + tick, pull-based unified dashboard (digest + SessionStart brief dropped), vault demoted to knowledge layer |
|
accepted-pilot-live | 2026-07-10 |
Backlog system: decision and pilot plan v2 (2026-07-06)
Research behind this decision: backlog-system-options-research (including the same-day second-pass Planka deep-dive and alternatives sweep).
Supersedes the v1 vault-native plan (same day). v1 chose vault task notes + Obsidian Bases kanban. It was overturned within hours by a requirement clarification, recorded here so the reasoning survives:
The requirement change that flipped the decision
The perspectives panel and v1 optimized for "push beats pull." The user corrected this: the pull surface — a visual board viewable and interactable from anywhere, any device, any time — is the primary requirement, not a nice-to-have. The founding pain point is "when I want to jump into a project I have no visual interface to see what's on the docket," and with ADHD a desktop-only interface means forgotten/missed tasks. Conversational access ("what's on my plate?" via chat) does not satisfy this; it must be visual.
- Vault-native's known weakness (dashboard maturity, mobile — Bases custom views are desktop-weak) became disqualifying.
- Planka's known weakness (task data outside markdown) became "a development problem" — solvable via REST API, per the user.
Decision
- Planka v2 Community Edition (AGPL, plankanban/planka) deployed on the OVH production server (
systems-prod-01, see~/servers/ovh-prod/), as a standard~/services/planka/docker-compose service behind Traefik with automatic SSL. Auto-discovered by the existing backup script. - Why OVH, not the home Proxmox box / hermes01: always-on independent of home ISP/power; already reachable from anywhere with SSL (phone needs a bookmark, not Tailscale); fits the established deploy + backup pattern. Access control (strong auth at minimum; optional Traefik middleware/IP allowlist — client names will appear on cards) is a deploy-time decision.
- No filesystem co-location with the vault is needed. Planka state is Postgres; all integration (CLI, tick, digest, future Hermes) goes through Planka's REST API + git. Cards reference SecondBrain notes by name/URL; any host that ever needs note content clones the vault from Forgejo (one command). The vault does NOT currently sync to OVH and doesn't need to.
- Vault role demoted to knowledge layer: how-tos, contractor/client notes, conventions, decisions stay in SecondBrain; task state lives in Planka. The proven Notion rental pattern (item-with-references) survives split across the two: card = state + links, vault note = knowledge.
- Forgejo issues remain the code-execution tracker (rule unchanged: Forgejo = code/arch/deployment work inside a repo; Planka = everything else; cards may link issues).
- CLI over MCP. No official Planka CLI exists; we build a thin Ruby one (Sandi Metz style,
lib/+bin/, mirroring the os-adr pattern) over the REST API.plankapy(Python SDK) is the endpoint-reference crib. Community MCP servers (bradrisse/kanban-mcp etc.) are shelf reference only.
Repo/artifact separation + gem scope (2026-07-07 amendment)
- Three repos, three concerns: deploy artifacts (compose, cron wiring, config, deploy PRD/runbook) live in
~/servers/ovh-prod/; the Ruby gem (API client +backlogCLI + tick/digest logic) lives in~/dev/ruby-gems/; cc-os carries only the SessionStart-brief plugin + its eval harness. The plugin depends on the gem's installed binary — no cross-repo source coupling. ovh-prod stays behavior-free (compose + cron + config only) so all logic remains model-free-testable inside the gem. - Gem is two-layer: (1) a thin faithful client layer wrapping the Planka REST API broadly — core resources (projects/boards/lists/cards/tasks/due-dates/labels/comments/memberships/auth) plus webhooks (decided: wanted, so Planka can trigger strategic outbound actions via n8n/other APIs) and admin + attachments (less certain but likely useful — included in the first pass on the grounds that shipping probably-working endpoints now beats reopening the client later; Planka API churn judged low-risk); (2) a small opinionated domain layer (
add --quick,list --all,tick) used by the CLI, digest, and future Hermes. Client layer generated with theapi-wrapperskill,plankapyas endpoint crib. Per-credential instantiation (no global auth singleton) to support Hermes' scoped tokens. - PRDs drafted 2026-07-07: deploy PRD → ovh-prod repo docs; gem PRD → ruby-gems repo. cc-os plugin PRD deferred to Phase 1 (plugin-home decision resolved 2026-07-10: new
os-backlog, ADR-023).
Organization + workflow v2 (2026-07-09 amendment — gate passed)
Phone gate PASSED 2026-07-09 (Planka v2.1.1 live at planka.hyperthrive.io since 2026-07-08). The per-hat board seeding from Phase 0 is superseded before it ran; this section replaces it.
Structure — two Planka projects, boards per unit of work:
- Dev project → one board per dev effort. Initial boards: cc-os and planka gem (
~/dev/ruby-gems/planka— gem v1 is functionally complete but never went through an organized check-off; its existing "Build" board cards get walked through Review as the first exercise of the process). - Clients project → one board per client. Initial board: philly-search-engine-marketing (
~/clients/philly-search-engine-marketing/). Client cards are PM-altitude: each either links a Dev board that executes it (URL in description — no first-class card links in Planka) or carries its own task checklist when too small for a dev board. - Property management and business-dev boards deferred — hypothetical/nuanced; revisit after living with the system.
- Uniform lists on every board:
Backlog → Next → Doing → Waiting → Review → Done(Waiting = blocked on outside input, doesn't count against WIP). - Labels are board-scoped in Planka, so the CLI/seeding scripts enforce an identical label set on every board:
P0/P1/P2/P3(priority; P3 added 2026-07-10 for the Apprise expansion cards — currently only on the cc-os board,backlog board ensureshould adopt it) +hitl/afk-ready(AI-workability convention, adopted from the gem issue cards).
Process — kanban with WIP limits, not agile sprints. Capture into Backlog is cheap; pulling into Next is the only planning ritual (when Next runs dry, not on a calendar); Doing is hard-capped at 2–3 for the human; cards flow one direction.
Human/AI column ownership: the human pulls into Next and is the only mover of Review → Done. AI agents pull Next → Doing when pointed at work, comment progress on the card, and land finished work in Review — never Done. AI-created cards (tick recurrence, captured tasks) enter at Backlog only. hitl-labeled cards are never picked up by AI autonomously.
Notification policy v2 — digest and SessionStart brief DROPPED (mental-clutter / notification-blindness risk; pull beats push applies to notifications too). Replaced by a single pull-based unified dashboard: a lightweight web view next to Planka on OVH reading via the API — due/P0/Doing/Review cards across all boards, rows linking into Planka. One starting-point view, opened when the user chooses. NOT Rails — lightweight JS (à la ~/dev/thinkfast/) or similar; details deferred to its own Planka card. The tick recurrence job survives unchanged (writes cards, never notifies).
Pre-seeding audits: before creating cards, audit each of the three initial projects to collect all outstanding items + where they're referenced in the repo (docs, TODOs, issues, PRDs), so dispatched card-writing subagents populate cards with full context and pointers.
Tracker routing (amends the Forgejo rule): Planka is the default target for /to-issues and any future /triage — the plugin skill resolves repo → board deterministically (board named after the repo/client dir; Dev vs. Clients project inferred from ~/dev/* vs ~/clients/*) and a backlog board ensure script creates missing boards with the standard lists + labels. Forgejo remains only where issue-linked commits/PRs in a repo justify it.
Board lifecycle (archive/activate) — VERIFIED 2026-07-09: live-instance API tests confirmed Planka v2.1.1 CE cannot move a board between projects (projectId is not a patchable field), cannot move cards across projects (E_NOT_FOUND on foreign listId), and board DELETE is permanent (cascades, no restore — never use for archiving). The Archive-project design is therefore dead; lifecycle is the rename convention: archiving = rename board archived--<name> + move to bottom position (ONLY on explicit human go-ahead); activating = rename back (no approval needed). Discovery via the API board listing: active board found → use; archived-- board found → activate silently; not found for an existing repo → stop and discuss. Label CRUD verified working per board (POST /api/boards/:id/labels, PATCH/DELETE /api/labels/:id; 41-name color whitelist, no hex). Also verified 2026-07-09 during seeding: creates require an undocumented type field — projects "private", lists "active", cards "project"; card-label attach is POST /api/cards/:cardId/card-labels {labelId}. Project visibility gotcha: a bot-created project gets ownerProjectManagerId set (single-owner "private" mode) and is invisible to every other account — even instance admins can't add managers (E_FORBIDDEN). Fix/required pattern for backlog board ensure: after create, PATCH the project with {"ownerProjectManagerId": null} (as the owner; {"type":"shared"} is silently ignored), then POST the human's userId to /api/projects/:id/project-managers.
Plugin scope widened: the cc-os plugin (decided 2026-07-10: new os-backlog plugin, ADR-023 — separation of concerns; os-vault stays memory/knowledge-only) is the AI's process-management surface and should be designed across all four plugin primitives: skills (capture/list/tick/board ops), scripts (deterministic API calls via the gem), named agents (e.g. card-triage, board-audit), and hooks (where session lifecycle genuinely helps — no push-style briefs per the notification policy).
Execution breakdown (2026-07-09) — grouped by subagent + model tier; Fable orchestrates and reviews only. Status 2026-07-09: steps 1–3 DONE (API verified, 3 audits run, boards seeded: Dev {cc-os, planka} + Clients {philly-search-engine-marketing}, 50 cards incl. 12 gem slices in Review and a dashboard-design card; old "planka-api gem" project left in place pending human deletion go-ahead):
- API verification (haiku, 1 agent, first — everything downstream depends on it): against the live instance, test board-move-between-projects, cross-project card moves, label CRUD per board. Mechanical curl/gem calls; report findings only.
- Project audits (sonnet, 3 parallel agents — judgment: what counts as an outstanding item): one each for cc-os,
~/dev/ruby-gems/planka,~/clients/philly-search-engine-marketing. Sweep docs/TODOs/issues/PRDs; return itemized outstanding work with file references, suggested priority (P0–P2), and hitl/afk-ready call. - Structure + seeding (1 agent, after 1+2): create Dev + Clients projects (no Archive project — boards can't move between projects, see lifecycle above), boards per convention, uniform lists + labels; write cards from the audit outputs (no human pre-approval — 2026-07-09: human wants to see the AI's card decisions and adjust after). Since the existing "planka-api gem" project's Build board can't be moved into Dev, recreate the gem board fresh in Dev: the 12 verified-done build slices become cards in Review (the check-off exercise), audit findings in Backlog/Waiting; the old project is left untouched pending a human deletion go-ahead.
- Dashboard (sonnet — design first as its own Planka card, then build): lightweight JS app on OVH reading the Planka API.
- Plugin (sonnet build after a Fable/human design pass — the os-backlog vs. extend-os-vault decision, skill/agent/hook inventory, and tracker-routing skill are design-tier): then card-triage/board-audit named agents,
backlog board ensurescript wiring,/to-issuesrouting. - tick cron on OVH (haiku): unchanged from Phase 1.
Human gates: archive go-aheads always, plugin design decision (5), gem-card Review→Done acceptance. (Card-content pre-approval rescinded 2026-07-09.)
Plugin home + notification transport (2026-07-10 amendment)
- Plugin decision resolved (human gate passed): new
os-backlogplugin in cc-os, NOT an os-vault extension — separation of concerns (memory/knowledge vs. workflow/process, different stores and failure modes). Recorded as cc-os ADR-023, which also makes the ecosystem framing explicit: cc-os = the always-on personal operating layer (os-*plugins, mutually aware over time, on every machine);~/dev/cc-plugins= optional as-needed plugins. - Apprise supersedes Pushover as the notification transport (cc-os ADR-024). Planka natively speaks Apprise; the user's services (Discord, Telegram, Bark, Home Assistant, Gnome, Zoom, Pushover) are all Apprise targets. This iteration stays minimal: Apprise API server as a docker-compose service on OVH + swap the gem's Pushover P0 for a minimal Apprise
notifyclient. Expansion seeded as P2/P3 cards on the cc-os board: Apprise client gem + CLI, anos-notifycc-os plugin (AI-routable notifications from any session/machine), multi-service routing, Planka's native Apprise integration pointed at the same server. Notification policy (pull beats push, silent days silent) is unchanged — transport only.
Fallback ladder (if the phone gate fails)
- TaskView (taskview.tech) — on-paper ideal (native mobile apps, scoped API tokens, first-party MCP) but source-available, ~6 months old, thin sourcing. Verify claims hands-on first, then trial. Modern-and-unproven; only reached if Planka fails the gate.
- Vikunja — mature API, kanban view, but mobile app explicitly alpha; revisit 2027.
- Vault-native v1 plan (archived below via git history) / Backlog.md — the markdown lane, if hosted boards fail entirely.
Donetick (recurring-chore tracker, native mobile) noted as a lane-specific fallback if tick-driven recurrence proves annoying for property maintenance — resisted for now (fifth-backlog trap).
The Planka Pro paywall and how we route around it
Planka went commercial (2025); CE keeps the full board UI. Three Pro-only features matter here, all covered by composing around the API — we never modify or fork Planka:
| Pro-only | Our layer instead |
|---|---|
| Recurring cards | tick script creates cards via REST on schedule — idempotent, elapsed-time catch-up (instantiates all missed occurrences), rules ours and portable |
| Cross-board global view | CLI backlog list --all, daily digest, and SessionStart brief aggregate across boards via API; in-app stays per-board (acceptable start) |
| Notification providers | The digest is ours (script-sent), Planka's notifiers irrelevant |
Known costs: "Pro discovery" banner in the free UI (cosmetic); API-token scoping story unverified (historically username/password; verify at deploy — matters for per-profile Hermes credentials; worst case a tiny API proxy enforces scope, which fits the approval-broker pattern anyway). Project health: v2 GA early 2025, tagged releases slowed since but commits continue — mature/stabilizing with a commercial turn, not dead. 12K+ stars, strong ecosystem.
Notification policy (ADHD / notification-blindness constraint)
Three tiers, designed so silence stays meaningful:
- Ambient (default, zero interruptions): the board itself + the Claude Code SessionStart brief. Information waits where the user already looks.
- Digest (the only routine notification): at most ONE morning message, on ONE channel, sent only when something is due or P0 — silent days stay silent.
- Interrupt: essentially never in v1; reserved for genuinely urgent items.
Target trajectory: reminders are the degenerate case where AI can't act yet. Eventually the agent drafts the action (e.g., tenant spigot email) and the notification becomes "draft ready — approve?" — a decision, not a chore.
Pilot plan — Fable orchestrates, cheap models do grunt work
Phase 0 — deploy + THE GATE (day 1)
- sonnet subagent: deploy Planka CE per the ovh-prod service pattern (
~/services/planka/, compose + postgres, Traefik labels, temp domain first, verify backup discovery). Decide auth posture at deploy. - haiku subagent: seed boards per hat (property, clients, cc-os/dev, business dev) + 8–10 real fixture cards via REST (spigot winterization due 2026-10-15; Woodfin HVAC/electrical/plumbing checkups; cc-os someday items incl. "adopt Storybloq handover-doc pattern"; 1–2 client items). Also proves API CRUD end-to-end.
- Human gate — the phone test: from the phone (responsive web; official app and Planka Pal as alternates), view boards, drag a card between lists, add a card, complete one. Pass → continue. Fail → fallback ladder.
Phase 1 — the agent layer (parallel after the gate)
- sonnet subagent: Ruby
backlogCLI (lib/+bin/, model-free tests):add --quick "title"(defaults board/list/priority),list --all(cross-board),tick(idempotent elapsed-time recurrence catch-up from a recurrence manifest; simple offsets+1y|+6m|+3m|+1monly — no rule engine). - haiku subagent: daily
tickscheduling on the OVH box (cron or a small container next to Planka).Digestdropped 2026-07-09. SessionStart briefdropped 2026-07-09 → replaced by the pull-based unified dashboard (own Planka card; lightweight JS, not Rails). Plugin (skills/scripts/agents/hooks) home + naming per cc-os-plugin-skill-naming-convention (decided 2026-07-10: newos-backlogplugin, cc-os ADR-023; runbin/refresh-pluginsafter).- Fable: review all deliverables; verify a fresh session surfaces the fixtures.
Phase 2 — Hermes (independent design exercise, guardrails-first — NOT in the pilot's critical path) Considered separately from the task system; the task system's only obligation is integrate-ability, which REST + (verified) scoped tokens provide by construction. Design principles locked now:
- Capability-based access: each Hermes profile/hat (property manager, accountant, client manager, business partner) gets its own narrow, revocable credential (e.g., read-only or single-board token). Hermes never holds credentials for catastrophic actions (money movement, deletion, infra).
- Approval broker: catastrophic-class actions are requests Hermes submits to an interface (n8n workflow / API) that holds the real credentials and routes to the user for approve/reject. Guardrails are the interface, not a policy.
- Sequence: read-only digest/query first, then narrow acting (comms drafting for
propertyitems), one hat at a time, property manager first. Gets its own design note when started.
Phase 3 — close-out (Fable)
- cc-os ADR + CLAUDE.md update; retire the v1 vault-task-type idea from vault-conventions planning.
- One-week live trial. Week-2 review gates (each pre-captured as a card): digest too noisy → tighten; capture friction → extend CLI; Forgejo top-issues added to brief; recurrence annoyance → evaluate Donetick for the property lane.
Explicitly deferred (captured as someday cards, not built): recurrence rule engine, effort/quick-win filter, AI comms drafting, Hermes acting autonomously, vault→OVH sync, per-board polish, TaskView evaluation (unless gate fails).
Success criteria
- The board is viewable and interactable from the phone, anywhere (the gate, then daily reality).
- Recurring tasks cannot silently miss a week (tick catch-up on an always-on host).
- Due/P0 items visible in ONE pull-based starting-point view with zero navigation (unified dashboard; digest + SessionStart brief dropped 2026-07-09).
- Capturing a task costs one command or one sentence to Claude.