| 中文文章 | English article |
这个实验用一个临时 Git 仓库和一个最小 HTTP 服务,走完一次 Agent 改动的验收链:
意图 -> 范围 -> 候选 commit -> 干净检出测试 -> 制品 -> 本地运行结果 -> 代码恢复
它只需要 Python 3 和 Git。所有仓库、制品、运行目录和事件记录都在脚本新建的临时根目录中;宿主仓库不会被提交、切分支或清理。
在仓库根目录执行:
python3 labs/ai-change-control/lab.py
脚本每次创建一个独立的实验根,并完成这些可观察动作:
SERVICE_TIMEOUT。基线测试保留该旧契约的缺失、空值、非整数和非正数边界;Agent 同时修改应用、添加目标测试,并改动一份与任务无关的笔记。1 和指定错误消息失败。30,显式正数保持原值,非整数和非正数仍报原来的错误。它在新建的干净 worktree 测试候选 commit,记录实际 SHA。git archive 从该 commit 构建 tar.gz 制品,生成制品外部的 JSON 清单,记录候选 commit SHA、制品 SHA-256、源码 SHA-256 和版本。它会断言制品中的笔记仍是提交版本,无关工作区编辑没有被打进制品。127.0.0.1 的系统分配端口启动其中的服务,并用真实 HTTP 请求验证默认超时值、版本、候选 SHA 和事件计数。git revert commit 恢复代码,再构建和运行回退制品。先前 HTTP 请求写入的临时事件文件仍有两条记录,展示 Git 回退不会自动撤销外部状态。每次输出中的 SHA-256、commit SHA 和端口都由本次运行产生。稳定的是输出标签和检查关系;示例格式见 expected.txt。
默认成功后会清理临时根。加 --keep 可保留成功结果:
python3 labs/ai-change-control/lab.py --keep
复制末行的路径到 lab_path,再检查真实中间证据:
lab_path=/printed/lab/root
python3 -m json.tool "$lab_path/evidence/exercise-evidence.json"
git -C "$lab_path/agent-worktree" log --oneline --decorate --all --graph
git -C "$lab_path/agent-worktree" status --short
cat "$lab_path/external-state/events.jsonl"
清理只接受脚本创建、名字匹配且根目录含正确标记文件的实验路径:
python3 labs/ai-change-control/lab.py --cleanup "$lab_path"
脚本不会删除仓库根目录、用户主目录、文件系统根目录、未标记目录,或临时目录之外的路径。
app.py,但只暂存了新增测试。测试为何在当前目录通过,而候选 commit 的干净 worktree 会失败?先写下判断,再运行实验,把它与 exercise-evidence.json 对照。
bash labs/ai-change-control/test.sh
自测会连续运行两次、验证每次保留结果的清单和事件证据、执行受控清理,并确认未标记路径被拒绝清理。
这是本地发布环境演练:HTTP 服务仅监听回环地址,事件文件是临时文件,清单是可重算的完整性记录。它没有连接真实 CI、托管平台、生产环境或外部服务;JSON 清单也不构成签名或供应链证明。
This lab uses a temporary Git repository and a minimal HTTP service to exercise one Agent-change acceptance chain:
intent -> scope -> candidate commit -> clean-checkout test -> artifact -> local runtime result -> code recovery
It needs only Python 3 and Git. The script creates all repositories, artifacts, runtime directories, and event records below its own temporary root. It does not commit, switch branches, or clean the host repository.
From the repository root:
python3 labs/ai-change-control/lab.py
Each run creates an isolated lab root and performs these observable actions:
SERVICE_TIMEOUT. Its tests retain the old-contract boundaries for missing, empty, non-integer, and non-positive values. The Agent changes the application, adds the target test, and edits an unrelated note.1 with the required failure message.30, preserve explicit positive values, and retain the prior errors for non-integer and non-positive values. It tests the candidate commit in a fresh clean worktree and records the actual SHA.git archive. An external JSON manifest records the candidate commit SHA, artifact SHA-256, source SHA-256, and version. The lab asserts that the note in the artifact is the committed version and excludes the unrelated working-tree edit.127.0.0.1 port and uses a real HTTP request to check the default timeout, version, candidate SHA, and event count.git revert commits to recover the code, then builds and runs a rollback artifact. The temporary event file retains two records, showing that a Git revert does not automatically undo external state.SHA-256 values, commit SHAs, and ports are measured anew on every run. The labels and assertions stay stable; see expected.txt for the output shape.
A successful default run removes its temporary root. Use --keep to retain one:
python3 labs/ai-change-control/lab.py --keep
Copy the final path into lab_path, then inspect real intermediate evidence:
lab_path=/printed/lab/root
python3 -m json.tool "$lab_path/evidence/exercise-evidence.json"
git -C "$lab_path/agent-worktree" log --oneline --decorate --all --graph
git -C "$lab_path/agent-worktree" status --short
cat "$lab_path/external-state/events.jsonl"
Cleanup accepts only an experiment path created by the script whose name and root marker both match:
python3 labs/ai-change-control/lab.py --cleanup "$lab_path"
The script refuses the repository root, home directory, filesystem root, unmarked directories, and paths outside the temporary directory.
app.py in its working tree but staged only the new test. Why does the test pass there while the clean worktree for the candidate commit fails?Write down your prediction before running the lab, then compare it with exercise-evidence.json.
bash labs/ai-change-control/test.sh
The self-test runs the lab twice, verifies each retained run’s manifest and event evidence, performs controlled cleanup, and checks that cleanup rejects an unmarked path.
This is a local release-environment exercise. The HTTP service listens only on loopback, and its event file is temporary. The manifest is a recomputable integrity record. The lab does not contact a real CI system, hosting platform, production environment, or external service, and its JSON manifest is not a signature or supply-chain proof.