feat: consolidate course into 21 lessons

This commit is contained in:
Haoran
2026-07-31 03:15:58 +08:00
parent 4bc33ec858
commit 2d69019342
200 changed files with 7338 additions and 10829 deletions

View File

@@ -27,7 +27,6 @@ import s18Annotations from "@/data/annotations/s18.json";
import s19Annotations from "@/data/annotations/s19.json";
import s20Annotations from "@/data/annotations/s20.json";
import s21Annotations from "@/data/annotations/s21.json";
import s22Annotations from "@/data/annotations/s22.json";
interface Decision {
id: string;
@@ -65,7 +64,6 @@ const ANNOTATIONS: Record<string, AnnotationFile> = {
s19: s19Annotations as AnnotationFile,
s20: s20Annotations as AnnotationFile,
s21: s21Annotations as AnnotationFile,
s22: s22Annotations as AnnotationFile,
};
interface DesignDecisionsProps {

View File

@@ -30,7 +30,6 @@ const scenarioModules: Record<string, () => Promise<{ default: Scenario }>> = {
s19: () => import("@/data/scenarios/s19.json") as Promise<{ default: Scenario }>,
s20: () => import("@/data/scenarios/s20.json") as Promise<{ default: Scenario }>,
s21: () => import("@/data/scenarios/s21.json") as Promise<{ default: Scenario }>,
s22: () => import("@/data/scenarios/s22.json") as Promise<{ default: Scenario }>,
};
interface AgentLoopSimulatorProps {

View File

@@ -21,12 +21,11 @@ const visualizations: Record<
s12: lazy(() => import("./s07-task-system")),
s13: lazy(() => import("./s08-background-tasks")),
s14: lazy(() => import("./s14-cron-scheduler")),
s15: lazy(() => import("./s09-agent-teams")),
s16: lazy(() => import("./s10-team-protocols")),
s17: lazy(() => import("./s11-autonomous-agents")),
s18: lazy(() => import("./s12-worktree-task-isolation")),
s19: lazy(() => import("./s19-mcp-tools")),
s20: lazy(() => import("./s20-comprehensive")),
s15: lazy(() => import("./s10-team-protocols")),
s16: lazy(() => import("./s11-autonomous-agents")),
s17: lazy(() => import("./s12-worktree-task-isolation")),
s18: lazy(() => import("./s19-mcp-tools")),
s19: lazy(() => import("./s20-comprehensive")),
};
export function SessionVisualization({ version }: { version: string }) {

View File

@@ -33,7 +33,7 @@
"id": "no-recursive-task-tool",
"title": "Subagents Cannot Spawn Subagents",
"description": "The child tool set omits task, preventing recursive delegation from exploding. The lesson keeps isolation visible before adding richer team behavior later.",
"alternatives": "Allowing recursion is powerful, but much harder to bound and explain in a teaching runtime.",
"alternatives": "Allowing recursion is powerful, but much harder to bound and explain.",
"zh": {
"title": "子代理不能再创建子代理",
"description": "子代理工具集中不包含 task避免递归委派失控。课程先把隔离讲清楚再在后续章节加入更复杂团队行为。"

View File

@@ -33,7 +33,7 @@
"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 would be more production-ready, but it would obscure the minimal moving parts needed to understand threaded agent work.",
"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": "小型共享存储让线程可观察",
"description": "实现用显式字典记录后台任务状态和结果。这样代码仍然易学,同时暴露并发中的关键问题:任务 id、生命周期状态和结果收集。"

View File

@@ -2,45 +2,59 @@
"version": "s15",
"decisions": [
{
"id": "lead-agent-owns-coordination",
"title": "The Lead Owns Coordination",
"description": "The lead agent decides when to spawn teammates, what to send them, and how to interpret replies. Teammates can work independently, but the user-facing conversation stays anchored in one lead loop.",
"alternatives": "A peer-to-peer team would be more flexible, but much harder to explain because no single loop owns the answer.",
"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": "由 Lead Agent 负责协调",
"description": "Lead agent 决定何时创建队友、发送什么任务、如何解释回复。队友可以独立工作,但面向用户的对话始终锚定在一个 lead 循环中。"
"title": "启动团队前先征得用户确认",
"description": "Lead 可以判断一个需求适合拆分,但要先提出职责清晰的小团队。只有用户确认后,运行时才启动额外的 Agent。"
},
"ja": {
"title": "調整はリードエージェントが担う",
"description": "リードエージェントがチームメイトの生成、送信内容、返信の解釈を決めます。チームメイトは独立して作業できますが、ユーザー向けの会話は一つのリードループに固定されます。"
"title": "チームを起動する前にユーザーが確認する",
"description": "Lead は依頼を分割できると判断しても、まず役割が明確な小さなチームを提案する。追加 Agent はユーザーの確認後に起動する。"
}
},
{
"id": "file-backed-mailboxes",
"title": "Mailboxes Make Team Communication Inspectable",
"description": "MessageBus writes JSONL mailboxes so every handoff is visible on disk. This avoids magical shared memory and gives learners a concrete artifact for debugging team behavior.",
"alternatives": "In-memory channels are faster, but they hide the communication history and disappear when the process stops.",
"id": "runtime-owned-delivery",
"title": "Message Delivery Belongs to the Runtime",
"description": "MessageBus stores each handoff in JSONL, while the runtime watches the Lead mailbox and injects new team events into the next turn. The model does not need an inbox polling tool.",
"alternatives": "A model-visible check_inbox tool is easy to add, but wastes turns and can leave completed work unnoticed.",
"zh": {
"title": "邮箱文件让团队通信可检查",
"description": "MessageBus 使用 JSONL 邮箱记录每次交接。这样避免了神秘的共享内存,也给学习者一个能直接调试团队行为的具体文件。"
"title": "消息投递由运行时负责",
"description": "MessageBus 把每次交接写入 JSONL运行时监听 Lead 邮箱,并把新的团队事件送入下一轮上下文。模型不需要调用邮箱轮询工具。"
},
"ja": {
"title": "メールボックスでチーム通信を検査可能にする",
"description": "MessageBus は JSONL メールボックスへ各ハンドオフを書き込みます。見えない共有メモリを避け、チーム動作をデバッグできる具体的な成果物を提供します。"
"title": "メッセージ配信はランタイムが担う",
"description": "MessageBus は各ハンドオフを JSONL に保存し、ランタイムが Lead のメールボックスを監視して新しい team event を次の turn に注入する。モデルに受信箱確認ツールは要らない。"
}
},
{
"id": "scoped-teammate-tools",
"title": "Teammates Use Scoped Tool Sets",
"description": "A teammate loop receives a narrower prompt and tool set than the lead. That keeps delegation focused and prevents a helper agent from accidentally taking over orchestration.",
"alternatives": "Giving every teammate the full tool pool is simpler, but it blurs roles and makes failures harder to attribute.",
"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": "队友循环拿到比 lead 更窄的提示词和工具集。这样委派更聚焦,也避免 helper agent 意外接管整体协调。"
"title": "类型化请求携带关联 ID",
"description": "计划和关机请求使用明确的消息类型与 request id。即使回复顺序不同运行时也能更新正确的 pending request。"
},
"ja": {
"title": "チームメイトには範囲を絞ったツールセットを与える",
"description": "チームメイトループにはリードより狭いプロンプトとツールセットを渡します。委任を集中させ、補助エージェントが誤って全体調整を奪うことを防ぎます。"
"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, and an idle teammate remains available for later assignments until a typed shutdown completes.",
"alternatives": "Treating approval as a conversational suggestion cannot prevent an early write or shell command.",
"zh": {
"title": "计划审批是执行闸门",
"description": "Lead 请求计划后,修改类工具会保持阻塞,直到对应计划通过。被拒绝的计划必须重新提交;空闲队友会继续保留,直到类型化关机协议完成。"
},
"ja": {
"title": "プラン承認を実行ゲートにする",
"description": "Lead がプランを要求すると、対応するプランが承認されるまで変更系ツールをブロックする。却下後は再提出が必要で、待機中のチームメイトは型付き終了プロトコルが完了するまで残る。"
}
}
]

View File

@@ -2,45 +2,45 @@
"version": "s16",
"decisions": [
{
"id": "typed-protocol-messages",
"title": "Typed Messages Replace Informal Chat",
"description": "Plan requests and shutdown requests are encoded as protocol messages with explicit kinds. The teammate can branch on message type instead of guessing intent from free-form text.",
"alternatives": "Plain natural-language messages are easier to write, but brittle once the team has multiple request types.",
"id": "idle-state-discovers-work",
"title": "Idle Teammates Look for Ready Work",
"description": "s15 already keeps teammates alive in IDLE. s16 gives that state one more input: after waiting for messages, a teammate scans the shared task board for pending, unowned, unblocked work.",
"alternatives": "The Lead could dispatch every assignment, but then an idle teammate cannot help with work that becomes ready later.",
"zh": {
"title": "用类型化协议消息替代随意聊天",
"description": "计划请求和关闭请求会编码成带有明确 kind 的协议消息。队友可以根据消息类型分支处理,而不是从自由文本中猜意图。"
"title": "空闲队友主动寻找就绪任务",
"description": "s15 已经让队友在 IDLE 中保持存活。s16 为这个状态增加任务板入口:等待消息后,队友会扫描 pending、未分配且依赖已完成的任务。"
},
"ja": {
"title": "非公式チャットを型付きプロトコルメッセージに置き換える",
"description": "計画要求とシャットダウン要求は明示的な kind を持つプロトコルメッセージとして表現されます。チームメイトは自由文から意図を推測せず、型で分岐できます。"
"title": "待機中のチームメイトが実行可能な仕事を探す",
"description": "s15 ですでにチームメイトは IDLE のまま残る。s16 はその状態にタスクボード入口を追加し、メッセージ待機後に pending、未所有、依存解決済みのタスクを探す。"
}
},
{
"id": "request-id-correlation",
"title": "Request IDs Close the Loop",
"description": "Each protocol request creates a pending record with a request_id. Responses must carry the same id, which lets the lead match replies even when multiple teammates are active.",
"alternatives": "Matching by latest message works in demos, but fails as soon as two requests overlap.",
"id": "atomic-claim",
"title": "Claiming Is Atomic",
"description": "The ownership check and task update run under one lock. When two teammates see the same ready task, only one can move it from pending to in_progress.",
"alternatives": "Scanning and writing without a shared lock can assign the same task twice.",
"zh": {
"title": "Request ID 闭合协议循环",
"description": "每个协议请求都会创建带 request_id 的 pending 记录。响应必须携带同一个 id因此即使多个队友同时工作lead 也能匹配对应回复。"
"title": "任务认领必须原子化",
"description": "所有权检查与任务更新在同一把锁内完成。两个队友同时看到一个就绪任务时,只有一个能把它从 pending 推进到 in_progress。"
},
"ja": {
"title": "request_id がループを閉じる",
"description": "各プロトコル要求は request_id 付きの pending レコードを作ります。応答も同じ id を持つため、複数のチームメイトが動いていてもリードは対応する返信を照合できます。"
"title": "タスク認領を原子的に行う",
"description": "所有権確認とタスク更新を同じ lock の中で行う。二つのチームメイトが同じ実行可能タスクを見ても、pending から in_progress へ進められるのは一方だけである。"
}
},
{
"id": "idle-protocol-handling",
"title": "Protocol Handling Runs During Idle Time",
"description": "Teammates can consume protocol messages while idle, so the lead can request plans or shutdowns without waiting for a separate user turn. This makes team control part of the runtime lifecycle.",
"alternatives": "Only checking protocols during active work would delay control messages and make shutdown unreliable.",
"id": "dependencies-filter-readiness",
"title": "Dependencies Define Readiness",
"description": "The scan returns a task only when every blockedBy dependency is completed. A teammate with nothing ready remains idle instead of starting work out of order.",
"alternatives": "Ignoring dependencies increases utilization, but produces work against unfinished inputs.",
"zh": {
"title": "空闲期也处理协议",
"description": "队友在空闲状态也会消费协议消息,因此 lead 可以请求计划或关闭,而不必等待另一个用户回合。这让团队控制成为运行时生命周期的一部分。"
"title": "依赖关系决定任务是否就绪",
"description": "只有 blockedBy 中的依赖全部完成,扫描才会返回该任务。没有就绪任务的队友继续保持 IDLE不会越过依赖提前开工。"
},
"ja": {
"title": "アイドル中にもプロトコルを処理する",
"description": "チームメイトはアイドル時にもプロトコルメッセージを消費します。リードは別のユーザーターンを待たずに計画や終了を要求でき、チーム制御がランタイムのライフサイクルに組み込まれます。"
"title": "依存関係が実行可能性を決める",
"description": "blockedBy の依存がすべて完了したタスクだけを走査結果に含める。実行可能な仕事がなければ IDLE を維持し、順序を飛ばして開始しない。"
}
}
]

View File

@@ -2,45 +2,45 @@
"version": "s17",
"decisions": [
{
"id": "idle-poll-loop",
"title": "Autonomy Starts from Idle Polling",
"description": "The agent becomes autonomous by doing useful checks while idle: scanning tasks, reading inbox messages, and deciding whether to claim work. No new magic planner is introduced.",
"alternatives": "A central scheduler could assign every task, but this lesson focuses on local autonomy inside each teammate loop.",
"id": "worktree-name-validation",
"title": "Worktree Names Are Validated Before Git Runs",
"description": "The tool validates names before creating branches or directories, so unsafe user input never reaches git or filesystem operations.",
"alternatives": "Passing names directly to git is shorter, but it turns a collaboration feature into an injection hazard.",
"zh": {
"title": "自治从空闲轮询开始",
"description": "Agent 通过在空闲时做有用检查获得自治能力:扫描任务、读取 inbox、判断是否 claim 工作。这里没有引入新的神秘规划器。"
"title": "运行 Git 前先校验 Worktree 名称",
"description": "工具在创建分支或目录前先校验名称,不让不安全的用户输入进入 git 或文件系统操作。"
},
"ja": {
"title": "自律性はアイドルポーリングから始まる",
"description": "エージェントはアイドル時にタスク走査、受信箱確認、作業の claim 判断を行うことで自律的になります。新しい魔法のプランナーは導入しません。"
"title": "git 実行前に worktree 名を検証する",
"description": "ブランチやディレクトリ作成前に名前を検証し、危険なユーザー入力が git やファイルシステム操作へ流れないようにします。"
}
},
{
"id": "claim-before-work",
"title": "Claim Before Work Prevents Collisions",
"description": "A teammate must claim a task before entering WORK state. Ownership checks make autonomous pickup safe when multiple agents poll the same task board.",
"alternatives": "Agents could simply pick any open task, but two agents might duplicate work or overwrite each other's result.",
"id": "task-bound-worktree",
"title": "The Task Record Owns the Worktree Binding",
"description": "A task stores its assigned worktree so future commands know where to run. The binding is explicit data, not a hidden convention based on naming or current working directory.",
"alternatives": "Deriving the worktree path from branch names is convenient, but brittle when tasks are renamed or moved.",
"zh": {
"title": "先 Claim 再工作,避免冲突",
"description": "队友必须先 claim 任务,再进入 WORK 状态。多个 agent 轮询同一个任务板时,所有权检查让自治领取任务更安全。"
"title": "任务记录持有 Worktree 绑定关系",
"description": "任务会记录自己分配到的 worktree因此后续命令知道应该在哪里运行。这个绑定是显式数据而不是依赖命名或当前目录的隐藏约定。"
},
"ja": {
"title": "作業前に claim して衝突を防ぐ",
"description": "チームメイトは WORK 状態へ入る前にタスクを claim します。複数のエージェントが同じタスクボードをポーリングしても、所有権チェックにより安全に取得できます。"
"title": "タスクレコードが worktree の紐付けを持つ",
"description": "タスクは割り当てられた worktree を保持し、後続コマンドは実行場所を把握できます。この紐付けは命名や現在ディレクトリに依存する暗黙の規約ではなく、明示的なデータです。"
}
},
{
"id": "identity-reinjection",
"title": "Advanced Teaching Workaround: Identity Re-injection",
"description": "The simplified lesson re-injects identity after its compaction heuristic. This is optional teaching scaffolding; production compaction should preserve stable system instructions instead.",
"alternatives": "Keep identity in stable system instructions and preserve that boundary through compaction.",
"id": "lifecycle-event-stream",
"title": "Lifecycle Events Stay Separate from Tool Results",
"description": "Creation, status, keep, and removal events are emitted to a side-channel log. That makes worktree state observable without overloading the conversational transcript.",
"alternatives": "Only returning tool results is simpler, but later debugging needs a durable audit trail of worktree lifecycle changes.",
"zh": {
"title": "进阶教学补丁:身份重注入",
"description": "简化课程在压缩启发式触发后重新注入身份。这是选学脚手架;生产实现应在压缩时保留稳定的 system 指令。"
"title": "生命周期事件与工具结果分离",
"description": "创建、状态、保留和移除事件会写入旁路日志。这样 worktree 状态可观察,同时不会把对话 transcript 塞满运行时事件。"
},
"ja": {
"title": "発展用の教育補助:アイデンティティ再注入",
"description": "簡略化した教材は圧縮ヒューリスティック後にアイデンティティを再注入します。これは任意の足場であり、本番実装では圧縮を越えて安定した system 指示を保持すべきです。"
"title": "ライフサイクルイベントをツール結果から分離する",
"description": "作成、状態、保持、削除のイベントはサイドチャネルログへ出力します。会話 transcript をランタイムイベントで埋めずに worktree 状態を観測できます。"
}
}
]

View File

@@ -2,45 +2,45 @@
"version": "s18",
"decisions": [
{
"id": "worktree-name-validation",
"title": "Worktree Names Are Validated Before Git Runs",
"description": "The tool validates names before creating branches or directories. That keeps a teaching implementation from normalizing unsafe user input into shell or filesystem operations.",
"alternatives": "Passing names directly to git is shorter, but it turns a collaboration feature into an injection hazard.",
"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": "运行 Git 前先校验 Worktree 名称",
"description": "工具在创建分支或目录前先校验名称。这样教学实现不会把不安全的用户输入直接传入 shell 或文件系统操作。"
"title": "MCP 工具使用规范化命名空间",
"description": "发现到的工具会暴露为 mcp__server__tool。前缀让工具来源明确也避免和内置工具或其他服务器工具冲突。"
},
"ja": {
"title": "git 実行前に worktree 名を検証する",
"description": "ブランチやディレクトリ作成前に名前を検証します。学習用実装が危険なユーザー入力を shell やファイルシステム操作へ流し込むことを防ぎます。"
"title": "MCP ツールは正規化された名前空間を使う",
"description": "発見されたツールは mcp__server__tool として公開されます。接頭辞により出所が明確になり、組み込みツールや別サーバーのツールとの衝突を避けます。"
}
},
{
"id": "task-bound-worktree",
"title": "The Task Record Owns the Worktree Binding",
"description": "A task stores its assigned worktree so future commands know where to run. The binding is explicit data, not a hidden convention based on naming or current working directory.",
"alternatives": "Deriving the worktree path from branch names is convenient, but brittle when tasks are renamed or moved.",
"id": "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": "任务记录持有 Worktree 绑定关系",
"description": "任务会记录自己分配到的 worktree因此后续命令知道应该在哪里运行。这个绑定是显式数据而不是依赖命名或当前目录的隐藏约定。"
"title": "工具发现会更新活动工具池",
"description": "连接服务器后,运行时会为下一次 LLM 调用组装新的工具池。模型只有在发现阶段让 MCP 工具可见之后,才能调用它们。"
},
"ja": {
"title": "タスクレコードが worktree の紐付けを持つ",
"description": "タスクは割り当てられた worktree を保持し、後続コマンドは実行場所を把握できます。この紐付けは命名や現在ディレクトリに依存する暗黙の規約ではなく、明示的なデータです。"
"title": "ツール発見がアクティブなツールプールを更新する",
"description": "サーバー接続後、ランタイムは次の LLM 呼び出し用に新しいツールプールを組み立てます。MCP ツールは発見で可視化された後にのみモデルが利用できます。"
}
},
{
"id": "lifecycle-event-stream",
"title": "Lifecycle Events Stay Separate from Tool Results",
"description": "Creation, status, keep, and removal events are emitted to a side-channel log. That makes worktree state observable without overloading the conversational transcript.",
"alternatives": "Only returning tool results is simpler, but later debugging needs a durable audit trail of worktree lifecycle changes.",
"id": "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": "创建、状态、保留和移除事件会写入旁路日志。这样 worktree 状态可观察,同时不会把对话 transcript 塞满运行时事件。"
"title": "外部结果复用 Tool Result 路径",
"description": "MCP 响应会像普通 tool result 一样追加到对话中。这样 agent 循环无需改变,同时外部系统仍然可以参与。"
},
"ja": {
"title": "ライフサイクルイベントをツール結果から分離する",
"description": "作成、状態、保持、削除のイベントはサイドチャネルログへ出力します。会話 transcript をランタイムイベントで埋めずに worktree 状態を観測できます。"
"title": "外部結果は tool result 経路を再利用する",
"description": "MCP の応答は通常の tool result と同じように会話へ追加されます。エージェントループを変えずに外部システムを参加させられます。"
}
}
]

View File

@@ -2,45 +2,45 @@
"version": "s19",
"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": "composition-over-new-loop",
"title": "The Final Agent Composes Previous Layers",
"description": "The comprehensive agent 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": "MCP 工具使用规范化命名空间",
"description": "发现到的工具会暴露为 mcp__server__tool。前缀让工具来源明确也避免和内置工具或其他服务器工具冲突。"
"title": "最终 Agent 是组合既有层,而不是换掉循环",
"description": "综合 Agent 没有用新架构替换循环,而是把 memory、task、skill、后台任务、团队、worktree、MCP 组合到同一个模型-工具-结果循环周围。"
},
"ja": {
"title": "MCP ツールは正規化された名前空間を使う",
"description": "発見されたツールは mcp__server__tool として公開されます。接頭辞により出所が明確になり、組み込みツールや別サーバーのツールとの衝突を避けます。"
"title": "最終エージェントは既存レイヤーの合成",
"description": "総合エージェントはループを新しい構造で置き換えません。memory、task、skill、バックグラウンド処理、チーム、worktree、MCP を同じ model-tool-result サイクルの周囲に合成します。"
}
},
{
"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": "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": "连接服务器后,运行时会为下一次 LLM 调用组装新的工具池。模型只有在发现阶段让 MCP 工具可见之后,才能调用它们。"
"title": "运行时状态来自具名来源",
"description": "上下文组装从 memory、task graph、skills、tool registry、policy 等具名来源读取。大型 agent 因此仍可调试,因为每块 prompt context 都有清晰归属。"
},
"ja": {
"title": "ツール発見がアクティブなツールプールを更新する",
"description": "サーバー接続後、ランタイムは次の LLM 呼び出し用に新しいツールプールを組み立てます。MCP ツールは発見で可視化された後にのみモデルが利用できます。"
"title": "ランタイム状態には名前付きの出所がある",
"description": "コンテキスト組み立ては memory、task graph、skills、tool registry、policy などの名前付きソースから取得します。各 prompt context に所有者があるため、大きなエージェントでもデバッグ可能です。"
}
},
{
"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": "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": "外部结果复用 Tool Result 路径",
"description": "MCP 响应会像普通 tool result 一样追加到对话中。这样 agent 循环无需改变,同时外部系统仍然可以参与。"
"title": "恢复能力是一等流程",
"description": "压缩、错误恢复和异步结果收集都属于正常循环。Harness 通过明确的路径处理恢复与续跑,而不是把逻辑散落在异常分支中。"
},
"ja": {
"title": "外部結果は tool result 経路を再利用する",
"description": "MCP の応答は通常の tool result と同じように会話へ追加されます。エージェントループを変えずに外部システムを参加させられます。"
"title": "リカバリは主要フローの一部",
"description": "圧縮、エラー回復、非同期結果収集を通常のループ動作として扱います。Harness は回復と再開を名前付きの経路にまとめ、例外分岐へ散らしません。"
}
}
]

