ubiquitous-invention/plans/Plan-agent-coordination/Epic-task-as-runnable-unit/Task-add-workflow-prompt-to-backlog-items.md

108 lines
6.5 KiB
Markdown
Raw Permalink Normal View History

plans: scaffold daily-driver-finish, saas-hardening, agent-coordination Three new plan trees that fill in the gaps surfaced during repo review. Together they map out what remains between the current scaffold-with-stubs state and a daily-usable, multitenant, agent-coordinated app. * Plan-daily-driver-finish (P0): turn stubs into real data. Five tasks covering the lint/shared-types breakage, hardcoded dashboard mocks, AI-page setTimeout placeholder, post-signin landing decision, and a cross-browser collab smoke test against the deployed Hocuspocus instance. * Plan-multitenant-saas-hardening (P1): everything multitenant needs beyond what Plan-multitenant-cursor-sync already covers. Invites and role management, soft-delete + append-only audit log, rate limits on the auth + mutation hot paths, and a Vitest + GitHub Actions test foundation so PRs can't ship red. * Plan-agent-coordination (P2): the layer that makes a Task-*.md runnable, not just readable. Adds workflow_prompt with task -> epic -> plan inheritance, an agent_runs table for auditable sessions, and two new MCP tools (claim_task / complete_task) that replace the freeform update_object composition agents do today. Includes an intentionally-deferred Epic-optional-orchestrator that captures the Symphony-shaped runner as a decision point rather than an immediate build. Each task is bead-scale (one focused Cursor session) with explicit in-scope, out-of-scope, and anti-goal sections so a future agent can pick up a single Task-*.md and start without scrollback context. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 00:52:22 -04:00
---
kind: task
slug: add-workflow-prompt-to-backlog-items
title: Add workflow_prompt column to markdown_backlog_items, with inheritance
plan_slug: agent-coordination
epic_slug: task-as-runnable-unit
status: in_progress
plans: scaffold daily-driver-finish, saas-hardening, agent-coordination Three new plan trees that fill in the gaps surfaced during repo review. Together they map out what remains between the current scaffold-with-stubs state and a daily-usable, multitenant, agent-coordinated app. * Plan-daily-driver-finish (P0): turn stubs into real data. Five tasks covering the lint/shared-types breakage, hardcoded dashboard mocks, AI-page setTimeout placeholder, post-signin landing decision, and a cross-browser collab smoke test against the deployed Hocuspocus instance. * Plan-multitenant-saas-hardening (P1): everything multitenant needs beyond what Plan-multitenant-cursor-sync already covers. Invites and role management, soft-delete + append-only audit log, rate limits on the auth + mutation hot paths, and a Vitest + GitHub Actions test foundation so PRs can't ship red. * Plan-agent-coordination (P2): the layer that makes a Task-*.md runnable, not just readable. Adds workflow_prompt with task -> epic -> plan inheritance, an agent_runs table for auditable sessions, and two new MCP tools (claim_task / complete_task) that replace the freeform update_object composition agents do today. Includes an intentionally-deferred Epic-optional-orchestrator that captures the Symphony-shaped runner as a decision point rather than an immediate build. Each task is bead-scale (one focused Cursor session) with explicit in-scope, out-of-scope, and anti-goal sections so a future agent can pick up a single Task-*.md and start without scrollback context. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 00:52:22 -04:00
priority: P2
tenant_id: global
owner: unassigned
cursor_todo_id: null
updated_at: "2026-06-02"
plans: scaffold daily-driver-finish, saas-hardening, agent-coordination Three new plan trees that fill in the gaps surfaced during repo review. Together they map out what remains between the current scaffold-with-stubs state and a daily-usable, multitenant, agent-coordinated app. * Plan-daily-driver-finish (P0): turn stubs into real data. Five tasks covering the lint/shared-types breakage, hardcoded dashboard mocks, AI-page setTimeout placeholder, post-signin landing decision, and a cross-browser collab smoke test against the deployed Hocuspocus instance. * Plan-multitenant-saas-hardening (P1): everything multitenant needs beyond what Plan-multitenant-cursor-sync already covers. Invites and role management, soft-delete + append-only audit log, rate limits on the auth + mutation hot paths, and a Vitest + GitHub Actions test foundation so PRs can't ship red. * Plan-agent-coordination (P2): the layer that makes a Task-*.md runnable, not just readable. Adds workflow_prompt with task -> epic -> plan inheritance, an agent_runs table for auditable sessions, and two new MCP tools (claim_task / complete_task) that replace the freeform update_object composition agents do today. Includes an intentionally-deferred Epic-optional-orchestrator that captures the Symphony-shaped runner as a decision point rather than an immediate build. Each task is bead-scale (one focused Cursor session) with explicit in-scope, out-of-scope, and anti-goal sections so a future agent can pick up a single Task-*.md and start without scrollback context. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 00:52:22 -04:00
---
# Task summary
Backlog items need a place to store a per-item agent prompt. Add a `workflow_prompt` text column to `markdown_backlog_items`, parse it from frontmatter, and define an inheritance chain (task → epic → plan → workspace default).
## Description
### Frontmatter contract
Add an optional `agent_prompt:` field to the YAML frontmatter of Plan/Epic/Task templates. It's a multiline string (use `|` block scalar in YAML). Example:
```yaml
agent_prompt: |
You are working on a focused implementation task in a multitenant TypeScript monorepo.
Read the task body in full before writing any code.
Validate every external input with zod.
Run pnpm lint && pnpm type-check before declaring done.
```
Update `docs/templates/{plan,epic,task}-template.md` to include the field (commented-out for tasks, since most tasks will inherit).
### Schema
Add to `markdown_backlog_items`:
- `workflow_prompt` text null
No new index needed; this column is rarely filtered on.
### Parser
In `packages/database/src/markdown-backlog/parse.ts`, extract `agent_prompt` from the parsed frontmatter into `workflow_prompt` on the upserted row. Use the existing zod schema for backlog frontmatter — extend it; don't fork.
### Inheritance helper
A new function `resolveWorkflowPrompt(db, { workspaceId, backlogItemId })` that walks task → epic → plan and returns the first non-null `workflow_prompt`. If none exist, return a built-in default string (lives as a constant in `packages/database/src/markdown-backlog/`). Workspace-level overrides can come later.
Don't store the resolved prompt anywhere — always compute on read. Caching is premature; this is a small lookup.
### Minimal UI
Add a "Workflow prompt" section to the task detail panel (`apps/web/components/panels/object-detail.tsx` or wherever the backlog-item detail lives). Show:
- "Effective prompt" — the result of `resolveWorkflowPrompt` (read-only).
- "Override" — a textarea bound to the item's own `workflow_prompt`. Empty = inherit.
Use a tRPC procedure `backlog.updateWorkflowPrompt({ backlogItemId, workflowPrompt })` that re-renders the panel on success.
### Anti-goals
- Don't write a template engine for the prompt. Symphony uses Liquid; we don't need that yet. A plain string is fine.
- Don't store prompts in `objects`. The agent flow is anchored on the markdown backlog, not the generic objects table.
## Subtasks
- [x] No zod schema in `parse.ts` to extend (the parser uses plain `readString` helpers, not a zod schema). Added a sibling `readMultilineString` helper that preserves interior newlines for `|` block scalars and added `workflowPrompt` to `ParsedBacklogFile`.
- [x] Added `workflow_prompt text` column to `markdown_backlog_items`. Migration `0008_curly_zzzax.sql`. Applied via psql against CT 102.
- [x] Parse `agent_prompt` from frontmatter, plumb through the importer (`sync.ts` insert + onConflictDoUpdate). Whitespace-only values normalize to `null` so an accidentally-blanked prompt doesn't silently shadow the epic/plan default.
- [x] `resolveWorkflowPrompt(db, { workspaceId, backlogItemId })` lives at `packages/database/src/markdown-backlog/resolve-prompt.ts`. Returns `{ prompt, source: "task" | "epic" | "plan" | "default" }`. Inheritance walk goes task → epic (slug-based lookup, NOT parent_id, because parent_id can be briefly null during importer transactions) → plan → built-in `DEFAULT_AGENT_PROMPT`. Workspace-scoped at every hop.
- [x] Updated Plan / Epic / Task templates in `docs/templates/` with commented-out `agent_prompt:` examples. Task template leaves it commented (most tasks inherit); Epic and Plan templates suggest filling it.
- [ ] **DEFERRED to follow-up** `Task-workflow-prompt-task-detail-ui.md`. There is no backlog-item detail panel in `apps/web` yet — the existing `components/panels/object-detail.tsx` is for the `objects` table, not for `markdown_backlog_items`. Adding an entirely new panel surface (with state, edit affordance, etc.) is a bigger UI task than this convoy bears. The data layer is fully in place — the follow-up just needs to render it.
The tRPC procedures are also ready (`backlog.getWorkflowPrompt` and `backlog.updateWorkflowPrompt`) so the future UI can render the override + effective preview with zero additional server work.
## Design decisions captured
- **No template engine.** Plain string, per spec. Symphony uses Liquid; we don't need that.
- **Slug-based walk, not parent_id-based.** The importer sets `parent_id` only for the immediate parent (task → epic). Walking by `(planSlug, epicSlug, slug)` works even mid-transaction when `parent_id` is null, and survives importer re-ordering.
- **`DEFAULT_AGENT_PROMPT` is intentionally generic.** The spec said "if you find yourself editing it frequently, that's a smell — fill in plan-level prompts instead." Documented in the constant's JSDoc.
- **Owner / admin only on `updateWorkflowPrompt`.** Agent prompts change downstream Cursor/Claude behavior; this isn't a "any member can edit" surface. Audit-logged on every write (`backlog.workflow_prompt_set` / `backlog.workflow_prompt_clear`).
- **Empty string normalizes to null.** A literally-empty override would shadow the epic/plan default with "no instructions at all" — bad UX. The procedure trims and treats empty as "clear the override."
plans: scaffold daily-driver-finish, saas-hardening, agent-coordination Three new plan trees that fill in the gaps surfaced during repo review. Together they map out what remains between the current scaffold-with-stubs state and a daily-usable, multitenant, agent-coordinated app. * Plan-daily-driver-finish (P0): turn stubs into real data. Five tasks covering the lint/shared-types breakage, hardcoded dashboard mocks, AI-page setTimeout placeholder, post-signin landing decision, and a cross-browser collab smoke test against the deployed Hocuspocus instance. * Plan-multitenant-saas-hardening (P1): everything multitenant needs beyond what Plan-multitenant-cursor-sync already covers. Invites and role management, soft-delete + append-only audit log, rate limits on the auth + mutation hot paths, and a Vitest + GitHub Actions test foundation so PRs can't ship red. * Plan-agent-coordination (P2): the layer that makes a Task-*.md runnable, not just readable. Adds workflow_prompt with task -> epic -> plan inheritance, an agent_runs table for auditable sessions, and two new MCP tools (claim_task / complete_task) that replace the freeform update_object composition agents do today. Includes an intentionally-deferred Epic-optional-orchestrator that captures the Symphony-shaped runner as a decision point rather than an immediate build. Each task is bead-scale (one focused Cursor session) with explicit in-scope, out-of-scope, and anti-goal sections so a future agent can pick up a single Task-*.md and start without scrollback context. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 00:52:22 -04:00
## Owner or assignee
Unassigned
## Status
ready
## Estimation
M
## Acceptance criteria
- [x] A task with no override falls back to its epic's prompt; an epic with no override falls back to its plan; a plan with no override falls back to the built-in default. (Tested by inspection of `resolve-prompt.ts`; an end-to-end DB-fixture test belongs to `Task-bootstrap-vitest-for-apps-web` once that lands.)
- [x] Setting `agent_prompt:` in frontmatter and re-importing populates `workflow_prompt`. (`parse.ts` + `sync.ts` plumb the field; verified by 3 new vitest cases in `parse.test.ts`.)
- [ ] UI shows effective prompt and override box. **Deferred** — see follow-up `Task-workflow-prompt-task-detail-ui.md`. Data layer (tRPC `backlog.getWorkflowPrompt` and `backlog.updateWorkflowPrompt`) is shipped so the UI is a pure rendering task.
plans: scaffold daily-driver-finish, saas-hardening, agent-coordination Three new plan trees that fill in the gaps surfaced during repo review. Together they map out what remains between the current scaffold-with-stubs state and a daily-usable, multitenant, agent-coordinated app. * Plan-daily-driver-finish (P0): turn stubs into real data. Five tasks covering the lint/shared-types breakage, hardcoded dashboard mocks, AI-page setTimeout placeholder, post-signin landing decision, and a cross-browser collab smoke test against the deployed Hocuspocus instance. * Plan-multitenant-saas-hardening (P1): everything multitenant needs beyond what Plan-multitenant-cursor-sync already covers. Invites and role management, soft-delete + append-only audit log, rate limits on the auth + mutation hot paths, and a Vitest + GitHub Actions test foundation so PRs can't ship red. * Plan-agent-coordination (P2): the layer that makes a Task-*.md runnable, not just readable. Adds workflow_prompt with task -> epic -> plan inheritance, an agent_runs table for auditable sessions, and two new MCP tools (claim_task / complete_task) that replace the freeform update_object composition agents do today. Includes an intentionally-deferred Epic-optional-orchestrator that captures the Symphony-shaped runner as a decision point rather than an immediate build. Each task is bead-scale (one focused Cursor session) with explicit in-scope, out-of-scope, and anti-goal sections so a future agent can pick up a single Task-*.md and start without scrollback context. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 00:52:22 -04:00
## Links to related Epic / Plan
- Epic: `./Epic-task-as-runnable-unit.md`
- Plan: `../Plan-agent-coordination.md`