From 26404758c62bdcc5862c21fc4562f6ff27c16e2d Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Mon, 19 Oct 2026 15:45:08 -0700 Subject: [PATCH] Move workflow file and TODO.md formats into the knowledge base --- docs/operations.md | 2 +- internal/agents/guidance.go | 2 +- internal/agents/kb/todo-file.md | 20 +++++++++++++ internal/agents/kb/workflow-files.md | 42 ++++++++++++++++++++++++++++ internal/agents/workflows.go | 10 +------ 5 files changed, 65 insertions(+), 11 deletions(-) create mode 100644 internal/agents/kb/todo-file.md create mode 100644 internal/agents/kb/workflow-files.md diff --git a/docs/operations.md b/docs/operations.md index 9b0db6e..b2197bc 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -41,7 +41,7 @@ An implementer says its task is ready to merge with the `ready_for_merge` MCP to Agents find closed tasks with the `search_closed_tasks` MCP tool, which task agents get for their own project and the lead for one project (`project_id`) or all: a case-insensitive substring match of `query` on title, merge title, TODO item, summary and merge commit (`Store.SearchClosedTasks`), newest closed first, at most `limit` (default 20, at most 100), each with its id, outcome, merge commit, close time, creator, titles, TODO item, fork source and summary. The lead reads a closed task's transcript with `read_transcript`. There is no closed-task list in the UI; the human asks the lead. -**Knowledge base.** How byre features work that agents need only now and then lives in articles they fetch on demand instead of in their guidance: the Markdown files in `internal/agents/kb/`, embedded in the binary (`kb.go`). A file's name without `.md` is its topic, its first line a one-line summary and the rest the article. The `read_knowledge` MCP tool, which task agents and the lead get, lists every topic with its summary in its description and returns the article for `topic`. Adding an article is adding a file; the index follows. The articles are `signing` (turning on signed merge commits) and `usage-commands` (the usage command's JSON format, see "Usage" under "Status"). +**Knowledge base.** How byre features work that agents need only now and then lives in articles they fetch on demand instead of in their guidance: the Markdown files in `internal/agents/kb/`, embedded in the binary (`kb.go`). A file's name without `.md` is its topic, its first line a one-line summary and the rest the article. The `read_knowledge` MCP tool, which task agents and the lead get, lists every topic with its summary in its description and returns the article for `topic`. Adding an article is adding a file; the index follows. The articles are `signing` (turning on signed merge commits), `usage-commands` (the usage command's JSON format, see "Usage" under "Status"), `workflow-files` (a workflow's YAML, see "Workflows"; `read_workflow` and `save_workflow` point at it) and `todo-file` (the `TODO.md` format; the task guidance points at it). `POST /api/tasks/{id}/discard` (the **Discard** button, the lead's `discard_task`, and byre itself for a finished workflow's other stages) doesn't remove anything at once: it gives the task's agent one dedicated turn to write its summary, and closes the task when that turn ends. The discard is a persisted state of the task, `tasks.discard_state`, and every step that changes it is one transaction in the store (`internal/store/discard.go`), which is what keeps it safe against turns starting, ending and byre restarting around it: diff --git a/internal/agents/guidance.go b/internal/agents/guidance.go index bea59fc..3f843cf 100644 --- a/internal/agents/guidance.go +++ b/internal/agents/guidance.go @@ -21,7 +21,7 @@ const guidance = `You are running inside byre. The human reads your work in byre - In that final message and in ask_human context, put long supporting detail (logs, full lists, data) in collapsed sections the human expands on demand: a line
Title, the Markdown content, then a line
. - Don't commit. byre commits everything in the worktree at the end of each turn, using the turn's final message. - Don't push, don't switch or touch other branches, and don't run git maintenance (gc, prune, worktree prune). byre handles merging and pushing. -- TODO.md at the repo root is the project's list of work for byre. Each item is a top-level ` + "`- `" + ` line holding only a short title, which byre uses as the task's title and the item's identity, with its description in lines indented two spaces under it. ` + "`#`" + ` headings group items into sections, and a checked ` + "`- [x]`" + ` item is skipped.` +- TODO.md at the repo root is the project's list of work for byre; its format is the read_knowledge article todo-file.` const proseQuestionNudge = "Your final message asks the human something in prose. Ask it with byre's ask_human tool " + "(context with the choices inline as `- ( ) choice` / `- (*) recommended` or `- [ ] choice` / `- [x] recommended` list items, question, why_blocked), " + diff --git a/internal/agents/kb/todo-file.md b/internal/agents/kb/todo-file.md new file mode 100644 index 0000000..d668871 --- /dev/null +++ b/internal/agents/kb/todo-file.md @@ -0,0 +1,20 @@ +The format of TODO.md, the project's list of work for byre: items, descriptions, sections and checked items. + +# TODO.md + +TODO.md at the repo root is the project's list of work for byre. + +- Each item is a top-level `- ` line holding only a short title. byre uses the title as the task's title and as the item's identity. +- The item's description is in lines indented two spaces under it. +- `#` headings group items into sections. +- A checked `- [x]` item is skipped. + +```markdown +# Agent UI +- Fix login redirect + The redirect drops the query string after sign-in. + Keep the original path and query through the round trip. +- [x] Drop the web app +``` + +Removing an item removes its title line and every indented line under it. diff --git a/internal/agents/kb/workflow-files.md b/internal/agents/kb/workflow-files.md new file mode 100644 index 0000000..42447ad --- /dev/null +++ b/internal/agents/kb/workflow-files.md @@ -0,0 +1,42 @@ +The YAML format of a workflow's file, which read_workflow returns and save_workflow takes: stages, after, base, model and teams. + +# Workflow files + +A workflow's file is YAML: an optional `description`, then `stages`. The workflow's name is not in the file. Unknown fields are refused. + +| Field | Meaning | +|---|---| +| `name` | One line, unique in the workflow. | +| `after` | The names of the stages whose outputs it gets; it starts once all of them have finished. Absent means the previous stage in the list, and for the first stage none, so a file without `after` is a chain. `[]` means it starts from the brief. | +| `base` | `parent`, the default: branch from the commit its one `after` stage finished at, or for a stage with none, from where the workflow was started. `main`: branch from the default branch. Refused on a stage with more than one `after` stage, which always branches from the default branch and is told the branches it can merge. | +| `model` | Also picks the vendor: `gpt-*` models run on Codex, `gemini-*` models on Antigravity, every other model on Claude Code. | +| `prompt` | The stage agent's instructions. | +| `agents` | In place of `model`: a list of at least two, each with `name`, `model` and `prompt`, that runs the stage as a team. They work in the stage's one task and worktree and talk through a shared board; each gets the stage's `prompt` and then its own, and the first agent finishes the stage. | + +Every stage runs as its own task. Exactly one stage is final (no other stage comes after it), and cycles are refused. + +```yaml +description: Build a change, review and test it in parallel, then fix what they found. +stages: + - name: Build + model: claude-opus-5-5 + prompt: Implement the brief. + - name: Review + after: [Build] + model: gpt-6.1-sol + prompt: Review the Build stage's work and list the problems. + - name: Test + after: [Build] + model: gemini-4-argon-high + prompt: Exercise the change and report what fails. + - name: Fix + after: [Review, Test] + agents: + - name: fixer + model: claude-opus-5-5 + prompt: Fix every problem the reports list. + - name: checker + model: gpt-6.1-sol + prompt: Check each fix as the fixer lands it. + prompt: Merge the branches you are given and address both reports. +``` diff --git a/internal/agents/workflows.go b/internal/agents/workflows.go index e41fb74..82c5de3 100644 --- a/internal/agents/workflows.go +++ b/internal/agents/workflows.go @@ -648,15 +648,7 @@ func stageGuidance(frozen store.FrozenWorkflow, stage string) string { "%s. Until you call it, the workflow waits on this stage.", stage, frozen.Name, then) } -const workflowFileHelp = "A workflow's file is YAML: an optional description, then stages, each with name (one line, unique in the workflow), " + - "after (the names of the stages whose outputs it gets; it starts once all of them have finished; absent means the previous stage in the list, and for the first stage none; [] means it starts from the brief), " + - "base (parent, the default: branch from the commit its one after stage finished at, or for a stage with none, from where the workflow was started; main: branch from the default branch; " + - "refused on a stage with more than one after stage, which always branches from the default branch and is told the branches it can merge), " + - "model (which also picks the vendor: gpt-* models run on Codex, gemini-* models on Antigravity, every other model on Claude Code) and prompt (the stage agent's instructions). " + - "In place of model, agents (a list of at least two, each with name, model and prompt) runs the stage as a team: those agents work in the stage's one task and worktree and talk through a shared board; " + - "each gets the stage's prompt and then its own; the first agent finishes the stage. " + - "Every stage runs as its own task. Exactly one stage is final (no other stage comes after it), and cycles are refused. " + - "The workflow's name is not in the file." +const workflowFileHelp = "The file's YAML format is the read_knowledge article workflow-files." func (m *Manager) workflowTools(tool func(name, description, schema string, run func(ctx context.Context, user api.User, raw json.RawMessage) (string, error)) mcp.Tool) []mcp.Tool { return []mcp.Tool{