Skip to content

Per-Task Render Surface Research

Status: Research — ID-20.2 deliverable (Subtask of ID-20 per-Task .md mirror feature). Session: kh-prod-readiness-S56. Author: Claude (sub-agent, worktree dispatch). Context: Companion to docs/research/per-task-file-mirror-design.md §8.


Plannotator (v0.19.18, github.com/backnotprop/plannotator) is a Bun-runtime monorepo comprising two apps that matter for this research:

  • apps/hook/ — the Claude Code plugin. Entry point: server/index.ts. Spawned as a local HTTP server (random port) by hooks or slash commands; opens the UI in the browser.
  • packages/ui/ — all shared React components, including Viewer.tsx, AnnotationPanel.tsx, the markdown parser, and annotation types.

Additional packages: packages/server/ (Bun server primitives), packages/shared/ (runtime-agnostic types + storage helpers), packages/editor/ (plan review app entry), packages/review-editor/ (code review app entry).

Plannotator runs in nine modes (per apps/hook/server/index.ts). The three relevant to this research:

ModeTriggerInputOutput
Annotate/plannotator-annotate <file.md>Single markdown file (path on disk)Structured annotation feedback → stdout (captured by calling agent)
Plan ReviewExitPlanMode PermissionRequest hookPlan markdown from hook JSON payloadapprove / deny decision → stdout
Code Review/plannotator-reviewgit diff outputAnnotation feedback → stdout

Verdict: annotation-only, no edit-in-place of source content.

What Plannotator does today:

  • Reads a markdown file and serves its content via /api/plan (GET endpoint in packages/server/annotate.ts).
  • Renders the markdown as parsed blocks (packages/ui/utils/parser.ts) inside the Viewer component (packages/ui/components/Viewer.tsx).
  • Annotates rendered text: user selects spans → toolbar → DELETION / COMMENT / GLOBAL_COMMENT annotation types. Annotation cards in the AnnotationPanel component support inline text editing of annotation comment text (the AnnotationCard isEditing state in packages/ui/components/AnnotationPanel.tsx), but this edits the annotation’s comment field, NOT the source document text.
  • Submits via /api/feedback (POST) — sends { feedback: string; annotations: unknown[] } to the server, which resolves the decisionPromise and writes the assembled feedback string to stdout. The calling agent receives this as a signal to revise. No write-back to the source file occurs at any point.

What Plannotator does NOT do today:

  • Does not write back to the source file (filePath is display-only in the server).
  • Does not support field-level structured edits (e.g., changing a status enum value).
  • Does not provide a form UI for structured metadata — frontmatter is rendered read-only via FrontmatterCard in Viewer.tsx.
  • Does not expose a JSON data layer; the server is stateless between invocations.
  • Single file path (plannotator annotate <file.md>) → reads to string → served via /api/plan.
  • HTML / URL / folder (via --render-html, Jina/Turndown, or folder browser) — these convert to markdown before serving; not relevant for per-Task .md mirrors.
  • Stdin (hook mode) — plan markdown embedded in hook JSON payload.

Plannotator’s storage architecture:

  • Annotation drafts (~/.plannotator/history/…): auto-saved per content hash via /api/draft endpoint; survive server restarts; NOT write-back to source.
  • Plan snapshots (~/.plannotator/plans/): saved on approve/deny decision; plan content only, no source mutation.
  • Config (~/.plannotator/config.json): user settings (displayName, diffOptions, conventionalComments). Mutated via /api/config POST.

There is no path from annotation data → source .md file mutation in the current codebase. The persistence layer is explicitly separated from the rendered source.


To support the per-Task .md mirror use case — view a Task .md file and edit text + status/priority from a browser UI with write-back to task-list.json — requires three distinct fork deltas.

Delta A — Edit-in-place of arbitrary text spans (for Subtask details editing)

Section titled “Delta A — Edit-in-place of arbitrary text spans (for Subtask details editing)”

