mirror of
https://github.com/shareAI-lab/analysis_claude_code.git
synced 2026-09-21 12:53:37 +08:00
refactor: streamline the course to 17 lessons
This commit is contained in:
@@ -2,45 +2,45 @@
|
||||
"version": "s10",
|
||||
"decisions": [
|
||||
{
|
||||
"id": "prompt-from-state",
|
||||
"title": "Model Input Is Built from Runtime State",
|
||||
"description": "Stable prompt sections and dynamic state are assembled at the model boundary: workspace, available tools, memory, and skills. Model input becomes a product of the runtime rather than a single hardcoded string.",
|
||||
"alternatives": "A static prompt is easier to inspect, but it goes stale as capabilities change.",
|
||||
"id": "tasks-as-files",
|
||||
"title": "Tasks Are Durable JSON Files",
|
||||
"description": "Each task is persisted under .tasks/ with id, subject, description, status, owner, and blockedBy. The task board survives context compaction and process restarts.",
|
||||
"alternatives": "In-memory tasks are easier to code, but vanish exactly when long-running coordination needs them most.",
|
||||
"zh": {
|
||||
"title": "模型输入由运行时状态构建",
|
||||
"description": "稳定 prompt section 与动态状态在模型边界组装:workspace、可用工具、memory 和 skills。模型输入是运行时的产物,而不是单个硬编码字符串。"
|
||||
"title": "任务是持久 JSON 文件",
|
||||
"description": "每个任务都持久化在 .tasks/ 下,包含 id、subject、description、status、owner、blockedBy。任务板能跨上下文压缩和进程重启保留。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "モデル入力はランタイム状態から作る",
|
||||
"description": "安定した prompt section と workspace、利用可能ツール、memory、skills などの動的状態をモデル境界で組み立てます。モデル入力は単一の固定文字列ではなくランタイムの産物です。"
|
||||
"title": "タスクは永続 JSON ファイル",
|
||||
"description": "各タスクは .tasks/ に id、subject、description、status、owner、blockedBy を持って保存されます。タスクボードはコンテキスト圧縮や再起動を越えて残ります。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "deterministic-cache-key",
|
||||
"title": "A Deterministic Cache Avoids Reassembly",
|
||||
"description": "The context object is serialized with stable ordering. If the key has not changed, the prompt can be reused safely.",
|
||||
"alternatives": "Rebuilding every turn is simple, but hides when the prompt actually changed.",
|
||||
"id": "blockedby-dependencies",
|
||||
"title": "blockedBy Encodes Ordering",
|
||||
"description": "A task can only be claimed when all blockedBy dependencies are completed. Missing dependencies are treated as blocked to fail closed.",
|
||||
"alternatives": "Letting the model remember ordering is fragile and hard for teammates to share.",
|
||||
"zh": {
|
||||
"title": "确定性缓存避免重复组装",
|
||||
"description": "Context 对象用稳定顺序序列化。如果 key 没变,提示词就可以安全复用。"
|
||||
"title": "blockedBy 编码任务顺序",
|
||||
"description": "只有所有 blockedBy 依赖都完成时,任务才能被 claim。缺失依赖也被视为阻塞,采用 fail closed。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "決定的キャッシュで再組み立てを避ける",
|
||||
"description": "context オブジェクトを安定した順序でシリアライズします。key が変わらなければプロンプトを安全に再利用できます。"
|
||||
"title": "blockedBy が順序を表現する",
|
||||
"description": "blockedBy の依存がすべて完了した時だけタスクを claim できます。存在しない依存もブロック扱いにして fail closed にします。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "sections-have-owners",
|
||||
"title": "Prompt Sections Have Owners",
|
||||
"description": "Identity, tools, workspace, and memory are separate sections. This makes it easier to debug which subsystem injected a bad instruction.",
|
||||
"alternatives": "Concatenating arbitrary strings works until the prompt grows and no one knows where a rule came from.",
|
||||
"id": "claim-complete-lifecycle",
|
||||
"title": "Claim and Complete Make Work Observable",
|
||||
"description": "claim_task records an owner and in_progress state; complete_task marks completion and reports downstream tasks that became unblocked.",
|
||||
"alternatives": "A simple checklist can say done, but it cannot safely coordinate ownership or dependencies.",
|
||||
"zh": {
|
||||
"title": "Prompt Section 有明确归属",
|
||||
"description": "identity、tools、workspace、memory 是分开的 section。这样更容易定位哪一层注入了错误指令。"
|
||||
"title": "Claim 和 Complete 让工作可观察",
|
||||
"description": "claim_task 记录 owner 和 in_progress 状态;complete_task 标记完成,并报告被解锁的下游任务。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "prompt section には所有者がある",
|
||||
"description": "identity、tools、workspace、memory を別 section にします。どのサブシステムが悪い指示を入れたかを追いやすくなります。"
|
||||
"title": "claim と complete が作業を観測可能にする",
|
||||
"description": "claim_task は owner と in_progress を記録し、complete_task は完了を記録して解放された下流タスクを報告します。"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -2,45 +2,45 @@
|
||||
"version": "s11",
|
||||
"decisions": [
|
||||
{
|
||||
"id": "classified-recovery",
|
||||
"title": "Different Failures Need Different Recovery Paths",
|
||||
"description": "max_tokens, prompt_too_long, and provider overload mean different things. The runtime classifies the error before retrying.",
|
||||
"alternatives": "Blind retry is easy, but wastes time and can repeat a failure that needs compaction or token escalation.",
|
||||
"id": "explicit-background-boundary",
|
||||
"title": "Background Work Is an Execution Mode, Not a New Tool",
|
||||
"description": "The lesson keeps the familiar tool surface and adds a background execution flag around slow operations. That makes the new mechanism visible: the same bash call can either block the loop or be moved to a thread. The agent learns that responsiveness is a runtime concern, not a reason to invent a separate tool for every slow task.",
|
||||
"alternatives": "A dedicated background_bash tool would be simpler to route, but it would hide the more general idea that any slow operation can be scheduled asynchronously.",
|
||||
"zh": {
|
||||
"title": "不同失败需要不同恢复路径",
|
||||
"description": "max_tokens、prompt_too_long 和供应商过载含义不同。运行时会先分类错误,再决定如何重试。"
|
||||
"title": "后台任务是执行模式,而不是新工具",
|
||||
"description": "课程保留原有工具表面,只在慢操作外增加后台执行标记。这样能清楚看到:同一个 bash 调用既可以阻塞主循环,也可以放入线程。Agent 学到的是响应性属于运行时问题,而不是每个慢任务都要发明一个新工具。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "失敗ごとに異なる回復経路が必要",
|
||||
"description": "max_tokens、prompt_too_long、プロバイダ過負荷は意味が違います。ランタイムは再試行前にエラーを分類します。"
|
||||
"title": "バックグラウンド処理は新ツールではなく実行モード",
|
||||
"description": "このレッスンでは既存のツール面を保ち、遅い操作にバックグラウンド実行フラグを加えます。同じ bash 呼び出しがループをブロックすることも、スレッドへ移すこともできる点が見えます。応答性はランタイムの責務であり、遅いタスクごとに新しいツールを作る必要はありません。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "recovery-state",
|
||||
"title": "RecoveryState Prevents Infinite Retries",
|
||||
"description": "The runtime tracks token escalation, compact retries, consecutive 529s, and fallback model use. Recovery becomes bounded and inspectable.",
|
||||
"alternatives": "A while-retry loop can accidentally retry forever or hide which mitigation has already run.",
|
||||
"id": "notification-reentry",
|
||||
"title": "Completed Threads Re-enter as Notifications",
|
||||
"description": "Background results are injected as task notifications instead of pretending to be immediate tool results. This preserves the chronology of the conversation: the model first sees that work started, and later sees that a task completed.",
|
||||
"alternatives": "The thread could mutate the last tool result in place, but that would make the transcript impossible to reason about and hard to replay.",
|
||||
"zh": {
|
||||
"title": "RecoveryState 防止无限重试",
|
||||
"description": "运行时记录 token 升级、compact retry、连续 529、fallback model 等状态。恢复因此有边界、可检查。"
|
||||
"title": "线程完成后以通知形式回到循环",
|
||||
"description": "后台结果会作为任务通知注入,而不是伪装成立即返回的 tool result。这样保留了对话时间线:模型先看到任务已启动,之后再看到任务完成。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "RecoveryState が無限リトライを防ぐ",
|
||||
"description": "token 拡張、compact retry、連続 529、fallback model の利用を追跡します。回復処理に境界と可観測性を与えます。"
|
||||
"title": "完了したスレッドは通知として戻る",
|
||||
"description": "バックグラウンド結果は即時の tool result ではなくタスク通知として注入されます。モデルはまず作業開始を見て、その後に完了を知るため、会話の時系列が保たれます。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "no-fake-continuation",
|
||||
"title": "Do Not Fake User Messages During Token Recovery",
|
||||
"description": "The first max_tokens escalation retries without appending a synthetic user prompt. The transcript should reflect real events, not internal recovery tricks.",
|
||||
"alternatives": "Always appending 'continue' is tempting, but it pollutes conversation history and may change model behavior.",
|
||||
"id": "shared-result-store",
|
||||
"title": "A Small Shared Store Keeps Threads Observable",
|
||||
"description": "The implementation tracks background task state and results in explicit dictionaries. That keeps the code teachable while still exposing the hard parts of concurrency: ids, lifecycle state, and safe collection.",
|
||||
"alternatives": "A full queue or job database adds durability, but it would obscure the minimal moving parts needed to understand threaded agent work.",
|
||||
"zh": {
|
||||
"title": "Token 恢复时不伪造用户消息",
|
||||
"description": "第一次 max_tokens 升级会直接重试,不追加合成 user prompt。Transcript 应反映真实事件,而不是内部恢复技巧。"
|
||||
"title": "小型共享存储让线程可观察",
|
||||
"description": "实现用显式字典记录后台任务状态和结果。这样代码仍然易学,同时暴露并发中的关键问题:任务 id、生命周期状态和结果收集。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "トークン回復で偽のユーザーメッセージを入れない",
|
||||
"description": "最初の max_tokens 拡張では合成 user prompt を追加せず再試行します。transcript は内部の回復処理ではなく実際の出来事を反映すべきです。"
|
||||
"title": "小さな共有ストアでスレッドを観測可能にする",
|
||||
"description": "実装は辞書でバックグラウンドタスクの状態と結果を追跡します。コードを学びやすく保ちながら、id、ライフサイクル、安全な収集という並行処理の要点を示します。"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -2,45 +2,45 @@
|
||||
"version": "s12",
|
||||
"decisions": [
|
||||
{
|
||||
"id": "tasks-as-files",
|
||||
"title": "Tasks Are Durable JSON Files",
|
||||
"description": "Each task is persisted under .tasks/ with id, subject, description, status, owner, and blockedBy. The task board survives context compaction and process restarts.",
|
||||
"alternatives": "In-memory tasks are easier to code, but vanish exactly when long-running coordination needs them most.",
|
||||
"id": "scheduler-outside-agent-loop",
|
||||
"title": "The Scheduler Runs Outside the Agent Loop",
|
||||
"description": "Cron matching is handled by a daemon loop rather than by asking the LLM to remember future times. This separates timekeeping from reasoning and makes recurring work reliable even when no user is actively chatting.",
|
||||
"alternatives": "The agent could poll schedules inside each conversation turn, but missed turns would mean missed jobs.",
|
||||
"zh": {
|
||||
"title": "任务是持久 JSON 文件",
|
||||
"description": "每个任务都持久化在 .tasks/ 下,包含 id、subject、description、status、owner、blockedBy。任务板能跨上下文压缩和进程重启保留。"
|
||||
"title": "调度器运行在 Agent 循环之外",
|
||||
"description": "Cron 匹配由独立守护循环处理,而不是让 LLM 记住未来时间。这把计时和推理分开,使定期任务在没有用户对话时也能可靠触发。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "タスクは永続 JSON ファイル",
|
||||
"description": "各タスクは .tasks/ に id、subject、description、status、owner、blockedBy を持って保存されます。タスクボードはコンテキスト圧縮や再起動を越えて残ります。"
|
||||
"title": "スケジューラはエージェントループの外で動く",
|
||||
"description": "cron の照合は LLM に未来時刻を覚えさせるのではなく、デーモンループで処理します。時間管理と推論を分離し、ユーザーが会話していない時でも定期処理を確実にします。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "blockedby-dependencies",
|
||||
"title": "blockedBy Encodes Ordering",
|
||||
"description": "A task can only be claimed when all blockedBy dependencies are completed. Missing dependencies are treated as blocked to fail closed.",
|
||||
"alternatives": "Letting the model remember ordering is fragile and hard for teammates to share.",
|
||||
"id": "queue-decouples-time-from-work",
|
||||
"title": "A Queue Decouples Due Time from Execution",
|
||||
"description": "When a schedule matches, the scheduler enqueues work and lets a queue processor invoke the agent loop. That keeps cron matching fast and prevents long agent runs from blocking future schedule checks.",
|
||||
"alternatives": "The scheduler could call the agent directly, but a slow job would stall the scheduler itself.",
|
||||
"zh": {
|
||||
"title": "blockedBy 编码任务顺序",
|
||||
"description": "只有所有 blockedBy 依赖都完成时,任务才能被 claim。缺失依赖也被视为阻塞,采用 fail closed。"
|
||||
"title": "队列把到期判断和任务执行解耦",
|
||||
"description": "当 schedule 匹配时,调度器只把任务放入队列,由队列处理器调用 agent_loop。这样 cron 匹配保持快速,长时间运行的 agent 任务不会阻塞后续调度检查。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "blockedBy が順序を表現する",
|
||||
"description": "blockedBy の依存がすべて完了した時だけタスクを claim できます。存在しない依存もブロック扱いにして fail closed にします。"
|
||||
"title": "キューが期限判定と実行を分離する",
|
||||
"description": "スケジュールが一致すると、スケジューラは作業をキューへ入れ、キュープロセッサが agent_loop を呼び出します。cron 照合は速く保たれ、長いエージェント実行が次の確認を妨げません。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "claim-complete-lifecycle",
|
||||
"title": "Claim and Complete Make Work Observable",
|
||||
"description": "claim_task records an owner and in_progress state; complete_task marks completion and reports downstream tasks that became unblocked.",
|
||||
"alternatives": "A simple checklist can say done, but it cannot safely coordinate ownership or dependencies.",
|
||||
"id": "durable-schedules",
|
||||
"title": "Schedules Are Durable Data",
|
||||
"description": "Cron jobs are stored in a small JSON file so they survive process restarts. The lesson treats scheduled work as data that can be listed, cancelled, and inspected, not as hidden timers.",
|
||||
"alternatives": "In-memory timers are shorter to implement, but they disappear on restart and are difficult to audit.",
|
||||
"zh": {
|
||||
"title": "Claim 和 Complete 让工作可观察",
|
||||
"description": "claim_task 记录 owner 和 in_progress 状态;complete_task 标记完成,并报告被解锁的下游任务。"
|
||||
"title": "计划任务是持久数据",
|
||||
"description": "Cron job 存储在小型 JSON 文件中,因此进程重启后仍然存在。课程把计划任务视为可列出、可取消、可检查的数据,而不是隐藏的计时器。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "claim と complete が作業を観測可能にする",
|
||||
"description": "claim_task は owner と in_progress を記録し、complete_task は完了を記録して解放された下流タスクを報告します。"
|
||||
"title": "スケジュールは永続データ",
|
||||
"description": "cron ジョブは小さな JSON ファイルに保存され、プロセス再起動後も残ります。予定された作業を、一覧化、取り消し、検査できるデータとして扱います。"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -2,45 +2,101 @@
|
||||
"version": "s13",
|
||||
"decisions": [
|
||||
{
|
||||
"id": "explicit-background-boundary",
|
||||
"title": "Background Work Is an Execution Mode, Not a New Tool",
|
||||
"description": "The lesson keeps the familiar tool surface and adds a background execution flag around slow operations. That makes the new mechanism visible: the same bash call can either block the loop or be moved to a thread. The agent learns that responsiveness is a runtime concern, not a reason to invent a separate tool for every slow task.",
|
||||
"alternatives": "A dedicated background_bash tool would be simpler to route, but it would hide the more general idea that any slow operation can be scheduled asynchronously.",
|
||||
"id": "confirm-team-before-spawn",
|
||||
"title": "The User Confirms the Team Before It Starts",
|
||||
"description": "The Lead may notice that a request can be split, but it first proposes a small team with clear responsibilities. Teammates start only after the user confirms the extra agents.",
|
||||
"alternatives": "Spawning immediately saves one turn, but hides the cost and coordination choice from the user.",
|
||||
"zh": {
|
||||
"title": "后台任务是执行模式,而不是新工具",
|
||||
"description": "课程保留原有工具表面,只在慢操作外增加后台执行标记。这样能清楚看到:同一个 bash 调用既可以阻塞主循环,也可以放入线程。Agent 学到的是响应性属于运行时问题,而不是每个慢任务都要发明一个新工具。"
|
||||
"title": "启动团队前先征得用户确认",
|
||||
"description": "Lead 可以判断一个需求适合拆分,但要先提出职责清晰的小团队。只有用户确认后,运行时才启动额外的 Agent。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "バックグラウンド処理は新ツールではなく実行モード",
|
||||
"description": "このレッスンでは既存のツール面を保ち、遅い操作にバックグラウンド実行フラグを加えます。同じ bash 呼び出しがループをブロックすることも、スレッドへ移すこともできる点が見えます。応答性はランタイムの責務であり、遅いタスクごとに新しいツールを作る必要はありません。"
|
||||
"title": "チームを起動する前にユーザーが確認する",
|
||||
"description": "Lead は依頼を分割できると判断しても、まず役割が明確な小さなチームを提案する。追加 Agent はユーザーの確認後に起動する。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "notification-reentry",
|
||||
"title": "Completed Threads Re-enter as Notifications",
|
||||
"description": "Background results are injected as task notifications instead of pretending to be immediate tool results. This preserves the chronology of the conversation: the model first sees that work started, and later sees that a task completed.",
|
||||
"alternatives": "The thread could mutate the last tool result in place, but that would make the transcript impossible to reason about and hard to replay.",
|
||||
"id": "runtime-owned-delivery",
|
||||
"title": "Message Delivery Belongs to the Runtime",
|
||||
"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": "后台结果会作为任务通知注入,而不是伪装成立即返回的 tool result。这样保留了对话时间线:模型先看到任务已启动,之后再看到任务完成。"
|
||||
"title": "消息投递由运行时负责",
|
||||
"description": "MessageBus 持久化每次交接,运行时监听 Lead 邮箱,并把新的团队事件送入下一轮上下文。模型不需要浪费轮次轮询收件箱。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "完了したスレッドは通知として戻る",
|
||||
"description": "バックグラウンド結果は即時の tool result ではなくタスク通知として注入されます。モデルはまず作業開始を見て、その後に完了を知るため、会話の時系列が保たれます。"
|
||||
"title": "メッセージ配信はランタイムが担う",
|
||||
"description": "MessageBus が各ハンドオフを永続化し、ランタイムが Lead の受信箱を監視して新しい team event を次の turn に注入する。モデルは受信箱のポーリングに turn を費やさない。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "shared-result-store",
|
||||
"title": "A Small Shared Store Keeps Threads Observable",
|
||||
"description": "The implementation tracks background task state and results in explicit dictionaries. That keeps the code teachable while still exposing the hard parts of concurrency: ids, lifecycle state, and safe collection.",
|
||||
"alternatives": "A full queue or job database adds durability, but it would obscure the minimal moving parts needed to understand threaded agent work.",
|
||||
"id": "typed-request-correlation",
|
||||
"title": "Typed Requests Carry Correlation IDs",
|
||||
"description": "Plan and shutdown requests use explicit message types and request ids. Replies can arrive in any order and still update the correct pending request.",
|
||||
"alternatives": "Matching the latest free-form message works only until requests overlap.",
|
||||
"zh": {
|
||||
"title": "小型共享存储让线程可观察",
|
||||
"description": "实现用显式字典记录后台任务状态和结果。这样代码仍然易学,同时暴露并发中的关键问题:任务 id、生命周期状态和结果收集。"
|
||||
"title": "类型化请求携带关联 ID",
|
||||
"description": "计划和关机请求使用明确的消息类型与 request id。即使回复顺序不同,运行时也能更新正确的 pending request。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "小さな共有ストアでスレッドを観測可能にする",
|
||||
"description": "実装は辞書でバックグラウンドタスクの状態と結果を追跡します。コードを学びやすく保ちながら、id、ライフサイクル、安全な収集という並行処理の要点を示します。"
|
||||
"title": "型付きリクエストに対応 ID を持たせる",
|
||||
"description": "プランと終了の要求は明示的な message type と request id を使う。返信順が変わっても、正しい pending request を更新できる。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"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 rather than a conversational workaround.",
|
||||
"alternatives": "Treating approval as a suggestion cannot prevent an early write or shell command.",
|
||||
"zh": {
|
||||
"title": "计划审批是执行闸门",
|
||||
"description": "Lead 请求计划后,修改类工具会保持阻塞,直到对应计划通过。被拒绝的计划必须重新提交,不能靠对话绕过。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "プラン承認を実行ゲートにする",
|
||||
"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 ルート配下の既知パスだけを受け付け、状態を確認できない場合や変更が残る場合は明示的な破棄なしに拒否し、タスクを副作用で完了させない。"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -2,45 +2,45 @@
|
||||
"version": "s14",
|
||||
"decisions": [
|
||||
{
|
||||
"id": "scheduler-outside-agent-loop",
|
||||
"title": "The Scheduler Runs Outside the Agent Loop",
|
||||
"description": "Cron matching is handled by a daemon loop rather than by asking the LLM to remember future times. This separates timekeeping from reasoning and makes recurring work reliable even when no user is actively chatting.",
|
||||
"alternatives": "The agent could poll schedules inside each conversation turn, but missed turns would mean missed jobs.",
|
||||
"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": "调度器运行在 Agent 循环之外",
|
||||
"description": "Cron 匹配由独立守护循环处理,而不是让 LLM 记住未来时间。这把计时和推理分开,使定期任务在没有用户对话时也能可靠触发。"
|
||||
"title": "MCP 工具使用规范化命名空间",
|
||||
"description": "发现到的工具会暴露为 mcp__server__tool。前缀让工具来源明确,也避免和内置工具或其他服务器工具冲突。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "スケジューラはエージェントループの外で動く",
|
||||
"description": "cron の照合は LLM に未来時刻を覚えさせるのではなく、デーモンループで処理します。時間管理と推論を分離し、ユーザーが会話していない時でも定期処理を確実にします。"
|
||||
"title": "MCP ツールは正規化された名前空間を使う",
|
||||
"description": "発見されたツールは mcp__server__tool として公開されます。接頭辞により出所が明確になり、組み込みツールや別サーバーのツールとの衝突を避けます。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "queue-decouples-time-from-work",
|
||||
"title": "A Queue Decouples Due Time from Execution",
|
||||
"description": "When a schedule matches, the scheduler enqueues work and lets a queue processor invoke the agent loop. That keeps cron matching fast and prevents long agent runs from blocking future schedule checks.",
|
||||
"alternatives": "The scheduler could call the agent directly, but a slow job would stall the scheduler itself.",
|
||||
"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": "当 schedule 匹配时,调度器只把任务放入队列,由队列处理器调用 agent_loop。这样 cron 匹配保持快速,长时间运行的 agent 任务不会阻塞后续调度检查。"
|
||||
"title": "工具发现会更新活动工具池",
|
||||
"description": "连接服务器后,运行时会为下一次 LLM 调用组装新的工具池。模型只有在发现阶段让 MCP 工具可见之后,才能调用它们。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "キューが期限判定と実行を分離する",
|
||||
"description": "スケジュールが一致すると、スケジューラは作業をキューへ入れ、キュープロセッサが agent_loop を呼び出します。cron 照合は速く保たれ、長いエージェント実行が次の確認を妨げません。"
|
||||
"title": "ツール発見がアクティブなツールプールを更新する",
|
||||
"description": "サーバー接続後、ランタイムは次の LLM 呼び出し用に新しいツールプールを組み立てます。MCP ツールは発見で可視化された後にのみモデルが利用できます。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "durable-schedules",
|
||||
"title": "Schedules Are Durable Data",
|
||||
"description": "Cron jobs are stored in a small JSON file so they survive process restarts. The lesson treats scheduled work as data that can be listed, cancelled, and inspected, not as hidden timers.",
|
||||
"alternatives": "In-memory timers are shorter to implement, but they disappear on restart and are difficult to audit.",
|
||||
"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": "Cron job 存储在小型 JSON 文件中,因此进程重启后仍然存在。课程把计划任务视为可列出、可取消、可检查的数据,而不是隐藏的计时器。"
|
||||
"title": "外部结果复用 Tool Result 路径",
|
||||
"description": "MCP 响应会像普通 tool result 一样追加到对话中。这样 agent 循环无需改变,同时外部系统仍然可以参与。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "スケジュールは永続データ",
|
||||
"description": "cron ジョブは小さな JSON ファイルに保存され、プロセス再起動後も残ります。予定された作業を、一覧化、取り消し、検査できるデータとして扱います。"
|
||||
"title": "外部結果は tool result 経路を再利用する",
|
||||
"description": "MCP の応答は通常の tool result と同じように会話へ追加されます。エージェントループを変えずに外部システムを参加させられます。"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -2,101 +2,45 @@
|
||||
"version": "s15",
|
||||
"decisions": [
|
||||
{
|
||||
"id": "confirm-team-before-spawn",
|
||||
"title": "The User Confirms the Team Before It Starts",
|
||||
"description": "The Lead may notice that a request can be split, but it first proposes a small team with clear responsibilities. Teammates start only after the user confirms the extra agents.",
|
||||
"alternatives": "Spawning immediately saves one turn, but hides the cost and coordination choice from the user.",
|
||||
"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": "启动团队前先征得用户确认",
|
||||
"description": "Lead 可以判断一个需求适合拆分,但要先提出职责清晰的小团队。只有用户确认后,运行时才启动额外的 Agent。"
|
||||
"title": "Harness 组合既有层,而不是换掉循环",
|
||||
"description": "集成后的 Harness 没有用新架构替换循环,而是把 memory、task、skill、后台任务、团队、worktree、MCP 组合到同一个模型-工具-结果循环周围。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "チームを起動する前にユーザーが確認する",
|
||||
"description": "Lead は依頼を分割できると判断しても、まず役割が明確な小さなチームを提案する。追加 Agent はユーザーの確認後に起動する。"
|
||||
"title": "Harness は既存レイヤーを統合する",
|
||||
"description": "統合された Harness はループを新しい構造で置き換えません。memory、task、skill、バックグラウンド処理、チーム、worktree、MCP を同じ model-tool-result サイクルの周囲に合成します。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "runtime-owned-delivery",
|
||||
"title": "Message Delivery Belongs to the Runtime",
|
||||
"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.",
|
||||
"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": "消息投递由运行时负责",
|
||||
"description": "MessageBus 持久化每次交接,运行时监听 Lead 邮箱,并把新的团队事件送入下一轮上下文。模型不需要浪费轮次轮询收件箱。"
|
||||
"title": "运行时状态来自具名来源",
|
||||
"description": "上下文组装从 memory、task graph、skills、tool registry、policy 等具名来源读取。大型 agent 因此仍可调试,因为每块 prompt context 都有清晰归属。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "メッセージ配信はランタイムが担う",
|
||||
"description": "MessageBus が各ハンドオフを永続化し、ランタイムが Lead の受信箱を監視して新しい team event を次の turn に注入する。モデルは受信箱のポーリングに turn を費やさない。"
|
||||
"title": "ランタイム状態には名前付きの出所がある",
|
||||
"description": "コンテキスト組み立ては memory、task graph、skills、tool registry、policy などの名前付きソースから取得します。各 prompt context に所有者があるため、大きなエージェントでもデバッグ可能です。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "typed-request-correlation",
|
||||
"title": "Typed Requests Carry Correlation IDs",
|
||||
"description": "Plan and shutdown requests use explicit message types and request ids. Replies can arrive in any order and still update the correct pending request.",
|
||||
"alternatives": "Matching the latest free-form message works only until requests overlap.",
|
||||
"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": "类型化请求携带关联 ID",
|
||||
"description": "计划和关机请求使用明确的消息类型与 request id。即使回复顺序不同,运行时也能更新正确的 pending request。"
|
||||
"title": "恢复能力是一等流程",
|
||||
"description": "压缩、错误恢复和异步结果收集都属于正常循环。Harness 通过明确的路径处理恢复与续跑,而不是把逻辑散落在异常分支中。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "型付きリクエストに対応 ID を持たせる",
|
||||
"description": "プランと終了の要求は明示的な message type と request id を使う。返信順が変わっても、正しい pending request を更新できる。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"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 rather than a conversational workaround.",
|
||||
"alternatives": "Treating approval as a suggestion cannot prevent an early write or shell command.",
|
||||
"zh": {
|
||||
"title": "计划审批是执行闸门",
|
||||
"description": "Lead 请求计划后,修改类工具会保持阻塞,直到对应计划通过。被拒绝的计划必须重新提交,不能靠对话绕过。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "プラン承認を実行ゲートにする",
|
||||
"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 ルート配下の既知パスだけを受け付け、状態を確認できない場合や変更が残る場合は明示的な破棄なしに拒否し、タスクを副作用で完了させない。"
|
||||
"title": "リカバリは主要フローの一部",
|
||||
"description": "圧縮、エラー回復、非同期結果収集を通常のループ動作として扱います。Harness は回復と再開を名前付きの経路にまとめ、例外分岐へ散らしません。"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -2,45 +2,45 @@
|
||||
"version": "s16",
|
||||
"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 を失敗させ、項目を黙って落として成功扱いしない。"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -2,45 +2,45 @@
|
||||
"version": "s17",
|
||||
"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 を返します。"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
{
|
||||
"version": "s18",
|
||||
"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 を失敗させ、項目を黙って落として成功扱いしない。"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
{
|
||||
"version": "s19",
|
||||
"decisions": [
|
||||
{
|
||||
"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": "完成闸门由宿主持有",
|
||||
"description": "工作模型可以请求停止,但 GoalController 会在 AgentSession 返回前评估 active goal。这个闸门就在原有的轮次边界上。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "完了ゲートはホストが所有する",
|
||||
"description": "作業モデルは停止を要求できますが、GoalController は AgentSession が return する前に active goal を評価します。この gate は既存の turn 境界に置かれます。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"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": "判断器接收 active condition 和当前对话,其中也包括已经写入的工具结果。它自己没有工具,只能根据对话中已有的内容判断。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "conversation が evaluator の入力になる",
|
||||
"description": "evaluator は active condition と現在の conversation を受け取り、そこに記録された tool result も読みます。自身では tool を使えず、conversation にある内容だけで判断します。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"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": "目标未满足时,controller 把判断理由追加到 messages[],并在同一个循环里继续。Stop hook 的连续阻止上限或全局轮次上限会把控制权交还用户,同时让目标保持 active。"
|
||||
},
|
||||
"ja": {
|
||||
"title": "上限では control を返し、goal は維持する",
|
||||
"description": "goal が未達なら、controller は evaluator の理由を messages[] に追加し、同じ loop を続けます。Stop hook の連続 block 上限または global turn limit に達すると、goal を active のまま user に control を返します。"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -49,266 +49,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
|
||||
{ from: "append", to: "llm" },
|
||||
],
|
||||
},
|
||||
s03: {
|
||||
nodes: [
|
||||
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
|
||||
{ id: "todo", label: "Create Todos", type: "process", x: COL_CENTER, y: 100 },
|
||||
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 180 },
|
||||
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 260 },
|
||||
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT, y: 340 },
|
||||
{ id: "append", label: "Append Result", type: "process", x: COL_LEFT, y: 410 },
|
||||
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 340 },
|
||||
],
|
||||
edges: [
|
||||
{ from: "start", to: "todo" },
|
||||
{ from: "todo", to: "llm" },
|
||||
{ from: "llm", to: "tool_check" },
|
||||
{ from: "tool_check", to: "exec", label: "yes" },
|
||||
{ from: "tool_check", to: "end", label: "no" },
|
||||
{ from: "exec", to: "append" },
|
||||
{ from: "append", to: "llm" },
|
||||
],
|
||||
},
|
||||
s04: {
|
||||
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 },
|
||||
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 190 },
|
||||
{ id: "is_task", label: "task tool?", type: "decision", x: COL_LEFT, y: 280 },
|
||||
{ id: "spawn", label: "Spawn Subagent\n(fresh messages[])", type: "subprocess", x: 60, y: 380 },
|
||||
{ id: "sub_loop", label: "Subagent Loop", type: "process", x: 60, y: 460 },
|
||||
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT + 80, y: 380 },
|
||||
{ id: "append", label: "Append Result", type: "process", x: COL_CENTER, y: 540 },
|
||||
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 280 },
|
||||
],
|
||||
edges: [
|
||||
{ from: "start", to: "llm" },
|
||||
{ from: "llm", to: "tool_check" },
|
||||
{ from: "tool_check", to: "is_task", label: "yes" },
|
||||
{ from: "tool_check", to: "end", label: "no" },
|
||||
{ from: "is_task", to: "spawn", label: "task" },
|
||||
{ from: "is_task", to: "exec", label: "other" },
|
||||
{ from: "spawn", to: "sub_loop" },
|
||||
{ from: "sub_loop", to: "append" },
|
||||
{ from: "exec", to: "append" },
|
||||
{ from: "append", to: "llm" },
|
||||
],
|
||||
},
|
||||
s05: {
|
||||
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 },
|
||||
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 190 },
|
||||
{ id: "is_skill", label: "load_skill?", type: "decision", x: COL_LEFT, y: 280 },
|
||||
{ id: "load", label: "Read SKILL.md", type: "subprocess", x: 60, y: 370 },
|
||||
{ id: "inject", label: "Inject via\ntool_result", type: "process", x: 60, y: 450 },
|
||||
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT + 80, y: 370 },
|
||||
{ id: "append", label: "Append Result", type: "process", x: COL_CENTER, y: 530 },
|
||||
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 280 },
|
||||
],
|
||||
edges: [
|
||||
{ from: "start", to: "llm" },
|
||||
{ from: "llm", to: "tool_check" },
|
||||
{ from: "tool_check", to: "is_skill", label: "yes" },
|
||||
{ from: "tool_check", to: "end", label: "no" },
|
||||
{ from: "is_skill", to: "load", label: "skill" },
|
||||
{ from: "is_skill", to: "exec", label: "other" },
|
||||
{ from: "load", to: "inject" },
|
||||
{ from: "inject", to: "append" },
|
||||
{ from: "exec", to: "append" },
|
||||
{ from: "append", to: "llm" },
|
||||
],
|
||||
},
|
||||
s06: {
|
||||
nodes: [
|
||||
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
|
||||
{ id: "compress_check", label: "Over token\nlimit?", type: "decision", x: COL_CENTER, y: 110 },
|
||||
{ id: "compress", label: "Compress Context", type: "subprocess", x: COL_RIGHT, y: 110 },
|
||||
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 200 },
|
||||
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 280 },
|
||||
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT, y: 360 },
|
||||
{ id: "append", label: "Append Result", type: "process", x: COL_LEFT, y: 430 },
|
||||
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 360 },
|
||||
],
|
||||
edges: [
|
||||
{ from: "start", to: "compress_check" },
|
||||
{ from: "compress_check", to: "compress", label: "yes" },
|
||||
{ from: "compress_check", to: "llm", label: "no" },
|
||||
{ from: "compress", to: "llm" },
|
||||
{ from: "llm", to: "tool_check" },
|
||||
{ from: "tool_check", to: "exec", label: "yes" },
|
||||
{ from: "tool_check", to: "end", label: "no" },
|
||||
{ from: "exec", to: "append" },
|
||||
{ from: "append", to: "compress_check" },
|
||||
],
|
||||
},
|
||||
s07: {
|
||||
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 },
|
||||
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 190 },
|
||||
{ id: "is_task", label: "task_manager?", type: "decision", x: COL_LEFT, y: 280 },
|
||||
{ id: "crud", label: "CRUD Task\n(file-based)", type: "subprocess", x: 60, y: 370 },
|
||||
{ id: "dep_check", label: "Check\nDependencies", type: "process", x: 60, y: 450 },
|
||||
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT + 80, y: 370 },
|
||||
{ id: "append", label: "Append Result", type: "process", x: COL_CENTER, y: 530 },
|
||||
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 280 },
|
||||
],
|
||||
edges: [
|
||||
{ from: "start", to: "llm" },
|
||||
{ from: "llm", to: "tool_check" },
|
||||
{ from: "tool_check", to: "is_task", label: "yes" },
|
||||
{ from: "tool_check", to: "end", label: "no" },
|
||||
{ from: "is_task", to: "crud", label: "task" },
|
||||
{ from: "is_task", to: "exec", label: "other" },
|
||||
{ from: "crud", to: "dep_check" },
|
||||
{ from: "dep_check", to: "append" },
|
||||
{ from: "exec", to: "append" },
|
||||
{ from: "append", to: "llm" },
|
||||
],
|
||||
},
|
||||
s08: {
|
||||
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 },
|
||||
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 190 },
|
||||
{ id: "bg_check", label: "Background?", type: "decision", x: COL_LEFT, y: 280 },
|
||||
{ id: "bg_spawn", label: "Spawn Thread", type: "subprocess", x: 60, y: 370 },
|
||||
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT + 80, y: 370 },
|
||||
{ id: "append", label: "Append Result", type: "process", x: COL_CENTER, y: 450 },
|
||||
{ id: "notify", label: "Notification\nQueue", type: "process", x: 60, y: 450 },
|
||||
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 280 },
|
||||
],
|
||||
edges: [
|
||||
{ from: "start", to: "llm" },
|
||||
{ from: "llm", to: "tool_check" },
|
||||
{ from: "tool_check", to: "bg_check", label: "yes" },
|
||||
{ from: "tool_check", to: "end", label: "no" },
|
||||
{ from: "bg_check", to: "bg_spawn", label: "bg" },
|
||||
{ from: "bg_check", to: "exec", label: "fg" },
|
||||
{ from: "bg_spawn", to: "notify" },
|
||||
{ from: "exec", to: "append" },
|
||||
{ from: "append", to: "llm" },
|
||||
{ from: "notify", to: "llm" },
|
||||
],
|
||||
},
|
||||
s09: {
|
||||
nodes: [
|
||||
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
|
||||
{ id: "llm", label: "LLM Call\n(team lead)", type: "process", x: COL_CENTER, y: 110 },
|
||||
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 200 },
|
||||
{ id: "is_team", label: "Team tool?", type: "decision", x: COL_LEFT, y: 290 },
|
||||
{ id: "spawn", label: "Spawn\nTeammate", type: "subprocess", x: 60, y: 390 },
|
||||
{ id: "msg", label: "Send Message\n(JSONL inbox)", type: "subprocess", x: 60, y: 470 },
|
||||
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT + 80, y: 390 },
|
||||
{ id: "append", label: "Append Result", type: "process", x: COL_CENTER, y: 550 },
|
||||
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 290 },
|
||||
{ id: "teammate", label: "Teammate Agent\n(own loop)", type: "process", x: COL_RIGHT, y: 470 },
|
||||
],
|
||||
edges: [
|
||||
{ from: "start", to: "llm" },
|
||||
{ from: "llm", to: "tool_check" },
|
||||
{ from: "tool_check", to: "is_team", label: "yes" },
|
||||
{ from: "tool_check", to: "end", label: "no" },
|
||||
{ from: "is_team", to: "spawn", label: "spawn" },
|
||||
{ from: "is_team", to: "exec", label: "other" },
|
||||
{ from: "spawn", to: "teammate" },
|
||||
{ from: "spawn", to: "msg" },
|
||||
{ from: "msg", to: "append" },
|
||||
{ from: "exec", to: "append" },
|
||||
{ from: "append", to: "llm" },
|
||||
],
|
||||
},
|
||||
s10: {
|
||||
nodes: [
|
||||
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
|
||||
{ id: "llm", label: "LLM Call\n(team lead)", type: "process", x: COL_CENTER, y: 110 },
|
||||
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 200 },
|
||||
{ id: "is_proto", label: "Protocol?", type: "decision", x: COL_LEFT, y: 290 },
|
||||
{ id: "shutdown", label: "Shutdown\nRequest", type: "subprocess", x: 60, y: 390 },
|
||||
{ id: "fsm", label: "FSM:\npending->approved", type: "process", x: 60, y: 470 },
|
||||
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT + 80, y: 390 },
|
||||
{ id: "append", label: "Append Result", type: "process", x: COL_CENTER, y: 550 },
|
||||
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 290 },
|
||||
{ id: "teammate", label: "Teammate\nreceives request_id", type: "process", x: COL_RIGHT, y: 470 },
|
||||
],
|
||||
edges: [
|
||||
{ from: "start", to: "llm" },
|
||||
{ from: "llm", to: "tool_check" },
|
||||
{ from: "tool_check", to: "is_proto", label: "yes" },
|
||||
{ from: "tool_check", to: "end", label: "no" },
|
||||
{ from: "is_proto", to: "shutdown", label: "shutdown" },
|
||||
{ from: "is_proto", to: "exec", label: "other" },
|
||||
{ from: "shutdown", to: "fsm" },
|
||||
{ from: "fsm", to: "teammate" },
|
||||
{ from: "teammate", to: "append" },
|
||||
{ from: "exec", to: "append" },
|
||||
{ from: "append", to: "llm" },
|
||||
],
|
||||
},
|
||||
s11: {
|
||||
nodes: [
|
||||
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
|
||||
{ id: "inbox", label: "Check Inbox", type: "process", x: COL_CENTER, y: 100 },
|
||||
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 180 },
|
||||
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 260 },
|
||||
{ id: "exec", label: "Execute Tool", type: "subprocess", x: COL_LEFT, y: 340 },
|
||||
{ id: "append", label: "Append Result", type: "process", x: COL_LEFT, y: 410 },
|
||||
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 340 },
|
||||
{ id: "idle", label: "Idle Cycle", type: "process", x: COL_RIGHT, y: 420 },
|
||||
{ id: "poll", label: "Poll Tasks\n+ Auto-Claim", type: "subprocess", x: COL_RIGHT, y: 500 },
|
||||
],
|
||||
edges: [
|
||||
{ from: "start", to: "inbox" },
|
||||
{ from: "inbox", to: "llm" },
|
||||
{ from: "llm", to: "tool_check" },
|
||||
{ from: "tool_check", to: "exec", label: "yes" },
|
||||
{ from: "tool_check", to: "end", label: "no" },
|
||||
{ from: "exec", to: "append" },
|
||||
{ from: "append", to: "llm" },
|
||||
{ from: "end", to: "idle" },
|
||||
{ from: "idle", to: "poll" },
|
||||
{ from: "poll", to: "inbox" },
|
||||
],
|
||||
},
|
||||
s12: {
|
||||
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 },
|
||||
{ id: "tool_check", label: "tool_use?", type: "decision", x: COL_CENTER, y: 190 },
|
||||
{ id: "is_wt", label: "worktree tool?", type: "decision", x: COL_LEFT, y: 280 },
|
||||
{ id: "task", label: "Task Board\\n(.tasks)", type: "process", x: 60, y: 360 },
|
||||
{ id: "wt_create", label: "Allocate / Enter\\nWorktree", type: "subprocess", x: 60, y: 440 },
|
||||
{ id: "wt_run", label: "Run in\\nIsolated Dir", type: "subprocess", x: COL_LEFT + 80, y: 360 },
|
||||
{ id: "wt_close", label: "Closeout:\\nworktree_keep / remove", type: "process", x: COL_LEFT + 80, y: 440 },
|
||||
{ id: "events", label: "Emit Lifecycle Events\\n(side-channel)", type: "process", x: COL_RIGHT, y: 420 },
|
||||
{ id: "events_read", label: "Optional Read\\nworktree_events", type: "subprocess", x: COL_RIGHT, y: 520 },
|
||||
{ id: "append", label: "Append Result", type: "process", x: COL_CENTER, y: 530 },
|
||||
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 280 },
|
||||
],
|
||||
edges: [
|
||||
{ from: "start", to: "llm" },
|
||||
{ from: "llm", to: "tool_check" },
|
||||
{ from: "tool_check", to: "is_wt", label: "yes" },
|
||||
{ from: "tool_check", to: "end", label: "no" },
|
||||
{ from: "is_wt", to: "task", label: "task ops" },
|
||||
{ from: "is_wt", to: "wt_create", label: "create/bind" },
|
||||
{ from: "is_wt", to: "wt_run", label: "run/status" },
|
||||
{ from: "task", to: "wt_create", label: "allocate lane" },
|
||||
{ from: "wt_create", to: "wt_run" },
|
||||
{ from: "task", to: "append", label: "task result" },
|
||||
{ from: "wt_create", to: "events", label: "emit create" },
|
||||
{ from: "wt_create", to: "append", label: "create result" },
|
||||
{ from: "wt_run", to: "wt_close" },
|
||||
{ from: "wt_run", to: "append", label: "run/status result" },
|
||||
{ from: "wt_close", to: "events", label: "emit closeout" },
|
||||
{ from: "wt_close", to: "append", label: "closeout result" },
|
||||
{ from: "events", to: "events_read", label: "optional query" },
|
||||
{ from: "events_read", to: "append", label: "events result" },
|
||||
{ from: "append", to: "llm" },
|
||||
],
|
||||
},
|
||||
s13: {
|
||||
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 },
|
||||
@@ -338,7 +79,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
|
||||
{ from: "append", to: "llm" },
|
||||
],
|
||||
},
|
||||
s14: {
|
||||
s12: {
|
||||
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 },
|
||||
@@ -366,7 +107,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
|
||||
{ from: "agent", to: "llm" },
|
||||
],
|
||||
},
|
||||
s15: {
|
||||
s13: {
|
||||
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 },
|
||||
@@ -401,7 +142,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
|
||||
{ from: "bus", to: "lead", label: "runtime delivery" },
|
||||
],
|
||||
},
|
||||
s16: {
|
||||
s14: {
|
||||
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 },
|
||||
@@ -428,7 +169,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
|
||||
{ from: "append", to: "llm" },
|
||||
],
|
||||
},
|
||||
s17: {
|
||||
s15: {
|
||||
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 },
|
||||
@@ -462,7 +203,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
|
||||
{ from: "recover", to: "context" },
|
||||
],
|
||||
},
|
||||
s18: {
|
||||
s16: {
|
||||
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 },
|
||||
@@ -486,7 +227,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
|
||||
{ from: "output", to: "notify" },
|
||||
],
|
||||
},
|
||||
s19: {
|
||||
s17: {
|
||||
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 },
|
||||
@@ -697,58 +438,6 @@ const CURRENT_FLOW_OVERRIDES: Record<string, FlowDefinition> = {
|
||||
],
|
||||
},
|
||||
s10: {
|
||||
nodes: [
|
||||
{ id: "start", label: "Runtime State", type: "start", x: COL_CENTER, y: 30 },
|
||||
{ id: "sections", label: "PROMPT_SECTIONS", type: "process", x: COL_CENTER, y: 120 },
|
||||
{ id: "context", label: "Build Context\nmemory/tools/workspace", type: "process", x: COL_CENTER, y: 220 },
|
||||
{ id: "cache", label: "Cache Hit?", type: "decision", x: COL_CENTER, y: 320 },
|
||||
{ id: "reuse", label: "Reuse Prompt", type: "process", x: COL_RIGHT, y: 420 },
|
||||
{ id: "assemble", label: "Assemble Prompt", type: "subprocess", x: COL_LEFT, y: 420 },
|
||||
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 540 },
|
||||
{ id: "loop", label: "Tool Loop", type: "subprocess", x: COL_CENTER, y: 640 },
|
||||
],
|
||||
edges: [
|
||||
{ from: "start", to: "sections" },
|
||||
{ from: "sections", to: "context" },
|
||||
{ from: "context", to: "cache" },
|
||||
{ from: "cache", to: "reuse", label: "yes" },
|
||||
{ from: "cache", to: "assemble", label: "no" },
|
||||
{ from: "reuse", to: "llm" },
|
||||
{ from: "assemble", to: "llm" },
|
||||
{ from: "llm", to: "loop" },
|
||||
{ from: "loop", to: "context" },
|
||||
],
|
||||
},
|
||||
s11: {
|
||||
nodes: [
|
||||
{ id: "start", label: "LLM Request", type: "start", x: COL_CENTER, y: 30 },
|
||||
{ id: "try", label: "try LLM Call", type: "process", x: COL_CENTER, y: 120 },
|
||||
{ id: "ok", label: "success?", type: "decision", x: COL_CENTER, y: 220 },
|
||||
{ id: "tools", label: "Execute Tools", type: "process", x: COL_RIGHT, y: 330 },
|
||||
{ id: "classify", label: "Classify Error", type: "decision", x: COL_LEFT, y: 330 },
|
||||
{ id: "tokens", label: "max_tokens\nEscalate", type: "subprocess", x: 40, y: 440 },
|
||||
{ id: "prompt", label: "prompt_too_long\nCompact", type: "subprocess", x: COL_LEFT, y: 610 },
|
||||
{ id: "backoff", label: "429 / 529\nBackoff", type: "subprocess", x: COL_LEFT + 140, y: 440 },
|
||||
{ id: "fallback", label: "Fallback Model", type: "process", x: COL_RIGHT, y: 540 },
|
||||
{ id: "retry", label: "Retry Request", type: "process", x: COL_CENTER, y: 740 },
|
||||
],
|
||||
edges: [
|
||||
{ from: "start", to: "try" },
|
||||
{ from: "try", to: "ok" },
|
||||
{ from: "ok", to: "tools", label: "yes" },
|
||||
{ from: "ok", to: "classify", label: "error" },
|
||||
{ from: "classify", to: "tokens", label: "max_tokens" },
|
||||
{ from: "classify", to: "prompt", label: "too long" },
|
||||
{ from: "classify", to: "backoff", label: "429/529" },
|
||||
{ from: "backoff", to: "fallback", label: "repeated 529" },
|
||||
{ from: "tokens", to: "retry" },
|
||||
{ from: "prompt", to: "retry" },
|
||||
{ from: "backoff", to: "retry" },
|
||||
{ from: "fallback", to: "retry" },
|
||||
{ from: "retry", to: "try" },
|
||||
],
|
||||
},
|
||||
s12: {
|
||||
nodes: [
|
||||
{ id: "start", label: "User Goal", type: "start", x: COL_CENTER, y: 30 },
|
||||
{ id: "create", label: "create_task", type: "subprocess", x: COL_CENTER, y: 120 },
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,27 +1,48 @@
|
||||
{
|
||||
"version": "s10",
|
||||
"title": "Context Assembly",
|
||||
"description": "Stable instructions and dynamic runtime state are assembled at the model boundary and cached by a deterministic context key.",
|
||||
"title": "Task System",
|
||||
"description": "A file-persisted task graph tracks status, ownership, and blockedBy dependencies.",
|
||||
"steps": [
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "context={workspace:\"/repo\", memories:true, skills:[\"code-review\"], tools:[\"bash\",\"read_file\"]}",
|
||||
"annotation": "Prompt inputs are explicit runtime data."
|
||||
"type": "user_message",
|
||||
"content": "Break the release into tasks and block deployment until tests pass.",
|
||||
"annotation": "The user asks for durable multi-step coordination."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "cache miss -> assemble_system_prompt(context)",
|
||||
"annotation": "A new context key causes sections to be selected and joined."
|
||||
"type": "tool_call",
|
||||
"toolName": "create_task",
|
||||
"content": "{\"subject\":\"Run tests\"}",
|
||||
"annotation": "Tasks are created as JSON files under .tasks/."
|
||||
},
|
||||
{
|
||||
"type": "assistant_text",
|
||||
"content": "I can use the workspace, memory index, tool guidance, and available skills for this task.",
|
||||
"annotation": "The LLM sees the assembled prompt, not a hardcoded static string."
|
||||
"type": "tool_call",
|
||||
"toolName": "create_task",
|
||||
"content": "{\"subject\":\"Deploy release\",\"blockedBy\":[\"task_tests\"]}",
|
||||
"annotation": "blockedBy encodes dependency ordering."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "same context key -> reuse cached prompt",
|
||||
"annotation": "Repeated turns avoid rebuilding identical prompt text."
|
||||
"type": "tool_call",
|
||||
"toolName": "claim_task",
|
||||
"content": "{\"task_id\":\"task_deploy\",\"owner\":\"agent\"}",
|
||||
"annotation": "The claim fails until dependencies are complete."
|
||||
},
|
||||
{
|
||||
"type": "tool_result",
|
||||
"toolName": "claim_task",
|
||||
"content": "Blocked by: [\"task_tests\"]",
|
||||
"annotation": "The task graph prevents premature work."
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
"toolName": "complete_task",
|
||||
"content": "{\"task_id\":\"task_tests\"}",
|
||||
"annotation": "Completing a dependency can unblock downstream tasks."
|
||||
},
|
||||
{
|
||||
"type": "tool_result",
|
||||
"toolName": "complete_task",
|
||||
"content": "Completed task_tests\nUnblocked: Deploy release",
|
||||
"annotation": "The harness reports newly available work."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,33 +1,45 @@
|
||||
{
|
||||
"version": "s11",
|
||||
"title": "Error Recovery",
|
||||
"description": "LLM calls are wrapped with targeted recovery paths for token limits, prompt overflow, and transient provider errors.",
|
||||
"title": "Background Tasks",
|
||||
"description": "Long-running work moves to a thread while the agent keeps the main loop responsive.",
|
||||
"steps": [
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "try LLM call with max_tokens=8000",
|
||||
"annotation": "The normal path is still a regular model call."
|
||||
"type": "user_message",
|
||||
"content": "Run a long repository scan and tell me when it finishes.",
|
||||
"annotation": "The user asks for work that may exceed the normal foreground loop."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "error=max_tokens -> escalate to 64000 without appending a fake user message",
|
||||
"annotation": "Token exhaustion gets a continuation-aware recovery path."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "error=prompt_too_long -> reactive_compact(messages) -> retry once",
|
||||
"annotation": "Prompt overflow triggers compaction instead of blind retry."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "error=529 -> exponential backoff with jitter; repeated 529 -> fallback model",
|
||||
"annotation": "Transient provider errors use backoff and model fallback."
|
||||
"type": "assistant_text",
|
||||
"content": "I'll start the scan in the background so we can keep the conversation responsive.",
|
||||
"annotation": "The model chooses the background path instead of blocking on the tool result."
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
"toolName": "read_file",
|
||||
"content": "{\"path\":\"README.md\"}",
|
||||
"annotation": "After recovery succeeds, the agent continues the normal tool loop."
|
||||
"toolName": "bash",
|
||||
"content": "rg \"TODO|FIXME\" .",
|
||||
"toolInput": "{\"background\":true}",
|
||||
"annotation": "The tool call is wrapped with a background flag."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "background_tasks[task_42] = Thread(target=run_bash)",
|
||||
"annotation": "The runtime starts a thread and returns immediately."
|
||||
},
|
||||
{
|
||||
"type": "tool_result",
|
||||
"toolName": "bash",
|
||||
"content": "Started background task task_42.",
|
||||
"annotation": "A placeholder result is appended to the main conversation."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "<task_notification id=\"task_42\" status=\"done\">Found 12 matches.</task_notification>",
|
||||
"annotation": "The completed thread injects a notification back into the next loop."
|
||||
},
|
||||
{
|
||||
"type": "assistant_text",
|
||||
"content": "The scan finished with 12 matches. I'll summarize the most important ones now.",
|
||||
"annotation": "The agent consumes the background result as fresh context."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,48 +1,44 @@
|
||||
{
|
||||
"version": "s12",
|
||||
"title": "Task System",
|
||||
"description": "A file-persisted task graph tracks status, ownership, and blockedBy dependencies.",
|
||||
"title": "Cron Scheduler",
|
||||
"description": "A daemon loop watches durable cron definitions, queues due jobs, and lets the agent process them.",
|
||||
"steps": [
|
||||
{
|
||||
"type": "user_message",
|
||||
"content": "Break the release into tasks and block deployment until tests pass.",
|
||||
"annotation": "The user asks for durable multi-step coordination."
|
||||
"content": "Every weekday morning, remind me to review open tasks.",
|
||||
"annotation": "The user asks for a recurring future action."
|
||||
},
|
||||
{
|
||||
"type": "assistant_text",
|
||||
"content": "I'll create a cron job and store it so the scheduler can pick it up later.",
|
||||
"annotation": "The agent delegates recurrence to the scheduler instead of relying on current context."
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
"toolName": "create_task",
|
||||
"content": "{\"subject\":\"Run tests\"}",
|
||||
"annotation": "Tasks are created as JSON files under .tasks/."
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
"toolName": "create_task",
|
||||
"content": "{\"subject\":\"Deploy release\",\"blockedBy\":[\"task_tests\"]}",
|
||||
"annotation": "blockedBy encodes dependency ordering."
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
"toolName": "claim_task",
|
||||
"content": "{\"task_id\":\"task_deploy\",\"owner\":\"agent\"}",
|
||||
"annotation": "The claim fails until dependencies are complete."
|
||||
"toolName": "schedule_cron",
|
||||
"content": "{\"name\":\"review-open-tasks\",\"cron\":\"0 9 * * 1-5\",\"prompt\":\"Review open tasks and summarize blockers.\"}",
|
||||
"annotation": "The new tool validates and persists a cron definition."
|
||||
},
|
||||
{
|
||||
"type": "tool_result",
|
||||
"toolName": "claim_task",
|
||||
"content": "Blocked by: [\"task_tests\"]",
|
||||
"annotation": "The task graph prevents premature work."
|
||||
"toolName": "schedule_cron",
|
||||
"content": "Scheduled review-open-tasks with id cron_7.",
|
||||
"annotation": "The job is written to the durable schedule store."
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
"toolName": "complete_task",
|
||||
"content": "{\"task_id\":\"task_tests\"}",
|
||||
"annotation": "Completing a dependency can unblock downstream tasks."
|
||||
"type": "system_event",
|
||||
"content": "cron_scheduler_loop: cron_7 matched current minute -> cron_queue.put(cron_7)",
|
||||
"annotation": "The independent scheduler daemon detects that the job is due."
|
||||
},
|
||||
{
|
||||
"type": "tool_result",
|
||||
"toolName": "complete_task",
|
||||
"content": "Completed task_tests\nUnblocked: Deploy release",
|
||||
"annotation": "The harness reports newly available work."
|
||||
"type": "system_event",
|
||||
"content": "queue_processor_loop: dequeued cron_7 and invoked agent_loop(prompt)",
|
||||
"annotation": "A separate processor turns due jobs into normal agent work."
|
||||
},
|
||||
{
|
||||
"type": "assistant_text",
|
||||
"content": "Scheduled. When the cron fires, the queue processor will run the reminder prompt through the agent loop.",
|
||||
"annotation": "The final answer explains the durable recurring behavior."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,45 +1,122 @@
|
||||
{
|
||||
"version": "s13",
|
||||
"title": "Background Tasks",
|
||||
"description": "Long-running work moves to a thread while the agent keeps the main loop responsive.",
|
||||
"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": "Run a long repository scan and tell me when it finishes.",
|
||||
"annotation": "The user asks for work that may exceed the normal foreground loop."
|
||||
"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": "I'll start the scan in the background so we can keep the conversation responsive.",
|
||||
"annotation": "The model chooses the background path instead of blocking on the tool result."
|
||||
"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": "The team starts only after explicit confirmation."
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
"toolName": "bash",
|
||||
"content": "rg \"TODO|FIXME\" .",
|
||||
"toolInput": "{\"background\":true}",
|
||||
"annotation": "The tool call is wrapped with a background flag."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "background_tasks[task_42] = Thread(target=run_bash)",
|
||||
"annotation": "The runtime starts a thread and returns immediately."
|
||||
"toolName": "create_task",
|
||||
"content": "{\"subject\":\"Refactor authentication\"}",
|
||||
"annotation": "The shared task board remains the source of ownership and status."
|
||||
},
|
||||
{
|
||||
"type": "tool_result",
|
||||
"toolName": "bash",
|
||||
"content": "Started background task task_42.",
|
||||
"annotation": "A placeholder result is appended to the main conversation."
|
||||
"toolName": "create_task",
|
||||
"content": "Created task_1a2b3c4d: 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_1a2b3c4d\"}",
|
||||
"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_1a2b3c4d\"]}",
|
||||
"annotation": "The task graph keeps dependent work from starting early."
|
||||
},
|
||||
{
|
||||
"type": "tool_result",
|
||||
"toolName": "create_task",
|
||||
"content": "Created task_5e6f7a8b: Update authentication tests (blockedBy: task_1a2b3c4d)",
|
||||
"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\":\"Review the assigned authentication task and propose a plan.\",\"task_id\":\"task_1a2b3c4d\",\"require_plan\":true}",
|
||||
"annotation": "The runtime claims the initial task and activates the plan gate before the teammate thread starts."
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
"toolName": "spawn_teammate",
|
||||
"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": "<task_notification id=\"task_42\" status=\"done\">Found 12 matches.</task_notification>",
|
||||
"annotation": "The completed thread injects a notification back into the next loop."
|
||||
"content": "spawn_teammate(backend, task_1a2b3c4d) -> task_store_lock commits owner=backend before thread start",
|
||||
"annotation": "The ownership check and persisted state transition share the cross-process task-store lock."
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
"toolName": "request_plan",
|
||||
"content": "{\"teammate\":\"backend\",\"task\":\"Inspect the claimed authentication task and submit a plan before changing files.\"}",
|
||||
"annotation": "The Lead delivers the plan request for the current assignment; the gate was already active before the teammate thread started."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "backend submit_plan -> plan_approval_request(request_id=req_000007, task_id=task_1a2b3c4d)",
|
||||
"annotation": "The request records the task and work version that the plan is meant to authorize."
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
"toolName": "review_plan",
|
||||
"content": "{\"request_id\":\"req_000007\",\"approve\":true,\"feedback\":\"Proceed with the scoped refactor.\"}",
|
||||
"annotation": "Approval is correlated by request ID and cannot carry into a different assignment."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "plan_approval_response(request_id=req_000007, approve=true) -> backend",
|
||||
"annotation": "The teammate receives the typed response before mutating tools are released."
|
||||
},
|
||||
{
|
||||
"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_1a2b3c4d\"}",
|
||||
"annotation": "Completing the first task makes its dependent test task ready."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "backend -> Lead: result(auth refactor complete) -> idle_notification",
|
||||
"annotation": "The task directory stays selected through the completion turn, then IDLE releases the assignment."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "claim_next_task(tests) -> task_5e6f7a8b; task_store_lock commits owner=tests",
|
||||
"annotation": "An idle teammate discovers newly ready work without another direct assignment."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"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": "The scan finished with 12 matches. I'll summarize the most important ones now.",
|
||||
"annotation": "The agent consumes the background result as fresh context."
|
||||
"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."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,44 +1,46 @@
|
||||
{
|
||||
"version": "s14",
|
||||
"title": "Cron Scheduler",
|
||||
"description": "A daemon loop watches durable cron definitions, queues due jobs, and lets the agent process them.",
|
||||
"title": "MCP Tools",
|
||||
"description": "The agent discovers external MCP tools and exposes them through a normalized tool namespace.",
|
||||
"steps": [
|
||||
{
|
||||
"type": "user_message",
|
||||
"content": "Every weekday morning, remind me to review open tasks.",
|
||||
"annotation": "The user asks for a recurring future action."
|
||||
},
|
||||
{
|
||||
"type": "assistant_text",
|
||||
"content": "I'll create a cron job and store it so the scheduler can pick it up later.",
|
||||
"annotation": "The agent delegates recurrence to the scheduler instead of relying on current context."
|
||||
"content": "Search the documentation for deployment guidance.",
|
||||
"annotation": "The user asks for a tool source outside the built-in set."
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
"toolName": "schedule_cron",
|
||||
"content": "{\"name\":\"review-open-tasks\",\"cron\":\"0 9 * * 1-5\",\"prompt\":\"Review open tasks and summarize blockers.\"}",
|
||||
"annotation": "The new tool validates and persists a cron definition."
|
||||
"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": "schedule_cron",
|
||||
"content": "Scheduled review-open-tasks with id cron_7.",
|
||||
"annotation": "The job is written to the durable schedule store."
|
||||
"toolName": "connect_mcp",
|
||||
"content": "Connected to MCP server 'docs'. Discovered 2 tools: search, get_version",
|
||||
"annotation": "Tool discovery expands the active tool pool."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "cron_scheduler_loop: cron_7 matched current minute -> cron_queue.put(cron_7)",
|
||||
"annotation": "The independent scheduler daemon detects that the job is due."
|
||||
"type": "tool_call",
|
||||
"toolName": "mcp__docs__search",
|
||||
"content": "{\"query\":\"deployment\"}",
|
||||
"annotation": "The LLM can now call the discovered tool by its normalized name."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "queue_processor_loop: dequeued cron_7 and invoked agent_loop(prompt)",
|
||||
"annotation": "A separate processor turns due jobs into normal agent work."
|
||||
"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": "assistant_text",
|
||||
"content": "Scheduled. When the cron fires, the queue processor will run the reminder prompt through the agent loop.",
|
||||
"annotation": "The final answer explains the durable recurring behavior."
|
||||
"content": "The docs server found three matches for deployment guidance.",
|
||||
"annotation": "The agent summarizes external tool output for the user."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,122 +1,102 @@
|
||||
{
|
||||
"version": "s15",
|
||||
"title": "Agent Team Runtime",
|
||||
"description": "The Lead coordinates persistent teammates while the runtime owns message delivery, atomic task claims, and task-bound worktree directories.",
|
||||
"title": "Integrated Harness",
|
||||
"description": "The harness combines system instructions, tools, memory, teams, background work, cron, worktrees, and MCP.",
|
||||
"steps": [
|
||||
{
|
||||
"type": "user_message",
|
||||
"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."
|
||||
"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 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."
|
||||
"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, go ahead.",
|
||||
"annotation": "The team starts only after explicit confirmation."
|
||||
"content": "Yes. Start the docs teammate and continue.",
|
||||
"annotation": "User confirmation opens the team boundary inherited from S13."
|
||||
},
|
||||
{
|
||||
"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\":\"Refactor authentication\"}",
|
||||
"annotation": "The shared task board remains the source of ownership and status."
|
||||
"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: Refactor authentication",
|
||||
"annotation": "The runtime-generated task ID is carried into every later operation on this 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": "{\"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."
|
||||
"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_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."
|
||||
"toolName": "create_worktree",
|
||||
"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": "spawn_teammate",
|
||||
"content": "{\"name\":\"backend\",\"role\":\"backend engineer\",\"prompt\":\"Claim the authentication task and propose a plan.\",\"require_plan\":true}",
|
||||
"annotation": "The plan gate is active before the teammate thread starts, so claim and mutation cannot race ahead of approval."
|
||||
"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": "spawn_teammate",
|
||||
"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."
|
||||
"toolName": "bash",
|
||||
"content": "{\"command\":\"python -m unittest tests.test_agent_teams_runtime\",\"run_in_background\":true}",
|
||||
"annotation": "Long-running validation goes through the background task path."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "claim_next_task(backend) -> task_1712345678_0042; task_store_lock commits owner=backend",
|
||||
"annotation": "The ownership check and persisted state transition share the cross-process task-store lock."
|
||||
"content": "permission: user approved the exact test command",
|
||||
"annotation": "Team confirmation does not authorize shell execution; the foreground turn asks separately before dispatch."
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
"toolName": "request_plan",
|
||||
"content": "{\"teammate\":\"backend\",\"task\":\"Inspect the claimed authentication task and submit a plan before changing files.\"}",
|
||||
"annotation": "The Lead delivers the plan request for the current assignment; the gate was already active before the teammate thread started."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "backend submit_plan -> plan_approval_request(request_id=req_000007, task_id=task_1712345678_0042)",
|
||||
"annotation": "The request records the task and work version that the plan is meant to authorize."
|
||||
"toolName": "connect_mcp",
|
||||
"content": "{\"name\":\"deploy\"}",
|
||||
"annotation": "External capabilities are added only when needed."
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
"toolName": "review_plan",
|
||||
"content": "{\"request_id\":\"req_000007\",\"approve\":true,\"feedback\":\"Proceed with the scoped refactor.\"}",
|
||||
"annotation": "Approval is correlated by request ID and cannot carry into a different assignment."
|
||||
"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": "plan_approval_response(request_id=req_000007, approve=true) -> backend",
|
||||
"annotation": "The teammate receives the typed response before mutating tools are released."
|
||||
},
|
||||
{
|
||||
"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": "The task directory stays selected through the completion turn, then IDLE releases the assignment."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"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": "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."
|
||||
"content": "task_notification(status=completed): tests passed; teammate result and deploy status appended",
|
||||
"annotation": "The integrated runtime folds asynchronous results back into the loop."
|
||||
},
|
||||
{
|
||||
"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."
|
||||
"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."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,46 +1,54 @@
|
||||
{
|
||||
"version": "s16",
|
||||
"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 load_user 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": "{\"name\":\"docs\"}",
|
||||
"annotation": "The runtime creates an MCP client for the named server."
|
||||
"toolName": "Workflow",
|
||||
"content": "{\"name\":\"review-changes\",\"args\":{\"budget\":null,\"changes\":\"def load_user(user_id):\\n query = f\\\"SELECT * FROM users WHERE id = {user_id}\\\"\\n return db.execute(query).fetchone()\\n\"}}",
|
||||
"annotation": "The model selects a saved workflow and arguments; the host registry supplies its trusted metadata and script."
|
||||
},
|
||||
{
|
||||
"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_0000000000001a7b) -> 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_0000000000001a7b.output.json)",
|
||||
"annotation": "The task emits its final lifecycle event after output is written."
|
||||
},
|
||||
{
|
||||
"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."
|
||||
"toolName": "Workflow",
|
||||
"content": "{\"launched\":{\"status\":\"async_launched\",\"taskId\":\"local_workflow_wf_review-changes_0000000000001a7b\",\"taskType\":\"local_workflow\",\"runId\":\"wf_review-changes_0000000000001a7b\",\"workflowName\":\"review-changes\"},\"result\":{\"confirmed\":[{\"dimension\":\"performance\",\"title\":\"audit:performance #1\",\"severity\":\"medium\"},{\"dimension\":\"performance\",\"title\":\"audit:performance #2\",\"severity\":\"medium\"},{\"dimension\":\"style\",\"title\":\"audit:style #1\",\"severity\":\"medium\"},{\"dimension\":\"style\",\"title\":\"audit:style #2\",\"severity\":\"medium\"},{\"dimension\":\"security\",\"title\":\"audit:security #1\",\"severity\":\"low\"},{\"dimension\":\"security\",\"title\":\"audit:security #2\",\"severity\":\"low\"}]},\"task\":{\"taskId\":\"local_workflow_wf_review-changes_0000000000001a7b\",\"taskType\":\"local_workflow\",\"runId\":\"wf_review-changes_0000000000001a7b\",\"workflowName\":\"review-changes\",\"status\":\"completed\",\"usage\":{\"agents\":11,\"tokens\":883},\"progress\":[{\"type\":\"workflow_phase\",\"title\":\"Review\"},{\"type\":\"workflow_agent\",\"label\":\"audit:correctness\",\"phase\":\"Review\",\"status\":\"done\"},{\"type\":\"workflow_phase\",\"title\":\"Verify\"},{\"type\":\"workflow_agent\",\"label\":\"audit:security\",\"phase\":\"Review\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"audit:performance\",\"phase\":\"Review\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"audit:style\",\"phase\":\"Review\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:correctness:audit:correctness #1\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:security:audit:security #1\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:security:audit:security #2\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:performance:audit:performance #1\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:performance:audit:performance #2\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:style:audit:style #1\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:style:audit:style #2\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_log\",\"message\":\"confirmed 6 real finding(s)\"}]}}",
|
||||
"annotation": "The demo fixture returns six synthetic findings and measured runner usage; these are not claims about the repository."
|
||||
},
|
||||
{
|
||||
"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": "[docs] Found 3 results for 'deployment'",
|
||||
"annotation": "The external result is appended like any other tool result."
|
||||
},
|
||||
{
|
||||
"type": "assistant_text",
|
||||
"content": "The docs server found three matches for deployment guidance.",
|
||||
"annotation": "The agent summarizes external tool output for the user."
|
||||
"type": "system_event",
|
||||
"content": "append Workflow tool_result -> messages[]",
|
||||
"annotation": "A main-loop integration can append this JSON-safe result and continue with the updated conversation."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,102 +1,49 @@
|
||||
{
|
||||
"version": "s17",
|
||||
"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 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."
|
||||
"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": "user_message",
|
||||
"content": "Yes. Start the docs teammate and continue.",
|
||||
"annotation": "User confirmation opens the team boundary inherited from S15."
|
||||
"type": "system_event",
|
||||
"content": "goal_evaluated ok=false -> block",
|
||||
"annotation": "The evaluator finds no test exit code in the conversation."
|
||||
},
|
||||
{
|
||||
"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": "{\"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": "Worktree 'release-docs' created for task_1712345678_0042",
|
||||
"annotation": "The task now carries the checkout used by its eventual owner."
|
||||
},
|
||||
{
|
||||
"type": "tool_call",
|
||||
"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": "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": "{\"command\":\"python -m unittest tests.test_agent_teams_runtime\",\"run_in_background\":true}",
|
||||
"annotation": "Long-running validation goes through the background task path."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "permission: user approved the exact test command",
|
||||
"annotation": "Team confirmation does not authorize shell execution; the foreground turn asks separately before dispatch."
|
||||
},
|
||||
{
|
||||
"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."
|
||||
"content": "pytest tests/auth",
|
||||
"annotation": "The next agent turn runs the missing 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": "task_notification(status=completed): tests passed; teammate result and deploy status appended",
|
||||
"annotation": "The integrated runtime folds asynchronous results back into the loop."
|
||||
"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."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
{
|
||||
"version": "s18",
|
||||
"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": "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\",\"args\":{\"budget\":null}}",
|
||||
"annotation": "The model selects a saved workflow and arguments; the host registry supplies its trusted metadata and script."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "async_launched(runId=wf_review-changes_0000000000001a7b) -> 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_0000000000001a7b.output.json)",
|
||||
"annotation": "The task emits its final lifecycle event after output is written."
|
||||
},
|
||||
{
|
||||
"type": "tool_result",
|
||||
"toolName": "Workflow",
|
||||
"content": "{\"launched\":{\"status\":\"async_launched\",\"taskId\":\"local_workflow_wf_review-changes_0000000000001a7b\",\"taskType\":\"local_workflow\",\"runId\":\"wf_review-changes_0000000000001a7b\",\"workflowName\":\"review-changes\"},\"result\":{\"confirmed\":[{\"dimension\":\"security\",\"title\":\"audit:security #1\",\"severity\":\"high\"},{\"dimension\":\"style\",\"title\":\"audit:style #1\",\"severity\":\"high\"},{\"dimension\":\"security\",\"title\":\"audit:security #2\",\"severity\":\"medium\"},{\"dimension\":\"performance\",\"title\":\"audit:performance #2\",\"severity\":\"medium\"},{\"dimension\":\"correctness\",\"title\":\"audit:correctness #1\",\"severity\":\"low\"},{\"dimension\":\"performance\",\"title\":\"audit:performance #1\",\"severity\":\"low\"}]},\"task\":{\"taskId\":\"local_workflow_wf_review-changes_0000000000001a7b\",\"taskType\":\"local_workflow\",\"runId\":\"wf_review-changes_0000000000001a7b\",\"workflowName\":\"review-changes\",\"status\":\"completed\",\"usage\":{\"agents\":11,\"tokens\":352},\"progress\":[{\"type\":\"workflow_phase\",\"title\":\"Review\"},{\"type\":\"workflow_agent\",\"label\":\"audit:correctness\",\"phase\":\"Review\",\"status\":\"done\"},{\"type\":\"workflow_phase\",\"title\":\"Verify\"},{\"type\":\"workflow_agent\",\"label\":\"audit:security\",\"phase\":\"Review\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"audit:performance\",\"phase\":\"Review\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"audit:style\",\"phase\":\"Review\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:correctness:audit:correctness #1\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:security:audit:security #1\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:security:audit:security #2\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:performance:audit:performance #1\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:performance:audit:performance #2\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:style:audit:style #1\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_agent\",\"label\":\"verify:style:audit:style #2\",\"phase\":\"Verify\",\"status\":\"done\"},{\"type\":\"workflow_log\",\"message\":\"confirmed 6 real finding(s)\"}]}}",
|
||||
"annotation": "The deterministic sample returns its six fixture findings and measured runner usage; these are not claims about the repository."
|
||||
},
|
||||
{
|
||||
"type": "system_event",
|
||||
"content": "append Workflow tool_result -> messages[]",
|
||||
"annotation": "A main-loop integration can append this JSON-safe result and continue with the updated conversation."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
{
|
||||
"version": "s19",
|
||||
"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": "/goal pytest tests/auth exits with code 0",
|
||||
"annotation": "The command stores an active completion condition and starts the work."
|
||||
},
|
||||
{
|
||||
"type": "assistant_text",
|
||||
"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": "system_event",
|
||||
"content": "goal_evaluated ok=false -> block",
|
||||
"annotation": "The evaluator finds no test exit code in the conversation."
|
||||
},
|
||||
{
|
||||
"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": "pytest tests/auth",
|
||||
"annotation": "The next agent turn runs the missing check."
|
||||
},
|
||||
{
|
||||
"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": "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."
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user