planr 0.0.1 → 1.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +144 -0
  3. package/docs/ARCHITECTURE.md +75 -0
  4. package/docs/CI.md +54 -0
  5. package/docs/CLAUDE_CODE.md +33 -0
  6. package/docs/CLI_REFERENCE.md +124 -0
  7. package/docs/CODEX.md +48 -0
  8. package/docs/CURSOR.md +30 -0
  9. package/docs/GOALS.md +155 -0
  10. package/docs/HANDOFFS_AND_STORIES.md +121 -0
  11. package/docs/IMPORT.md +21 -0
  12. package/docs/INSTALL.md +98 -0
  13. package/docs/MCP_CONTRACT.md +70 -0
  14. package/docs/MCP_GUIDE.md +40 -0
  15. package/docs/NPM.md +40 -0
  16. package/docs/OPERATING_MODEL.md +250 -0
  17. package/docs/RELEASE.md +140 -0
  18. package/docs/SECURITY.md +8 -0
  19. package/docs/SKILLS.md +278 -0
  20. package/docs/TASK_GRAPH_MODEL.md +222 -0
  21. package/docs/TESTING.md +87 -0
  22. package/docs/TROUBLESHOOTING.md +26 -0
  23. package/docs/fixtures/mcp-contract.json +92 -0
  24. package/docs/planr-spec/ADRS.md +160 -0
  25. package/docs/planr-spec/AI_SPEC.md +138 -0
  26. package/docs/planr-spec/ANALYTICS_OBSERVABILITY_SPEC.md +124 -0
  27. package/docs/planr-spec/API_AND_DATA_MODEL.md +517 -0
  28. package/docs/planr-spec/BACKEND_IMPLEMENTATION_SPEC.md +178 -0
  29. package/docs/planr-spec/CLIENT_IMPLEMENTATION_SPEC.md +119 -0
  30. package/docs/planr-spec/DESIGN_SYSTEM_SPEC.md +102 -0
  31. package/docs/planr-spec/PRODUCT_SPEC.md +193 -0
  32. package/docs/planr-spec/QA_ACCEPTANCE_TESTS.md +146 -0
  33. package/docs/planr-spec/README.md +67 -0
  34. package/docs/planr-spec/REFERENCES.md +29 -0
  35. package/docs/planr-spec/RELEASE_READINESS.md +95 -0
  36. package/docs/planr-spec/SAFETY_PRIVACY_SECURITY.md +169 -0
  37. package/docs/planr-spec/TASKS.md +932 -0
  38. package/docs/planr-spec/TECH_ARCHITECTURE.md +143 -0
  39. package/docs/planr-spec/UX_FLOWS.md +235 -0
  40. package/docs/planr-spec/V1_1_DIFFERENTIATION_CONTRACT.md +177 -0
  41. package/docs/planr-spec.zip +0 -0
  42. package/npm/bin/planr.js +54 -0
  43. package/npm/native/darwin-arm64/planr +0 -0
  44. package/npm/native/darwin-x86_64/planr +0 -0
  45. package/npm/native/linux-arm64/planr +0 -0
  46. package/npm/native/linux-x86_64/planr +0 -0
  47. package/package.json +27 -8
  48. package/plugins/planr/.claude-plugin/plugin.json +11 -0
  49. package/plugins/planr/.codex-plugin/plugin.json +25 -0
  50. package/plugins/planr/agents/planr-reviewer.md +12 -0
  51. package/plugins/planr/agents/planr-worker.md +10 -0
  52. package/plugins/planr/skills/planr/SKILL.md +52 -0
  53. package/plugins/planr/skills/planr-goal/SKILL.md +69 -0
  54. package/plugins/planr/skills/planr-loop/SKILL.md +112 -0
  55. package/plugins/planr/skills/planr-loop/agents/planr-reviewer.toml +17 -0
  56. package/plugins/planr/skills/planr-loop/agents/planr-worker.toml +14 -0
  57. package/plugins/planr/skills/planr-plan/SKILL.md +58 -0
  58. package/plugins/planr/skills/planr-review/SKILL.md +49 -0
  59. package/plugins/planr/skills/planr-status/SKILL.md +50 -0
  60. package/plugins/planr/skills/planr-summary/SKILL.md +28 -0
  61. package/plugins/planr/skills/planr-task-graph/SKILL.md +228 -0
  62. package/plugins/planr/skills/planr-verify-web/SKILL.md +76 -0
  63. package/plugins/planr/skills/planr-work/SKILL.md +68 -0