What it requires:

  1. Extend Viewer.tsx to support an “edit mode” toggle that replaces rendered blocks with editable <textarea> or contenteditable elements.
  2. On “Save” confirmation, POST the edited markdown to a new /api/save server endpoint.
  3. /api/save writes the mutated content back to the source file path (using Bun.write(filePath, markdown)).
  4. The startAnnotateServer in packages/server/annotate.ts needs filePath to be a writable path (already passed in), and the server needs a new route handler for the save endpoint.

Rough effort: ~4–6 hours. The React-side block editing (toggling rendered blocks to <textarea> with auto-resize) is the main UI work. The server endpoint is simple (Bun.write). No new external dependencies needed.

Caveat: Per-Task .md mirrors are generated files — they are the output of gen:tasks, not editable directly as canonical source. “Edit-in-place” in the mirror would need to either: (a) write back to task-list.json directly (preferred — canonical source), or (b) write to the .md mirror and trigger a reverse generator. Option (a) is architecturally cleaner; see §2 write-back discussion below.

Delta B — Structured field edit for status and priority enums

Section titled “Delta B — Structured field edit for status and priority enums”

What it requires:

  1. Detect YAML frontmatter fields that match known enum schemas (status, priority). The frontmatter parser (packages/ui/utils/parser.ts / Frontmatter type) already extracts frontmatter key-value pairs.
  2. Replace the read-only FrontmatterCard in Viewer.tsx with an editable version that renders <select> dropdowns for known enum fields and <input> for free-text fields.
  3. On field change, POST to /api/save-field with { field, value }.
  4. Server handler updates task-list.json (canonical) for the matched Task/Subtask ID (parsed from the .md filename or an embedded frontmatter field task_id).

Rough effort: ~3–4 hours. Frontmatter detection is already in place; the main work is the editable FrontmatterCard component + server-side JSON patch logic.

Important constraint: For enum edits to reach task-list.json, the server must know the canonical JSON path (tasks[i].status vs tasks[i].subtasks[j].status). This requires either: (a) encoding the Task ID in the .md mirror frontmatter (e.g., task_id: "20", subtask_id: "2"), or (b) parsing the Task ID from the filename (ID-20.md → task 20). Option (b) is simpler and avoids frontmatter schema coupling.

Delta C — Write-back target: direct to task-list.json vs to .md mirror

Section titled “Delta C — Write-back target: direct to task-list.json vs to .md mirror”

Analysis:

Write-back targetProsCons
Direct to task-list.jsonCanonical source stays authoritative; mirror regenerates on next gen:tasks run; consistent with parseTaskListWithWarnings ingress contractRequires server-side JSON patch logic (not trivial for nested Subtask details fields with embedded journal blocks); server needs to know task-list.json absolute path
To .md mirror onlySimpler server logic (Bun.write(filePath, markdown)); Delta A is sufficientBidirectional sync needed (reverse generator) — adds complexity + drift risk; violates §5 of design doc (“bidirectional sync is out of scope”)

Recommendation: Write back directly to task-list.json. The server receives the mutated field value + task/subtask IDs and performs a targeted JSON patch using JSON.parse / field mutation / JSON.stringify. The details field with embedded journal blocks is a string field — replacing it with a new string is a straightforward patch. Per-Task .md mirrors regenerate via gen:tasks automatically (via Stop hook after task-list.json is saved).

Rough effort for Delta C (server-side JSON patch): ~2–3 hours. Main complexity is the nested Subtask lookup (tasks.find(t => t.id === taskId).subtasks.find(s => s.id === subtaskId)). The write is atomic: read JSON → patch → write.

DeltaScopeEffort
A: Edit-in-place text spansViewer.tsx edit mode + /api/save endpoint~4–6h
B: Structured field edit (status/priority)Editable FrontmatterCard + /api/save-field endpoint~3–4h
C: Write-back to task-list.jsonServer-side JSON patch + task/subtask ID resolution~2–3h
Total~9–13h

