Skip to content

feat(annotate): approve/reject flow for spec-driven development frameworks #570

@punk-dev-robot

Description

@punk-dev-robot

Context

Spec-driven development frameworks (spec-kit, kiro, openspec, etc.) are replacing traditional plan mode in AI coding workflows. Instead of a single plan file, these frameworks generate multiple markdown artifacts (spec.md, plan.md, tasks.md, research.md, data-model.md) that go through iterative review cycles.

Plannotator's annotation UI is a perfect fit for reviewing these artifacts — inline, targeted feedback on markdown is exactly what's needed. I've built integrations for both Claude Code (PostToolUse hook) and OpenCode (event plugin) that trigger plannotator annotate whenever a spec artifact is written.

The value proposition is significant: every spec-driven framework generates multiple markdown files per feature, each needing human review. Plannotator could be the universal review layer across all of them.

Problem

plannotator annotate currently has no approve/accept exit path. The UI shows Close and Annotate buttons, but no Approve.

This creates three issues:

  1. No "looks good" signal: Closing without feedback returns "Annotation session closed without feedback" on stdout. There's no way to distinguish "I reviewed this and it's fine" from "I dismissed this without looking."

  2. Claude Code hook breaks: The Claude Code hook (source) runs as a blocking PostToolUse hook. Any stdout from plannotator triggers a block — including the "closed without feedback" message. This means every spec file write gets blocked with no way to approve.

  3. OpenCode plugin works around it, but incompletely: The OpenCode plugin (source) runs async and sends annotations back as a session prompt. Empty stdout = no action, which is better. But "closed without feedback" still produces stdout, and there's still no explicit approve signal.

Proposed Solution

Add an Approve (or Accept) button to the annotation UI for plannotator annotate:

  • Approve: exits with code 0 and empty stdout (or a structured {"decision": "approved"} if downstream hooks want to distinguish approved from dismissed)
  • Annotate: existing behavior — exits with annotations on stdout
  • Close/Dismiss: exits with code 0 and empty stdout (current behavior for no annotations, but currently outputs the "closed without feedback" message)

Optionally:

  • A --gate or --review-mode flag that explicitly enables the 3-button (Approve/Annotate/Dismiss) UX for hook integrations
  • Structured JSON output mode (--json) so hooks can parse the decision cleanly

Why This Matters Beyond Plan Mode

Plannotator currently shines for plan review. But spec-driven development is where the volume is:

  • A single feature generates 4-6 markdown files (spec, plan, tasks, research, data-model, quickstart)
  • Each goes through clarify → review → approve cycles
  • Multiple frameworks exist (spec-kit, kiro, openspec) with the same pattern
  • All of them need a human-in-the-loop review step for markdown artifacts

A working approve/reject flow for plannotator annotate would make plannotator the universal review tool for all of these frameworks.

Related Issues

Environment

  • plannotator binary: ~/.local/bin/plannotator (installed ~April 14, 2026)
  • Claude Code: PostToolUse Python hook
  • OpenCode: Bun event plugin
  • OS: macOS Darwin 25.4.0

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions