Submatter/.convoys/worker-closeout-docwriter/brief-2-operator-notes.md
Randall Stillwell 86155455a7 feat(worker): close Epic 7 — draft PR + operator notes + doc-writer
- Draft PR via forge (apps/worker/src/git/pr.ts) push branch + createPullRequest draft with echodo-convoy marker, expose prUrl in Mission Control (convoy-service, convoys router, detail panel)
- Operator notes mid-build: convoy_operator_messages (0016), tRPC post/list, worker poll between tool rounds (queued) and before generateText (direct), detail panel thread for in_progress
- Doc-writer: harness doc-writer examples (docs/examples/research-pipeline.md), SOP template (docs/templates/doc-sop.md), role-doc-writer wiring

Convoy: .convoys/worker-closeout-docwriter

Co-authored-by: orchestrator
2026-08-25 16:56:02 -05:00

41 lines
2.5 KiB
Markdown

---
brief: 2
convoy: worker-closeout-docwriter
role: role-implementer
title: Operator notes mid-build — queued + direct messages
status: ready
priority: P1
slice_dependencies: []
recommended_model: qwen-coder
model_tier: local
---
# Brief 2 — Operator notes `Task-worker-operator-notes.md`
## Goal
Let operators send `queued` notes and `direct` messages to an active worker session without waiting for gate — Autensa benchmark row `operator-notes` `plans/Plan-automation-foundation/Plan-automation-foundation.md:229`.
## Files
- `packages/database/src/schema/convoy_operator_messages.ts` NEW — `id uuid PK, workspace_id fk, convoy_id fk objects.id, brief_id fk optional, agent_run_id fk optional, delivery enum queued|direct, body text, author_user_id fk users, delivered_at timestamptz nullable, created_at defaultNow`. Index `workspace_id, convoy_id, delivered_at`.
- `packages/database/migrations/0016_*` — `pnpm db:generate`.
- `apps/web/server/routers/convoys.ts` — add `postOperatorNote` (workspace member; `delivery:queued|direct`, `body 1..2000`, `convoyId, briefId?`) inserts row; `listOperatorNotes` for detail panel thread.
- `apps/worker/src/db/operator-notes.ts` NEW — `pollOperatorNotes(db, workspaceId, convoyId, briefId?)` where `delivered_at IS NULL` ordered `created_at`.
- `apps/worker/src/handle-job.ts:40` — between tool rounds poll queued notes, append `Queued note from ${author}: ${body}` to `toolHistory` summary; before next `generateText` prepend direct messages to system prompt tail. Mark `delivered_at=now()` after injection. Log `harnessAlias`.
- `apps/web/app/(app)/[workspaceSlug]/mission-control/convoy-detail-panel.tsx` — thread tab when `status===in_progress` (textarea + Send → `postOperatorNote`, list `listOperatorNotes`), distinct from gate co-pilot.
## Acceptance
- Operator posts `Queued note: use existing auth middleware` → worker sees it on next tool round (logged in checkpoint summary).
- `Direct message` arrives before next model call when run active (show in worker log `direct message injected`).
- Workspace-scoped, auditable (author + delivered_at visible in detail panel).
- `pnpm lint && pnpm type-check` pass.
## Prompt
You are `role-implementer` brief 2. Read `plans/Plan-automation-foundation/Epic-apps-worker-v1/Task-worker-operator-notes.md`, `packages/database/src/schema/convoy_events.ts`, `apps/web/server/routers/convoys.ts:173`, `docs/worker.md`. Keep polling fallback simple (no Redis pubsub).
## Depends
None — disjoint from brief 1.