These estimates assume the fork is maintained locally (not upstreamed to the public Plannotator repo). Upstreaming would require making the feature configurable and adding tests — roughly double the effort.


§3 — kh-knowledge-platform legacy state-rendering inventory

Section titled “§3 — kh-knowledge-platform legacy state-rendering inventory”

The kh-knowledge-platform worktree (branch: kh-knowledge-platform, /Users/liamj/Documents/development/knowledge-hub-knowledge-platform) has a /state route that renders three state-doc tabs: Roadmap, Backlog, and SOP. It is a KH-coupled Next.js application.

Git status: mostly clean (one deleted .claude/skills/review/SKILL.md, three untracked spec drafts). No uncommitted production code changes.

File pathSummaryKH-coupling reasonReusability rating
app/state/page.tsxTab-switching page for /state route. Three lazy-loaded panels: Roadmap, Backlog, SOP. Uses useSearchParams, useRouter from Next.js; useUserRole hook. Client component.Next.js App Router, KH auth hook (useUserRole)Low
components/state-docs/roadmap-panel.tsxRenders roadmap_items Supabase table: expandable section cards, filter bar (status + section), sortable item table. Uses TanStack Query (fetchRoadmapItems). Read-only.Supabase (roadmap_items table), KH query-key + fetcher pattern, KH token CSS (--color-status-error, semantic tokens)Low
components/state-docs/backlog-panel.tsxRenders backlog_items Supabase table: category-grouped items, filter dropdowns (category/status/priority), sortable columns. Read-only.Supabase (backlog_items table), KH query-key + fetcher patternLow
components/state-docs/sop-panel.tsxRenders sop_sections Supabase table: hierarchical section list with body markdown rendering. Read-only.Supabase (sop_sections table), KH query-key + fetcher patternLow
components/state-docs/status-badge.tsxReusable StatusBadge + PriorityBadge components. Renders enum values as colour-coded badges using KH semantic tokens.KH design-system tokens (--color-* vars from app/globals.css); badge colour-to-status mapping is KH-specificMedium (badge concept is portable; token values are not)
types/state-docs.tsTypeScript types for RoadmapItem, BacklogItem, SopSection. Derived from Supabase migration schema. Enum constants for statuses, priorities, categories.Supabase schema; comment explicitly states “Read-only UI types — no mutation types needed (spec §2: no edit UI).”Medium (enum definitions portable; Supabase-derived field names not)
lib/query/fetchers.ts (lines 130–184)Three async fetchers: fetchRoadmapItems, fetchBacklogItems, fetchSopSections. Query Supabase tables directly via createClient().Supabase-js client, KH project ID, user_roles table RLS policy. provenance: 'engineering_seed' constant is KH-specific.Nil
lib/query/query-keys.ts (state-docs section)TanStack Query key factory for stateDocs.roadmap, stateDocs.backlog(opts), stateDocs.sop.KH query-key convention (queryKeys pattern).Low
supabase/migrations/20260422164830_create_state_docs_tables.sqlCreates roadmap_items, backlog_items, sop_sections tables with RLS policies, CHECK constraints, indexes, updated_at trigger.KH Supabase project, user_roles table dependency, engineering_seed provenance constant.Nil (migration is non-portable)
supabase/migrations/20260423224800_create_client_state_doc_tables.sqlCreates client-facing (possibly staging-only) state-doc table variants.Same KH coupling as above.Nil
hooks/use-user-role.ts (indirect)Auth hook used by app/state/page.tsx to gate loading spinner.KH auth system, Supabase user_roles table.Nil

Files investigated: 11 distinct files (6 source + 2 types + 2 migrations + 1 hook reference). Not all were fully read — SQL migrations examined in full; component files examined in full; fetchers examined in the state-doc section.


