算法可视化与交互学习平台

Coding Agent Engineering:让 Agent 在真实仓库中工作Coding Agents: Repository Understanding, Editing and Verification

No.17 建立 Action → Observation 控制循环,No.18 让 Agent 能规划与 Replan,No.19 让任务可以 checkpoint / resume;No.20 把这些能力放进真实 Git repository。用户下载完整示例包和本地 Qwen2.5-Coder-1.5B-Instruct,浏览器直连 127.0.0.1:4891 的 Mini Coding Agent Runner:模型提出搜索、计划、诊断与交付候选,确定性 Runtime 负责路径授权、真实文件修改、Git、build、lint、test 和 receipts。六个递进实验共用一次模型加载,在隔离 Todo CLI 仓库中真实经历定位、首轮失败、重规划、修复、验证与 diff 审查,也可在明确批准后切换到自选仓库;全程不使用预填成功 trace。

RAG & AgentsAdvancedFree
KernelGPU

Module runtime · real local repository

No.20 统一 Coding Agent 运行环境

六张实验卡共享同一 Runner、代码模型、workspace 配置与人工批准状态。fixture 的每个 run 都会复制出独立 Git 工作副本,卡片之间不继承文件或 receipts; 不会修改解压后的 Runner 示例包;custom 只在你明确填写绝对路径后启用,其中 Patch / Mission 写入要求 clean Git baseline。默认不批准写文件或运行命令。

Runner · 待检查Local model · 待检查
先确认文件去向:实验修改不会写回 ZIP 解压目录

fixture 的真实仓库在 %TEMP%\algolab-coding-agent-runs\<run-id>\workspace,隐藏 Git 目录在 workspace\.git,Diff 与 Git 状态分别在同一 run 的 artifacts\git.diffartifacts\git-status.txt

custom 使用你填写的目录,但选择模式或点击运行都不会自动 git init;写入任务要求它事先是 clean Git repository。

查看完整目录地图 ↓

首次准备:下载完整包,再由用户明确下载本地模型

ZIP 不含模型权重。解压后任选下面一组命令;下载器默认保存 Qwen2.5-Coder-1.5B-Instruct,写入权重来源与逐文件 SHA-256,Runner 启动后保持离线加载。

下载 No.20 完整 ZIP
Windows PowerShell · Python 3.12
py -3.12 -m venv .venv
& .\.venv\Scripts\python.exe -m pip install -r .\requirements.txt
& .\.venv\Scripts\python.exe .\download_model.py
.\run.ps1 -PythonPath .\.venv\Scripts\python.exe
Linux / macOS
python3 -m venv .venv
./.venv/bin/python -m pip install -r ./requirements.txt
./.venv/bin/python ./download_model.py
chmod +x run.sh && ./run.sh ./.venv/bin/python

内存不足时,可在下载命令后加 --model Qwen/Qwen2.5-Coder-0.5B-Instruct。模型加载一次后,六张实验卡共享同一进程。

尚未检查本机 4891 Coding Agent Runner。
填写本地模型目录并连接 Runner 后检查;页面不会自动下载模型。

Workspace scope

页面不会扫描磁盘或自动选择仓库;实际 canonical path、Git root 与 writable scope 由本地 Runner 再次校验。

fixture:工作副本位于 %TEMP%\algolab-coding-agent-runs\<run-id>\workspace,解压目录只提供 Runner 与不可变模板。

custom:选择模式或点击实验按钮都不会自动执行 git init。Patch / Mission 写入要求目录已经初始化 Git、有 baseline commit 且工作树干净。

本次运行的人工批准

运行后到哪里找工作仓库、Diff 与 Git 状态?

ZIP 解压目录、fixture 工作仓库和 run artifacts 是三个不同位置。每张实验卡都会创建新的 run;完成后请在该卡片的“本次 run 的本地文件位置”中复制精确绝对路径。

当前选择 · fixture
① ZIP 解压目录 · 执行器
…\coding_agent_local\

保存 Runner、prompt、schema 与只读 fixture 模板。fixture 实验不会在这里创建 .git,也不会修改这里的源码。

② fixture run · 独立真实仓库
<run-root> = %TEMP%\algolab-coding-agent-runs\<run-id>
工作仓库 = <run-root>\workspace
隐藏 Git 目录 = <run-root>\workspace\.git
Diff 产物 = <run-root>\artifacts\git.diff
Git 状态 = <run-root>\artifacts\git-status.txt

git.diffgit-status.txt 是审查快照;真正的代码变化位于同一 run 的 workspace。Windows 资源管理器需开启“隐藏的项目”才能看到 .git

③ custom · 用户指定仓库
尚未填写绝对路径

custom 不会复制仓库,也不会自动初始化、commit、reset 或清理改动。Patch / Mission 遇到非 Git 仓库会以 not_git_repository 停止,baseline 不干净则以 dirty_baseline 停止;artifacts 仍保存在独立 run 临时目录,不写进 custom 仓库。

只创建或填写一个空文件夹不等于配置了代码仓库。它默认也不是 ZIP 解压目录;请另选包含真实源码/测试的任务仓库,不要把 Runner 自己的 coding_agent_local 目录当作修改目标。

A. 使用自己的真实项目

不需要复制示例文件。直接把上方 custom 路径指向项目的 Git 根目录。已有 Git 仓库不要重新初始化;先按项目自己的流程提交或妥善处理现有改动,再确认 git status --short 没有输出。不要在不理解内容时直接执行 git add -A

  • 目录中应有真实源码、测试和项目自己的依赖/构建配置。
  • Patch / Mission 写入前必须有 .git、至少一个 HEAD commit 和 clean baseline。
  • 需要修改时开启“允许受限写入”;需要 test / lint / build 时再开启“允许白名单命令”。

B. 使用 No.20 教学项目

从 ZIP 解压目录中只复制 fixture/ 里面的内容到一个新的空 TEMP_REPO。其中 todo/exporter.py 保留 NotImplementedErrortests/test_csv_export.py 保留测试入口;这是预期的任务 baseline,等待 Agent 补全实现和验收测试。

TEMP_REPO/
├─ README.md
├─ todo/
│  ├─ __init__.py
│  ├─ cli.py
│  ├─ storage.py
│  └─ exporter.py
└─ tests/
   ├─ __init__.py
   └─ test_csv_export.py

不要复制:runner/prompts/schemas/models/run.ps1requirements.txtalgolab_local_runner.py;这些属于执行器,不是目标仓库代码。

Windows:复制教学 fixture 并初始化 Git baseline

下面命令应在 ZIP 解压后的 coding_agent_local 目录执行,并会在复制前拒绝非空目标。若 Git 提示缺少提交身份,请先按 Git 提示配置您自己的 user.nameuser.email,再重新执行 commit。

# 请先在 PowerShell 进入 ZIP 解压后的 coding_agent_local 目录
$customRepo = Join-Path $env:USERPROFILE "AlgoLab\TEMP_REPO"

# 只允许复制到不存在或完全为空的目录,避免覆盖用户文件
if (Test-Path -LiteralPath $customRepo) {
  if (Get-ChildItem -LiteralPath $customRepo -Force) {
    throw "TEMP_REPO 必须为空;请换一个新目录,避免覆盖已有文件。"
  }
} else {
  New-Item -ItemType Directory -Path $customRepo | Out-Null
}

Copy-Item -Path ".\fixture\*" -Destination $customRepo -Recurse

# 建立可审查的 Git baseline
git -C $customRepo init
git -C $customRepo status --short
git -C $customRepo add README.md todo tests
git -C $customRepo diff --cached --stat
git -C $customRepo commit -m "baseline: G-TODO-CSV fixture"

# 两项验收:HEAD 必须存在;最后一条命令必须没有输出
git -C $customRepo rev-parse --verify HEAD
git -C $customRepo status --short
初始化完成标准:rev-parse --verify HEAD 返回 commit;最后一次 git status --short 完全没有输出。Windows 资源管理器可能隐藏 .git,请以这两条 Git 命令为准。
运行模式不会互相替代:Scope / Inspect 只读;Verify 只验证当前代码;Review 只审查已有 Git diff;只有 Patch / Mission 会生成并应用代码修改。Runner 永远不会替用户自动执行 git init、commit、reset、stash 或清理工作树。
模式能力:custom 的 Scope / Inspect 可以只读查看非 Git 或 dirty 目录;Verify 只运行允许的验证命令;Review 需要 Git 才能产生 status / diff;只有 Patch / Mission 会写入,并强制 clean Git baseline。无论哪种模式,artifacts 都通过对应实验卡的下载链接获取。
完整示例包:Runner、Mini Coding Agent、fixture 仓库与测试