View File

@@ -2,45 +2,45 @@
"version": "s20",
"decisions": [
{
"id": "composition-over-new-loop",
"title": "The Final Agent Composes Previous Layers",
"description": "The comprehensive agent 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": "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": "最终 Agent 是组合既有层,而不是换掉循环",
"description": "综合 Agent 没有用新架构替换循环,而是把 memory、task、skill、后台任务、团队、worktree、MCP 组合到同一个模型-工具-结果循环周围。"
"title": "固定编排由代码负责",
"description": "当阶段与汇总规则事先确定时workflow 脚本能让流程并行、可复现、可检查,同时不修改主 Agent 循环。"
},
"ja": {
"title": "最終エージェントは既存レイヤーの合成",
"description": "総合エージェントはループを新しい構造で置き換えません。memory、task、skill、バックグラウンド処理、チーム、worktree、MCP を同じ model-tool-result サイクルの周囲に合成します。"
"title": "固定された編成はコードが担う",
"description": "段階と集約ルールが事前に決まっているなら、workflow script は main Agent loop を変えずに処理を並列化し、再現可能で検査可能にする。"
}
},
{
"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": "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": "上下文组装从 memory、task graph、skills、tool registry、policy 等具名来源读取。大型 agent 因此仍可调试,因为每块 prompt context 都有清晰归属。"
"title": "语义键让恢复不依赖完成顺序",
"description": "Journal 用稳定的调用内容作为 key而不是共享完成计数器。并发调用无论以什么顺序结束都能命中正确缓存。"
},
"ja": {
"title": "ランタイム状態には名前付きの出所がある",
"description": "コンテキスト組み立ては memory、task graph、skills、tool registry、policy などの名前付きソースから取得します。各 prompt context に所有者があるため、大きなエージェントでもデバッグ可能です。"
"title": "意味キーで完了順序に依存せず再開する",
"description": "Journal は共有完了カウンタではなく安定した call 内容を key にする。並行 call の終了順が変わっても正しい cache result に対応できる。"
}
},
{
"id": "recovery-is-first-class",
"title": "Recovery Is Part of the Main Flow",
"description": "Compaction, error recovery, and asynchronous result collection are treated as normal loop behavior. The final lesson shows that production agents spend as much effort recovering and resuming as they do calling tools.",
"alternatives": "Recovery could be left as error handling around the edges, but then the architecture would understate what real long-running agents need.",
"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": "压缩、错误恢复、异步结果收集都被视为正常循环行为。最终课展示了生产级 agent 在恢复和续跑上投入的工程量,并不低于调用工具本身。"
"title": "编排故障必须向上传播",
"description": "阶段失败、结构化结果不合法、journal 损坏或超过全局限制时workflow 直接失败,而不是静默丢项后仍报告成功。"
},
"ja": {
"title": "リカバリは主要フローの一部",
"description": "圧縮、エラー回復、非同期結果収集を通常のループ動作として扱います。実運用の長時間エージェントでは、ツール呼び出しと同じくらい回復と再開が重要であることを示します。"
"title": "編成の失敗は上位へ伝播させる",
"description": "stage failure、無効な structured result、破損 journal、run-wide limit 超過は workflow を失敗させ、項目を黙って落として成功扱いしない。"
}
}
]

View File

@@ -2,45 +2,45 @@
"version": "s21",
"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.",
"id": "host-owns-completion-gate",
"title": "The Host Owns the Completion Gate",
"description": "The working model may request to stop, but the harness evaluates the active goal before returning. Completion is a program decision at the turn boundary.",
"alternatives": "Asking the working model whether it is finished is simpler, but lets the same actor make and verify its own claim.",
"zh": {
"title": "固定编排由代码负责",
"description": "当阶段与汇总规则事先确定时workflow 脚本能让流程并行、可复现、可检查,同时不修改主 Agent 循环。"
"title": "完成闸门由宿主持有",
"description": "工作模型可以请求停止,但 harness 会在 return 前评估 active goal。是否完成是轮次边界上的程序决策。"
},
"ja": {
"title": "固定された編成はコードが担う",
"description": "段階と集約ルールが事前に決まっているなら、workflow script は main Agent loop を変えずに処理を並列化し、再現可能で検査可能にする。"
"title": "完了ゲートはホストが所有する",
"description": "作業モデルは停止を要求できるが、harness は return 前に active goal を評価する。完了は turn 境界でのプログラム判断である。"
}
},
{
"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.",
"id": "host-assigned-evidence-origins",
"title": "Evidence Trust Comes from the Ingress Path",
"description": "Ordinary submit calls cannot attach trusted labels. Only an allowlisted host-event channel can deliver task or monitor evidence, so user and model prose cannot certify itself.",
"alternatives": "Trusting text content or caller-supplied labels makes the evidence boundary forgeable.",
"zh": {
"title": "语义键让恢复不依赖完成顺序",
"description": "Journal 用稳定的调用内容作为 key而不是共享完成计数器。并发调用无论以什么顺序结束都能命中正确缓存。"
"title": "证据信任来自入口路径",
"description": "普通 submit 不能附加可信标签;只有白名单宿主事件通道能送入 task 或 monitor 证据,因此用户与模型文本不能自证完成。"
},
"ja": {
"title": "意味キーで完了順序に依存せず再開する",
"description": "Journal は共有完了カウンタではなく安定した call 内容を key にする。並行 call の終了順が変わっても正しい cache result に対応できる。"
"title": "証拠の信頼は入力経路から得る",
"description": "通常の submit は trusted label を付けられず、allowlist 済み host event channel だけが task や monitor evidence を届ける。ユーザーやモデルの文章は自己証明できない。"
}
},
{
"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.",
"id": "bounded-continuation",
"title": "Every Automatic Continuation Needs a Budget",
"description": "An unmet goal queues another turn only while budget remains. Exhaustion marks the goal blocked and releases the gate instead of creating an infinite loop.",
"alternatives": "An unbounded goal is persistent, but an impossible condition can consume resources forever.",
"zh": {
"title": "编排故障必须向上传播",
"description": "阶段失败、结构化结果不合法、journal 损坏或超过全局限制时workflow 直接失败,而不是静默丢项后仍报告成功。"
"title": "每次自动续轮都必须有预算",
"description": "目标未满足时只在预算剩余时继续;耗尽后将目标标记为 blocked 并释放闸门,避免无限循环。"
},
"ja": {
"title": "編成の失敗は上位へ伝播させる",
"description": "stage failure、無効な structured result、破損 journal、run-wide limit 超過は workflow を失敗させ、項目を黙って落として成功扱いしない。"
"title": "自動継続には必ず予算を置く",
"description": "goal 未達時は予算が残る間だけ次の turn を追加する。使い切れば blocked にして gate を解放し、無限 loop を防ぐ。"
}
}
]