status-badge.tsx — Medium reusability. The concept (enum value → coloured badge) is generic and useful for a per-Task viewer. However the token names (--color-status-error, bg-primary, text-muted-foreground) are KH’s Warm Meridian design system. Reuse in a cross-project tool would require either:

  • Porting the token definitions into the tool’s own CSS, or
  • Replacing tokens with hardcoded colours (defeats the purpose), or
  • Accepting a Warm Meridian dependency in the cross-project tool (problematic).

types/state-docs.ts — Medium portability for the enum concept, nil for schema. The enum constants (ROADMAP_STATUSES, BACKLOG_STATUSES, etc.) are useful as a reference for what status values exist. The actual TypeScript types are derived from a Supabase schema that doesn’t map to task-list.json. For per-Task mirrors, new types would be needed based on the TaskListSchema from lib/validation/task-list-schema.ts.

roadmap-panel.tsx, backlog-panel.tsx, sop-panel.tsx — Low/nil reusability.

All three are deeply coupled to:

  • Supabase as the data source (via TanStack Query fetchers that call supabase.from(…))
  • KH’s user_roles-based RLS for data access
  • KH’s Vercel/Next.js deployment environment (route handler, cookies, auth)
  • A provenance: 'engineering_seed' data model that maps to KH’s roadmap/backlog JSON format (a different schema from task-list.json)

The state-docs UI was explicitly designed as a read-only view of Supabase tables (per types/state-docs.ts comment: “Read-only UI types — no mutation types needed”). It has no edit path whatsoever. Adding edit-back would require building a new mutation layer from scratch — comparable effort to building Option C (new minimal UI) without the cross-project portability benefit.

Fetchers — Nil reusability. The Supabase fetchers hard-code table names, provenance constants, and KH auth patterns. They cannot be reused cross-project.

The kh-knowledge-platform state-docs code provides inspiration for UI patterns (tab structure, expandable sections, filter bars, badge components) but is architecturally unsuited for reuse as cross-project tooling. The data layer, auth layer, and deployment environment are all KH-specific. Reusing it would require stripping out approximately 80% of the code and rebuilding the data layer — at which point you are building Option C (new minimal UI) anyway, with added migration complexity.


Option A — Plannotator fork + required deltas

Section titled “Option A — Plannotator fork + required deltas”

Description: Fork Plannotator locally (already at /Users/liamj/Documents/development/plannotator), implement Deltas A + B + C from §2, and deploy as a Claude plugin at ~/.claude/plugins/task-list-mirror/. The forked plannotator annotate command becomes task-mirror annotate <ID-N.md>, or the existing /plannotator-annotate skill gains a new code path for .md mirror files.

Implementation cost: ~9–13h (§2 estimates). Maintained as a local fork of an active upstream project.

Cross-project tooling fit (per §7 constraint): Plannotator is already a cross-project tool (~/.claude/plugins/plannotator or installed globally). Adding per-Task edit capability either: (a) extends the existing Plannotator plugin with a task-mirror-specific mode (low friction but pollutes a general tool with KH-specific schema knowledge), or (b) creates a separate task-list-mirror plugin that vendors the Plannotator UI layer (higher ceremony but cleaner separation).

Risk register:

  • R1: Upstream Plannotator receives breaking API changes that diverge from the fork. Mitigation: pin a fork commit; rebasing required periodically.
  • R2: Delta C (JSON patch to task-list.json) has edge cases around journal blocks with embedded ISO timestamps — the details field is a free-form string with embedded XML blocks. Patch logic must be tested carefully.
  • R3: The Plannotator fork adds maintenance surface to a tool that currently requires no maintenance (plugin marketplace install). Liam must own the fork.
  • R4: Plannotator is annotation-oriented (feedback → agent). Re-purposing it as a structured editor may feel semantically mismatched.

Fit for §8 edit-back requirement: Full fit once Deltas A + B + C are implemented. View, text edit, and status/priority field edit all supported. Write-back goes to task-list.json (Delta C).

