Skip to content

feat(cli): context instructions scaffold — 空工作区项目指令引导(对齐 Claude Code /init 与 Codex /init) - #518

Merged
Qiyuanqiii merged 5 commits into
mainfrom
Qiyuanqiii/instructions-scaffold
Nov 2, 2026
Merged

Qiyuanqiii merged 5 commits into
mainfrom
Qiyuanqiii/instructions-scaffold

Conversation

@Qiyuanqiii

@Qiyuanqiii Qiyuanqiii commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

动机 / Motivation

对照 Claude Code 与 Codex CLI 的功能盘点(重点核对了各自的 /init 工作流):两者都能在进入项目时一键生成项目指令文件(Claude Code 生成 CLAUDE.md,Codex 生成 AGENTS.md),让跨会话约定从第一次任务就生效。Universal-Code 的 docs/context-continuity.md 已经把 AGENTS.md / AGENTS.override.md / CLAUDE.md / .prayu 作为一等指令源,发现、指纹、revision ledger 都已就绪,但没有任何从零引导生成这些文件的入口——新项目的操作者只能凭空手写,首版体验在这里断档。

本 PR 补上这一环:cyberagent context instructions scaffold,设计上与 Claude Code /init、Codex /init 对齐,但严格遵循本仓库的确定性原则:离线、不调用模型、不读取标识文件内容。

变更 / Changes

  • internal/projectconfig/instructions_scaffold.go(新增):
    • 固定顺序检测表覆盖 go.mod、package.json 及各锁文件、Cargo.toml、pyproject.toml、Gemfile、pom.xml、build.gradle(.kts)、composer.json、CMakeLists.txt、Make 系、Docker 系、README、.prayu/*、CLAUDE.md、.github/workflows;仅 Lstat 判断存在性,不读取内容,秘密不可能进入草稿。
    • 渲染双语 AGENTS.md 草稿:无时间戳、无 map 迭代,输出逐字节确定并附 SHA-256;大小写变体标识(Makefile/makefile 等)用 os.SameFile 聚合,跨平台不多报。
    • 写入模式在目标目录已存在 AGENTS.md 或 AGENTS.override.md(含会被发现流程拒绝的空文件)时拒绝,绝不覆盖;--print 始终可预览。32 KiB 上限严格小于发现流程 64 KiB 单文件上限。
    • 复用 instructionBoundary 的全部边界校验;另要求 target 本身必须是已存在的真实目录(评审 F1:否则单层缺失目标会经父目录回退写错位置——已修复并加回归)。
  • internal/app/context_command.go / app.go:context instructions scaffold --workspace <name> [--target <dir>] [--print] [--json] 接线、帮助文本;仅在 args[1] == "scaffold" 精确匹配时进入,不影响既有 context instructions 用法。
  • docs/usage.md / docs/context-continuity.md:中英文档新增脚手架说明。
  • docs/reviews/instructions-scaffold/:按仓库惯例记录 OCR delegate 复审(发现 F1 P1 / F2 P3 / F3 P3,全部修复并复测)与覆盖明细。

安全与边界 / Safety

  • 草稿本身写明项目指令是 untrusted 工作流建议:经 DiscoverInstructions 复核,trust=project_workflow_untrusted,授权字段除 workflow/formatting/validation 外全 false(含测试断言)。
  • 不授予任何权限、不联网、不调用模型、不写入 .prayu 可执行配置;仅产出一份可编辑的工作区文档。
  • .github / workflows 目录 symlink 不跟随(评审 F3 修复);标识文件 symlink 仅报告不跟随。

验证 / Verification

  • gofmt -l 无输出;go vet ./internal/projectconfig/ ./internal/app/ 无告警。
  • go test -race ./internal/projectconfig/ 通过;go test ./internal/app/ -run Context 通过(Go 1.26.5 / windows-amd64)。
  • 真实构建 cmd/cyberagent 端到端冒烟:workspace init → scaffold 写入(正确检出 go.mod、README.md)→ 重复写入被拒 → --print 预览 → --target nonexistent 明确报错 → --json 可解析 → context instructions 能发现草稿并给出 fingerprint。
  • 桌面端 UI 入口(Context 面板按钮)留待后续 PR;本 PR 仅覆盖 CLI 与文档,供维护者先行验收命令契约。

差距说明 / Gap context

除本 PR 外,与 Claude Code / Codex 逐项对照后仍存在的差距(供后续规划参考,本 PR 不涉及):侧问通道(/btw、/side)、语音听写、输出风格定制。

评审跟进 / Review follow-up

外部评审提出一处 P2:instructions_scaffold.go 先用 os.Lstat 判断存在性、再用 os.WriteFile 写入,而 os.WriteFile 会截断已存在文件。两个并发脚手架进程可能同时通过存在性检查,后写入者覆盖前者刚创建的 AGENTS.md,与"绝不覆盖"契约冲突。

修复(commit d68fe5ea):

  • 写入路径改为 os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o644),由文件系统原子保证目标不存在;AGENTS.md 的拒绝不再依赖先前的存在性预检查,AGENTS.override.md 的预检查保留(脚手架自身不会创建 override)。
  • os.ErrExist 统一映射为原有拒绝文案("%s already exists in %s; scaffolding never overwrites project files (--print renders a preview)",参数不变),对外错误语义不变;AGENTS.md 的拒绝时机从渲染前移到写入时,文案与参数保持不变。
  • 内容写入失败时删除已创建的部分文件,不留半截 AGENTS.md;--print 预览仍然不落盘。
  • 公共 API、结果结构、协议版本与其他包均未改动,无新增依赖。

新增回归测试(internal/projectconfig/instructions_scaffold_test.go):

  • TestScaffoldProjectInstructionsNeverOverwritesExistingFiles:已有 AGENTS.md(含空文件)与已有 AGENTS.override.md 三种情况均拒绝,错误文案逐字比对,原文件内容逐字不变。
  • TestScaffoldProjectInstructionsConcurrentCreateWritesOnce:8 个并发写者经就绪门同时争抢同一次创建,断言恰好一个成功、其余全部得到既有拒绝文案,磁盘内容与成功者的内容及 SHA-256 完全一致(无截断、无交错)。Windows 上 O_CREAT|O_EXCL 映射为 CREATE_NEW,确定性由文件系统保证,不依赖调度时序。

复测(Go 1.26.10 / windows-amd64,commit d68fe5ea):

  • gofmt -l internal/projectconfig 无输出;go vet ./internal/projectconfig/... 通过。
  • go test -count=3 ./internal/projectconfig/... 通过;go test -race -count=1 ./internal/projectconfig/... 通过。
  • go build ./... 通过。
  • 反向验证:临时还原旧的"先检查后写入"实现后,新增并发用例稳定失败(多个写者同时成功),确认该用例确实覆盖评审指出的竞态。

Add 'cyberagent context instructions scaffold' — the deterministic,
offline, no-model analog of Claude Code /init and Codex /init. It detects
fixed root markers (reading no file contents), renders a bilingual
AGENTS.md draft, and never overwrites an existing AGENTS.md or
AGENTS.override.md; --print previews, --json emits the full result.
The draft is untrusted workflow guidance and grants no authority.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
claude and others added 3 commits October 30, 2026 04:40
…ject-configuration-contract family

Co-Authored-By: Claude <noreply@anthropic.com>
…osition

The symlink subtest only ever executed on CI Linux (Windows skips
symlink creation without privilege), where the positional index
assertion was wrong: go.mod sorts first in the fixed detection table,
so Detected[1] is the Makefile. Look the marker up by path instead.

Co-Authored-By: Claude <noreply@anthropic.com>
@Qiyuanqiii
Qiyuanqiii merged commit 9c2440b into main Nov 2, 2026
23 checks passed
@Qiyuanqiii
Qiyuanqiii deleted the Qiyuanqiii/instructions-scaffold branch November 2, 2026 07:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants