Consolidate agent harness course into 19 lessons

This commit is contained in:
Haoran
2026-08-04 02:25:40 +08:00
parent 2ad77cee19
commit b36dbcd84f
168 changed files with 6544 additions and 10400 deletions

View File

@@ -18,15 +18,15 @@
{
"id": "runtime-owned-delivery",
"title": "Message Delivery Belongs to the Runtime",
"description": "MessageBus stores each handoff in JSONL, while the runtime watches the Lead mailbox and injects new team events into the next turn. The model does not need an inbox polling tool.",
"description": "The MessageBus persists each handoff, while the runtime watches the Lead mailbox and injects new team events into the next turn. The model does not spend turns polling an inbox.",
"alternatives": "A model-visible check_inbox tool is easy to add, but wastes turns and can leave completed work unnoticed.",
"zh": {
"title": "消息投递由运行时负责",
"description": "MessageBus 每次交接写入 JSONL,运行时监听 Lead 邮箱,并把新的团队事件送入下一轮上下文。模型不需要调用邮箱轮询工具。"
"description": "MessageBus 持久化每次交接,运行时监听 Lead 邮箱,并把新的团队事件送入下一轮上下文。模型不需要浪费轮次轮询收件箱。"
},
"ja": {
"title": "メッセージ配信はランタイムが担う",
"description": "MessageBus 各ハンドオフを JSONL に保存し、ランタイムが Lead のメールボックスを監視して新しい team event を次の turn に注入する。モデル受信箱確認ツールは要らない。"
"description": "MessageBus 各ハンドオフを永続化し、ランタイムが Lead の受信箱を監視して新しい team event を次の turn に注入する。モデル受信箱のポーリングに turn を費やさない。"
}
},
{
@@ -46,15 +46,57 @@
{
"id": "plan-approval-is-a-gate",
"title": "Plan Approval Is an Execution Gate",
"description": "When the Lead requests a plan, mutating tools remain blocked until the matching plan is approved. Rejection requires a new submission, and an idle teammate remains available for later assignments until a typed shutdown completes.",
"alternatives": "Treating approval as a conversational suggestion cannot prevent an early write or shell command.",
"description": "When the Lead requests a plan, mutating tools remain blocked until the matching plan is approved. Rejection requires a new submission rather than a conversational workaround.",
"alternatives": "Treating approval as a suggestion cannot prevent an early write or shell command.",
"zh": {
"title": "计划审批是执行闸门",
"description": "Lead 请求计划后,修改类工具会保持阻塞,直到对应计划通过。被拒绝的计划必须重新提交;空闲队友会继续保留,直到类型化关机协议完成。"
"description": "Lead 请求计划后,修改类工具会保持阻塞,直到对应计划通过。被拒绝的计划必须重新提交,不能靠对话绕过。"
},
"ja": {
"title": "プラン承認を実行ゲートにする",
"description": "Lead がプランを要求すると、対応するプランが承認されるまで変更系ツールをブロックする。却下後は再提出が必要で、待機中のチームメイトは型付き終了プロトコルが完了するまで残る。"
"description": "Lead がプランを要求すると、対応するプランが承認されるまで変更系ツールをブロックする。却下後は会話で迂回せず再提出が必要になる。"
}
},
{
"id": "idle-claim-is-atomic",
"title": "Idle Discovery and Claiming Form One Safe Path",
"description": "An idle teammate scans only pending, unowned tasks whose dependencies are complete. The ownership check and pending-to-in_progress update happen under one lock, so two teammates cannot claim the same work.",
"alternatives": "Central dispatch keeps assignment simple, while an unlocked scan can assign the same task twice.",
"zh": {
"title": "空闲发现与原子认领组成一条安全路径",
"description": "空闲队友只扫描 pending、未分配且依赖已完成的任务。所有权检查与 pending 到 in_progress 的更新在同一把锁内完成,因此两个队友不会认领同一任务。"
},
"ja": {
"title": "待機中の探索と原子的な認領を一つの安全な経路にする",
"description": "待機中のチームメイトは pending、未所有、依存解決済みのタスクだけを探す。所有権確認と pending から in_progress への更新を同じ lock 内で行い、二重認領を防ぐ。"
}
},
{
"id": "task-bound-worktree",
"title": "The Working Directory Is a Task Property",
"description": "A task records its worktree binding, and a teammate's bash, read, and write tools derive their working directory from the claimed task. This is explicit cwd routing for parallel edits, not a security sandbox or a second orchestration system.",
"alternatives": "Letting agents switch directories implicitly is shorter, but makes the cwd boundary invisible and easy to lose.",
"zh": {
"title": "工作目录是任务的显式属性",
"description": "任务记录自己的 worktree 绑定,队友的 bash、read、write 工具从已认领任务推导工作目录。这是为并行编辑提供的显式 cwd 路由,不是安全沙箱,也不是第二套编排系统。"
},
"ja": {
"title": "作業ディレクトリをタスクの明示的な属性にする",
"description": "タスクが worktree の紐付けを保持し、チームメイトの bash、read、write は認領したタスクから作業ディレクトリを決める。これは並行編集のための明示的な cwd routing であり、security sandbox や第二の編成システムではない。"
}
},
{
"id": "worktree-cleanup-fails-closed",
"title": "Worktree Cleanup Fails Closed",
"description": "Creation binds a task only after git succeeds. Removal accepts only a known path under the worktree root and refuses unverifiable or dirty state unless discard is explicit; it never completes the task as a side effect.",
"alternatives": "Unconditional force removal is convenient, but can destroy unreviewed work and blur task completion with directory cleanup.",
"zh": {
"title": "Worktree 清理默认拒绝不安全操作",
"description": "只有 git 创建成功后才绑定任务。删除仅接受 worktree 根目录下的已知路径;状态无法验证或存在未保存改动时,除非明确选择丢弃,否则拒绝删除,并且不会顺带完成任务。"
},
"ja": {
"title": "Worktree の片付けは安全側に失敗する",
"description": "git の作成成功後にだけタスクを紐付ける。削除は worktree ルート配下の既知パスだけを受け付け、状態を確認できない場合や変更が残る場合は明示的な破棄なしに拒否し、タスクを副作用で完了させない。"
}
}
]

View File