Recommended location: ~/.claude/plugins/task-list-mirror/ as a separate plugin that vendored the minimal Plannotator UI primitives (Viewer, AnnotationPanel stripped of annotation logic, FrontmatterCard replaced with editable fields). Avoids polluting the upstream Plannotator plugin.


Option B — kh-knowledge-platform legacy state-rendering reuse

Section titled “Option B — kh-knowledge-platform legacy state-rendering reuse”

Description: Extract the read-only state-docs UI components from kh-knowledge-platform and adapt them for per-Task mirror rendering with an added edit layer.

Implementation cost: ~15–20h minimum. Extracting from Next.js + Supabase context, replacing the data layer with a local JSON reader, adding edit capability, and packaging for cross-project use all require substantial rework. This is essentially building a new UI with extra steps (unwinding the Supabase/Next.js coupling).

Cross-project tooling fit: Poor. Every layer of the kh-knowledge-platform state-docs code assumes KH’s Supabase instance, auth system, and Next.js deploy environment. These are not cross-project by design. The kh-knowledge-platform branch itself is noted as “being decommissioned” in CLAUDE.md. Building on decommissioned code is a poor investment.

Risk register:

  • R1: Code is being decommissioned — no upstream investment, potential bitrot.
  • R2: Data layer rewrite is comparable to building Option C from scratch, with added migration complexity.
  • R3: Read-only design (types/state-docs.ts: “no mutation types needed”) means every edit-back component must be built from scratch — no reuse benefit on the most important feature.
  • R4: KH’s semantic token dependency (--color-*) must either be replicated or replaced in the cross-project context.

Fit for §8 edit-back requirement: Nil out of the box. The current code is explicitly read-only. Edit-back requires a complete new mutation layer.

Verdict: Option B is dominated by both Option A (better UI primitives, smaller delta to edit capability) and Option C (cleaner cross-project packaging without legacy debt). Not recommended.


Description: Build a minimal task-viewer + editor UI from scratch, purpose-built for task-list.json per-Task .md mirror rendering with edit-back. Likely a single-file Vite + React app or a simple HTML page with vanilla JS.

Implementation cost: ~8–12h for a functional first version covering: markdown rendering (via marked or similar), frontmatter field editing (status/priority dropdowns), details field text editing, write-back to task-list.json via a local Node/Bun server. The UI would be simpler than Plannotator (no annotation system, no sharing, no plan diff), which reduces scope.

Cross-project tooling fit (per §7 constraint): Excellent — built from scratch with cross-project use as the primary constraint. No KH dependencies. Can live at ~/.claude/plugins/task-list-mirror/ or ~/.claude/tools/task-list-mirror/ with a clean plugin manifest.

Risk register:

  • R1: No existing UI primitives — markdown rendering, theming, keyboard shortcuts all require implementation from scratch.
  • R2: Initial build produces a simpler UI than Plannotator (no block-level annotation, no plan diff). If Liam later wants annotation capability, it must be added separately.
  • R3: Bun/Node dependency for the write-back server — requires local runtime; no hosted option without more work.

Fit for §8 edit-back requirement: Full fit — purpose-built for this use case. View, text edit (per-field or per-section), status/priority dropdown edit, and write-back to task-list.json can all be first-class features with no legacy constraints.

Recommended location: ~/.claude/plugins/task-list-mirror/ as a self-contained Claude plugin. Alternatively ~/.claude/tools/task-list-mirror/ if plugin discovery is not needed (invoked via explicit command from a skill).


Leading recommendation: Option C — New minimal UI

Section titled “Leading recommendation: Option C — New minimal UI”

Rationale: The per-Task .md mirror feature has a specific, narrow requirement: render one Task’s content, allow field edits and text edits, write back to task-list.json. Neither Plannotator nor the kh-platform code serves this requirement out of the box. Option C reaches the same end state (~10h) with fewer risks: no upstream divergence (Option A R1), no decommissioned code debt (Option B R1), and clean cross-project packaging from day one.

