Repository navigation
feat(plan): lint and import a plan/ package onto the Kanban board, with an approval card - #17
Merged
Merged
Conversation
…th an approval card A planner bot writes plan/tasks/*.md but never a Kanban card (the model that writes a plan is not the one that gets to decide it is correct, see docs/room-guardrails.md). This is the bridge: a linted preview the user approves, then the server — not an LLM — writes the cards. - plan-lib.js (pure, no fs): parseTaskFile (front matter + body), lintPlan (errors: duplicate id, unknown/missing bot, a depends_on cycle or dangling reference, missing title; warnings: no acceptance/verification section, no ТЗ coverage), buildImportPlan (create/update/skip, never a dangling depends_on), guessTzFile (name-based, for the coverage check). - plan-import.js: reads plan/tasks/*.md + 00-overview.md + the guessed ТЗ file (fsImpl injectable) and builds the review object; never touches the DB. - server.js: tasks.plan_task_id column (re-approving a plan UPDATES its cards instead of duplicating them, and never resets a status a human already moved past 'backlog'); POST /api/plans/review (dry run) and /api/plans/import (writes, re-lints fresh, cards land as 'backlog' — approving a plan never starts unattended work); the room posts a plan_review card automatically the moment its closing step changes plan/tasks/*.md (the disk diff it already computes, no extra model call); WS approve_plan applies the card's selection. - public/index.html: the approval card (checkboxes, deselecting a task also deselects its dependents, errors/warnings, an "imported" done state), restored identically from the DB on reload, wired into the same places agent_plan already is (Done-footer skip, markdown export skip, the message-ingestion loop). Tests: plan-lib (54), plan-import (21, fake fs), plans-api (19, a real server + real files: review/import/re-import/idempotency/status-preserved/subset-selection/dangling-dependency- skip), render/plan-review.test.mjs (card HTML + wiring). Confirmed live: a scripted room run (real runConversationRoom, a fake CLI that writes real plan files) posts the card the moment the closing step writes plan/tasks/*.md, with correct coverage; the card itself checked in real headless Chrome (render, checkbox/dependent interaction, the imported state) against the branch's own server.js. Whole npm test suite green. Not verified: a live run with a real model as the closing writer end to end through the actual card (the scripted-CLI run above covers the server-side wiring; PR #12's live run already showed the planner writing real plan/ files). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y2ZSHUdJHqVsvSNQ5ZeQ3f
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the loop the
plannerbot (#9-#13) exists for: a planner writesplan/tasks/*.mdbut never a Kanban card — the model that writes a plan is not the one that gets to decide it is correct (seedocs/room-guardrails.md). This is the bridge: a linted preview the user approves, then the server, not an LLM, writes the cards.What
plan-lib.js(pure):parseTaskFile,lintPlan(errors block approval: duplicate id, unknown/missing bot, adepends_oncycle or dangling reference, missing title; warnings don't: no acceptance/verification section, no ТЗ coverage),buildImportPlan(create/update/skip — never a danglingdepends_on),guessTzFile(name-based, for the coverage check).plan-import.js: readsplan/tasks/*.md+00-overview.md+ the guessed ТЗ file (fs injectable for tests) into the review object; no DB.server.js:tasks.plan_task_idcolumn so re-approving a plan updates its cards instead of duplicating them, and never resets a status a human already moved pastbacklog.POST /api/plans/review(dry run) and/api/plans/import(writes, re-lints fresh, cards land asbacklog— approving a plan never starts unattended work). The room posts aplan_reviewcard automatically the moment its closing step changesplan/tasks/*.md(the disk diff it already computes — no extra model call). WSapprove_planapplies the card's selection.agent_planalready is.Tests
plan-lib54,plan-import21 (fake fs),plans-api19 (real server + real files: review/import/re-import/idempotency/status-preserved/subset-selection/dangling-dependency-skip),render/plan-review(card HTML + wiring). Confirmed live: a scripted room run (realrunConversationRoom, a fake CLI that writes real plan files) posts the card the moment the closing step writesplan/tasks/*.md, with correct coverage math; the card itself checked in real headless Chrome (render, checkbox/dependent interaction, the imported state) against this branch's ownserver.js. Wholenpm testsuite green.Not verified
A live run with a real model as the closing writer, all the way through the actual card (the scripted-CLI run above covers the server-side wiring end to end; PR #12's earlier live run already showed the planner writing real
plan/files).Known gap (documented in
docs/plan-kanban-import.md)No manual "review this plan again" button in the UI yet — only the automatic trigger right after a room's closing step, plus the two HTTP endpoints.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Y2ZSHUdJHqVsvSNQ5ZeQ3f