@@ -2,45 +2,45 @@
"version": "s16",
"decisions": [
{
"id": "idle-state-discovers-work",
"title": "Idle Teammates Look for Ready Work",
"description": "s15 already keeps teammates alive in IDLE. s16 gives that state one more input: after waiting for messages, a teammate scans the shared task board for pending, unowned, unblocked work.",
"alternatives": "The Lead could dispatch every assignment, but then an idle teammate cannot help with work that becomes ready later.",
"id": "normalized-mcp-namespace",
"title": "MCP Tools Use a Normalized Namespace",
"description": "Discovered tools are exposed as mcp__server__tool. The prefix makes the source explicit and avoids collisions with built-in tools or tools from another server.",
"alternatives": "Using the raw tool name is shorter, but search from two servers could overwrite each other.",
"zh": {
"title": "空闲队友主动寻找就绪任务",
"description": "s15 已经让队友在 IDLE 中保持存活。s16 为这个状态增加任务板入口:等待消息后,队友会扫描 pending、未分配且依赖已完成的任务。"
"title": "MCP 工具使用规范化命名空间",
"description": "发现到的工具会暴露为 mcp__server__tool。前缀让工具来源明确也避免和内置工具或其他服务器工具冲突。"
},
"ja": {
"title": "待機中のチームメイトが実行可能な仕事を探す",
"description": "s15 ですでにチームメイトは IDLE のまま残る。s16 はその状態にタスクボード入口を追加し、メッセージ待機後に pending、未所有、依存解決済みのタスクを探す。"
"title": "MCP ツールは正規化された名前空間を使う",
"description": "発見されたツールは mcp__server__tool として公開されます。接頭辞により出所が明確になり、組み込みツールや別サーバーのツールとの衝突を避けます。"
}
},
{
"id": "atomic-claim",
"title": "Claiming Is Atomic",
"description": "The ownership check and task update run under one lock. When two teammates see the same ready task, only one can move it from pending to in_progress.",
"alternatives": "Scanning and writing without a shared lock can assign the same task twice.",
"id": "dynamic-tool-pool",
"title": "Tool Discovery Updates the Active Tool Pool",
"description": "After connecting to a server, the runtime assembles a new tool pool for the next LLM call. The model can only use MCP tools after discovery has made them visible.",
"alternatives": "Preloading every possible MCP tool would create a huge prompt and expose capabilities the user did not request.",
"zh": {
"title": "任务认领必须原子化",
"description": "所有权检查与任务更新在同一把锁内完成。两个队友同时看到一个就绪任务时,只有一个能把它从 pending 推进到 in_progress。"
"title": "工具发现会更新活动工具池",
"description": "连接服务器后,运行时会为下一次 LLM 调用组装新的工具池。模型只有在发现阶段让 MCP 工具可见之后,才能调用它们。"
},
"ja": {
"title": "タスク認領を原子的に行う",
"description": "所有権確認とタスク更新を同じ lock の中で行う。二つのチームメイトが同じ実行可能タスクを見ても、pending から in_progress へ進められるのは一方だけである。"
"title": "ツール発見がアクティブなツールプールを更新する",
"description": "サーバー接続後、ランタイムは次の LLM 呼び出し用に新しいツールプールを組み立てます。MCP ツールは発見で可視化された後にのみモデルが利用できます。"
}
},
{
"id": "dependencies-filter-readiness",
"title": "Dependencies Define Readiness",
"description": "The scan returns a task only when every blockedBy dependency is completed. A teammate with nothing ready remains idle instead of starting work out of order.",
"alternatives": "Ignoring dependencies increases utilization, but produces work against unfinished inputs.",
"id": "external-results-append-like-tools",
"title": "External Results Reuse the Tool Result Path",
"description": "MCP responses are appended to the conversation like ordinary tool results. This keeps the agent loop unchanged while still letting external systems participate.",
"alternatives": "A separate external-response channel would make MCP feel special and require extra loop logic.",
"zh": {
"title": "依赖关系决定任务是否就绪",
"description": "只有 blockedBy 中的依赖全部完成,扫描才会返回该任务。没有就绪任务的队友继续保持 IDLE不会越过依赖提前开工。"
"title": "外部结果复用 Tool Result 路径",
"description": "MCP 响应会像普通 tool result 一样追加到对话中。这样 agent 循环无需改变,同时外部系统仍然可以参与。"
},
"ja": {
"title": "依存関係が実行可能性を決める",
"description": "blockedBy の依存がすべて完了したタスクだけを走査結果に含める。実行可能な仕事がなければ IDLE を維持し、順序を飛ばして開始しない。"
"title": "外部結果は tool result 経路を再利用する",
"description": "MCP の応答は通常の tool result と同じように会話へ追加されます。エージェントループを変えずに外部システムを参加させられます。"
}
}
]

View File

@@ -2,45 +2,45 @@
"version": "s17",
"decisions": [
{
"id": "worktree-name-validation",
"title": "Worktree Names Are Validated Before Git Runs",
"description": "The tool validates names before creating branches or directories, so unsafe user input never reaches git or filesystem operations.",
"alternatives": "Passing names directly to git is shorter, but it turns a collaboration feature into an injection hazard.",
"id": "composition-over-new-loop",
"title": "The Harness Composes Previous Layers",
"description": "The integrated harness does not replace the loop with a new architecture. It composes memory, tasks, skills, background work, teams, worktrees, and MCP around the same core model-tool-result cycle.",
"alternatives": "A new orchestration framework would look more impressive, but it would hide the continuity across the course.",
"zh": {
"title": "运行 Git 前先校验 Worktree 名称",
"description": "工具在创建分支或目录前先校验名称,不让不安全的用户输入进入 git 或文件系统操作。"
"title": "Harness 组合既有层,而不是换掉循环",
"description": "集成后的 Harness 没有用新架构替换循环,而是把 memory、task、skill、后台任务、团队、worktree、MCP 组合到同一个模型-工具-结果循环周围。"
},
"ja": {
"title": "git 実行前に worktree 名を検証する",
"description": "ブランチやディレクトリ作成前に名前を検証し、危険なユーザー入力が git やファイルシステム操作へ流れないようにします。"
"title": "Harness は既存レイヤーを統合する",
"description": "統合された Harness はループを新しい構造で置き換えません。memory、task、skill、バックグラウンド処理、チーム、worktree、MCP を同じ model-tool-result サイクルの周囲に合成します。"
}
},
{
"id": "task-bound-worktree",
"title": "The Task Record Owns the Worktree Binding",
"description": "A task stores its assigned worktree so future commands know where to run. The binding is explicit data, not a hidden convention based on naming or current working directory.",
"alternatives": "Deriving the worktree path from branch names is convenient, but brittle when tasks are renamed or moved.",
"id": "single-source-of-runtime-truth",
"title": "Runtime State Has Named Sources",
"description": "Context assembly pulls from named sources such as memory, task graph, skills, tool registry, and policy. This keeps a large agent debuggable because each piece of prompt context has an owner.",
"alternatives": "Dumping everything into one prompt string is shorter, but it becomes impossible to tell which subsystem caused a bad decision.",
"zh": {
"title": "任务记录持有 Worktree 绑定关系",
"description": "任务会记录自己分配到的 worktree因此后续命令知道应该在哪里运行。这个绑定是显式数据而不是依赖命名或当前目录的隐藏约定。"
"title": "运行时状态来自具名来源",
"description": "上下文组装从 memory、task graph、skills、tool registry、policy 等具名来源读取。大型 agent 因此仍可调试,因为每块 prompt context 都有清晰归属。"
},
"ja": {
"title": "タスクレコードが worktree の紐付けを持つ",
"description": "タスクは割り当てられた worktree を保持し、後続コマンドは実行場所を把握できます。この紐付けは命名や現在ディレクトリに依存する暗黙の規約ではなく、明示的なデータです。"
"title": "ランタイム状態には名前付きの出所がある",
"description": "コンテキスト組み立ては memory、task graph、skills、tool registry、policy などの名前付きソースから取得します。各 prompt context に所有者があるため、大きなエージェントでもデバッグ可能です。"
}
},
{
"id": "lifecycle-event-stream",
"title": "Lifecycle Events Stay Separate from Tool Results",
"description": "Creation, status, keep, and removal events are emitted to a side-channel log. That makes worktree state observable without overloading the conversational transcript.",
"alternatives": "Only returning tool results is simpler, but later debugging needs a durable audit trail of worktree lifecycle changes.",
"id": "recovery-is-first-class",
"title": "Recovery Is Part of the Main Flow",
"description": "Compaction, error recovery, and asynchronous result collection are normal loop behavior. The harness handles recovery and resumption through named paths instead of scattered exception branches.",
"alternatives": "Leaving recovery at the edges makes it harder to see which state is safe to resume.",
"zh": {
"title": "生命周期事件与工具结果分离",
"description": "创建、状态、保留和移除事件会写入旁路日志。这样 worktree 状态可观察,同时不会把对话 transcript 塞满运行时事件。"
"title": "恢复能力是一等流程",
"description": "压缩、错误恢复和异步结果收集都属于正常循环。Harness 通过明确的路径处理恢复与续跑,而不是把逻辑散落在异常分支中。"
},
"ja": {
"title": "ライフサイクルイベントをツール結果から分離する",
"description": "作成、状態、保持、削除のイベントはサイドチャネルログへ出力します。会話 transcript をランタイムイベントで埋めずに worktree 状態を観測できます。"
"title": "リカバリは主要フローの一部",
"description": "圧縮、エラー回復、非同期結果収集を通常のループ動作として扱います。Harness は回復と再開を名前付きの経路にまとめ、例外分岐へ散らしません。"
}
}
]

View File

@@ -2,45 +2,45 @@
"version": "s18",
"decisions": [
{
"id": "normalized-mcp-namespace",
"title": "MCP Tools Use a Normalized Namespace",
"description": "Discovered tools are exposed as mcp__server__tool. The prefix makes the source explicit and avoids collisions with built-in tools or tools from another server.",
"alternatives": "Using the raw tool name is shorter, but search from two servers could overwrite each other.",
"id": "script-owns-fixed-orchestration",
"title": "Code Owns Fixed Orchestration",
"description": "When the stages and aggregation rules are known in advance, a workflow script makes the process parallel, reproducible, and inspectable without changing the main agent loop.",
"alternatives": "Letting the model choose every next step is more flexible, but slower and harder to resume for a fixed procedure.",
"zh": {
"title": "MCP 工具使用规范化命名空间",
"description": "发现到的工具会暴露为 mcp__server__tool。前缀让工具来源明确也避免和内置工具或其他服务器工具冲突。"
"title": "固定编排由代码负责",
"description": "当阶段与汇总规则事先确定时workflow 脚本能让流程并行、可复现、可检查,同时不修改主 Agent 循环。"
},
"ja": {
"title": "MCP ツールは正規化された名前空間を使う",
"description": "発見されたツールは mcp__server__tool として公開されます。接頭辞により出所が明確になり、組み込みツールや別サーバーのツールとの衝突を避けます。"
"title": "固定された編成はコードが担う",
"description": "段階と集約ルールが事前に決まっているなら、workflow script は main Agent loop を変えずに処理を並列化し、再現可能で検査可能にする。"
}
},
{
"id": "dynamic-tool-pool",
"title": "Tool Discovery Updates the Active Tool Pool",
"description": "After connecting to a server, the runtime assembles a new tool pool for the next LLM call. The model can only use MCP tools after discovery has made them visible.",
"alternatives": "Preloading every possible MCP tool would create a huge prompt and expose capabilities the user did not request.",
"id": "semantic-journal-keys",
"title": "Semantic Keys Make Resume Independent of Completion Order",
"description": "Journal entries use stable call content rather than a shared completion counter. Concurrent calls can finish in any order and still map to the correct cached result.",
"alternatives": "Indexing by completion order is simpler, but replays the wrong result as soon as concurrent timing changes.",
"zh": {
"title": "工具发现会更新活动工具池",
"description": "连接服务器后,运行时会为下一次 LLM 调用组装新的工具池。模型只有在发现阶段让 MCP 工具可见之后,才能调用它们。"
"title": "语义键让恢复不依赖完成顺序",
"description": "Journal 用稳定的调用内容作为 key而不是共享完成计数器。并发调用无论以什么顺序结束都能命中正确缓存。"
},
"ja": {
"title": "ツール発見がアクティブなツールプールを更新する",
"description": "サーバー接続後、ランタイムは次の LLM 呼び出し用に新しいツールプールを組み立てます。MCP ツールは発見で可視化された後にのみモデルが利用できます。"
"title": "意味キーで完了順序に依存せず再開する",
"description": "Journal は共有完了カウンタではなく安定した call 内容を key にする。並行 call の終了順が変わっても正しい cache result に対応できる。"
}
},
{
"id": "external-results-append-like-tools",
"title": "External Results Reuse the Tool Result Path",
"description": "MCP responses are appended to the conversation like ordinary tool results. This keeps the agent loop unchanged while still letting external systems participate.",
"alternatives": "A separate external-response channel would make MCP feel special and require extra loop logic.",
"id": "fail-the-workflow",
"title": "Orchestration Failures Propagate",
"description": "A failed stage, invalid structured result, corrupt journal, or exceeded run-wide limit fails the workflow instead of silently dropping an item and reporting success.",
"alternatives": "Best-effort collection can be useful for optional work, but it must be explicit rather than the default.",
"zh": {
"title": "外部结果复用 Tool Result 路径",
"description": "MCP 响应会像普通 tool result 一样追加到对话中。这样 agent 循环无需改变,同时外部系统仍然可以参与。"
"title": "编排故障必须向上传播",
"description": "阶段失败、结构化结果不合法、journal 损坏或超过全局限制时workflow 直接失败,而不是静默丢项后仍报告成功。"
},
"ja": {
"title": "外部結果は tool result 経路を再利用する",
"description": "MCP の応答は通常の tool result と同じように会話へ追加されます。エージェントループを変えずに外部システムを参加させられます。"
"title": "編成の失敗は上位へ伝播させる",
"description": "stage failure、無効な structured result、破損 journal、run-wide limit 超過は workflow を失敗させ、項目を黙って落として成功扱いしない。"
}
}
]

View File

@@ -2,45 +2,45 @@
"version": "s19",
"decisions": [
{
"id": "composition-over-new-loop",
"title": "The Harness Composes Previous Layers",
"description": "The integrated harness does not replace the loop with a new architecture. It composes memory, tasks, skills, background work, teams, worktrees, and MCP around the same core model-tool-result cycle.",
"alternatives": "A new orchestration framework would look more impressive, but it would hide the continuity across the course.",
"id": "host-owns-completion-gate",
"title": "The Host Owns the Completion Gate",
"description": "The working model may request to stop, but GoalController evaluates the active goal before AgentSession returns. The gate sits at the existing turn boundary.",
"alternatives": "Asking the working model whether it is finished is simpler, but lets the same actor make and verify its own claim.",
"zh": {
"title": "Harness 组合既有层,而不是换掉循环",
"description": "集成后的 Harness 没有用新架构替换循环,而是把 memory、task、skill、后台任务、团队、worktree、MCP 组合到同一个模型-工具-结果循环周围。"
"title": "完成闸门由宿主持有",
"description": "工作模型可以请求停止,但 GoalController 会在 AgentSession 返回前评估 active goal。这个闸门就在原有的轮次边界上。"
},
"ja": {
"title": "Harness は既存レイヤーを統合する",
"description": "統合された Harness はループを新しい構造で置き換えません。memory、task、skill、バックグラウンド処理、チーム、worktree、MCP を同じ model-tool-result サイクルの周囲に合成します。"
"title": "完了ゲートはホストが所有する",
"description": "作業モデルは停止を要求できますが、GoalController は AgentSession が return する前に active goal を評価します。この gate は既存の turn 境界に置かれます。"
}
},
{
"id": "single-source-of-runtime-truth",
"title": "Runtime State Has Named Sources",
"description": "Context assembly pulls from named sources such as memory, task graph, skills, tool registry, and policy. This keeps a large agent debuggable because each piece of prompt context has an owner.",
"alternatives": "Dumping everything into one prompt string is shorter, but it becomes impossible to tell which subsystem caused a bad decision.",
"id": "conversation-is-evaluator-input",
"title": "The Conversation Is the Evaluator's Input",
"description": "The evaluator receives the active condition and the current conversation, including tool results reported there. It has no tools of its own and judges only what the conversation contains.",
"alternatives": "Letting the evaluator rerun commands would turn a completion check into another worker and create a second execution path.",
"zh": {
"title": "运行时状态来自具名来源",
"description": "上下文组装从 memory、task graph、skills、tool registry、policy 等具名来源读取。大型 agent 因此仍可调试,因为每块 prompt context 都有清晰归属。"
"title": "对话记录就是判断器的输入",
"description": "判断器接收 active condition 和当前对话,其中也包括已经写入的工具结果。它自己没有工具,只能根据对话中已有的内容判断。"
},
"ja": {
"title": "ランタイム状態には名前付きの出所がある",
"description": "コンテキスト組み立ては memory、task graph、skills、tool registry、policy などの名前付きソースから取得します。各 prompt context に所有者があるため、大きなエージェントでもデバッグ可能です。"
"title": "conversation が evaluator の入力になる",
"description": "evaluator は active condition と現在の conversation を受け取り、そこに記録された tool result も読みます。自身では tool を使えず、conversation にある内容だけで判断します。"
}
},
{
"id": "recovery-is-first-class",
"title": "Recovery Is Part of the Main Flow",
"description": "Compaction, error recovery, and asynchronous result collection are normal loop behavior. The harness handles recovery and resumption through named paths instead of scattered exception branches.",
"alternatives": "Leaving recovery at the edges makes it harder to see which state is safe to resume.",
"id": "continuation-limits-preserve-goal",
"title": "Limits Return Control Without Clearing the Goal",
"description": "When a goal is unmet, the controller appends the evaluator's reason to messages[] and continues the same loop. The Stop-hook block cap or global turn limit returns control to the user while leaving the goal active.",
"alternatives": "Continuing without any limit can hold one request forever; marking the goal complete or clearing it at the limit would lose unfinished work.",
"zh": {
"title": "恢复能力是一等流程",
"description": "压缩、错误恢复和异步结果收集都属于正常循环。Harness 通过明确的路径处理恢复与续跑,而不是把逻辑散落在异常分支中。"
"title": "达到限制时交还控制权,但保留目标",
"description": "目标未满足时controller 把判断理由追加到 messages[]并在同一个循环里继续。Stop hook 的连续阻止上限或全局轮次上限会把控制权交还用户,同时让目标保持 active。"
},
"ja": {
"title": "リカバリは主要フローの一部",
"description": "圧縮、エラー回復、非同期結果収集を通常のループ動作として扱います。Harness は回復と再開を名前付きの経路にまとめ、例外分岐へ散らしません。"
"title": "上限では control を返し、goal は維持する",
"description": "goal が未達なら、controller は evaluator の理由を messages[] に追加し、同じ loop を続けます。Stop hook の連続 block 上限または global turn limit に達すると、goal を active のまま user に control を返します。"
}
}
]

View File

@@ -1,47 +0,0 @@
{
"version": "s20",
"decisions": [
{
"id": "script-owns-fixed-orchestration",
"title": "Code Owns Fixed Orchestration",
"description": "When the stages and aggregation rules are known in advance, a workflow script makes the process parallel, reproducible, and inspectable without changing the main agent loop.",
"alternatives": "Letting the model choose every next step is more flexible, but slower and harder to resume for a fixed procedure.",
"zh": {
"title": "固定编排由代码负责",
"description": "当阶段与汇总规则事先确定时workflow 脚本能让流程并行、可复现、可检查,同时不修改主 Agent 循环。"
},
"ja": {
"title": "固定された編成はコードが担う",
"description": "段階と集約ルールが事前に決まっているなら、workflow script は main Agent loop を変えずに処理を並列化し、再現可能で検査可能にする。"
}
},
{
"id": "semantic-journal-keys",
"title": "Semantic Keys Make Resume Independent of Completion Order",
"description": "Journal entries use stable call content rather than a shared completion counter. Concurrent calls can finish in any order and still map to the correct cached result.",
"alternatives": "Indexing by completion order is simpler, but replays the wrong result as soon as concurrent timing changes.",
"zh": {
"title": "语义键让恢复不依赖完成顺序",
"description": "Journal 用稳定的调用内容作为 key而不是共享完成计数器。并发调用无论以什么顺序结束都能命中正确缓存。"
},
"ja": {
"title": "意味キーで完了順序に依存せず再開する",
"description": "Journal は共有完了カウンタではなく安定した call 内容を key にする。並行 call の終了順が変わっても正しい cache result に対応できる。"
}
},
{
"id": "fail-the-workflow",
"title": "Orchestration Failures Propagate",
"description": "A failed stage, invalid structured result, corrupt journal, or exceeded run-wide limit fails the workflow instead of silently dropping an item and reporting success.",
"alternatives": "Best-effort collection can be useful for optional work, but it must be explicit rather than the default.",
"zh": {
"title": "编排故障必须向上传播",
"description": "阶段失败、结构化结果不合法、journal 损坏或超过全局限制时workflow 直接失败,而不是静默丢项后仍报告成功。"
},
"ja": {
"title": "編成の失敗は上位へ伝播させる",
"description": "stage failure、無効な structured result、破損 journal、run-wide limit 超過は workflow を失敗させ、項目を黙って落として成功扱いしない。"
}
}
]
}

View File

@@ -1,47 +0,0 @@
{
"version": "s21",
"decisions": [
{
"id": "host-owns-completion-gate",
"title": "The Host Owns the Completion Gate",
"description": "The working model may request to stop, but the harness evaluates the active goal before returning. Completion is a program decision at the turn boundary.",
"alternatives": "Asking the working model whether it is finished is simpler, but lets the same actor make and verify its own claim.",
"zh": {
"title": "完成闸门由宿主持有",
"description": "工作模型可以请求停止,但 harness 会在 return 前评估 active goal。是否完成是轮次边界上的程序决策。"
},
"ja": {
"title": "完了ゲートはホストが所有する",
"description": "作業モデルは停止を要求できるが、harness は return 前に active goal を評価する。完了は turn 境界でのプログラム判断である。"
}
},
{
"id": "host-assigned-evidence-origins",
"title": "Evidence Trust Comes from the Ingress Path",
"description": "Ordinary submit calls cannot attach trusted labels. Only an allowlisted host-event channel can deliver task or monitor evidence, so user and model prose cannot certify itself.",
"alternatives": "Trusting text content or caller-supplied labels makes the evidence boundary forgeable.",
"zh": {
"title": "证据信任来自入口路径",
"description": "普通 submit 不能附加可信标签;只有白名单宿主事件通道能送入 task 或 monitor 证据,因此用户与模型文本不能自证完成。"
},
"ja": {
"title": "証拠の信頼は入力経路から得る",
"description": "通常の submit は trusted label を付けられず、allowlist 済み host event channel だけが task や monitor evidence を届ける。ユーザーやモデルの文章は自己証明できない。"
}
},
{
"id": "bounded-continuation",
"title": "Every Automatic Continuation Needs a Budget",
"description": "An unmet goal queues another turn only while budget remains. Exhaustion marks the goal blocked and releases the gate instead of creating an infinite loop.",
"alternatives": "An unbounded goal is persistent, but an impossible condition can consume resources forever.",
"zh": {
"title": "每次自动续轮都必须有预算",
"description": "目标未满足时只在预算剩余时继续;耗尽后将目标标记为 blocked 并释放闸门,避免无限循环。"
},
"ja": {
"title": "自動継続には必ず予算を置く",
"description": "goal 未達時は予算が残る間だけ次の turn を追加する。使い切れば blocked にして gate を解放し、無限 loop を防ぐ。"
}
}
]
}

View File

