Vikunja PM system — design (tracking issue for vikunja-pm-system.md) #25

Closed
opened 2026-08-21 05:39:42 +00:00 by Mark · 4 comments
Owner

Design document

~/Projects/org_mode/docs/vikunja-pm-system.md — Vikunja + Hermes together replace OpenProject-style PM. Vikunja owns the PM artifact (plan spine, projects, milestones, dependencies, tasks). Hermes owns mechanical PM triggers, cross-substrate wiring, execution feedback. No monolith.

Substrate split (settled)

  • Vikunja — PM artifact: projects, milestones, timeline, dependencies, tasks, comments, kanban views
  • Forgejo — Durable code artifacts: issues, PRs, commits, labels
  • Hermes Kanban — Automation execution state: cards, lane metadata, dispatch state

Join keys via mention, no shared database. Vikunja does not talk to Forgejo directly — the kanban is the bridge.

Build milestones

Each is a separate Forgejo issue, linked below:

  • M-PM-1: Project baseline (init projects, kanban views, webhooks)
  • M-PM-2: Vikunja → kanban outbound state reflection
  • M-PM-3: PM observation crons (drift / rollup / stale / weekly)
  • M-PM-4: Spec → swarm bridge (Module O wire-up)
  • M-PM-5: Cadence / review cron (milestone close + weekly digest)

Verification gate

workers/verify-vikunja-pm.sh smoke test runs against a fresh Vikunja project with 3 mixed-due-date tasks + a milestone. All 4 PM crons run. Confirms: drift cron emits overdue+today observations, milestone rollup shows correct %, stale janitor clean, weekly digest synthesizes. No milestone ships until smoke test passes against real Vikunja, not mocked.

Open design questions (defaults in parens)

  • Q1: stale-janitor auto-archive at 90d, or observe only? (observe only)
  • Q2: daily drift card per project, or per drift finding? (per finding)
  • Q3: weekly-review delivery channel? (Home + project Matrix room)
  • Q4: missed-deadline auto-extend, or observe? (observe only)

Refs

  • docs/kanban-design.md §1 — Vikunja-as-truth principle
  • docs/kanban-roadmap.md Modules A/B/D/E/N/O/P
  • src/server/vikunja_api.py — Vikunja REST client (live)
  • workers/vikunja-webhook-to-kanban.sh — existing inbound ingress (live)
  • workers/vikunja-project-init.sh — existing idempotent project init (live)
## Design document `~/Projects/org_mode/docs/vikunja-pm-system.md` — Vikunja + Hermes together replace OpenProject-style PM. Vikunja owns the PM artifact (plan spine, projects, milestones, dependencies, tasks). Hermes owns mechanical PM triggers, cross-substrate wiring, execution feedback. No monolith. ## Substrate split (settled) - **Vikunja** — PM artifact: projects, milestones, timeline, dependencies, tasks, comments, kanban views - **Forgejo** — Durable code artifacts: issues, PRs, commits, labels - **Hermes Kanban** — Automation execution state: cards, lane metadata, dispatch state Join keys via mention, no shared database. Vikunja does not talk to Forgejo directly — the kanban is the bridge. ## Build milestones Each is a separate Forgejo issue, linked below: - M-PM-1: Project baseline (init projects, kanban views, webhooks) - M-PM-2: Vikunja → kanban outbound state reflection - M-PM-3: PM observation crons (drift / rollup / stale / weekly) - M-PM-4: Spec → swarm bridge (Module O wire-up) - M-PM-5: Cadence / review cron (milestone close + weekly digest) ## Verification gate `workers/verify-vikunja-pm.sh` smoke test runs against a fresh Vikunja project with 3 mixed-due-date tasks + a milestone. All 4 PM crons run. Confirms: drift cron emits overdue+today observations, milestone rollup shows correct %, stale janitor clean, weekly digest synthesizes. **No milestone ships until smoke test passes against real Vikunja, not mocked.** ## Open design questions (defaults in parens) - Q1: stale-janitor auto-archive at 90d, or observe only? **(observe only)** - Q2: daily drift card per project, or per drift finding? **(per finding)** - Q3: weekly-review delivery channel? **(Home + project Matrix room)** - Q4: missed-deadline auto-extend, or observe? **(observe only)** ## Refs - `docs/kanban-design.md` §1 — Vikunja-as-truth principle - `docs/kanban-roadmap.md` Modules A/B/D/E/N/O/P - `src/server/vikunja_api.py` — Vikunja REST client (live) - `workers/vikunja-webhook-to-kanban.sh` — existing inbound ingress (live) - `workers/vikunja-project-init.sh` — existing idempotent project init (live)
Author
Owner

🔧 CORRECTION (2026-08-21) — static workers are WRONG

Major error caught by the user: this design originally mapped the PM observation
layer onto static cron scripts (vikunja-pm-deadline-drift.py,
-milestone-rollup.py, -stale-janitor.py, -weekly-review.py,
verify-vikunja-pm.sh). That breaks the substrate principle:

"the substrate routes, workers execute" (kanban-design.md §13,
kanban-roadmap.md)

Those scripts were (a) none of them ever built — all absent from disk, and
(b) the wrong shape even if they were — they are static nonsense, not proper
auto-dispatched kanban agents.

Corrected design (docs/vikunja-pm-system.md §3, §9, §10, §12):

  • PM observation/review is a lane on the PM observer profile
    (wired into Module B admin-janitor per §5.1), tagged lane: pm-observer.
  • The lane's job: given a trigger card, read Vikunja state, write an
    observation/review card or room post. No static script.
  • Cadence = thin card-creators that drop level-0 cards for the dispatcher
    to auto-assign to the PM observer agent — not a script schedule.
  • Verification = a channel test through the real dispatcher + agent,
    not a bash smoke test.
  • Build milestones M-PM-3 and M-PM-5 rewritten to agent-based shape.
    M-PM-3 = "PM observer agent + lane"; M-PM-5 = "Milestone-close review".

Live-state check (2026-08-21):

  • vikunja-kanban-sync cron IS live + healthy (every 1m, no_agent,
    last_status OK, 43 inbound_done_mirrored on last pass). The outbound bridge
    in ~/Projects/hermes-scripts/scripts/vikunja-kanban-sync.py is real and
    working. The worker vikunja-sync-worker.{py,sh} are deprecation stubs —
    NOT the live path.
  • Milestones API 404s on Vikunja v2.3.0; relations unverified. Confirmed
    working: subtasks via related_tasks (task #59 → [60,61,62,63]).
  • org_mode project: all 50 tasks are done=True, zero open.
--- ### 🔧 CORRECTION (2026-08-21) — static workers are WRONG Major error caught by the user: this design originally mapped the PM observation layer onto **static cron scripts** (`vikunja-pm-deadline-drift.py`, `-milestone-rollup.py`, `-stale-janitor.py`, `-weekly-review.py`, `verify-vikunja-pm.sh`). That breaks the substrate principle: > "the substrate routes, workers execute" (`kanban-design.md` §13, > `kanban-roadmap.md`) Those scripts were (a) none of them ever built — all absent from disk, and (b) the wrong shape even if they were — they are static nonsense, not proper auto-dispatched kanban agents. **Corrected design (`docs/vikunja-pm-system.md` §3, §9, §10, §12):** - PM observation/review is a **lane** on the PM observer profile (wired into Module B `admin-janitor` per §5.1), tagged `lane: pm-observer`. - The lane's job: given a trigger card, read Vikunja state, write an observation/review card or room post. No static script. - Cadence = thin **card-creators** that drop level-0 cards for the dispatcher to auto-assign to the PM observer agent — not a script schedule. - Verification = a **channel test** through the real dispatcher + agent, not a bash smoke test. - Build milestones M-PM-3 and M-PM-5 rewritten to agent-based shape. M-PM-3 = "PM observer agent + lane"; M-PM-5 = "Milestone-close review". **Live-state check (2026-08-21):** - `vikunja-kanban-sync` cron IS live + healthy (every 1m, no_agent, last_status OK, 43 inbound_done_mirrored on last pass). The outbound bridge in `~/Projects/hermes-scripts/scripts/vikunja-kanban-sync.py` is real and working. The `worker vikunja-sync-worker.{py,sh}` are deprecation stubs — NOT the live path. - Milestones API 404s on Vikunja v2.3.0; relations unverified. Confirmed working: subtasks via `related_tasks` (task #59 → [60,61,62,63]). - org_mode project: all 50 tasks are `done=True`, zero open.
Author
Owner

🔧 CORRECTION #2 (2026-08-21) — agent profile, not a lane; sync untouched

Second round of the correction:

  1. M-PM-2 (sync) is DROPPED from scope. The Vikunja↔kanban sync bridge
    (vikunja-kanban-sync cron, every 1m) is LIVE and healthy — verified 43
    inbound_done_mirrored, errors 0, 48 mapping rows. It will NOT be reworked.
    #27 is now an out-of-scope info issue.

  2. PM observation is a new dedicated profile pm-observer — NOT a lane on
    admin-janitor (no such profile exists) and NOT a lane on janitor (janitor
    is coupled to the GSD pipeline). New directory with SOUL.md/config/.env/
    skills/memory; self-registered by file existence (§13).

  3. Cards are for the dispatcher → agent, NOT for a human to read. No
    "create a card a human looks at" script. Triggers assign cards to the
    pm-observer profile (qa-post-deploy-trigger / verifier-trigger precedent);
    the agent delivers its report to the project room.

Milestones renumbered: M-PM-1 baseline · M-PM-2 pm-observer profile ·
M-PM-3 spec→swarm (Module O) · M-PM-4 milestone-close review.

### 🔧 CORRECTION #2 (2026-08-21) — agent profile, not a lane; sync untouched Second round of the correction: 1. **M-PM-2 (sync) is DROPPED from scope.** The Vikunja↔kanban sync bridge (`vikunja-kanban-sync` cron, every 1m) is LIVE and healthy — verified 43 inbound_done_mirrored, errors 0, 48 mapping rows. It will NOT be reworked. #27 is now an out-of-scope info issue. 2. **PM observation is a new dedicated profile `pm-observer`** — NOT a lane on `admin-janitor` (no such profile exists) and NOT a lane on `janitor` (janitor is coupled to the GSD pipeline). New directory with SOUL.md/config/.env/ skills/memory; self-registered by file existence (§13). 3. **Cards are for the dispatcher → agent, NOT for a human to read.** No "create a card a human looks at" script. Triggers assign cards to the pm-observer profile (qa-post-deploy-trigger / verifier-trigger precedent); the agent delivers its report to the project room. Milestones renumbered: M-PM-1 baseline · M-PM-2 pm-observer profile · M-PM-3 spec→swarm (Module O) · M-PM-4 milestone-close review.
Author
Owner

🧹 PURGE (2026-08-21) — phantom PM machinery removed from the plan

Following ground-truth review of the implemented substrate, the entire
pm-observer / cadence / rollup / review / build-milestone layer has been
purged as incompatible invention. Nothing in it matched how the system
actually runs.

What the substrate actually is (confirmed on disk):

  • tasker-worker on the tasker board is the PM driver
    (~/.hermes/profiles/tasker-worker/SOUL.md): it drains Vikunja-backed cards,
    classifies them (physical/human-op → do support then block; code → route via
    Forgejo issue; non-code → do inline), and writes back to Vikunja on
    complete/block. It is the writer, not a sync layer.
  • vikunja-webhook-to-kanban.sh is the inbound ingress, event-driven via the
    daemon ("DO NOT CRON IT"). The 1m poll cron is retired.
  • vikunja-kanban-sync cron is the outbound catch-up, not the writer.
  • Vikunja is truth; the kanban automates it; no observer/rollup/cadence layer.

Purged from docs/vikunja-pm-system.md: the pm-observer profile, the
drift/rollup/stale/weekly triggers, the cadence/review section, the M-PM build
milestones, and the phantom verification gate. Rewritten to describe the
implemented tasker-worker driver + real ing,estion path + PM principles.

Closed as superseded: #26 (baseline — already implemented), #28 (pm-observer
profile — phantom), #30 (milestone-close review — phantom). #29 retitled to
stand alone as a roadmap (Module O) item, decoupled from the killed M-PM scheme.
#27 remains an out-of-scope note (sync bridge untouched).

