Files
shiro-neko/.hermes/plans/v8-workflow.md
T
asepharyana a3739eb628
ci / check (macos-latest) (push) Canceled after 0s
ci / check (ubuntu-latest) (push) Canceled after 0s
ci / check (windows-latest) (push) Canceled after 0s
workflow: project-driven agent workflow (docs-first, TODO/ROADMAP tracking, verify-before-done)
- system prompt gains a Project workflow block when the repo tracks its own
  progress (TODO.md/ROADMAP.md/docs): read the task list first and keep it
  current, spec-first for non-trivial work, complete unit tests, verify before
  declaring done
- TODO.md + ROADMAP.md loaded as 'Project tracker' instruction blocks, capped
  tighter than AGENTS.md so the agent sees the shape without drowning in it
- one soft nudge per session when a turn writes files without touching the
  task list; suppressed when todo_write was called; never a gate
- /workflow command + panel showing TODO/ROADMAP/docs presence, line/file
  counts, nudge state
- config: workflow.enabled (default true), workflow.docsDir (default docs)
- prompt-cache version key extended with wf: so toggling the workflow busts
  the cached system prompt
- docs: docs/workflow.md, configuration table row, ROADMAP + TODO entries
- tests: test/workflow.test.ts (9 tests)

830 tests pass, typecheck clean, build green, live headless demo verified
2026-09-09 19:00:22 +07:00

4.6 KiB

Project-Driven Agent Workflow

Status: spec Date: 2026-09-09

Why

The user wants shiro-neko agents to produce the same quality as this repo itself: docs-driven development, TODO.md + ROADMAP.md lifecycle, spec-first plans, complete unit tests, verify-before-done. Today the agent only reads AGENTS.md/CLAUDE.md/.shiro.md; it has no visibility of the project's task tracking, roadmap, or docs conventions, and nothing reminds it to keep them current.

Scope

  • Prompt-level workflow policy (rendered in system prompt when enabled)
  • Boot loading of TODO.md + ROADMAP.md (compact, capped)
  • Lifecycle nudge: after a turn that wrote files without touching the task list, emit a soft reminder
  • /workflow command: show project workflow state
  • Config: workflow.enabled (default true), workflow.docsDir (default docs/)
  • Docs: docs/workflow.md + ROADMAP/TODO entries
  • Tests: prompt rendering, boot load, lifecycle nudge, config merge, /workflow

Out of scope (explicitly not doing)

  • New tools (no permission surface, no storage)
  • Blocking / hard gates (agent stays in control; nudges only)
  • Auto-updating TODO.md (the agent does it via existing write tools)
  • Skill/plugin autoloading (existing system stays)

Files touched

  • src/config.ts — workflow?: { enabled?: boolean; docsDir?: string } + merge arm
  • src/prompt.ts — WorkflowPolicy block in renderPrompt; depends on config
  • src/instructions.ts — load TODO.md + ROADMAP.md from git root; format compact
  • src/session.ts — SessionOptions.workflow config; after-turn nudge when fileChangeSeq bumped && no todo_write this turn
  • src/commands.ts — /workflow command (status summary)
  • src/cli.tsx — pass config; register /workflow
  • src/ui/App.tsx + panel-bodies.ts — /workflow panel
  • docs/workflow.md — new; ROADMAP.md, TODO.md updated
  • test/workflow.test.ts — new

Design

Config (config.ts)

export type WorkflowConfig = {
  enabled?: boolean;   // default true
  docsDir?: string;    // default 'docs'
};

Merged in config.merge (same pattern as maxSpendPerTurn).

Prompt block (prompt.ts)

Rendered only when workflow.enabled !== false, and only when the project has TODO.md/ROADMAP.md/docs/ (so a bare repo gets no noise). Wording:

Project workflow (this repo tracks its own progress). When the project has a
TODO.md, read it before starting work and keep it current as you go:
- mark done what you finished, and the sub-task you are on
- add tests alongside code; the project expects complete unit tests
- update ROADMAP.md when you ship a milestone
- for anything non-trivial, write a short plan (spec-first) before code
- verify with the project's check commands before declaring done

Keyed in promptCache versions as wf so toggling the flag re-renders.

Boot load (instructions.ts)

loadInstructions also collects <gitroot>/TODO.md and <gitroot>/ROADMAP.md when present, capped (e.g. 6_000 chars each), rendered as:

--- TODO.md (project task list) ---
<first N lines, preserving section headers>

Rendered AFTER instructions, BEFORE notebook/memory. So the agent always knows what the project is tracking before it starts.

Lifecycle nudge (session.ts)

After a turn's stream finishes (where fileChangeSeq is known): if workflow.enabled !== false AND the turn wrote files (fileChangeSeq bumped) AND the turn did NOT call todo_write AND the project has a TODO.md at the git root AND this is not the 1st turn (avoid nudge at boot): emit one info line via the normal notice mechanism:

reminder: you modified files without updating the project task list (TODO.md).
Keep it current: mark what you did.

This is one soft line, not a stop; the run continues normally. Tracked as workflowNudged so it fires at most once per run (and once per session).

/workflow command

Status summary rendered in a panel:

  • workflow.enabled from config
  • TODO.md present? yes/no + line count
  • ROADMAP.md present? yes/no + line count
  • docsDir exists? yes/no
  • docs/ file count
  • tests: count of *.test.ts / *.test.tsx in tree (bounded)
  • nudged count this session

Tests (test/workflow.test.ts)

  1. config merge: workflow.enabled + docsDir survive loadConfig merge
  2. prompt: workflow policy rendered when enabled + TODO present; absent when disabled or bare repo
  3. instructions: TODO.md + ROADMAP.md loaded from git root, capped
  4. lifecycle nudge: turn writes file, no todo_write -> info message once
  5. no nudge when todo_write was called
  6. /workflow command parses + panel renders

Verification

  • bun run typecheck
  • bun test test/workflow.test.ts test/config.test.ts test/commands.test.ts
  • full bun test (background)
  • bun run build