View File

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

View File

@@ -368,74 +368,45 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
},
s15: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "lead", label: "Lead LLM", type: "process", x: COL_CENTER, y: 110 },
{ id: "team_tool", label: "team tool?", type: "decision", x: COL_CENTER, y: 200 },
{ id: "spawn", label: "Spawn Teammate", type: "subprocess", x: COL_LEFT, y: 300 },
{ id: "send", label: "Send Message", type: "subprocess", x: COL_CENTER, y: 300 },
{ id: "bus", label: "MessageBus\n.mailboxes", type: "process", x: COL_CENTER, y: 400 },
{ id: "teammate", label: "Teammate Loop", type: "process", x: COL_RIGHT, y: 500 },
{ id: "tools", label: "Scoped Tools", type: "subprocess", x: COL_RIGHT, y: 590 },
{ id: "inbox", label: "Lead Inbox", type: "process", x: COL_CENTER, y: 700 },
{ id: "append", label: "Append Result", type: "process", x: COL_LEFT, y: 700 },
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 300 },
{ id: "start", label: "User Requirement", type: "start", x: COL_CENTER, y: 30 },
{ id: "lead", label: "Lead Proposes\nSmall Team", type: "process", x: COL_CENTER, y: 110 },
{ id: "team_tool", label: "User Confirms?", type: "decision", x: COL_CENTER, y: 200 },
{ id: "spawn", label: "Spawn Persistent\nTeammates", type: "subprocess", x: COL_LEFT, y: 300 },
{ id: "send", label: "Assignment /\nTyped Request", type: "subprocess", x: COL_LEFT, y: 400 },
{ id: "bus", label: "MessageBus\nJSONL Mailboxes", type: "process", x: COL_CENTER, y: 500 },
{ id: "teammate", label: "Teammate\nWORK / IDLE", type: "process", x: COL_RIGHT, y: 400 },
{ id: "tools", label: "Scoped Tools /\nPlan Gate", type: "subprocess", x: COL_RIGHT, y: 500 },
{ id: "inbox", label: "Runtime Delivery", type: "process", x: COL_CENTER, y: 600 },
{ id: "append", label: "Append Team Events", type: "process", x: COL_LEFT, y: 690 },
{ id: "end", label: "Continue Alone", type: "end", x: COL_RIGHT, y: 300 },
],
edges: [
{ from: "start", to: "lead" },
{ from: "lead", to: "team_tool" },
{ from: "team_tool", to: "spawn", label: "spawn" },
{ from: "team_tool", to: "send", label: "send" },
{ from: "team_tool", to: "spawn", label: "yes" },
{ from: "team_tool", to: "end", label: "no" },
{ from: "spawn", to: "bus", label: "register" },
{ from: "spawn", to: "send" },
{ from: "send", to: "bus" },
{ from: "bus", to: "teammate" },
{ from: "teammate", to: "tools" },
{ from: "tools", to: "bus", label: "reply" },
{ from: "bus", to: "inbox" },
{ from: "tools", to: "bus", label: "result / protocol reply" },
{ from: "bus", to: "inbox", label: "wake Lead" },
{ from: "inbox", to: "append" },
{ from: "append", to: "lead" },
],
},
s16: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "lead", label: "Lead LLM", type: "process", x: COL_CENTER, y: 110 },
{ id: "protocol", label: "protocol?", type: "decision", x: COL_CENTER, y: 200 },
{ id: "request", label: "request_plan /\nrequest_shutdown", type: "subprocess", x: COL_LEFT, y: 300 },
{ id: "pending", label: "Pending Requests\nrequest_id", type: "process", x: COL_LEFT, y: 390 },
{ id: "dispatch", label: "Dispatch Message", type: "process", x: COL_CENTER, y: 470 },
{ id: "teammate", label: "Teammate Handler", type: "process", x: COL_RIGHT, y: 470 },
{ id: "response", label: "submit_plan /\nack shutdown", type: "subprocess", x: COL_RIGHT, y: 560 },
{ id: "match", label: "match_response?", type: "decision", x: COL_CENTER, y: 640 },
{ id: "append", label: "Append Protocol\nResult", type: "process", x: COL_CENTER, y: 730 },
{ id: "end", label: "Output", type: "end", x: COL_RIGHT, y: 300 },
],
edges: [
{ from: "start", to: "lead" },
{ from: "lead", to: "protocol" },
{ from: "protocol", to: "request", label: "yes" },
{ from: "protocol", to: "end", label: "no" },
{ from: "request", to: "pending" },
{ from: "pending", to: "dispatch" },
{ from: "dispatch", to: "teammate" },
{ from: "teammate", to: "response" },
{ from: "response", to: "match" },
{ from: "match", to: "append", label: "matched" },
{ from: "append", to: "lead" },
],
},
s17: {
nodes: [
{ id: "start", label: "System Tick", type: "start", x: COL_CENTER, y: 30 },
{ id: "idle", label: "Idle Poll", type: "process", x: COL_CENTER, y: 110 },
{ id: "scan", label: "Scan Tasks", type: "subprocess", x: COL_CENTER, y: 190 },
{ id: "claimable", label: "claimable?", type: "decision", x: COL_CENTER, y: 280 },
{ id: "claim", label: "claim_task\n(owner check)", type: "subprocess", x: COL_LEFT, y: 380 },
{ id: "start", label: "Teammate IDLE", type: "start", x: COL_CENTER, y: 30 },
{ id: "idle", label: "Wait for Messages", type: "process", x: COL_CENTER, y: 110 },
{ id: "scan", label: "Scan Ready Tasks", type: "subprocess", x: COL_CENTER, y: 190 },
{ id: "claimable", label: "Ready Task?", type: "decision", x: COL_CENTER, y: 280 },
{ id: "claim", label: "Atomic Claim\ntask_lock", type: "subprocess", x: COL_LEFT, y: 380 },
{ id: "work", label: "WORK State", type: "process", x: COL_LEFT, y: 470 },
{ id: "complete", label: "complete_task", type: "subprocess", x: COL_LEFT, y: 560 },
{ id: "inbox", label: "Check Inbox", type: "process", x: COL_RIGHT, y: 380 },
{ id: "shutdown", label: "Shutdown?", type: "decision", x: COL_RIGHT, y: 470 },
{ id: "done", label: "IDLE / SHUTDOWN", type: "end", x: COL_RIGHT, y: 560 },
{ id: "inbox", label: "No Ready Task", type: "process", x: COL_RIGHT, y: 380 },
{ id: "shutdown", label: "Remain IDLE", type: "process", x: COL_RIGHT, y: 470 },
{ id: "done", label: "Result + IDLE Event", type: "process", x: COL_CENTER, y: 650 },
],
edges: [
{ from: "start", to: "idle" },
@@ -445,13 +416,13 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
{ from: "claimable", to: "inbox", label: "no" },
{ from: "claim", to: "work" },
{ from: "work", to: "complete" },
{ from: "complete", to: "idle" },
{ from: "complete", to: "done" },
{ from: "done", to: "idle" },
{ from: "inbox", to: "shutdown" },
{ from: "shutdown", to: "done", label: "yes" },
{ from: "shutdown", to: "idle", label: "no" },
{ from: "shutdown", to: "idle" },
],
},
s18: {
s17: {
nodes: [
{ id: "start", label: "Task Selected", type: "start", x: COL_CENTER, y: 30 },
{ id: "create", label: "create_worktree", type: "subprocess", x: COL_CENTER, y: 110 },
@@ -480,7 +451,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
{ from: "keep", to: "end" },
],
},
s19: {
s18: {
nodes: [
{ id: "start", label: "User Input", type: "start", x: COL_CENTER, y: 30 },
{ id: "llm", label: "LLM Call", type: "process", x: COL_CENTER, y: 110 },
@@ -507,7 +478,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
{ from: "append", to: "llm" },
],
},
s20: {
s19: {
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 },
@@ -541,7 +512,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
{ from: "recover", to: "context" },
],
},
s21: {
s20: {
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 },
@@ -565,7 +536,7 @@ export const EXECUTION_FLOWS: Record<string, FlowDefinition> = {
{ from: "output", to: "notify" },
],
},
s22: {
s21: {
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 },

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,51 +1,60 @@
{
"version": "s15",
"title": "Agent Teams: Runtime Lab",
"description": "The first Agent Teams lab builds persistent teammate loops and file-backed mailboxes.",
"title": "Agent Teams",
"description": "The Lead proposes a team for a normal user request, waits for confirmation, then coordinates persistent teammates through runtime-delivered events.",
"steps": [
{
"type": "user_message",
"content": "Split this task: one agent checks tests, another reviews docs.",
"annotation": "The request needs parallel work with separate responsibilities."
"content": "Refactor the configuration loader and authentication flow, then update the tests.",
"annotation": "The user describes the goal without designing a team."
},
{
"type": "assistant_text",
"content": "I'll spawn teammates with narrow roles and coordinate their updates through the message bus.",
"annotation": "The lead keeps orchestration authority while delegating execution."
"content": "These areas can be handled in parallel. I propose one teammate for configuration and authentication, and another for tests. Shall I start that team?",
"annotation": "The Lead chooses a small team and makes the extra-agent decision visible."
},
{
"type": "user_message",
"content": "Yes, go ahead.",
"annotation": "Teammates start only after explicit confirmation."
},
{
"type": "tool_call",
"toolName": "spawn_teammate",
"content": "{\"name\":\"test-runner\",\"role\":\"Run test commands and report failures.\"}",
"annotation": "A teammate thread starts with its own simplified loop."
"content": "{\"name\":\"backend\",\"role\":\"backend engineer\",\"prompt\":\"Refactor configuration and authentication while preserving interfaces.\"}",
"annotation": "The first persistent teammate enters WORK with a focused assignment."
},
{
"type": "tool_call",
"toolName": "send_message",
"content": "{\"to\":\"test-runner\",\"message\":\"Run the focused test suite and summarize failures.\"}",
"annotation": "The lead sends work through the file-backed mailbox."
"toolName": "spawn_teammate",
"content": "{\"name\":\"tests\",\"role\":\"test engineer\",\"prompt\":\"Update and run tests for the refactor.\"}",
"annotation": "The second teammate gets an independent slice."
},
{
"type": "system_event",
"content": ".mailboxes/test-runner.jsonl <- {from:\"lead\", message:\"Run the focused test suite\"}",
"annotation": "MessageBus persists the handoff as JSONL."
"content": "backend -> Lead: result(refactor complete) -> idle_notification",
"annotation": "Result and idle state are separate events; the teammate remains available."
},
{
"type": "system_event",
"content": ".mailboxes/lead.jsonl <- {from:\"test-runner\", message:\"Tests passed.\"}",
"annotation": "The teammate replies without sharing the lead's whole conversation."
"content": "tests -> Lead: result(test suite passed) -> idle_notification",
"annotation": "The runtime observes mailbox writes and wakes the Lead without a polling tool."
},
{
"type": "assistant_text",
"content": "Both parts are complete. The interfaces were preserved and the updated tests pass.",
"annotation": "The Lead combines teammate results into one user-facing answer."
},
{
"type": "tool_call",
"toolName": "check_inbox",
"content": "{\"agent\":\"lead\"}",
"annotation": "The lead polls its own inbox for teammate updates."
"toolName": "request_shutdown",
"content": "{\"teammate\":\"backend\"}",
"annotation": "A typed request with a request id closes the persistent teammate cleanly."
},
{
"type": "tool_result",
"toolName": "check_inbox",
"content": "test-runner: Tests passed.",
"annotation": "Mailbox messages re-enter the lead loop as tool results."
"type": "system_event",
"content": "shutdown_response(request_id=req_42, approve=true)",
"annotation": "The matching response resolves the pending protocol request."
}
]
}

View File

@@ -1,45 +1,50 @@
{
"version": "s16",
"title": "Agent Teams: Protocol Lab",
"description": "The second Agent Teams lab adds typed requests, request ids, and response matching to the s15 runtime.",
"title": "Autonomous Agents",
"description": "Idle teammates discover ready tasks on a shared board and use an atomic claim before starting work.",
"steps": [
{
"type": "user_message",
"content": "Ask the reviewer agent for a plan before it edits anything.",
"annotation": "The lead needs a structured plan request, not free-form chat."
"content": "Update the API examples, then add tests that use the final examples.",
"annotation": "The request contains two tasks with a clear dependency."
},
{
"type": "tool_call",
"toolName": "request_plan",
"content": "{\"to\":\"reviewer\",\"task\":\"Review the parser change before editing.\"}",
"annotation": "The protocol records a pending request with a request_id."
},
{
"type": "system_event",
"content": "pending_requests[req_18] = {kind:\"plan\", to:\"reviewer\", status:\"pending\"}",
"annotation": "ProtocolState keeps the request open until a matching response arrives."
},
{
"type": "system_event",
"content": "dispatch_message -> reviewer inbox: {type:\"plan_request\", request_id:\"req_18\"}",
"annotation": "The message is typed so the teammate knows how to handle it."
"toolName": "create_task",
"content": "{\"subject\":\"Update API examples\"}",
"annotation": "The Lead creates the first task in the shared graph."
},
{
"type": "tool_call",
"toolName": "submit_plan",
"content": "{\"request_id\":\"req_18\",\"plan\":[\"inspect parser\",\"run fixtures\",\"report risks\"]}",
"annotation": "The teammate responds with the same request_id."
"toolName": "create_task",
"content": "{\"subject\":\"Add example tests\",\"blockedBy\":[\"task_examples\"]}",
"annotation": "The second task cannot start until the examples are complete."
},
{
"type": "system_event",
"content": "match_response(req_18) -> status: ready_for_review",
"annotation": "The lead can correlate the reply with the exact request."
"content": "alice, bob: state=IDLE -> scan_unclaimed_tasks()",
"annotation": "Existing IDLE teammates scan the board after waiting for messages."
},
{
"type": "system_event",
"content": "claim_next_task(alice) -> task_examples; task_lock commits owner=alice",
"annotation": "The ownership check and pending-to-in_progress update are atomic."
},
{
"type": "system_event",
"content": "claim_next_task(bob) -> no ready task; remain IDLE",
"annotation": "The test task is still blocked, so Bob does not start it early."
},
{
"type": "tool_call",
"toolName": "review_plan",
"content": "{\"request_id\":\"req_18\",\"approved\":true}",
"annotation": "The lead explicitly approves the plan before work proceeds."
"toolName": "complete_task",
"content": "{\"task_id\":\"task_examples\"}",
"annotation": "Completing the examples unblocks the dependent test task."
},
{
"type": "system_event",
"content": "claim_next_task(bob) -> task_tests; task_lock commits owner=bob",
"annotation": "Bob claims the newly ready work without another direct assignment."
}
]
}

View File

@@ -1,46 +1,45 @@
{
"version": "s17",
"title": "Autonomous Agents",
"description": "Idle teammates can scan the task board, claim eligible work, and return to idle after completion.",
"title": "Worktree Isolation",
"description": "A task can be bound to an isolated git worktree so concurrent agents avoid stepping on each other.",
"steps": [
{
"type": "system_event",
"content": "teammate(worker-a): state=IDLE -> idle_poll()",
"annotation": "Autonomy starts from an idle lifecycle tick, not a direct user command."
"type": "user_message",
"content": "Update the docs and parser in parallel without letting the changes interfere.",
"annotation": "Concurrent edits need isolated working directories."
},
{
"type": "tool_call",
"toolName": "list_tasks",
"content": "{\"status\":\"open\"}",
"annotation": "The idle agent scans the shared task board."
"toolName": "create_worktree",
"content": "{\"task_id\":\"task_docs\",\"name\":\"docs-fix\"}",
"annotation": "The tool validates a safe worktree name before touching git."
},
{
"type": "system_event",
"content": "git worktree add .worktrees/docs-fix -b agent/docs-fix",
"annotation": "A separate branch and checkout are created for that task."
},
{
"type": "tool_result",
"toolName": "list_tasks",
"content": "[{\"id\":\"task_5\",\"status\":\"open\",\"owner\":null,\"title\":\"Update README\"}]",
"annotation": "Only unclaimed work is eligible for autonomous pickup."
},
{
"type": "tool_call",
"toolName": "claim_task",
"content": "{\"id\":\"task_5\",\"owner\":\"worker-a\"}",
"annotation": "The task manager enforces ownership before work begins."
"toolName": "create_worktree",
"content": "task_docs bound to .worktrees/docs-fix",
"annotation": "The task record stores the assigned worktree path."
},
{
"type": "system_event",
"content": "worker-a: state=WORK task=task_5",
"annotation": "The lifecycle moves from IDLE to WORK."
"content": ".worktrees/events.jsonl <- {event:\"created\", task:\"task_docs\", worktree:\"docs-fix\"}",
"annotation": "Lifecycle events are emitted as a side channel."
},
{
"type": "tool_call",
"toolName": "complete_task",
"content": "{\"id\":\"task_5\",\"result\":\"README updated with setup notes.\"}",
"annotation": "Completion writes the result back to the shared board."
"toolName": "keep_worktree",
"content": "{\"task_id\":\"task_docs\",\"reason\":\"needs human review\"}",
"annotation": "Closeout can preserve a worktree instead of deleting it immediately."
},
{
"type": "system_event",
"content": "worker-a: state=IDLE next_poll_in=5s",
"annotation": "After finishing, the agent becomes available for more work."
"type": "assistant_text",
"content": "The docs task now has an isolated worktree and can be reviewed independently from parser changes.",
"annotation": "The user sees the isolation boundary, not just a raw git command."
}
]
}

View File

@@ -1,45 +1,46 @@
{
"version": "s18",
"title": "Worktree Isolation",
"description": "A task can be bound to an isolated git worktree so concurrent agents avoid stepping on each other.",
"title": "MCP Tools",
"description": "The agent discovers external MCP tools and exposes them through a normalized tool namespace.",
"steps": [
{
"type": "user_message",
"content": "Let one teammate fix the docs while another changes the parser.",
"annotation": "Concurrent edits need isolated working directories."
"content": "Search the documentation for deployment guidance.",
"annotation": "The user asks for a tool source outside the built-in set."
},
{
"type": "tool_call",
"toolName": "create_worktree",
"content": "{\"task_id\":\"task_docs\",\"name\":\"docs-fix\"}",
"annotation": "The tool validates a safe worktree name before touching git."
"toolName": "connect_mcp",
"content": "{\"server\":\"docs\",\"command\":\"mock-docs-server\"}",
"annotation": "The runtime creates an MCP client for the named server."
},
{
"type": "system_event",
"content": "git worktree add .worktrees/docs-fix -b agent/docs-fix",
"annotation": "A separate branch and checkout are created for that task."
"content": "normalize_mcp_name(\"docs\", \"search\") -> mcp__docs__search",
"annotation": "External tools are namespaced to avoid collisions."
},
{
"type": "tool_result",
"toolName": "create_worktree",
"content": "task_docs bound to .worktrees/docs-fix",
"annotation": "The task record stores the assigned worktree path."
},
{
"type": "system_event",
"content": ".worktrees/events.jsonl <- {event:\"created\", task:\"task_docs\", worktree:\"docs-fix\"}",
"annotation": "Lifecycle events are emitted as a side channel."
"toolName": "connect_mcp",
"content": "Connected docs with tools: mcp__docs__search, mcp__docs__read",
"annotation": "Tool discovery expands the active tool pool."
},
{
"type": "tool_call",
"toolName": "keep_worktree",
"content": "{\"task_id\":\"task_docs\",\"reason\":\"needs human review\"}",
"annotation": "Closeout can preserve a worktree instead of deleting it immediately."
"toolName": "mcp__docs__search",
"content": "{\"query\":\"deployment\"}",
"annotation": "The LLM can now call the discovered tool by its normalized name."
},
{
"type": "tool_result",
"toolName": "mcp__docs__search",
"content": "[\"Deploy with npm run build\", \"Use environment variables for tokens\"]",
"annotation": "The external result is appended like any other tool result."
},
{
"type": "assistant_text",
"content": "The docs task now has an isolated worktree and can be reviewed independently from parser changes.",
"annotation": "The user sees the isolation boundary, not just a raw git command."
"content": "The docs server says to build first and keep tokens in environment variables.",
"annotation": "The agent summarizes external tool output for the user."
}
]
}

View File

@@ -1,46 +1,57 @@
{
"version": "s19",
"title": "MCP Tools",
"description": "The agent discovers external MCP tools and exposes them through a normalized tool namespace.",
"title": "Comprehensive Agent",
"description": "The final agent composes context assembly, tools, memory, teams, background work, cron, worktrees, and MCP.",
"steps": [
{
"type": "user_message",
"content": "Connect the docs server and search for deployment guidance.",
"annotation": "The user asks for a tool source outside the built-in set."
},
{
"type": "tool_call",
"toolName": "connect_mcp",
"content": "{\"server\":\"docs\",\"command\":\"mock-docs-server\"}",
"annotation": "The runtime creates an MCP client for the named server."
"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": "normalize_mcp_name(\"docs\", \"search\") -> mcp__docs__search",
"annotation": "External tools are namespaced to avoid collisions."
},
{
"type": "tool_result",
"toolName": "connect_mcp",
"content": "Connected docs with tools: mcp__docs__search, mcp__docs__read",
"annotation": "Tool discovery expands the active tool pool."
},
{
"type": "tool_call",
"toolName": "mcp__docs__search",
"content": "{\"query\":\"deployment\"}",
"annotation": "The LLM can now call the discovered tool by its normalized name."
},
{
"type": "tool_result",
"toolName": "mcp__docs__search",
"content": "[\"Deploy with npm run build\", \"Use environment variables for tokens\"]",
"annotation": "The external result is appended like any other tool result."
"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": "The docs server says to build first and keep tokens in environment variables.",
"annotation": "The agent summarizes external tool output for the user."
"content": "I'll inspect the task graph, delegate docs, start the slow scan in the background, and use the release checklist skill.",
"annotation": "The model chooses multiple mechanisms while keeping one coherent plan."
},
{
"type": "tool_call",
"toolName": "load_skill",
"content": "{\"name\":\"release-check\"}",
"annotation": "Skills contribute procedural context before execution."
},
{
"type": "tool_call",
"toolName": "spawn_teammate",
"content": "{\"name\":\"docs\",\"role\":\"Update release notes in its worktree.\"}",
"annotation": "Team delegation handles a parallel slice of the release."
},
{
"type": "tool_call",
"toolName": "bash",
"content": "npm run lint && npm run test",
"toolInput": "{\"background\":true}",
"annotation": "Long-running validation goes through the background task path."
},
{
"type": "tool_call",
"toolName": "connect_mcp",
"content": "{\"server\":\"deploy\",\"command\":\"mock-deploy-server\"}",
"annotation": "External capabilities are added only when needed."
},
{
"type": "system_event",
"content": "recover: background task done, teammate replied, MCP deploy status ready",
"annotation": "The integrated runtime folds asynchronous results back into the loop."
},
{
"type": "assistant_text",
"content": "Release preparation is ready: checks passed, docs are updated in the teammate worktree, and deployment status is available.",
"annotation": "The comprehensive agent returns a single user-facing outcome."
}
]
}

View File

@@ -1,57 +1,43 @@
{
"version": "s20",
"title": "Comprehensive Agent",
"description": "The final agent composes context assembly, tools, memory, teams, background work, cron, worktrees, and MCP.",
"title": "Workflow Runtime",
"description": "A fixed review pipeline runs in parallel, records a journal, and resumes completed agent calls from cache.",
"steps": [
{
"type": "user_message",
"content": "Plan a release: inspect tasks, run checks, delegate docs, and keep long scans in the background.",
"annotation": "The final lesson combines many earlier capabilities in one request."
"content": "Review this change across correctness, security, performance, and style.",
"annotation": "The goal is open-ended, but the review procedure has a fixed shape."
},
{
"type": "tool_call",
"toolName": "Workflow",
"content": "{\"name\":\"review-changes\",\"phases\":[\"Review\",\"Verify\"]}",
"annotation": "One tool call hands deterministic orchestration to the workflow runtime."
},
{
"type": "tool_result",
"content": "{\"status\":\"async_launched\",\"runId\":\"wf_review-changes_6779\"}",
"annotation": "The product runtime returns a claim ticket while work continues in the background."
},
{
"type": "system_event",
"content": "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'll inspect the task graph, delegate docs, start the slow scan in the background, and use the release checklist skill.",
"annotation": "The model chooses multiple mechanisms while keeping one coherent plan."
},
{
"type": "tool_call",
"toolName": "load_skill",
"content": "{\"name\":\"release-check\"}",
"annotation": "Skills contribute procedural context before execution."
},
{
"type": "tool_call",
"toolName": "spawn_teammate",
"content": "{\"name\":\"docs\",\"role\":\"Update release notes in its worktree.\"}",
"annotation": "Team delegation handles a parallel slice of the release."
},
{
"type": "tool_call",
"toolName": "bash",
"content": "npm run lint && npm run test",
"toolInput": "{\"background\":true}",
"annotation": "Long-running validation goes through the background task path."
},
{
"type": "tool_call",
"toolName": "connect_mcp",
"content": "{\"server\":\"deploy\",\"command\":\"mock-deploy-server\"}",
"annotation": "External capabilities are added only when needed."
"content": "phase=Review -> pipeline([correctness, security, performance, style])",
"annotation": "Each item advances independently through the scripted stages."
},
{
"type": "system_event",
"content": "recover: background task done, teammate replied, MCP deploy status ready",
"annotation": "The integrated runtime folds asynchronous results back into the loop."
"content": "phase=Verify -> adversarial checks run in parallel",
"annotation": "Structured results cross a validation boundary before aggregation."
},
{
"type": "assistant_text",
"content": "Release preparation is ready: checks passed, docs are updated in the teammate worktree, and deployment status is available.",
"annotation": "The comprehensive agent returns a single user-facing outcome."
"type": "system_event",
"content": "journal append -> task_notification(status=completed)",
"annotation": "Every completed agent call is checkpointed before the final notification."
},
{
"type": "system_event",
"content": "resumeFromRunId -> unchanged calls status=cached",
"annotation": "Semantic keys reuse completed work without depending on concurrency order."
}
]
}

View File

@@ -1,43 +1,37 @@
{
"version": "s21",
"title": "Workflow Runtime",
"description": "A fixed review pipeline runs in parallel, records a journal, and resumes completed agent calls from cache.",
"title": "Goal Loop",
"description": "A host-owned completion gate keeps the turn alive until trusted evidence satisfies the active goal.",
"steps": [
{
"type": "user_message",
"content": "Review this change across correctness, security, performance, and style.",
"annotation": "The goal is open-ended, but the review procedure has a fixed shape."
"content": "/goal until tests passed and deploy green",
"annotation": "The command defines the condition but sits outside the evidence window."
},
{
"type": "tool_call",
"toolName": "Workflow",
"content": "{\"name\":\"review-changes\",\"phases\":[\"Review\",\"Verify\"]}",
"annotation": "One tool call hands deterministic orchestration to the workflow runtime."
"type": "system_event",
"content": "goal_started -> evidence window reset",
"annotation": "The harness, not the working model, owns the completion gate."
},
{
"type": "assistant_text",
"content": "Tests passed and deployment is green.",
"annotation": "Assistant prose is not trusted completion evidence."
},
{
"type": "system_event",
"content": "goal_evaluated satisfied=false -> continuation queued",
"annotation": "An unmet condition pushes the loop into another bounded turn."
},
{
"type": "tool_result",
"content": "{\"status\":\"async_launched\",\"runId\":\"wf_review-changes_6779\"}",
"annotation": "The product runtime returns a claim ticket while work continues in the background."
"content": "<task_notification>tests passed; deploy green</task_notification>",
"annotation": "Only an allowlisted host event can attach a trusted evidence origin."
},
{
"type": "system_event",
"content": "phase=Review -> pipeline([correctness, security, performance, style])",
"annotation": "Each item advances independently through the scripted stages."
},
{
"type": "system_event",
"content": "phase=Verify -> adversarial checks run in parallel",
"annotation": "Structured results cross a validation boundary before aggregation."
},
{
"type": "system_event",
"content": "journal append -> task_notification(status=completed)",
"annotation": "Every completed agent call is checkpointed before the final notification."
},
{
"type": "system_event",
"content": "resumeFromRunId -> unchanged calls status=cached",
"annotation": "Semantic keys reuse completed work without depending on concurrency order."
"content": "goal_evaluated satisfied=true -> goal_completed",
"annotation": "Trusted evidence closes the goal and releases the stop gate."
}
]
}

View File

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

View File

@@ -1,10 +1,10 @@
{
"meta": { "title": "Learn Claude Code", "description": "Build a nano Claude Code-like agent from 0 to 1, one mechanism at a time" },
"nav": { "home": "Home", "timeline": "Timeline", "compare": "Compare", "layers": "Layers", "github": "GitHub" },
"home": { "hero_title": "Learn Claude Code", "hero_subtitle": "Build a nano Claude Code-like agent from 0 to 1, one mechanism at a time", "start": "Start Learning", "core_pattern": "The Core Pattern", "core_pattern_desc": "Every AI coding agent shares the same loop: call the model, execute tools, feed results back. Production systems add policy, permissions, and lifecycle layers on top.", "learning_path": "Learning Path", "learning_path_desc": "22 progressive sessions, from a simple loop to deterministic orchestration and goal closure", "layers_title": "Architectural Layers", "layers_desc": "Five orthogonal concerns that compose into a complete agent", "loc": "LOC", "learn_more": "Learn More", "versions_in_layer": "versions", "message_flow": "Message Growth", "message_flow_desc": "Watch the messages array grow as the agent loop executes" },
"home": { "hero_title": "Learn Claude Code", "hero_subtitle": "Build a nano Claude Code-like agent from 0 to 1, one mechanism at a time", "start": "Start Learning", "core_pattern": "The Core Pattern", "core_pattern_desc": "Every AI coding agent shares the same loop: call the model, execute tools, feed results back. The harness adds policy, permissions, memory, coordination, and lifecycle control around it.", "learning_path": "Learning Path", "learning_path_desc": "21 progressive sessions, from a simple loop to deterministic orchestration and goal closure", "layers_title": "Architectural Layers", "layers_desc": "Five orthogonal concerns that compose into a complete agent", "loc": "LOC", "learn_more": "Learn More", "versions_in_layer": "versions", "message_flow": "Message Growth", "message_flow_desc": "Watch the messages array grow as the agent loop executes" },
"version": { "loc": "lines of code", "tools": "tools", "new": "New", "prev": "Previous", "next": "Next", "view_source": "View Source", "view_diff": "View Diff", "design_decisions": "Design Decisions", "whats_new": "What's New", "tutorial": "Tutorial", "simulator": "Agent Loop Simulator", "execution_flow": "Execution Flow", "architecture": "Architecture", "concept_viz": "Concept Visualization", "alternatives": "Alternatives Considered", "tab_learn": "Learn", "tab_simulate": "Simulate", "tab_code": "Code", "tab_deep_dive": "Deep Dive" },
"sim": { "play": "Play", "pause": "Pause", "step": "Step", "reset": "Reset", "speed": "Speed", "step_of": "of" },
"timeline": { "title": "Learning Path", "subtitle": "s01 to s22: Progressive Agent Harness Design", "layer_legend": "Layer Legend", "loc_growth": "LOC Growth", "learn_more": "Learn More" },
"timeline": { "title": "Learning Path", "subtitle": "s01 to s21: Progressive Agent Harness Design", "layer_legend": "Layer Legend", "loc_growth": "LOC Growth", "learn_more": "Learn More" },
"layers": {
"title": "Architectural Layers",
"subtitle": "Five orthogonal concerns that compose into a complete agent",
@@ -53,14 +53,13 @@
"s12": "Task System",
"s13": "Background Tasks",
"s14": "Cron Scheduler",
"s15": "Agent Teams: Runtime Lab",
"s16": "Agent Teams: Protocol Lab",
"s17": "Autonomous Agents",
"s18": "Worktree Isolation",
"s19": "MCP Tools",
"s20": "Comprehensive Agent Turn",
"s21": "Workflow Runtime",
"s22": "Goal Loop"
"s15": "Agent Teams",
"s16": "Autonomous Agents",
"s17": "Worktree Isolation",
"s18": "MCP Tools",
"s19": "Comprehensive Agent",
"s20": "Workflow Runtime",
"s21": "Goal Loop"
},
"layer_labels": {
"tools": "Tools & Execution",
@@ -84,13 +83,12 @@
"s12": "Task Board Dependencies",
"s13": "Background Task Lanes",
"s14": "Cron Scheduler",
"s15": "Agent Teams Runtime Lab",
"s16": "Agent Teams Protocol Lab",
"s17": "Autonomous Agent Cycle",
"s18": "Worktree Task Isolation",
"s19": "MCP Tool Bridge",
"s20": "Comprehensive Agent Turn",
"s21": "Workflow Runtime",
"s22": "Goal Completion Gate"
"s15": "Agent Teams and Protocols",
"s16": "Autonomous Agent Cycle",
"s17": "Worktree Task Isolation",
"s18": "MCP Tool Bridge",
"s19": "Comprehensive Agent Turn",
"s20": "Workflow Runtime",
"s21": "Goal Completion Gate"
}
}

View File

@@ -1,10 +1,10 @@
{
"meta": { "title": "Learn Claude Code", "description": "0 から 1 へ nano Claude Code-like agent を構築し、毎回 1 つの仕組みを追加" },
"nav": { "home": "ホーム", "timeline": "学習パス", "compare": "バージョン比較", "layers": "アーキテクチャ層", "github": "GitHub" },
"home": { "hero_title": "Learn Claude Code", "hero_subtitle": "0 から 1 へ nano Claude Code-like agent を構築し、毎回 1 つの仕組みを追加", "start": "学習を始める", "core_pattern": "コアパターン", "core_pattern_desc": "すべての AI コーディングエージェントは同じループを共有する:モデルを呼び出し、ツールを実行し、結果を返す。実運用ではこの上にポリシー、権限、ライフサイクル層が重なる。", "learning_path": "学習パス", "learning_path_desc": "22の段階的セッション、シンプルなループから決定的な編成と目標完了まで", "layers_title": "アーキテクチャ層", "layers_desc": "5つの直交する関心事が完全なエージェントを構成", "loc": "行", "learn_more": "詳細を見る", "versions_in_layer": "バージョン", "message_flow": "メッセージの増加", "message_flow_desc": "エージェントループ実行時のメッセージ配列の成長を観察" },
"home": { "hero_title": "Learn Claude Code", "hero_subtitle": "0 から 1 へ nano Claude Code-like agent を構築し、毎回 1 つの仕組みを追加", "start": "学習を始める", "core_pattern": "コアパターン", "core_pattern_desc": "すべての AI コーディングエージェントは同じループを共有する:モデルを呼び出し、ツールを実行し、結果を返す。Harness はその周囲にポリシー、権限、記憶、協調、ライフサイクル制御を加える。", "learning_path": "学習パス", "learning_path_desc": "21の段階的セッション、シンプルなループから決定的な編成と目標完了まで", "layers_title": "アーキテクチャ層", "layers_desc": "5つの直交する関心事が完全なエージェントを構成", "loc": "行", "learn_more": "詳細を見る", "versions_in_layer": "バージョン", "message_flow": "メッセージの増加", "message_flow_desc": "エージェントループ実行時のメッセージ配列の成長を観察" },
"version": { "loc": "行のコード", "tools": "ツール", "new": "新規", "prev": "前のバージョン", "next": "次のバージョン", "view_source": "ソースを見る", "view_diff": "差分を見る", "design_decisions": "設計判断", "whats_new": "新機能", "tutorial": "チュートリアル", "simulator": "エージェントループシミュレーター", "execution_flow": "実行フロー", "architecture": "アーキテクチャ", "concept_viz": "コンセプト可視化", "alternatives": "検討された代替案", "tab_learn": "学習", "tab_simulate": "シミュレーション", "tab_code": "ソースコード", "tab_deep_dive": "詳細分析" },
"sim": { "play": "再生", "pause": "一時停止", "step": "ステップ", "reset": "リセット", "speed": "速度", "step_of": "/" },
"timeline": { "title": "学習パス", "subtitle": "s01からs22へ:段階的エージェント Harness 設計", "layer_legend": "レイヤー凡例", "loc_growth": "コード量の推移", "learn_more": "詳細を見る" },
"timeline": { "title": "学習パス", "subtitle": "s01からs21へ:段階的エージェント Harness 設計", "layer_legend": "レイヤー凡例", "loc_growth": "コード量の推移", "learn_more": "詳細を見る" },
"layers": {
"title": "アーキテクチャ層",
"subtitle": "5つの直交する関心事が完全なエージェントを構成",
@@ -53,14 +53,13 @@
"s12": "タスクシステム",
"s13": "バックグラウンドタスク",
"s14": "Cron スケジューラー",
"s15": "Agent Teams:ランタイム実験",
"s16": "Agent Teamsプロトコル実験",
"s17": "自律エージェント",
"s18": "Worktree 分離",
"s19": "MCP ツール",
"s20": "Comprehensive Agent Turn",
"s21": "Workflow Runtime",
"s22": "Goal Loop"
"s15": "Agent Teams",
"s16": "自律エージェント",
"s17": "Worktree 分離",
"s18": "MCP ツール",
"s19": "Comprehensive Agent",
"s20": "Workflow Runtime",
"s21": "Goal Loop"
},
"layer_labels": {
"tools": "ツールと実行",
@@ -84,13 +83,12 @@
"s12": "タスクボード依存関係",
"s13": "バックグラウンドタスクレーン",
"s14": "Cron スケジューラー",
"s15": "Agent Teams ランタイム実験",
"s16": "Agent Teams プロトコル実験",
"s17": "自律エージェントサイクル",
"s18": "Worktree タスク分離",
"s19": "MCP ツールブリッジ",
"s20": "Comprehensive Agent Turn",
"s21": "Workflow Runtime",
"s22": "目標完了ゲート"
"s15": "Agent Teams と協調プロトコル",
"s16": "自律エージェントサイクル",
"s17": "Worktree タスク分離",
"s18": "MCP ツールブリッジ",
"s19": "Comprehensive Agent Turn",
"s20": "Workflow Runtime",
"s21": "目標完了ゲート"
}
}

View File

@@ -1,10 +1,10 @@
{
"meta": { "title": "Learn Claude Code", "description": "从 0 到 1 构建 nano Claude Code-like agent每次只加一个机制" },
"nav": { "home": "首页", "timeline": "学习路径", "compare": "版本对比", "layers": "架构层", "github": "GitHub" },
"home": { "hero_title": "Learn Claude Code", "hero_subtitle": "从 0 到 1 构建 nano Claude Code-like agent每次只加一个机制", "start": "开始学习", "core_pattern": "核心模式", "core_pattern_desc": "所有 AI 编程 Agent 共享同一个循环:调用模型、执行工具、回传结果。生产级系统会在其上叠加策略、权限和生命周期。", "learning_path": "学习路径", "learning_path_desc": "22 个渐进式课程,从简单循环到确定性编排与目标闭环", "layers_title": "架构层次", "layers_desc": "五个正交关注点组合成完整的 Agent", "loc": "行", "learn_more": "了解更多", "versions_in_layer": "个版本", "message_flow": "消息增长", "message_flow_desc": "观察 Agent 循环执行时消息数组的增长" },
"home": { "hero_title": "Learn Claude Code", "hero_subtitle": "从 0 到 1 构建 nano Claude Code-like agent每次只加一个机制", "start": "开始学习", "core_pattern": "核心模式", "core_pattern_desc": "所有 AI 编程 Agent 共享同一个循环:调用模型、执行工具、回传结果。Harness 在循环周围加入策略、权限、记忆、协作与生命周期控制。", "learning_path": "学习路径", "learning_path_desc": "21 个渐进式课程,从简单循环到确定性编排与目标闭环", "layers_title": "架构层次", "layers_desc": "五个正交关注点组合成完整的 Agent", "loc": "行", "learn_more": "了解更多", "versions_in_layer": "个版本", "message_flow": "消息增长", "message_flow_desc": "观察 Agent 循环执行时消息数组的增长" },
"version": { "loc": "行代码", "tools": "个工具", "new": "新增", "prev": "上一版", "next": "下一版", "view_source": "查看源码", "view_diff": "查看变更", "design_decisions": "设计决策", "whats_new": "新增内容", "tutorial": "教程", "simulator": "Agent 循环模拟器", "execution_flow": "执行流程", "architecture": "架构", "concept_viz": "概念可视化", "alternatives": "替代方案", "tab_learn": "学习", "tab_simulate": "模拟", "tab_code": "源码", "tab_deep_dive": "深入探索" },
"sim": { "play": "播放", "pause": "暂停", "step": "单步", "reset": "重置", "speed": "速度", "step_of": "/" },
"timeline": { "title": "学习路径", "subtitle": "s01 到 s22:渐进式 Agent Harness 设计", "layer_legend": "层次图例", "loc_growth": "代码量增长", "learn_more": "了解更多" },
"timeline": { "title": "学习路径", "subtitle": "s01 到 s21:渐进式 Agent Harness 设计", "layer_legend": "层次图例", "loc_growth": "代码量增长", "learn_more": "了解更多" },
"layers": {
"title": "架构层次",
"subtitle": "五个正交关注点组合成完整的 Agent",
@@ -53,14 +53,13 @@
"s12": "Task System",
"s13": "Background Tasks",
"s14": "Cron Scheduler",
"s15": "Agent Teams:运行时实验",
"s16": "Agent Teams协议实验",
"s17": "Autonomous Agents",
"s18": "Worktree Isolation",
"s19": "MCP Tools",
"s20": "Comprehensive Agent Turn",
"s21": "Workflow Runtime",
"s22": "Goal Loop"
"s15": "Agent Teams",
"s16": "Autonomous Agents",
"s17": "Worktree Isolation",
"s18": "MCP Tools",
"s19": "Comprehensive Agent",
"s20": "Workflow Runtime",
"s21": "Goal Loop"
},
"layer_labels": {
"tools": "工具与执行",
@@ -84,13 +83,12 @@
"s12": "任务看板依赖",
"s13": "Background Task Lanes",
"s14": "Cron Scheduler",
"s15": "Agent Teams 运行时实验",
"s16": "Agent Teams 协议实验",
"s17": "Autonomous Agent Cycle",
"s18": "Worktree Task Isolation",
"s19": "MCP Tool Bridge",
"s20": "Comprehensive Agent Turn",
"s21": "Workflow Runtime",
"s22": "目标完成闸门"
"s15": "Agent Teams 与协作协议",
"s16": "Autonomous Agent Cycle",
"s17": "Worktree Task Isolation",
"s18": "MCP Tool Bridge",
"s19": "Comprehensive Agent Turn",
"s20": "Workflow Runtime",
"s21": "目标完成闸门"
}
}

View File

@@ -22,7 +22,6 @@ export const VERSION_ORDER = [
"s19",
"s20",
"s21",
"s22",
] as const;
export const LEARNING_PATH = VERSION_ORDER;
@@ -150,68 +149,60 @@ export const VERSION_META: Record<string, {
prevVersion: "s13",
},
s15: {
title: "Agent Teams: Runtime Lab",
subtitle: "Persistent Teammates and Mailboxes",
coreAddition: "Teammate mailboxes",
keyInsight: "Persistent teammates let work continue in parallel without stuffing every thought into one context.",
title: "Agent Teams",
subtitle: "Persistent Teammates and Coordination Protocols",
coreAddition: "Team runtime and typed protocols",
keyInsight: "A Lead can coordinate persistent teammates when message delivery, approval, and shutdown belong to the runtime.",
layer: "collaboration",
prevVersion: "s14",
},
s16: {
title: "Agent Teams: Protocol Lab",
subtitle: "Typed Requests, Replies, and Handshakes",
coreAddition: "Shared coordination protocols",
keyInsight: "Multi-agent systems need explicit message contracts, not vibes.",
title: "Autonomous Agents",
subtitle: "Check the Board, Claim the Task",
coreAddition: "Autonomous task claiming",
keyInsight: "Idle teammates can discover ready work when claiming is atomic and respects task dependencies.",
layer: "collaboration",
prevVersion: "s15",
},
s17: {
title: "Autonomous Agents",
subtitle: "Check the Board, Claim the Task",
coreAddition: "Autonomous task claiming",
keyInsight: "Teammates become useful when they can discover and claim work themselves.",
layer: "collaboration",
prevVersion: "s16",
},
s18: {
title: "Worktree Isolation",
subtitle: "Separate Directories, No Conflicts",
coreAddition: "Worktree lifecycle",
keyInsight: "Parallel agents need isolated filesystems as much as isolated conversations.",
layer: "collaboration",
prevVersion: "s17",
prevVersion: "s16",
},
s19: {
s18: {
title: "MCP Tools",
subtitle: "External Tools, Standard Protocol",
coreAddition: "MCP tool bridge",
keyInsight: "External services can become agent tools through a standard discovery and call protocol.",
layer: "collaboration",
prevVersion: "s18",
prevVersion: "s17",
},
s20: {
s19: {
title: "Comprehensive Agent",
subtitle: "All Mechanisms, One Loop",
coreAddition: "Integrated harness",
keyInsight: "The final harness is still one loop, now surrounded by the systems that make it production-shaped.",
keyInsight: "The complete harness is still one loop, surrounded by the systems introduced across the course.",
layer: "collaboration",
prevVersion: "s19",
prevVersion: "s18",
},
s21: {
s20: {
title: "Workflow Runtime",
subtitle: "Scripts Own Fixed Orchestration",
coreAddition: "Resumable workflow runtime",
keyInsight: "When orchestration has a fixed shape, code can make it parallel, deterministic, and resumable.",
layer: "concurrency",
prevVersion: "s20",
prevVersion: "s19",
},
s22: {
s21: {
title: "Goal Loop",
subtitle: "Trusted Evidence Decides When to Stop",
coreAddition: "Goal completion gate",
keyInsight: "A durable goal keeps the loop working until trusted evidence satisfies an explicit condition.",
layer: "planning",
prevVersion: "s21",
prevVersion: "s20",
},
};
@@ -226,7 +217,7 @@ export const LAYERS = [
id: "planning" as const,
label: "Planning & Control",
color: "#10B981",
versions: ["s05", "s06", "s07", "s10", "s11", "s22"],
versions: ["s05", "s06", "s07", "s10", "s11", "s21"],
},
{
id: "memory" as const,
@@ -238,12 +229,12 @@ export const LAYERS = [
id: "concurrency" as const,
label: "Concurrency & Scheduling",
color: "#F59E0B",
versions: ["s13", "s14", "s21"],
versions: ["s13", "s14", "s20"],
},
{
id: "collaboration" as const,
label: "Multi-Agent Platform",
color: "#EF4444",
versions: ["s12", "s15", "s16", "s17", "s18", "s19", "s20"],
versions: ["s12", "s15", "s16", "s17", "s18", "s19"],
},
] as const;