Plan: pal-e-docs — Interactive Knowledge Platform

plan-pal-e-docs Plan

plan deprecated

Vision

Replace Jinja with SvelteKit so that note_type drives the renderer. Static HTML for docs, interactive components for boards. One frontend, one backend, one URL. The sprint board — one board per project — is the killer feature that justifies the migration and proves the pattern.
Organizing principles:
  • One plan per project. All actionable work lives here. TODOs and bugs link to phases via parent_slug. Orphan TODOs = untriaged inbox.
  • One board per project. Boards replace sprints. Permanent kanban, not time-boxed. Column position = scoping depth (Backlog → Todo → Next Up → In Progress → Done).
  • note_type drives rendering. A board note renders as an interactive SvelteKit component. A doc note renders as static HTML. Same system, different renderers.
  • Playground-first. Design experiments in html-playground before committing to production repos.
  • Docker Compose for dev. Postgres + API + frontend containers. No cluster dependency during development.

Projects & Repos Touched

Repo Platform Role
<code>forgejo_admin/pal-e-docs</code> (future: pal-e-api) Forgejo FastAPI backend — notes, blocks, projects, boards, search
<code>pal-e-app</code> (new) Forgejo SvelteKit frontend — renders notes, interactive boards
<code>forgejo_admin/pal-e-docs-mcp</code> Forgejo MCP server — board/sprint tool updates
<code>forgejo_admin/pal-e-docs-sdk</code> Forgejo Python SDK — board/sprint method updates
<code>forgejo_admin/html-playground</code> Forgejo Design experiments for board UI

Context

Act 1 (SQLite → Postgres) and Act 2 (Knowledge Engine — blocks, search, compiled pages) are complete. The platform has 262 notes, 32 MCP tools, full-text search, and a block content model. But the frontend is still Jinja server-rendered templates with zero interactivity. Sprint management exists as API + MCP tools but the multi-board/time-boxed sprint model proved wrong — projects need their own cadence and their own boards. This plan unifies the SvelteKit migration and the board redesign into one effort.

Previous Plan

plan-2026-02-26-tf-modularize-postgres — Act 1 + Act 2 (completed). plan-2026-03-01-pal-e-sprints — sprint backend (completed). plan-2026-03-03-sprint-workflow-automation — DORA instrumentation (completed).

Depends On

  • Block content model (Phase 7) — COMPLETED
  • Sprint tables + API (Phase 1 of sprints backend) — COMPLETED
  • Full-text search (Phase 5) — COMPLETED

Decisions Made

Decision Rationale
Boards replace sprints. One board per project. Projects have different cadences. A cross-project sprint doesn't map to how work actually gets done.
Board columns are a scoping pipeline Backlog (fuzzy) → Todo (defined) → Next Up (scoped) → In Progress (issue exists, agent spawned) → Done.
note_type drives rendering Unifies static docs and interactive components in one system. Sprint board is the first interactive renderer.
pal-e-docs = project, not repo pal-e-api = backend repo. pal-e-app = frontend repo. Eliminates naming confusion.
Sprint SDK/MCP rename deferred Build new stuff against current API first. Renames are high blast radius, low immediate value.
Board data stays in pal-e-docs DB Unified backend. boards + board_items tables replace sprints + sprint_items.
One plan per project, TODOs parent to phases Prevents orphan work. All actionables tracked under one plan. Orphan check = TODOs with null parent_slug.

Phases

See child phase notes: list_notes(parent_slug="plan-pal-e-docs")

Key Files

TBD — will be populated as phases complete.

Verification

  • Board renders in SvelteKit with real data from pal-e-docs API
  • Drag-and-drop moves items between columns
  • note_type determines renderer (board vs static HTML)
  • Docker Compose dev environment works without cluster
  • All open TODOs have a parent_slug pointing to a phase

Next Plan Seeds

  • DORA dashboard — once board tracks work, Grafana visualizes velocity
  • Semantic search UI — search bar with keyword/semantic/hybrid modes
  • In-browser editing — block-level CRUD UI for notes
  • Quick-jot + inbox — rapid note creation, triage workflow
  • project-pal-e-docs — project page (needs update)
  • plan-2026-03-01-pal-e-sprints — completed predecessor
  • plan-2026-03-03-sprint-workflow-automation — completed predecessor
  • plan-2026-02-26-tf-modularize-postgres — completed predecessor

Epilogue

  • PR #166 nit: inline import patternfrom pal_e_docs.routes.boards import _status_to_column inside update_note. Consider shared module.
  • PR #166 nit: broad exception catchexcept Exception could be narrowed.
  • PR #166 nit: position=0 for all synced items — Consider using phase.position.
  • PR #166 nit: duplicated test helpers — Need shared conftest fixtures.
  • PR #166 nit: falsy check on status — Status comparison could be more explicit.
  • Frontend nit: $lib/constants.ts needed — RESOLVED. Extracted to $lib/columns.ts (commit 0c4019a).
  • PR #17 nit: URL sync effect cycles$effect fires redundantly. Consider debounce or guard.
  • PR #17 nit: SvelteURLSearchParams — Use plain URLSearchParams where reactivity not needed.
  • PR #20 nit: updated_at as column entry proxy — Known API limitation for stuck detection.
  • PR #20 nit: inline border-left style — Competes with Tailwind class.
  • PR #21 nit: duplicate listProjects() — Layout + home both fetch projects.
  • PR #21 nit: unsanitized body HTML — Quick-jot relies on backend sanitization only.
  • PR #21 nit: SELECT in isInput guard — Affects all keyboard shortcuts.
  • PR #24 nit: missing .env.example — Auth env vars undocumented for local dev.
  • PR #24 nit: hardcoded Tailscale URLs — Low priority given tailnet-only deployment.
  • PR #24 nit: @ts-expect-error — Should use proper type augmentation in app.d.ts.
  • PR #24 nit: unused accessToken — Stored in JWT callback but never consumed. Inflates cookie size.
  • PR #24 nit: missing plan slug in PR body — PR template compliance.
  • F12 nit: embedding worker NetworkPolicy gap — Worker pod not covered by app=pal-e-docs policy. Needs scoped policy in pal-e-deployments. (PR #90 QA)
  • F12 nit: PromQL float equalityembedding_total == 0 uses float equality. Consider threshold. (PR #90 QA)
  • F13b-1 nit: sequential board queries — Could parallelize with background jobs. (PR #114 QA)
  • F13b-1 nit: dirname resolution — Use resolved HOOK_DIR instead of dirname "$0". (PR #114 QA)
  • MCP labels nit: normalization duplication — Labels join+strip logic duplicated in create and update. Extract helper. (PR #42 QA)
  • SDK labels type mismatchpal-e-docs-sdk add_board_item types labels as list[str] | None instead of str | None. Issue #30. (PR #42 discovered scope)
  • DEFERRED: Phase 5b-2 deployforgejo-api-token k8s secret needed in pal-e-docs-secrets for Forgejo issue sync to work in prod. Code merged (PR #171).
  • DEFERRED: Phase 5b-3 stale detectionstale_at field, periodic sweep, stuck-item flagging. Issue TBD.
  • DEFERRED: Phase 6 — Token Metrics — Token usage tracking per sprint item. Needs observability foundation (DORA correlation).
  • DEFERRED: Phase 8 — Repo Renames — pal-e-docs → pal-e-api, pal-e-docs-mcp → pal-e-mcp, etc. High blast radius, low immediate value.
  • DEFERRED: Phase 9 — Jinja Sunset — Remove legacy Jinja templates. Low priority — SvelteKit frontend is primary.
  • DEFERRED: Phase 10 — Orchestration Automation — Auto-QA trigger, auto-dev-respawn. Auto-board-sync already absorbed by Agency Phase 11.
  • PR #185 nit: write endpoints lack auth gating — POST/PUT/DELETE on /projects and /boards have no auth check. Pre-existing, out of scope for #184. Should be tracked. (F14 QA)
  • PR #185 nit: /projects/{slug}/notes no project-level is_public gate — Endpoint returns public notes even if the project itself is private. Documented intentionally in test. (F14 QA)
  • PR #39 nit: deleteBoardItem DRY — duplicates header construction instead of using apiFetch. (F14 QA)
  • PR #39 nit: slugCache auth-state keying — Cache stores slugs from most-privileged request. Anonymous request within 60s TTL could see private slugs in cache (note-detail endpoint still filters). (F14 QA)
  • PR #39 nit: sign-in CSS duplication.contact-btn and .login-submit are 99% identical. Merge into single class. (F14 QA) → Addressed by F11a subphase.
  • PR #39 nit: hardcoded portfolio URLhttps://portfolio.tail5b443a.ts.net hardcoded in signin page. Consider env var. (F14 QA)