本文是《AI Coding Assistant Best Practices:从提示词到工程闭环》的配套实操篇。前文解释原则,本文只做一件事:把一个普通仓库逐步变成 Agent 可以理解、修改、验证并交付的工程环境。

本文面向已经使用 Codex、Cursor、Claude Code 或 GitHub Copilot 的开发者。示例中的命令是模板,不代表适用于所有项目;执行前必须替换为仓库真实存在、已经人工确认过的命令。不要因为 Agent 能生成命令,就跳过读取 README、CI、构建文件和脚本。

完成本文后,目标仓库应具备一条可以重复运行的闭环:

1
Bootstrap → Instruct → Equip → Isolate → Implement → Verify → Review

它不意味着 Agent 可以自动批准危险操作。Rules、Instructions 和 Skills 都不是安全边界;Sandbox、Allow/Deny 策略、Hook、CI 和分支保护才分别承担访问限制、命令控制、确定性阻断、最终验收和合并保护职责。

1. 先定义完成状态

把“Agent-ready”写成可观察的结果,而不是一句“让 AI 更聪明”:

  • 新成员可以按文档启动项目,不需要猜运行时、依赖或入口。
  • Agent 可以从仓库文件找到构建、测试、Lint 和类型检查命令。
  • 快速验证和完整验证都由仓库脚本提供,CI 复用同一入口。
  • 每个任务都在独立分支或 worktree 中进行。
  • Agent 能提交文件级计划、执行结果和未验证项。
  • 高风险的生产写入、删除、扩权、迁移和外部写入会停下来等待人工批准。

2. 五类配置先分工

同一个 Markdown 文件可以被多个 Agent 读到,但“能被读到”不等于“每个工具都按相同语义处理”。先按职责放置内容:

类型 放什么 典型问题
AGENTS.md 跨工具、长期有效的项目事实和硬约束 项目入口在哪里?真实验证命令是什么?
Rule / Instruction 某路径、语言或文件类型的短规范 修改 API 时必须保持什么兼容性?
Skill 按需加载的多步骤流程、参考资料和可选脚本 如何执行一次系统化 Bug 调查?
Hook 必须在固定生命周期执行的格式化、阻断、审计或提醒 每次工具调用前如何阻止生产命令?
MCP 连接 Issue、知识库、浏览器、数据库等外部系统 如何读取工单或调用受控测试服务?

记忆口诀是:事实放指引,局部约束放 Rule,流程放 Skill,强制执行放 Hook,外部能力放 MCP。

3. 公共底座:目录与三个完成信号

3.1 推荐目录树

下面是适配层与公共底座分离的示例。.cursor.claude.github 是可选目录,不要为了“看起来完整”而全部创建。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
project/
├── AGENTS.md
├── README.md
├── CODEOWNERS
├── .gitignore
├── scripts/
│ ├── bootstrap.sh
│ ├── verify-fast.sh
│ └── verify.sh
├── docs/
│ ├── architecture.md
│ └── decisions/
├── src/
├── tests/
├── .agents/
│ └── skills/
│ └── release-check/
│ └── SKILL.md
├── .cursor/
│ └── rules/
│ └── api-contract.mdc
├── .claude/
│ └── rules/
│ └── api-contract.md
├── .github/
│ ├── copilot-instructions.md
│ ├── instructions/
│ │ └── api.instructions.md
│ └── workflows/
└── .devcontainer/
└── devcontainer.json

工具专用文件只做适配和索引,不复制整份公共规范。例如 Cursor Rule 可以写“先读取根目录 AGENTS.md,本文件只补充 API 文件的局部规则”,避免多个版本逐渐漂移。

3.2 三个完成信号

  1. 可启动:新成员在干净环境运行 scripts/bootstrap.sh,得到明确的成功或缺失依赖信息。
  2. 可验证:Agent 修改一个小而可逆的文件后,可以运行 scripts/verify-fast.sh 并报告退出状态。
  3. 可复用:CI 调用仓库脚本,而不是另写一套只有 CI 知道的命令。

4. 场景一:从零创建新项目

本场景贯穿创建一个 Search App Monorepoapps/web 是 React + TypeScript 前端,apps/api 是 FastAPI + Python 后端,数据层使用 PostgreSQL,测试使用 Pytest 与 Playwright,基础设施使用 Terraform 与 Kubernetes。推荐目标目录如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
search-app/
├── apps/
│ ├── web/
│ └── api/
├── packages/
│ └── contracts/
├── infra/
│ ├── terraform/
│ └── k8s/
├── scripts/
├── tests/
├── .agents/
│ └── skills/
└── .github/
└── workflows/

每个 Step 都要求 Agent 产出证据,但涉及版本、依赖、Git 设置、数据库、云资源、MCP、Hook 和安装动作时,最终决定权仍属于人。

Step 1:先定义运行与完成契约

实际操作入口:在目标目录中启动 Bootstrap Agent。它必须在首次写入前确认目录为空且不是 Git repository,再读取可见环境和官方帮助,记录真实输出;不能猜 Python、Node、uv、pnpm、PostgreSQL 或任何依赖版本,也不能自行选择未批准的依赖。

可复制的 Bootstrap Agent Prompt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
You are the bootstrap agent for a new Search App Monorepo.

Before creating or modifying any file:
1. Inspect the target directory without writing. Confirm it is empty and that `git rev-parse --is-inside-work-tree` does not report an existing repository. Stop on any existing file, `.git` directory, or repository.
2. Ask the human to approve the target directory, the allowed network scope, the toolchain, the dependency set, and the database and infrastructure policies.
3. Run only version and help commands for installed tools. Record the exact command and output for Python, Node.js, uv, pnpm, PostgreSQL client, Docker, Terraform, kubectl, Git, and the selected Agent tool.
4. Do not infer or upgrade a version. Do not install a tool or dependency. Do not select a package, framework plugin, database driver, lockfile format, or Kubernetes provider without explicit approval.
5. Produce a version-and-dependency proposal with three states for every item: verified, missing, or awaiting approval. Do not create the project until all required approvals are recorded.

After approval:
6. Create only this repository shape: apps/web, apps/api, packages/contracts, infra/terraform, infra/k8s, scripts, tests, .agents/skills, and .github/workflows.
7. Generate a minimal runnable React and TypeScript app in apps/web and a minimal runnable FastAPI app in apps/api using only the approved dependency set. Write the approved versions and dependencies to manifests and lockfiles.
8. Create pnpm-workspace.yaml, the root package.json with Playwright ownership, packages/contracts/package.json, and the approved pnpm and uv lockfiles.
9. Define a minimal Search API contract and a health or search vertical slice in packages/contracts and apps/api, then connect the approved web client to that slice without crossing the PostgreSQL boundary.
10. Add README.md, AGENTS.md, .gitignore, CODEOWNERS, scripts/bootstrap.sh, scripts/verify-fast.sh, scripts/verify.sh, and .github/workflows/verify.yml. Create `.agents/skills/project-bootstrap/SKILL.md` explicitly, using the template later in this article. Compute SHA-256 for every created file and write each path and hash to `.bootstrap-created-files.json`. Add the exact reviewed `generated_artifact_exclusions` list to the manifest.
11. Replace placeholders with verified commands for this repository; leave only genuinely unavailable checks marked unconfigured and fail-safe.
12. Implement `scripts/bootstrap.sh --ci` to install only committed lockfile dependencies and verify every configured Playwright project, its lockfile-matched browser executable, and required system dependencies without downloading browsers.
13. Run and record the real contracts test command and root Playwright command, including exact output and exit status. If either command cannot be established, mark it UNCONFIGURED and block final acceptance.
14. Run the first fast and full baseline after the skeleton is created. Record every command, exit status, duration, and pre-existing or environment-dependent failure.
15. Never create credentials, production configuration, cloud resources, migrations, or deployment applies.

Report: exact version commands and outputs, approved dependencies and lockfiles, created-file manifest with paths and SHA-256 hashes, package and Playwright ownership files, project-bootstrap Skill path, contract and vertical-slice files, contracts test evidence, root Playwright evidence, verified commands, baseline results, unresolved checks, commands not run, and the next human approval point.
Stop immediately on ambiguity or an existing user file.

任务契约模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
project:
name: "search-app"
frontend: "React with TypeScript"
backend: "FastAPI with Python"
database: "PostgreSQL"
browser_tests: "Playwright"
infrastructure: "Terraform and Kubernetes"
toolchain:
python: "VERIFIED_VERSION"
node: "VERIFIED_VERSION"
uv: "VERIFIED_VERSION"
pnpm: "VERIFIED_VERSION"
postgresql_client: "VERIFIED_VERSION"
commands:
bootstrap: "VERIFIED_COMMAND_OR_UNCONFIGURED"
web_dev: "VERIFIED_COMMAND_OR_UNCONFIGURED"
api_dev: "VERIFIED_COMMAND_OR_UNCONFIGURED"
fast_check: "VERIFIED_COMMAND_OR_UNCONFIGURED"
full_check: "VERIFIED_COMMAND_OR_UNCONFIGURED"
approval:
dependency_set: "PENDING"
database_schema: "PENDING"
infrastructure: "PENDING"

Agent 产物:版本记录、批准的依赖清单、目录树、最小可运行 Web/API、contract、lockfiles、README/AGENTS/脚本、created-file manifest、fast/full baseline 和未配置命令清单。
人工审批点:批准工具版本、依赖集合、网络访问范围、目标目录、数据库策略和 infrastructure 策略;确认 Bootstrap 生成物、package ownership、lockfiles、contracts test 和 root Playwright 证据可以进入审核。
完成标志:每个工具都标为 VERIFIEDMISSINGPENDING_APPROVAL,React/FastAPI 最小切片可运行,pnpm-workspace.yaml、root package.jsonpackages/contracts/package.json 和批准的 lockfiles 已写入,contracts test 与 root Playwright 命令有真实证据,未知项仍 fail-safe。

Step 2:初始化版本控制与隔离环境

实际操作入口:先由人工审核 Step 1 的 created-file manifest,再执行 Git 初始化。Step 1 已经创建文件,因此这里不再要求目录为空,也不使用 git status --porcelain 阻断受控未跟踪文件。以下命令只适用于 Step 1 manifest 已审核、内容完全一致且尚未初始化 Git 的新项目目录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
set -euo pipefail

if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
printf 'ERROR: an existing Git repository was found; stop without changing it.\n' >&2
exit 1
fi
test -d apps/web
test -d apps/api
test -d packages/contracts
test -d infra/terraform
test -d infra/k8s
test -d scripts
test -d tests
test -d .agents/skills
test -f .agents/skills/project-bootstrap/SKILL.md
test -f .github/workflows/verify.yml
test -f .bootstrap-created-files.json
manifest_paths_output="$(python3 - <<'PY'
import hashlib
import json
import os
from pathlib import Path

root = Path(".")
manifest_path = root / ".bootstrap-created-files.json"
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
entries = manifest.get("files")
if not isinstance(entries, list) or not entries:
raise SystemExit("ERROR: manifest must contain a non-empty files list.")

allowed_exclusions = {
".venv",
"node_modules",
".pnpm-store",
".pytest_cache",
"__pycache__",
"playwright-report",
"test-results",
".terraform",
"dist",
"build",
"coverage",
}
exclusions = manifest.get("generated_artifact_exclusions")
if not isinstance(exclusions, list) or set(exclusions) != allowed_exclusions:
raise SystemExit("ERROR: manifest exclusions must exactly match the reviewed generated-artifact list.")

declared = {}
for entry in entries:
path = entry.get("path")
expected_sha256 = entry.get("sha256")
if not isinstance(path, str) or not isinstance(expected_sha256, str):
raise SystemExit("ERROR: every manifest entry needs a path and sha256.")
relative_path = Path(path)
if (
path == ".bootstrap-created-files.json"
or path.startswith(".git/")
or relative_path.is_absolute()
or ".." in relative_path.parts
):
raise SystemExit("ERROR: manifest contains an invalid path.")
root_resolved = root.resolve()
resolved_path = (root / relative_path).resolve()
try:
relative_path = resolved_path.relative_to(root_resolved)
except ValueError:
raise SystemExit("ERROR: manifest path resolves outside the repository root.")
if os.path.commonpath((root_resolved, resolved_path)) != str(root_resolved):
raise SystemExit("ERROR: manifest path has an invalid common path.")
path = relative_path.as_posix()
if path in declared:
raise SystemExit(f"ERROR: manifest contains a duplicate path: {path}")
declared[path] = expected_sha256

required = {
".github/workflows/verify.yml",
".agents/skills/project-bootstrap/SKILL.md",
"pnpm-workspace.yaml",
"package.json",
"pnpm-lock.yaml",
"apps/api/pyproject.toml",
"apps/api/uv.lock",
"packages/contracts/package.json",
}
missing_required = sorted(required - declared.keys())
if missing_required:
raise SystemExit(f"ERROR: manifest omits required files: {missing_required}")

for path, expected_sha256 in declared.items():
file_path = root / path
if not file_path.is_file():
raise SystemExit(f"ERROR: manifest file is missing: {path}")
actual_sha256 = hashlib.sha256(file_path.read_bytes()).hexdigest()
if actual_sha256 != expected_sha256:
raise SystemExit(f"ERROR: SHA-256 mismatch for {path}")

actual = {
str(path.relative_to(root))
for path in root.rglob("*")
if path.is_file()
and path != manifest_path
and ".git" not in path.parts
and not any(
relative == excluded or relative.startswith(f"{excluded}/")
for excluded in exclusions
for relative in [str(path.relative_to(root))]
)
}
unexpected = sorted(actual - declared.keys())
if unexpected:
raise SystemExit(f"ERROR: unexpected files are present: {unexpected}")
print("\n".join(sorted(declared)))
PY
)"
git init
git branch -M main
manifest_paths=()
while IFS= read -r path; do
[[ -n "$path" ]] || continue
manifest_paths+=("$path")
done <<<"$manifest_paths_output"
git add -- "${manifest_paths[@]}" .bootstrap-created-files.json
git diff --cached --check
AUTHOR_NAME="$(git config --get user.name || true)"
AUTHOR_EMAIL="$(git config --get user.email || true)"
if [[ -z "$AUTHOR_NAME" || -z "$AUTHOR_EMAIL" ]]; then
printf 'ERROR: configure Git user.name and user.email manually before committing.\n' >&2
exit 1
fi
git commit -m "chore: establish search app baseline"
git rev-parse --verify HEAD
BASELINE_COMMIT="$(git rev-parse HEAD)"
git switch -c chore/agent-ready-foundation
git worktree add ../search-app-feature -b feat/first-search-slice "$BASELINE_COMMIT"

逐项把实际文件路径与 Step 1 manifest 比对;manifest 中的 generated_artifact_exclusions 必须是人工审核的固定列表,只能包含 .venv/node_modules/.pnpm-store/.pytest_cache/__pycache__/playwright-report/test-results/.terraform/dist/build/coverage/。这些目录及其内容、.git 和 manifest 自身可以排除;除此之外的所有实际文件都必须列入 manifest 且 SHA-256 匹配。如果目录内容多了、少了、路径不同或文件内容未经批准,立即停止,不要自动修复。若 git rev-parse --is-inside-work-tree 成功,说明目录已有 repository,立即停止,不要 git init。不要对已有仓库运行本段命令。Step 1 之后出现的用户修改同样不得覆盖、清理或提交。

人工步骤:

  1. 检查 git diff --cached --check、Commit ID 和提交内容。
  2. 检查只读读取到的 user.nameuser.email;任一缺失时由人配置,Agent 不得修改 Git config。
  3. CODEOWNERS 中为 apps/api/apps/web/packages/contracts/infra/.agents/ 指定真实负责人。
  4. 在 GitHub 或其他 Git 服务中人工开启 branch protection:禁止直接推送默认分支,要求 Pull Request、CI 成功和至少一名负责人审查;不要让 Agent 修改这些设置。
  5. 人工确认 worktree 路径和分支名称,不允许 Agent 自动推送、合并、改写历史或删除分支。

可复制的检查 Prompt:

1
Inspect the Git state without changing it. Verify that the initial commit is parseable, the working tree has no unintended changes, CODEOWNERS covers application, contract, and infrastructure paths, and the feature worktree points to the recorded baseline. Report evidence. Do not push, merge, rewrite history, change branch protection, or delete anything.

Agent 产物:manifest 比对报告、可解析的首个 Commit、基线 Commit ID、独立分支/worktree 检查报告和待人工配置清单。
人工审批点:接受 manifest 比对和首个 Commit;批准 CODEOWNERS、branch protection、CI 必需检查和 worktree 位置。
完成标志:已有 repository 会被显式阻断,manifest 不一致会停止,git rev-parse --verify HEAD 成功,基线可复现,工作区用户修改未被覆盖,默认分支保护由人完成。

Step 3:写第一个 AGENTS.md

实际操作入口:在根目录创建公共指引;它必须描述 Search App 的真实边界、命令和审批,而不是泛泛要求“保持高质量”。下面是一份可直接落地、提交前仍需人工替换版本和命令的完整模板。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# Search App Agent Guide

## Project

- Purpose: Provide a search web application with a React client and a FastAPI service.
- Frontend: `apps/web` uses React and TypeScript.
- Backend: `apps/api` uses FastAPI and Python.
- Shared contract: `packages/contracts` is the source of truth for API request and response shapes.
- Database: PostgreSQL is accessed by the API only.
- Tests: Pytest covers Python behavior; Playwright covers approved browser journeys.
- Infrastructure: Terraform describes infrastructure; Kubernetes manifests describe workloads.

## Repository map

- `apps/web/`: browser UI, client state, and browser-facing API calls.
- `apps/api/`: HTTP routes, validation, service logic, database access, and migrations.
- `packages/contracts/`: versioned API contract and generated client types when approved.
- `infra/terraform/`: infrastructure declarations; never apply from an Agent session.
- `infra/k8s/`: Kubernetes manifests; never apply to a real cluster from an Agent session.
- `scripts/`: repository-owned bootstrap and verification entry points.
- `tests/`: cross-application, integration, and Playwright tests.
- `.agents/skills/`: reviewed, pinned, repository-local Agent workflows.
- `.github/workflows/`: approved CI workflows that call repository verification scripts.
- `README.md`: verified setup and command reference.

## Boundaries

- `apps/web` may call the public API contract but must not access PostgreSQL.
- `apps/api` owns validation, authorization, query construction, and database access.
- Contract changes require updates to compatibility tests, documentation, and affected clients.
- Edit generators instead of generated files.
- Do not modify migrations, Terraform, Kubernetes manifests, dependency locks, or production configuration without explicit approval.
- Do not create cloud resources, run production applies, expose services, or change database schema automatically.
- Do not read, print, commit, or transmit secrets. Use approved environment injection.
- Keep changes inside the requested scope and preserve existing user modifications.

## Authoritative commands

Run only commands verified in `README.md`, CI, or repository scripts.

- Bootstrap: `./scripts/bootstrap.sh`
- Web development: `pnpm --dir apps/web dev`
- API development: `uv run --project apps/api uvicorn app.main:app --reload`
- Fast verification: `./scripts/verify-fast.sh`
- Full verification: `./scripts/verify.sh`
- Python tests: `uv run --project apps/api pytest`
- Browser tests: `pnpm exec playwright test`
- Terraform validation: `terraform -chdir=infra/terraform init -backend=false && terraform -chdir=infra/terraform validate`
- Kubernetes validation: `kubectl apply --dry-run=client -f infra/k8s/`

If a command is not verified, report it as unconfigured and fail the corresponding script.

## Testing

- Add focused Pytest coverage for API and data behavior.
- Add contract compatibility tests when `packages/contracts` changes.
- Use Playwright only against an approved local or test environment.
- Run the fast check after each vertical slice.
- Run the full check before delivery.
- Record commands, exit status, duration, skipped checks, and pre-existing failures.

## Git permissions

- Work on a dedicated branch or worktree.
- Do not push, merge, rewrite history, delete branches, or change repository settings without approval.
- Do not commit credentials, local state, database dumps, build output, or generated secrets.
- Keep commits small and explain the user-visible result.

## Approval gates

- Human approval is required for dependencies, public API changes, database schema or migrations, Terraform changes, Kubernetes changes, network access, external writes, and production actions.
- Rules, Skills, AGENTS.md files, and prompts are not security boundaries.
- Sandbox, permissions, Allow/Deny policy, Hooks, CI, and branch protection provide separate controls.

## Completion report

Report changed files, contract and behavior changes, exact commands, exit status, duration,
test evidence, skipped or unconfigured checks, known failures, approvals requested,
security-sensitive actions, and rollback instructions.

包级 AGENTS.md 只能补充目录事实,例如 apps/api/ 的数据库边界或 apps/web/ 的 UI 约定;不要复制根文件。创建后用以下 Prompt 检查层级和事实:

1
Read the root AGENTS.md and every existing nested AGENTS.md. Compare them with the Search App directory tree, README, package manifests, CI files, and scripts. Report contradictions, invented commands, missing approval gates, and files that are outside the declared map. Do not edit files.

Agent 产物:根 AGENTS.md、必要的包级补充指引和事实冲突报告。
人工审批点:确认运行时、边界、测试命令、数据库/infra 审批和 Git 权限表述真实;确认没有把 Rules/Skills 当成安全控制。
完成标志:新 Agent 仅读指引和 README 就能找到 monorepo 地图、真实命令、测试入口、边界和完成报告格式。

Step 4:添加工具适配层