@@ -370,88 +370,38 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
nodes: [
{ id: "start", label: "User Requirement", type: "start", x: COL_CENTER, y: 30 },
{ id: "lead", label: "Lead Proposes\nSmall Team", type: "process", x: COL_CENTER, y: 110 },
{ id: "team_tool", label: "User Confirms?", type: "decision", x: COL_CENTER, y: 200 },
{ id: "spawn", label: "Spawn Persistent\nTeammates", type: "subprocess", x: COL_LEFT, y: 300 },
{ id: "send", label: "Assignment /\nTyped Request", type: "subprocess", x: COL_LEFT, y: 400 },
{ id: "bus", label: "MessageBus\nJSONL Mailboxes", type: "process", x: COL_CENTER, y: 500 },
{ id: "teammate", label: "Teammate\nWORK / IDLE", type: "process", x: COL_RIGHT, y: 400 },
{ id: "tools", label: "Scoped Tools /\nPlan Gate", type: "subprocess", x: COL_RIGHT, y: 500 },
{ id: "inbox", label: "Runtime Delivery", type: "process", x: COL_CENTER, y: 600 },
{ id: "append", label: "Append Team Events", type: "process", x: COL_LEFT, y: 690 },
{ id: "end", label: "Continue Alone", type: "end", x: COL_RIGHT, y: 300 },
{ id: "confirm", label: "User Confirms?", type: "decision", x: COL_CENTER, y: 190 },
{ id: "spawn", label: "Spawn Persistent\nTeammate", type: "subprocess", x: COL_LEFT, y: 280 },
{ id: "bus", label: "MessageBus\nTyped Requests", type: "process", x: COL_CENTER, y: 370 },
{ id: "teammate", label: "Teammate\nWORK / IDLE", type: "process", x: COL_RIGHT, y: 280 },
{ id: "gate", label: "Plan Approved?", type: "decision", x: COL_RIGHT, y: 370 },
{ id: "scan", label: "Scan Ready Tasks", type: "subprocess", x: COL_CENTER, y: 470 },
{ id: "ready", label: "Ready Task?", type: "decision", x: COL_CENTER, y: 560 },
{ id: "claim", label: "Atomic Claim\ntask_lock", type: "subprocess", x: COL_LEFT, y: 650 },
{ id: "cwd", label: "Task Worktree\nTool cwd", type: "process", x: COL_RIGHT, y: 650 },
{ id: "result", label: "Result + IDLE\nRuntime Delivery", type: "process", x: COL_CENTER, y: 740 },
{ id: "end", label: "Continue Alone", type: "end", x: COL_RIGHT, y: 190 },
],
edges: [
{ from: "start", to: "lead" },
{ from: "lead", to: "team_tool" },
{ from: "team_tool", to: "spawn", label: "yes" },
{ from: "team_tool", to: "end", label: "no" },
{ from: "spawn", to: "send" },
{ from: "send", to: "bus" },
{ from: "lead", to: "confirm" },
{ from: "confirm", to: "spawn", label: "yes" },
{ from: "confirm", to: "end", label: "no" },
{ from: "spawn", to: "bus", label: "assignment" },
{ from: "bus", to: "teammate" },
{ from: "teammate", to: "tools" },
{ from: "tools", to: "bus", label: "result / protocol reply" },
{ from: "bus", to: "inbox", label: "wake Lead" },
{ from: "inbox", to: "append" },
{ from: "append", to: "lead" },
{ from: "teammate", to: "gate" },
{ from: "gate", to: "bus", label: "waiting" },
{ from: "gate", to: "scan", label: "approved / idle" },
{ from: "scan", to: "ready" },
{ from: "ready", to: "bus", label: "no: wait" },
{ from: "ready", to: "claim", label: "yes" },
{ from: "claim", to: "cwd" },
{ from: "cwd", to: "result" },
{ from: "result", to: "bus", label: "reply + wake Lead" },
{ from: "bus", to: "lead", label: "runtime delivery" },
],
},
s16: {
nodes: [
{ id: "start", label: "Teammate IDLE", type: "start", x: COL_CENTER, y: 30 },
{ id: "idle", label: "Wait for Messages", type: "process", x: COL_CENTER, y: 110 },
{ id: "scan", label: "Scan Ready Tasks", type: "subprocess", x: COL_CENTER, y: 190 },
{ id: "claimable", label: "Ready Task?", type: "decision", x: COL_CENTER, y: 280 },
{ id: "claim", label: "Atomic Claim\ntask_lock", type: "subprocess", x: COL_LEFT, y: 380 },
{ id: "work", label: "WORK State", type: "process", x: COL_LEFT, y: 470 },
{ id: "complete", label: "complete_task", type: "subprocess", x: COL_LEFT, y: 560 },
{ id: "inbox", label: "No Ready Task", type: "process", x: COL_RIGHT, y: 380 },
{ id: "shutdown", label: "Remain IDLE", type: "process", x: COL_RIGHT, y: 470 },
{ id: "done", label: "Result + IDLE Event", type: "process", x: COL_CENTER, y: 650 },
],
edges: [
{ from: "start", to: "idle" },
{ from: "idle", to: "scan" },
{ from: "scan", to: "claimable" },
{ from: "claimable", to: "claim", label: "yes" },
{ from: "claimable", to: "inbox", label: "no" },
{ from: "claim", to: "work" },
{ from: "work", to: "complete" },
{ from: "complete", to: "done" },
{ from: "done", to: "idle" },
{ from: "inbox", to: "shutdown" },
{ from: "shutdown", to: "idle" },
],
},
s17: {
nodes: [
{ id: "start", label: "Task Selected", type: "start", x: COL_CENTER, y: 30 },
{ id: "create", label: "create_worktree", type: "subprocess", x: COL_CENTER, y: 110 },
{ id: "validate", label: "Validate Name", type: "process", x: COL_CENTER, y: 190 },
{ id: "git", label: "git worktree add", type: "subprocess", x: COL_LEFT, y: 290 },
{ id: "bind", label: "Bind Task\nworktree field", type: "process", x: COL_LEFT, y: 380 },
{ id: "run", label: "Run in Isolated\nDirectory", type: "subprocess", x: COL_CENTER, y: 470 },
{ id: "events", label: "Lifecycle Events\n.events.jsonl", type: "process", x: COL_RIGHT, y: 190 },
{ id: "close", label: "keep / remove", type: "decision", x: COL_CENTER, y: 560 },
{ id: "cleanup", label: "remove_worktree", type: "subprocess", x: COL_LEFT, y: 650 },
{ id: "keep", label: "keep_worktree", type: "process", x: COL_RIGHT, y: 650 },
{ id: "end", label: "Task Result", type: "end", x: COL_CENTER, y: 740 },
],
edges: [
{ from: "start", to: "create" },
{ from: "create", to: "validate" },
{ from: "validate", to: "git" },
{ from: "git", to: "bind" },
{ from: "bind", to: "run" },
{ from: "create", to: "events", label: "emit" },
{ from: "run", to: "events", label: "status" },
{ from: "run", to: "close" },
{ from: "close", to: "cleanup", label: "remove" },
{ from: "close", to: "keep", label: "keep" },
{ from: "cleanup", to: "end" },
{ from: "keep", to: "end" },
],
},
s18: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 110 },
@@ -478,7 +428,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
{ from: "append", to: "llm" },
],
},
s19: {
s17: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "context", label: "Assemble Context\nmemory + tasks", type: "process", x: COL_CENTER, y: 115 },
@@ -512,7 +462,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
{ from: "recover", to: "context" },
],
},
s20: {
s18: {
nodes: [
{ id: "start", label: "Workflow Tool Call", type: "start", x: COL_CENTER, y: 30 },
{ id: "validate", label: "Validate Meta +\nPermission", type: "process", x: COL_CENTER, y: 120 },
@@ -536,28 +486,34 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
{ from: "output", to: "notify" },
],
},
s21: {
s19: {
nodes: [
{ id: "start", label: "Model Wants to Stop", type: "start", x: COL_CENTER, y: 30 },
{ id: "active", label: "Active Goal?", type: "decision", x: COL_CENTER, y: 120 },
{ id: "evidence", label: "Read Trusted\nEvidence Window", type: "process", x: COL_CENTER, y: 220 },
{ id: "evaluate", label: "Goal Satisfied?", type: "decision", x: COL_CENTER, y: 320 },
{ id: "complete", label: "goal_completed", type: "end", x: COL_RIGHT, y: 430 },
{ id: "budget", label: "Budget Left?", type: "decision", x: COL_LEFT, y: 430 },
{ id: "continue", label: "Queue Goal\nContinuation", type: "process", x: COL_LEFT, y: 540 },
{ id: "loop", label: "Next Agent Turn", type: "subprocess", x: COL_LEFT, y: 650 },
{ id: "blocked", label: "goal_blocked", type: "end", x: COL_CENTER, y: 540 },
{ id: "background", label: "Background Work\nRunning?", type: "decision", x: COL_CENTER, y: 215 },
{ id: "defer", label: "defer\nGoal Stays Active", type: "end", x: COL_RIGHT, y: 215 },
{ id: "conversation", label: "Evaluator Reads\nConversation", type: "process", x: COL_CENTER, y: 315 },
{ id: "evaluate", label: "Evaluator Result?", type: "decision", x: COL_CENTER, y: 415 },
{ id: "complete", label: "achieved\nGoal Cleared", type: "end", x: COL_RIGHT, y: 415 },
{ id: "failed", label: "failed\nGoal Cleared", type: "end", x: COL_RIGHT, y: 520 },
{ id: "cap", label: "Stop-Block Cap\nReached?", type: "decision", x: COL_LEFT, y: 520 },
{ id: "continue", label: "Append Reason\nto messages[]", type: "process", x: COL_LEFT, y: 625 },
{ id: "loop", label: "Next Agent Turn", type: "subprocess", x: COL_LEFT, y: 730 },
{ id: "limit", label: "limit\nGoal Stays Active", type: "end", x: COL_CENTER, y: 520 },
{ id: "return", label: "Return", type: "end", x: COL_RIGHT, y: 120 },
],
edges: [
{ from: "start", to: "active" },
{ from: "active", to: "return", label: "no" },
{ from: "active", to: "evidence", label: "yes" },
{ from: "evidence", to: "evaluate" },
{ from: "evaluate", to: "complete", label: "yes" },
{ from: "evaluate", to: "budget", label: "no" },
{ from: "budget", to: "continue", label: "yes" },
{ from: "budget", to: "blocked", label: "no" },
{ from: "active", to: "background", label: "yes" },
{ from: "background", to: "defer", label: "yes" },
{ from: "background", to: "conversation", label: "no" },
{ from: "conversation", to: "evaluate" },
{ from: "evaluate", to: "complete", label: "ok" },
{ from: "evaluate", to: "failed", label: "impossible" },
{ from: "evaluate", to: "cap", label: "not yet" },
{ from: "cap", to: "limit", label: "yes" },
{ from: "cap", to: "continue", label: "no" },
{ from: "continue", to: "loop" },
{ from: "loop", to: "start" },
],

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,60 +1,105 @@
{
"version": "s15",
"title": "Agent Teams",
"description": "The Lead proposes a team for a normal user request, waits for confirmation, then coordinates persistent teammates through runtime-delivered events.",
"title": "Agent Team Runtime",
"description": "The Lead coordinates persistent teammates while the runtime owns message delivery, atomic task claims, and task-bound worktree directories.",
"steps": [
{
"type": "user_message",
"content": "Refactor the configuration loader and authentication flow, then update the tests.",
"annotation": "The user describes the goal without designing a team."
"content": "Refactor authentication and update its dependent tests in parallel without mixing the edits.",
"annotation": "The user states the outcome and parallel-edit boundary, not an implementation-specific worktree procedure."
},
{
"type": "assistant_text",
"content": "These areas can be handled in parallel. I propose one teammate for configuration and authentication, and another for tests. Shall I start that team?",
"annotation": "The Lead chooses a small team and makes the extra-agent decision visible."
"content": "I propose a backend teammate for authentication and a test teammate that picks up the dependent checks once they are ready. Shall I start the team?",
"annotation": "The Lead makes the extra-agent decision visible before spawning."
},
{
"type": "user_message",
"content": "Yes, go ahead.",
"annotation": "Teammates start only after explicit confirmation."
"annotation": "The team starts only after explicit confirmation."
},
{
"type": "tool_call",
"toolName": "create_task",
"content": "{\"subject\":\"Refactor authentication\"}",
"annotation": "The shared task board remains the source of ownership and status."
},
{
"type": "tool_result",
"toolName": "create_task",
"content": "Created task_1712345678_0042: Refactor authentication",
"annotation": "The runtime-generated task ID is carried into every later operation on this task."
},
{
"type": "tool_call",
"toolName": "create_worktree",
"content": "{\"name\":\"auth-refactor\",\"task_id\":\"task_1712345678_0042\"}",
"annotation": "The worktree directory is recorded on the task instead of managed as a separate workflow or security sandbox."
},
{
"type": "tool_call",
"toolName": "create_task",
"content": "{\"subject\":\"Update authentication tests\",\"blockedBy\":[\"task_1712345678_0042\"]}",
"annotation": "The task graph keeps dependent work from starting early."
},
{
"type": "tool_result",
"toolName": "create_task",
"content": "Created task_1712345678_0043: Update authentication tests (blockedBy: task_1712345678_0042)",
"annotation": "The second generated ID names the dependent task that the test teammate will later claim."
},
{
"type": "tool_call",
"toolName": "spawn_teammate",
"content": "{\"name\":\"backend\",\"role\":\"backend engineer\",\"prompt\":\"Refactor configuration and authentication while preserving interfaces.\"}",
"annotation": "The first persistent teammate enters WORK with a focused assignment."
"content": "{\"name\":\"backend\",\"role\":\"backend engineer\",\"prompt\":\"Claim the authentication task and propose a plan.\"}",
"annotation": "A persistent teammate receives focused work through the team runtime."
},
{
"type": "tool_call",
"toolName": "spawn_teammate",
"content": "{\"name\":\"tests\",\"role\":\"test engineer\",\"prompt\":\"Update and run tests for the refactor.\"}",
"annotation": "The second teammate gets an independent slice."
"content": "{\"name\":\"tests\",\"role\":\"test engineer\",\"prompt\":\"Watch the board and claim the dependent test task when it becomes ready.\"}",
"annotation": "A second persistent teammate can wait in IDLE without another direct dispatch."
},
{
"type": "system_event",
"content": "backend -> Lead: result(refactor complete) -> idle_notification",
"content": "plan_request(req_plan_7) -> plan_response(req_plan_7, approved=true)",
"annotation": "Typed correlation and an approval gate protect mutating tools."
},
{
"type": "system_event",
"content": "claim_next_task(backend) -> task_1712345678_0042; task_lock commits owner=backend",
"annotation": "The ownership check and state transition are atomic."
},
{
"type": "system_event",
"content": "backend tool cwd -> .worktrees/auth-refactor",
"annotation": "Bash, read, and write derive their directory from the claimed task binding."
},
{
"type": "tool_call",
"toolName": "complete_task",
"content": "{\"task_id\":\"task_1712345678_0042\"}",
"annotation": "Completing the first task makes its dependent test task ready."
},
{
"type": "system_event",
"content": "backend -> Lead: result(auth refactor complete) -> idle_notification",
"annotation": "Result and idle state are separate events; the teammate remains available."
},
{
"type": "system_event",
"content": "tests -> Lead: result(test suite passed) -> idle_notification",
"annotation": "The runtime observes mailbox writes and wakes the Lead without a polling tool."
},
{
"type": "assistant_text",
"content": "Both parts are complete. The interfaces were preserved and the updated tests pass.",
"annotation": "The Lead combines teammate results into one user-facing answer."
},
{
"type": "tool_call",
"toolName": "request_shutdown",
"content": "{\"teammate\":\"backend\"}",
"annotation": "A typed request with a request id closes the persistent teammate cleanly."
"content": "claim_next_task(tests) -> task_1712345678_0043; task_lock commits owner=tests",
"annotation": "An idle teammate discovers newly ready work without another direct assignment."
},
{
"type": "system_event",
"content": "shutdown_response(request_id=req_42, approve=true)",
"annotation": "The matching response resolves the pending protocol request."
"content": "tests -> Lead: result(test suite passed) -> idle_notification",
"annotation": "The runtime wakes the Lead when mailbox events arrive instead of asking the model to poll."
},
{
"type": "assistant_text",
"content": "Authentication was refactored in its task-bound worktree and the dependent tests pass.",
"annotation": "The Lead combines parallel results into one user-facing outcome."
}
]
}

View File

@@ -1,50 +1,46 @@
{
"version": "s16",
"title": "Autonomous Agents",
"description": "Idle teammates discover ready tasks on a shared board and use an atomic claim before starting work.",
"title": "MCP Tools",
"description": "The agent discovers external MCP tools and exposes them through a normalized tool namespace.",
"steps": [
{
"type": "user_message",
"content": "Update the API examples, then add tests that use the final examples.",
"annotation": "The request contains two tasks with a clear dependency."
"content": "Search the documentation for deployment guidance.",
"annotation": "The user asks for a tool source outside the built-in set."
},
{
"type": "tool_call",
"toolName": "create_task",
"content": "{\"subject\":\"Update API examples\"}",
"annotation": "The Lead creates the first task in the shared graph."
"toolName": "connect_mcp",
"content": "{\"name\":\"docs\"}",
"annotation": "The runtime creates an MCP client for the named server."
},
{
"type": "system_event",
"content": "normalize_mcp_name(\"docs\", \"search\") -> mcp__docs__search",
"annotation": "External tools are namespaced to avoid collisions."
},
{
"type": "tool_result",
"toolName": "connect_mcp",
"content": "Connected to MCP server 'docs'. Discovered 2 tools: search, get_version",
"annotation": "Tool discovery expands the active tool pool."
},
{
"type": "tool_call",
"toolName": "create_task",
"content": "{\"subject\":\"Add example tests\",\"blockedBy\":[\"task_examples\"]}",
"annotation": "The second task cannot start until the examples are complete."
"toolName": "mcp__docs__search",
"content": "{\"query\":\"deployment\"}",
"annotation": "The LLM can now call the discovered tool by its normalized name."
},
{
"type": "system_event",
"content": "alice, bob: state=IDLE -> scan_unclaimed_tasks()",
"annotation": "Existing IDLE teammates scan the board after waiting for messages."
"type": "tool_result",
"toolName": "mcp__docs__search",
"content": "[docs] Found 3 results for 'deployment'",
"annotation": "The external result is appended like any other tool result."
},
{
"type": "system_event",
"content": "claim_next_task(alice) -> task_examples; task_lock commits owner=alice",
"annotation": "The ownership check and pending-to-in_progress update are atomic."
},
{
"type": "system_event",
"content": "claim_next_task(bob) -> no ready task; remain IDLE",
"annotation": "The test task is still blocked, so Bob does not start it early."
},
{
"type": "tool_call",
"toolName": "complete_task",
"content": "{\"task_id\":\"task_examples\"}",
"annotation": "Completing the examples unblocks the dependent test task."
},
{
"type": "system_event",
"content": "claim_next_task(bob) -> task_tests; task_lock commits owner=bob",
"annotation": "Bob claims the newly ready work without another direct assignment."
"type": "assistant_text",
"content": "The docs server found three matches for deployment guidance.",
"annotation": "The agent summarizes external tool output for the user."
}
]
}

View File

@@ -1,45 +1,97 @@
{
"version": "s17",
"title": "Worktree Isolation",
"description": "A task can be bound to an isolated git worktree so concurrent agents avoid stepping on each other.",
"title": "Integrated Harness",
"description": "The harness composes context assembly, tools, memory, teams, background work, cron, worktrees, and MCP.",
"steps": [
{
"type": "user_message",
"content": "Update the docs and parser in parallel without letting the changes interfere.",
"annotation": "Concurrent edits need isolated working directories."
"content": "Prepare this project for release. Check the code, update the docs, and report deployment readiness.",
"annotation": "One ordinary request needs several earlier capabilities to work together."
},
{
"type": "system_event",
"content": "assemble_prompt: memory + task graph + skills + available tools + policy",
"annotation": "The runtime builds the prompt from layered sources of context."
},
{
"type": "assistant_text",
"content": "I suggest a docs teammate while I run the release checks and inspect deployment status. Shall I start that team?",
"annotation": "The Lead proposes the team before adding another persistent agent."
},
{
"type": "user_message",
"content": "Yes. Start the docs teammate and continue.",
"annotation": "User confirmation opens the team boundary inherited from S15."
},
{
"type": "tool_call",
"toolName": "load_skill",
"content": "{\"name\":\"code-review\"}",
"annotation": "Skills contribute procedural context before execution."
},
{
"type": "tool_call",
"toolName": "create_task",
"content": "{\"subject\":\"Update release notes\",\"description\":\"Prepare release documentation and report the result.\"}",
"annotation": "The shared task board gives the docs work a stable owner and lifecycle."
},
{
"type": "tool_result",
"toolName": "create_task",
"content": "Created task_1712345678_0042: Update release notes",
"annotation": "The task ID connects the assignment to its working directory."
},
{
"type": "tool_call",
"toolName": "create_worktree",
"content": "{\"task_id\":\"task_docs\",\"name\":\"docs-fix\"}",
"annotation": "The tool validates a safe worktree name before touching git."
},
{
"type": "system_event",
"content": "git worktree add .worktrees/docs-fix -b agent/docs-fix",
"annotation": "A separate branch and checkout are created for that task."
"content": "{\"name\":\"release-docs\",\"task_id\":\"task_1712345678_0042\"}",
"annotation": "The pending docs task receives a separate checkout before it is claimed."
},
{
"type": "tool_result",
"toolName": "create_worktree",
"content": "task_docs bound to .worktrees/docs-fix",
"annotation": "The task record stores the assigned worktree path."
},
{
"type": "system_event",
"content": ".worktrees/events.jsonl <- {event:\"created\", task:\"task_docs\", worktree:\"docs-fix\"}",
"annotation": "Lifecycle events are emitted as a side channel."
"content": "Worktree 'release-docs' created for task_1712345678_0042",
"annotation": "The task now carries the checkout used by its eventual owner."
},
{
"type": "tool_call",
"toolName": "keep_worktree",
"content": "{\"task_id\":\"task_docs\",\"reason\":\"needs human review\"}",
"annotation": "Closeout can preserve a worktree instead of deleting it immediately."
"toolName": "spawn_teammate",
"content": "{\"name\":\"docs\",\"role\":\"documentation engineer\",\"prompt\":\"Claim task_1712345678_0042, update the release notes in its task-bound worktree, and report the result.\"}",
"annotation": "Team delegation handles a parallel slice of the release."
},
{
"type": "tool_call",
"toolName": "bash",
"content": "{\"command\":\"npm run lint && npm run test\",\"run_in_background\":true}",
"annotation": "Long-running validation goes through the background task path."
},
{
"type": "tool_call",
"toolName": "connect_mcp",
"content": "{\"name\":\"deploy\"}",
"annotation": "External capabilities are added only when needed."
},
{
"type": "tool_call",
"toolName": "mcp__deploy__status",
"content": "{\"service\":\"web\"}",
"annotation": "Connecting discovers the tool; a separate call performs the status check."
},
{
"type": "tool_result",
"toolName": "mcp__deploy__status",
"content": "[deploy] web: running (v1.4.2)",
"annotation": "The readiness statement now comes from the MCP tool result rather than the connection event."
},
{
"type": "system_event",
"content": "recover: background task done, teammate replied, deploy status result appended",
"annotation": "The integrated runtime folds asynchronous results back into the loop."
},
{
"type": "assistant_text",
"content": "The docs task now has an isolated worktree and can be reviewed independently from parser changes.",
"annotation": "The user sees the isolation boundary, not just a raw git command."
"content": "Release preparation is ready: checks passed, docs are updated in the teammate worktree, and deployment status is available.",
"annotation": "The integrated harness returns a single user-facing outcome."
}
]
}

View File

@@ -1,46 +1,54 @@
{
"version": "s18",
"title": "MCP Tools",
"description": "The agent discovers external MCP tools and exposes them through a normalized tool namespace.",
"title": "Workflow Runtime",
"description": "A fixed review pipeline executes inside one Workflow call, records a journal, emits lifecycle and progress events, and returns one final tool result.",
"steps": [
{
"type": "user_message",
"content": "Search the documentation for deployment guidance.",
"annotation": "The user asks for a tool source outside the built-in set."
"content": "Review this change across correctness, security, performance, and style.",
"annotation": "The goal is open-ended, but the review procedure has a fixed shape."
},
{
"type": "tool_call",
"toolName": "connect_mcp",
"content": "{\"server\":\"docs\",\"command\":\"mock-docs-server\"}",
"annotation": "The runtime creates an MCP client for the named server."
"toolName": "Workflow",
"content": "{\"name\":\"review-changes\",\"description\":\"Review changed files across dimensions and verify each finding\",\"phases\":[\"Review\",\"Verify\"]}",
"annotation": "One tool call hands deterministic orchestration to the workflow runtime."
},
{
"type": "system_event",
"content": "normalize_mcp_name(\"docs\", \"search\") -> mcp__docs__search",
"annotation": "External tools are namespaced to avoid collisions."
"content": "async_launched(runId=wf_review-changes_6779) -> task_started",
"annotation": "The runtime emits launch lifecycle events before it executes the script; this is not a tool result."
},
{
"type": "system_event",
"content": "phase=Review -> pipeline([correctness, security, performance, style])",
"annotation": "Each item advances independently through the scripted stages."
},
{
"type": "system_event",
"content": "phase=Verify -> adversarial checks run in parallel",
"annotation": "Structured results cross a validation boundary before aggregation."
},
{
"type": "system_event",
"content": "workflow_agent status=done -> journal append",
"annotation": "Every completed agent call is checkpointed as the script runs."
},
{
"type": "system_event",
"content": "task_notification(status=completed, outputFile=.runtime/wf_review-changes_6779.output.json)",
"annotation": "The task emits its final lifecycle event after output is written."
},
{
"type": "tool_result",
"toolName": "connect_mcp",
"content": "Connected docs with tools: mcp__docs__search, mcp__docs__read",
"annotation": "Tool discovery expands the active tool pool."
"toolName": "Workflow",
"content": "{\"launched\":{\"status\":\"async_launched\",\"runId\":\"wf_review-changes_6779\"},\"result\":{\"confirmed\":[]},\"task\":{\"status\":\"completed\"}}",
"annotation": "The completed call returns once, with launch metadata, the workflow result, and task state together."
},
{
"type": "tool_call",
"toolName": "mcp__docs__search",
"content": "{\"query\":\"deployment\"}",
"annotation": "The LLM can now call the discovered tool by its normalized name."
},
{
"type": "tool_result",
"toolName": "mcp__docs__search",
"content": "[\"Deploy with npm run build\", \"Use environment variables for tokens\"]",
"annotation": "The external result is appended like any other tool result."
},
{
"type": "assistant_text",
"content": "The docs server says to build first and keep tokens in environment variables.",
"annotation": "The agent summarizes external tool output for the user."
"type": "system_event",
"content": "append Workflow tool_result -> messages[]",
"annotation": "The main loop receives that single result and continues with the updated conversation."
}
]
}

View File

@@ -1,57 +1,49 @@
{
"version": "s19",
"title": "Integrated Harness",
"description": "The harness composes context assembly, tools, memory, teams, background work, cron, worktrees, and MCP.",
"title": "Goal Loop",
"description": "A separate evaluator reads the conversation at the end of a turn and sends unfinished work back through the same loop.",
"steps": [
{
"type": "user_message",
"content": "Prepare this project for release. Check the code, update the docs, and report deployment readiness.",
"annotation": "One ordinary request needs several earlier capabilities to work together."
},
{
"type": "system_event",
"content": "assemble_prompt: memory + task graph + skills + available tools + policy",
"annotation": "The runtime builds the prompt from layered sources of context."
"content": "/goal pytest tests/auth exits with code 0",
"annotation": "The command stores an active completion condition and starts the work."
},
{
"type": "assistant_text",
"content": "I'll inspect the task graph, delegate docs, start the slow scan in the background, and use the release checklist skill.",
"annotation": "The model chooses multiple mechanisms while keeping one coherent plan."
"content": "The authentication code looks correct. The tests should pass now.",
"annotation": "With no more tool calls, the session asks the evaluator whether the active goal is complete."
},
{
"type": "tool_call",
"toolName": "load_skill",
"content": "{\"name\":\"release-check\"}",
"annotation": "Skills contribute procedural context before execution."
"type": "system_event",
"content": "goal_evaluated ok=false -> block",
"annotation": "The evaluator finds no test exit code in the conversation."
},
{
"type": "tool_call",
"toolName": "spawn_teammate",
"content": "{\"name\":\"docs\",\"role\":\"Update release notes in its worktree.\"}",
"annotation": "Team delegation handles a parallel slice of the release."
"type": "system_event",
"content": "[Goal still active] Run pytest tests/auth and surface the exit code.",
"annotation": "The controller appends the reason to messages[] and continues the same loop; no queue is involved."
},
{
"type": "tool_call",
"toolName": "bash",
"content": "npm run lint && npm run test",
"toolInput": "{\"background\":true}",
"annotation": "Long-running validation goes through the background task path."
"content": "pytest tests/auth",
"annotation": "The next agent turn runs the missing check."
},
{
"type": "tool_call",
"toolName": "connect_mcp",
"content": "{\"server\":\"deploy\",\"command\":\"mock-deploy-server\"}",
"annotation": "External capabilities are added only when needed."
},
{
"type": "system_event",
"content": "recover: background task done, teammate replied, MCP deploy status ready",
"annotation": "The integrated runtime folds asynchronous results back into the loop."
"type": "tool_result",
"toolName": "bash",
"content": "exit_code=0\n12 passed in 0.42s",
"annotation": "The concrete command result enters the same conversation."
},
{
"type": "assistant_text",
"content": "Release preparation is ready: checks passed, docs are updated in the teammate worktree, and deployment status is available.",
"annotation": "The integrated harness returns a single user-facing outcome."
"content": "pytest tests/auth exited 0: 12 tests passed.",
"annotation": "A turn with no further tool call reaches the Stop hook again."
},
{
"type": "system_event",
"content": "goal_evaluated ok=true -> achieved",
"annotation": "The controller records success, clears the active goal, and returns."
}
]
}

View File

@@ -1,43 +0,0 @@
{
"version": "s20",
"title": "Workflow Runtime",
"description": "A fixed review pipeline runs in parallel, records a journal, and resumes completed agent calls from cache.",
"steps": [
{
"type": "user_message",
"content": "Review this change across correctness, security, performance, and style.",
"annotation": "The goal is open-ended, but the review procedure has a fixed shape."
},
{
"type": "tool_call",
"toolName": "Workflow",
"content": "{\"name\":\"review-changes\",\"phases\":[\"Review\",\"Verify\"]}",
"annotation": "One tool call hands deterministic orchestration to the workflow runtime."
},
{
"type": "tool_result",
"content": "{\"status\":\"async_launched\",\"runId\":\"wf_review-changes_6779\"}",
"annotation": "The product runtime returns a claim ticket while work continues in the background."
},
{
"type": "system_event",
"content": "phase=Review -> pipeline([correctness, security, performance, style])",
"annotation": "Each item advances independently through the scripted stages."
},
{
"type": "system_event",
"content": "phase=Verify -> adversarial checks run in parallel",
"annotation": "Structured results cross a validation boundary before aggregation."
},
{
"type": "system_event",
"content": "journal append -> task_notification(status=completed)",
"annotation": "Every completed agent call is checkpointed before the final notification."
},
{
"type": "system_event",
"content": "resumeFromRunId -> unchanged calls status=cached",
"annotation": "Semantic keys reuse completed work without depending on concurrency order."
}
]
}

View File

@@ -1,37 +0,0 @@
{
"version": "s21",
"title": "Goal Loop",
"description": "A host-owned completion gate keeps the turn alive until trusted evidence satisfies the active goal.",
"steps": [
{
"type": "user_message",
"content": "/goal until tests passed and deploy green",
"annotation": "The command defines the condition but sits outside the evidence window."
},
{
"type": "system_event",
"content": "goal_started -> evidence window reset",
"annotation": "The harness, not the working model, owns the completion gate."
},
{
"type": "assistant_text",
"content": "Tests passed and deployment is green.",
"annotation": "Assistant prose is not trusted completion evidence."
},
{
"type": "system_event",
"content": "goal_evaluated satisfied=false -> continuation queued",
"annotation": "An unmet condition pushes the loop into another bounded turn."
},
{
"type": "tool_result",
"content": "<task_notification>tests passed; deploy green</task_notification>",
"annotation": "Only an allowlisted host event can attach a trusted evidence origin."
},
{
"type": "system_event",
"content": "goal_evaluated satisfied=true -> goal_completed",
"annotation": "Trusted evidence closes the goal and releases the stop gate."
}
]
}