Skip to content

运行时治理

本页解释 spec-first init 背后的治理模型。它不只是“复制一些文件到项目里”,而是把 source assets、宿主差异、受管状态、预览计划和安全写入组合成一条可审查的 runtime 投递链路。

核心判断是:source 改动发生在 package 仓库,runtime mirrors 由 init 投递,managed state 只记录 spec-first 拥有什么,宿主入口只消费当前投影结果。

Spec-First runtime assets

运行时资产分层

位置角色典型操作
Source assetsskills/(含 skill-local references/agents)、templates/src/cli/行为真相源修改 skill、agent、模板、CLI、contract
Projection logicspec-first init、host adapter、manifest/governance filter确定性投影过滤投递对象、改写宿主路径、生成 operation plan
Runtime mirrors.claude/.codex/.agents/skills/宿主加载副本init 创建、刷新、清理
Control-plane facts.spec-first/config.spec-first/workspace.spec-first/sessions本机运行事实由 setup/session/provider 命令维护
Team knowledgedocs/brainstormsdocs/plansdocs/tasksdocs/solutions团队长期知识由 workflow 生成并通常提交

这几层不能混用。修 workflow 文案、agent 引用或入口行为时,应回到 source assets;runtime mirror 漂移时,先确认 source,再重新 spec-first init

Init Plan:先预览,再写入

init 的设计重点是 preview-first。它先构造计划,再执行副作用:

text
input: projectRoot / host / developer / lang
  -> build init plan
  -> preview next managed state
  -> pre-sync old managed assets
  -> write runtime mirrors and state
  -> apply operation plan

计划对象通常包含三类动作:

计划段解决的问题不是
preSyncPlan移除过时、退休或命名空间外的受管资产不清理第三方或用户文件
writePlan写入本轮 runtime mirror、host instruction block、state不判断业务需求
destructiveResetPlanlegacy state 或 current runtime drift 下做受管硬重置不是删除整个宿主目录

这让用户和工具可以在写入前看到将发生什么,也让错误计划在落盘前停止。

Managed State:ownership ledger

state.json 记录的是 spec-first 上一轮管理过的资产集合,不是 runtime 目录完整索引。

字段含义
manifestVersion本轮 source manifest 版本
commands受管 command-backed workflow 文件
skills受管 standalone/internal skill mirrors
workflowSkills受管 workflow skill mirrors
agents受管 agent profiles
agentSupportFilesagent 支撑文件

因此,cleaninit 和 drift 修复只应删除 spec-first 拥有的资产。宿主自身文件、第三方 provider 文件和用户手写文件不应因为位于同一 runtime root 就被当作 spec-first 资产。

原子写入与路径安全

Runtime 投递必须先保证文件系统边界:

风险防线
相对路径逃出项目根operation target 解析时拒绝
symlink 把 runtime root 指向仓库外realpath containment 检查
单文件写入半成品同目录临时文件写入后 rename
destructive reset 中断reset 分支使用 runtime backup
旧资产残留pre-sync 根据 managed state 清理

这不是为了把 init 变成复杂事务系统,而是为了让每个文件副作用都可解释、可限制、可失败退出。

多宿主投递矩阵

Claude Code 与 Codex 的 runtime 拓扑不同,init 不做同构复制。

投递面Claude CodeCodex
命令入口.claude/commands/spec.claude/commands/spec-*.md.agents/skills 承载 spec-* workflow skills
Workflow skills.claude/spec-first/workflows.agents/skills
Standalone skills.claude/skills.agents/skills
Agents.claude/agents.codex/agents
Managed state.claude/spec-first/state.json.codex/spec-first/state.json
Host instructionCLAUDE.md managed blockAGENTS.md managed block

Codex 侧还会把共享文本中的 Claude 路径、agent 调度语义和入口名称改写到 Codex 可消费的形态。这个改写属于 adapter 责任,不应由用户手工在 .agents/skills 里批量替换。

Preview 宿主的投影边界

当前 source catalog 还登记了四个显式 opt-in 宿主。它们共享 source assets 和 spec-* workflow 名称,但 runtime 拓扑与验证声明不能与 Claude Code / Codex 混为一谈:

宿主主要投影当前边界
Cursor.cursor/skills/.cursor/agents/.cursor/spec-first/generated_runtime_preview;仅证明生成,不声明完整 loader/user journey
Kiro.kiro/skills/.kiro/agents/.kiro/spec-first/.kiro/settings/opt-in preview;IDE 实机 smoke 仍需单独取证
Qoder.qoder/commands/spec-*.md.qoder/skills/.qoder/agents/.qoder/spec-first/opt-in degraded preview;CLI 与 agent 工具能力取决于本机宿主
OpenCode.opencode/commands/spec-*.md.opencode/skills/.opencode/agents/.opencode/spec-first/opt-in preview;宿主发现与完整 user journey 需单独验证

因此,init --cursorinit --kiroinit --qoderinit --opencode 的成功只证明对应 projection / contract 层面完成;是否适合生产 workflow,仍以对应宿主的真实 smoke、user journey 和 field evidence 为准。

Developer Profile 与语言策略

init 会使用 developer profile 写入项目级语言与作者信息。常见来源顺序是:

  1. 显式 --user / --lang
  2. 全局 ~/.spec-first/.developer
  3. git config user.name

Profile 主要影响两件事:默认生成语言,以及 CHANGELOG.md 这类需要作者字段的变更记录。它不是权限系统,也不是 workflow state。

正确修复路径

现象正确处理反模式
spec-* 文案错修改 source skill / template,重新 init手改 generated runtime mirror
agent 名称或引用错修改 skill-local skills/**/references/agents/ 或 adapter transform在 runtime mirror 里补丁
doctor 报 runtime drift确认 source 与版本,再 spec-first init删除 state 后手工拼 runtime
Codex 入口仍带 Claude 路径检查 Codex adapter 与 path rewrite批量搜索替换 generated mirror
旧版本资产残留init/clean 的受管删除路径手删整个宿主目录导致第三方文件丢失

阅读下一步