实际操作入口:只创建确实需要的适配文件,并让它们引用根 AGENTS.md;不要复制整份规则,也不要捏造统一 /init

  • Codex:原生使用分层 AGENTS.md/init 可生成初稿,生成后必须人工精简。Skills、MCP、permissions 和 review 使用 Codex 自己的配置与文档。
  • Cursor:公共事实放 AGENTS.md;路径规则放 .cursor/rules/*.mdc;流程放 .agents/skills/.cursor/skills/。Cursor 没有与 Codex /init 完全等价的统一初始化命令。
  • Claude Code:原生核心是 CLAUDE.md.claude/rules//init/context。不要声称它与 Codex 对 AGENTS.md 完全等价;若引用公共文件,先核对当前版本的导入行为。
  • GitHub Copilot:区分 CLI、IDE、Cloud Agent 和 Code Review。仓库级公共指引使用 .github/copilot-instructions.md,路径规则使用 .github/instructions/*.instructions.md。没有统一 /init

不要跨工具复制 Hook 事件和配置格式。MCP 配置入口也不同:Codex 通常使用 config.toml,Cursor 使用 .cursor/mcp.json 或 Customize,Claude Code 使用 claude mcp add,Copilot 使用其支持的 .mcp.json.github/mcp.json 入口;这些配置随产品变化较快,使用前核对当前官方文档。

落地顺序:

  1. 先把根 AGENTS.md、README 和验证脚本提交为公共事实层。
  2. 为每个实际使用的工具只增加入口指引、路径规则或索引。
  3. 在测试仓库分别启动四种工具,确认它们读取的文件、层级和命令,不以一个工具的行为推断另一个工具。

检查 Prompt:

1
For the selected Agent tool, identify its official repository instruction file, rule directory, skill directory, MCP entry point, hook entry point, and initialization commands. Compare each claim with the current official documentation. Then inspect this repository and report exactly which adapter files are needed. Do not create a universal init command, copy another tool's configuration, or edit files before approval.

Agent 产物:适配矩阵、最小入口文件、官方文档核对记录和启动检查结果。
人工审批点:选择实际使用的工具;批准新增适配文件、规则层级、官方文档版本和信任设置。
完成标志:每个适配层可独立解释、可启动、可检查,且没有把 Codex、Cursor、Claude Code、Copilot 的语义或配置格式混为一谈。

Step 5:建立验证脚手架

实际操作入口:把 Search App 的真实命令接入 scripts/verify-fast.shscripts/verify.sh。脚本必须 fail-safe:命令为空、仍是占位符、工具缺失或检查未配置时返回非零,不能静默跳过。

scripts/verify-fast.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/usr/bin/env bash
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"

run_required() {
local label="$1"
shift
if [[ "$#" -lt 1 ]]; then
printf 'ERROR: %s has no configured command.\n' "$label" >&2
return 1
fi
local argument
for argument in "$@"; do
if [[ -z "$argument" ||
"$argument" == *REPLACE_WITH_* ||
"$argument" == *UNCONFIGURED* ]]; then
printf 'ERROR: %s is not configured with a verified command.\n' "$label" >&2
return 1
fi
done
printf 'Running %s\n' "$label"
"$@"
}

run_required "web format check" pnpm --dir apps/web format:check
run_required "web lint" pnpm --dir apps/web lint
run_required "web typecheck" pnpm --dir apps/web typecheck
run_required "api lint" uv run --project apps/api ruff check .
run_required "api focused tests" uv run --project apps/api pytest tests/unit -q
run_required "contract check" pnpm --dir packages/contracts test

scripts/verify.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/usr/bin/env bash
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"

run_required() {
local label="$1"
shift
if [[ "$#" -lt 1 ]]; then
printf 'ERROR: %s has no configured command.\n' "$label" >&2
return 1
fi
local argument
for argument in "$@"; do
if [[ -z "$argument" ||
"$argument" == *REPLACE_WITH_* ||
"$argument" == *UNCONFIGURED* ]]; then
printf 'ERROR: %s is not configured with a verified command.\n' "$label" >&2
return 1
fi
done
printf 'Running %s\n' "$label"
"$@"
}

run_required "web format check" pnpm --dir apps/web format:check
run_required "web lint" pnpm --dir apps/web lint
run_required "web typecheck" pnpm --dir apps/web typecheck
run_required "api lint" uv run --project apps/api ruff check .
run_required "api unit tests" uv run --project apps/api pytest
run_required "contract compatibility tests" pnpm --dir packages/contracts test
run_required "Playwright tests" pnpm exec playwright test
run_required "Terraform init" terraform -chdir=infra/terraform init -backend=false
run_required "Terraform validation" terraform -chdir=infra/terraform validate
run_required "Kubernetes manifest validation" kubectl apply --dry-run=client -f infra/k8s/
run_required "web build" pnpm --dir apps/web build
run_required "security scan" REPLACE_WITH_APPROVED_SECURITY_SCAN_COMMAND
1
2
chmod +x scripts/verify-fast.sh scripts/verify.sh
./scripts/verify-fast.sh

CI 应直接调用 ./scripts/verify-fast.sh./scripts/verify.sh,不要在 workflow 中另写一套命令。Agent 检查 Prompt:

1
Inspect scripts/verify-fast.sh and scripts/verify.sh. Map every command to apps/web, apps/api, packages/contracts, tests, infra/terraform, or infra/k8s. Execute the fast check only after confirming commands are verified. Confirm that an unconfigured command, missing tool, failed test, Terraform validation failure, or Kubernetes validation failure returns non-zero. Report the CI command reuse path. Do not replace placeholders with guesses.

受审批的 CI 示例(.github/workflows/verify.yml)只复用仓库脚本;不要让 Agent 自动 push。干净 runner 必须使用由人工构建和批准、并固定 digest 的 CI container image;该镜像应包含 Step 1 记录的精确 Node.js、pnpm、Python、uv、Terraform、kubectl 版本,以及与 lockfile 中 Playwright 版本匹配的全部 configured browser projects 的 browser binaries 和 system dependencies。bootstrap.sh --ci 只能安装 lockfile dependencies,并必须验证 Playwright 版本、每个 configured browser project 的 browser executable 和 system dependencies 已存在;不得隐式联网下载安装未知浏览器。以下所有 REPLACE_WITH_* 值在验收前必须替换并审核,带占位符的模板不可宣称可用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
name: verify

on:
pull_request:
push:
branches: ["main"]

jobs:
verify:
runs-on: ubuntu-latest
container:
image: REPLACE_WITH_APPROVED_CI_IMAGE@sha256:REPLACE_WITH_REVIEWED_IMAGE_DIGEST
permissions:
contents: read
steps:
- uses: actions/checkout@REPLACE_WITH_APPROVED_ACTION_SHA
- name: Install lockfile dependencies
run: ./scripts/bootstrap.sh --ci
- name: Verify Playwright browser
run: |
pnpm exec playwright --version
pnpm exec playwright test --list
pnpm exec playwright test tests/smoke/browser-launch.spec.ts
- name: Run fast verification
run: ./scripts/verify-fast.sh
- name: Run full verification
run: ./scripts/verify.sh

CI 验收 Prompt:

1
Inspect the approved CI workflow and both repository verification scripts. Prove that the workflow invokes ./scripts/verify-fast.sh and ./scripts/verify.sh, and that it does not duplicate their underlying commands. Use the workflow file, CI configuration, and a completed CI run as evidence. Record the CI run URL or log reference, commit SHA, job names, exit statuses, and skipped checks. Do not push, approve, merge, or change branch protection.

人工打开一个 Pull Request 后,检查 workflow 的实际日志和 run URL;对照脚本逐项确认 CI 没有复制另一套命令。还要验证 container 中的工具版本与 Step 1 记录一致、playwright test --list 列出的每个 project 都有匹配且可执行的 browser binary、最小 browser launch/smoke test 在所有 configured projects 中通过、system dependencies 存在、./scripts/bootstrap.sh --ci 使用 lockfiles 且没有隐式浏览器下载。没有可访问的 CI run 时,验收状态必须是未验证,而不是通过。

CI bootstrap 失败验收 Prompt:

1
Run the approved CI workflow on a clean runner using the reviewed digest-pinned container image. Verify the exact Node.js, pnpm, Python, uv, Terraform, kubectl, and Playwright system dependency versions against the Step 1 record. Verify that ./scripts/bootstrap.sh --ci installs only the committed lockfile dependencies, lists every configured Playwright project, validates the matching browser executable and system dependencies for every project, runs the minimal browser launch/smoke test for every project, and does not download an unapproved browser. A missing lockfile, dependency installation failure, project mismatch, browser mismatch, missing executable, missing system dependency, smoke-test failure, or tool version mismatch must fail the job before verification. Record the CI run URL, commit SHA, image digest, tool outputs, logs, exit statuses, and failure evidence. Do not push, approve, merge, or change repository settings.

Agent 产物:两个可执行验证脚本、命令映射、首次基线结果和 CI 复用说明。
人工审批点:批准真实 lint、typecheck、Pytest、Playwright、Terraform、Kubernetes、build 和 security 命令;确认测试数据库与浏览器环境不是生产环境。
完成标志:快速检查覆盖 Web/API/contract,完整检查覆盖 Pytest/Playwright/infra/build/security,CI 复用同一脚本,未配置项会失败。

Step 6:只安装最小 Skills 套件

实际操作入口:先生成审查报告,再人工安装;不要让 Agent 直接安装或执行未知 Skill。先安装或自建 skill-creator,然后只按触发场景加入 systematic-debuggingtest-driven-developmentverification-before-completionrequesting-code-review。Web 项目再评估 Anthropic webapp-testing、Microsoft playwright-cli 或经审查的 Playwright 流程;React 项目按需评估 Vercel 的 react-best-practicesweb-design-guidelines

安全敏感项目可以评估 OpenAI codex-security、NVIDIA Verified Skills、Trail of Bits 审计 Skills,或逐项审查 github/awesome-copilot 中的安全 Skill。openai/skills 已弃用,Codex 优先参考官方 Skills 文档和 openai/plugins

skills.sh 是 Vercel 运营的发现与安装生态,不是所有 Skill 的官方维护者,也不代表安全背书。github/awesome-copilot 是 GitHub 组织下的社区贡献集合,具体 Skill 仍需审查。

GitHub CLI 的命令是单数 skill,不是 skills。截至 2026-08,gh skill 要求 GitHub CLI 2.90.0+,并处于 public preview:

1
2
3
4
5
gh skill preview github/awesome-copilot documentation-writer
gh skill install github/awesome-copilot documentation-writer \
--agent REPLACE_WITH_SUPPORTED_AGENT \
--scope REPLACE_WITH_SUPPORTED_SCOPE \
--pin REPLACE_WITH_REVIEWED_TAG_OR_SHA

也可以使用 Skills 生态工具,但应同时固定安装 CLI 和 Skill 来源。先 checkout 已审查的来源版本,再从本地目录安装:

1
2
3
4
5
git clone https://github.com/vercel-labs/agent-skills.git reviewed-agent-skills
git -C reviewed-agent-skills checkout REPLACE_WITH_REVIEWED_TAG_OR_SHA
npx skills@REPLACE_WITH_REVIEWED_CLI_VERSION add ./reviewed-agent-skills \
--skill web-design-guidelines \
--agent REPLACE_WITH_SUPPORTED_AGENT

推荐优先检查这些来源:

  • anthropics/skills
  • openai/plugins
  • nvidia/skills
  • microsoft/playwright-cli
  • vercel-labs/agent-skills
  • trailofbits/skills
  • obra/superpowers(社区流程套件,需要单独评估)

安装前检查来源、许可证、最近变更、SKILL.mdscripts/references/assets/、依赖、网络、凭据、自动触发和破坏性动作。固定 Tag 或 Commit SHA,记录负责人和更新策略。Skill 可以携带可执行脚本,不能按“纯提示词”信任。

审查 Prompt:

1
Create a Skill security review report before installing anything. For each proposed Skill, inspect the pinned source, tag or commit, license, SKILL.md, scripts, references, assets, dependencies, network access, credential access, automatic triggers, file writes, shell commands, and destructive actions. Classify findings as allow, allow-after-human-approval, or reject. Include exact evidence and an update owner. Do not install, execute, or modify the repository until a human approves the report.

Agent 产物:固定来源和版本、逐项安全审查报告、最小安装清单和更新负责人记录。
人工审批点:审查代码与脚本;批准来源、Tag/SHA、CLI 版本、安装 scope、触发方式和更新策略。
完成标志:只安装已审查且固定版本的最小 Skill 集合,安装动作可回滚,未知脚本和网络行为未被执行。

Step 7:配置最小权限与 MCP

实际操作入口:先只读、后写入;为 Search App 只接入确实需要的文档、Issue 或代码查询服务。MCP 提供能力连接,不提供天然安全保证。生产数据库禁止由 Agent 直接操作;数据库变更通过受控流水线和人工审批执行。

采用以下执行清单:

  1. 列出服务器、工具、启动命令、工作目录、网络目的地和所需环境变量。
  2. 默认只允许 searchfetch 等只读工具;写 Issue、创建 PR、浏览器提交、数据库变更和生产操作分别授权。
  3. 验证 Allow/Deny、人工审批、超时、服务器退出、缺少 Token 和无效响应的行为。
  4. Token 使用环境变量、OAuth 或 Secret Manager 注入,不写入 JSON、TOML、Rule 或 Skill。
  5. 人工检查服务器实现、Tool annotations、外部系统权限和审计记录。

下面只展示只读文档服务器的配置形状,名称、包名和 URL 都必须替换成已审查的真实服务。配置中不放真实 Token。

Codex:~/.codex/config.toml 或受信任项目的 .codex/config.toml 中使用 mcp_servers 表;stdio 使用 command,远程 Streamable HTTP 使用 urlenv_vars 可转发当前环境变量,HTTP 可使用 bearer_token_env_var

1
2
3
4
5
6
[mcp_servers.readonly_docs]
command = "REPLACE_WITH_VERIFIED_DOCS_SERVER"
args = ["REPLACE_WITH_VERIFIED_READ_ONLY_ARGUMENT"]
env_vars = ["DOCS_MCP_TOKEN"]
enabled_tools = ["search", "fetch"]
default_tools_approval_mode = "prompt"

检查方式:运行 codex mcp list,需要更多选项时运行 codex mcp --help,并在 Codex TUI 中用 /mcp 确认只出现预期的只读工具。

Cursor: 在项目 .cursor/mcp.json 或 Customize 中添加 MCP。Cursor 的环境变量插值使用 ${env:NAME},远程服务器不能使用 envFile

1
2
3
4
5
6
7
8
9
10
11
12
{
"mcpServers": {
"readonly-docs": {
"type": "stdio",
"command": "REPLACE_WITH_VERIFIED_DOCS_SERVER",
"args": ["REPLACE_WITH_VERIFIED_READ_ONLY_ARGUMENT"],
"env": {
"DOCS_MCP_TOKEN": "${env:DOCS_MCP_TOKEN}"
}
}
}
}

检查方式:在 Cursor Customize 页面确认服务器状态和工具列表,或使用当前 Cursor MCP 面板执行只读工具检查。不要将 Cursor JSON 当作 Codex TOML。

Claude Code: 推荐通过 CLI 添加并显式指定 scope。stdio 的 -- 分隔 Claude Code 参数和服务器参数;--env 的值来自本地环境或受控 Secret 注入,不要把真实凭据提交到仓库。

1
2
3
4
claude mcp add --transport stdio --scope project readonly-docs \
--env DOCS_MCP_TOKEN="$DOCS_MCP_TOKEN" \
-- REPLACE_WITH_VERIFIED_DOCS_SERVER REPLACE_WITH_VERIFIED_READ_ONLY_ARGUMENT
claude mcp list

在 Claude Code 会话内使用 /mcp 检查服务器和工具列表。若直接编辑 .mcp.json,退出并重新启动会话后再检查。

GitHub Copilot: Copilot CLI 项目级 MCP 可放在根目录 .mcp.json.github/mcp.json;Cloud Agent 的仓库配置入口与 CLI 不完全相同,必须按当前 GitHub 文档配置。下面的本地只读示例不需要凭据。Cloud Agent 支持 $COPILOT_MCP_NAME${COPILOT_MCP_NAME} 和带默认值的官方引用语法,并且被引用的 Secret 或变量名必须以 COPILOT_MCP_ 开头;不要套用其他客户端的插值规则。

1
2
3
4
5
6
7
8
9
10
{
"mcpServers": {
"readonly-docs": {
"type": "local",
"command": "REPLACE_WITH_VERIFIED_DOCS_SERVER",
"args": ["REPLACE_WITH_VERIFIED_READ_ONLY_ARGUMENT"],
"tools": ["search", "fetch"]
}
}
}

检查方式:Copilot CLI 运行 copilot mcp list --json,交互模式运行 /mcp show,并确认工作目录已信任;Cloud Agent 检查仓库 MCP 配置与 Agent secrets/variables。若服务器需要认证,优先使用 OAuth、Copilot 的交互式添加流程或对应平台的 Secret 机制;共享配置只引用 COPILOT_MCP_* Secret 或变量,不写入实际 Token。

四个工具的配置格式、信任模型、工具筛选字段和检查命令不能互相复制。涉及快速变化的字段时,先打开当前官方文档,使用测试仓库验证启动、工具列表、只读行为、缺少 Token 时的失败行为和审计记录。

验收 Prompt:

1
For the configured MCP server, produce an execution checklist covering startup, server list, tool list, allowed tools, denied tools, approval prompts, timeout, missing-token behavior, process failure, invalid response, audit evidence, and rollback. Run read-only checks only. Do not call a write tool, connect to production PostgreSQL, apply Terraform, apply Kubernetes manifests, or expose credentials.

Agent 产物:逐工具权限矩阵、启动与工具列表证据、allow/deny/approval/timeout/failure 验收报告。
人工审批点:批准服务器、scope、环境变量、工具白名单、网络范围和任何写入权限;确认数据库与 infra 只走受控流程。
完成标志:只读 MCP 能启动并展示预期工具,拒绝和失败行为可观察,凭据未进入配置,生产操作没有直接入口。

Step 8:配置最小 Hooks

实际操作入口:只把每次都必须执行的格式化、敏感文件保护、命令阻断、审计和提醒放入 Hook。先在测试仓库验证触发、超时、无效输入和 fail-closed/fail-open 行为。Rules/Skills 不是安全边界;高风险控制仍需要权限策略、CI 和人工审批。

执行清单:

  1. 记录每个工具的 Hook 入口、事件名、输入协议、输出协议、matcher、timeout 和失败行为。
  2. 用无害的 terraform plankubectl diff 和模拟生产命令测试允许、阻止、超时、崩溃和无效输出。
  3. 验证 Hook 是否真的覆盖 Bash/Shell 工具;不要凭配置文件存在推断已生效。
  4. 将 Hook 日志纳入审计,但不要记录 Token、连接串或完整请求体。
  5. 人工确认生产命令、数据库写入、凭据访问和外部写入仍有独立审批。

Codex: 配置入口是受信任项目的 .codex/hooks.jsonconfig.toml[hooks],事件名使用 PascalCase。下面是 hooks.json 的最小入口和一个 Bash PreToolUse 输出片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"hooks": {
"PreToolUse": [
{
"matcher": "^Bash$",
"hooks": [
{
"type": "command",
"command": "./.codex/hooks/block-production.sh",
"timeout": 10
}
]
}
]
}
}
1
2
3
4
5
6
7
#!/usr/bin/env bash
set -euo pipefail

input="$(cat)"
if printf '%s' "$input" | grep -Eq '(^|[[:space:]])(kubectl|terraform)[[:space:]].*(apply|delete|destroy)'; then
printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Production mutation blocked by hook."}}'
fi

PreToolUse 通过 stdout 返回 hookSpecificOutputpermissionDecision: "deny" 阻止工具调用,未返回决定则交给正常审批流程。不要在 Codex PreToolUse 中使用尚未支持的 continue: falsestopReasonpermissionDecision: "ask"。检查当前 Codex Hooks 文档中的事件、输入字段和受支持工具覆盖范围。

Cursor: 入口是项目 .cursor/hooks.json;顶层使用 "version": 1,事件名使用 camelCase。以下示例采用 beforeShellExecution、命令 Hook、matchertimeoutfailClosed 字段;安装后必须按当前 Cursor 官方 Hooks 文档和实际版本验收:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"version": 1,
"hooks": {
"beforeShellExecution": [
{
"type": "command",
"command": "./.cursor/hooks/block-production.sh",
"timeout": 10,
"matcher": "kubectl|terraform",
"failClosed": true
}
]
}
}

Hook 从 stdin 接收命令上下文并通过 stdout 返回 JSON 权限决定。对 beforeShellExecution,退出码 0 使用 Hook 输出,退出码 2 阻止动作;其他错误默认放行,failClosed: true 可在失败、超时或无效 JSON 时阻止。字段和配置入口变化较快,安装后必须用当前 Cursor 官方文档和实际测试命令验证允许、阻止、超时和无效输出四种结果;若当前版本不支持该入口,状态应记为未配置,不得猜测替代字段。

Claude Code: 入口是项目 settings 中的 hooks,也可以在 Skill frontmatter 中注册;事件名使用 PascalCase。官方确认的 PreToolUse 结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-production.sh"
}
]
}
]
}
}

脚本 stdout 返回的最小阻断对象是:

1
2
3
4
5
6
7
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Production mutation blocked by hook."
}
}

deny 取消工具调用并把原因反馈给 Claude;allowdenyask 的权限语义由 PreToolUse 定义。也可以使用退出码 2 阻止并把 stderr 作为原因,但同一个 Hook 应选择一种输出方式。用当前 Claude Code 文档验证 JSON 输入、settings 层级和 workspace trust。

GitHub Copilot: 入口是 .github/hooks/*.json,顶层必须有 "version": 1;事件使用 camelCase。CLI 的最小安全入口需要 macOS/Linux 的 bash 和 Windows 的 powershell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"version": 1,
"hooks": {
"preToolUse": [
{
"type": "command",
"bash": "./scripts/copilot-pre-tool-use.sh",
"powershell": "./scripts/copilot-pre-tool-use.ps1",
"cwd": ".",
"timeoutSec": 15
}
]
}
}

脚本从 stdin 读取工具输入。preToolUse 命令 Hook 的退出码 2、崩溃和其他非超时错误会阻止工具执行,但超时始终 fail-open,仅返回正常权限流程。具体 JSON 输入和输出字段应按当前 Copilot Hooks Reference 实现。先用无害测试命令验证允许、阻止、超时和脚本错误四种情况;高风险控制不能只依赖 Hook,还需要权限策略、CI 和人工审批。

以上四段不能互相复制:Codex 使用 PascalCase 和 hookSpecificOutput,Cursor 使用 camelCase、退出码 2failClosed,Claude Code 使用 PascalCase 与 hookSpecificOutput,Copilot 使用 .github/hooks/*.jsonversion: 1、bash/powershell 以及自己的输入输出协议。Hook 是确定性控制的一层,但 CI 仍然是最终权威;Hook 失败不能被 Agent 的文字结论覆盖。

验收 Prompt:

1
Execute the Hook acceptance checklist in a disposable test repository. Test an allowed read-only command, a blocked production mutation, a timeout, a crashed hook, invalid JSON, and missing input. Record the actual event, exit status, stdout, stderr, decision, and whether the underlying tool ran. Do not use real credentials, production endpoints, Terraform apply, Kubernetes apply, database writes, or destructive commands.

Agent 产物:四工具 Hook 适配记录、测试矩阵、触发证据、超时与失败行为报告和审计字段清单。
人工审批点:批准阻断规则、timeout、fail behavior、日志范围和测试环境;人工确认 Hook 不是唯一安全控制。
完成标志:允许、阻止、超时、崩溃和无效输入的实际行为都已记录,核心示例未被删除,生产写入仍被独立策略拦截。

.agents/skills/project-bootstrap/SKILL.md 模板

该 Skill 只提供可审查的初始化流程,不代替权限、Hook、CI 或人工审批。它不会自动触发;Agent 必须在验收 Prompt 中被明确要求发现并调用它。模板保持英文,便于跨工具复用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
---
name: project-bootstrap
description: Bootstrap an approved Search App Monorepo from verified local tools and repository decisions.
---

# Project Bootstrap Skill

## Trigger

Use only when a human explicitly requests initialization of a new Search App Monorepo.
Do not trigger automatically for existing repositories, migrations, production changes, or dependency upgrades.

## Inputs

Require the target directory, approved tool versions, approved dependencies, network scope,
repository owner, verification commands, database policy, and infrastructure policy.
Stop if any input is missing or conflicts with existing files.

## Initialization

1. Inspect the directory without changing it.
2. Record exact version and help command outputs for approved tools.
3. Create only `apps/web`, `apps/api`, `packages/contracts`, `infra/terraform`,
`infra/k8s`, `scripts`, `tests`, `.agents/skills`, and `.github/workflows`.
4. Create a minimal runnable React and TypeScript web app and FastAPI Python API,
write approved dependency manifests and lockfiles, and define a minimal Search API slice.
5. Create documentation, ignore rules, and fail-safe verification entry points.
6. Do not install unapproved tools or dependencies.

## Verification

Run only verified commands. Fail when a command is missing, unconfigured, or exits non-zero.
Verify the directory map, Git baseline, contract boundary, fast check, full check wiring,
and the first fast and full baseline.

## Boundaries

Never read, print, commit, or transmit secrets. Never overwrite user changes.
Never run database writes, migrations, Terraform apply, Kubernetes apply, production commands,
external writes, or Git history operations without explicit human approval.
Rules, Skills, prompts, and AGENTS.md are not security boundaries.

## Completion report

Report exact tool outputs, approved dependencies and lockfiles, created-file manifest,
contract and vertical-slice files, commands and exit statuses, baseline results,
unconfigured checks, skipped actions, approval requests, risks, and rollback instructions.

简化调用 Prompt:

1
Explicitly discover and invoke the reviewed project-bootstrap Skill for the approved Search App Monorepo. Verify and record tool versions first, stop for missing approvals or existing files, create only the approved directory map, generate the minimal React and FastAPI vertical slice with approved lockfiles, wire fail-safe checks, run fast and full baselines, and return the required completion report. Do not install, apply, migrate, push, or overwrite anything.

Step 9:运行一次 Agent-ready 验收

实际操作入口:在独立测试分支或 worktree 中发送一个只改文档的小任务。下面 Prompt 要求 Agent 解释仓库、运行 fast check、做可逆变更、重新验证并报告证据:

1
2
3
4
5
6
7
8
9
10
11
12
13
You are performing the final Agent-ready acceptance for the Search App Monorepo.

1. Read the root AGENTS.md, README.md, the repository map, verification scripts, applicable tool adapter files, and `.agents/skills/project-bootstrap/SKILL.md`.
2. In a disposable empty fixture, ask the selected Agent tool to discover and explicitly invoke the repository `project-bootstrap` Skill. Record the discovery path and invocation evidence. Explain that it is not automatically triggered. Do not invoke it against this existing repository.
3. Explain the roles and boundaries of apps/web, apps/api, packages/contracts, infra/terraform, infra/k8s, scripts, tests, and .agents/skills.
4. Verify pnpm-workspace.yaml, the root package.json with Playwright ownership, packages/contracts/package.json, and the approved lockfiles. Verify the recorded contracts test and root Playwright command evidence. If either command is UNCONFIGURED, stop and fail acceptance.
5. Run the verified fast-check entry point exactly as documented. Report the command, exit status, duration, pre-existing failures, and any unconfigured check. Do not invent a replacement command.
6. Make one small, reversible documentation-only change in an approved documentation file. Do not touch application code, contracts, dependencies, migrations, PostgreSQL data, Terraform, Kubernetes manifests, credentials, hooks, or settings.
7. Show the diff and explain why the change is reversible.
8. Run the same fast-check entry point again and compare the evidence with the baseline.
9. Do not commit, push, merge, create infrastructure, access production, or call write-capable MCP tools.

Return a completion report with: repository explanation, changed file, diff summary, exact commands, exit statuses, durations, test evidence, skipped or unconfigured checks, approval requests, security-sensitive actions, and rollback instructions.

验收重点是 Agent 是否读到了正确规则、是否理解前后端与 contract 边界、是否能复用真实验证入口、是否越界修改、是否把猜测标成事实,以及是否诚实报告未运行的检查。

Agent 产物:仓库解释、两次 fast check 证据、可逆文档 diff、完整完成报告和未验证项清单。
人工审批点:审查 diff、命令与退出状态;确认没有应用代码、数据库、infra、凭据或外部写入;决定是否接受 Agent-ready 基线。
完成标志:Agent 能解释 Search App、完成两次可追溯验证、只做批准的可逆文档变更,并明确报告所有证据与限制。

5. 场景二:开启一个新需求开发

本场景以 Search App 新增 status 搜索过滤器为例。假设技术栈为 React + TypeScript、FastAPI + Python、PostgreSQL、Pytest 和 Playwright;真实文件、符号和允许值必须先从仓库证据中确认。下列 Prompt 是可复制的执行指令,Prompt 本身及其中的代码、命令、配置和模板统一使用英文,正文负责解释执行边界。

Step 1:用完整 Bootstrap Prompt 建立 Task Contract

第一步不是让 Agent 立即改代码,而是把产品请求变成可核对的契约。下面的案例约定选择 activearchived 两个值;这只是教程中的明确示例,不是替业务确认的事实。真实项目必须把待确认项保留为问题,并在人工批准后才能落地。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# Feature Bootstrap Prompt: Search App Status Filter

You are working on an existing Search App. Do not edit files, run write-capable commands, change data, or call external write tools until a human approves the task contract.

## Goal

Add an optional `status` search filter across the FastAPI API, PostgreSQL query path, React TypeScript UI, Pytest coverage, and Playwright coverage.

## Required contract questions

Before implementation, inspect the repository and mark every answer as verified, proposed, or unknown:

- What is the canonical search endpoint and response schema?
- What are the business-approved status values?
- Does an omitted `status` differ from an empty `status`?
- What must happen for an invalid value: HTTP 422, HTTP 400, or an existing domain error?
- Which database column and existing query abstraction are authoritative?
- Which frontend selector naming convention and accessible label are required?
- Which URL and request behavior is expected when the selector changes?
- Which old clients and old URLs must remain compatible?

## API query parameter

The parameter is optional and named exactly `status`. The FastAPI/Pydantic parameter-validation boundary first receives the raw query value; `BeforeValidator` only normalizes the exact `""` and `None` cases to `None`, and then validates the result as `Literal["active", "archived"] | None`. The dependency or route receives the validated value before it reaches the query builder. An explicit raw dependency is equivalent only when it preserves this same order.

- Omitted `status`: normalize to `None` and apply no status filter.
- `?status`: normalize to `None` and apply no status filter.
- `?status=`: normalize to `None` and apply no status filter.
- `active` and `archived`: valid non-empty values that filter results by the selected value.
- Any other non-empty value: return the approved validation response using the existing FastAPI/Pydantic error envelope; do not silently broaden the query.
- Repeated values, whitespace, casing, and URL encoding: inspect existing conventions and obtain approval for any new behavior.

## Case convention for this tutorial

Case agreement only: valid values are `active` and `archived`; omitted, `?status`, and `?status=` normalize to `None` and mean no status filter; other non-empty values return the existing HTTP 422 validation shape. Replace this agreement with business-approved values before implementation.

## Frontend behavior

- Add an accessible selector with a stable test selector: `status-filter`.
- The selector must expose an explicit empty option.
- The URL is the source of truth for shareable filter state.
- On initial load and browser back/forward, derive React state from the normalized URL.
- A user selection updates the URL only; the request is derived from normalized URL state.
- Selecting `all` or the empty option removes the `status` parameter instead of serializing an empty value.
- Avoid bidirectional effects that update URL from state and state from URL in a loop.
- The request includes `status` only when normalized URL state is `active` or `archived`.
- Loading, error, reset, back/forward navigation, and stale-response behavior must follow existing Search App conventions.

## Compatibility

- Existing requests without `status` must keep their response shape and result semantics.
- Do not rename existing query parameters or response fields.
- Do not require old clients to send `status`.
- Preserve the existing API version and content type.
- Treat omitted, `?status`, and `?status=` as backward-compatible no-filter requests.

## Constraints

- Use the existing FastAPI route, Pydantic validation style, query builder, and database access abstraction where possible.
- Keep PostgreSQL queries parameterized; never concatenate user input into SQL.
- Do not change the database schema, migrations, ranking, pagination, authentication, or unrelated UI.
- Do not add dependencies without explicit approval.
- Use test databases and test services only.

## Non-goals

- No new status taxonomy.
- No data migration or backfill.
- No production database access or write.
- No redesign of search ranking, pagination, caching, or error presentation.
- No unrelated refactor or formatting sweep.

## Approval points

Ask a human to approve:

1. The canonical status values and empty-value semantics.
2. The invalid-value HTTP status and error shape if not already authoritative.
3. Any public API, URL, response, schema, migration, dependency, or database-access change.
4. The file-level implementation plan and any unresolved unknown.
5. The final diff, verification evidence, risks, and rollback.

## Completion contract

Return a Task Contract containing verified facts, proposed case agreement, unknowns, files to inspect, compatibility invariants, non-goals, approval points, and acceptance criteria. Do not edit until approval is recorded.

Agent 产物:一份逐项标注 verifiedproposedunknown 的 Task Contract,以及待确认问题。
人工审批点:确认业务允许值、空值和非法值行为;确认是否允许 URL 或公共 API 行为变化。
完成标志:契约可测试、兼容性不变量明确、非目标明确,且所有未确认决策都有负责人。

Step 2:用只读 Explore Prompt 找到真实影响面

Explore 阶段只读。不要因为 Agent 能够定位文件,就默认它可以编辑。该 Prompt 要求输出权威 contract 和完整调用链,避免凭文件名猜入口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# Read-only Explore Prompt: Search App Status Filter

Explore the repository in read-only mode. Do not edit, create, delete, format, migrate, install, commit, push, call write-capable MCP tools, or access production systems.

## Feature context

The proposed feature adds an optional `status` filter to the existing Search App. Treat the approved Task Contract as the source of intended behavior, and flag any mismatch instead of inventing a decision.

## Required investigation

1. Identify the canonical API route, HTTP method, query parameters, response model, error envelope, and API version.
2. Identify the authoritative FastAPI route symbol and Pydantic validation symbol for query parameters.
3. Trace the query builder and PostgreSQL access path, including parameter binding and transaction boundaries.
4. Identify the React TypeScript search component, state owner, request client, URL synchronization, reset behavior, loading state, and error state.
5. Locate existing API tests, frontend tests, Playwright tests, fixtures, factories, and test database configuration.
6. Find similar filters and record their exact conventions.
7. Identify generated files, shared contracts, snapshots, schema artifacts, and files that must not be edited directly.
8. List risks: contract drift, SQL injection, invalid-value handling, stale responses, URL loops, accessibility, and compatibility.
9. List unknowns that require human decisions. Do not resolve them by assumption.

## Evidence format

For every finding, provide:

- repository-relative file path
- symbol, test name, or configuration key
- relevant behavior
- evidence status: verified, proposed, or unknown
- impact on the status-filter feature

## Output

Return only an exploration report with:

- system map
- authoritative contract
- API and validation path
- database query path
- React state and request flow
- test and verification entry points
- risks
- unknowns
- files likely to change
- files explicitly out of scope

End with: "No files were edited."

Agent 产物:带路径、符号和证据状态的影响面报告。
人工审批点:确认 Agent 找到的是权威 route、Pydantic model、query builder、React state owner 和测试入口。
完成标志:能从 selector 或 URL 追到 API、数据库和测试,并且报告明确写出未知项和禁止编辑文件。

Step 3:用文件级 Plan Prompt 设计垂直切片

计划要以文件和符号为单位,并把 API contract、backend behavior、frontend integration 分成可独立验证的垂直切片。计划不是实现授权;人工批准前仍不得编辑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File-level Plan Prompt: Search App Status Filter

Use the approved Task Contract and read-only exploration report. Do not edit files.

Create a file-level implementation plan with three vertical slices:

## Slice A: API contract

- canonical route and method
- query parameter name and type
- valid, empty, omitted, repeated, whitespace, casing, and invalid-value behavior
- response and error compatibility
- exact files and symbols to change
- Pytest tests to add or update

## Slice B: Backend behavior

- FastAPI/Pydantic boundary
- query builder and PostgreSQL access symbol
- parameterized query shape
- fixture and test-database changes, if any
- exact files and symbols to change
- focused verification command: `TO_BE_VERIFIED_FROM_REPOSITORY`

## Slice C: Frontend integration

- React state owner and selector component
- accessible label and stable selector `status-filter`
- URL synchronization and request serialization
- reset, loading, error, and stale-response behavior
- Playwright tests for selector, URL, request, and result behavior
- exact files and symbols to change

For every slice, include:

- allowed files
- forbidden files
- preconditions
- implementation steps
- tests
- verification commands
- expected evidence
- completion definition
- rollback strategy

## Human approval gates

Stop for approval before:

1. changing a public route, query parameter contract, response shape, or error shape;
2. changing schema, migrations, dependencies, shared generated contracts, or database configuration;
3. editing files outside the approved file list;
4. choosing behavior for an unresolved Task Contract question;
5. running anything against a non-test database or production service.

End with a decision log containing verified facts, approved choices, unresolved questions, and "No files were edited."

Agent 产物:按 API contract、backend behavior、frontend integration 划分的文件级计划、测试矩阵、命令和回滚方案。
人工审批点:批准文件列表、公共 contract、数据库边界、依赖边界和每个未知项的决定。
完成标志:每个切片都有允许/禁止范围、符号、测试、验证命令和可观察完成条件。

Step 4:TDD 先保存 RED,再最小实现为 GREEN

这里要保留真实证据,不要把测试结果写成预期结果。先添加合法值、三种空值形式、非法值的 FastAPI/Pytest 测试,再添加 React/Playwright 的 selector、URL 和 request 测试;运行并保存 RED 输出,确认失败原因是缺少功能而不是环境错误,然后才实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# TDD Execution Prompt: Search App Status Filter

Use only the approved file list and test environment. Do not change production data or services.

## Phase 1: Write failing tests first

Add focused tests before implementation:

- API/Pytest: a valid `active` or `archived` value filters results.
- API/Pytest: omitted `status`, `?status`, and `?status=` each normalize to `None` and preserve current behavior.
- API/Pytest: another non-empty value returns the approved validation status and error shape.
- API/Pytest: the FastAPI/Pydantic parameter-validation boundary receives the raw query value, `BeforeValidator` normalizes exact empty values before `Literal["active", "archived"] | None` validation, and the dependency or route receives the validated value.
- React/Playwright: the selector has the stable selector `status-filter`.
- React/Playwright: initial load and back/forward derive state from the normalized URL.
- React/Playwright: selecting a valid value updates the URL, then derives the request from URL state.
- React/Playwright: selecting `all` or the empty option removes `status` and does not create an effect loop.

Run `TO_BE_VERIFIED_FROM_REPOSITORY` after replacing it with the real focused command discovered during Explore and approved by a human. Save the unedited command, exit code, duration, and complete failure output to the task evidence. Label this evidence RED. Do not claim RED if the command failed because the test environment was unavailable.

## Phase 2: Minimal implementation

After a human confirms that the RED failures represent the missing feature:

- implement the smallest API/Pydantic boundary change;
- pass the validated value to the existing parameterized query path;
- normalize omitted `status`, `?status`, and `?status=` to `None` before validation and query construction;
- preserve the old query and response behavior for all three no-filter forms;
- add the selector without changing unrelated layout;
- derive React state and requests from normalized URL state, and remove `status` for `all` or empty selection;
- avoid concatenating user input into SQL;
- do not broaden the allowed status set.

## Phase 3: Re-run focused tests

Run the same human-approved focused command, no longer represented by `TO_BE_VERIFIED_FROM_REPOSITORY`. Save command, exit code, duration, and output. Label evidence GREEN only when the tests actually pass. If a test fails, report the failure and continue debugging within the approved scope; never replace evidence with an expected result.

## Stop conditions

Stop and request approval for contract changes, migrations, dependency changes, production access, generated-file changes, or out-of-scope edits.

Agent 产物:失败测试及真实 RED 证据、最小实现 diff、真实 GREEN 证据;若环境失败则是独立的环境阻塞记录。
人工审批点:确认 RED 原因是功能缺失;确认实现不会改变未携带 status 的旧请求行为。
完成标志:合法/空/非法值和 selector/request 行为都有测试;GREEN 由实际命令和退出码证明。

Step 5:分别执行三个垂直切片

TDD 之后按切片推进,每次只处理一个用户可观察结果。下面三个 Prompt 可以分别复制执行;它们故意重复允许和禁止范围,便于在不同 Agent 会话中保持边界。

Slice A:API contract

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Vertical Slice A Prompt: API Contract

Implement only the approved API contract for the optional `status` query parameter.

## Allowed

- approved FastAPI route and Pydantic query-validation files
- approved API contract tests and fixtures
- test-only configuration required by those tests

## Forbidden

- React files, Playwright files, database schema, migrations, dependencies, production services, unrelated refactors
- changing response fields, existing query parameter names, or old-client requirements
- inventing status values or invalid-value semantics

## Required behavior

- valid values follow the approved Task Contract;
- omitted and approved empty values preserve the old behavior;
- invalid values use the existing validation envelope;
- the route remains backward compatible.

## Verification

Run `TO_BE_VERIFIED_FROM_REPOSITORY` after replacing it with the real approved focused Pytest command discovered during Explore. Cover valid values, omitted `status`, `?status`, `?status=`, and invalid values. Record command, exit code, duration, and evidence.

## Completion

The API tests demonstrate the approved contract, the diff contains only approved files, and a human has approved any public contract change.

Slice B:backend behavior

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Vertical Slice B Prompt: Backend Query Behavior

Implement only backend propagation of the approved `status` value into the existing PostgreSQL query path.

## Allowed

- approved query builder, repository, or data-access symbols
- approved backend tests, fixtures, and test-database setup

## Forbidden

- raw SQL string interpolation, schema or migration changes, production database access, React or Playwright changes, unrelated query rewrites

## Required behavior

- use the existing parameterized query mechanism;
- bind `status` as a query parameter;
- preserve the old query shape when no filter is requested;
- verify that an invalid value cannot reach the query layer as an unvalidated value.

## Verification

Run `TO_BE_VERIFIED_FROM_REPOSITORY` after replacing it with the real approved backend focused Pytest command. Where available, assert the bound parameter or query-builder behavior without exposing real credentials.

## Completion

Valid filtering and no-filter compatibility pass in the test database, parameterization is visible in the diff, and no schema or production access occurred.

Slice C:frontend integration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Vertical Slice C Prompt: Frontend Integration

Implement only the approved React TypeScript integration for the `status` filter.

## Allowed

- approved selector component, search state, request client, URL adapter, and Playwright files
- approved frontend fixtures or test helpers

## Forbidden

- backend or database files, dependency changes, unrelated UI refactors, inaccessible hidden-only controls, production endpoints

## Required behavior

- render an accessible selector with `data-testid="status-filter"` only if that is the approved project convention;
- keep the explicit empty option;
- derive selector state from the normalized URL on initial load and back/forward;
- update the URL only when the user changes the selector, then derive the request from URL state;
- remove `status` for `all` or empty selection and avoid bidirectional effect loops;
- preserve loading, error, reset, back/forward, and stale-response behavior;
- assert request behavior through the test environment, not a production service.

## Verification

Run `TO_BE_VERIFIED_FROM_REPOSITORY` after replacing it with the real approved React and Playwright command(s). Cover selector visibility, initial URL state, selection, back/forward, request query, clearing, `all`, and result behavior.

## Completion

The user-visible flow works in the test browser, the request contains only the approved parameter behavior, accessibility checks pass, and the diff stays within the approved frontend files.

Agent 产物:三个独立切片的代码 diff、focused test 输出和完成声明。
人工审批点:每个切片完成后检查 diff;尤其确认 API 兼容性、参数化查询和前端 URL/request 契约。
完成标志:三个切片均达到各自完成条件,且没有跨切片越界或把测试环境连接到生产。

Step 6:用 Verify Prompt 形成可审计证据

验证顺序应从窄到宽:focused checks、复用场景一的 scripts/verify-fast.sh,最后复用 scripts/verify.sh。脚本的含义和参数必须以仓库真实内容为准,不要在文章或 Prompt 中假定脚本会自动覆盖所有检查。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# Verify Prompt: Search App Status Filter

Verify the approved implementation in the test environment only. Do not write to production databases, production APIs, external services, or infrastructure.

## Order

1. Run `TO_BE_VERIFIED_FROM_REPOSITORY` after replacing it with the real focused Pytest, React, and Playwright check command(s) discovered during Explore and approved by a human.
2. Run the existing repository entry point:

./scripts/verify-fast.sh

3. Run the existing repository entry point:

./scripts/verify.sh

Read both scripts before execution if their scope is not already known. Do not edit the scripts as part of this feature.

## Evidence record

For every command, record:

- exact command
- working directory
- start and end time
- duration
- exit code
- relevant output or artifact path
- checks skipped and why
- pre-existing failures confirmed against the baseline

## Required checks

- valid, omitted, empty, and invalid API values;
- response and error compatibility;
- parameterized PostgreSQL query behavior in the test database;
- React selector accessibility and state;
- URL and request synchronization;
- Playwright browser behavior;
- focused verification;
- verify-fast verification;
- full verification.

## Honesty rules

Do not convert a timeout, unavailable service, missing browser, missing database, or pre-existing failure into a pass. If a command is not run, mark it unverified and explain why. Compare failures with the recorded baseline before attributing them to this feature.

Return a verification report and do not modify files.

Agent 产物:按命令、退出码、耗时、证据、跳过项和 pre-existing failure 分类的验证报告。
人工审批点:确认数据库和浏览器都只使用测试环境;确认脚本未被改写且未验证项被诚实列出。
完成标志:focused → ./scripts/verify-fast.sh./scripts/verify.sh 顺序完成,或每个阻塞都有可复核证据。

Step 7:用 Review Prompt 做 diff-first 独立审查

Review 先看完整 diff 和文件边界,再看测试结果。审查 Agent 不应因为测试通过就忽略需求遗漏、contract drift 或越界改动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Review Prompt: Search App Status Filter

Review the uncommitted diff and verification evidence. Start with the complete diff, changed-file list, and baseline; do not rely on the implementation summary.

## Review questions

1. Does the implementation cover every approved requirement and no unapproved requirement?
2. Are FastAPI and Pydantic boundaries correct for valid, omitted, empty, repeated, and invalid values?
3. Can any user-controlled value reach SQL through string concatenation or unparameterized interpolation?
4. Does the React selector preserve state, URL, request, reset, loading, error, back/forward, and stale-response behavior?
5. Did response, error, query-parameter, accessibility, or URL contracts drift?
6. Are API/Pytest, React, and Playwright tests complete and meaningful?
7. Are changed files limited to the approved plan?
8. Are there generated files, migrations, dependencies, credentials, production URLs, or external writes that were not approved?
9. Are verification claims supported by exact commands, exit codes, durations, and artifacts?

## Output

Return findings ordered by severity with file path and symbol references, followed by:

- requirement coverage
- compatibility assessment
- security assessment
- test-gap assessment
- boundary assessment
- unverified items
- approval requests
- final recommendation: approve, approve with conditions, or needs changes

Do not edit files, commit, push, merge, or call write-capable tools.

Agent 产物:带严重级别、路径和符号引用的独立 Review 报告,以及最终建议。
人工审批点:逐条确认高风险发现;最终批准 diff、测试证据、越界检查和交付。
完成标志:需求、边界、安全、契约漂移、测试缺口和越界改动均有结论;没有用摘要替代 diff。

Step 8:用 Delivery Report 模板完成交付

这里展示的是目标 Search App 应创建的两个示例文件,不是在当前博客仓库落盘。它们只固化长期规则和可复用流程,不写本次 feature 的真实路径、业务值或内部地址;验收时要确认它们位于目标 Search App 的批准范围内。

目标 Search App 的根级 AGENTS.md 增量模板:

1
2
3
4
5
6
7
8
## Stable Engineering Rules

- Preserve API contract compatibility unless a human approves a contract change.
- Keep user-controlled values out of SQL text; use parameterized queries.
- Treat the shareable URL as the source of truth for filter state; derive requests from normalized URL state.
- Cover API behavior with backend tests and user-visible behavior with frontend or browser tests.
- Run focused checks first, then the repository's approved fast and full verification entry points.
- Use test databases, test services, and test browsers for feature verification.

目标 Search App 的 .agents/skills/feature-delivery/SKILL.md 紧凑模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
---
name: feature-delivery
description: Deliver a bounded feature with contract-first exploration, TDD, vertical slices, verification, and review.
---

# Feature Delivery

## Trigger

Use only when a human explicitly invokes this skill. Do not claim automatic triggering.

## Inputs

Require the feature goal, approved acceptance criteria, repository path, allowed files, non-goals, test environment, and verified repository commands. Mark missing decisions as unknown.

## Explore

Read only. Map the authoritative contract, API route and validation boundary, database query path, frontend state and URL flow, tests, verification entry points, risks, and unknowns. Report paths and symbols. Do not edit, install, migrate, access production, or call write-capable tools.

## Plan

Create a file-level plan with API contract, backend behavior, and frontend integration slices. List allowed and forbidden files, symbols, tests, commands, evidence, completion criteria, rollback, and human approval gates.

## TDD

Add focused failing tests first. Preserve real RED evidence. Implement the smallest approved change, then rerun the same checks and preserve real GREEN evidence. Never fabricate results or convert environment failures into passes.

## Slices

- API contract: normalize and validate at the approved boundary; preserve compatibility.
- Backend behavior: pass validated values through parameterized database queries.
- Frontend integration: derive state and requests from normalized shareable URL state; test selector, URL, request, reset, and browser behavior.

## Verify

Replace every `TO_BE_VERIFIED_FROM_REPOSITORY` with a real command discovered during Explore and approved by a human. Run focused checks, then the approved fast entry point, then the approved full entry point. Record command, exit code, duration, evidence, skips, and pre-existing failures. Use test services only.

## Review

Review the complete diff first. Check requirement coverage, validation boundaries, SQL injection, URL/state synchronization, contract drift, test gaps, and out-of-scope edits. Do not edit, commit, push, merge, or access production.

## Report

Return changed files, behavior, contract, tests, commands, evidence, risks, approvals, rollback, and unverified items. A final report must contain no command placeholder and must not claim pass while any required evidence is missing.

## Boundaries

- No production access or writes.
- No real credentials or internal URLs.
- No schema, dependency, public contract, or external-service change without approval.
- No edits outside the approved file list.

## Explicit Invocation Prompt

Use this prompt to invoke the skill:

Use the feature-delivery skill for this repository and feature.
Feature goal:
Approved contract:
Non-goals:
Repository path:
Allowed files:
Test environment:
Focused command: TO_BE_VERIFIED_FROM_REPOSITORY
Fast command:
Full command:

Start with read-only exploration. Do not edit until a human approves the Task Contract and file-level plan. Preserve real RED and GREEN evidence, use parameterized queries, test only against test services, review the complete diff, and return a delivery report with no unresolved placeholders.

Agent 产物:目标 Search App 的两个模板草案、显式调用 Prompt、模板验收结果和边界说明。
人工审批点:确认模板只包含长期稳定规则;确认目标 Search App 的文件路径、权限和落盘范围;确认 skill 只在显式调用后执行。
完成标志:模板不包含本次 feature 的业务细节,显式调用可复用,且纳入目标 Search App 的验收清单。

交付报告要把“改了什么”和“证明了什么”分开。未运行的检查、未解决风险和人工批准不能被省略。下面的 TO_BE_VERIFIED_FROM_REPOSITORY 只能出现在草稿阶段;完成报告必须替换为真实命令,不能保留占位符并宣称通过。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# Delivery Report: Search App Status Filter

## Summary

- feature:
- repository:
- baseline commit:
- implementation branch:
- final recommendation:

## Changed files

- path:
- symbols:
- reason:
- approved by:

## Behavior

- valid `status` values:
- omitted-value behavior:
- empty-value behavior:
- invalid-value behavior:
- selector behavior:
- URL behavior:
- request behavior:
- result behavior:

## Contract

- route and method:
- query parameter:
- response compatibility:
- error compatibility:
- API version:
- backward-compatibility statement:

## Tests

- API/Pytest:
- React:
- Playwright:
- test database:
- test browser:

## Verification commands

| Command | Exit code | Duration | Evidence |
| --- | ---: | ---: | --- |
| `TO_BE_VERIFIED_FROM_REPOSITORY` | `REPLACE_WITH_ACTUAL_EXIT_CODE` | `REPLACE_WITH_ACTUAL_DURATION` | `REPLACE_WITH_ACTUAL_EVIDENCE` |
| `./scripts/verify-fast.sh` | `REPLACE` | `REPLACE` | `REPLACE` |
| `./scripts/verify.sh` | `REPLACE` | `REPLACE` | `REPLACE` |

## Evidence

- RED evidence:
- GREEN evidence:
- browser artifacts:
- API response artifacts:
- database/query evidence:
- review report:

## Risks and mitigations

- risk:
- mitigation:
- owner:
- residual risk:

## Approvals

- Task Contract:
- status values and empty semantics:
- public contract:
- file-level plan:
- migrations or dependencies:
- final diff:
- final verification:

## Rollback

- revert commit or approved file diff:
- database rollback: `NOT_APPLICABLE_OR_APPROVED_TEST_ONLY_PLAN`
- API compatibility fallback:
- frontend feature-disable plan:

## Unverified items

- item:
- reason:
- follow-up owner:
- follow-up command:

## Boundary statement

No production database, production API, infrastructure, real credential, external write, commit, push, or merge was used unless explicitly listed above with human approval.

Agent 产物:完整 Delivery Report、最终 diff、测试与验证证据、风险和未验证项。
人工审批点:确认 changed files、contract、命令结果、证据、审批记录和 rollback 方案真实可追溯。
完成标志:报告能让未参与实现的人复核行为、兼容性、测试、风险和回滚;没有把未验证内容写成已完成。

本场景只复用场景一已经建立的验证脚本和权限边界,不重复 MCP、Hooks 或初始化流程。长期规则放在根级 AGENTS.md,可复用的 feature-delivery 流程放在 .agents/skills/feature-delivery/SKILL.md;二者描述规则和流程,不把本次 status 细节固化为永久约束。

6. 场景三:修复 Bug

本场景把一个 Search App 回归当作完整调试练习:React+TypeScript 前端或旧客户端发送 ?status= 时,FastAPI 当前观察到 422 Unprocessable Entity;也可能只在某个客户端或路由路径出现不同的 observed response。不要先把响应写死成 400。真正需要恢复的是长期 contract:省略 status、发送裸参数 ?status、发送精确空参数 ?status=,都表示不做状态过滤;非空合法值执行过滤,非空非法值继续失败。纯空白、大小写和编码变体不自动继承空字符串语义,必须按仓库已确认的 contract 处理,未确认时停止并请求审批。场景二已经定义的 contract 是权威来源,场景三可以修复回归,也可以修复一条遗留路径对 contract 的偏离。

全程使用 React+TS、FastAPI+Python、PostgreSQL、Pytest 和 Playwright 的分层证据。下面的命令只有在 Explore 读取仓库后才能执行;仓库中找不到真实命令时,必须保留 TO_BE_VERIFIED_FROM_REPOSITORY,先查 README、package.jsonpyproject.toml、CI 和测试配置,再把它替换为真实命令。这里展示的是教程和模板,不会自动创建真实的 AGENTS.md、Skill 或调试证据文件。

Step 1:Capture——先保存 Bug Intake 证据

先让 Agent 只读收集事实,不允许修改代码、数据库、配置或依赖。把以下 Prompt 复制到已连接仓库的 Agent 中;其中的 issue 标识必须使用不含凭据的短标识。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
You are investigating a Search App regression. Read repository documentation, package manifests, CI configuration, route definitions, and existing tests in read-only mode.

Bug contract:
- Omitted status, bare ?status, and ?status= mean no status filter.
- A non-empty valid status applies the filter.
- A non-empty invalid status remains a validation error.

Observed symptom:
- A React TypeScript frontend or legacy client sends ?status=.
- FastAPI currently returns the observed response recorded by the reporter, commonly 422 Unprocessable Entity.
- Do not replace the observed response with an assumption such as 400.

Do not edit code, install dependencies, write to PostgreSQL, call production services, or create files.
Return only:
1. Repository-derived commands, each marked VERIFIED or TO_BE_VERIFIED_FROM_REPOSITORY.
2. The exact route and client call sites you found.
3. The data-flow boundaries: React serialization, FastAPI/Pydantic pre-validation, route dependency, service/query builder, and PostgreSQL query.
4. Missing evidence that a human must provide.
5. A redacted Bug Intake record with method, path, query, headers, response body, status, logs, version, and frequency.

只把脱敏副本保存到 docs/debugging/<issue>/EVIDENCE.md。原始敏感资料只能留在获准的受控系统中,绝不落盘到仓库、工作区、日志或测试 artifact。Headers 只保留字段名和脱敏后的值,不保存 Authorization、Cookie、API key、内部 URL 或个人数据;HTTP status phrase 只记录 observed value,不把它升级为长期 contract。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Bug Evidence

## Intake
- Issue: SEARCH-STATUS-EMPTY
- Method: GET
- Path: TO_BE_VERIFIED_FROM_REPOSITORY
- Query: status=
- Headers: Content-Type=REDACTED; Authorization=REDACTED
- Observed response status phrase: OBSERVED_RESPONSE_STATUS_PHRASE
- Response body: REDACTED_REPORTER_RESPONSE
- Logs: REDACTED_REPORTER_LOGS
- App version: TO_BE_VERIFIED_FROM_REPOSITORY
- Client version: TO_BE_VERIFIED_FROM_REPOSITORY
- Frequency: TO_BE_VERIFIED_FROM_REPOSITORY
- Captured at: TO_BE_VERIFIED_FROM_REPOSITORY

## Contract
- Omitted status: no filter
- Bare status: no filter
- Empty status: no filter
- Whitespace, case, and encoding variants: follow the existing contract; do not infer
- Valid non-empty status: apply filter
- Invalid non-empty status: validation error

## Safety
- Read-only investigation: true
- Production access: not used
- Credentials present: false

实际操作:读取仓库并补齐证据;不要用想象的日志或响应替换缺失字段。
Agent 产物EVIDENCE.md 草稿、命令清单、组件边界和缺失证据列表。
人工审批点:确认 issue 标识、脱敏结果、观察到的 response、版本和频率;批准后才能开始复现。
完成标志:脱敏后的 method/path/query/headers/response/status/log/version/frequency 可追溯,未知项明确标注,原始敏感数据没有落盘,工作区没有代码改动。

Step 2:Reproduce——用最小请求和 focused test 复现

先从仓库确认真实 endpoint、启动方式、测试入口和允许使用的测试数据库。下面的请求只表达复现结构;未 Explore 前不得把占位符当作通过证据。

1
2
3
4
curl --silent --show-error --include \
--request GET \
"http://127.0.0.1:TO_BE_VERIFIED_FROM_REPOSITORY/search?status=" \
--header "Accept: application/json"

依次比较五个输入:省略、裸参数、空参数、合法值、非法值。裸参数必须保留为 ?status,不能被 shell 或脚本自动改写。

1
2
3
4
5
curl --silent --show-error --include "http://127.0.0.1:TO_BE_VERIFIED_FROM_REPOSITORY/search"
curl --silent --show-error --include "http://127.0.0.1:TO_BE_VERIFIED_FROM_REPOSITORY/search?status"
curl --silent --show-error --include "http://127.0.0.1:TO_BE_VERIFIED_FROM_REPOSITORY/search?status="
curl --silent --show-error --include "http://127.0.0.1:TO_BE_VERIFIED_FROM_REPOSITORY/search?status=active"
curl --silent --show-error --include "http://127.0.0.1:TO_BE_VERIFIED_FROM_REPOSITORY/search?status=TO_BE_VERIFIED_FROM_REPOSITORY"

active 只是示例,必须替换为仓库 contract 中确认的合法值;非法值也必须替换为一个确认不会被接受的非空值。随后运行最小的 Pytest 和 Playwright focused test;如果仓库没有对应入口,记录 TO_BE_VERIFIED_FROM_REPOSITORY,不要伪造绿色输出。

1
2
TO_BE_VERIFIED_FROM_REPOSITORY
TO_BE_VERIFIED_FROM_REPOSITORY

每次复现都把 exact command、exit code、完整 relevant output、Python/Node/browser/database 环境和 commit/version 追加到证据文件。敏感内容先脱敏,不要把响应截断到只剩状态码。

实际操作:在只读或隔离测试环境执行五组请求,并运行 focused test。
Agent 产物:复现矩阵、命令与输出记录、环境快照、更新后的 EVIDENCE.md
人工审批点:确认请求指向测试环境而非生产;确认数据库仅使用隔离数据且没有写入。
完成标志:至少一条命令稳定复现目标问题,或明确记录“无法复现”及完整尝试;五种输入的实际响应均有证据。

Step 3:Hypothesis——只提出一个可证伪假设

先沿数据流定位故障层,不要同时改 React、FastAPI 和 SQL。依次检查:

  1. React serialization 是否把 undefinednull'' 序列化成了不同的 query。
  2. FastAPI/Pydantic pre-validation 是否在进入 handler 前拒绝空字符串。
  3. Route dependency 是否把 status 重新解析成了必填或枚举。
  4. Service/query builder 是否把空值错误地变成过滤条件。
  5. PostgreSQL 查询是否在收到 None 时保持无过滤,并继续使用参数化 SQL。

假设必须是单一、可证伪的句子,例如:“在确认客户端实际发送 status= 后,FastAPI/Pydantic pre-validation 将空字符串当作非空枚举值拒绝,因此请求在 route handler 之前返回 observed 422。”这不是结论,只有 probe 结果才能确认。

1
2
3
4
Hypothesis: After React serialization is confirmed to send status=, FastAPI/Pydantic pre-validation rejects the empty string before the route handler receives it.
Probe: Log or inspect the parsed route input in an isolated test and compare it with the raw query for omitted, bare, and empty status.
Expected falsifier: The handler receives an empty string and the service or query builder creates the wrong filter.
Stop condition: If the probe cannot distinguish layers, gather boundary evidence before proposing a fix.

实际操作:只做读取、断点、临时诊断或隔离 probe;不把诊断 instrumentation 混入修复。
Agent 产物:一条假设、一个最小 probe、输入和输出边界对照。
人工审批点:确认假设没有偷偷包含多个原因,且 probe 不触碰生产数据。
完成标志:确定或排除一个故障层;若仍不清楚,返回补证据,不进入修复。

本教程明确调用已审查的 systematic-debugging Skill,使用以下 Prompt。该 Skill 的核心门禁是“先找到根因,再修复”,并要求读错误、稳定复现、追踪边界、形成单一假设、先写失败测试,三次失败后停止。

1
2
3
4
5
6
7
Use the repository's reviewed systematic-debugging Skill for this incident.
Follow its root-cause-first process: read the complete error, reproduce consistently, inspect recent changes, trace data across React, FastAPI/Pydantic, route dependency, service/query builder, and PostgreSQL boundaries, then form one falsifiable hypothesis.
Do not propose or apply a fix before the RED regression test proves the target bug.
Count every action that changes observable system behavior, including code, configuration, tests, dependencies, runtime flags, proxy or deployment configuration, migrations, and generated clients.
Append the same attempt index across sessions and agents; changing the prompt or agent never resets it.
After three invalid attempts, stop editing and produce an investigation report for human review.
If the Skill is unavailable, do not pretend it exists or trigger it automatically. Use only the minimal project-level fallback template supplied below, after a human reviews it.

如果目标仓库没有这项 Skill,只能由人工安全安装并审查,或临时使用下列最小 fallback 模板;本教程不自动创建它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Systematic Debugging Fallback

## Gates
1. Capture redacted evidence before edits.
2. Reproduce with exact commands and outputs.
3. Trace one data-flow boundary at a time.
4. State one falsifiable hypothesis.
5. Add a failing regression test before a fix.
6. Make one minimal fix at the confirmed normalization boundary.
7. Verify focused, fast, full, and real HTTP paths.
8. Stop after three invalid fix attempts.

## Safety
- No production writes.
- No credentials or internal URLs.
- No dependency upgrades during a bug fix.
- Mark unknown commands as TO_BE_VERIFIED_FROM_REPOSITORY.

Step 4:RED——先添加失败回归测试

在确认故障层后,添加最小 Pytest 回归测试,使用隔离 fixture 数据断言返回记录集合,覆盖 contract 的五种输入。测试可以使用真实项目的 TestClient、依赖覆盖和隔离数据库;下面仅展示测试意图,导入路径、fixture、endpoint 和 repository double 必须从仓库替换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import pytest
from unittest.mock import Mock
from fastapi.testclient import TestClient


@pytest.fixture
def repository():
repository = Mock()
records = [
{"id": 1, "status": "active"},
{"id": 2, "status": "archived"},
]

def search(*, status):
return [
record
for record in records
if status is None or record["status"] == status
]

repository.search.side_effect = search
return repository


@pytest.fixture
def client(repository):
# app must be the same FastAPI instance passed to TestClient.
# Replace provide_repository with the dependency used by the real app.
app.dependency_overrides[provide_repository] = lambda: repository
with TestClient(app) as test_client:
yield test_client
app.dependency_overrides.clear()


@pytest.mark.parametrize(
("query", "expected_ids"),
[
("", {1, 2}),
("?status", {1, 2}),
("?status=", {1, 2}),
("?status=active", {1}),
],
)
def test_search_status_contract(client, repository, query, expected_ids):
response = client.get(f"/TO_BE_VERIFIED_FROM_REPOSITORY/search{query}")

assert response.status_code == 200
assert {record["id"] for record in response.json()["records"]} == expected_ids
expected_status = None if query in ("", "?status", "?status=") else "active"
repository.search.assert_called_once_with(status=expected_status)


def test_invalid_status_returns_validation_response_without_query(
client, repository
):
response = client.get(
"/TO_BE_VERIFIED_FROM_REPOSITORY/search?status=TO_BE_VERIFIED_FROM_REPOSITORY"
)

assert response.status_code == 422
error_body = response.json()
assert set(error_body) == {"detail"}
assert isinstance(error_body["detail"], list)
assert error_body["detail"][0]["loc"] == ["query", "status"]
repository.search.assert_not_called()

上面的断言字段必须改成仓库实际响应;不能为了让测试运行而宽化断言。示例按场景二 contract 和现有 FastAPI error envelope 确认 422 以及 {"detail": [...]} 结构;如果仓库确认的 contract 或 envelope 不同,先停止并请求审批,再替换为精确值。repository fixture 必须返回隔离数据,例如 id 为 1、2 的记录,并能断言实际 query 参数;更重要的是,client fixture 必须通过真实 FastAPI app.dependency_overrides 把这个 mock 注入 client 正在使用的 app,否则 repository.search 断言没有意义。先运行 RED,保存命令、exit code、完整失败输出和环境。失败必须是目标 Bug,例如 ?status= 得到 observed validation response 而 contract 期待 200;不能把 status phrase 写成固定 contract。如果失败来自导入错误、语法错误、缺少 fixture、数据库未启动或版本冲突,这不是 RED evidence,先修正测试环境或标记未验证。

只有仓库存在并经核实的 legacy-client fixture/route 时,才补 Playwright focused test;下面的 status= 断言只用于旧客户端回归复现路径,不能代表新 React UI。若不存在经核实的 legacy browser fixture,则将该测试记为 N/A,?status= 兼容性只由 raw HTTP/API 测试覆盖。新 React UI 必须单独断言选择 all 或空选项时移除 status 参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import { expect, test } from "@playwright/test";

test("legacy client regression reproduces an empty status parameter", async ({ page }) => {
const requestPromise = page.waitForRequest((request) =>
request.url().includes("/TO_BE_VERIFIED_FROM_REPOSITORY/search"),
);

await page.goto("REPLACE_WITH_VERIFIED_LEGACY_CLIENT_FIXTURE_URL");
const legacyMarker = page.getByTestId("legacy-client-marker");
await expect(legacyMarker).toBeVisible();
await expect(legacyMarker).toHaveAttribute(
"data-client-version",
"REPLACE_WITH_VERIFIED_LEGACY_CLIENT_VERSION",
);
await page.getByRole("button", { name: "Search" }).click();

const request = await requestPromise;
expect(new URL(request.url()).searchParams.get("status")).toBe("");
const response = await request.response();
expect(response).not.toBeNull();
});

test("new React UI removes status for all", async ({ page }) => {
await page.goto(
"http://127.0.0.1:TO_BE_VERIFIED_FROM_REPOSITORY/search?status=active",
);
await page.getByTestId("status-filter").selectOption("all");

const url = new URL(page.url());
expect(url.searchParams.get("status")).toBeNull();
});

test("new React UI removes status for the empty option", async ({ page }) => {
await page.goto(
"http://127.0.0.1:TO_BE_VERIFIED_FROM_REPOSITORY/search?status=active",
);
await page.getByTestId("status-filter").selectOption("");

const url = new URL(page.url());
expect(url.searchParams.get("status")).toBeNull();
});

上面的 status= 断言只有在 legacy fixture URL、marker 和版本均已从仓库核实时才执行,明确属于旧客户端回归复现路径,不能作为新 React UI 的行为证明。没有经核实的 legacy browser fixture 时,将该测试记为 N/A;新 UI 的 all/空选项测试必须断言 searchParams.get("status")null(即参数已移除),而 ?status= 的兼容性继续由 raw HTTP/API regression 覆盖。

实际操作:先写最小测试并运行,确认失败属于目标回归。
Agent 产物:测试 diff、RED evidence、五种输入的断言和失败输出。
人工审批点:确认测试没有因为语法、依赖、fixture 或环境问题失败;批准后才允许编辑实现。
完成标志:RED 明确证明 contract 与当前行为冲突,且失败证据可在隔离环境复现。

Step 5:GREEN——只修复已确认的 normalization boundary

如果 Step 3 证明 FastAPI/Pydantic 参数验证边界是故障边界,最小修复应保持统一顺序:先接收原始 query 值,BeforeValidator 只把精确空字符串 ""None 规范化为 None,再验证为 Literal["active", "archived"] | None,最后由 dependency/route 收到已验证值。纯空白、大小写变化和编码变体不能未经批准被改写;它们必须按已确认的现有 contract 处理,未确认时停止并请求审批。非空非法值仍必须失败;不要把类型改成任意字符串,不要吞掉校验错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from typing import Annotated, Literal

from fastapi import Depends, FastAPI, Query
from pydantic import BeforeValidator


Status = Literal["active", "archived"]


def normalize_exact_empty_status(value: object) -> object:
if value is None or value == "":
return None
return value


StatusQuery = Annotated[
Status | None,
BeforeValidator(normalize_exact_empty_status),
Query(),
]


def get_status(status: StatusQuery = None) -> Status | None:
return status


app = FastAPI()


@app.get("/search")
def search(status: Status | None = Depends(get_status)):
return search_service.search(status=status)

这里使用 Pydantic v2 的 BeforeValidator:raw query value 先经过精确空字符串转换,再进入 Literal["active", "archived"] | None validation。get_status 明确把已验证的类型交给 route,非空非法值会在进入 search 前产生 FastAPI validation response,不会以任意字符串流入 service。None 表示省略、裸参数和空参数的无过滤语义;纯空白、大小写和编码变体仍原样进入现有 validation,除非仓库 contract 和人工审批明确规定其他行为。

1
2
3
4
5
6
7
8
def build_search_query(status: str | None, limit: int):
filters = []
params = {"limit": limit}
if status is not None:
filters.append("status = :status")
params["status"] = status
where_clause = " AND ".join(filters) or "TRUE"
return f"SELECT id, title FROM search_items WHERE {where_clause} LIMIT :limit", params

如果 probe 证明 React serialization 才是根因,则只修 serialization boundary,并让 API contract test 防止旧客户端路径再次偏离;如果证明 route dependency 或 query builder 才是根因,就在那里做同样范围的最小规范化。不要并行修改多个层。

实际操作:只改已确认的一个 normalization boundary,保留参数化 SQL,不升级依赖、不重构目录、不更换框架。
Agent 产物:最小修复 diff、GREEN evidence、更新后的 Pytest/Playwright 结果。
人工审批点:检查 changed files、contract、非空非法值行为、SQL 参数化和是否存在无关改动。
完成标志:原 RED 测试转绿,空值无过滤,合法值仍过滤,非空非法值仍失败。

Step 6:Verify/Review——分层验证并做 diff-first review

按风险从小到大执行:focused Pytest → 快速测试集 → 全量测试 → 真实 HTTP path;如果前端 query serialization 受影响,再运行对应 Playwright 测试。命令必须从仓库 Explore 结果填入,禁止用未确认的命令制造通过证据。

1
2
3
4
TO_BE_VERIFIED_FROM_REPOSITORY
TO_BE_VERIFIED_FROM_REPOSITORY
TO_BE_VERIFIED_FROM_REPOSITORY
TO_BE_VERIFIED_FROM_REPOSITORY

比较 RED/GREEN 的 exact command、exit code、relevant output 和环境差异,确认绿灯不是跳过测试、命中缓存、错误 endpoint 或连到了错误数据库。然后先看 diff,再看测试报告:

1
2
3
4
5
6
7
8
Review the diff before reading the success summary.
Confirm that only the confirmed normalization boundary and regression tests changed.
Confirm omitted, bare, and empty status produce no filter.
Confirm valid non-empty status still filters.
Confirm invalid non-empty status still fails.
Confirm SQL remains parameterized.
Confirm no credential, internal URL, production write, dependency upgrade, unrelated refactor, or generated file was introduced.
Record browser/API compatibility for React TypeScript, legacy clients, FastAPI, Pytest, and Playwright.

实际操作:依序完成四层测试、真实 HTTP 验证、diff-first review 和兼容性检查;只使用测试环境。
Agent 产物:红绿对照、测试报告、最终 diff review、回归风险和未验证项。
人工审批点:人工核对响应、查询结果、测试数据库、浏览器请求和 changed files;明确批准是否可交付。
完成标志:所有声明都有命令或输出证据;没有把 skipped、未运行或占位命令写成 passed。

Step 7:Stop/Report——三次无效尝试后停止并报告

attempt 按一次为了验证假设而改变系统可观察行为的动作计数。范围包括代码、配置、测试、依赖、runtime flag、proxy/deployment config、migration 和 generated client;即使改动最后被回滚,也算一次。只读 probe、收集证据和修复测试语法不算修复 attempt,但必须记录。

出现以下任一情况,记为一次无效 attempt:RED 未证明目标 Bug、改动改变了非目标行为、目标测试仍失败、失败原因是新回归、或证据无法证明改动命中根因。相同 issue 必须跨会话共享 attempt 计数和证据索引;换 Prompt、换 Agent、换命令、重跑测试、拆分提交或回滚,都不能重置或规避计数。第三次无效 attempt 后立即停止编辑,回到架构边界、依赖和证据审查,并等待人工决定。

停止时生成 docs/debugging/<issue>/INVESTIGATION.md。以下模板中的字段必须用真实证据填写,不能虚构结论。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Investigation Report

## Summary
- Issue: TO_BE_VERIFIED_FROM_REPOSITORY
- Contract: omitted, bare, and empty status mean no filter
- Observed response: TO_BE_VERIFIED_FROM_REPOSITORY
- Root cause layer: TO_BE_VERIFIED_FROM_REPOSITORY
- Final disposition: fixed, unresolved, or architecture review required

## Attempts
- Shared attempt index: append-only across sessions and agents
- Attempt 1: change category, observed behavior, hypothesis, exact command, exit code, result
- Attempt 2: change category, observed behavior, hypothesis, exact command, exit code, result
- Attempt 3: change category, observed behavior, hypothesis, exact command, exit code, result

## Evidence
- RED: exact command and output
- GREEN: exact command and output
- Fast tests: exact command and output
- Full tests: exact command and output
- Real HTTP path: exact command and output
- Browser path: exact command and output

## Review
- Changed files:
- Regression risks:
- Browser/API compatibility:
- Unverified items:
- Rollback command or procedure: TO_BE_VERIFIED_FROM_REPOSITORY

## Boundary
- Test environment only: true
- Production writes: false
- Credentials and internal URLs included: false

实际操作:三次无效 attempt 后停止;填写 investigation report、完成报告和回滚步骤。
Agent 产物INVESTIGATION.md、完成/未完成结论、证据索引和 rollback procedure。
人工审批点:人工决定修复、继续调查、架构评审或回滚;批准后才可进入交付流程。
完成标志:读者能从报告重放调查,知道哪些已证实、哪些未验证、如何回滚;没有将失败包装成成功。

这套流程与场景二的长期 contract 保持一致:场景二定义行为,场景三只修复回归或遗留路径偏离,不把本次 status 细节偷偷升级为新的永久规则。调试证据、AGENTS.md 或 Skill 模板若需要落地,必须由真实项目流程和人工审批单独创建;本节本身不会创建这些文件。

7. 场景四:把旧项目改造成 Agent-ready 仓库

本场景面对一个已有 FastAPI Search Service 的遗留仓库:React 前端、FastAPI API 和 PostgreSQL 数据层混在历史目录中,启动、构建和测试命令散落在 README、CI、shell 脚本和容器文件里,测试覆盖不足,仓库中还可能存在 .cursorrules、重复 Prompt 或超长指导文件。目标不是立刻重构业务,而是先建立一组可验证的 Agent readiness:Agent 能找到事实、遵守边界、复用确定性验证入口,并在人工批准后逐步扩大变更范围。

这里的案例是教程背景,不是一个真实可运行项目。下面的命令、路径、端口、测试选择器和响应字段,只有在读取目标仓库并得到证据后才能替换。所有未知命令必须保留为 TO_BE_VERIFIED_FROM_REPOSITORY;占位符不是成功,也不能被写进通过报告。

先回答一个经常被忽略的提交边界问题:

  • AGENTS.md、项目级 Rules/Skills、验证脚本、CI 入口、characterization tests、README 和 docs/agent-readiness/BASELINE.md,如果服务于团队协作并且不含秘密,应提交到目标代码仓库
  • 个人偏好、用户级配置、凭据、临时日志、未脱敏 evidence 不提交。
  • 项目级 Hook/MCP 只有在不含秘密、经过团队批准、跨环境可复现,并且不会把危险操作偷偷扩大时,才考虑提交;否则保留在用户或受控平台配置中。
  • 本文只展示教程模板,不会在博客根目录或目标项目中真实创建这些文件,也不会提交 Git。

Step 1:Read-only Audit Prompt——先做只读仓库体检

实际操作

把以下 Prompt 交给已连接目标仓库的 Agent。第一轮只能使用专用文件读取工具,以及禁用 pager、hook、alias 的只读 Git metadata 查询读取提交、分支和文件元数据;允许的 Git 查询仅限项目平台提供的等价 rev-parselogbranch --show-currentstatus --short 元数据读取。命令验证必须推迟到人工批准后的隔离环境。不能因为审计需要“看看能否运行”就执行仓库脚本、Make/Task、测试、构建、Docker/Compose、包管理器、数据库、网络或任何可能写入的命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
You are auditing a legacy FastAPI Search Service in strict read-only mode.

System context:
- React frontend and FastAPI service share a historical repository layout.
- PostgreSQL is part of the data layer.
- Commands may be scattered across README files, CI workflows, manifests, scripts, container files, and build configuration.
- The repository may contain .cursorrules, duplicated prompts, or oversized guidance files.

Safety:
- Do not edit, create, delete, rename, format, generate, install, migrate, or commit anything.
- Do not run repository scripts, Make, Task, tests, builds, Docker, Compose,
package managers, database clients, migrations, network clients, or services.
- Do not run Git aliases or commands that can invoke hooks, pagers, editors,
filters, or external programs.
- Do not call production endpoints or read secret values.
- Use only dedicated file-reading tools and the allowlisted read-only Git
metadata queries with pager, hook, and alias execution disabled.
- Do not use Git commands outside rev-parse, log, branch --show-current, and
status --short metadata reads.
- A local audit cannot observe platform branch protection; mark it BLOCKED
until a platform owner supplies evidence.
- If a credential or secret is discovered, stop immediately. Record only the
minimum file location and risk category, notify the owner, and wait for a
separately approved remediation task. Do not remove, rotate, copy, or print it.

Audit these areas:
1. README and other developer documentation.
2. CI workflows, required checks, branch protections if visible, and release jobs.
3. Package manifests, lockfiles, Python metadata, frontend build configuration, and environment examples.
4. Application entry points, API routes, React entry points, database adapters, migrations, and generated code.
5. Scripts, Makefiles, task runners, Dockerfiles, compose files, Kubernetes manifests, and deployment files.
6. Test configuration, unit tests, integration tests, API tests, browser tests, fixtures, and test databases.
7. Git history for recent changes, ownership clues, generated-file patterns, and risky modules.
8. Guidance files such as AGENTS.md, CLAUDE.md, .cursorrules, and project-local instruction files.

For every command or workflow you discover without executing it:
- Quote the exact source file and line or section.
- Mark it SOURCE_CONFIRMED, BLOCKED, or TO_BE_VERIFIED_FROM_REPOSITORY.
- Do not invent a replacement command.

Return a proposed docs/agent-readiness/BASELINE.md draft with:
- Repository map and runtime/tool versions.
- Authoritative commands and evidence sources.
- Known failures and missing prerequisites.
- Test layers and coverage gaps.
- Risk modules and secrets boundaries.
- Owners, generated files, approval gates, and unknowns.
- A separation between source evidence and execution evidence.

Use TO_BE_VERIFIED_FROM_REPOSITORY for missing facts. Do not claim readiness,
passing tests, or production safety.

Agent 产物

Agent 应输出一份只读审计结果和 docs/agent-readiness/BASELINE.md 草稿,至少包含仓库地图、运行时、命令来源、测试入口、风险模块、秘密边界、生成文件、负责人和未知项。它还应列出冲突的 README 命令、失效 CI job、未确认的数据库启动方式以及任何无法从仓库证明的结论。

人工审批点

人工确认审计范围确实只读;确认 Agent 没有启动服务、写数据库、读取或复制凭据;确认每条“权威命令”都有仓库证据。若 README 与 CI 冲突,先批准“记录冲突”,不要让 Agent 自行选择一个命令。

完成标志

审计报告可由另一位工程师从原文件重放;所有未知项写成 TO_BE_VERIFIED_FROM_REPOSITORY,或在无法继续时标为 BLOCKED;没有源码 diff、依赖变更、数据库写入、生产调用或未脱敏内容。Step 1 不能产生 EXECUTION_VERIFIED,因为它没有执行命令。

Step 2:Baseline——把事实、失败和边界写下来

实际操作

在确认 Step 1 的审计结果后,人工将草稿整理成一个短而可维护的基线文件。基线不是“项目健康证明”,而是改造前的可比快照:它必须同时记录成功、失败、未运行和不知道的内容。不要为了填满模板而猜 Python、Node、PostgreSQL、Docker 或浏览器版本,也不要把“命令存在”写成“命令通过”。

为避免把静态发现误当成运行证明,使用以下状态机:

  • SOURCE_CONFIRMED:在 README、CI、manifest 或脚本中找到候选命令,但尚未执行。
  • EXECUTION_VERIFIED:只在人工批准后的隔离环境中,记录了 commit、脱敏 argv、exit code、duration、evidence 和 approver。
  • FAILED:命令已执行并返回非零,且保存了相关失败证据。
  • BLOCKED:因前置条件、权限、秘密、生产边界或安全门禁停止,未声称命令结果。
  • SKIPPED:经人工决定不执行,不能计为成功。

只有 EXECUTION_VERIFIED 才能进入 Step 3 的批准命令映射;SOURCE_CONFIRMED 只能作为候选来源。

下面是可提交到目标代码仓库的英文模板。实际项目中应删除不适用章节,并用仓库事实替换占位符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# Agent Readiness Baseline

## Scope
- Repository: TO_BE_VERIFIED_FROM_REPOSITORY
- Commit: TO_BE_VERIFIED_FROM_REPOSITORY
- Captured at: TO_BE_VERIFIED_FROM_REPOSITORY
- Auditor: TO_BE_VERIFIED_FROM_REPOSITORY
- Read-only audit: true

## Repository Map
- `apps/api/`: TO_BE_VERIFIED_FROM_REPOSITORY
- `apps/web/`: TO_BE_VERIFIED_FROM_REPOSITORY
- `db/` or migrations: TO_BE_VERIFIED_FROM_REPOSITORY
- `scripts/`: TO_BE_VERIFIED_FROM_REPOSITORY
- Generated files: TO_BE_VERIFIED_FROM_REPOSITORY
- Historical coupling: TO_BE_VERIFIED_FROM_REPOSITORY

## Runtime and Tool Versions
- Python: TO_BE_VERIFIED_FROM_REPOSITORY
- Node.js: TO_BE_VERIFIED_FROM_REPOSITORY
- Package managers: TO_BE_VERIFIED_FROM_REPOSITORY
- PostgreSQL: TO_BE_VERIFIED_FROM_REPOSITORY
- Container or browser tools: TO_BE_VERIFIED_FROM_REPOSITORY
- Version evidence: TO_BE_VERIFIED_FROM_REPOSITORY

## Authoritative Commands
| Purpose | Exact command | Status | Evidence source |
|---|---|---|---|
| Bootstrap | TO_BE_VERIFIED_FROM_REPOSITORY | BLOCKED | TO_BE_VERIFIED_FROM_REPOSITORY |
| Fast verification | TO_BE_VERIFIED_FROM_REPOSITORY | BLOCKED | TO_BE_VERIFIED_FROM_REPOSITORY |
| Full verification | TO_BE_VERIFIED_FROM_REPOSITORY | BLOCKED | TO_BE_VERIFIED_FROM_REPOSITORY |
| API tests | TO_BE_VERIFIED_FROM_REPOSITORY | BLOCKED | TO_BE_VERIFIED_FROM_REPOSITORY |
| Web tests | TO_BE_VERIFIED_FROM_REPOSITORY | BLOCKED | TO_BE_VERIFIED_FROM_REPOSITORY |

## Execution Evidence
- Required status: EXECUTION_VERIFIED
- Commit: TO_BE_VERIFIED_FROM_REPOSITORY
- Sanitized argv: TO_BE_VERIFIED_FROM_REPOSITORY
- Exit code: TO_BE_VERIFIED_FROM_REPOSITORY
- Duration: TO_BE_VERIFIED_FROM_REPOSITORY
- Evidence location: TO_BE_VERIFIED_FROM_REPOSITORY
- Approver: TO_BE_VERIFIED_FROM_REPOSITORY

## Known Failures
- Command: TO_BE_VERIFIED_FROM_REPOSITORY
- Exit code: TO_BE_VERIFIED_FROM_REPOSITORY
- Relevant output: REDACTED_OR_UNAVAILABLE
- Environment: TO_BE_VERIFIED_FROM_REPOSITORY
- Classification: pre-existing, flaky, blocked, or unknown

## Test Layers
- Unit: TO_BE_VERIFIED_FROM_REPOSITORY
- API or integration: TO_BE_VERIFIED_FROM_REPOSITORY
- Browser: TO_BE_VERIFIED_FROM_REPOSITORY
- Database or migration: TO_BE_VERIFIED_FROM_REPOSITORY
- Coverage and gaps: TO_BE_VERIFIED_FROM_REPOSITORY

## Risk Modules
- Search route and request parsing: TO_BE_VERIFIED_FROM_REPOSITORY
- Query builder and SQL boundaries: TO_BE_VERIFIED_FROM_REPOSITORY
- Authentication or authorization: TO_BE_VERIFIED_FROM_REPOSITORY
- Migrations and shared schemas: TO_BE_VERIFIED_FROM_REPOSITORY
- Frontend API client and serialization: TO_BE_VERIFIED_FROM_REPOSITORY

## Secrets Boundaries
- Secret sources: TO_BE_VERIFIED_FROM_REPOSITORY
- Files never to read or copy: TO_BE_VERIFIED_FROM_REPOSITORY
- Production endpoints and databases: not used for verification
- Redaction policy: no credentials, tokens, cookies, personal data, or internal URLs

## Owners and Generated Files
- API owner: TO_BE_VERIFIED_FROM_REPOSITORY
- Web owner: TO_BE_VERIFIED_FROM_REPOSITORY
- Database owner: TO_BE_VERIFIED_FROM_REPOSITORY
- CI owner: TO_BE_VERIFIED_FROM_REPOSITORY
- Generated-file owner and regeneration command: TO_BE_VERIFIED_FROM_REPOSITORY

## Approval Gates
1. Approve baseline corrections.
2. Approve verification adapter changes.
3. Approve guidance and project Skill changes.
4. Approve characterization tests.
5. Approve each pilot task and scope expansion.

## Unverified Items
- TO_BE_VERIFIED_FROM_REPOSITORY

Agent 产物

最终产物是 docs/agent-readiness/BASELINE.md、命令证据索引和一份“已知失败/未验证项”清单。若执行了只读测试或构建,还要保存脱敏的 exit code、相关输出、commit、环境版本和耗时;临时日志和含秘密的原始 evidence 不进入仓库。

人工审批点

人工审查每个命令的证据来源,特别是 API、前端、数据库和 CI 命令是否确实来自目标项目。审查人必须拒绝“看起来合理但没有出处”的命令,并决定哪些已知失败可作为基线、哪些失败需要先补环境。

完成标志

任何人都能区分 SOURCE_CONFIRMEDEXECUTION_VERIFIEDFAILEDBLOCKEDSKIPPED;基线包含 repo map、runtime/tool versions、authoritative commands、evidence sources、known failures、test layers、risk modules、secrets boundaries、owners、generated files 和 approval gates,且没有猜测。

Step 3:Bootstrap/verification adapters——建立确定性验证入口

实际操作

只在基线得到批准后,让 Agent 根据已执行验证的命令映射创建目标项目的 scripts/bootstrap.shscripts/verify-fast.shscripts/verify.sh。适配层的作用是统一入口和失败语义,不是偷偷重写构建系统。命令必须由人工审批后写成固定 argv 数组,或委托到已审查的仓库脚本/Make target;不能执行动态完整 shell 字符串、不能使用 bash -lc,也不能把 SOURCE_CONFIRMED 当作执行证明。

先使用这个 Prompt,要求 Agent 只生成补丁,不立即执行破坏性操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Using the approved BASELINE.md, create only these verification adapters:
- scripts/bootstrap.sh
- scripts/verify-fast.sh
- scripts/verify.sh

Rules:
- Reuse only commands marked EXECUTION_VERIFIED.
- Use fixed argv arrays or approved repository scripts and Make targets.
- Do not use bash -lc, eval, sh -c, or dynamically assembled shell strings.
- Preserve the repository's existing package managers, environments, test selectors, and service boundaries.
- If a required command is empty, unknown, contains any placeholder, or is not
in the approved command mapping, exit non-zero.
- Use strict shell failure behavior and propagate child exit codes.
- Do not ignore failures, use unconditional success, or hide output needed for diagnosis.
- Do not install from the network unless the approved repository command explicitly requires it.
- Do not write to production, use real credentials, or run destructive migrations.
- In terminal and CI, log only a stable command ID and a pre-approved
sanitized argv summary.
- Write the complete sanitized argv only to controlled execution evidence.
- Never print an argv that may contain tokens, private URLs, or secret values.
- Show the proposed diff before execution.

The adapters must:
1. Fail fast on missing prerequisites.
2. Log the stable command ID and sanitized argv summary before running it.
3. Return non-zero when a delegated command fails.
4. Distinguish unverified commands from successful verification.
5. Be reusable by local development and CI.

这里的 fail-safe 核心模板只展示控制结构,不假装知道目标仓库的真实命令。实际项目应把每条已批准命令写成固定数组;若仓库已有经过审查的脚本或 Make target,优先直接委托该入口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/usr/bin/env bash
set -Eeuo pipefail

run_verified() {
local label="$1"
local command_id="$2"
local argv_summary="$3"
shift 3
if [[ "$#" -lt 1 ]]; then
printf 'ERROR: %s has no configured argv.\n' "$label" >&2
return 1
fi
printf '==> %s\n' "$label"
printf 'Command ID: %s\n' "$command_id"
printf 'Argv summary: %s\n' "$argv_summary"
"$@"
}

require_approved_argv() {
local argv_name="$1"
shift
case "$argv_name" in
"api bootstrap"|"web bootstrap"|"api fast verification"|"web fast verification")
;;
*)
printf 'Unapproved argv mapping: %s\n' "$argv_name" >&2
exit 2
;;
esac
if [[ "$#" -eq 0 ]]; then
printf 'Empty approved argv: %s\n' "$argv_name" >&2
exit 2
fi
local argument
for argument in "$@"; do
if [[ -z "$argument" ||
"$argument" == *TO_BE_VERIFIED_FROM_REPOSITORY* ]]; then
printf 'Invalid approved argv: %s\n' "$argv_name" >&2
exit 2
fi
done
}

bootstrap() {
local api_bootstrap_argv=(TO_BE_VERIFIED_FROM_REPOSITORY)
local web_bootstrap_argv=(TO_BE_VERIFIED_FROM_REPOSITORY)
require_approved_argv "api bootstrap" "${api_bootstrap_argv[@]}"
require_approved_argv "web bootstrap" "${web_bootstrap_argv[@]}"
run_verified \
"API bootstrap" \
"approved-api-bootstrap" \
"REDACTED: approved API bootstrap argv" \
"${api_bootstrap_argv[@]}"
run_verified \
"Web bootstrap" \
"approved-web-bootstrap" \
"REDACTED: approved web bootstrap argv" \
"${web_bootstrap_argv[@]}"
}

bootstrap

verify-fast.shverify.sh 应沿用同一失败语义:先把每一条真实命令放入变量或直接调用,再通过 run_verified 执行;不得用 || true、吞 stderr、固定 exit 0 或将未配置项当作跳过成功。若仓库的命令包含复杂 shell 语法,应引用已审查的脚本或 CI job,而不是自行重新拼接。

Agent 产物

Agent 产出三个脚本的补丁、命令映射说明、脚本自检结果和 CI 复用建议。脚本应明确哪些是 bootstrap、快速验证、全量验证,以及它们是否需要隔离 PostgreSQL、浏览器、容器或外部服务。

人工审批点

人工审查脚本是否只调用基线中的 EXECUTION_VERIFIED 命令,是否非零传播错误,是否会安装依赖、执行迁移或连接外部服务。批准后才在隔离环境执行;执行结果不能因为脚本本身成功而掩盖子命令失败。

完成标志

在目标项目中,缺少前置条件、未验证命令、任一子命令失败都会得到非零退出码;成功时每条命令都有 stable command ID 和受控证据。verify-fast.shverify.sh 可由本地和 CI 复用,且没有生产写入、秘密硬编码或无依据的命令。

Step 4:Guidance——提交公共事实,迁移旧规则

实际操作

本步骤只能使用已经过人工批准的 docs/agent-readiness/BASELINE.mdSOURCE_CONFIRMED 只表示来源被确认,不表示命令可以执行;只有标记为 EXECUTION_VERIFIED 的命令,才可以写成验证入口。未知命令必须保留为未知项,不能根据命令名称、README 或 Agent 的猜测补全。

先让 Agent 只读审计仓库,再由人工审批迁移表和拟写入文件。审批通过后,Agent 才能生成 patch。根级 AGENTS.md 保持精简,目录级文件只写相对于根规则的增量;重复的流程进入 Skill,个人偏好和用户配置不提交。发现 secret 后立即停止并做最小化报告,不复制、打印、删除或轮换它。冲突或未知项保留为 unresolved,不擅自选择;旧文件默认保留,只有 owner 单独批准后才删除。

可复制的双审批门 Agent Prompt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
You are migrating repository guidance under a strict two-gate approval process.

Hard boundary:
- Use only the human-approved docs/agent-readiness/BASELINE.md.
- SOURCE_CONFIRMED means the source was confirmed; it does not authorize execution.
- Only EXECUTION_VERIFIED commands may become verification entry points.
- Do not guess unknown commands, owners, scopes, URLs, credentials, or tool behavior.
- Do not edit files during Gate 1.

Gate 1 — read-only audit:
1. Read only the human-approved docs/agent-readiness/BASELINE.md entries that are not marked
secret or user configuration, README files, CI configuration, the existing CLAUDE.md and
.cursorrules, repository instructions, available Skills, and the directory structure.
The existing CLAUDE.md, .cursorrules, and instructions are classification sources, not
fact authorities. Reuse a shared fact or directory rule only when it maps exactly to an
approved BASELINE entry; otherwise set its disposition to unresolved.
2. Reuse the strict read-only boundary from Step 1. Allow only file reads and Git metadata
queries with pagers, hooks, and aliases disabled. The only permitted Git metadata query
forms are `git --no-pager -c core.hooksPath=/dev/null rev-parse`,
`git --no-pager -c core.hooksPath=/dev/null log`,
`git --no-pager -c core.hooksPath=/dev/null branch --show-current`, and
`git --no-pager -c core.hooksPath=/dev/null status --short`.
The allowlist accepts only built-in Git subcommands; aliases are not accepted as commands.
Do not run repository scripts, Make, Task, tests, builds, Docker, package managers,
databases, services, startup, migration, deployment, network access, or any command
inferred from repository content.
3. Do not read any path that the BASELINE marks as secret or user configuration.
4. Classify every candidate item as exactly one of:
shared facts, directory-scoped rules, on-demand workflows, personal preferences,
secrets/user configuration.
5. Propose the smallest file set. Prefer a concise root AGENTS.md, directory-level files
only for local deltas, and Skills for reusable workflows.
6. Produce a migration table with one row per item and these columns:
row_id, source, baseline_reference, target, scope, status, owner, reason, disposition.
baseline_reference must identify the exact approved BASELINE entry, or be unresolved.
Use status values such as confirmed, proposed, unresolved, blocked, or do-not-commit.
7. Return the proposed files, migration table, conflicts, unknowns, and deletion candidates.
8. Stop and wait for explicit human approval. Do not edit, generate a patch, or delete any
old file in Gate 1.

Gate 2 — patch generation after explicit human approval:
- Require and echo all of these inputs before generating anything:
approved BASELINE revision, approved migration row IDs, exact file allowlist, and each old
file's retain/deprecate/delete disposition. If any input is missing, stop.
- For every approved migration row ID, require an exact approved BASELINE reference and an
eligible disposition. Never generate a patch for a row whose disposition is unresolved,
blocked, or do-not-commit, even when its row ID was supplied.
- Generate a patch only for the approved proposed files.
- Generate a patch only; do not execute adapters, tests, services, startup, migration,
deployment, or any command.
- Set verification evidence to NOT_RUN. Running an EXECUTION_VERIFIED adapter requires a
separate independent human approval and an isolated environment; this Guidance task does
not execute it.
- Keep root AGENTS.md concise and write only shared repository facts and global boundaries.
- Directory-level AGENTS.md files may contain only incremental local facts; do not copy root rules.
- Move repeatable workflows into Skills instead of embedding procedures in AGENTS.md.
- Never commit personal preferences, user configuration, credentials, secrets, internal URLs,
production values, or one-off task details.
- If a secret is discovered, stop immediately and return only its file path and risk category.
Do not print, copy, delete, rotate, or expose the secret.
- Keep conflicts and unknowns unresolved. Do not choose an interpretation without owner approval.
- Do not delete old guidance files unless the owner separately approves that exact deletion.
- Do not invent commands. A verification entry point must be marked EXECUTION_VERIFIED in the
approved BASELINE.md and must run through an approved adapter.
- Starting the backend may run migrations, seed data, create or modify S3 objects, or start
background jobs. It is not ordinary verification. Never run production migration/apply.

Required final report:
1. changed files
2. migration decisions
3. unresolved conflicts
4. commands referenced, including each command status and adapter
5. verification evidence
6. rollback procedure

根级模板:

下面是一个完整示例,仅适用于“已批准 Baseline 明确确认 backend/ 使用 FastAPI、frontend/ 使用 Vue、CLI 使用 Typer、Kubernetes 使用 Kustomize”的项目。它不能机械复制;如果目标 Baseline 确认的是 React 或其他结构,必须按 Baseline 替换,未确认的项不得写入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Repository Guidance

## Scope
- This file contains shared repository facts and safe working boundaries.
- Read the nearest nested AGENTS.md before editing a scoped directory.
- Use only the human-approved `docs/agent-readiness/BASELINE.md`.
- `SOURCE_CONFIRMED` is not executable; only `EXECUTION_VERIFIED` commands are verification entry points.

## Repository Map
- `backend/`: FastAPI and PostgreSQL application; Alembic owns schema migrations.
- `frontend/`: Vue 3, TypeScript, and Vite application.
- `cli/`: Typer command-line interface.
- `k8s/`: Kustomize overlays and Kubernetes manifests.
- `scripts/`: approved adapters for setup and verification; do not infer commands from filenames.
- `docs/agent-readiness/BASELINE.md`: human-approved facts, command status, known failures, and owners.

## Working Rules
- Explore before editing.
- Change the smallest approved scope.
- Use only `EXECUTION_VERIFIED` commands through approved `scripts/` adapters.
- Unknown commands remain unresolved; never guess.
- Keep secrets, personal configuration, and production data outside the repository.
- Show the diff before running broad verification.

## Verification
- Verification entry points are only approved `EXECUTION_VERIFIED` adapters in `scripts/`.
- Do not promote `SOURCE_CONFIRMED` or `TO_BE_VERIFIED_FROM_REPOSITORY` to a runnable command.
- This Guidance task generates a patch only and does not execute verification.
- Verification evidence is `NOT_RUN` unless a separate independent human approval authorizes
an approved adapter in an isolated environment.

## Approval Gates
- Human approval is required for migrations, deployment files, authentication, shared schemas,
cross-module changes, production configuration, and scope expansion.

一个目录级文件只描述本目录的增量事实。例如,backend/AGENTS.md 不重复根级地图、审批和秘密规则:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Backend Guidance

## Scope
- These rules apply only to `backend/`.

## Boundaries
- Keep FastAPI routes thin: validate transport concerns and delegate business behavior to services.
- Keep services independent from HTTP concerns and make database access explicit through the
repository/DB boundary.
- Routes must not bypass the approved service-to-repository/DB ownership boundary.
- Alembic owns backend schema migrations; creation or application requires explicit human approval.

## Testing and Startup
- Use an isolated test database approved for the current task.
- Backend startup may run migrations, seed data, create or modify S3 objects, or start background jobs.
- Treat startup as side-effectful; it is not ordinary verification.
- Never run migration or apply commands against production.

迁移 .cursorrules、重复 Prompt 和超长指导文件时,先分类为公共事实、目录规则、按需流程、个人偏好和秘密/用户配置。公共事实进入 AGENTS.md,目录规则进入最近的目录级文件,重复流程进入项目 Skill,个人偏好和用户级配置不提交。若发现 credential 或 secret,立即停止迁移,不自动删除、不自动轮换、不复制也不打印;只记录最小化的文件位置和风险类别,通知 owner,由另一个单独且经过审批的 remediation 任务处理。保留迁移记录,避免多个文件对同一事实给出冲突版本。

生成 patch 后,先使用以下只读 Review Prompt;Critical 或 Important 问题必须修复,或者阻断合并:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Review the generated guidance migration as a read-only reviewer.

Check every item:
- Trace every migrated fact to its exact baseline_reference and confirm that the reference
points to a human-approved BASELINE entry. Treat legacy CLAUDE.md, .cursorrules, and
instructions only as classification sources; do not require those legacy sources
themselves to be approved authorities.
- Confirm each migration row has a row_id, baseline_reference, source, target, scope, status,
owner, reason, and disposition. Reject a migration without an approved BASELINE mapping.
- Confirm every approved row has an eligible disposition; reject patch content for rows
marked unresolved, blocked, or do-not-commit, regardless of supplied row ID.
- Check AGENTS.md hierarchy: root rules are concise, nested files contain only local deltas,
and no nested file duplicates the root.
- Check every referenced command and adapter status. Only EXECUTION_VERIFIED commands may be
verification entry points; SOURCE_CONFIRMED and unknown commands must not be executable.
- Confirm the Gate 1 read-only boundary excludes scripts, Make/Task, tests, builds, Docker,
package managers, databases, network access, secret paths, and user-configuration paths.
- Confirm Gate 2 only generated a patch, did not execute adapters or other commands, and reports
verification evidence as NOT_RUN.
- Confirm the approved BASELINE revision, migration row IDs, exact file allowlist, and every
old-file retain/deprecate/delete disposition were supplied and echoed.
- Detect duplicated, contradictory, guessed, stale, or scope-leaking rules.
- Detect secrets, credentials, internal URLs, production values, personal preferences, user
configuration, and one-off task details.
- Check that backend startup side effects are explicit in the backend guidance and that
production migration/apply is prohibited.
- Check every old guidance file and confirm deletion has separate owner approval.
- Check that reusable workflows moved to Skills and that the migration table is complete.

Classify each finding as Critical, Important, or Minor.
Critical and Important findings must be fixed or block approval. Minor findings are recorded
as non-blocking improvements. Return:
findings, source trace, hierarchy result, command-status result, deletion-approval result,
required fixes, and final approval status.

Agent 产物

Agent 产出根级和必要的目录级 AGENTS.md、旧规则分类表、含 row ID 与 baseline_reference 的迁移记录、生成后的 patch 以及只读 Review Prompt 的审查结果。最终报告必须包含 approved BASELINE revision、approved migration row IDs、exact file allowlist、old-file dispositions、changed files、migration decisions、unresolved conflicts、commands referenced、verification evidence(本任务默认 NOT_RUN)和 rollback;产物要说明每条规则的来源、作用范围、维护责任人和验证方式。Review findings 中的 Critical/Important 必须已修复或阻断,Minor 作为非阻断改进记录。

人工审批点

人工先批准 Gate 1 的 proposed files、逐条迁移表、Baseline revision 和 row IDs,再批准 Gate 2 的 exact file allowlist、旧文件 dispositions 和 patch。审批人确认指导文件没有凭据、内部 URL、个人偏好或一次性任务细节;确认根级文件足够短,嵌套文件只增加目录特有事实;确认 .cursorrules 等旧文件是保留、迁移、弃用还是删除,并由仓库所有者单独批准删除。若审计发现 credential 或 secret,审批点只确认最小化记录和 owner 通知,不在本任务中批准删除或轮换。只读 Review Prompt 的 Critical/Important 问题必须修复或阻断,Minor 问题记录为非阻断改进。

完成标志

Gate 1 和 Gate 2 均有明确人工批准记录,并且回显了 approved BASELINE revision、migration row IDs、exact file allowlist 和所有旧文件 dispositions;每个获批 row 都有精确的 approved BASELINE reference 和 eligible disposition;新会话中的 Agent 能从根文件找到经 Baseline 确认的目录地图、边界和验证入口;backend/ 的局部事实不会污染全局规则;只有 EXECUTION_VERIFIED adapters 被引用为验证入口;本 Guidance 任务的 verification evidence 为 NOT_RUN;只读 Review Prompt 的 Critical/Important 问题均已修复或已阻断,Minor 问题已记录为非阻断改进;团队需要的 AGENTS.md、Rules/Skills 变更可审查并提交,而用户级配置、凭据、秘密、生产值和临时内容没有进入 Git,旧文件也没有未经 owner 单独批准而删除。

Step 5:Characterization tests——先固定 Search API 的真实行为

实际操作

选择高风险且高变更频率的 Search API path,先建立 characterization tests,不先“修正”奇怪行为。测试应覆盖真实请求解析、分页/排序、过滤、错误 envelope、空值语义、权限边界以及数据库交互中当前必须兼容的行为。使用隔离 PostgreSQL、fixtures 或 repository double,并在测试前保存 before evidence:精确命令、commit、环境、输入、输出、状态码和查询结果。

可以先给 Agent 以下操作约束:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Create characterization tests for the existing Search API behavior.

Explore first:
- Find the real FastAPI route, request model, service, query builder, database fixture,
test client, and existing API test command.
- Find the React request serialization only if it is part of the observed behavior.

Rules:
- Do not fix, normalize, refactor, rename, or improve behavior.
- Preserve odd but compatible responses as observations.
- Require TEST_DATABASE_URL and an approved test-database record.
- Require the host to be in APPROVED_TEST_HOSTS.
- Require the name to be in APPROVED_TEST_DATABASE_NAMES or to match an
approved test-database prefix.
- Require a temporary schema that matches the approved schema rule.
- Require a dedicated low-privilege role.
- Use transaction rollback only when the behavior under test does not cross a commit boundary.
- Never use production data, credentials, or production endpoints.
- Record before evidence before adding assertions.
- Mark unknown paths, commands, response fields, and status meanings as
TO_BE_VERIFIED_FROM_REPOSITORY or BLOCKED.

Return:
1. A behavior matrix with request, response, database effect, and evidence.
2. The smallest test diff that captures current behavior.
3. Exact commands and outputs.
4. Behaviors that are intentionally not asserted because evidence is missing.
5. A human approval request before any implementation change.

在运行测试前,再给 Agent 一个专门的 guard Prompt。它的目的不是检查字符串格式,而是阻断错误的数据库身份、生产目标和外部写入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Before running characterization tests, enforce these guards:
1. TEST_DATABASE_URL must be present and parse successfully.
2. Load the approved record containing APPROVED_TEST_HOSTS,
APPROVED_TEST_DATABASE_NAMES, approved database prefixes,
APPROVED_TEST_SERVER_IDENTITIES, APPROVED_TEST_ROLES, and the temporary
schema rule.
3. Require the configured host and database name to match the positive
allowlist and require a dedicated low-privilege role.
4. Connect and require server, database, and current_user identity to match
the approved record exactly.
5. Create a temporary schema that matches the approved schema rule.
6. Keep production host and database denylist checks as a second layer only.
7. Record redacted pre-test identity evidence.
8. Disable migrations and external writes by default.
9. Run the focused test.
10. Record redacted post-test identity evidence and verify teardown leaves no
temporary database, schema, table, role, or fixture residue.
11. Stop with BLOCKED on any failed guard; never continue with a fallback URL.

核心示例只展示防护顺序。parse_database_urlconnect_admin_for_testdrop_temporary_schema 必须替换为目标仓库已审查的实现;未知实现不能当作通过:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import os


APPROVED_TEST_HOSTS = frozenset({"TO_BE_VERIFIED_FROM_REPOSITORY"})
APPROVED_TEST_DATABASE_NAMES = frozenset({"TO_BE_VERIFIED_FROM_REPOSITORY"})
APPROVED_TEST_DATABASE_PREFIXES = ("TO_BE_VERIFIED_FROM_REPOSITORY",)
APPROVED_TEST_ROLES = frozenset({"TO_BE_VERIFIED_FROM_REPOSITORY"})
APPROVED_TEST_SERVER_IDENTITIES = frozenset({"TO_BE_VERIFIED_FROM_REPOSITORY"})
APPROVED_TEST_SCHEMA_PREFIX = "TO_BE_VERIFIED_FROM_REPOSITORY"
APPROVED_PRODUCTION_HOSTS = frozenset()
APPROVED_PRODUCTION_DATABASES = frozenset()


def require_test_database():
raw_url = os.environ.get("TEST_DATABASE_URL")
if not raw_url:
raise RuntimeError("TEST_DATABASE_URL is required")

database = parse_database_url(raw_url)
if any("TO_BE_VERIFIED_FROM_REPOSITORY" in value for value in (
database.host,
database.name,
database.role,
APPROVED_TEST_SCHEMA_PREFIX,
)):
raise RuntimeError("Database approval record is incomplete")
if database.host not in APPROVED_TEST_HOSTS:
raise RuntimeError("Database host is not allowlisted")
if (
database.name not in APPROVED_TEST_DATABASE_NAMES
and not any(
database.name.startswith(prefix)
for prefix in APPROVED_TEST_DATABASE_PREFIXES
)
):
raise RuntimeError("Database name is not allowlisted")
if database.role not in APPROVED_TEST_ROLES:
raise RuntimeError("Database role is not allowlisted")
if database.host in APPROVED_PRODUCTION_HOSTS:
raise RuntimeError("Production database host is forbidden")
if database.name in APPROVED_PRODUCTION_DATABASES:
raise RuntimeError("Production database name is forbidden")

identity_before = query_database_identity(database)
if identity_before.server not in APPROVED_TEST_SERVER_IDENTITIES:
raise RuntimeError("Database server identity is not approved")
if identity_before.database != database.name:
raise RuntimeError("Database identity does not match the URL")
if identity_before.current_user != database.role:
raise RuntimeError("Database user identity does not match the role")
assert_identity_is_low_privilege(identity_before)
temporary_schema = create_temporary_schema(
database,
prefix=APPROVED_TEST_SCHEMA_PREFIX,
)
assert_schema_matches_approved_rule(temporary_schema)
return database, temporary_schema, identity_before


def run_characterization():
database, schema, identity_before = require_test_database()
try:
run_focused_test(database, schema, allow_migrations=False)
finally:
identity_after = query_database_identity(database)
assert_same_approved_identity(identity_before, identity_after)
drop_temporary_schema(database, schema)
assert_no_test_residue(database, schema)

测试 fixture 必须在执行前后查询数据库 identity;默认禁止 migration 和外部写入;teardown 必须验证临时 database/schema、table、role 和 fixture 没有残留。事务 rollback 只适用于被测行为不跨提交边界的情况;如果代码显式提交、触发异步任务、写出消息或调用外部系统,必须使用临时 database/schema 和显式清理,不能把 rollback 当作隔离证明。

行为矩阵可以采用如下英文格式;字段必须替换为真实值,不能将示例 status、path 或 response 当作项目事实:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Search API Characterization

## Evidence
- Commit: TO_BE_VERIFIED_FROM_REPOSITORY
- Command: TO_BE_VERIFIED_FROM_REPOSITORY
- Database: isolated test database only
- Captured output: REDACTED_OR_UNAVAILABLE

## Matrix
| Input | Observed status | Response shape | Database effect | Evidence |
|---|---|---|---|---|
| Omitted filter | TO_BE_VERIFIED_FROM_REPOSITORY | TO_BE_VERIFIED_FROM_REPOSITORY | TO_BE_VERIFIED_FROM_REPOSITORY | TO_BE_VERIFIED_FROM_REPOSITORY |
| Empty filter | TO_BE_VERIFIED_FROM_REPOSITORY | TO_BE_VERIFIED_FROM_REPOSITORY | TO_BE_VERIFIED_FROM_REPOSITORY | TO_BE_VERIFIED_FROM_REPOSITORY |
| Valid filter | TO_BE_VERIFIED_FROM_REPOSITORY | TO_BE_VERIFIED_FROM_REPOSITORY | TO_BE_VERIFIED_FROM_REPOSITORY | TO_BE_VERIFIED_FROM_REPOSITORY |
| Invalid filter | TO_BE_VERIFIED_FROM_REPOSITORY | TO_BE_VERIFIED_FROM_REPOSITORY | TO_BE_VERIFIED_FROM_REPOSITORY | TO_BE_VERIFIED_FROM_REPOSITORY |

## Compatibility Notes
- Odd behavior intentionally preserved: TO_BE_VERIFIED_FROM_REPOSITORY
- Behavior not asserted: TO_BE_VERIFIED_FROM_REPOSITORY
- Production access: false
- Credentials included: false

Agent 产物

Agent 产出 characterization test diff、行为矩阵、before evidence 索引和未覆盖风险列表。测试应能说明“当前发生了什么”,而不是暗示“应该发生什么”;若响应字段或状态码尚未被仓库事实确认,就保持 TO_BE_VERIFIED_FROM_REPOSITORYBLOCKED

人工审批点

人工确认测试使用 TEST_DATABASE_URL、专用低权限 role、临时 database/schema 和 identity evidence;确认默认禁止 migration/外部写入且 teardown 无残留。还要确认事务 rollback 只用于不跨提交边界的行为,确认奇怪但兼容的行为被如实固定,确认测试没有把缺陷偷偷写成新 contract。只有在审查人批准后,Agent 才能进入业务实现修改。

完成标志

Search API 的关键路径有可重复的 before evidence;至少覆盖一个高风险输入矩阵和数据库边界;测试失败时能区分环境失败与行为差异;没有因为写测试而修改业务行为。

Step 6:Project Skill——把改造流程变成按需能力

实际操作

在确认团队需要重复执行这套流程后,提交一个紧凑的项目 Skill:.agents/skills/legacy-agent-readiness/SKILL.md。Skill 必须以 YAML Front Matter 开头,至少包含符合命名约束的 name 和同时说明用途、触发场景的 description;需要强制显式调用的 Cursor 项目还可以加入 disable-model-invocation: true。Skill 不应复制所有项目细节,而应定义调用时的顺序、证据要求、停止条件和边界。具体命令、负责人和当前失败留在 BASELINE.md,避免 Skill 随每次基线变化而失效。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
---
name: legacy-agent-readiness
description: Prepare legacy repositories for safe, evidence-based Agent work. Use when auditing an existing repository, establishing verified commands and guidance, adding characterization tests, or running an approved readiness pilot.
disable-model-invocation: true
---

# Legacy Agent Readiness

## Purpose
Make a legacy repository safe to explore, verify, and change incrementally.

## Inputs
- Approved repository scope.
- Current `docs/agent-readiness/BASELINE.md`.
- Human owner for the requested change.
- A non-production environment.

## Workflow
1. `audit`: inspect repository facts in read-only mode.
2. `baseline`: record verified commands, failures, risks, owners, and unknowns.
3. `scripts`: create fail-safe bootstrap and verification adapters from execution-verified commands.
4. `guidance`: maintain concise AGENTS.md files and migrate stale guidance.
5. `tests`: add characterization tests before behavior changes.
6. `pilot`: execute one low-risk reversible task.
7. `adoption`: expand scope only after evidence and approval.
8. `boundaries`: enforce secret, production, generated-file, and migration limits.
9. `report`: record changed files, commands, outputs, approvals, risks, and rollback.

## Evidence Rules
- Mark missing facts as TO_BE_VERIFIED_FROM_REPOSITORY or BLOCKED.
- Mark unknown commands as TO_BE_VERIFIED_FROM_REPOSITORY.
- Never treat a placeholder as success.
- Preserve command IDs, sanitized argv evidence, exit codes, relevant output,
commit, and environment in controlled execution evidence.
- Redact credentials, tokens, cookies, personal data, internal URLs, and secret values.

## Change Rules
- Explore before editing.
- Use the smallest approved scope.
- Do not refactor unrelated legacy code.
- Do not upgrade dependencies during readiness work without separate approval.
- Do not write to production or use production credentials.
- Do not modify generated files without an approved regeneration path.

## Stop Conditions
Stop and request human review when:
- A command, owner, contract, or boundary is unverified.
- The task requires migration, deployment, authentication, or cross-module changes.
- Verification fails for an unknown reason.
- A secret or production access path is encountered.
- The approved scope must expand.

## Completion Report
Report:
- Scope and changed files.
- Exact verification commands and exit codes.
- Before and after evidence.
- Known failures and unverified items.
- Approval records and rollback procedure.

调用 Prompt 也应显式指定 Skill 和范围,避免 Agent 把“legacy readiness”解释成一次性重构:

1
2
3
4
5
6
7
8
9
10
Use the project Skill `.agents/skills/legacy-agent-readiness/SKILL.md`.
Run only the `pilot` workflow for this approved scope:
- Scope: TO_BE_VERIFIED_FROM_REPOSITORY
- Owner: TO_BE_VERIFIED_FROM_REPOSITORY
- Environment: isolated non-production
- Rollback: TO_BE_VERIFIED_FROM_REPOSITORY

First read BASELINE.md and the nearest AGENTS.md.
Stop before editing if any command, boundary, owner, or rollback procedure is unverified.
Return the proposed plan and approval request before implementation.

Agent 产物

Agent 产出 Skill 文件、调用 Prompt、Skill 与 baseline/AGENTS.md 的关系说明,以及一次 dry-run 结果。Skill 必须覆盖 auditbaselinescriptsguidancetestspilotadoptionboundariesreport

人工审批点

人工确认 Skill 是项目级公共流程,不是个人偏好;确认它没有凭据、内部 URL、隐含生产权限或“自动批准”语言;确认团队愿意维护它,并批准其提交到目标代码仓库。

完成标志

另一位 Agent 按显式 Prompt 可以找到 Skill、读取基线、在未验证处停止,并生成可审查的报告;Skill 没有把占位符、跳过测试或一次成功误报为 readiness。

Pilot Eligibility Checklist

在 Step 7 之前,人工必须通过两道独立门禁。第一道只决定是否允许 Explore;第二道决定是否允许 Implement。任一未知项都保持 BLOCKED,不能用一次成功或口头确认跳过。

Pre-Explore Gate

这道门禁不要求先拥有代码 diff 或执行证据,只确认任务是否值得安全探索:

1
2
3
4
5
6
7
8
9
10
# Pre-Explore Gate

- Pilot ID: TO_BE_VERIFIED_FROM_REPOSITORY
- Task type: documentation update or characterization test only
- Owner: TO_BE_VERIFIED_FROM_REPOSITORY
- Read-only exploration scope: TO_BE_VERIFIED_FROM_REPOSITORY
- Production access: false
- Credential and secret boundary: no secret values may be read or copied
- Pre-Explore decision: approved or BLOCKED
- Approver: TO_BE_VERIFIED_FROM_REPOSITORY

Implementation Gate

Explore 完成后、Implement 之前,必须单独填写并批准以下门禁:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Implementation Gate

- Pilot ID: TO_BE_VERIFIED_FROM_REPOSITORY
- Exact file allowlist: TO_BE_VERIFIED_FROM_REPOSITORY
- Explicitly forbidden paths: generated files, shared configuration,
migrations, deployment files, credentials, and production configuration
- Risk level: low
- Rollback procedure: TO_BE_VERIFIED_FROM_REPOSITORY
- Database isolation evidence: not applicable or TO_BE_VERIFIED_FROM_REPOSITORY
- Related command IDs: TO_BE_VERIFIED_FROM_REPOSITORY
- Every related command status: EXECUTION_VERIFIED
- Production access: false
- Credential or secret exposure: false
- Implementation decision: approved or BLOCKED
- Approver: TO_BE_VERIFIED_FROM_REPOSITORY
- Approval recorded at: TO_BE_VERIFIED_FROM_REPOSITORY

Exact file allowlist 必须是明确的路径集合,而不是“相关文件”;共享配置和生成物默认排除。若 pilot 涉及数据库,Implementation Gate 必须补齐 TEST_DATABASE_URL、正向 allowlist、低权限 role、临时 schema/database、server/database/current_user identity 和 teardown evidence。任何相关命令只有在隔离环境记录 commit、脱敏 argv、exit code、duration、evidence 和 approver 后,才能标为 EXECUTION_VERIFIED

Step 7:Pilot task——用低风险任务验证闭环

实际操作

第一项 pilot 必须低风险、可逆、边界窄。推荐二选一:补充 README 中已有事实的文档,或为一个已知 bug 增加 characterization test;不要在 pilot 中改 Search API 逻辑、迁移数据库、修改部署、升级依赖或跨模块重构。

下面的 Prompt 要求完整执行 Explore → Plan → Implement → Verify → Review,但每个阶段都设置人工门禁:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Use `.agents/skills/legacy-agent-readiness/SKILL.md` for this pilot.

Pilot task:
- Type: documentation update or characterization test only
- Scope: TO_BE_VERIFIED_FROM_REPOSITORY
- Issue: TO_BE_VERIFIED_FROM_REPOSITORY
- Owner: TO_BE_VERIFIED_FROM_REPOSITORY
- Rollback: revert the approved commit or restore the approved file change

Explore:
- Read BASELINE.md, the nearest AGENTS.md, the relevant README, source, tests, and CI entry.
- Do not edit anything.
- Return facts, execution-verified command IDs, affected files, risks, and unknowns.

Plan:
- Propose the smallest reversible diff.
- State what is explicitly out of scope.
- State the approval needed before implementation.
- Stop for human approval.

Implement:
- Edit only approved files.
- Do not change business behavior, dependencies, migrations, deployment, or generated files.
- Show the diff immediately after editing.

Verify:
- Run the approved fast verification command by command ID.
- Run the focused test or documentation check from the repository.
- Return command IDs, exit codes, relevant output, and environment.
- Stop if any command is not EXECUTION_VERIFIED or fails unexpectedly.

Review:
- Review the diff before the success summary.
- Confirm scope, evidence, redaction, rollback, and no unrelated changes.
- Return a completion report with changed files, approvals, risks, and unverified items.

Agent 产物

Pilot 应产生 Explore 事实清单、Plan、经批准的最小 diff、验证报告、diff-first review 和完成报告。文档任务的证据应证明链接/命令来自仓库;characterization test 任务的证据应证明测试捕获当前行为而没有修复它。

人工审批点

人工分别批准 Explore 后的计划、Implement 前的范围、Verify 后的交付。审查人要核对 changed files、命令 exit code、测试是否真正执行、是否使用隔离 DB、是否出现凭据或生产访问。

完成标志

pilot 可在一个小 PR 中回滚;完整闭环有可重放证据;没有范围蔓延、无关重构、隐含权限扩大或把 TO_BE_VERIFIED_FROM_REPOSITORY 当成通过。一次 pilot 成功只证明这个范围可控,不证明整个遗留项目 ready。

Step 8:Progressive adoption——按证据逐级扩大范围

实际操作

将 Agent 权限和任务范围分成四个阶段。每阶段都要先满足准入证据,并明确回退条件;不能因为一次文档修改或一次测试成功,就直接开放生产、infra 或跨模块修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# Progressive Adoption Gates

## Stage 0: Read-only
Entry evidence:
- Approved read-only audit.
- BASELINE.md with SOURCE_CONFIRMED, EXECUTION_VERIFIED, FAILED, BLOCKED,
and SKIPPED facts.
- Secret and production boundaries identified.
Allowed:
- Repository reading, history inspection, and evidence planning.
Rollback:
- Stop the session and discard local evidence that is not approved.

## Stage 1: Documentation and Tests
Entry evidence:
- Stage 0 approved.
- Root and nested guidance reviewed.
- Isolated test database or fixtures confirmed.
- Fast verification adapter returns correct non-zero failures.
Allowed:
- README, AGENTS.md, project Skill, and characterization tests.
Rollback:
- Revert the small approved commit and remove unapproved evidence.

## Stage 2: Scoped Code
Entry evidence:
- Stage 1 pilot completed with diff-first review.
- Characterization tests cover the selected boundary.
- Owner, rollback, and exact verification commands are approved.
Allowed:
- One named module or route path with no migration, deployment, or dependency upgrade.
Rollback:
- Revert the scoped change, rerun characterization and verification, and request review.

## Stage 3: Cross-module
Entry evidence:
- Multiple scoped changes have stable evidence.
- API, web, and database owners approve the dependency map.
- Full verification and CI entry are reproducible.
- Rollback and compatibility plans are tested.
Allowed:
- Explicitly approved cross-module work.
Never implicit:
- Production access, infrastructure changes, migrations, secret handling, or deployment approval.
Rollback:
- Stop at the first unexpected boundary change and return to the last approved stage.

下面是一份可调整的示例 policy,不是通用默认值,必须由团队根据项目风险批准后生效:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Example Adoption Policy

## Stage 2 Admission
- Three consecutive approved pilots completed.
- Two weeks of observation after the third pilot.
- Required CI passed on 100 percent of approved commits.
- Zero unexplained verification failures.
- One successful rollback drill.
- API, web, and database owners signed off.

## Stage 3 Admission
- Five consecutive approved scoped PRs completed.
- Four weeks of observation after the fifth scoped PR.
- Required CI passed on 100 percent of approved commits.
- Zero unexplained verification failures.
- Rollback drill completed for each relevant boundary.
- API, web, database, and release owners signed off.

## Demotion
- Any threshold becomes false: demote to the previous stage.
- Any unexplained failure: pause scope expansion until explained and approved.
- Any boundary, secret, production, or rollback violation: stop immediately.
- No stage grants implicit production, infrastructure, migration, or deployment access.

Agent 产物

Agent 产出阶段准入记录、每次任务的 evidence index、changed files、验证结果、审批记录和 rollback 记录。项目还应在 CI 中复用已批准的 verify-fast.sh/verify.sh 入口;CI 是最终验收入口之一,但不是把权限交给 Agent 的理由。

人工审批点

每次从 Stage 0 到 Stage 3 都需要人工批准,且示例 policy 中的连续 pilot 数、观察周期、required CI 通过率、未解释失败数、rollback drill 和 owner sign-off 必须由团队书面调整并批准。特别审查生产配置、infra、迁移、认证、秘密、生成文件和跨模块边界;这些内容即使在 Stage 3 也必须单独授权。项目级 Hook/MCP 只有在无秘密、团队批准、跨环境可复现且边界明确时才可进入仓库,否则不提交。

完成标志

Agent adoption 是渐进、可回退、以证据为准的;每阶段都有准入和退出条件,CI 能复用确定性验证,未知项不会变成绿灯。示例阈值一旦失效,就降回上一阶段并暂停扩权;任何一次成功都不会自动开放生产或 infra 权限。至此,旧项目获得的是可验证的 Agent readiness,而不是未经证明的“全自动重构能力”。

本场景结束时,目标代码仓库中可以提交团队共享的根/目录级 AGENTS.md、项目级 Rules/Skills、bootstrap/verification scripts、CI 入口、characterization tests、README 更新和 BASELINE.md。个人偏好、用户级配置、凭据、临时日志、未脱敏 evidence 不提交;Hook/MCP 按无秘密、团队批准和跨环境可复现性逐项决定。本文仍只修改博客中的教程内容,不创建目标项目文件,也不提交 Git。

8. 场景五:大型需求与跨会话开发

大型需求最容易失败的地方不是代码量,而是多人、多分支和多会话对“当前真实状态”的理解不一致。本节用一个贯穿案例说明可执行做法:将旧搜索模块迁移到新实现,同时保持现有 API 兼容。四个垂直切片依次是:

  1. 兼容契约与 characterization tests。
  2. 在现有接口之后实现后端。
  3. 客户端接入与错误状态。
  4. 完成采用后的迁移清理。

先分清三层操作入口:

  • 仓库尚未固化流程时,发送一次性完整 Agent Prompt,让 Agent 按本次任务执行。
  • 长期有效的项目事实、边界和状态维护要求,写入根 AGENTS.md
  • 需要反复执行的八步流程,固化为项目级 .agents/skills/large-task-workflow/SKILL.md,任务开始时显式调用。

三者不是安全边界:它们负责提供上下文和流程约束;权限、Sandbox、人工审批、CI 和分支保护承担相应的控制职责。Hook 只能提醒或阻断明确的工具调用,不能自动推断“哪个业务切片已完成”或替 Agent 更新业务状态。状态必须由 Prompt、AGENTS.md 或 Skill 明确触发并由人检查。

Step 1:用 Bootstrap Prompt 创建 Roadmap

仓库尚未有该需求的流程文件时,先让 Agent 只读探索,再创建 docs/roadmaps/search-migration/ROADMAP.md。下面是一份可直接发送的一次性 Prompt;其中验证命令只是示例入口,必须替换为仓库真实存在并已经验证过的命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
You are the bootstrap agent for a large repository change.

Goal:
Migrate the legacy search module to a new implementation while preserving the
existing public API, response shape, error behavior, and supported client
behavior unless an approved decision says otherwise.

Scope:
1. Compatibility contract and characterization tests.
2. Backend implementation behind the existing interface.
3. Client integration and explicit loading, empty, and error states.
4. Migration cleanup only after adoption evidence and approval.

Non-goals:
- Do not redesign the public API.
- Do not change unrelated modules, dependencies, lock files, or generated files.
- Do not run production writes, deploy, push, merge, or delete user changes.

Required read-only exploration:
- Read the repository README, contribution guide, CI configuration, build files,
package or dependency manifests, existing search code, client code, tests,
migration files, and verification scripts.
- Locate the public search interface, request and response types, error mapping,
persistence boundary, client call sites, and existing test commands.
- Do not edit files during exploration.
- If a path or command cannot be verified, mark it as unknown instead of guessing.

Required output before writing:
- A file-and-symbol evidence map.
- Four independently verifiable slices with dependencies and non-goals.
- Compatibility invariants and characterization-test candidates.
- Risks, approval points, rollback points, and unresolved questions.
- Verified repository commands for focused, fast, full, integration, and
end-to-end checks, or an explicit unconfigured marker.

Approval points:
- Ask before changing a public interface or response shape.
- Ask before changing a database schema, migration, external service, or
production configuration.
- Ask before adding or upgrading a dependency or changing a lock file.
- Ask before any push, merge, deployment, deletion, or production write.

After the read-only report:
- Create only docs/roadmaps/search-migration/ROADMAP.md.
- Do not create STATE.md yet.
- Include the goal, scope, four slices, dependencies, evidence paths,
verification commands, approval points, rollback strategy, and stop conditions.
- Report the exact created file and keep all unknowns explicit.

Done when:
- The read-only evidence report is complete.
- ROADMAP.md exists and is internally consistent.
- No source, test, dependency, migration, or configuration file was edited.

推荐的需求目录仍然是独立目录;小型仓库只有一个大型需求时,可以暂时使用根级 ROADMAP.md,但不要让多个需求共享一个状态文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
project/
├── AGENTS.md
├── docs/
│ └── roadmaps/
│ └── search-migration/
│ ├── ROADMAP.md
│ ├── STATE.md
│ └── HANDOFF.md
├── .agents/
│ └── skills/
│ └── large-task-workflow/
│ └── SKILL.md
├── src/
├── tests/
└── scripts/

下面是 Agent 应生成的完整但紧凑的 Roadmap 示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# Search Module Migration Roadmap

## Goal

Replace the legacy search implementation behind the existing public API.
Existing clients must continue to receive the same successful response shape
and documented error behavior during the migration.

## Evidence Map

- Public interface: `REPLACE_WITH_VERIFIED_INTERFACE_SYMBOL` in `REPLACE_WITH_VERIFIED_PATH`
- Legacy implementation: `REPLACE_WITH_VERIFIED_SYMBOL` in `REPLACE_WITH_VERIFIED_PATH`
- Client entry point: `REPLACE_WITH_VERIFIED_SYMBOL` in `REPLACE_WITH_VERIFIED_PATH`
- Existing tests: `REPLACE_WITH_VERIFIED_TEST_PATH`
- Verified fast check: `REPLACE_WITH_VERIFIED_COMMAND`
- Verified full check: `REPLACE_WITH_VERIFIED_COMMAND`

## Slices

1. Compatibility contract and characterization tests
- Capture current request, response, status, error, ordering, and edge-case behavior.
- Write focused tests without changing the public interface.
2. Backend implementation behind the existing interface
- Implement the new search engine behind the existing adapter or interface.
- Keep old and new implementations comparable until adoption evidence exists.
3. Client integration and error states
- Switch the client through the existing API.
- Cover loading, empty, invalid-input, authorization, timeout, and server-error states.
4. Migration cleanup after adoption
- Remove obsolete paths only after approval, adoption evidence, rollback readiness,
and the integration matrix are complete.

## Dependencies

- Slice 2 depends on the contract and tests from Slice 1.
- Slice 3 depends on the stable API behavior from Slice 2.
- Slice 4 depends on adoption evidence and explicit approval.

## Compatibility Invariants

- Preserve the public method or route signature.
- Preserve successful response fields, types, and documented ordering.
- Preserve status codes and error envelope for known failures.
- Preserve authentication, authorization, timeout, and retry behavior.

## Verification Commands

- Focused: `REPLACE_WITH_VERIFIED_FOCUSED_COMMAND`
- Fast: `REPLACE_WITH_VERIFIED_FAST_COMMAND`
- Full: `REPLACE_WITH_VERIFIED_FULL_COMMAND`
- Integration: `REPLACE_WITH_VERIFIED_INTEGRATION_COMMAND`
- End-to-end: `REPLACE_WITH_VERIFIED_E2E_COMMAND`

## Approval Points

- Public interface or response change: required.
- Schema, migration, or external service change: required.
- Dependency or lock-file change: required.
- Production write, deployment, push, or merge: required.

## Rollback

- Keep each slice in a separate branch or worktree.
- Revert to the latest verified checkpoint after confirming the checkpoint and
working-tree state; do not rewrite history or remove user changes.

## Stop Conditions

- A compatibility test contradicts the proposed behavior.
- A required command is unknown or fails for an unexplained reason.
- Two tasks need to edit the same shared file or public interface.
- A migration, dependency, production, or external write needs approval.

完成标志:只读证据已列出、Roadmap 文件已创建、四个切片依赖明确,并且 Agent 没有编辑实现代码。

Step 2:创建 STATE 并固化维护触发器

让 Agent 根据 Roadmap 创建 docs/roadmaps/search-migration/STATE.md。状态文件只记录已经由代码、测试或命令验证的事实;假设、待决定事项和跳过的检查必须明确标记。已有的路径约定仍然适用:每个大型需求使用 docs/roadmaps/<feature>/ROADMAP.md 与同目录 STATE.md,不要堆到一个不断膨胀的根文件。

1
2
3
4
5
Create docs/roadmaps/search-migration/STATE.md from ROADMAP.md.
Read ROADMAP.md, the current branch, and the current worktree first.
Do not edit source, tests, dependency files, migrations, or configuration.
Use only verified facts. Mark assumptions as assumptions and preserve unknowns.
After creating the file, report its path and the evidence used.

完整的 STATE.md 示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# Search Migration State

## Verified

- Roadmap exists at `docs/roadmaps/search-migration/ROADMAP.md`.
- Public interface is `REPLACE_WITH_VERIFIED_SYMBOL` in `REPLACE_WITH_VERIFIED_PATH`.
- Characterization test command is `REPLACE_WITH_VERIFIED_COMMAND`.
- Last verified checkpoint: `REPLACE_WITH_VERIFIED_COMMIT`.
- Last verification result: `REPLACE_WITH_VERIFIED_COMMAND` exited with `0`.

## Decisions

- Preserve the existing public API and response envelope.
- Keep the legacy implementation available until adoption is verified.
- Do not change schema, dependencies, or lock files without approval.

## Open Questions

- [ ] Confirm the adoption threshold and observation window.
- [ ] Confirm whether the timeout behavior is part of the supported contract.

## Current Slice

- Name: Compatibility contract and characterization tests
- Status: planned
- Branch: `REPLACE_WITH_BRANCH`
- Worktree: `REPLACE_WITH_WORKTREE`
- Allowed files: `REPLACE_WITH_VERIFIED_PATHS`
- Last action: `REPLACE_WITH_VERIFIED_ACTION`

## Next Slice

- Name: Backend implementation behind the existing interface
- Entry condition: Slice 1 has a verified checkpoint and reviewed contract tests.

## Blocked

- None.

## Verification Log

- Command: `REPLACE_WITH_VERIFIED_COMMAND`
- Exit status: `0`
- Result: `REPLACE_WITH_VERIFIED_RESULT`
- Skipped: `REPLACE_WITH_CHECK`
- Reason: `REPLACE_WITH_REASON`

可直接追加到根 AGENTS.md 的英文片段如下。它只规定维护触发器,不声称 Agent 会自动维护状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
## Large Task State Maintenance

- For a large task, read `docs/roadmaps/<feature>/ROADMAP.md` and
`docs/roadmaps/<feature>/STATE.md` before editing.
- After every slice has been verified, update `STATE.md` with the verified
checkpoint, commands, exit statuses, changed scope, skipped checks, risks,
current slice, and next slice.
- Before ending a session, update `STATE.md` and create or update
`docs/roadmaps/<feature>/HANDOFF.md`.
- Do not claim that state is current unless the relevant files, branch, worktree,
and verification commands were checked in this session.
- Prompt, Skill, or explicit task instructions must trigger these updates;
agents must not assume that state files are maintained automatically.

在同一个 Step 内固化项目级 Skill,可让后续任务复用八步流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
---
name: large-task-workflow
description: Execute a tracked eight-step workflow for large changes across slices and sessions.
---

# Large Task Workflow

## Trigger

Use when a task spans multiple modules, sessions, agents, branches, worktrees,
or a compatibility-sensitive migration.

## Required inputs

- User-visible goal, scope, non-goals, and approval points.
- Existing repository facts and verified commands.
- Roadmap path and state path, or permission to create them.
- Named slice, allowed files, dependencies, and rollback checkpoint.

## Required workflow

1. Read-only exploration and Roadmap creation.
2. State creation and explicit state-maintenance trigger.
3. Clean baseline, verification, commit recording, and isolated worktree.
4. Read-only and non-overlapping implementation delegation.
5. Explore, Plan, Implement, Verify, and Review for one slice.
6. Cross-slice integration matrix and evidence log.
7. Handoff creation and fresh-session revalidation.
8. Stop, recover, or continue only from a verified checkpoint.

## Required artifacts

- `docs/roadmaps/<feature>/ROADMAP.md`
- `docs/roadmaps/<feature>/STATE.md`
- `docs/roadmaps/<feature>/HANDOFF.md`
- Commands, exit statuses, skipped checks, risks, and review outcomes.

## Boundaries

- Read `AGENTS.md` and the roadmap state before editing.
- Do not guess commands, paths, business status, or compatibility facts.
- Do not parallelize edits to a public interface, migration, lock file, or
shared source file.
- Do not push, merge, deploy, delete user changes, rewrite history, or perform
production writes without explicit approval.
- Do not use `git reset --hard` or `git clean`.
- Do not treat this Skill, a Prompt, an instruction file, or a Hook as a
security boundary.

## Verification and handoff

- Record actual commands and exit statuses.
- A checkpoint is verified only after required verification exits `0` and Review
passes.
- Before ending a session, update `STATE.md` and write `HANDOFF.md`.
- A new session must revalidate the checkpoint, worktree, and key facts before
editing.

## Recovery

- Stop on unexplained failures, contradictory contract evidence, scope overlap,
or missing approval.
- Find the latest verified checkpoint using read-only Git commands.
- Create a new worktree from that checkpoint and continue with a new Prompt.

之后用精简任务 Prompt 调用该 Skill:

1
2
3
4
5
Use the project skill large-task-workflow for the search migration.
Read AGENTS.md, ROADMAP.md, and STATE.md first. Work only on the named slice,
record actual commands and exit statuses, update state after verification and
before session end, and stop for approval or scope overlap. Do not push, merge,
deploy, delete user changes, use git reset --hard, or use git clean.

完成标志:STATE.md 的固定字段齐全,根指引明确写出维护时机,Skill 模板包含输入、产物、验证、交接、恢复和边界,且没有把它们描述成安全边界。

Step 3:记录只读基线并创建切片 worktree

先在当前工作区确认没有未提交修改;若存在用户修改,暂停并确认边界,不要用清理或重置命令覆盖它们。基线验证必须发生在创建切片 worktree 之前:

1
2
3
4
5
git status --short
git diff --check
BASELINE_COMMIT="$(git rev-parse HEAD)"
printf 'Baseline commit: %s\n' "$BASELINE_COMMIT"
REPLACE_WITH_VERIFIED_FAST_COMMAND

如果仓库已经验证过这些脚本,可用下面入口;它们只是已由仓库验证的示例,实际使用前仍要替换为真实命令:

1
2
./scripts/verify-fast.sh
./scripts/verify.sh

运行后记录每条命令的实际退出状态、旧失败、耗时和环境要求。然后从记录的基线创建第一个切片 worktree:

1
2
3
git worktree add ../search-migration-slice-1 -b feat/search-migration-slice-1 "$BASELINE_COMMIT"
git -C ../search-migration-slice-1 status --short
git -C ../search-migration-slice-1 rev-parse HEAD

BASELINE_COMMIT、分支、worktree 路径、允许修改的文件和基线结果写入 STATE.md。不要使用 git reset --hardgit clean,不要删除或覆盖用户更改;也不要要求 Agent 自行 push 或 merge。

完成标志:原工作区边界已确认、基线 Commit 已记录、验证结果可区分旧失败与新回归,且切片 worktree 的初始 Commit 与基线一致。

Step 4:用明确契约分派 Subagent

先用只读 Subagent 建立证据,再分派无重叠范围的实现 Subagent。两份完整英文 Prompt 如下;路径和命令必须由仓库事实替换。

只读调查 Subagent:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
You are a read-only investigation subagent for Slice 1 of the search migration.

Task:
Map the existing public search contract and identify characterization tests
needed before replacing the legacy implementation.

Read only:
- AGENTS.md
- docs/roadmaps/search-migration/ROADMAP.md
- docs/roadmaps/search-migration/STATE.md
- The verified public search interface and its implementation
- Existing search tests and client call sites
- Relevant README, CI, build, dependency, and verification files

Write scope:
None. Do not edit, create, delete, format, or generate files.

Investigate:
- Request method, path or method signature, headers, parameters, and defaults.
- Success response fields, types, ordering, pagination, and empty results.
- Status codes and error envelope for invalid input, unauthorized access,
timeout, unavailable backend, and unexpected failure.
- Authentication, authorization, retry, idempotency, and persistence boundaries.
- Existing test coverage, test fixtures, generated files, migrations, and
shared files that must not be changed in parallel.

Output:
1. A table of claims with evidence paths and symbols.
2. A characterization-test list with expected current behavior.
3. Unknowns and assumptions, clearly labeled.
4. Risks, approval points, and a recommended non-breaking test plan.
5. Verified commands and their exit statuses if you run any read-only checks.

Constraints:
- Do not infer business behavior from names alone.
- Do not modify public interfaces, migrations, dependencies, lock files, or
shared source files.
- Do not push, merge, deploy, or perform external writes.
- Stop if a required fact cannot be verified.

无重叠范围实现 Subagent:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
You are an implementation subagent for the named search migration slice.

Preconditions:
- Read AGENTS.md, ROADMAP.md, STATE.md, and the approved investigation report.
- Confirm the current branch and worktree.
- Confirm the exact allowed files below and stop if they are already modified.

Slice:
Compatibility contract and characterization tests only.

Allowed write scope:
- REPLACE_WITH_VERIFIED_TEST_FILE
- REPLACE_WITH_VERIFIED_TEST_FIXTURE_FILE
- REPLACE_WITH_VERIFIED_ROADMAP_OR_STATE_UPDATE_IF_REQUESTED

Forbidden write scope:
- Public interfaces, routes, request or response types.
- Legacy or new implementation code.
- Client code.
- Database migrations or schema files.
- Dependency manifests and lock files.
- Generated files and shared configuration.
- Any file outside the allowed write scope.

Implementation requirements:
- Capture current behavior, including documented edge cases and known behavior
that must remain compatible during migration.
- Make tests deterministic and focused.
- Do not “fix” production behavior in this slice.
- If actual behavior contradicts the Roadmap, stop and report evidence.

Verification:
- Run the verified focused test command.
- Run the verified fast command if this slice permits it.
- Record exact commands, exit statuses, skipped checks, and remaining risks.

Review handoff:
- Report changed files, test names, behavior captured, and evidence paths.
- Do not commit, push, merge, deploy, or change shared files.
- Stop after producing the implementation diff and verification report.

Subagent 可以并行做只读调查,但不能并行修改公共接口、迁移文件、锁文件或同一源文件。若两个切片都需要共享文件,改为串行并在 STATE.md 记录前置接口和占用范围。

完成标志:调查报告每个结论都有证据,实施任务的读写范围不重叠,所有共享文件冲突已被改为串行安排。

Step 5:对每个切片重复执行开发闭环

四个切片都必须独立执行 Explore → Plan → Implement → Verify → Review。下面先完整演示 Slice 1,再给出 Slice 2、3、4 的执行卡片。所有允许修改的路径和验证命令,都必须来自 ROADMAP.md、只读探索报告或仓库事实;不要把示例占位符替换成猜测。统一状态流为:
planned → exploring → ready-for-implementation → implementing → verified-pending-review → verified
任何失败或证据不足都进入 blockedneeds-fix,不得跳过状态。恢复只有两条转换路径:blocked → exploringneeds-fix → ready-for-implementation。它们不是正常流的捷径,必须满足下列条件:

  • blocked → exploring:仅当缺失事实、依赖或所需人工审批已经获得;恢复前重新只读验证相关事实。
  • needs-fix → ready-for-implementation:仅当失败原因、允许修复范围和修订计划已经人工确认;不能直接回到 implementing
  • 每次恢复都必须在 STATE.md 记录触发证据、人工负责人或批准者、原状态、目标状态、时间、重新验证命令及结果。
  • 如果前置条件不满足,保持原状态并停止编辑。

Slice 1:兼容契约与 characterization tests

目标是记录旧搜索模块当前可观察行为,而不是提前修复它。开始时将 STATE.mdplanned 更新为 exploring

Explore:

1
2
3
4
5
Read AGENTS.md, ROADMAP.md, STATE.md, and the read-only investigation report.
Explore only the legacy search interface, implementation, client call sites,
fixtures, and existing tests. Do not edit files.
Return an evidence map, compatibility invariants, test candidates, forbidden
files, verified commands, and unresolved questions.

产物是调查报告;调查完成后状态迁移为 ready-for-implementation。若找不到真实接口或测试入口,保持 blocked,不要开始编辑。

Plan:

1
2
3
4
5
Create a file-level implementation plan for Slice 1 only.
The plan must list each allowed file, each characterization behavior, test data,
expected current result, verification command, and rollback point.
Do not change source files, public interfaces, migrations, dependencies, lock
files, or client code. Ask for approval if the plan requires any forbidden file.

产物是经人工确认的文件级计划和测试矩阵;状态保持 ready-for-implementation,直到人工确认可以实现。计划必须明确“不改变当前业务行为”。

Implement:

1
2
3
4
5
6
Implement only the approved Slice 1 plan.
Add deterministic characterization tests for the verified current search
contract. Keep production code, public interfaces, migrations, dependency
manifests, lock files, client files, generated files, and shared configuration
unchanged. After editing, show the diff and stop before any commit, push, or
merge.

产物是测试 diff;开始编辑时状态迁移为 implementing。如果测试暴露了需要修复生产代码的问题,记录为新问题并暂停,不要扩大切片。

Verify:

1
2
3
4
git diff --check
REPLACE_WITH_VERIFIED_FOCUSED_TEST_COMMAND
REPLACE_WITH_VERIFIED_FAST_COMMAND
git status --short

只有当聚焦验证和要求的快速验证都实际执行且退出状态为 0,才能将状态写为 verified-pending-review。若使用仓库已验证的示例入口,可写成:

1
./scripts/verify-fast.sh

但必须提醒读者替换为真实命令,不能把示例入口的存在当作本仓库已验证。验证产物包含实际命令、退出状态、未运行项及原因、测试报告和完整 diff。

Review:

1
2
3
4
5
6
Review the complete diff for Slice 1 against ROADMAP.md, STATE.md, the approved
plan, and the compatibility evidence.
Check scope, test fidelity, determinism, public API preservation, forbidden
file changes, generated-file rules, dependency changes, and verification
evidence. Return PASS or FAIL with file-and-symbol findings.
Do not edit files, commit, push, merge, or deploy.

只有两个条件同时满足,才可以建立并记录 verified checkpoint:验证命令退出状态为 0,并且 Review 明确通过。记录 Commit 时不要让 Agent 自行 push 或 merge:

1
2
3
The human owner will create the checkpoint after verification and review pass.
Update STATE.md with the checkpoint only after the owner provides its commit
identifier. Do not create a remote branch, push, merge, or deploy.

状态迁移应可追踪:planned → exploring → ready-for-implementation → implementing → verified-pending-review → verified;失败则迁移到 blockedneeds-fix,并记录证据,而不是伪造绿色状态。

完成标志:第一个切片的测试只覆盖已证实的旧行为,聚焦与要求的快速验证均退出 0,完整 diff Review 通过,人工创建的 Commit 已写入 STATE.md 并标为 verified checkpoint。

Slice 2:现有接口后的后端实现

  • 目标:在已验证的现有搜索接口之后接入新实现,保持 legacy 实现可回退、可对比,且不改变 API 契约。
  • 允许修改范围如何确定:只读探索现有接口、adapter、legacy 实现、新实现入口、测试 fixture 和配置加载路径;把实际符号与文件写入计划,只有计划中的路径才能写入。若需要公共接口、迁移、依赖或锁文件,先停下请求审批。
  • 禁止范围:公共 route、request/response 类型、客户端调用、数据库迁移、依赖清单、锁文件、生成文件和未列入计划的共享文件。
  • 专属 Agent Prompt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Implement Slice 2 of the search migration behind the existing public interface.
Read AGENTS.md, ROADMAP.md, STATE.md, and the approved Slice 2 exploration and
plan first. Use only the implementation and test paths explicitly verified in
those artifacts; replace no path or command from guesswork.

Keep the legacy implementation available for fallback and side-by-side
comparison. Preserve the existing request, response, status-code, error
mapping, authentication, timeout, retry, and ordering behavior.

Before editing, confirm the allowed files and stop on scope overlap. Do not
modify public interfaces, client code, migrations, dependency manifests, lock
files, generated files, or shared configuration unless separately approved.
Add focused tests for equivalent results, error mapping, concurrent requests,
fallback behavior, and the performance threshold recorded in the plan.
Run only the verified focused commands, report exact exit statuses, and stop
before commit, push, merge, deploy, or production writes.
  • 聚焦验证要求:运行 Roadmap 中已验证的 backend focused command;至少覆盖结果等价、错误映射、并发安全、legacy 回退/对比和按需性能基线。每条命令记录实际退出状态。
  • Review 重点:接口兼容性、并发共享状态、错误边界、legacy 回退是否真实可用、性能回归、配置差异和越界文件。
  • 完成标志:新实现可通过现有接口访问,legacy 仍可回退或对比,聚焦验证退出 0,Review 通过,并将人工提供的 Commit 记录为 verified
  • 额外审批点:改变接口或错误格式、删除 legacy、修改 schema/迁移、增加依赖或锁文件、改变生产配置,均需单独审批。

Slice 3:客户端接入与错误状态

  • 目标:客户端通过现有 API 接入新后端,并明确处理加载、空结果、错误、权限和超时状态。
  • 允许修改范围如何确定:只读探索现有 API client、搜索页面或调用组件、状态管理、类型、测试 fixture 和 UI 测试入口;只把探索报告确认的客户端文件加入计划。UI 证据按仓库能力和需求风险决定是否需要。
  • 禁止范围:后端公共接口、服务端迁移、依赖和锁文件、无关页面、生成文件、未批准的 API 类型变更及其他切片正在使用的源文件。
  • 专属 Agent Prompt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Implement Slice 3 of the search migration through the existing API.
Read AGENTS.md, ROADMAP.md, STATE.md, and the approved Slice 3 exploration and
plan. Use only verified client paths, symbols, fixtures, and commands from
those artifacts.

Connect the client without changing the public API. Implement and test loading,
empty, server-error, authorization-error, invalid-input, and timeout states.
Preserve existing successful data rendering, request cancellation, retry, and
accessibility behavior where verified.

Write only the approved client and client-test files. Do not edit backend
interfaces, migrations, dependency manifests, lock files, generated files,
unrelated screens, or shared files outside the plan. If visual evidence is
required, capture the approved user path, states, viewport, console, network,
and accessibility evidence. Run verified focused checks and report commands
and exit statuses. Do not commit, push, merge, deploy, or perform external
writes.
  • 聚焦验证要求:运行已验证的 client focused command;覆盖上述五类状态、请求参数和成功响应兼容性。需要 UI 证据时按计划检查桌面/移动视口、键盘焦点、控制台和网络请求。
  • Review 重点:现有 API 是否仍被使用、错误状态是否可恢复、权限/超时是否泄露信息、加载与空状态是否误报成功、无障碍和越界范围。
  • 完成标志:客户端通过现有 API 正确渲染成功和全部必需状态,聚焦验证退出 0,所需 UI 证据齐全,Review 通过并记录 verified checkpoint。
  • 额外审批点:公共 API 或客户端类型变化、共享状态重构、依赖/锁文件变化、遥测或外部服务写入,需单独审批。

Slice 4:采用后的迁移清理

  • 目标:在新实现完成采用并有证据后,清理 legacy 路径、临时适配层和不再需要的迁移材料。
  • 允许修改范围如何确定:只读探索采用开关、流量/调用证据、legacy 引用、迁移文件、恢复脚本、锁文件和公共接口引用;把实际删除或修改路径、恢复步骤和审批记录写入计划。没有采用证据时允许范围为空。
  • 禁止范围:未经审批的删除、破坏性迁移、公共接口移除、锁文件变化、生产配置变更、数据库生产写入、无关清理和覆盖现有 worktree。
  • 专属 Agent Prompt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Prepare Slice 4 cleanup for the search migration only after adoption evidence
and explicit human approval are present in STATE.md.

Read AGENTS.md, ROADMAP.md, STATE.md, HANDOFF.md, the adoption evidence, and
the approved cleanup plan. Reconfirm every cleanup path from repository facts.
If adoption evidence, rollback evidence, or approval is missing, stop without
editing and report the missing item.

Before editing, list the exact legacy files, migration files, lock-file changes,
and public-interface references in scope. Preserve a tested rollback or restore
path. Treat deletion, schema or data migration, lock-file modification, and
public-interface change as separate approval points; do not bundle them into
implicit approval.

After approval, make only the approved cleanup changes. Run the verified
focused cleanup, compatibility, migration-order, rollback, and recovery checks.
Report actual commands, exit statuses, skipped checks, and evidence. Do not
push, merge, deploy, or perform production writes.
  • 聚焦验证要求:验证采用阈值与 observation window、旧引用已清理、新旧版本兼容窗口、迁移顺序、回滚/恢复演练和按需锁文件重现性;每项写入实际命令与退出状态。
  • Review 重点:删除是否有证据、迁移是否向前/向后兼容、恢复是否可执行、公共 API 是否仍兼容、锁文件和生成文件是否被意外改变。
  • 完成标志:采用证据、人工审批、回滚/恢复证据和验证矩阵齐全,所有要求的聚焦验证退出 0,Review 通过后才标记 verified。
  • 额外审批点:任何删除、迁移、锁文件修改、公共接口变化、生产配置变化或外部写入都必须逐项审批;未批准时保持 blocked

每张卡都遵守同一门槛:只读探索决定实际写入范围,验证和 Review 未通过不能记录 verified checkpoint;任何切片失败都更新 STATE.md,并把下一动作留在 blockedneeds-fix

Step 6:用集成矩阵验证四个切片

切片分别通过后,不能只看单元测试;要把实际命令、退出状态、跳过原因和风险写入 Roadmap 或 STATE.md。下面是一份完整矩阵,按仓库真实能力填写;没有该能力时写 skipped 及原因,不写成 passed

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# Search Migration Integration Verification Matrix

## API compatibility

- Contract test command: `REPLACE_WITH_VERIFIED_COMMAND`
- Exit status: `REPLACE_WITH_STATUS`
- Existing method, route, headers, parameters: `pass/fail/unknown`
- Success response shape and field types: `pass/fail/unknown`
- Empty result and ordering behavior: `pass/fail/unknown`
- Invalid input and error envelope: `pass/fail/unknown`
- Authentication and authorization behavior: `pass/fail/unknown`
- Timeout, retry, and idempotency behavior: `pass/fail/unknown`
- Uncovered compatibility behavior: `REPLACE_WITH_FACTS`

## Data and migration order

- Expand or compatibility preparation: `REPLACE_WITH_COMMAND_OR_SKIPPED`
- Exit status: `REPLACE_WITH_STATUS_OR_NOT_RUN`
- Backward-compatible application order: `pass/fail/unknown`
- New and old implementation coexistence: `pass/fail/unknown`
- Data validation query or test: `REPLACE_WITH_VERIFIED_COMMAND`
- Rollback or restore rehearsal: `REPLACE_WITH_COMMAND_OR_SKIPPED`
- Skip reason and owner: `REPLACE_WITH_REASON`

## Configuration

- Configuration keys and defaults compared: `pass/fail/unknown`
- Feature flag or adapter selection tested: `pass/fail/unknown`
- Environment-specific behavior checked: `pass/fail/unknown`
- Secret names and access paths unchanged: `pass/fail/unknown`
- Configuration validation command: `REPLACE_WITH_VERIFIED_COMMAND`
- Exit status: `REPLACE_WITH_STATUS`

## Dependencies and lock files

- Dependency manifest diff reviewed: `pass/fail`
- Lock file changed: `yes/no`
- Lock file change approved: `yes/no/not_applicable`
- Reproducible install command: `REPLACE_WITH_VERIFIED_COMMAND`
- License or vulnerability check: `REPLACE_WITH_COMMAND_OR_SKIPPED`
- Skip reason and risk: `REPLACE_WITH_REASON_AND_RISK`

## End-to-end

- E2E command: `REPLACE_WITH_VERIFIED_COMMAND`
- Exit status: `REPLACE_WITH_STATUS`
- Existing client request reaches the new implementation: `pass/fail/unknown`
- Loading state: `pass/fail/unknown/not_applicable`
- Empty state: `pass/fail/unknown/not_applicable`
- Invalid-input and authorization errors: `pass/fail/unknown`
- Timeout and server-error recovery: `pass/fail/unknown`
- Skip reason and risk: `REPLACE_WITH_REASON_AND_RISK`

## Security and performance, as needed

- Authorization and tenant isolation: `pass/fail/unknown/not_applicable`
- Input validation and injection checks: `pass/fail/unknown/not_applicable`
- Sensitive data exposure review: `pass/fail/unknown/not_applicable`
- Baseline latency command: `REPLACE_WITH_COMMAND_OR_SKIPPED`
- New latency comparison: `REPLACE_WITH_RESULT`
- Load or concurrency command: `REPLACE_WITH_COMMAND_OR_SKIPPED`
- Skip reason, threshold, and risk: `REPLACE_WITH_REASON_AND_RISK`

## Common evidence

- Full verification command: `REPLACE_WITH_VERIFIED_COMMAND`
- Exit status: `REPLACE_WITH_STATUS`
- Build command: `REPLACE_WITH_VERIFIED_COMMAND`
- Exit status: `REPLACE_WITH_STATUS`
- Skipped checks: `REPLACE_WITH_CHECKS_AND_REASONS`
- Remaining risks: `REPLACE_WITH_RISKS`
- Human approval required for cleanup: `yes/no`

迁移清理必须等到 API 兼容、数据顺序、配置、锁文件、E2E 以及按需的安全和性能检查都有证据;否则第四切片保持未完成。完成标志:矩阵每一项都有 passfailunknown 或带原因的 skipped,没有用一次构建成功替代其他证据。

Step 7:生成 HANDOFF 并启动新会话

会话结束前让 Agent 创建 docs/roadmaps/search-migration/HANDOFF.md,同时更新 STATE.md。完整模板如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# Search Migration Handoff

## Goal

Migrate the legacy search module while preserving the existing public API.

## Current slice

- Name: `REPLACE_WITH_SLICE`
- Status: `planned/exploring/ready-for-implementation/implementing/verified-pending-review/verified/blocked/needs-fix`
- User-visible result: `REPLACE_WITH_RESULT`

## Repository state

- Branch: `REPLACE_WITH_BRANCH`
- Worktree: `REPLACE_WITH_WORKTREE`
- Base commit: `REPLACE_WITH_BASELINE_COMMIT`
- Last verified checkpoint: `REPLACE_WITH_COMMIT`
- Working tree status result: `REPLACE_WITH_STATUS_OUTPUT`

## Verified evidence

- Command: `REPLACE_WITH_COMMAND`
- Exit status: `0`
- Result: `REPLACE_WITH_RESULT`
- Review: `pass/fail`
- Review evidence: `REPLACE_WITH_PATH_OR_SUMMARY`

## Changed scope

- `REPLACE_WITH_PATH`: `REPLACE_WITH_REASON`

## Not verified

- Check: `REPLACE_WITH_CHECK`
- Reason: `REPLACE_WITH_REASON`
- Risk and owner: `REPLACE_WITH_RISK_AND_OWNER`

## Decisions and open questions

- Decision: `REPLACE_WITH_DECISION`
- Open question: `REPLACE_WITH_QUESTION`

## Next safe action

`REPLACE_WITH_READ_ONLY_OR_APPROVED_COMMAND`

## Boundaries

- Do not push, merge, deploy, delete user changes, rewrite history, use
`git reset --hard`, or use `git clean`.
- Ask before changing public interfaces, migrations, dependencies, lock files,
production configuration, or external systems.

新会话用下面的 Prompt 启动。它要求重新验证 Commit、工作区和关键事实,不能盲信旧摘要:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Resume the search migration from the handoff.

Before editing:
1. Read AGENTS.md, ROADMAP.md, STATE.md, and HANDOFF.md.
2. Confirm the current branch and worktree.
3. Confirm the working-tree status without changing it.
4. Re-verify that the last checkpoint exists and inspect its diff.
5. Re-run the key verification command recorded in the handoff.
6. Re-check the public search interface, current slice, and next-slice
preconditions against repository files.

If any fact, command, checkpoint, or worktree differs from the handoff, stop and
report the discrepancy. Otherwise continue only with the named next slice and
its allowed files. Record actual commands and exit statuses, update STATE.md
after verification, and update HANDOFF.md before ending.

Do not push, merge, deploy, delete user changes, rewrite history, use
git reset --hard, or use git clean.

完成标志:新会话入口、最近验证 Commit、工作区状态和下一切片前置条件都写入 handoff,并且启动 Prompt 明确要求先重新验证。

Step 8:定义停止条件并从 checkpoint 恢复

遇到以下任一情况立即停止编辑,并把失败证据写入 STATE.md 或 handoff:兼容契约与实现矛盾;验证命令非零且原因不明;两个任务需要修改同一共享文件;出现未批准的 API、迁移、依赖、锁文件或外部写入;Agent 重复尝试却没有新证据;状态文件与仓库事实不一致。停止不是失败,它能防止把不确定性扩散到后续切片。

恢复状态前先按唯一转换规则判断:

  1. 对于 blocked → exploring,人工确认缺失事实、依赖或审批已获得;然后只读重新验证相关文件、版本、权限或批准记录。任一项不成立,就保持 blocked 并停止编辑。
  2. 对于 needs-fix → ready-for-implementation,人工确认失败原因、允许修复文件范围和修订计划;然后只读重新验证修订计划与当前 diff。任一项不成立,就保持 needs-fix 并停止编辑。修复完成后仍须经过 implementing → verified-pending-review → verified,不能从 needs-fix 直接进入 implementing
  3. 每次允许恢复时,在 STATE.md 追加一条记录。记录不完整时,恢复转换无效:
1
2
3
4
5
6
7
8
9
10
11
12
## Recovery Transition

- Trigger evidence: `REPLACE_WITH_FAILURE_EVIDENCE_OR_APPROVAL_RECORD`
- Human owner: `REPLACE_WITH_NAME_OR_ROLE`
- Approver: `REPLACE_WITH_NAME_OR_ROLE_OR_NOT_REQUIRED`
- Original status: `blocked/needs-fix`
- Target status: `exploring/ready-for-implementation`
- Time: `REPLACE_WITH_TIMESTAMP`
- Revalidation command: `REPLACE_WITH_READ_ONLY_VERIFIED_COMMAND`
- Revalidation exit status: `REPLACE_WITH_STATUS`
- Revalidation result: `REPLACE_WITH_RESULT`
- Scope and plan confirmed: `REPLACE_WITH_PATHS_AND_PLAN`

从明确的 verified checkpoint 创建恢复 worktree 由人工执行,先确认目标路径不存在且不覆盖现有 worktree:

1
2
3
4
5
6
VERIFIED_COMMIT="REPLACE_WITH_VERIFIED_COMMIT"
RECOVERY_BRANCH="REPLACE_WITH_RECOVERY_BRANCH"
RECOVERY_WORKTREE="REPLACE_WITH_RECOVERY_WORKTREE"
git worktree add "$RECOVERY_WORKTREE" -b "$RECOVERY_BRANCH" "$VERIFIED_COMMIT"
git -C "$RECOVERY_WORKTREE" rev-parse HEAD
git -C "$RECOVERY_WORKTREE" status --short

将实际 Commit、分支、路径、rev-parse HEAD 输出和 status --short 结果写入 STATE.mdHANDOFF.md。如果目标 worktree 或分支已存在,停止并请求人工决定;不要覆盖现有 worktree,不要使用 git reset --hardgit clean

查找最近 verified checkpoint 时只使用只读命令:

1
2
3
4
5
6
git log --all --decorate --oneline -- docs/roadmaps/search-migration
git log --all --format='%H %s' --grep='verified checkpoint'
git show --stat --oneline REPLACE_WITH_CANDIDATE_COMMIT
git diff REPLACE_WITH_BASELINE_COMMIT..REPLACE_WITH_CANDIDATE_COMMIT --check
git worktree list
git status --short

候选 Commit 只有在 STATE.md 中有对应验证命令、退出状态为 0、Review 通过且范围匹配时,才能标记为 verified checkpoint。失败证据应使用如下格式,避免把失败覆盖掉:

1
2
3
4
5
6
7
8
9
10
11
12
## Failure Evidence

- Time: `REPLACE_WITH_TIMESTAMP`
- Slice: `REPLACE_WITH_SLICE`
- Command: `REPLACE_WITH_COMMAND`
- Exit status: `REPLACE_WITH_NONZERO_STATUS`
- Observed output: `REPLACE_WITH_SHORT_NON_SECRET_OUTPUT`
- Expected behavior: `REPLACE_WITH_EXPECTATION`
- Suspected cause: `hypothesis only; not verified`
- Files changed before stop: `REPLACE_WITH_PATHS`
- Decision needed: `REPLACE_WITH_HUMAN_DECISION`
- Next safe action: `REPLACE_WITH_READ_ONLY_ACTION`

从 checkpoint 恢复时创建新的 worktree,不覆盖当前工作区:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
The previous search migration attempt is blocked or needs a fix.
Read AGENTS.md, ROADMAP.md, STATE.md, HANDOFF.md, and the failure evidence.
Determine the current status from STATE.md before taking any action.
If the status is blocked, resume only through blocked -> exploring after the
missing fact, dependency, or human approval is present and related facts have
been revalidated read-only. If the status is needs-fix, resume only through
needs-fix -> ready-for-implementation after the failure cause, allowed fix
scope, and revised plan have been confirmed by a human. Never transition
needs-fix directly to implementing.
Record the recovery transition in STATE.md with trigger evidence, human owner,
approver, original status, target status, time, revalidation command, exit
status, and result. If any precondition is missing, preserve the original
status and stop editing.
Use only the latest checkpoint explicitly marked verified in STATE.md.
The human owner will create a new worktree from that checkpoint; do not rewrite
history or modify the existing worktree.
In the new worktree, verify the checkpoint, branch, working-tree status, public
search contract, and recorded verification command before editing.
Continue only with the named slice and approved files. Preserve the existing API.
Record the failed evidence, new commands, exit statuses, review result, and
state transitions. Do not use git reset --hard or git clean, and do not push,
merge, deploy, delete user changes, or perform external writes.

完成标志:停止原因和失败证据可复现,恢复点是最近明确验证的 checkpoint,新 worktree 已重新验证,且没有使用 git reset --hardgit clean

9. 场景六:UI、API、数据与基础设施的差异化验证

大型迁移或搜索功能变更不能用“一次构建成功”证明交付安全。本场景继续使用 Search App:React + TypeScript UI 调用 FastAPI API,API 访问 PostgreSQL,Schema 由 Alembic 管理,运行环境由 Terraform 和 Kubernetes 描述。目标是把每一层的可观察结果汇总成同一份 evidence 和可审计交付报告;全程只使用批准的测试环境,不执行生产写入。

本节只补充跨层验证方法。仓库真实入口、脚本和版本必须先按场景一的只读探索确认;大型需求的 STATE.mdHANDOFF.md 和变更边界按场景五复用,不在本节重新发明一套状态文件。凡是尚未从仓库确认的命令,一律保留 TO_BE_VERIFIED_FROM_REPOSITORY,探索并实际执行后才可写入证据。

Step 1:用 Change Classification Prompt 识别变更类型和风险

先读取只读 diff、变更计划和公开契约,再分类 UI、API、数据库和基础设施影响面。分类结果至少要包含风险等级、目标环境、required checks、负责人和 approval gates;不能因为某一层改动很小,就跳过被它间接影响的层。

实际操作:

  1. 确认基线 Commit、当前变更范围和场景五中的 STATE.md/HANDOFF.md
  2. 只读查看 React 路由与组件、FastAPI route/dependency、Alembic revisions、Terraform modules 和 Kubernetes manifests。
  3. 记录用户可观察结果、兼容性窗口、数据风险、权限变化、外部写入风险和停止条件。
  4. 生成 artifacts/verification/<change-id>/classification.md。如果 artifacts/.gitignore 忽略,不能强行修改忽略规则;改用受控的外部 evidence 存储,并在报告中记录索引、访问控制、保留期限和不可变性证明。

Agent Prompt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
You are classifying a Search App change for read-only verification.

Read only:
- The current diff and merge plan.
- The verified public API contract.
- The repository map, real scripts, and environment documentation.
- The large-task STATE.md and HANDOFF.md when present.
- React and TypeScript UI paths.
- FastAPI routes, dependencies, schemas, and tests.
- PostgreSQL and Alembic migration paths.
- Terraform and Kubernetes paths.

Do not edit source files, tests, migrations, infrastructure state, or external
systems. Do not run production commands or print secrets.

Classify the change as UI, API, database, infrastructure, or a combination.
For every affected domain, report observable acceptance criteria, failure impact,
environment prerequisites, required checks, owner, approval gate, rollback
compatibility, read-only actions, forbidden writes, and unknowns.
Use TO_BE_VERIFIED_FROM_REPOSITORY for every unverified path or command.
Write only the requested classification report to:
artifacts/verification/<change-id>/classification.md
If artifacts is ignored, report the controlled external evidence index strategy
instead of changing ignore rules.

Agent 产物:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# Change Classification

- Change ID: REPLACE_WITH_CHANGE_ID
- Baseline commit: REPLACE_WITH_COMMIT
- Candidate commit: REPLACE_WITH_COMMIT
- Scope source: diff, plan, contract, STATE.md, HANDOFF.md
- Target environment: REPLACE_WITH_APPROVED_NON_PRODUCTION_ENVIRONMENT

## Domains

### UI
- Affected paths:
- Observable acceptance:
- Risk:
- Required checks:
- Owner:
- Approval gate:

### API
- Affected paths:
- Observable acceptance:
- Risk:
- Required checks:
- Owner:
- Approval gate:

### Database
- Affected paths:
- Observable acceptance:
- Risk:
- Required checks:
- Owner:
- Approval gate:

### Infrastructure
- Affected paths:
- Observable acceptance:
- Risk:
- Required checks:
- Owner:
- Approval gate:

## Boundaries

- Read-only actions:
- Forbidden writes:
- Unknowns:
- Stop conditions:

人工审批点:变更负责人确认分类完整、环境为批准的非生产环境、每个 domain 有 owner,并批准 required checks。涉及公共契约、数据迁移、权限、外部系统或不可逆资源时,必须有对应负责人单独批准。

完成标志:分类报告已生成或已登记受控外部索引;四个 domain 均明确写出适用性、风险、检查、负责人、审批门和未知项;没有把未验证命令写成事实。

Step 2:建立统一 Evidence Layout 和 manifest

所有层都使用同一套 evidence 元数据,才能审计“谁在什么 Commit、什么环境、执行了什么命令、结果如何”。Evidence bundle 必须写入 append-only、versioned、controlled storage;每次验证使用新的 <change-id> 和不可复用的 bundle version,禁止覆盖旧 evidence、伪造成功结果、保存凭据、Cookie、Token、原始 Secret 或未脱敏内部 URL。

实际操作:

  1. 为每个 change 生成唯一 bundle version;真实目录或外部存储命令必须先由仓库规则确认。
  2. 复制场景一中已验证的 bootstrap/verification 入口,不重复编造脚本。
  3. 每项检查结束后立即记录命令、退出状态、duration、环境、artifact hash、redaction、skip、pre-existing failure 和 reviewer。
  4. 先脱敏,再对保存的文件记录 algorithm、size、generated_at 和 digest;原始敏感 artifact 只进入受控位置。
  5. 最终 manifest 和 report 在独立的 finalization step 生成独立 digest,并锚定到外部不可变版本、时间戳和 access-control evidence。

manifest digest 必须可由独立审计者重算。计算前先从待签名 manifest 对象中移除 finalization.manifest_digest 字段(字段不存在时保持对象不变),再按 RFC 8785 JSON Canonicalization Scheme (JCS) 序列化为无 BOM 的 UTF-8 bytes,最后对这些 bytes 计算 SHA-256。必须记录 RFC/JCS 版本、算法、输入对象版本和 digest record;external anchor 指向该 digest record,而不是指向未定义的“最终文件 hash”。report_digest 也必须声明独立输入对象和 canonicalization 规则;如果实现不支持 RFC 8785,必须定义同等精确、可独立重算的 canonical 算法并经审计批准,不能依赖语言默认 JSON 排序。

1
2
3
4
5
6
7
8
9
10
11
manifest_digest_input = manifest_object without finalization.manifest_digest
canonical_bytes = RFC8785_JCS_serialize(manifest_digest_input).encode("UTF-8")
manifest_digest = SHA256(canonical_bytes)
record = {
"algorithm": "SHA-256",
"canonicalization": "RFC 8785 JCS",
"canonicalization_version": "RFC 8785",
"input": "manifest without finalization.manifest_digest",
"digest": manifest_digest,
"external_anchor": "REPLACE_WITH_IMMUTABLE_DIGEST_RECORD"
}

Agent Prompt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Create an append-only, versioned evidence bundle for a Search App change.

Read the verified repository evidence entry points, classification report, and
approved storage policy first. Use TO_BE_VERIFIED_FROM_REPOSITORY for any
unknown command or storage adapter. Do not edit source files or change ignore
rules.

Create a new bundle version instead of overwriting an earlier bundle. For every
saved, redacted artifact record the hash algorithm, byte size, generated_at
timestamp, digest, redaction summary, command, exit status, and owner. Keep
original sensitive plans or logs only in controlled storage; never print them in
ordinary logs.

Finalize the manifest and delivery report in a separate step. Generate their
independent digests and anchor them to an immutable external version, timestamp,
and access-control evidence. Define the self-reference boundary: the manifest
may describe its own pre-finalization digest input, while the final digest
covers the finalized manifest and report bytes without recursively embedding
their own final digest.

命令策略:

1
2
3
4
TO_BE_VERIFIED_FROM_REPOSITORY
TO_BE_VERIFIED_FROM_REPOSITORY --bundle-version=REPLACE_WITH_VERSION
TO_BE_VERIFIED_FROM_REPOSITORY --redact
TO_BE_VERIFIED_FROM_REPOSITORY --algorithm=sha256 --size --generated-at

目录树模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
artifacts/
└── verification/
└── <change-id>/
├── classification.md
├── manifest.json
├── report.md
├── ui/
│ ├── desktop-before.png
│ ├── desktop-after.png
│ ├── mobile-before.png
│ ├── mobile-after.png
│ ├── playwright-trace.zip
│ └── console-network.json
├── api/
│ ├── contract-test.xml
│ └── response-samples.json
├── database/
│ ├── migration.log
│ ├── invariant-results.json
│ └── restore-rehearsal.log
└── infra/
├── terraform-plan.redacted
├── policy-results.json
└── kubernetes-diff.redacted

manifest.json 模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
{
"change_id": "REPLACE_WITH_CHANGE_ID",
"baseline_commit": "REPLACE_WITH_COMMIT",
"candidate_commit": "REPLACE_WITH_COMMIT",
"environment": "REPLACE_WITH_APPROVED_NON_PRODUCTION_ENVIRONMENT",
"created_at_utc": "REPLACE_WITH_TIMESTAMP",
"records": [
{
"domain": "ui",
"name": "REPLACE_WITH_CHECK_NAME",
"command": "TO_BE_VERIFIED_FROM_REPOSITORY",
"started_at_utc": "REPLACE_WITH_TIMESTAMP",
"duration_ms": 0,
"exit_status": 0,
"result": "passed",
"artifact": "ui/REPLACE_WITH_ARTIFACT",
"artifact_hash": {
"algorithm": "SHA-256",
"digest": "REPLACE_WITH_DIGEST",
"size_bytes": 0,
"generated_at_utc": "REPLACE_WITH_TIMESTAMP"
},
"redaction": "REPLACE_WITH_REDACTION_SUMMARY",
"skipped": false,
"skip_reason": null,
"pre_existing_failure": false,
"owner": "REPLACE_WITH_ROLE",
"reviewer": "REPLACE_WITH_ROLE"
}
],
"bundle": {
"storage": "append-only/versioned/controlled",
"version": "REPLACE_WITH_BUNDLE_VERSION",
"external_immutable_anchor": "REPLACE_WITH_CONTROLLED_ANCHOR",
"anchor_timestamp_utc": "REPLACE_WITH_TIMESTAMP",
"access_control_evidence": "REPLACE_WITH_ACCESS_CONTROL_ARTIFACT",
"self_reference_boundary": "Final digest excludes its own recursively embedded value"
},
"finalization": {
"manifest_digest": "REPLACE_WITH_FINAL_MANIFEST_DIGEST",
"manifest_digest_input": "Manifest object without finalization.manifest_digest",
"manifest_canonicalization": "RFC 8785 JCS",
"manifest_canonicalization_version": "RFC 8785",
"report_digest": "REPLACE_WITH_FINAL_REPORT_DIGEST",
"report_canonicalization": "RFC 8785 JCS",
"report_canonicalization_version": "RFC 8785",
"digest_algorithm": "SHA-256",
"external_anchor": "REPLACE_WITH_IMMUTABLE_DIGEST_RECORD",
"finalized_at_utc": "REPLACE_WITH_TIMESTAMP"
},
"forbidden_actions_not_run": [
"production write",
"production apply",
"production delete",
"permission expansion"
]
}

交付报告模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# Search App Cross-Layer Verification Report

## Scope

- Change ID:
- Baseline commit:
- Candidate commit:
- Approved environment:
- Evidence index:
- Evidence retention:
- Bundle storage and version:
- Immutable anchor:
- Access-control evidence:

## Decision

- Status: passed/failed/blocked/partial
- Production write executed: no
- Production promotion authorization: NOT_AUTHORIZED
- Promotion approver:
- Promotion scope:
- Promotion authorization expires_at:
- Required fixes:
- Explicit skips:

## Domain Results

- UI:
- API:
- Database:
- Infrastructure:

## Cross-Layer Gates

- Database expand:
- Backward-compatible API:
- UI enablement:
- Observation:
- Cleanup:

## Audit Trail

- Manifest:
- Commands and exit statuses:
- Artifact hashes for redacted saved files:
- Final manifest digest:
- Final report digest:
- Digest algorithm, sizes, and generated_at:
- Manifest canonicalization and version:
- Manifest digest input:
- Redactions:
- Pre-existing failures:
- Reviewers and approvals:

## Risks and Rollback

- Remaining risks:
- Rollback compatibility:
- Restore or forward-fix rehearsal:

人工审批点:Evidence owner 确认目录权限、保留策略和脱敏结果;审计负责人确认 manifest 不可覆盖、hash 与文件匹配,且 skipped、blocked 和 pre-existing failure 没有被改写成 passed。

完成标志:统一目录、manifest 和 report 模板可用;每个 artifact 都能通过 hash 回溯;秘密和未脱敏敏感数据被排除;旧 evidence 未被覆盖。

Step 3:验证 React + TypeScript UI

UI 验证关注用户能观察到什么,不把 TypeScript 编译或构建成功当作交互证据。Search App 至少覆盖登录后搜索、输入 query、提交、筛选、打开结果和结果为空的路径;实际路径、脚本和 fixture 必须先从仓库替换占位符。

实际操作:

  1. 仅在 approved test environment 启动真实 UI、真实 API 依赖或仓库批准的 sandbox。
  2. 用 Playwright 验证 desktop/mobile screenshots、before/after、loading/empty/error/disabled/long-text 状态。
  3. 保存 trace、console errors、network failures,并用键盘走完搜索流程。
  4. 分层检查可访问性:自动化 axe/semantic、人工键盘、人工视觉/对比度,以及 scope 要求时的真实 screen reader。
  5. 失败也保留截图、Trace 和诊断,不删除或覆盖失败 evidence。

Agent Prompt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Verify the Search App UI in the approved test environment.

First read the repository's verified UI start command, Playwright configuration,
test fixtures, route paths, and the classification report. Replace no command
from guesswork; use TO_BE_VERIFIED_FROM_REPOSITORY until repository exploration
confirms it.

Exercise the real user-observable flow:
sign in with approved test credentials -> search -> apply a filter -> open a
result. Cover loading, success, empty, error, disabled, and long-text states.
Run approved desktop and mobile viewports. Capture before and after screenshots,
browser trace, console errors, failed network requests, and accessibility results.
Use keyboard navigation for the complete flow.

Do not use production credentials, print secrets, mutate production data, or
delete failed evidence. Run automated axe and semantic checks, manual keyboard
checks, manual visual and contrast checks, and a real screen reader when the
approved scope requires it. Automated checks do not prove full WCAG compliance.
Write results and artifact paths to the verification evidence directory. Report
pass, fail, blocked, skipped, and pre-existing failures separately.

命令占位:

1
2
3
TO_BE_VERIFIED_FROM_REPOSITORY
TO_BE_VERIFIED_FROM_REPOSITORY --project=REPLACE_WITH_PLAYWRIGHT_PROJECT
TO_BE_VERIFIED_FROM_REPOSITORY --trace=on

UI evidence 模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# UI Evidence

- Environment:
- Build or app commit:
- User path:
- Desktop viewport:
- Mobile viewport:
- Before artifacts:
- After artifacts:
- Loading result:
- Success result:
- Empty result:
- Error result:
- Disabled result:
- Long-text result:
- Keyboard flow:
- Accessibility automated axe/semantic:
- Accessibility manual keyboard:
- Accessibility manual visual/contrast:
- Accessibility real screen reader:
- Accessibility uncovered scope:
- Console result:
- Network failures:
- Trace:
- Exit status:
- Pre-existing failures:
- Owner:
- Reviewer:

人工审批点:产品或 UI owner 确认 acceptance 是可观察的;Accessibility reviewer 确认键盘和语义证据;测试 owner 确认截图差异不是设备、字体或测试数据噪声。

完成标志:任务范围内的批准检查已完成并记录未覆盖项;desktop/mobile before/after、Trace、console/network、keyboard 和适用的 accessibility evidence 齐全;失败项保留且状态诚实。自动化 accessibility 结果不得单独表述为完整 WCAG 合规证明。

Step 4:验证 FastAPI API 契约和真实依赖

API 验证要同时覆盖公开契约与真实 route/dependency。Search App 的 request/response schema、认证和授权必须从仓库或已批准 contract 得到,不能仅根据前端调用猜测。外部服务可使用隔离 Stub 或 Sandbox,但必须标明未覆盖的真实行为。

实际操作:

  1. 运行真实 FastAPI route、middleware、dependency override 边界和序列化路径。
  2. 验证 valid、empty、invalid request 的状态码和 error envelope。
  3. 验证 authn、authz、timeout;只有 contract 明确允许、fixture 可隔离且可清理时才执行 retry。对非幂等操作默认记录 N/A,或验证客户端不会重试;禁止制造重复外部副作用。
  4. 检查响应字段、类型、排序、分页、错误格式和向后兼容。
  5. 保存测试报告、脱敏 response sample、请求摘要和失败响应;不保存 Authorization header 或 token。

Agent Prompt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Verify the Search App FastAPI contract in the approved isolated environment.

Read the verified route, dependency, schema, authentication, authorization,
test fixture, and test command from the repository. Use the real route and
dependency boundary. Do not infer paths, statuses, headers, or response shapes.
Replace unknowns with TO_BE_VERIFIED_FROM_REPOSITORY.

Cover valid, empty, invalid, unauthenticated, unauthorized, and timeout behavior.
Run retry checks only when the contract explicitly allows retries and the
isolated fixture is cleanable. For non-idempotent operations, record N/A or
verify that the client does not retry; never create duplicate external side
effects. Test idempotency only for an operation where the contract requires it.
Check request and response schemas, error envelope, pagination, ordering, and
backward compatibility. Use only an isolated service and database or an
approved sandbox. Do not write production data and do not print credentials.

Record commands, exit statuses, sanitized request and response summaries,
uncovered real-service behavior, failures, and artifacts in the verification
evidence directory.

契约模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
api_contract:
method: "REPLACE_WITH_VERIFIED_METHOD"
path: "REPLACE_WITH_VERIFIED_PATH"
request_headers: "REPLACE_WITH_NON_SECRET_HEADERS"
request_body: "REPLACE_WITH_VERIFIED_BODY_SHAPE"
valid:
status: 200
response_shape: "REPLACE_WITH_VERIFIED_SHAPE"
empty:
status: "REPLACE_WITH_VERIFIED_STATUS"
response_shape: "REPLACE_WITH_VERIFIED_SHAPE"
invalid:
status: "REPLACE_WITH_VERIFIED_STATUS"
error_envelope: "REPLACE_WITH_VERIFIED_ERROR_SHAPE"
unauthenticated:
status: 401
unauthorized:
status: 403
timeout:
behavior: "REPLACE_WITH_VERIFIED_BEHAVIOR"
retry:
applicable: false
preconditions: "Contract permission and isolated cleanable fixture"
behavior: "N/A unless explicitly approved"
idempotency:
applicable: false
behavior: "not applicable"
compatibility: "REPLACE_WITH_VERIFIED_SUPPORTED_CLIENTS"

命令占位:

1
2
3
TO_BE_VERIFIED_FROM_REPOSITORY
TO_BE_VERIFIED_FROM_REPOSITORY --junitxml=api/contract-test.xml
TO_BE_VERIFIED_FROM_REPOSITORY --cov-report=term-missing

人工审批点:API owner 确认状态码、错误 envelope 和兼容性;Security/API reviewer 确认 authn/authz、敏感字段和真实 dependency 覆盖;任何公共契约变化必须另行批准。

完成标志:真实 route/dependency 测试完成;valid/empty/invalid、authn/authz、timeout/retry 和适用的 idempotency 均有结果;未覆盖的真实服务行为、失败和旧失败单独记录。

Step 5:在临时 PostgreSQL 上验证 Alembic 迁移

数据库验证必须在临时数据库和“仅限隔离 DB 的最小 migration 权限/对象 ownership”下进行,不触及 production 或 staging。先确认 migration 的正向 allowlist、锁影响、数据量、兼容窗口和应用发布顺序,再执行 upgrade。若迁移不能安全 downgrade,必须明确改用备份 restore rehearsal 或 forward fix;不能把不可逆迁移伪装成可回滚。

实际操作:

  1. 创建或申请隔离的临时 PostgreSQL 实例、数据库和最小 migration 权限/对象 ownership;凭据通过环境注入,不写入 evidence。
  2. 以 migration revision 的正向 allowlist 对比实际 SQL、索引、约束、默认值和数据变换。
  3. 执行 upgrade,验证 schema invariants、数据 invariants、旧应用兼容性和新应用兼容性。
  4. 对可安全 downgrade 的迁移执行 downgrade rehearsal;否则执行批准的备份 restore rehearsal 或记录 forward-fix 方案。
  5. 记录耗时、锁观察、备份点、恢复结果和失败 evidence。不得对生产或 staging 执行 upgrade、downgrade、restore、delete 或写入。

Agent Prompt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Verify the PostgreSQL and Alembic change in a temporary isolated database.

Read the verified database URL mechanism, migration command, revision range,
schema invariants, data invariants, compatibility requirements, and repository
backup or restore procedure. Use only the minimum migration privileges and object
ownership scoped to the isolated database, plus an explicit positive allowlist of
migration actions. Use
TO_BE_VERIFIED_FROM_REPOSITORY for unknown commands.

Run the migration upgrade in the temporary database. Check schema and data
invariants, old-application compatibility, new-application compatibility,
lock-sensitive behavior, and migration duration. If downgrade is safe and
approved, run a downgrade rehearsal. If it is not safely reversible, do not
run downgrade; perform the approved restore rehearsal or document a tested
forward-fix path.

Never connect to production or staging. Do not print connection strings,
credentials, secrets, or raw sensitive data. Preserve failed evidence and
record the backup point, restore result, exit status, and reviewer.

命令占位:

1
2
3
4
TO_BE_VERIFIED_FROM_REPOSITORY
TO_BE_VERIFIED_FROM_REPOSITORY upgrade head
TO_BE_VERIFIED_FROM_REPOSITORY downgrade REPLACE_WITH_APPROVED_REVISION
TO_BE_VERIFIED_FROM_REPOSITORY --check-invariants

数据库 evidence 模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Database Evidence

- Temporary database identifier:
- Isolated database migration privileges and object ownership:
- Migration range:
- Positive allowlist:
- Upgrade command:
- Upgrade exit status:
- Schema invariants:
- Data invariants:
- Old application compatibility:
- New application compatibility:
- Lock and duration observation:
- Backup point:
- Restore source:
- Restore point:
- Restore target:
- Data loss window:
- Reversibility: safe downgrade/restore rehearsal/forward fix
- Restore or downgrade result:
- Restored schema invariants:
- Restored data invariants:
- Restore approver:
- Production and staging touched: no
- Secrets redacted: yes
- Owner:
- Reviewer:

人工审批点:DBA 或数据 owner 批准临时实例、隔离 DB 的最小 migration 权限/对象 ownership、allowlist、备份/restore 方案和不可逆判断;restore rehearsal 必须记录恢复源、恢复点、目标、数据损失窗口、恢复后 invariants 和 approver。应用 owner 批准 expand/contract 兼容窗口。任何 production/staging 操作都不在本教程范围内。

完成标志:临时 DB 上 upgrade 和 invariants 有证据;兼容性已验证;downgrade、restore rehearsal 或 forward fix 的选择有依据;备份点、耗时、锁风险和失败结果已记录。

Step 6:只读验证 Terraform 和 Kubernetes 基础设施

基础设施检查只允许在批准的 sandbox 和只读/干运行边界内执行。Terraform 使用 fmtvalidateplan 和 policy check;Kubernetes 必须区分 kubectl diffkubectl apply --server-side --dry-run=server:前者比较期望状态与当前状态,后者联系 API server/admission webhook 做服务端 dry-run,二者都不是普通本地解析。不得执行 production apply/delete/destroy、权限扩张、Secret 输出或任何未经批准的外部写入。

实际操作:

  1. 从仓库确认 Terraform backend/account/workspace、provider、变量来源、lock/refresh 策略和 policy command;确认目标不是生产账号,并记录只读的 cluster URL、identity、context 和 namespace。
  2. 将目标账号、workspace、cluster URL、identity、namespace 与 allowlist 匹配后,运行 fmt、validate、plan 和 policy check,审查资源替换、网络暴露、IAM/RBAC、Secret 引用、成本和不可逆动作。
  3. 对 Kubernetes manifest 做 schema validation;使用固定 --context--namespace 分别执行 kubectl diffkubectl apply --server-side --dry-run=server。server dry-run 仍会联系 API server 和 admission webhook,必须记录其外部观察范围。
  4. 若没有批准 cluster,标记 SKIPPEDBLOCKED,写明缺少什么、owner 和后续动作;不能写成 passed。
  5. 对 plan 和 diff 脱敏后保存到受控位置;原始 binary plan 可能含敏感值,不在普通日志展示原始 terraform show,只保存脱敏派生输出及其 hash。

Agent Prompt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Verify Terraform and Kubernetes changes without external production writes.

Read the repository's verified Terraform entry points, backend, account,
workspace, provider, lock and refresh policy, policy checks, Kubernetes
manifests, schema validator, and approved sandbox cluster procedure. Before
running checks, record the read-only cluster URL, identity, context, namespace,
Terraform account, backend, and workspace, then match them against the explicit
allowlist. Use
TO_BE_VERIFIED_FROM_REPOSITORY for unknown commands.

Run only fmt, validate, plan, policy checks, schema validation, `kubectl diff`,
and `kubectl apply --server-side --dry-run=server` against an approved sandbox
cluster. These Kubernetes commands require explicit fixed context and namespace.
The server dry-run contacts the API server and admission webhooks and is not a
purely local check. Review resource
replacement, network exposure, IAM or RBAC changes, Secret references, cost,
and irreversible actions. Do not run production apply, delete, destroy,
permission expansion, or state mutation. Do not print credentials or raw plan
secrets. Do not show raw `terraform show` output in ordinary logs.

If no approved sandbox cluster exists, mark the cluster checks SKIPPED or
BLOCKED with the exact missing prerequisite, owner, and next safe action.
Redact sensitive plan and diff output before storing evidence.

命令占位:

1
2
3
4
5
6
7
8
9
TO_BE_VERIFIED_FROM_REPOSITORY fmt -check
TO_BE_VERIFIED_FROM_REPOSITORY validate
TO_BE_VERIFIED_FROM_REPOSITORY plan -out=REPLACE_WITH_CONTROLLED_BINARY_PLAN_PATH
TO_BE_VERIFIED_FROM_REPOSITORY policy-check
TO_BE_VERIFIED_FROM_REPOSITORY schema-validate
kubectl --context=REPLACE_WITH_APPROVED_CONTEXT --namespace=REPLACE_WITH_APPROVED_NAMESPACE diff -f REPLACE_WITH_MANIFEST
kubectl --context=REPLACE_WITH_APPROVED_CONTEXT --namespace=REPLACE_WITH_APPROVED_NAMESPACE apply --server-side --dry-run=server -f REPLACE_WITH_MANIFEST
TO_BE_VERIFIED_FROM_REPOSITORY --redacted-plan-output
TO_BE_VERIFIED_FROM_REPOSITORY --plan-hash --algorithm=sha256

如需 -lock=false-refresh=false,只能在 backend/account/workspace owner 批准后显式选择,并记录验证局限:前者可能遗漏并发状态保护,后者可能使用过时远端状态。二者都不是默认选项,也不能把 plan 称为无副作用;即使不 apply,backend lock、state refresh、provider 读取和 API/admission 访问仍可能产生外部观察或锁影响。

人工审批点:Infra owner 确认 backend、account、workspace、lock/refresh 策略、cluster URL、context、namespace 和 identity 均与 allowlist 匹配;Security/FinOps reviewer 确认权限、网络、Secret、成本和资源替换;审批人确认 binary plan 进入受控位置、普通日志不展示原始 terraform show,且 server dry-run 的 API/admission 访问已被接受。

完成标志:Terraform 检查和 policy evidence 齐全;Kubernetes 检查在批准 sandbox 执行或诚实标记 skipped/blocked;没有 production apply/delete/destroy、权限扩张或 state mutation。

Step 7:按跨层兼容顺序执行 Gates

四层分别通过仍可能在联合流程中失败。Search App 采用 expand/contract 顺序,并显式验证 old/new schema × old/new API × old/new UI 的兼容组合:

1
DB expand -> backward-compatible API -> UI enable -> observe -> cleanup

实际操作:

  1. Gate 0:确认分类、证据目录、批准环境和回滚/恢复方案。
  2. Gate 1:DB expand。新增可选字段、索引或兼容结构;验证 old API 与 old UI 仍可运行。
  3. Gate 2:backward-compatible API。先接受旧客户端形状,再提供新字段或新查询行为;验证 old API/new API 与 old UI/new UI 的允许组合。
  4. Gate 3:UI enable。仅在 API compatibility evidence 通过后启用 UI;验证真实 Search App 用户路径和数据结果。
  5. Gate 4:observe。观察批准测试环境中的错误、延迟、超时、空结果和数据一致性;将观察窗口和查询写入 evidence。
  6. Gate 5:cleanup。只有 adoption、rollback compatibility 和人工批准齐全,才验证清理计划;本场景不执行生产清理。
  7. 每个 Gate 由对应 owner 人工批准后才能进入下一 Gate;任一 required check 失败则进入 needs-fixblocked,不能跳过继续。

Agent Prompt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Build the Search App cross-layer compatibility matrix from verified evidence.

Read the classification, manifest, UI and API evidence, database migration
evidence, infrastructure evidence, approved contract, and STATE.md or HANDOFF.md
when present. Use TO_BE_VERIFIED_FROM_REPOSITORY for any missing repository
command or path. Do not run production actions or edit source files.

Evaluate old and new schema against old and new API, and old and new UI. For each
combination record compatible, incompatible, not applicable, or unknown. For
every incompatible combination state whether the safe path is rollback,
forward-fix only, or restore required. For an irreversible data change, require
API and UI forward-fix evidence or an approved restore path.

List required evidence for every gate: classification, environment identity,
artifact digests, schema and data invariants, API contract and auth results, UI
observable and accessibility results, Terraform and Kubernetes read-only
results, observation results, rollback or restore rehearsal, and human approvals.
Produce the gate record and stop on missing required evidence.

Step 7 命令策略:本 Step 只读取已生成的 classification、manifest、domain evidence 和 Gate evidence,不运行新的 UI/API/DB/infra 验证,不创建新环境,不联系 cluster、database 或外部 provider,因此不会新增环境副作用。仓库读取入口、索引命令或 artifact 定位命令未知时,保留 TO_BE_VERIFIED_FROM_REPOSITORY;只有在执行前由仓库探索结果替换后才能运行。若 evidence 缺失,标记 BLOCKEDUNKNOWN,不能为了填表而补跑验证。

kubectl 的差异结果必须分开记录 raw exit code 和 interpreted result。执行前先读取并记录当前 kubectl 版本,并按该已验证版本的官方语义确认 kubectl diff 的退出码:通常 0 表示 no diff,1 表示 differences,>1 表示 failure;若当前版本语义不同,以已验证版本为准。禁止使用 || true,也不能把 raw exit code 1 直接当作失败或成功覆盖;matrix 必须同时保存 raw code、版本、解释结果和 diff artifact。

1
2
3
4
5
6
7
8
TO_BE_VERIFIED_FROM_REPOSITORY
kubectl --context=REPLACE_WITH_APPROVED_CONTEXT --namespace=REPLACE_WITH_APPROVED_NAMESPACE version --client
set +e
kubectl --context=REPLACE_WITH_APPROVED_CONTEXT --namespace=REPLACE_WITH_APPROVED_NAMESPACE diff -f REPLACE_WITH_MANIFEST > REPLACE_WITH_DIFF_STDOUT 2> REPLACE_WITH_DIFF_STDERR
RAW_EXIT=$?
set -e
printf '%s\n' "$RAW_EXIT" > REPLACE_WITH_DIFF_RAW_EXIT
TO_BE_VERIFIED_FROM_REPOSITORY --read-existing-evidence-only

兼容矩阵模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# Search App Compatibility Matrix

| Row | Schema | API | UI | Status | Evidence | Rollback class |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | old | old | old | REPLACE_WITH_STATUS | REPLACE_WITH_EVIDENCE | rollback |
| 2 | old | old | new | REPLACE_WITH_STATUS | REPLACE_WITH_EVIDENCE | rollback/forward-fix only/restore required |
| 3 | old | new | old | REPLACE_WITH_STATUS | REPLACE_WITH_EVIDENCE | rollback/forward-fix only/restore required |
| 4 | old | new | new | REPLACE_WITH_STATUS | REPLACE_WITH_EVIDENCE | rollback/forward-fix only/restore required |
| 5 | new | old | old | REPLACE_WITH_STATUS | REPLACE_WITH_EVIDENCE | rollback/forward-fix only/restore required |
| 6 | new | old | new | REPLACE_WITH_STATUS | REPLACE_WITH_EVIDENCE | rollback/forward-fix only/restore required |
| 7 | new | new | old | REPLACE_WITH_STATUS | REPLACE_WITH_EVIDENCE | rollback/forward-fix only/restore required |
| 8 | new | new | new | REPLACE_WITH_STATUS | REPLACE_WITH_EVIDENCE | rollback/forward-fix only/restore required |

For every row, use `N/A` plus a reason when the combination is not applicable.
Do not omit a row. A missing evidence reference is `BLOCKED` or `UNKNOWN`, not
`passed`.

## Required Evidence

- Classification and approved environment identity:
- Schema and data invariants:
- API contract, authn, authz, timeout, and retry result:
- UI observable, keyboard, and scoped accessibility result:
- Terraform and Kubernetes read-only result:
- Raw kubectl diff exit code, verified kubectl version, and interpreted result:
- Observation result:
- Rollback, forward-fix, or restore rehearsal:
- Human approvals:

## Gate Summary

- Gate 0 classification:
- Gate 1 database expand:
- Gate 2 backward-compatible API:
- Gate 3 UI enable:
- Gate 4 observe:
- Gate 5 cleanup plan:
- Production action executed: no

人工审批点:每个 Gate 都要有 owner、evidence 和明确批准;cleanup、删除、数据变换、公共契约变化或生产动作必须逐项审批。AI 可以整理证据,不能自批 production。

完成标志:只读取已生成 evidence 且没有新增环境副作用;完整 2×2×2 八行矩阵每行都有 status、evidence 和 rollback class,不适用项写为 N/A 及原因;raw kubectl exit code 与 interpreted result 已按已验证版本语义分开记录;不可逆数据变更已约束 API/UI forward fix 或 restore;失败、阻断和未执行 cleanup 没有被报告成成功。

Step 8:用 Matrix Skill 和独立 Review 生成交付报告

将统一 manifest、四层 evidence、Gate 记录和场景五的 STATE.md/HANDOFF.md 汇总为 verification matrix、domain reviewer findings 和 delivery report。Evidence bundle 使用 append-only/versioned controlled storage;最终 manifest/report 生成独立 digest,锚定外部不可变版本、时间戳和 access-control evidence,并定义自引用边界。建议把以下内容保存为项目内受审查的 .agents/skills/change-verification-matrix/SKILL.md;本教程只展示模板,不创建真实文件。

完整英文 Skill 模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
---
name: change-verification-matrix
description: Build an auditable cross-layer verification matrix from verified evidence.
---

# Change Verification Matrix

## Trigger

Use after a UI, API, database, infrastructure, or cross-layer change has a
verified classification and an approved non-production verification environment.

## Inputs

- `artifacts/verification/<change-id>/classification.md`
- `artifacts/verification/<change-id>/manifest.json`
- Domain evidence for UI, API, database, and infrastructure
- Cross-layer gate records
- `STATE.md` and `HANDOFF.md` when present
- The complete diff and approved change contract

## Procedure

1. Confirm the baseline commit, candidate commit, environment, scope, and owners.
2. Read every manifest record and verify its artifact hash.
3. Reconcile each result with the command exit status and observed artifact.
4. Mark each check as `passed`, `failed`, `blocked`, `skipped`, or `unknown`.
5. Preserve pre-existing failures and distinguish them from new regressions.
6. Check the order `DB expand -> backward-compatible API -> UI enable -> observe -> cleanup`.
7. Collect independent findings from UI, API, database, and infrastructure reviewers.
8. Mark Critical and Important findings as release blockers until fixed or explicitly
accepted by the authorized human owner.
9. Verify that every saved redacted artifact records algorithm, digest, size, and
generated_at, and that final manifest/report digests are independently anchored.
For the manifest digest, remove `finalization.manifest_digest`, serialize the
remaining object with RFC 8785 JCS as UTF-8 bytes, and compute SHA-256.
10. Produce the verification matrix, reviewer findings, and delivery report.

## Evidence Rules

- Never invent a command, result, artifact, approval, or hash.
- Never overwrite an earlier evidence directory or mutate its manifest.
- Never include credentials, tokens, cookies, raw secrets, or unredacted sensitive logs.
- A skipped check is never a passed check.
- A plan or dry-run is evidence of intent, not proof of a successful apply.
- Evidence bundles are append-only, versioned, and stored under controlled access.
- Artifact hashes cover the redacted saved file, not an unsaved or raw source.
- The final manifest and report have independent digests anchored to an immutable
external version, timestamp, and access-control evidence.
- The manifest digest input removes `finalization.manifest_digest` before RFC 8785
JCS serialization; record the RFC/JCS version and SHA-256 algorithm.
- The self-reference boundary must be explicit: a final digest does not recursively
include its own embedded final digest value.
- Production writes, deletes, destroys, permission expansion, and data mutation are
forbidden in this workflow.

## Review Gates

- UI owner: observable behavior, visual regression, keyboard flow, accessibility.
- API owner: contract, authentication, authorization, errors, timeout, retry, idempotency.
- Database owner: invariants, lock risk, compatibility, rollback or restore rehearsal.
- Infrastructure owner: target, policy, permissions, network, cost, replacement risk.
- Authorized human delivery owner: final decision and any explicit risk acceptance.

## Outputs

- `verification-matrix.md`
- `domain-reviewer-findings.md`
- `delivery-report.md`
- `final-digest-record.md`

## Completion

Complete only when every required check has evidence, every skip or block has a
reason and owner, Critical and Important findings are fixed or explicitly block
delivery, required approvals are recorded, final digests are independently
anchored, production promotion authorization is explicitly recorded as
`NOT_AUTHORIZED` by default or approved by an authorized human with approver,
scope, and expiration, and no production action was run.

显式调用 Prompt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Use the project skill change-verification-matrix.

Read the classification, manifest, all domain evidence, cross-layer gate records,
the complete diff, the approved contract, and STATE.md or HANDOFF.md when present.
Verify artifact hashes and reconcile commands with exit statuses. Do not invent
missing evidence, approvals, commands, or results. Preserve failed, skipped,
blocked, unknown, and pre-existing statuses.

Produce:
1. verification-matrix.md,
2. domain-reviewer-findings.md,
3. delivery-report.md,
4. final-digest-record.md.

Apply the order DB expand -> backward-compatible API -> UI enable -> observe ->
cleanup. Treat Critical and Important findings as blockers until fixed or
explicitly accepted by the authorized human owner. Do not self-approve
production. Set production promotion authorization to NOT_AUTHORIZED unless an
authorized human provides approver, scope, and expires_at. Non-production
verification is not production authorization. Do not run production writes and
do not include secrets.

final digest record 模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Final Digest Record

- Bundle version:
- Storage type: append-only/versioned/controlled
- Immutable external anchor:
- Anchor timestamp:
- Access-control evidence:
- Artifact hash algorithm:
- Manifest canonicalization: RFC 8785 JCS
- Manifest canonicalization version: RFC 8785
- Manifest digest input: manifest without finalization.manifest_digest
- Redacted saved-file count:
- Manifest digest:
- Report digest:
- Finalized_at_utc:
- Self-reference boundary:
- Production promotion authorization: NOT_AUTHORIZED
- Promotion approver:
- Promotion scope:
- Promotion authorization expires_at:

verification matrix 模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Verification Matrix

| Domain | Required check | Command | Exit | Evidence | Status | Owner |
| --- | --- | --- | ---: | --- | --- | --- |
| UI | User-observable Search App flow | REPLACE_WITH_VERIFIED_COMMAND | 0 | ui/REPLACE_WITH_ARTIFACT | passed | REPLACE_WITH_ROLE |
| API | Contract and auth checks | REPLACE_WITH_VERIFIED_COMMAND | 0 | api/REPLACE_WITH_ARTIFACT | passed | REPLACE_WITH_ROLE |
| Database | Upgrade and invariants | REPLACE_WITH_VERIFIED_COMMAND | 0 | database/REPLACE_WITH_ARTIFACT | passed | REPLACE_WITH_ROLE |
| Infrastructure | Plan, policy, and sandbox dry-run | REPLACE_WITH_VERIFIED_COMMAND | 0 | infra/REPLACE_WITH_ARTIFACT | passed | REPLACE_WITH_ROLE |

## Skipped or Blocked

- Check:
- Status:
- Reason:
- Owner:
- Safe follow-up:

## Pre-Existing Failures

- Check:
- Evidence:
- Why it is pre-existing:
- Impact:

domain reviewer findings 模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Domain Reviewer Findings

## UI
- Critical:
- Important:
- Minor:
- Reviewer:
- Decision:

## API
- Critical:
- Important:
- Minor:
- Reviewer:
- Decision:

## Database
- Critical:
- Important:
- Minor:
- Reviewer:
- Decision:

## Infrastructure
- Critical:
- Important:
- Minor:
- Reviewer:
- Decision:

人工审批点:四个 domain reviewer 分别签字;delivery owner 审核 evidence、风险、skips、pre-existing failures 和 rollback/restore;Critical/Important 必须修复或明确阻断,不能由 Agent 自批 production。

完成标志:verification matrix、domain reviewer findings、delivery report 均可由 manifest 和 artifact hash 回溯;每个 required check 有真实命令和退出状态;skipped/blocked/unknown、旧失败和剩余风险清楚;所有必要审批已记录,且没有生产写入。

10. 四种工具的操作差异

能力 Codex Cursor Claude Code GitHub Copilot
初始化 /init,生成后人工精简 手动创建配置;无统一等价 /init /init,用 /context 验证加载 手动创建配置;无统一 /init
全局项目指引 分层 AGENTS.md 可读取 AGENTS.md CLAUDE.md .github/copilot-instructions.md
路径规则 更具体目录的 AGENTS.md .cursor/rules/*.mdc .claude/rules/ *.instructions.md
流程能力 Skills、MCP 和权限配置 .agents/skills/.cursor/skills/ Skills 和 / 工作流 .github/skills、CLI/Cloud Agent 支持有差异
MCP config.toml .cursor/mcp.json 或 Customize claude mcp add .mcp.json / .github/mcp.json 等当前入口
安全控制 Sandbox、approval policy、Allow/Deny、Review 权限、Hooks、工具批准 permissions、Hooks、sandbox 权限、Hooks、仓库保护和平台策略
Review 当前 Codex Review 能力 Review 工作流 Review 能力 CLI、IDE、Cloud Agent、Code Review 范围不同

功能和命令更新很快。涉及配置字段、事件名、CLI 参数或兼容性时,核对 2026-08 的官方文档;不要从另一种工具的示例推导当前行为。

11. 第三方 Rules 与 Skills 的安全安装

11.1 可信度与审查顺序

优先级可以是:项目自建或供应商官方 → 知名专业团队 → 社区集合 → 匿名来源。来源可信不等于具体版本安全。

安装前逐项检查:

  1. 仓库所有者、许可证、最近变更和固定 Tag 或 SHA。
  2. 完整阅读 SKILL.md,尤其是自动触发和“忽略既有规则”的指令。
  3. 阅读 scripts/references/assets/ 和依赖清单。
  4. 搜索网络访问、凭据读取、Shell、eval、动态导入、删除和外部写入。
  5. 判断最小权限、触发条件、输出处理和数据流。
  6. 使用 gh skill preview 先查看,不要直接安装。
  7. 对下载目录运行 NVIDIA SkillSpector。
  8. 安装后检查目录 diff、触发测试、最小权限、负责人和更新策略。

11.2 SkillSpector

NVIDIA SkillSpector 用于扫描 Agent Skill 的提示注入、数据外传、权限提升、供应链风险、危险代码和 MCP 工具投毒等问题。静态扫描通常更快、可重复性更高,但结果仍受扫描器版本、规则集、依赖数据库和输入解析影响;记录扫描器版本。可选语义分析用于比较 Skill 的声明与行为。

1
2
3
4
5
6
git clone REPLACE_WITH_REVIEWED_SKILLSPECTOR_SOURCE
cd SkillSpector
git checkout REPLACE_WITH_REVIEWED_TAG_OR_SHA
uv tool install .
skillspector --version
skillspector scan ./downloaded-skill --no-llm

不要直接跟踪默认分支,也不要在没有审查版本的情况下填写一个看似真实的 release tag。先下载源码或发行包,审查来源并 checkout REPLACE_WITH_REVIEWED_TAG_OR_SHA,记录实际解析到的 Commit、SkillSpector 版本、规则集版本和依赖数据库日期。--no-llm 默认避免把待扫描文件发送给 LLM Provider,但供应链检查仍可能向 OSV.dev 发送依赖名称和版本;需要语义分析时,必须先审批 Provider、数据范围和保留策略。若当前官方安装方式变化,核对 NVIDIA 官方文档后再替换上述占位符。

扫描不能替代人工审查,也不能替代 Sandbox、权限策略、Hook、CI 和分支保护。报告有误报、漏报和依赖环境边界;把它作为安装门禁的一项证据。

11.3 安装记录模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Skill Review Record

- Source:
- Version or SHA:
- Owner:
- License:
- Intended trigger:
- Read `SKILL.md`: yes/no
- Read scripts and dependencies: yes/no
- Network access:
- Credential access:
- Destructive actions:
- SkillSpector command:
- SkillSpector result:
- Human reviewer:
- Allowed tools:
- Update policy:
- Rollback path:

12. 维护与度量

每月或每季度审计 AGENTS.md、Rules、Skills、Hooks 和 MCP 权限。把重复 Review 意见沉淀为测试、Linter、Hook 或 Rule;删除无触发、冲突、过时或产生噪声的配置。

建议跟踪:

  • 首次验证通过率。
  • 返工率和缺陷逃逸率。
  • Review 时间。
  • 越界修改次数。
  • 被阻止的高风险动作。
  • 状态文件与真实代码不一致的次数。
  • 被跳过的验证项及其原因。

13. 可直接复制的附录

13.1 Cursor .mdc Rule

下面只补充 API 文件的局部约束;公共事实仍放在根 AGENTS.md

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---
description: API contract checks for server and client API files
globs:
- "src/**/api/**/*"
- "tests/**/api/**/*"
alwaysApply: false
---