The kh-platform reuse option (B) is strictly dominated. The Plannotator fork option (A) is viable but adds ~3h of fork-maintenance overhead relative to Option C, for features (annotation system, plan diff, URL sharing) that are not required for the per-Task viewer use case.

Minimum viable scope for Option C:

  1. A Bun.serve HTTP server (single file, ~150 lines) that:
    • Serves the UI HTML on GET /
    • Returns task-list.json parsed Task on GET /api/task/:id
    • Accepts field patches on PATCH /api/task/:id and writes back to task-list.json
  2. A React SPA (Vite, ~300 lines) that:
    • Renders the Task frontmatter table with editable dropdowns for status and priority
    • Renders the Subtask list with details field editable via <textarea>
    • Renders <info added on …> journal blocks read-only
  3. A Claude plugin entry point (skill) at ~/.claude/plugins/task-list-mirror/commands/ that invokes task-mirror <ID-N.md> and waits for the user to close the browser.

Second-place fallback: Option A — Plannotator fork

Section titled “Second-place fallback: Option A — Plannotator fork”

If Liam prefers to invest in Plannotator (already installed and familiar) rather than building new tooling, Option A is the fallback. The fork is manageable if kept local. Key condition: Delta C (JSON patch to task-list.json) must be the write-back target — writing to the .md mirror without reverse-generation is out of scope per design doc §5.

The recommendation hinges on one architectural judgement call:

OQ-1 (dispositive): Do you prefer to extend Plannotator (familiar, already installed) with task-editor capability (Option A, ~12–16h total including fork maintenance setup), or build a minimal purpose-built tool (Option C, ~10h, cleaner cross-project boundary)?


§7 — Cross-project tooling location implications

Section titled “§7 — Cross-project tooling location implications”

Per per-task-file-mirror-design.md §7 constraint: generator + render surface MUST NOT live inside knowledge-hub/scripts/ or lib/.

For the leading recommendation (Option C):

