Bold questions
This commit is contained in:
+24
-22
@@ -83,10 +83,10 @@ This plan reflects decisions already agreed. Do not deviate from it without aski
|
||||
|
||||
Vendor specifics live behind adapters. The event model is a **shared core plus vendor-specific extensions**:
|
||||
|
||||
- Core event kinds: message, tool call, tool result, file change, question, report, turn end, error.
|
||||
- Core event kinds: message, tool call, tool result, file change, question, turn end, error.
|
||||
- Vendor-specific event types for features that don't map cleanly, rendered by vendor-specific UI components.
|
||||
|
||||
**Full interface requirement.** The SPA must offer the full capability of each vendor's native interface, not a reduced view with a drop-out escape hatch. This includes slash commands, plan mode, model switching, compaction, todo lists, subagent views, image input, `@`-file mentions, and interrupts. Tracking vendor feature releases is an ongoing cost.
|
||||
**Interface coverage.** The SPA covers the vendor capabilities this workflow actually uses, each added as a specific feature when it is needed, rather than mirroring the native interface wholesale: interrupts, model switching, compaction, and image input. Compaction is byre's own and vendor-agnostic, not the vendor's: the agent writes a handoff (the same contents as an `export_context` bundle) and the work continues in a new session that starts from it. Subagent views and Mermaid rendering come later, once agents use them. Not planned: generic slash-command passthrough (a command worth having gets its own UI) and plan mode (planning is a workflow stage).
|
||||
|
||||
**Claude.** Implement the Claude Code CLI's stream-json control protocol natively in Go, reverse-engineered from the open-source Agent SDKs (TypeScript and Python). These SDKs spawn the `claude` CLI and exchange stream-json over stdio with a bidirectional control channel. Required capabilities: start session, stream events, send messages, interrupt, resume by session ID, fork session, register hooks (at minimum Stop and PostToolUse), attach MCP servers.
|
||||
|
||||
@@ -94,14 +94,14 @@ Vendor specifics live behind adapters. The event model is a **shared core plus v
|
||||
|
||||
**Protocol stability.** Neither protocol is a guaranteed public contract.
|
||||
|
||||
- Disable CLI auto-updates and pin CLI versions in config.
|
||||
- Maintain a contract test suite built from recorded transcripts; run it before bumping a CLI version.
|
||||
- Disable CLI auto-updates, so the version changes only when the owner updates the CLI. The version is not pinned.
|
||||
- Maintain a contract test suite built from recorded transcripts; run it after updating the CLI.
|
||||
- Fallback if Claude protocol drift becomes painful: a thin Node sidecar wrapping the official SDK, speaking our protocol to Go. Do not adopt the fallback without asking.
|
||||
|
||||
### Session configuration
|
||||
|
||||
- Permission posture: fully permissive ("yolo"). Agents act freely inside their worktree; humans review afterwards.
|
||||
- Agents may commit inside their task branch. Instruct them not to attribute themselves in commits. For Claude, also disable co-author attribution via Claude Code's settings for the session, since attribution is a default behavior.
|
||||
- Agents don't commit. byre commits everything in the worktree to the task branch at the end of every turn that changed files, authored as the session's creator, with the first sentence of the turn's summary as the message. Turns are the unit the human reviews, and the merge cycle squashes the branch anyway, so these commits only mark turn boundaries for diffing and restore. For Claude, also disable co-author attribution via Claude Code's settings for the session, since attribution is a default behavior.
|
||||
- Instruct agents not to push, not to touch other branches, and not to run git maintenance commands (see "Known hazards").
|
||||
- Every session is launched with our MCP server attached.
|
||||
|
||||
@@ -120,8 +120,6 @@ The Go server hosts an MCP server attached to every agent session.
|
||||
- `blocking: true` means the agent should end its turn; `false` means it continues with unblocked work.
|
||||
- The human's answer arrives as a structured next turn.
|
||||
- `thread_id` continues an existing inbox thread.
|
||||
- `report(done[], next_steps[], risks[], deviations[])`
|
||||
- `deviations[]` lists every departure from the task's plan.
|
||||
- `request_review(scope, concerns[], profile?)`
|
||||
- `export_context(purpose)` → a handoff bundle (see "Handoff bundles").
|
||||
- `spawn_stages(stages[])` and `collect(stage_ids[])` for just-in-time fan-out and fan-in (see "Workflows").
|
||||
@@ -130,13 +128,9 @@ The Go server hosts an MCP server attached to every agent session.
|
||||
|
||||
Validation: reject malformed calls with a corrective message (for example, an `ask_human` with no options or no `why_blocked`).
|
||||
|
||||
**Enforcement when an agent ends a turn without reporting:**
|
||||
**Turn summaries.** There is no report tool. Each turn's final message is its summary: session guidance asks agents to end every turn with one covering what they did, every departure from the plan, risks, and what's next, and byre files it to the inbox as a report. A dedicated report tool was tried and dropped: models wrote the closing recap anyway, even when the tool's result, the system prompt and a per-turn reminder all said not to, so the human read everything twice.
|
||||
|
||||
1. Claude: a Stop hook blocks stopping until `report` has been called this turn, injecting an instruction to call it.
|
||||
2. Codex (or any vendor without a stop gate): on turn completion with no report, the server automatically sends a follow-up turn asking for one.
|
||||
3. After the nudge limit (`maxNudges` in `internal/report/gate.go`), the review agent synthesizes a report from the transcript and diff. The UI marks it as synthesized, not self-reported.
|
||||
|
||||
The same mechanism bounces questions asked in plain prose (a final message that asks something without an `ask_human` call). Expect to tune strictness; overly strict validation produces nudge loops, overly lenient produces filler reports.
|
||||
Questions asked in plain prose (a final message that asks something without an `ask_human` call) are bounced by a Stop hook that sends the agent back to ask properly, once per turn. Detection is a sentence ending in `?` outside code, quotes and blockquotes; expect to tune it, since overly strict detection produces nudge loops and overly lenient lets prose questions through.
|
||||
|
||||
---
|
||||
|
||||
@@ -150,7 +144,7 @@ Project (id, name, repo_path, default_branch, remote, setup_config,
|
||||
Workflow (id, name, version, definition) -- server-side, exportable
|
||||
Task (id, project_id, title, branch, worktree_path, base_ref,
|
||||
status, workflow_id, workflow_snapshot, created_by,
|
||||
created_at, completed_at)
|
||||
created_at, closed_at, merge_commit)
|
||||
TaskIssueLink (task_id, tracker, issue_ref)
|
||||
Stage (id, task_id, parent_stage_id, def_id, role, vendor, model,
|
||||
state, origin) -- origin: workflow | jit
|
||||
@@ -267,7 +261,7 @@ Rules:
|
||||
|
||||
- Versioned. Humans edit through the inbox; agents propose edits, which go to the inbox for approval.
|
||||
- Stored on the server and attached to merges via git notes. Not committed to the repo.
|
||||
- Build agents report departures in `report.deviations[]`.
|
||||
- Build agents state every departure from the plan in their turn summaries.
|
||||
- Eval stages report pass or fail per acceptance criterion.
|
||||
- The plan-conformance review profile compares the diff against the plan.
|
||||
|
||||
@@ -343,15 +337,15 @@ A task can go through many merge cycles before completion. Merges happen only at
|
||||
- Author: the human who confirmed the merge.
|
||||
- Co-author trailers: other humans who participated in the task since the last merge cycle (resolved inbox items, messaged agents, triggered forks).
|
||||
- No agent attribution.
|
||||
- Message: drafted by an agent from the task's `report` calls since the last merge; the human edits before confirming.
|
||||
- Message: drafted by an agent from the task's turn summaries since the last merge; the human edits before confirming.
|
||||
4. Attach a git note to the squash commit (see "History").
|
||||
5. Push the default branch and the notes ref. If rejected because the remote moved, fetch and repeat from step 2.
|
||||
6. Reset the task branch to the new default-branch head. Required because squash commits make agent commits non-ancestors of the default branch; without the reset, later cycles accumulate spurious conflicts. Pre-squash history remains available via snapshot refs.
|
||||
6. Reset the task branch to the new default-branch head. Required because squash commits make agent commits non-ancestors of the default branch; without the reset, later cycles accumulate spurious conflicts. Pre-squash history (the per-turn commits) remains available via snapshot refs.
|
||||
7. Tell the agent explicitly that its branch history was squashed and reset, so it doesn't try to repair history. Then resume it. Files on disk are unchanged by the reset.
|
||||
|
||||
### Task completion
|
||||
|
||||
An explicit human action. Removes the worktree, the task branch, and the task's snapshot refs. Transcripts, artifacts, reviews, and inbox history remain archived in SQLite.
|
||||
An explicit human action, as one of two buttons: **Merge** squashes the task onto the default branch and then removes it; **Discard** removes it without merging, after a confirm that states the commits and changed files that will be lost. Either way the worktree, the task branch, and the task's snapshot refs are removed. Transcripts, artifacts, reviews, and inbox history remain archived in SQLite. Nothing deletes a task branch without one of these two buttons.
|
||||
|
||||
---
|
||||
|
||||
@@ -456,6 +450,7 @@ Issues identified in review that implementation must account for:
|
||||
- **Visual review reliability.** Capturing meaningful screenshots requires building, seeding data, and navigating to the affected screen. Expect flakiness; noisy reviews train users to ignore them.
|
||||
- **Squash-and-reset under a running agent.** Agents may notice their commits disappearing and try to repair history; step 7 of the merge cycle addresses this and needs testing per vendor.
|
||||
- **Event log growth.** Stream-json is verbose and tool outputs are large. SSE resume and scrubbing need efficient queries; consider separating large payloads into blobs.
|
||||
- **Migration numbering across branches.** Migrations are tracked by position (`PRAGMA user_version`). Each task branch appends its own, and byre is deployed from task branches, so two branches can claim the same number: the database records it as applied and the other branch's migration silently never runs. Fix: track applied migrations by name in a table. Before switching, make every existing data migration safe to run twice, since one recorded only by number would run again under its name.
|
||||
|
||||
---
|
||||
|
||||
@@ -479,12 +474,18 @@ Record transcripts from the spike as the seed of the contract test suite.
|
||||
|
||||
- **M0 — Skeleton.** launchd service, tailscale serve auth, SQLite schema, OpenAPI spec, projects, tasks, worktree create/delete, event log, SSE stream with resume, embedded SPA shell, basic server observability.
|
||||
- **Status: done**, and running as a service on the Mac Studio. Observability is exposed through `GET /api/admin/status` only; the SPA has no admin view yet.
|
||||
- **M1 — One agent end to end (Claude).** Sessions, streaming, messaging, full-interface rendering for Claude, MCP tools (`ask_human`, `report`), report enforcement, inbox with all views and response types, web push notifications, restart-and-resume, concurrency caps.
|
||||
- **Done:** sessions, streaming, messaging, interrupt; `ask_human` and `report` with validation; Stop-hook report enforcement; inbox with global, project, and task views and every response type, answered as one batch and delivered to the agent as one message; restart-and-resume; global and per-vendor caps with queueing; rate limits as their own inbox state; the web UI (two panes, task switcher, transcript, inbox) with Markdown rendering.
|
||||
- **Not done:** full-interface rendering beyond messages, tool calls, and interrupt (slash commands, plan mode, model switching, compaction, todo lists, subagent views, image input, `@`-file mentions, Mermaid rendering); web push notifications; bouncing questions asked in plain prose; the synthesized-report fallback (needs the M3 review agent); the session instructions from "Session configuration" (no pushing, no other branches, no git maintenance, no self-attribution; only the attribution setting is applied); pinning the CLI version (auto-update is disabled, the version isn't pinned).
|
||||
- **M1 — One agent end to end (Claude).** Sessions, streaming, messaging, the interface coverage for Claude, the `ask_human` MCP tool, turn summaries, inbox with all views and response types, web push notifications, restart-and-resume, concurrency caps.
|
||||
- **Done:** sessions, streaming, messaging, interrupt; `ask_human` with validation; each turn's final message filed to the inbox as its summary; inbox with global, project, and task views and every response type, answered as one batch and delivered to the agent as one message; restart-and-resume; global and per-vendor caps with queueing; rate limits as their own inbox state; the web UI (two panes, task switcher, transcript, inbox) with Markdown rendering; the session instructions from "Session configuration", given as an appended system prompt and a per-turn reminder; per-turn commits by byre; bouncing questions asked in plain prose.
|
||||
- **Not done:** image input (see "Interface coverage"); web push notifications. Compaction is done, as a handoff into a fresh session; model switching is done, per message.
|
||||
- **Later:** subagent views and Mermaid rendering.
|
||||
- **M2 — Seeing the work.** Temp-index diffs and stats, snapshots, timeline scrubbing, terminals, file browser, previews.
|
||||
- **M3 — Second vendor and review.** Codex adapter with full-interface rendering, review profiles, review triggers, visual review output, cross-vendor review.
|
||||
- **Done:** temp-index diffs and stats, with a Changes view.
|
||||
- **Not done:** snapshots, timeline scrubbing, terminals, file browser, previews.
|
||||
- **M3 — Second vendor and review.** Codex adapter with the same interface coverage, review profiles, review triggers, visual review output, cross-vendor review.
|
||||
- **M4 — Merging and history.** Full merge cycle with squash, authorship and co-author trailers, drafted commit messages, merge-resolution stage, git notes, task completion and archive, archive search, GitHub Issues integration.
|
||||
- **Done:** Merge and Discard replace "Complete task". Merge squashes the worktree, uncommitted files included, into one commit on the default branch, authored by the merging user, and fast-forwards the project checkout; it doesn't push, and it refuses on conflicts or while a turn is running.
|
||||
- **Next:** the squash commit message, which is the task title for now. Decided: a one-shot `claude -p` run in the task's worktree writes a one-line summary from the branch's log and diff stat, so Merge becomes a background job that reports back with a `task.merged` event or an error.
|
||||
- **Not done:** co-author trailers, merge-resolution stage, git notes, push, repeated merge cycles, archive search, GitHub Issues.
|
||||
- **M5 — Workflows.** Workflow definitions and storage, stages, gates, bounded loops, plan artifact, eval stages, task intake, mid-task swapping.
|
||||
- **M6 — Fan-out.** `export_context` and handoff bundles, same-vendor forks, cross-vendor handoffs, fork-and-compare, just-in-time fan-out with limits.
|
||||
- **M7 — Inbox triage.**
|
||||
@@ -501,3 +502,4 @@ Record transcripts from the spike as the seed of the contract test suite.
|
||||
- Periodic review thresholds (defaults for time and diff size).
|
||||
- Default limits for just-in-time fan-out (depth, concurrency, budget).
|
||||
- Task navigation: keep both the ⌘K switcher and the Tasks view, or only one.
|
||||
- Interface coverage still undecided: todo-list rendering and `@`-file mentions.
|
||||
|
||||
Reference in New Issue
Block a user