Read the root `AGENTS.md` before editing.

- Preserve the existing public response shape unless the task contract approves a change.
- Add tests for success, invalid input, authentication, authorization, timeout, retry, and idempotency.
- Do not change migrations or external service configuration without explicit approval.
- Run the repository's focused API checks after each vertical slice.
- Report commands, exit status, skipped checks, and remaining risks.

13.2 最小 SKILL.md

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
---
name: release-check
description: Run a read-only release readiness check and produce evidence.
---

# Release Check

## Use when

Use this workflow before proposing a release or delivery.

## Steps

1. Read `AGENTS.md` and `STATE.md` if present.
2. Confirm the current branch and working tree.
3. Run the repository's verified fast and full checks.
4. Review the diff without editing files.
5. Report commands, exit status, skipped checks, risks, and rollback steps.

## Boundaries

- Do not push, merge, deploy, delete, or change production state.
- Do not print secrets or long-lived tokens.
- Do not claim a skipped check passed.

13.3 新需求任务契约

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# Task Contract

## Goal

Replace with one user-visible outcome.

## User-visible behavior

- Replace with observable behavior.

## Context

- Entry point:
- Related symbols:
- Existing tests:

## Constraints

- Preserve:
- Must not change:

## Done when

- [ ] Focused test passes.
- [ ] Fast verification passes.
- [ ] Full verification passes or skips are documented.
- [ ] Diff is reviewed.

## Non-goals

- Replace with explicit exclusions.

## Approval points

- Public API:
- Data migration:
- External write:
- Production action:

13.4 Bug 修复模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# Bug Fix Contract

## Symptom

Replace with the exact user-visible failure.

## Environment

- Version:
- Platform:
- Input:
- Reproduction frequency:

## Reproduction

1. Replace with a deterministic step.
2. Record the original error.

## Falsifiable hypothesis

One sentence that can be disproved by an observation.

## Regression signal

Test or minimal reproduction that fails before the fix.

## Minimal fix

Files and symbols allowed to change:

## Verification

- Red result:
- Green result:
- Related tests:
- Full verification:
- Real path:

## Not fixed

List unrelated findings and known risks.

13.5 完成报告

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Completion Report

## Summary

Replace with the delivered user-visible result.

## Changed files

- `path/to/file`: reason for change.

## Commands and results

| Command | Exit status | Result |
| --- | ---: | --- |
| `REPLACE_WITH_COMMAND` | 0 | passed |

## Skipped checks

- Check:
- Reason:
- Follow-up owner:

## Review

- Diff reviewed: yes/no
- Independent review: yes/no
- Human approval: yes/no

## Risks

- Replace with remaining risks.

## Rollback

- Replace with a tested rollback or restore entry point.

13.6 Agent-ready 检查清单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# Agent-ready Checklist

## Repository

- [ ] Runtime and package manager are documented.
- [ ] Repository map exists.
- [ ] Generated and dangerous areas are marked.
- [ ] Secrets are excluded from source and instructions.

## Commands

- [ ] Bootstrap is real and repeatable.
- [ ] Fast verification is real and repeatable.
- [ ] Full verification is real and repeatable.
- [ ] CI reuses repository verification scripts.
- [ ] Baseline failures are recorded.

## Guidance

- [ ] Root `AGENTS.md` contains facts and hard boundaries.
- [ ] Path-specific rules are short and scoped.
- [ ] Skills describe repeatable workflows.
- [ ] Tool-specific formats are not copied across products.

## Isolation and safety

- [ ] Agent work uses a branch or worktree.
- [ ] Sandbox and network boundaries are configured.
- [ ] Allow/Deny policies are reviewed.
- [ ] Hooks are tested and fail closed where required.
- [ ] Production writes require human approval.
- [ ] CI and branch protection remain authoritative.

## Delivery

- [ ] Task contract includes non-goals and approval points.
- [ ] Evidence includes commands and exit statuses.
- [ ] Skipped checks are explicit.
- [ ] Rollback is documented.

13.7 独立 PR checklist

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# Pull Request Checklist

## Scope

- [ ] The PR has one clear user-visible purpose.
- [ ] The task contract and non-goals are included.
- [ ] The diff contains no unrelated cleanup.
- [ ] Generated files were changed only through their generator.

## Evidence

- [ ] Baseline commit is recorded.
- [ ] Focused tests passed.
- [ ] Fast verification passed.
- [ ] Full verification passed, or every skip has a reason.
- [ ] UI, API, database, or infrastructure evidence is attached as applicable.

## Safety

- [ ] No secret, token, private URL, or sensitive log is included.
- [ ] Production, deletion, permission, and external-write actions were not run without approval.
- [ ] Dependencies and Skill changes were reviewed.
- [ ] Migration and rollback steps are documented.

## Review

- [ ] Complete diff was reviewed independently.
- [ ] Required code owners approved.
- [ ] CI passed on the PR head commit.
- [ ] Branch protection requirements are satisfied.
- [ ] The merge and deployment decision is made by a human owner.

13.8 新项目 Agent-ready 验收清单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# New Project Agent-ready Acceptance

## Baseline

- [ ] The repository has an initial parseable commit.
- [ ] The baseline commit hash is recorded.
- [ ] A new task worktree can be created from that commit.

## Startup

- [ ] A clean checkout can run bootstrap.
- [ ] Runtime and dependency versions are documented.
- [ ] Development and test entry points are verified.

## Guidance

- [ ] Root `AGENTS.md` contains verified facts and boundaries.
- [ ] Tool-specific adapters are scoped and current.
- [ ] No rule claims to be a security boundary.

## Verification

- [ ] `verify-fast.sh` fails clearly when placeholders remain.
- [ ] `verify.sh` fails clearly when placeholders remain.
- [ ] CI reuses the repository scripts.
- [ ] A baseline failure record exists.

## Isolation and safety

- [ ] Agent work is isolated by branch or worktree.
- [ ] Sandbox and network policy are documented.
- [ ] Hooks were tested for allow, deny, timeout, and failure behavior.
- [ ] MCP starts with read-only tools and environment-injected credentials.
- [ ] Branch protection and required review are enabled.

## Trial task

- [ ] An Agent explained the repository map.
- [ ] An Agent completed a reversible change.
- [ ] Verification evidence includes commands and exit statuses.
- [ ] Unverified items were reported honestly.

13.9 遗留项目 Agent-ready 验收清单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Legacy Project Agent-ready Acceptance

## Read-only assessment

- [ ] README, CI, build files, and real scripts were inspected.
- [ ] Runtime, dependencies, entry points, generated files, secrets, and dangerous areas are catalogued.

## Baseline

- [ ] Existing build and tests ran before source changes.
- [ ] Known failures, duration, environment dependencies, and flaky tests are recorded.
- [ ] Baseline results are distinguishable from new regressions.

## Characterization tests

- [ ] High-risk and high-coupling behavior has characterization coverage.
- [ ] Tests preserve current behavior, including known defects that cannot change yet.
- [ ] A human reviewed that tests describe the current system accurately.

## Operational entry points

- [ ] Bootstrap, fast verification, and full verification adapters exist.
- [ ] Every adapter command is present in the repository or marked unconfigured.
- [ ] CI and local verification share the same core entry points.

## Guidance migration

- [ ] `.cursorrules`, duplicate prompts, and oversized `CLAUDE.md` files were inventoried.
- [ ] Facts moved to public `AGENTS.md` or native project instructions.
- [ ] Path-specific constraints moved to Rules.
- [ ] Repeatable workflows moved to Skills.
- [ ] Conflicting and obsolete instructions were removed.

## Progressive adoption

- [ ] Documentation and tests came before broad refactoring.
- [ ] Small Bugs and mechanical migrations are delivered as small changes.
- [ ] Each subsystem is adopted separately.
- [ ] Cross-module work waits until earlier evidence is stable.
- [ ] Every change has a real verification result and rollback entry point.

14. 总结

  • 先把真实命令、目录边界和完成标准写下来,再让 Agent 写代码。
  • AGENTS.md、Rules、Skills、Hooks 和 MCP 按职责分工,不要把它们当成同一种配置。
  • 每个任务都使用契约、隔离工作区、垂直切片和可失败的验收信号。
  • 场景不同,证据不同:UI 看交互与可访问性,API 看契约与鉴权,数据库看迁移与恢复,基础设施看 plan、权限和目标环境。
  • Skill 是可执行的第三方依赖,先预览、扫描、人工审查并固定版本,再安装。
  • 最终安全和质量依靠 Sandbox、Allow/Deny、Hook、CI、分支保护和人工审批形成纵深防御。

参考资料

本文由 AI 辅助生成,如有错误或建议,欢迎指出。