The user confirmed: the current substrate is more correct in implementation and
goals; it already processes Vikunja tasks and, where not directly actionable,
does what it can to support human ops.

### 🧹 PURGE (2026-08-21) — phantom PM machinery removed from the plan Following ground-truth review of the implemented substrate, the entire `pm-observer` / cadence / rollup / review / build-milestone layer has been **purged** as incompatible invention. Nothing in it matched how the system actually runs. **What the substrate actually is (confirmed on disk):** - `tasker-worker` on the `tasker` board is the PM driver (`~/.hermes/profiles/tasker-worker/SOUL.md`): it drains Vikunja-backed cards, classifies them (physical/human-op → do support then block; code → route via Forgejo issue; non-code → do inline), and **writes back to Vikunja** on complete/block. It is the writer, not a sync layer. - `vikunja-webhook-to-kanban.sh` is the inbound ingress, event-driven via the daemon ("DO NOT CRON IT"). The 1m poll cron is retired. - `vikunja-kanban-sync` cron is the outbound catch-up, not the writer. - Vikunja is truth; the kanban automates it; no observer/rollup/cadence layer. **Purged from `docs/vikunja-pm-system.md`:** the `pm-observer` profile, the drift/rollup/stale/weekly triggers, the cadence/review section, the M-PM build milestones, and the phantom verification gate. Rewritten to describe the implemented `tasker-worker` driver + real ing,estion path + PM principles. **Closed as superseded:** #26 (baseline — already implemented), #28 (pm-observer profile — phantom), #30 (milestone-close review — phantom). #29 retitled to stand alone as a roadmap (Module O) item, decoupled from the killed M-PM scheme. #27 remains an out-of-scope note (sync bridge untouched). The user confirmed: the current substrate is more correct in implementation and goals; it already processes Vikunja tasks and, where not directly actionable, does what it can to support human ops.
Author
Owner

Closing — design/tracking issue for vikunja-pm-system.md. Doc lives in ~/Projects/org_mode/docs/. Reopen if work is wanted.

Closing — design/tracking issue for vikunja-pm-system.md. Doc lives in ~/Projects/org_mode/docs/. Reopen if work is wanted.
Mark closed this issue 2026-09-15 15:36:52 +00:00
Sign in to join this conversation.
No description provided.