下载后在本机运行,网页只连接 127.0.0.1:4891

ZIP 包包含可审计源码、隔离 fixture、真实 Git/patch/build/lint/test 流程和启动脚本。Runner 不会自动下载模型,也不会把仓库上传到 AlgoLab 服务端。

下载完整示例包 ZIP
先理解系统边界,再逐文件阅读

一套让本地模型在真实 Git 仓库里工作的完整工程,而不是一段自动改代码的演示

根目录负责准备模型与启动 4891,runner/ 把 HTTP Job、LLM Decision 和可信执行层连接起来,agent.py 提供受限文件、Patch、命令与 Checkpoint 原语,fixture/ 提供可复制的真实 Git 任务,tests/ 则在不下载模型时验证同一条安全与修复闭环。

1
模型只提议

本地 Qwen 只返回受 schema 约束的 plan、搜索目标、候选 Patch、diagnosis 和 review;它拿不到文件句柄,也不能提交 shell 文本。

2
Runtime 控制副作用

CodingAgentRuntime 校验 Decision、检查写入与命令批准,再调用 WorkspaceAdapter 和 CommandRunner;路径、命令、时间、输出与 artifact 都有确定性边界。

3
仓库证据决定下一步

文件清单、搜索命中、读取片段、精确 Patch receipt、真实进程退出码、git status 与 git diff 才是可审计事实;模型的文字不能替代执行结果。

4
验证形成因果闭环

mission 必须先让真实 unittest 因三类 CSV escaping 缺陷失败,再把 receipt 交给模型诊断与重规划;修复后重跑同一测试,并通过 tabnanny、内存 compile 和最终 Git diff 审查。

文档结构:六个文件角色共同组成可运行、可验证的 Coding Agent

每个标签都对应 ZIP 与 manifest 中的真实文件;点击后会在下方同步打开完整内容和逐文件解释。

文件标签可交互
8 files
根目录 · 准备、发布与启动

从包级说明、依赖与模型溯源,到 Windows/POSIX 启动脚本及两个等价的 Python 服务入口。

4 files
公开 API 与仓库工程原语

顶层 API、受限文件/Patch/Checkpoint/命令原语、确定性 Mini Agent CLI,以及把 fixture 复制为临时 Git 仓库的工厂。

6 files
runner/ · 六阶段控制器

实现严格 Decision、真实/测试模型策略、六模式编排、异步 Job 与 4891 HTTP 协议,把模型提议接到可信仓库原语。

5 files
prompts/ + schemas/ · 模型与请求契约

三份提示词约束常规 Decision、mission 因果链与一次格式修复;两份 JSON Schema 公开模型输出和页面请求的机器可读边界。

7 files
fixture/ · 可复制的真实 Git 教学仓库

一个尚未完成 CSV export 的最小 Python 项目:已有存储与 list CLI,缺失 exporter 实现和验收测试,供 Agent 真实修改并产生可重复的失败。

3 files
tests/ · 不下载模型也能运行的工程回归

分别验证底层 workspace/patch/command 原语,以及六模式 Runtime、FakeModelPolicy、Job、API helper、批准与 artifact 边界。

文件调用关系:模型候选如何变成仓库证据

箭头表示一次 run 中的控制或数据推进;不同泳道刻意区分模型建议、确定性执行、仓库事实和最终验收。横向内容可滚动查看。

启动 / HTTPLLM DecisionRepository tools验证 / 审查无模型回归
准备模型 → 启动 4891 → 创建与轮询 Job

模型由用户显式下载;指定的 Python 启动 loopback 服务,浏览器以 HTTP 创建异步 run,并按 trace seq 增量读取状态或协作式取消。

准备可复查环境

安装固定推理依赖,下载允许的 Qwen,并记录 revision、逐文件大小与 SHA-256。

使用明确的 Python

Windows 或 POSIX 脚本不猜虚拟环境,只转交用户给出的解释器和 4891 参数。

Loopback HTTP

检查本地模型文件,创建/查询/取消 run,并只开放五类固定 artifact。

异步 Job 生命周期

维护 queued/running/terminal、增量 trace、取消事件、路径脱敏和进程内模型复用。

边界:HTTP 服务默认只监听 127.0.0.1:4891;模型路径和 custom workspace 路径只以名称或 SHA-256 出现在公共快照中。

仓库上下文 → 本地 Qwen → 候选 Coding Decision

Runtime 只提供当前 stage 所需的公开仓库证据、批准状态与 schema;模型返回候选计划、定位、Patch、诊断或审查意见,随后再次接受严格校验。

Stage-specific context

scope、inspect、patch、verify、review、mission 各自获得有界上下文和候选约束。

本地模型适配
LLM

只从本地目录加载 Qwen,按 path/device/dtype 缓存,串行生成并响应 deadline/cancel。

严格 Decision

必须是唯一 JSON 对象,字段、candidate、Patch 数量、诊断和 review 均受固定协议限制。

一次有界修复

若第一次输出非法,Runtime 用验证错误和同一 schema 请求一次替换 JSON;再次失败即停止。

边界:模型永远不接收 WorkspaceAdapter、subprocess 或任意 shell 能力;即使 JSON 合法,批准门和 Runtime 的阶段规则仍可拒绝它。

合法 Decision → 仓库搜索、精确修改与 Git 证据

所有仓库动作都通过 canonical workspace adapter;写入前建立 Checkpoint,全部 old-text 唯一命中后才进行原子事务,最终由 Git 展示真实变化。

创建隔离 fixture 或锁定 custom root

fixture 被复制并初始化为临时 Git 仓库;custom 写入要求用户指定路径且 baseline clean。

搜索与读取

只遍历 workspace 内普通 UTF-8 文件,拒绝绝对路径、父级穿越、symlink 逃逸和超限读取。

Checkpoint + 多文件事务

记录写前快照,校验每个精确 preimage,原子写入四个文件;中途失败会反向回滚。

git status + git diff

Runtime 使用固定 command ID 获取工作树状态与未暂存 diff,并保存为最终 artifacts。

边界:custom 仓库不会继承 fixture 的预审代码:模型必须先读真实文件并给出 exact old→new;Runtime 仍拒绝脏基线、重复目标和范围外路径。

真实失败 → 模型诊断与重规划 → 同一测试通过 → 最终审查

mission 的第一版手写 CSV 拼接必须产生非零测试 receipt;模型只能依据该输出诊断,Runtime 应用 csv.writer 修复后重跑,并补齐 lint、build 和 Git 审查。

Plan-v1 修改四个文件

CLI、exporter、五项验收测试与 README 作为一个事务落盘,exporter 暂用有缺陷的手写拼接。

真实 unittest 失败
EXIT 1

逗号、双引号和嵌入换行三个测试真实失败;exit code 与受限输出成为诊断 receipt。

Diagnosis + Plan-v2

本地模型引用失败证据并提议 csv.writer 候选;Runtime 只替换已诊断的 exporter 缺陷。

同测通过 + 扩展验收
1 → 0 → 0 → 0

同一 unittest 变为五项通过,随后 tabnanny 与不写产物的内存 compile 都必须为零退出。

Git 与模型双重 review

Runtime 先取得 status/diff;模型只能基于测试 receipts 和 diff 给出 approve/revise/blocked。

边界:verify 模式会故意保留失败仓库用于教学诊断;只有 mission 才要求修复、复测、lint/build 和最终 approve 全部完成。

FakeModelPolicy → 同一 Runtime → 无模型安全回归

测试双替身只替代文本生成,不绕过 CodingAgentRuntime、WorkspaceAdapter、CommandRunner、真实 Git 或真实 unittest,因此无需模型权重也能稳定验证工程边界。

确定性候选 Decision

FakeModelPolicy 按 stage 返回与真实 Qwen 相同 schema,可选择非法首包以测试一次 repair。

底层原语回归

验证路径逃逸、精确 diff、事务回滚、Checkpoint 批准、命令 allowlist、超时与输出上限。

六模式与闭环回归

真实临时 Git fixture 跑 scope 到 mission,并断言 first test 三项失败、second test 五项通过和最终 diff。

Job/API/artifact 回归

验证增量 seq、异步 Job、请求体上限、模型预检不加载权重、路径脱敏和 artifact allowlist。

边界:FakeModelPolicy 证明控制面与真实仓库动作;它不证明某台机器上的 Qwen 权重、显存或生成质量,真实模型仍需用户显式下载后单独运行。

正在读取发布 manifest…
1

No.17–19 让 Agent 会行动、规划和恢复,No.20 让它对真实仓库负责

No.17 的 Runtime 能把模型候选动作变成可验证的 Action 与 Observation;No.18 用 Goal、Plan、Ledger 和 Replan 对完整任务负责;No.19 又让这些状态可以压缩、checkpoint 与 resume。但如果工具只会查知识、算数字或操作一份虚构状态,系统还没有跨进 Coding Agent 最关键的边界:读取用户已有代码,在有限范围内产生真实文件和命令副作用,并用仓库自己的验证系统证明修改成立。

User Goal → Inspect Repository → Build Plan → Search / Read → Edit → Test → Diagnose Failure → Replan → Verify Diff → Final Summary

本章不是浏览器动画。先下载页面提供的完整 ZIP,用 download_model.pyQwen/Qwen2.5-Coder-1.5B-Instruct 保存到本机,再启动 127.0.0.1:4891。六张实验卡共用同一个模型进程;浏览器只发送目标和审批,所有源码、模型、Git 与终端输出都留在用户电脑。模型负责提出可审查的计划、诊断和总结,Runtime 才拥有路径检查、Patch、命令与验收的执行权。

贯穿任务是下载包中的 G-TODO-CSV:一个真实 Python Todo CLI 已能读取并列出待办,现在要新增 python -m todo.cli export-csv --db todos.json --output todos.csv。修改准确落到 todo/cli.pytodo/exporter.pytests/test_csv_export.pyREADME.md;第一版故意用朴素字符串拼接,普通行和空列表测试通过,而逗号、双引号和内嵌换行三个独立断言真实失败。Agent 必须把真实 unittest 输出交给本地模型诊断,再由 Runtime 验证最小修复。

2

Repository Task Contract 同时约束目标、验收、范围与副作用

一个可执行仓库任务不是一句需求,而是 Goal、Acceptance Criteria、Workspace、Constraints、允许的 Side Effects 与 Permission Policy 的联合契约。

用户目标与期望交付物
User goal and requested deliverables
可由测试、构建和人工检查验证的验收条件
Acceptance criteria verified by tests, builds, and review
显式授权的 workspace roots 与仓库基线
Explicit workspace roots and repository baseline
语言、依赖、兼容性、时间和成本约束
Language, dependency, compatibility, time, and cost constraints
本任务允许产生的文件与命令副作用集合
Allowed file and command side effects
沙箱规则、审批门和禁止操作
Sandbox rules, approval gates, and prohibited operations

G-TODO-CSV 的验收

AC1:CLI 接受 export-csv、--db 与 --output;AC2:普通与空列表输出稳定表头;AC3:逗号、双引号和换行按 CSV 规则转义;AC4:unittest、tabnanny lint 与内存 compile build 全部通过,README 与行为一致。

deliverables = [todo/cli.py, todo/exporter.py, tests/test_csv_export.py, README.md] evidence = [test/lint/build receipts, git diff]

范围不是建议

Workspace 和允许副作用在模型提出动作之前由 Runtime 固定。模型可以建议增加文件,但不能自行扩大 root、开启网络或批准 destructive command。

完成条件来自外部证据

Final Answer 只能总结已经存在的 receipts;一句“测试应该能过”不能替代 exit_code=0,也不能把未运行写成已通过。

3
Experiment 1 · real workspace scope

实验一:先固定 Workspace、Git baseline 与允许路径,再让 Agent 看代码

点击运行后,浏览器把目标发送给本机 4891 Runner。本地 Qwen2.5-Coder-1.5B-Instruct 先生成公开的 scope / inspect 建议,确定性 Runtime 再创建真实的临时 Todo CLI Git 仓库,解析 repository root 与 canonical paths,执行 git status,计算文件 hash、baseline tree、tracked / untracked 与 protected paths,并把模型建议与 policy receipt 并列展示。此阶段保持 read-only:allow_write 与 allow_commands 均不需要开启。路径越界、symlink 逃逸或 dirty baseline 的结论必须来自本机文件系统和 Git,模型不能自行授权,页面也没有预填成功结果。

User goal · sent to local model

每次点击都会创建真实异步 run;没有连接或模型时保持 not_run,不执行浏览器 fallback。

尚未运行
! 4891 Runner! 本地模型 allow_write · 本卡不需要 allow_commands · 本卡不需要
1. 本地模型给出 inspect 建议
2. Runtime 建立真实临时 Git 仓库
3. canonical path / dirty baseline / policy receipt

请先在模块顶部下载示例包和模型,启动 4891,依次完成“检查 Runner”和“检查本地模型”。

Local model
待本卡执行
Scope
待本卡执行
Inspect
本卡不涉及
Plan
本卡不涉及
Edit
本卡不涉及
Test
本卡不涉及
Diagnose
本卡不涉及
Replan
本卡不涉及
Verify
本卡不涉及
Diff
本卡不涉及
Checkpoint
本卡不涉及
Summary
待本卡执行
run = not_run
phase = not_run
events = 0 · receipts = 0
stop_reason =
本次真实边界
workspace = fixture · %TEMP%\algolab-coding-agent-runs\<run-id>\workspace
model = ./models/Qwen2.5-Coder-1.5B-Instruct
approvals = write:false / commands:false
fixture 每次复制到独立临时 Git 工作区;六张卡共享配置,但不共享仓库或上一张卡的 receipts。下载的 Runner 包与原始 fixture 不会被修改。
Incremental public trace

模型候选与 Runtime 证据分开记录

after_seq = 0
尚无本地事件。完成 Runner 与模型检查后启动实验;页面不会生成离线替代 trace。
4

Workspace root、Git root 与可写范围是三条不同边界

Workspace 是用户交给 Agent 的可见环境;repository root 是 Git 元数据定义的版本边界;writable scope 是本次任务允许修改的最小子集。三者常常重合,但不能依靠“通常如此”授权。Monorepo 可能只有一个 Git root,却只允许修改一个 package;submodule 有独立历史;symlink 的文本路径在 root 内,真实目标却可能越界。

对象本章真实实例Runtime 判断
Workspace root每个 run 的临时 workspace/;custom 时为用户填写的绝对目录先 resolve 为 canonical base,不能用 .. 或 symlink 逃逸
Git baselineRunner 复制 fixture 后真实执行 git init/add/commit用真实 git status --short 区分 clean baseline 与已有修改
Writable pathstodo/**tests/**README.md.git/**、模型目录、run artifacts 与越界路径默认拒绝
Command cwdcanonical repository root每个稳定 command ID 单独绑定 cwd,模型不能用隐式 cd

Inspect 阶段先记录 dirty baseline。custom workspace 一旦有未提交改动,写模式直接以 dirty_baseline 安全停止,不猜测哪些内容属于用户,也不覆盖或 reset;scope / inspect 仍保留只读能力。

5

路径授权发生在 canonicalize 之后,而不是字符串前缀比较之后

只有真实路径位于动作对应的授权 roots 内、动作在 allowlist 中且目标不受保护时,Runtime 才能分派。

工具请求中的候选路径
Candidate path from the tool request
read、search、patch 或 command 等动作
Action such as read, search, patch, or command
动作 a 对应的授权根目录集合
Authorized roots for action a
当前权限状态允许的动作集合
Actions allowed by the current permission state

先解析再比较

必须处理 ..、大小写规则、junction / symlink 与路径分隔符;字符串 startsWith 不能证明真实目标仍在 root 内。

读写策略分离

依赖源码或 lockfile 可以被读取以理解项目,但若不在 writable set 中,patch 仍应得到 scope_denied receipt。

拒绝也进入 trace

拒绝事件至少记录 normalized path、action、policy version 与 reason;敏感绝对路径在导出前脱敏。

6

项目结构要从入口、依赖与验证配置共同推断,不能只看目录名

文件树只能回答“有什么”,不能回答“运行时谁调用谁”。Inspect Repository 应先找到入口、依赖声明、语言与构建配置、测试发现规则和相邻实现,再画出与任务有关的最小依赖图。本章下载包刻意使用零第三方运行时依赖的 Python fixture:todo/cli.py 解析参数,todo/storage.py 读取 JSON,todo/exporter.py 定义待实现接口,tests/test_csv_export.py 承载可执行验收,README 是用户接口。

证据回答的问题本章真实读取
入口与 importsCLI、storage 与 formatter 的调用边todo/cli.pytodo/__init__.py
相邻实现Todo 字段、JSON 读法、返回值与换行约定todo/storage.pytodo/exporter.py
测试发现怎样证明普通、空与三个 escaping 边界python -m unittest discover -s tests -p test_*.py -v
静态验证怎样在零下载条件下 lint / build标准库 tabnanny 与逐文件内存 compile()
7
Experiment 2 · real search and read

实验二:从结构与依赖出发,用 Search → Read 建立可引用的修改证据

本地模型读取 Runtime 提供的真实文件清单与目标后,输出结构化 Search → Read 候选;Runner 只执行 allowlist 内的搜索和精确读取,从 todo/cli.py、todo/exporter.py、todo/storage.py、tests/test_csv_export.py 与 README 当前字节构建 evidence。trace 分别显示 model.decision、search.completed、read.completed、path 与 excerpt,使用户能检查“模型为什么想看”与“仓库实际返回什么”。fixture 是隔离的真实目录,不是 JavaScript 内存文件表;custom workspace 仍先只读,任何越界路径由 Runtime 拒绝。

User goal · sent to local model

每次点击都会创建真实异步 run;没有连接或模型时保持 not_run,不执行浏览器 fallback。

尚未运行
! 4891 Runner! 本地模型 allow_write · 本卡不需要 allow_commands · 本卡不需要
1. 模型提出结构化 Search → Read 候选
2. Runtime 执行真实文件搜索与读取
3. evidence IDs 连接到计划

请先在模块顶部下载示例包和模型,启动 4891,依次完成“检查 Runner”和“检查本地模型”。

Local model
待本卡执行
Scope
待本卡执行
Inspect
待本卡执行
Plan
本卡不涉及
Edit
本卡不涉及
Test
本卡不涉及
Diagnose
本卡不涉及
Replan
本卡不涉及
Verify
本卡不涉及
Diff
本卡不涉及
Checkpoint
本卡不涉及
Summary
待本卡执行
run = not_run
phase = not_run
events = 0 · receipts = 0
stop_reason =
本次真实边界
workspace = fixture · %TEMP%\algolab-coding-agent-runs\<run-id>\workspace
model = ./models/Qwen2.5-Coder-1.5B-Instruct
approvals = write:false / commands:false
fixture 每次复制到独立临时 Git 工作区;六张卡共享配置,但不共享仓库或上一张卡的 receipts。下载的 Runner 包与原始 fixture 不会被修改。
Incremental public trace

模型候选与 Runtime 证据分开记录

after_seq = 0
尚无本地事件。完成 Runner 与模型检查后启动实验;页面不会生成离线替代 trace。
8

搜索负责缩小候选,精确读取负责把候选变成可修改证据

高效定位通常是逐层收窄:先用真实文件列表确认语言与 package 边界,再搜索用户术语和未实现 marker,随后读取命中点附近的完整函数、调用者和测试。Agent 不应从第一个字符串命中直接开始编辑,也不应为了“理解完整项目”把所有文件读一遍。

  1. File list:确认 todo/*.pytests/test_csv_export.py 与 README,跳过 .git__pycache__ 和模型目录。
  2. Text search:默认搜索 NotImplementedErrorCSV_EXPORT_TESTS,把实现 seam 和测试 seam 同时定位出来。
  3. Focused read:模型选择目标文件,Runtime 返回当前精确字节的 UTF-8 文本、大小和受限 excerpt;CRLF/LF 不被读取层偷偷归一化。
  4. Cross-reference:沿 from .storage import load_todosexport_csv 与测试调用确认传播范围。

每条 evidence 都能回到具体 trace seq、path、search hit 或 read receipt。Plan 的每个 edit step必须引用这些事实;如果“需要改 README”只是模型经验而不是验收或仓库证据,它应被标记为待确认。

9

修改计划必须把每个文件变化连接到证据和验证命令

No.18 已经说明 Plan step 要产生可验收状态变化;在仓库里还要增加两类坐标:evidence refs 说明为什么改这里,verification refs 说明怎样证明这一步没有破坏项目。G-TODO-CSV 的初始计划不是“写 CSV、跑测试”,而是一个可以被执行器逐项拒绝或完成的文件级计划。

Step预期变化真实证据验证
S1todo/exporter.py 从 NotImplementedError 变为可测 export_csvexporter read + Todo dict fields五个独立 unittest cases
S2todo/cli.py 接入 export-csv --db --outputargparse dispatch + storage importCLI 写文件断言
S3tests/test_csv_export.py 补普通、空、逗号、引号、换行与 CLI cases测试 marker + AC2/AC3Plan v1 真实出现三项 escaping failure
S4README 记录可复制命令用户交付契约最终 diff review

Plan 还要声明修改顺序、允许路径、预计稳定 command IDs 和停止条件。新证据可以改变计划:真实测试证明手写拼接不满足 CSV quoting 后,Plan v2 保留 CLI、tests 与文档,只把 formatter 换为标准库 csv.writer

10

Patch 只有在 preimage 与 hunk 上下文仍匹配时才能安全应用

Runtime 在修改前同时检查文件 preimage hash 和每个 hunk 的上下文;任一不匹配都拒绝整项修改并要求重新读取。

带目标路径、hunks 与预期 hash 的 patch
Patch with target path, hunks, and expected hash
应用时的当前文件内容
Current file content at application time
当前内容的稳定 hash
Stable hash of current content
读取证据中记录的 preimage hash
Preimage hash captured by the read evidence
一个包含删除、增加与上下文的 hunk
A hunk containing removals, additions, and context

拒绝 stale edit

读取后若用户或另一进程修改了文件,旧 patch 不能靠模糊匹配强行落盘;应重新 read、更新证据并重算 diff。

多文件原子边界

教学 Runtime 先验证全部目标,再提交 workspace snapshot;生产实现可使用临时文件、transaction 或 Git worktree 避免半套修改。

validate(all preimages) → stage candidate snapshot → compute diff → commit snapshot

Patch receipt

记录 before/after hash、applied hunks、changed lines、policy decision 和 patch ID;不记录含 secret 的完整文件副本。

11
Experiment 3 · real multi-file patch

实验三:把计划变成多文件 Patch,并从 baseline 计算真实 diff

本地模型根据真实 evidence 生成文件级 Plan 与候选 ID;只有用户开启 allow_write 后,Runner 才在本次隔离 Git fixture 中检查 canonical scope,并以 exact old → new transaction 真实修改 todo/cli.py、todo/exporter.py、tests/test_csv_export.py 与 README.md。四个目标先全部验证,任一 preimage 不匹配就整组拒绝;成功后逐文件返回 before/after SHA-256、unified diff 与 checkpoint receipt。Plan v1 故意使用手写 f-string + join,同时写入五个独立测试,为下一实验产生普通/空通过、comma/quote/newline 三项真实失败;关闭批准时只返回 approval_required。

User goal · sent to local model

每次点击都会创建真实异步 run;没有连接或模型时保持 not_run,不执行浏览器 fallback。

尚未运行
! 4891 Runner! 本地模型 allow_commands · 本卡不需要

批准由你显式勾选,只用于之后新建的 run;被截停的旧 run 不能原地续跑。

1. 模型生成 evidence-backed Plan v1
2. Runtime 校验 writable scope 与 preimage
3. 真实文件落盘并生成 git diff
完整实验尚未获批,主按钮已锁定。 请直接勾选上方本卡所需的批准;批准后点击主按钮会新建完整 run。审批拦截是独立的安全实验,不会进入 Edit、Test,也不会修改文件。

请先在模块顶部下载示例包和模型,启动 4891,依次完成“检查 Runner”和“检查本地模型”。

Local model
待本卡执行
Scope
待本卡执行
Inspect
待本卡执行
Plan
待本卡执行
Edit
待本卡执行
Test
本卡不涉及
Diagnose
本卡不涉及
Replan
本卡不涉及
Verify
本卡不涉及
Diff
待本卡执行
Checkpoint
待本卡执行
Summary
待本卡执行
run = not_run
phase = not_run
events = 0 · receipts = 0
stop_reason =
本次真实边界
workspace = fixture · %TEMP%\algolab-coding-agent-runs\<run-id>\workspace
model = ./models/Qwen2.5-Coder-1.5B-Instruct
approvals = write:false / commands:false
fixture 每次复制到独立临时 Git 工作区;六张卡共享配置,但不共享仓库或上一张卡的 receipts。下载的 Runner 包与原始 fixture 不会被修改。
Incremental public trace

模型候选与 Runtime 证据分开记录

after_seq = 0
尚无本地事件。完成 Runner 与模型检查后启动实验;页面不会生成离线替代 trace。
12

精确修改不是少改几行,而是让所有受影响契约同步变化

“最小 diff”不等于“只改一个文件”。新增 CSV export 同时改变 formatter API、CLI route、测试真值和用户文档;如果只在 todo/exporter.py 写函数却不接入 CLI,局部代码可能正确,任务仍然失败。相反,顺手格式化全仓库会扩大审查面,并可能覆盖用户无关改动。

文件精确变化不应发生
todo/exporter.py实现 export_csv;Plan v2 只替换失败 formatter重写 storage 或让模型直接写任意源码
todo/cli.py新增一个 argparse 子命令并写 UTF-8 输出更换整个参数解析框架
tests/test_csv_export.py独立期望覆盖普通、空、comma、quote、newline 与 CLI调用实现函数计算 expected
README.md记录真实 export-csv --db --output 命令宣称尚未验证的行为

Runner 的 transaction 先准备全部目标,再用同目录临时文件、flush、fsync 与原子 replace 写入;中途失败会按保存的原始字节回滚。读取和 Patch 都保留 CRLF/LF 精确字节,避免 Windows 上“模型看到 LF、校验器看到 CRLF”的 stale edit 假冲突。

13

终端命令必须显式声明 cwd、参数、超时、环境与副作用级别

Shell 是 Coding Agent 最强也最危险的工具。模型不能提交一整段 shell 文本;它只能选择 Runtime 注册的稳定 command ID。Runtime 再绑定固定 argv、canonical cwd、最小环境、timeout 与 64 KiB 输出上限,并以 subprocess.Popen(..., shell=False) 执行。

稳定 ID真实 argv / 作用本章策略
testspython -m unittest discover -s tests -p test_*.py -v真实执行 fixture 测试;保留 exit 1 与 exit 0 两次 receipt
python_lintpython -m tabnanny todo tests标准库缩进 lint,不下载工具
python_build逐个读取 Python 文件并在内存 compile(..., 'exec')真实语法 build,不写 pyc 或生成目录
git_status / git_diff固定只读 Git argv只用于 baseline 与最终审查
install、reset、push不在 registry即使模型请求或通用批准开启也无法执行

每次命令返回真实 argv、exit code、合并后的 stdout/stderr、duration、timeout 与 truncation。custom JavaScript 仓库只从已有 package scripts 中选择安全的 lint/test/build ID,先拒绝包含下载、安装、删除等明显危险 marker 的 script。

14

Command Receipt 把一次终端执行变成可恢复、可审查的 Observation

命令收据同时记录执行环境、时间边界、退出状态、输出与文件状态变化,后续诊断不能只看一段自然语言摘要。

规范化且已授权的工作目录
Canonical authorized working directory
未经过二次 shell 展开的参数向量
Argument vector without a second shell expansion
受控环境增量与 timeout
Controlled environment delta and timeout
exit code 或 signal / cancelled 状态
Exit code or signal/cancelled state
stdout 与 stderr artifact
Stdout and stderr artifacts
命令前后文件状态差异
File-state delta before and after the command

exit code 优先

日志中出现 PASS 不代表命令成功;Runtime 以进程状态和测试结构化结果为准。

环境失败不冒充代码失败

缺少依赖、命令不存在、权限拒绝与断言失败使用不同 error code,决定下一步是请求批准、修环境还是改代码。

文件 delta 揭示隐藏副作用

lint/build 即使 exit_code=0,也要检查是否意外改写源码、lockfile 或越界生成文件。

15
Experiment 4 · real failing test and diagnosis

实验四:让第一版在真实边界测试中失败,再从 stderr 与断言定位原因

开启 allow_write 与 allow_commands 后,Runner 在真实 fixture 中应用 Plan v1,并用固定 argv 启动 unittest 子进程。五个测试中,普通/空列表与 plain CLI case 通过,comma、quote、embedded newline 三项独立断言失败,整个命令真实返回 exit_code=1;stdout/stderr、duration、timeout 与 truncation 都来自本机。Runner 随后把失败 receipt 交给同一个本地模型进行第二次结构化调用,输出 cause/evidence/repair;实验以“成功捕获并诊断真实失败”完成,但仓库仍保持红色,绝不把 diagnosis 写成测试通过。

User goal · sent to local model

每次点击都会创建真实异步 run;没有连接或模型时保持 not_run,不执行浏览器 fallback。

尚未运行
! 4891 Runner! 本地模型

批准由你显式勾选,只用于之后新建的 run;被截停的旧 run 不能原地续跑。

1. 真实 subprocess 与 exit code
2. 失败输出成为 Observation
3. 模型诊断不等于测试通过
完整实验尚未获批,主按钮已锁定。 请直接勾选上方本卡所需的批准;批准后点击主按钮会新建完整 run。审批拦截是独立的安全实验,不会进入 Edit、Test,也不会修改文件。

请先在模块顶部下载示例包和模型,启动 4891,依次完成“检查 Runner”和“检查本地模型”。

Local model
待本卡执行
Scope
待本卡执行
Inspect
本卡不涉及
Plan
待本卡执行
Edit
待本卡执行
Test
待本卡执行
Diagnose
待本卡执行
Replan
本卡不涉及
Verify
本卡不涉及
Diff
本卡不涉及
Checkpoint
待本卡执行
Summary
待本卡执行
run = not_run
phase = not_run
events = 0 · receipts = 0
stop_reason =
本次真实边界
workspace = fixture · %TEMP%\algolab-coding-agent-runs\<run-id>\workspace
model = ./models/Qwen2.5-Coder-1.5B-Instruct
approvals = write:false / commands:false
fixture 每次复制到独立临时 Git 工作区;六张卡共享配置,但不共享仓库或上一张卡的 receipts。下载的 Runner 包与原始 fixture 不会被修改。
Incremental public trace

模型候选与 Runtime 证据分开记录

after_seq = 0
尚无本地事件。完成 Runner 与模型检查后启动实验;页面不会生成离线替代 trace。
16

测试失败先分类,再决定重试、修环境、改代码还是 Replan

失败日志是 Observation,不是自动要求“再生成一版代码”。相同的非零 exit code 可能来自解析错误、lint、断言差异、环境缺失、timeout 或 flaky case;不同类别需要不同证据和恢复路径。

示例正确下一步
EnvironmentPython、Git 或 test discovery 不可用核对 health、manifest 与 argv;不改业务代码
Buildtodo.cli import / 语法失败读取 compiler location 与当前文件,修接线
Linttabnanny 报缩进歧义按当前文件最小修改,不全仓格式化
Test assertioncomma 字段缺少外层双引号比较失败 expected/actual 与当前 formatter,建立可证伪假设
Timeout子进程超过上限被 kill检查阻塞原因,不把 timeout 当实现错误
Regressionescaping 通过但 CLI 写文件失败扩大到 CLI case 并 Replan,不能只保留局部绿色

本章首轮是结构性实现缺口:手写 f-stringjoin 不执行 RFC 风格 quoting。真实输出中三个测试名分别指向 comma、quote、embedded newline;Runtime 把 receipt 交给模型形成 diagnosis,Plan v2 保留已经有效的 CLI route、tests 和文档,只把 todo/exporter.py 换为标准库 csv.writer

17

Diagnosis 用可证伪假设连接失败 Observation 与下一次最小动作

在与当前 Observation 一致的候选原因中,优先选择单位成本能排除最多假设的安全动作,而不是直接生成最大 patch。

由错误位置、契约与近期 diff 形成的候选原因集合
Candidate causes derived from error locations, contracts, and recent diffs
测试、构建、lint 或权限 Observation
Test, build, lint, or permission observation
用于验证假设 h 的 read、search、command 或 patch
Read, search, command, or patch used to test hypothesis h
动作对候选原因的区分能力
How strongly the action discriminates among candidate causes
时间、token、命令与副作用风险
Time, tokens, commands, and side-effect risk

本章的三个假设

H1:整行需要统一包裹;H2:只有含特殊字符的 cell 需要包裹并双写内部引号;H3:测试期望错误。读取断言与 CSV 契约即可排除 H1/H3。

Replan 保留有效产物

CLI route、普通 case 与 README 结构仍有效;Plan v2 只替换 escaping step,并增加回归验证,不重新检查整仓库。

keep = [scope, evidence, todo/cli.py, tests, README] replace = [todo/exporter.py: manual join → csv.writer] add = [lint, build, Git review]

失败指纹防止盲重试

command、case IDs、error code 与 relevant diff hash 相同且无新证据时视为同一失败;达到阈值后停止或请求人工判断。

18

验证从最便宜的 targeted check 逐层扩展到仓库级验收

修复后立刻只看最终绿色会丢掉因果链,只重跑一个 case 又可能漏回归。Coding Agent 使用从便宜到完整的 verification ladder;每一层都形成独立 command receipt,失败决定回到 Read、Edit 或 Replan。

  1. Static sanity:重新读取 changed regions,确认 import、argparse route、精确换行与 preimage。
  2. 同一完整 unittest:先在 Plan v1 得到 exit 1 和三个命名失败;修复后用完全相同的 argv 得到 5 tests、exit 0,避免换命令逃避失败。
  3. Lint:运行标准库 tabnanny 检查 todotests,保存真实 exit code。
  4. Build:逐文件读取并调用内存 compile(),输出实际编译文件数,不产生 pyc 副作用。
  5. Repository review:最后执行 Git status/diff,确认 verifier 没有额外生成文件。

custom workspace 根据真实 manifest 选择已有 npm lint/test/build;缺少某层时写 not_run,而不是套用 fixture 命令。测试返回 0 但发现 0 个 tests 时仍不能满足 AC。

19

完成是验收、验证、范围与变更审查的合取,不是某个测试的绿色图标

只有验收条件、build、lint、tests、diff review 全部满足且没有 scope violation 时,任务才能标记 completed。

逐项验收条件均有证据
Every acceptance criterion has evidence
所需 build/typecheck 成功
Required build or typecheck succeeds
所需 lint 成功
Required lint succeeds
目标与回归测试均成功且发现数有效
Targeted and regression tests pass with valid discovery
git status 与最终 diff 已审查
Git status and final diff have been reviewed
越界写入、未批准副作用或受保护文件变化
Scope violations, unapproved side effects, or protected-file changes

三态而非布尔

每项 verifier 使用 passed / failed / not_run;not_run 不能在聚合时变成 true 或 0 failures。

测试与验收分开

测试通过可以证明行为样例,但 README、允许范围、用户已有改动和最终交付字段仍需独立检查。

正确停止也是结果

权限被拒、环境缺失或 baseline 冲突时,Runtime 可以安全 stopped;这不等于任务成功,但优于越权完成。

20
Experiment 5 · repair, verify and diff review

实验五:应用 Plan v2,重跑验证并审查真实 Git status / diff

本卡让本地模型在同一个全新 fixture run 内完成真实闭环,不读取实验四的临时仓库:review.inspect 先 search/read,review.initial 形成四文件 csv-naive Plan v1;获得写入与命令批准后,Runtime 应用它并运行 unittest 得到 exit 1 与三个 escaping failures。本地模型再依次产生 review.diagnosis 和 review.replan,Plan v2 保留 CLI、tests、README,只把 todo/exporter.py 替换为 csv.writer。随后同一 unittest 必须报告 5 tests / exit 0,tabnanny lint 与内存 compile build 也必须 exit 0;Runtime 再运行 git status --short、git diff,并把真实 diff 交给 review.final 形成公开 verdict/findings。

User goal · sent to local model

每次点击都会创建真实异步 run;没有连接或模型时保持 not_run,不执行浏览器 fallback。

尚未运行
! 4891 Runner! 本地模型

批准由你显式勾选,只用于之后新建的 run;被截停的旧 run 不能原地续跑。

1. 模型 Replan,只替换失败子步骤
2. Runtime 重跑 verification ladder
3. 最终 Git diff 与 AC matrix
完整实验尚未获批,主按钮已锁定。 请直接勾选上方本卡所需的批准;批准后点击主按钮会新建完整 run。审批拦截是独立的安全实验,不会进入 Edit、Test,也不会修改文件。

请先在模块顶部下载示例包和模型,启动 4891,依次完成“检查 Runner”和“检查本地模型”。

Local model
待本卡执行
Scope
待本卡执行
Inspect
待本卡执行
Plan
待本卡执行
Edit
待本卡执行
Test
待本卡执行
Diagnose
待本卡执行
Replan
待本卡执行
Verify
待本卡执行
Diff
待本卡执行
Checkpoint
待本卡执行
Summary
待本卡执行
run = not_run
phase = not_run
events = 0 · receipts = 0
stop_reason =
本次真实边界
workspace = fixture · %TEMP%\algolab-coding-agent-runs\<run-id>\workspace
model = ./models/Qwen2.5-Coder-1.5B-Instruct
approvals = write:false / commands:false
fixture 每次复制到独立临时 Git 工作区;六张卡共享配置,但不共享仓库或上一张卡的 receipts。下载的 Runner 包与原始 fixture 不会被修改。
Incremental public trace

模型候选与 Runtime 证据分开记录

after_seq = 0
尚无本地事件。完成 Runner 与模型检查后启动实验;页面不会生成离线替代 trace。
21

Git status 与 diff 是最终审查入口,不是 Agent 记忆的装饰

验证通过后仍要回到仓库状态。真实 git status --short 回答哪些 tracked/untracked paths 改变,完整 git diff --no-ext-diff -- 检查语义、秘密、调试残留、生成文件和测试质量。只展示 Agent 保存的候选 patch 会漏掉命令副作用,也无法发现运行期间的新改动。

审查问题G-TODO-CSV 的真实期望异常信号
范围todo/cli.pytodo/exporter.py、一个测试文件与 README__pycache__、模型、artifact 或凭据文件出现
必要性每个 hunk 对应 S1–S4 / AC无关重命名、全文件格式化
正确性csv.writer、CLI 接线、独立 expected测试复用实现函数计算 expected
可交付性5 tests、lint、build receipts 都通过skip、弱化断言或把 expected failure 隐去

custom baseline 必须 clean 才允许写;无法区分用户改动时直接 dirty_baseline,不会 restore、checkout 或 reset。最终 artifacts 固定为 summary.json、trace.json、git.diff、git-status.txt 与 workspace-manifest.json,路由不能读取其他文件。

22

Checkpoint 保存的是可继续工作的仓库协议,不是一句“做到测试了”

No.19 的 checkpoint 在 Coding Agent 中必须绑定仓库身份和精确副作用。至少保存 task/goal hash、workspace policy version、baseline tree、current tree、Plan version/cursor、evidence IDs、patch receipts、command receipts、approval receipts、verification matrix 与未解决失败。大 diff 和日志作为带 hash 的 artifacts 引用,不塞进摘要。

  1. 保存:在 patch 或 command 到达终态后,先持久化 receipts 与 artifacts,再推进 cursor。
  2. 中断:丢弃进程内模型上下文不影响 Git snapshot 与 checkpoint manifest。
  3. 恢复校验:重新 canonicalize root,核对 repository identity、baseline/current hashes、policy 与 artifact hashes。
  4. 重建:从 receipts 归约 changed files、passed checks、remaining plan 和 approval state。
  5. 继续:只从 next safe action 分派,避免重复 patch、重复安装或重复外部写入。

如果恢复时 workspace 被用户修改,Runtime 不猜测如何合并。它生成 checkpoint/current diff,保留只读诊断能力,并要求重新 inspect、Replan 或人工决定。对可重复测试可安全重跑;对发布、删除、提交等副作用必须检查 idempotency key 或明确重新批准。

23

Resume 只有在仓库、状态、策略与副作用收据共同一致时成立

仓库身份、baseline/current hashes、policy version、artifact receipts 与 side-effect receipts 必须全部通过校验。

repository identity 与 canonical root 匹配
Repository identity and canonical root match
baseline 与 checkpoint current tree hashes
Baseline and checkpoint current tree hashes
workspace / permission policy version
Workspace and permission policy version
patch、log 与测试 artifact receipts
Patch, log, and test artifact receipts
命令及外部副作用的幂等收据
Idempotency receipts for commands and external side effects

current tree 不是 baseline

baseline 说明任务开始前状态,current tree 说明 checkpoint 时已完成修改;二者都需要,才能发现外部漂移并避免重复工作。

审批不会永久继承

批准应绑定 action fingerprint、scope 与有效期;Resume 后命令或目标改变时必须重新判断。

恢复后的第一步

先生成恢复报告并重建 verification matrix,再决定重跑失败测试或继续 diff review,不能直接让模型猜 next step。

24

本地 Runner 承载真实能力,Sandbox、权限与人工批准决定动作能否发生

真实 Coding Agent 不能只放在浏览器中:网页没有权限读取任意仓库、调用 Git 或启动测试进程。因此本章采用与 No.16、No.17 相同的本地边界,但把工具扩大到 repository engineering。AlgoLab Backend 只发布页面与完整示例 ZIP;浏览器直接连接用户电脑上的 127.0.0.1:4891;模型权重、仓库文件、命令输出和 artifacts 不经过部署服务器。

组件职责明确不做
课程页面配置目标、模型路径、workspace mode 与批准;展示 trace不伪造文件、diff 或 exit code
本地模型提出结构化 inspect、plan、diagnosis、review 与 summary不直接打开文件、不执行命令、不授予自己权限
确定性 Runtimecanonicalize、policy、Git、Patch、subprocess、receipts、checkpoint不把模型文本当成功证据
隔离 fixture每次 run 建立真实临时 Git 仓库,安全复现实验不修改 AlgoLab 主仓库

首次使用依次完成四步:下载并解压 ZIP;在虚拟环境安装 requirements.txt;运行 download_model.pyQwen/Qwen2.5-Coder-1.5B-Instruct 保存到用户指定目录;用 run.ps1run.sh 启动服务并在页面检查 health 与 model inspect。模型只加载一次,六个实验共用该进程。权重不会被打进 ZIP,也不会在点击实验时静默下载。

Sandbox 是执行边界,permission policy 是决策规则,human approval 是特定动作的临时授权,三者不能合并成一个“安全模式”开关。

等级示例默认处理
Read-onlylist/search/read、git status/diff授权 root 内自动执行并记录
Workspace write对计划文件应用已验证 patch用户开启 allow_write,且路径、preimage、writable set 均通过
Execute repository codetest/lint/build用户开启 allow_commands;Runtime 校验 argv、cwd、timeout 与脚本
Network / installnpm install、下载工具实验 run 中默认拒绝;模型下载是用户在启动前显式执行的独立步骤
Destructive / external删除、reset、commit、push、发布示例 Runtime 默认拒绝,不因通用写入批准而放行

审批请求应绑定 exact argv、cwd、目标 paths、preimage、policy version 与预计副作用。用户拒绝后,Agent 可以保留只读诊断并报告 not_run;不能换一种拼写重复请求同一动作。

25

动作分派必须同时通过能力、范围、风险与审批四道门

工具存在、作用域允许、风险未超过当前自动执行阈值且所需审批有效,动作才进入执行器。

Runtime 提供并允许该工具能力
The runtime provides and allows the capability
路径、cwd 与资源均在授权 scope
Paths, cwd, and resources remain in authorized scope
依据写入、网络、破坏性与外部影响计算的风险
Risk derived from writes, network, destructiveness, and external impact
当前可自动执行的最大风险级别
Maximum risk level currently allowed without escalation
若需要,存在绑定到当前动作指纹的有效批准
A valid approval bound to the current action fingerprint when required

动作指纹

approval 应绑定 tool、normalized args、cwd、target hashes 与 policy version;参数改变后旧批准失效。

风险和模型置信度无关

即使模型确信 reset 能修复问题,destructive risk 也不会下降;审批门由 Runtime 计算。

拒绝后的可用路径

系统保留 read-only inspect、diff 和报告能力,并把 blocked verifier 写入 Final Summary。

26

完整示例包让实验可复现,危险操作控制让副作用可停止、可恢复

页面提供的 ZIP 不是一段演示脚本,而是一套可以离开 AlgoLab 仓库独立运行的最小工程:README 与 manifest 解释协议,模型下载脚本固定本地保存流程,HTTP server 与 job store 提供异步运行和取消,model policy 约束结构化输出,workspace policy 负责路径与命令安全,prompts / schemas 固定公开决策契约,fixture 是带测试的真实小仓库,tests 使用 FakeModelPolicy 验证安全规则而不下载权重。页面还能按 manifest 浏览每个源码文件并核对 SHA-256。

运行模式适用场景副作用边界
fixture(默认)学习六阶段闭环、复现真实失败复制到临时目录并初始化 Git;结束后可由系统清理
custom + read-only在自己的仓库练习定位、计划与 review只能 list/search/read/status/diff
custom + approvals进阶多文件修改与验证写入和命令分别批准;baseline dirty 状态会进入交付报告

危险不只等于删除。覆盖未提交文件、递归移动目录、运行未知 postinstall、修改数据库、推送分支、发布包和长时间占用资源都可能难以恢复。Runtime 在执行前识别 side-effect class,在执行中支持 timeout / cancellation,在执行后记录 receipt 与真实文件 delta。

  1. 删除与覆盖:拒绝 workspace root、home、通配 broad target;示例 Agent 不提供任意删除工具。
  2. 版本控制:不以 reset/checkout 清理用户改动;fixture 通过新建临时 Git 仓库获得干净 baseline。
  3. 依赖与脚本:先读 manifest 与 script;run 中拒绝安装、网络和 shell 拼接,只执行允许的结构化 argv。
  4. 外部系统:commit、push、PR、部署与消息发送不在本章 capability set 中,通用批准不能凭空增加工具。
  5. Secrets:搜索、日志、diff、artifact 与 Final Summary 都需过滤敏感路径和环境值。
27
Core experiment · complete local coding-agent loop

核心实验:让 Mini Coding Agent 在同一真实 fixture 中完成完整仓库闭环

核心实验把前五个阶段串成一个异步本地 run:同一个已加载的 Qwen2.5-Coder-1.5B-Instruct 依次产生 mission.inspect、mission.initial、mission.diagnosis、mission.replan 与 mission.review 五次结构化决策;确定性 Runtime 先在真实临时 Git 仓库中 search/read,再创建 checkpoint、应用四文件 Plan v1、运行 unittest 得到 exit 1 与三个 escaping failures、应用只替换 exporter 的 Plan v2、用同一 unittest 得到 5 tests / exit 0,最后运行 tabnanny lint、内存 compile build 与 Git review。每个事件有递增 seq、公开 summary、工具参数、path/hash 与 receipt,可取消并下载五个 artifacts。页面只轮询 4891,不播放固定动画;custom workspace 必须显式路径、clean baseline 和两项批准。

User goal · sent to local model

每次点击都会创建真实异步 run;没有连接或模型时保持 not_run,不执行浏览器 fallback。

尚未运行
! 4891 Runner! 本地模型

批准由你显式勾选,只用于之后新建的 run;被截停的旧 run 不能原地续跑。

1. 同一模型完成 plan / diagnose / replan / summary
2. 真实仓库多文件修改与失败恢复
3. checkpoint、artifacts 与可信交付
完整实验尚未获批,主按钮已锁定。 请直接勾选上方本卡所需的批准;批准后点击主按钮会新建完整 run。审批拦截是独立的安全实验,不会进入 Edit、Test,也不会修改文件。

请先在模块顶部下载示例包和模型,启动 4891,依次完成“检查 Runner”和“检查本地模型”。

Local model
待本卡执行
Scope
待本卡执行
Inspect
待本卡执行
Plan
待本卡执行
Edit
待本卡执行
Test
待本卡执行
Diagnose
待本卡执行
Replan
待本卡执行
Verify
待本卡执行
Diff
待本卡执行
Checkpoint
待本卡执行
Summary
待本卡执行
run = not_run
phase = not_run
events = 0 · receipts = 0
stop_reason =
本次真实边界
workspace = fixture · %TEMP%\algolab-coding-agent-runs\<run-id>\workspace
model = ./models/Qwen2.5-Coder-1.5B-Instruct
approvals = write:false / commands:false
fixture 每次复制到独立临时 Git 工作区;六张卡共享配置,但不共享仓库或上一张卡的 receipts。下载的 Runner 包与原始 fixture 不会被修改。
Incremental public trace

模型候选与 Runtime 证据分开记录

after_seq = 0
尚无本地事件。完成 Runner 与模型检查后启动实验;页面不会生成离线替代 trace。
28

逐项读核心 trace,并把已验证事实写成最终交付说明

默认 mission 的增量 trace 能重建完整因果链:repository.baseline 与 workspace.scoped 固定真实 Git/root 边界;mission.inspect 产生 search/read events;mission.initial 给出基于本次读取的 Plan v1;checkpoint.created 先于任何写入;plan-v1 的四文件 patch receipts 证明改动落盘;第一次 tests receipt 以 exit 1 暴露 comma / quote / newline 三项失败;mission.diagnosis 引用真实输出;mission.replan 保留有效 CLI、tests、README,只替换 exporter;同一 tests argv 随后报告 5 tests / exit 0,python_lint 与 python_build 也各自 exit 0;最后 git.reviewed 与 mission.review 共同约束交付。

Final 字段必须来自本章真实内容
Goal / resultTask Contract + terminal stateexport-csv --db --output implemented,completed
Changed files真实 git status / diffCLI、exporter、一个独立测试文件、README
Behavior5 个 unittest 方法普通 + 空列表、逗号、引号、换行与 CLI 写文件五组断言均被覆盖
Verification4 张 command receiptstests exit 1 → tests exit 0 → lint exit 0 → build exit 0
Failure and repair五次 model decisions + patch receipts手写 join 失败,最小替换为 csv.writer
Scope / approvalspolicy.approval + safety写入/命令批准;shell/network/destructive=false
Artifactsartifact allowlist + SHA-256summary、trace、diff、status、workspace manifest
Checkpointcheckpoint manifest写前快照文件数与 restore_requires_approval;精确内容留在本地 run 内

Final Summary 不粘贴整段日志,也不用“应该”“看起来”。模型可以组织语言,但 Runtime 只交付 receipt 支撑的字段。fixture 小模型连续两次违反结构化契约时,Runtime 只允许审计候选并公开记录 contract normalization;custom 仍严格停止。审批被拒、用户取消、测试仍失败或 custom baseline 漂移时,明确返回 stop_reason 和已有证据。

29

Coding Agent 评测必须同时覆盖定位、修改、验证、安全、恢复与交付

单一 Task Success 无法解释失败发生在定位、patch、验证、权限、恢复还是最终报告;各指标必须从同一 trace 独立计算。

Task Success:AC 是否全部成立
Task success across all acceptance criteria
Localization Evidence:计划修改是否由正确证据支持
Whether planned edits are supported by correct localization evidence
Patch Precision:必要 changed hunks 占全部 hunks 的比例
Proportion of changed hunks necessary for the task
Verification Coverage:required verifiers 的真实执行覆盖
Actual execution coverage of required verifiers
Regression Safety:原有行为是否保持
Whether existing behavior remains intact
Scope Violations:越界写入与未授权命令数
Out-of-scope writes and unauthorized commands
Approval Correctness:高风险动作是否正确请求或拒绝
Whether risky actions were correctly escalated or denied
Resume Success:中断后是否从正确状态继续且不重复副作用
Whether resume continues from the right state without duplicate effects
Final Faithfulness:交付声明是否都有 receipts 支持
Whether final delivery claims are supported by receipts

分母为零显示 N/A

没有请求高风险动作时 Approval Correctness 可能是 N/A;没有 checkpoint 场景时 Resume Success 也不能伪装成 100%。

效率单独报告

Steps、search/read bytes、patch attempts、commands、wall-time proxy 与 Context tokens 描述成本,但不能覆盖安全和正确性。

默认 mission 的预期

首轮 Task Success 为失败但 Diagnosis 有效;Plan v2 后 AC 全通过、scope violations=0、verification coverage=100%,Final claims 均能回到 receipts。

安全停止不是任务成功

越界注入时 Scope gate 正确拒绝可提高安全指标,但 Task Success 仍为 false;两者必须同时呈现。

30

精炼 typed controller:让证据、Patch、测试与权限收据驱动同一个循环

python
这段代码做什么

这段 typed controller 是下载包中真实 Runner 的最小抽象:本地模型只经 propose 返回候选,文件系统、Git、Patch 和 subprocess 全部经 authorize / execute;Observation 与 receipts 才能推进状态。完整可运行实现、fixture、启动脚本与无模型单测请在本模块顶部下载 ZIP 并逐文件浏览。

按执行顺序理解与检查

Stage 1

Stage 2

Stage 3

Stage 4

Stage 5

完整可运行脚本
from __future__ import annotations

from dataclasses import dataclass, field
from enum import Enum
from typing import Any, Literal, Protocol


class Phase(str, Enum):
    INSPECT = 'inspect'
    PLAN = 'plan'
    EDIT = 'edit'
    VERIFY = 'verify'
    DIAGNOSE = 'diagnose'
    REVIEW = 'review'
    DELIVER = 'deliver'
    STOPPED = 'stopped'


@dataclass(frozen=True)
class ToolCall:
    name: Literal['list', 'search', 'read', 'patch', 'command', 'status', 'diff']
    args: dict[str, Any]
    reason: str


@dataclass(frozen=True)
class PolicyDecision:
    allowed: bool
    risk: Literal['read', 'write', 'execute', 'network', 'destructive']
    approval_id: str | None = None
    reason: str = ''


@dataclass(frozen=True)
class Receipt:
    kind: str
    ok: bool
    data: dict[str, Any]
    error_code: str | None = None


@dataclass
class AgentState:
    goal: dict[str, Any]
    workspace: dict[str, Any]
    phase: Phase = Phase.INSPECT
    plan_version: int = 0
    evidence: dict[str, Receipt] = field(default_factory=dict)
    patches: list[Receipt] = field(default_factory=list)
    commands: list[Receipt] = field(default_factory=list)
    approvals: list[PolicyDecision] = field(default_factory=list)
    failures: list[Receipt] = field(default_factory=list)
    acceptance: dict[str, Literal['passed', 'failed', 'not_run']] = field(default_factory=dict)
    blockers: list[str] = field(default_factory=list)
    last_failure_fingerprint: str | None = None
    repeated_failure_count: int = 0


class Runtime(Protocol):
    def propose(self, state: AgentState) -> ToolCall: ...
    def authorize(self, state: AgentState, call: ToolCall) -> PolicyDecision: ...
    def execute(self, state: AgentState, call: ToolCall) -> Receipt: ...
    def reduce(self, state: AgentState, call: ToolCall, receipt: Receipt) -> None: ...
    def checkpoint(self, state: AgentState) -> Receipt: ...
    def final_report(self, state: AgentState) -> dict[str, Any]: ...


def run_agent(runtime: Runtime, state: AgentState, max_steps: int = 40) -> dict[str, Any]:
    for _ in range(max_steps):
        if state.phase is Phase.DELIVER:
            return runtime.final_report(state)
        if state.phase is Phase.STOPPED:
            return runtime.final_report(state)

        call = runtime.propose(state)
        policy = runtime.authorize(state, call)
        state.approvals.append(policy)
        if not policy.allowed:
            state.blockers.append(f'{call.name}: {policy.reason}')
            state.phase = Phase.STOPPED
            continue

        receipt = runtime.execute(state, call)
        runtime.reduce(state, call, receipt)

        if call.name == 'patch':
            state.patches.append(receipt)
        if call.name == 'command':
            state.commands.append(receipt)
        if not receipt.ok:
            state.failures.append(receipt)

        checkpoint = runtime.checkpoint(state)
        if not checkpoint.ok:
            state.blockers.append('checkpoint validation failed')
            state.phase = Phase.STOPPED

    state.blockers.append('max_steps reached before verified delivery')
    state.phase = Phase.STOPPED
    return runtime.final_report(state)
AI
问问 LLM:把 repository trace、Patch、测试失败与权限决策解释成可执行判断

正在检查登录状态与模型配置…