ComponentWhere it livesRationale
Generator script (generate-task-md.ts)~/.claude/tools/task-list-mirror/generate.tsCross-project script invoked by the Stop hook. KH’s .claude/settings.json wires the PostToolUse hook to invoke it. Invocable by any project that adopts the pattern.
Task mirror viewer server~/.claude/plugins/task-list-mirror/server/index.tsBun server + React SPA as a Claude plugin. Discovered automatically by Claude Code. Can be invoked from any project directory.
Plugin manifest~/.claude/plugins/task-list-mirror/.claude-plugin/plugin.jsonStandard Claude plugin location.
Task mirror viewer skill~/.claude/skills/task-list-mirror/SKILL.md or ~/.claude/plugins/task-list-mirror/commands/task-mirror.mdSlash command that invokes task-mirror <ID-N.md> — or a zero-arg command that opens the current project’s task list.
Write-back server (/api/task/:id PATCH)Part of plugin server (~/.claude/plugins/task-list-mirror/server/)Server reads/writes task-list.json at the path provided (project-relative). Cross-project: each project supplies the path.
Per-project glueKH’s .claude/settings.json PostToolUse hook + .github/workflows/ci.yml gen:tasks --check stepThe hook wiring and CI guard are per-project configuration — they stay in KH but reference the cross-project tool by absolute path or $PATH name.
Mirror output files (docs/reference/tasks/*.md)KH’s docs/reference/tasks/These are KH-rendered artefacts — per design doc §7, the output stays in KH even if the generator lives outside it.

What does NOT leave KH:

  • docs/reference/task-list.json (canonical data, KH-owned)
  • docs/reference/tasks/*.md (generated artefacts, KH-owned)
  • .claude/settings.json Stop hook entry (per-project glue)
  • .github/workflows/ci.yml gen:tasks --check step (per-project glue)
  • lib/validation/task-list-schema.ts and parseTaskListWithWarnings (KH validation layer; the cross-project generator imports it or vendors a copy)

For Option A (Plannotator fork fallback):

The forked Plannotator lives at /Users/liamj/Documents/development/plannotator (already there). The per-Task edit mode additions would be confined to the fork. The plugin install would point at the local fork directory:

claude --plugin-dir /Users/liamj/Documents/development/plannotator/apps/hook

Or, once stable, packaged to ~/.claude/plugins/plannotator-local/ mirroring the fork. The generator script still lives at ~/.claude/tools/task-list-mirror/generate.ts — same as Option C.


§8 — Open questions for Liam ratification (gates ID-20.3 PRODUCT.md authoring)

Section titled “§8 — Open questions for Liam ratification (gates ID-20.3 PRODUCT.md authoring)”

These questions are in addition to the Q1–Q8 from per-task-file-mirror-design.md §3 (file shape questions, still open). The render-surface OQs are lettered to distinguish them.


OQ-1 (DISPOSITIVE — gates option choice): Build a new minimal task-viewer + editor (Option C, ~10h, clean cross-project boundary from day one) or extend Plannotator with edit capability (Option A, ~12–16h including fork setup, familiar tool)?

Default proposal: Option C. Rationale: narrower scope, no upstream divergence risk, purpose-built for the task-viewer use case.


OQ-2: For write-back, should edits in the viewer always go directly to task-list.json (canonical), with the .md mirror regenerating automatically via Stop hook? Or is it acceptable to write to the .md mirror first and run a reverse generator?

Default proposal: Direct to task-list.json. Reverse generation adds sync complexity and is out of scope per design doc §5.


OQ-3: Should the task viewer be invoked as a Claude plugin (auto-discovered by Claude Code, available as a slash command from any session) or as a standalone CLI tool (invoked explicitly outside Claude Code, e.g., task-mirror ID-20)?

Default proposal: Claude plugin (cross-project slash command). Rationale: consistent with the Plannotator pattern Liam already uses; Claude Code context available during editing (e.g., agent can apply changes after Liam edits).


OQ-4: For structured field edits (status, priority), should the viewer understand the full Task status state machine (pending → in_progress → done → cancelled), or just present all valid enum values without enforcing transitions?

Default proposal: Present all valid values without enforcing transitions. Transition enforcement is a workflow-orchestration concern; the viewer is a lightweight editing surface.


OQ-5: Should the details field editor show the raw text (including embedded <info added on …> journal blocks), or should journal blocks be rendered read-only with only the pre-journal content editable?

Default proposal: Full raw details field editable as a single textarea. Journal blocks are already marked with ISO timestamps; Liam is unlikely to accidentally corrupt them when editing Subtask description text above them. Separating the two adds UI complexity.


OQ-6: Cross-project tool location: ~/.claude/plugins/task-list-mirror/ (Claude plugin, slash-command invocation) vs. ~/.claude/tools/task-list-mirror/ (bare scripts dir, invoked by name) vs. separate dev-tooling git repo?

Default proposal: ~/.claude/plugins/task-list-mirror/ (Claude plugin). Rationale: auto-discovered; slash command available from any session; consistent with CLAUDE.md §7 tooling target evaluation.


OQ-7 (new — from §2 Delta C): The details field in Subtasks contains embedded journal blocks using the <info added on YYYY-MM-DDTHH:MM:SS.sssZ> convention. If Liam edits the details text via the viewer UI, should the edit be appended as a new journal block (with a system-generated timestamp prefix) or applied as an in-place mutation of the pre-journal content?

Default proposal: In-place mutation of pre-journal content only. The editor separates the static details description (editable) from journal blocks (append-only, not editable in the viewer). New journal blocks continue to be appended by workflow agents.


End of open questions.