@@ -0,0 +1,517 @@
1
+ # API And Data Model
2
+
3
+ ## Storage Locations
4
+
5
+ - SQLite: authoritative map graph state, picks, contexts, logs, runs, events, search indexes.
6
+ - `.planr/project/*.md`: durable project context pack.
7
+ - `.planr/plans/product/<slug>/`: product specification packages.
8
+ - `.planr/plans/build/*.plan.md`: Markdown implementation plans.
9
+ - `.planr/reviews/*.review.md`: optional saved review artifacts.
10
+ - Git: source diffs, commits, branches, and worktrees.
11
+
12
+ ## Core Tables
13
+
14
+ ### projects
15
+
16
+ ```text
17
+ id TEXT PRIMARY KEY
18
+ name TEXT NOT NULL
19
+ root_path TEXT NOT NULL
20
+ description TEXT
21
+ status TEXT NOT NULL
22
+ metadata JSON
23
+ created_at DATETIME
24
+ updated_at DATETIME
25
+ ```
26
+
27
+ ### items
28
+
29
+ ```text
30
+ id TEXT PRIMARY KEY
31
+ project_id TEXT NOT NULL
32
+ parent_item_id TEXT
33
+ title TEXT NOT NULL
34
+ description TEXT
35
+ status TEXT NOT NULL
36
+ work_type TEXT NOT NULL
37
+ priority INTEGER
38
+ worker_id TEXT
39
+ plan_path TEXT
40
+ pick_token TEXT
41
+ picked_at DATETIME
42
+ last_heartbeat_at DATETIME
43
+ progress_percent INTEGER
44
+ progress_note TEXT
45
+ paused_at DATETIME
46
+ timeout_seconds INTEGER
47
+ max_retries INTEGER
48
+ retry_count INTEGER
49
+ retry_backoff TEXT
50
+ retry_delay_ms INTEGER
51
+ pre_condition TEXT
52
+ post_condition TEXT
53
+ approval_status TEXT
54
+ approval_requested_at DATETIME
55
+ approved_by TEXT
56
+ approval_comment TEXT
57
+ started_at DATETIME
58
+ completed_at DATETIME
59
+ result JSON
60
+ error TEXT
61
+ metadata JSON
62
+ created_at DATETIME
63
+ updated_at DATETIME
64
+ ```
65
+
66
+ Item work types:
67
+
68
+ - generic
69
+ - research
70
+ - plan
71
+ - code
72
+ - review
73
+ - fix
74
+ - test
75
+ - shell
76
+ - release
77
+
78
+ Item statuses:
79
+
80
+ - pending
81
+ - ready
82
+ - picked
83
+ - running
84
+ - in_review
85
+ - blocked
86
+ - closed
87
+ - closed_partial
88
+ - failed
89
+ - cancelled
90
+
91
+ ### links
92
+
93
+ ```text
94
+ id INTEGER PRIMARY KEY
95
+ from_item TEXT NOT NULL
96
+ to_item TEXT NOT NULL
97
+ kind TEXT NOT NULL
98
+ condition TEXT NOT NULL
99
+ metadata JSON
100
+ UNIQUE(from_item, to_item, kind)
101
+ ```
102
+
103
+ Link kinds:
104
+
105
+ - blocks: upstream must complete before downstream is ready.
106
+ - hands_to: upstream result is included in downstream handoff.
107
+ - reviews: review item blocks parent/target closure.
108
+ - relates_to: non-blocking context relationship.
109
+
110
+ ### plans
111
+
112
+ ```text
113
+ id TEXT PRIMARY KEY
114
+ project_id TEXT NOT NULL
115
+ stage TEXT NOT NULL
116
+ path TEXT NOT NULL
117
+ title TEXT NOT NULL
118
+ slug TEXT NOT NULL
119
+ package_manifest JSON
120
+ frontmatter JSON
121
+ parse_status TEXT NOT NULL
122
+ content_hash TEXT NOT NULL
123
+ created_at DATETIME
124
+ updated_at DATETIME
125
+ ```
126
+
127
+ Plan stages:
128
+
129
+ - product
130
+ - build
131
+ - review
132
+
133
+ ### source_links
134
+
135
+ ```text
136
+ id INTEGER PRIMARY KEY
137
+ source_type TEXT NOT NULL
138
+ source_id TEXT NOT NULL
139
+ item_id TEXT NOT NULL
140
+ section_id TEXT
141
+ relationship TEXT NOT NULL
142
+ ```
143
+
144
+ Relationships:
145
+
146
+ - scopes
147
+ - implements
148
+ - verifies
149
+ - reviews
150
+ - references
151
+
152
+ ### contexts
153
+
154
+ ```text
155
+ id TEXT PRIMARY KEY
156
+ project_id TEXT NOT NULL
157
+ item_id TEXT
158
+ worker_id TEXT
159
+ kind TEXT NOT NULL
160
+ content TEXT NOT NULL
161
+ tags JSON
162
+ created_at DATETIME
163
+ ```
164
+
165
+ Kinds:
166
+
167
+ - discovery
168
+ - decision
169
+ - constraint
170
+ - pattern
171
+ - blocker
172
+ - bug
173
+ - risk
174
+
175
+ ### runs
176
+
177
+ ```text
178
+ id TEXT PRIMARY KEY
179
+ project_id TEXT NOT NULL
180
+ item_id TEXT NOT NULL
181
+ worker_id TEXT NOT NULL
182
+ client TEXT NOT NULL
183
+ profile TEXT
184
+ command TEXT
185
+ cwd TEXT
186
+ worktree_path TEXT
187
+ status TEXT NOT NULL
188
+ started_at DATETIME
189
+ ended_at DATETIME
190
+ exit_code INTEGER
191
+ metadata JSON
192
+ ```
193
+
194
+ Clients:
195
+
196
+ - codex
197
+ - claude-code
198
+ - cursor
199
+ - generic-mcp
200
+ - human
201
+ - ci
202
+
203
+ ### logs
204
+
205
+ ```text
206
+ id TEXT PRIMARY KEY
207
+ project_id TEXT NOT NULL
208
+ item_id TEXT NOT NULL
209
+ run_id TEXT
210
+ kind TEXT NOT NULL
211
+ summary TEXT NOT NULL
212
+ files JSON
213
+ commands JSON
214
+ tests JSON
215
+ review_findings JSON
216
+ blocked_or_unverified JSON
217
+ created_at DATETIME
218
+ ```
219
+
220
+ Log kinds:
221
+
222
+ - completion
223
+ - review
224
+ - failure
225
+ - handoff
226
+ - verification
227
+
228
+ ### artifacts
229
+
230
+ ```text
231
+ id TEXT PRIMARY KEY
232
+ project_id TEXT NOT NULL
233
+ item_id TEXT
234
+ name TEXT NOT NULL
235
+ kind TEXT
236
+ path TEXT
237
+ content TEXT
238
+ mime_type TEXT
239
+ size_bytes INTEGER
240
+ metadata JSON
241
+ created_at DATETIME
242
+ ```
243
+
244
+ ### events
245
+
246
+ ```text
247
+ id INTEGER PRIMARY KEY
248
+ project_id TEXT
249
+ item_id TEXT
250
+ worker_id TEXT
251
+ event_type TEXT NOT NULL
252
+ payload JSON
253
+ timestamp DATETIME
254
+ ```
255
+
256
+ ## Plan Package Contract
257
+
258
+ Product plan packages use this structure:
259
+
260
+ ```text
261
+ .planr/plans/product/<slug>/
262
+ README.md
263
+ PRODUCT_SPEC.md
264
+ UX_FLOWS.md
265
+ DESIGN_SYSTEM_SPEC.md
266
+ TECH_ARCHITECTURE.md
267
+ ADRS.md
268
+ AI_SPEC.md
269
+ SAFETY_PRIVACY_SECURITY.md
270
+ API_AND_DATA_MODEL.md
271
+ CLIENT_IMPLEMENTATION_SPEC.md
272
+ BACKEND_IMPLEMENTATION_SPEC.md
273
+ ANALYTICS_OBSERVABILITY_SPEC.md
274
+ QA_ACCEPTANCE_TESTS.md
275
+ RELEASE_READINESS.md
276
+ TASKS.md
277
+ REFERENCES.md
278
+ ```
279
+
280
+ - REQ-API-001: Plan packages must include a manifest with generated date, source prompt, assumptions, and included documents.
281
+ - REQ-API-002: Plan work lists are candidate work, not live map items until accepted.
282
+
283
+ ## Build Plan Contract
284
+
285
+ Plan files use this minimum shape:
286
+
287
+ ```markdown
288
+ ---
289
+ name: short-name
290
+ overview: One paragraph.
291
+ todos:
292
+ - id: phase-1
293
+ content: Summary item.
294
+ status: pending
295
+ isProject: false
296
+ ---
297
+
298
+ # Plan Title
299
+
300
+ ## Scope Decision
301
+ ## Ownership Target
302
+ ## Existing Leverage
303
+ ## Phase 1: ...
304
+ ## Out Of Scope
305
+ ## Verification
306
+ ## Acceptance Criteria
307
+ ```
308
+
309
+ - REQ-API-010: Plan parsing must preserve unknown frontmatter fields.
310
+ - REQ-API-011: Plan parsing failure must not delete or rewrite the original Markdown.
311
+ - REQ-API-012: Closure status must not be inferred solely from Markdown checkboxes.
312
+
313
+ ## CLI API
314
+
315
+ ### Project
316
+
317
+ ```bash
318
+ planr project init [--client codex|claude|cursor|all] [--force]
319
+ planr project show [--json]
320
+ planr project list [--json]
321
+ planr doctor [--client codex|claude|cursor|all]
322
+ planr install codex|claude|cursor [--dry-run]
323
+ planr prompt cli|mcp|http [--client codex|claude|cursor|all]
324
+ planr mcp
325
+ planr serve --port 7526
326
+ planr import <file> [--preview] [--confirm]
327
+ planr export --out planr.json [--include-plans] [--include-logs] [--template-name "..."] [--tag tag]
328
+ ```
329
+
330
+ ### Plan
331
+
332
+ ```bash
333
+ planr plan new "App idea" [--platform web] [--ai] [--backend]
334
+ planr plan refine <plan-id>
335
+ planr plan split <plan-id> --slice "MVP backend"
336
+ planr plan check <plan-id>
337
+ planr plan show <plan-id>
338
+ planr plan archive <plan-id>
339
+ ```
340
+
341
+ ### Map
342
+
343
+ ```bash
344
+ planr map show
345
+ planr map build --from <plan-id>
346
+ planr map status
347
+ planr map preview --close <item-id>
348
+ planr map unlocks <item-id>
349
+ planr map lookahead [--from <item-id>]
350
+ planr item create "title" --description "..." [--after item-id] [--timeout-seconds N] [--max-retries N] [--retry-backoff fixed|exponential] [--retry-delay-ms N] [--pre "..."] [--post "..."]
351
+ planr item breakdown <item-id> --into "A, B, C"
352
+ planr item insert "title" --description "..." --after <item-id> [--before <item-id>] [--preview|--confirm]
353
+ planr item amend <item-id> --note "..."
354
+ planr item replan <parent-id> --into "A, B, C" [--preview|--confirm]
355
+ planr link add <from-item> <to-item> --type blocks
356
+ planr pick
357
+ planr pick release <item-id> [--force]
358
+ planr pick heartbeat [item-id]
359
+ planr pick progress <item-id> --percent 0..100 [--note "..."]
360
+ planr pick pause <item-id> [--note "..."]
361
+ planr pick resume <item-id>
362
+ planr pick stale [--older-than-seconds 900] [--release]
363
+ planr recover sweep [--older-than-seconds 900] [--apply]
364
+ planr approval request <item-id> [--reason "..."]
365
+ planr approval approve <item-id> --by "name" [--comment "..."]
366
+ planr approval deny <item-id> --by "name" [--comment "..."]
367
+ planr approval list [--open]
368
+ planr artifact add "name" [--item <item-id>] [--kind evidence] [--path file] [--content "..."]
369
+ planr artifact show <artifact-id>
370
+ planr artifact list [--item <item-id>]
371
+ planr event list [--item <item-id>] [--limit 50]
372
+ planr debug bundle [--item <item-id>] --preview
373
+ planr log add --item <item-id> --summary "..." [--files a,b] [--cmd "..."]
374
+ planr review request <item-id>
375
+ planr review annotate <item-id> --message "..." [--severity info|warning|blocking] [--file path] [--line N] [--author "..."]
376
+ planr review ingest <item-id> (--from feedback.json|--stdin)
377
+ planr review artifact <review-item-id> [--out path]
378
+ planr review evidence <item-id> [--pr-url https://...]
379
+ planr review close <review-item-id> --verdict complete|not-complete|unclear [--close-target]
380
+ planr close [item-id] --summary "..." [--next]
381
+ planr done [item-id] --summary "..." [--files a --files b] [--cmd "..."] [--tests "..."] [--review] [--next]
382
+ planr map lane --critical
383
+ planr map pressure
384
+ ```
385
+
386
+ ## MCP Tools
387
+
388
+ - `planr_project_show`
389
+ - `planr_map_show`
390
+ - `planr_map_status`
391
+ - `planr_map_preview`
392
+ - `planr_map_unlocks`
393
+ - `planr_map_lookahead`
394
+ - `planr_plan_create`
395
+ - `planr_plan_refine`
396
+ - `planr_plan_split`
397
+ - `planr_plan_check`
398
+ - `planr_plan_link`
399
+ - `planr_map_build`
400
+ - `planr_item_create`
401
+ - `planr_item_breakdown`
402
+ - `planr_item_insert`
403
+ - `planr_item_amend`
404
+ - `planr_item_replan`
405
+ - `planr_pick_item`
406
+ - `planr_pick_heartbeat`
407
+ - `planr_pick_progress`
408
+ - `planr_pick_pause`
409
+ - `planr_pick_resume`
410
+ - `planr_pick_stale`
411
+ - `planr_recover_sweep`
412
+ - `planr_approval_request`
413
+ - `planr_approval_approve`
414
+ - `planr_approval_deny`
415
+ - `planr_approval_list`
416
+ - `planr_artifact_add`
417
+ - `planr_artifact_list`
418
+ - `planr_artifact_show`
419
+ - `planr_event_list`
420
+ - `planr_debug_bundle`
421
+ - `planr_log_add`
422
+ - `planr_review_annotate`
423
+ - `planr_review_ingest`
424
+ - `planr_review_artifact`
425
+ - `planr_review_evidence`
426
+ - `planr_review_close`
427
+ - `planr_close_item`
428
+ - `planr_context_create`
429
+ - `planr_search`
430
+ - `planr_log_read`
431
+
432
+ ## MCP Resources
433
+
434
+ - `planr://project/context`
435
+ - `planr://project/map`
436
+ - `planr://item/{id}`
437
+ - `planr://plan/{id}`
438
+ - `planr://log/{id}`
439
+
440
+ ## MCP Prompts
441
+
442
+ - `planr-plan`
443
+ - `planr-work`
444
+ - `planr-review`
445
+ - `planr-map`
446
+ - `planr-summary`
447
+
448
+ ## HTTP API
449
+
450
+ HTTP is optional in V1 and localhost-only by default.
451
+
452
+ ```text
453
+ GET /review
454
+ GET /v1/review-workspace
455
+ GET /v1/projects
456
+ POST /v1/projects
457
+ GET /v1/projects/:id/map
458
+ GET /v1/projects/:id/items
459
+ POST /v1/projects/:id/items
460
+ POST /v1/pick
461
+ POST /v1/items/:id/heartbeat
462
+ POST /v1/items/:id/progress
463
+ POST /v1/items/:id/pause
464
+ POST /v1/items/:id/resume
465
+ POST /v1/items/:id/approval/request
466
+ POST /v1/items/:id/approval/approve
467
+ POST /v1/items/:id/approval/deny
468
+ GET /v1/approvals?open=true
469
+ POST /v1/artifacts
470
+ GET /v1/artifacts
471
+ GET /v1/artifacts/:id
472
+ GET /v1/events
473
+ GET /v1/debug/bundle
474
+ POST /v1/items/:id/log
475
+ POST /v1/items/:id/close
476
+ POST /v1/items/:id/reviews
477
+ POST /v1/items/:id/review-annotations
478
+ GET /v1/items/:id/review-evidence
479
+ POST /v1/items/:id/review-evidence
480
+ POST /v1/items/:id/review-feedback
481
+ POST /v1/reviews/:id/close
482
+ POST /v1/reviews/:id/artifact
483
+ GET /v1/reviews/:id/artifact
484
+ POST /v1/contexts
485
+ GET /v1/search?q=...
486
+ GET /v1/events/stream
487
+ ```
488
+
489
+ ## Error Model
490
+
491
+ ```json
492
+ {
493
+ "error": {
494
+ "code": "not_found",
495
+ "message": "item not found",
496
+ "details": {}
497
+ }
498
+ }
499
+ ```
500
+
501
+ Required codes:
502
+
503
+ - bad_request
504
+ - not_found
505
+ - conflict
506
+ - invalid_transition
507
+ - locked
508
+ - parse_error
509
+ - unauthorized_remote
510
+ - internal_error
511
+
512
+ ## Retention
513
+
514
+ - Local database persists until user deletes it.
515
+ - Plan files persist in Git/repo unless archived or deleted.
516
+ - Log persists locally by default.
517
+ - Full transcript retention is off by default.
@@ -0,0 +1,178 @@
1
+ # Backend Implementation Specification
2
+
3
+ ## Backend Scope
4
+
5
+ The backend is a local engine embedded in the `planr` binary. It owns map state, plan parsing, search, MCP tools, optional HTTP/SSE, and integration runners.
6
+
7
+ ## Language And Runtime
8
+
9
+ Recommended default:
10
+
11
+ - Rust 2021 or newer.
12
+ - `rusqlite` or equivalent SQLite binding.
13
+ - `clap` for CLI.
14
+ - `serde` for JSON.
15
+ - `tokio` and `axum` only if HTTP/SSE ships in V1.
16
+
17
+ ## Core Modules
18
+
19
+ ```text
20
+ src/
21
+ core/
22
+ graph.rs
23
+ state_machine.rs
24
+ readiness.rs
25
+ log.rs
26
+ reviews.rs
27
+ search.rs
28
+ storage/
29
+ schema.rs
30
+ upgrades.rs
31
+ sqlite.rs
32
+ planpack/
33
+ markdown.rs
34
+ frontmatter.rs
35
+ project_pack.rs
36
+ packages.rs
37
+ cli/
38
+ mcp/
39
+ server/
40
+ agents/
41
+ codex.rs
42
+ claude_code.rs
43
+ cursor.rs
44
+ git/
45
+ ```
46
+
47
+ ## State Machine
48
+
49
+ REQ-BE-001: State transitions must be centralized.
50
+
51
+ Required transitions:
52
+
53
+ ```text
54
+ pending -> ready
55
+ ready -> picked
56
+ picked -> running
57
+ running -> picked
58
+ running -> closed
59
+ running -> blocked
60
+ running -> failed
61
+ failed -> ready
62
+ running -> cancelled
63
+ ```
64
+
65
+ Lenient single-agent convenience may allow `ready -> closed` only when no other active pick exists and the worker id is explicit.
66
+
67
+ ## Readiness Engine
68
+
69
+ REQ-BE-010: Readiness must be recomputed transactionally after item creation, link changes, and closure.
70
+
71
+ REQ-BE-011: An item is ready only when all blocking and feeds-into links are closed or closed_partial.
72
+
73
+ REQ-BE-012: Parent item closure must check required children and reviews.
74
+
75
+ ## Atomic Picking
76
+
77
+ REQ-BE-020: Picking must use an atomic update equivalent to:
78
+
79
+ ```sql
80
+ UPDATE items
81
+ SET status = 'picked',
82
+ worker_id = ?,
83
+ pick_token = ?,
84
+ picked_at = CURRENT_TIMESTAMP,
85
+ last_heartbeat_at = CURRENT_TIMESTAMP
86
+ WHERE id = ? AND status = 'ready';
87
+ ```
88
+
89
+ The caller succeeds only when exactly one row changes.
90
+
91
+ REQ-BE-021: Heartbeat updates must require the same worker owner when an owner exists, move `picked` to `running`, and refresh `last_heartbeat_at`.
92
+
93
+ REQ-BE-022: Progress, pause, and resume must preserve `worker_id` and `pick_token`.
94
+
95
+ REQ-BE-023: Stale detection must compare `last_heartbeat_at`, `picked_at`, or `updated_at` against an explicit threshold and release only when the caller requests release.
96
+
97
+ ## Approval Gates
98
+
99
+ REQ-BE-025: Approval request must store status `requested`, request time, and optional reason.
100
+
101
+ REQ-BE-026: Approval approve and deny must store the decision maker and optional comment.
102
+
103
+ REQ-BE-027: Close must reject items with approval status `requested` or `denied`.
104
+
105
+ ## Markdown Plan Parser
106
+
107
+ REQ-BE-030: Parser must support YAML frontmatter and Markdown headings.
108
+
109
+ REQ-BE-031: Parser must preserve files on parse errors and store a parse error record.
110
+
111
+ REQ-BE-032: Parser must map headings to stable section ids using slug + heading depth + ordinal.
112
+
113
+ REQ-BE-033: Parser must not execute instructions contained in plan files.
114
+
115
+ ## Search
116
+
117
+ REQ-BE-040: Search must index:
118
+
119
+ - item title/description;
120
+ - context content;
121
+ - plan title/manifest/frontmatter/headings;
122
+ - log summary;
123
+ - review findings summary.
124
+
125
+ REQ-BE-041: Search results must identify source type and path/id.
126
+
127
+ ## MCP Server
128
+
129
+ REQ-BE-050: MCP stdio server must start with `planr mcp`.
130
+
131
+ REQ-BE-051: Tool schemas must validate all mutation inputs.
132
+
133
+ REQ-BE-052: Tools must return compact JSON optimized for agent context.
134
+
135
+ REQ-BE-053: Resources must expose read-only project, item, plan, and log data.
136
+
137
+ REQ-BE-054: Prompts must expose Planr workflow prompts.
138
+
139
+ ## HTTP/SSE Server
140
+
141
+ Optional V1:
142
+
143
+ - `planr serve --port 7526`.
144
+ - localhost default bind.
145
+ - JSON REST API.
146
+ - SSE stream for events.
147
+ - no remote auth in V1 unless explicitly implemented.
148
+
149
+ ## Package Import
150
+
151
+ REQ-BE-060: Import must consume Planr JSON packages created by `planr export`.
152
+
153
+ REQ-BE-061: Import preview must report package metadata, create counts, and conflicting item ids without mutating state.
154
+
155
+ REQ-BE-062: Confirmed import must restore package graph items, links, contexts, optional logs, optional plan file snapshots, and review artifacts.
156
+
157
+ ## Agent Runners
158
+
159
+ Runner wrappers are optional but expected after core V1:
160
+
161
+ - Codex: `codex exec`, `codex review`.
162
+ - Claude Code: command runner or MCP-only guidance.
163
+ - Cursor: `cursor-agent` where available or MCP-only guidance.
164
+
165
+ REQ-BE-070: Runners must record run metadata and log.
166
+
167
+ REQ-BE-071: Runners must not hide approval, sandbox, or command failures.
168
+
169
+ ## Verification
170
+
171
+ Backend must include:
172
+
173
+ - unit tests for state transitions;
174
+ - integration tests for atomic pick races;
175
+ - integration tests for heartbeat, progress, pause, resume, stale release, and approval-blocked closure;
176
+ - parser tests for valid and invalid plan files;
177
+ - MCP tool schema tests;
178
+ - import fixture tests for existing `.planr` layouts.