arckit-build
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseArcKit Build Harness (v0.4)
ArcKit 构建管理工具(v0.4)
You are running the ArcKit build harness. Your job is orchestration only — never read or write artefact content yourself. Spawn subagents for that.
你正在运行ArcKit构建管理工具。你的职责仅为编排调度——绝不要自行读写工件内容,此类操作交由子Agent完成。
Operating principles
操作原则
- Never read or write artefact content in main context. That's what subagents are for.
- One commit per wave, not per artefact (atomic units of progress, clean history).
- Halt-on-fail by default — if any agent in a wave reports failure, stop and surface to user.
- State is sacred — update after every wave, before moving on.
projects/{P}-{NAME}/.arckit/state.json - Single message, multiple Agent calls for parallelism within a wave. Never loop sequential Agent calls.
- Idempotency: if state says , the file exists at the recorded path, AND every input file's SHA-256 matches the hash recorded at build time, skip. Otherwise the target is stale — rebuild it (and propagate staleness through the DAG). See § "Input-hash change detection".
complete - Trust the path-allocation hook. ArcKit's PreToolUse hook is the authoritative path normalizer — it allocates sequence numbers, applies subfolders, pads project IDs at write time. The orchestrator and workers never construct paths by string substitution or call
validate-arc-filename.mjsdirectly. Read the corrected path back from the Write tool result.generate-document-id.sh
- 主上下文绝不读写工件内容:此类操作是子Agent的职责。
- 每批次提交一次,而非每个工件提交一次(原子性进度单元,清晰的历史记录)。
- 默认失败即停止——如果批次中任何Agent报告失败,立即停止并告知用户。
- 状态是核心——每完成一个批次后,更新,再进行下一批次。
projects/{P}-{NAME}/.arckit/state.json - 单消息多Agent调用以实现批次内并行。绝不循环进行顺序Agent调用。
- 幂等性:如果状态显示、文件存在于记录路径且所有输入文件的SHA-256与构建时记录的哈希匹配,则跳过该目标。否则目标为过期——需重建(并将过期状态沿DAG传播)。详见「输入哈希变更检测」章节。
complete - 信任路径分配钩子:ArcKit的PreToolUse钩子是权威的路径标准化工具——它会分配序列号、应用子文件夹、在写入时补全项目ID。编排器和工作节点绝不通过字符串拼接构造路径,也不直接调用
validate-arc-filename.mjs。从Write工具结果中读取修正后的路径。generate-document-id.sh
Args
参数
| Arg | Effect |
|---|---|
| Project directory name or numeric ID (e.g. |
| Dry run. Print the wave plan, do not dispatch any Agents, exit. |
| Read state.json; continue from last incomplete wave. |
| Build only NAME and its missing dependencies. |
| Force-rebuild NAME and everything downstream. |
| Skip the per-wave git commit. |
| Recipe name (default |
| Enable an optional target (e.g. |
| Exclude a default-on optional target (e.g. |
| Treat any |
| 参数 | 作用 |
|---|---|
| 项目目录名称或数字ID(例如 |
| 试运行。打印批次计划,不调度任何Agent,执行后退出。 |
| 读取state.json;从最后未完成的批次继续。 |
| 仅构建NAME及其缺失的依赖项。 |
| 强制重建NAME及其所有下游依赖。 |
| 跳过每批次的git提交。 |
| 方案名称(默认 |
| 启用可选目标(例如 |
| 排除默认启用的可选目标(例如 |
| 将任何输出文件存在的 |
Recipe loading
方案加载
Recipes are external YAML files. Lookup precedence for (first hit wins):
--recipe NAME- Project override: — user customizations preserved across plugin updates.
.arckit/recipes/{NAME}.yaml - Core plugin: — recipes shipped with the
${CLAUDE_PLUGIN_ROOT}/skills/arckit-build/recipes/{NAME}.yamlcore plugin (arckit,uk-saas).uk-mod-sovereign - Sibling community plugins: — recipes shipped with installed community plugins (e.g.
${CLAUDE_PLUGIN_ROOT}/../arckit-*/recipes/{NAME}.yaml,arckit-uae/recipes/uae-federal-ai.yaml).arckit-ca/recipes/ca-federal-fitaa.yaml
Resolution: glob the parent directory of for and take the first match. The glob works in both layouts — marketplace-installed plugins land as siblings under the same marketplace-source cache directory, and the dev-mode same-repo layout has them as sibling directories in the repo root.
${CLAUDE_PLUGIN_ROOT}arckit-*/recipes/{NAME}.yamlDefault recipe is . To customize, copy the core default to and edit there:
uk-saas.arckit/recipes/uk-saas.yamlbash
mkdir -p .arckit/recipes
cp "${CLAUDE_PLUGIN_ROOT}/skills/arckit-build/recipes/uk-saas.yaml" .arckit/recipes/uk-saas.yamlBuilt-in recipes:
| Recipe | Plugin | Use case |
|---|---|---|
| | UK Government managed multi-tenant SaaS — civilian departments |
| | UK MOD / sovereign / air-gapped — |
| | UAE Federal AI — full Cabinet agentic AI decree compliance with all 12 UAE community commands, integrated research wave (general AI + AWS / Azure UAE region availability), plus core ArcKit governance |
| | UAE Federal Agentic AI Transformation — focused 24-month playbook for the 23 April 2026 Cabinet framework's 50%-of-services-by-April-2028 target; ADRs reshaped around agentic architecture (orchestration, human-in-the-loop, observability, kill-switch); PLAN + ROADMAP timeboxed to the 24-month window |
| | Canadian Federal — FITAA, ITSG-33, GC Digital Standards |
| | Australian Federal / DISP-supplier — ASD Essential Eight, ISM, DTA DSS, Privacy Act 1988, OAIC NDB, PSPF, AI Assurance, DISP attestation (35 targets, 9 waves) |
| | Australian Energy Sector — AESCSF maturity, AER ring-fencing, AEMC NER/NGR, AEMO interfaces, DERMS/DOE, CSIP-AUS layered on the AU federal baseline (Essential Eight, ISM, OT security, SOCI/CIRMP, Privacy Act/NDB). Optional default-off |
| | UK NHS Clinical Safety + UK/EU MDR — NHS DCB0129 (manufacturer) + DCB0160 (deployer) clinical safety case (Marcus Baw SAFETY.md 3-file spec), NHS DTAC v3, UK MDR 2002 + EU MDR 2017/745 SaMD/AIaMD classification. Composes with UK SaaS baseline (no swaps; adds clinical safety + medical-device regulation on top). 44 targets across 8 waves. First sector overlay. |
方案是外部YAML文件。的查找优先级(找到即停止):
--recipe NAME- 项目覆盖:——用户自定义内容,在插件更新时会被保留。
.arckit/recipes/{NAME}.yaml - 核心插件:——随
${CLAUDE_PLUGIN_ROOT}/skills/arckit-build/recipes/{NAME}.yaml核心插件发布的方案(arckit、uk-saas)。uk-mod-sovereign - 社区兄弟插件:——随已安装社区插件发布的方案(例如
${CLAUDE_PLUGIN_ROOT}/../arckit-*/recipes/{NAME}.yaml、arckit-uae/recipes/uae-federal-ai.yaml)。arckit-ca/recipes/ca-federal-fitaa.yaml
解析方式:对的父目录执行glob匹配,取第一个匹配项。该glob在两种布局下均有效——市场安装的插件位于同一市场源缓存目录下的同级目录,开发模式同仓库布局中它们是仓库根目录下的同级目录。
${CLAUDE_PLUGIN_ROOT}arckit-*/recipes/{NAME}.yaml默认方案为。如需自定义,将核心默认方案复制到并编辑:
uk-saas.arckit/recipes/uk-saas.yamlbash
mkdir -p .arckit/recipes
cp "${CLAUDE_PLUGIN_ROOT}/skills/arckit-build/recipes/uk-saas.yaml" .arckit/recipes/uk-saas.yaml内置方案:
| 方案 | 插件 | 使用场景 |
|---|---|---|
| | 英国政府托管多租户SaaS——民用部门 |
| | 英国国防部/主权/气隙环境—— |
| | 阿联酋联邦AI——完全符合内阁Agentic AI法令要求,集成所有12个阿联酋社区命令,包含集成研究批次(通用AI + AWS/Azure阿联酋区域可用性),加上核心ArcKit治理 |
| | 阿联酋联邦Agentic AI转型——针对2026年4月23日内阁框架2028年4月前实现50%服务目标的24个月聚焦规划;ADR围绕Agentic架构重新设计(编排、人在回路、可观测性、终止开关);PLAN + ROADMAP限定在24个月窗口期 |
| | 加拿大联邦——FITAA、ITSG-33、GC数字标准 |
| | 澳大利亚联邦/DISP供应商——ASD Essential Eight、ISM、DTA DSS、1988年隐私法、OAIC NDB、PSPF、AI保证、DISP认证(35个目标,9个批次) |
| | 澳大利亚能源行业——AESCSF成熟度、AER环网隔离、AEMC NER/NGR、AEMO接口、DERMS/DOE、CSIP-AUS叠加在澳大利亚联邦基线之上(Essential Eight、ISM、OT安全、SOCI/CIRMP、隐私法/NDB)。可选默认关闭的 |
| | 英国NHS临床安全 + 英国/欧盟MDR——NHS DCB0129(制造商) + DCB0160(部署方)临床安全案例(Marcus Baw SAFETY.md 3文件规范)、NHS DTAC v3、英国MDR 2002 + 欧盟MDR 2017/745 SaMD/AIaMD分类。基于英国SaaS基线扩展(无替换;在基础上添加临床安全 + 医疗器械法规)。44个目标,分8个批次。首个行业扩展方案。 |
Recipe schema (v1)
方案 schema(v1)
See for an annotated reference. Top-level keys:
${CLAUDE_PLUGIN_ROOT}/skills/arckit-build/recipes/uk-saas.yaml- — recipe name (string, must match filename stem)
recipe - — recipe schema version (currently
schema_version)1 - — free text
description - — default version stamp for outputs (e.g.
defaults.version)"1.0" - — map of target ID →
optional_targets{description, default} - — list of
post_build_hooksto run after final wave (parallel){skill, args} - — list of target entries
targets
Each entry:
targets[]| Field | Required | Notes |
|---|---|---|
| yes | Unique target ID (e.g. |
| yes | ArcKit skill name (e.g. |
| yes | Args string passed to the skill, after substitution |
| yes | |
| yes | ArcKit doc-type code ( |
| no | Orientation hint shown in |
| no | Orientation hint; the hook's |
| no | Used in commit messages and |
| yes | List of target IDs, may include glob |
The / fields document recipe author intent for human readers and output, but the path-allocation hook is the source of truth at write time. If a recipe says for a single-instance type the hook doesn't recognise, the file lands wherever the hook decides — debug via the hook, not the recipe.
output.subfolderoutput.multi_instance--plansubfolder: decisions参考带注释的。顶层键:
${CLAUDE_PLUGIN_ROOT}/skills/arckit-build/recipes/uk-saas.yaml- — 方案名称(字符串,必须与文件名主干匹配)
recipe - — 方案schema版本(当前为
schema_version)1 - — 自由文本描述
description - — 输出的默认版本标记(例如
defaults.version)"1.0" - — 目标ID →
optional_targets的映射{description, default} - — 最终批次后运行的
post_build_hooks列表(并行){skill, args} - — 目标条目列表
targets
每个条目:
targets[]| 字段 | 必填 | 说明 |
|---|---|---|
| 是 | 唯一目标ID(例如 |
| 是 | ArcKit Skill名称(例如 |
| 是 | 传递给Skill的参数字符串,替换后生效 |
| 是 | |
| 是 | ArcKit文档类型代码( |
| 否 | 在 |
| 否 | 方向提示;钩子的 |
| 否 | 用于提交消息和 |
| 是 | 目标ID列表,可包含通配符 |
output.subfolderoutput.multi_instance--plansubfolder: decisionsVariable substitution
变量替换
The orchestrator substitutes these placeholders in and before dispatching to workers (workers never see placeholders):
argsoutput.project| Placeholder | Source |
|---|---|
| Project ID, zero-padded (e.g. |
| Project slug (e.g. |
| |
| |
编排器在调度给工作节点前,会替换和中的这些占位符(工作节点不会看到占位符):
argsoutput.project| 占位符 | 来源 |
|---|---|
| 项目ID,补零(例如 |
| 项目短名称(例如 |
| 方案中的 |
| |
Dep resolution
依赖解析
deps: ["ADR-*"]ADR-deps: ["ADR-*"]ADR-Input-hash change detection
输入哈希变更检测
The orchestrator records the SHA-256 of every input artefact at build time and compares against the live filesystem on the next run. This catches the "user edited REQ after the build completed but never re-ran" case that pure idempotency misses.
test -f编排器会在构建时记录每个输入工件的SHA-256,并在下次运行时与实时文件系统对比。这可以捕获“用户在构建完成后编辑了REQ但从未重新运行”的情况,而单纯的幂等性无法检测到这种情况。
test -fWhat counts as an input
什么算作输入
A target's inputs are the resolved output paths of its (after glob expansion). Externally-supplied inputs (e.g. ) are not hashed by v0.4 — only artefacts the harness itself produced or recorded as . Recipes that surface external inputs should hash them in v0.5.
depsexternal/policies/*.mdsource: "pre-existing"目标的输入是其的解析输出路径(通配符展开后)。v0.4不计算外部提供的输入(例如)的哈希——仅计算管理工具自身生成或记录为的工件。涉及外部输入的方案应在v0.5中计算其哈希。
depsexternal/policies/*.mdsource: "pre-existing"What's recorded
记录内容
Each completed target's state entry gains an map of dep-ID → SHA-256:
input_hashesjson
"RISK": {
"status": "complete",
"path": "projects/001-arckit-saas/ARC-001-RISK-v1.0.md",
"input_hashes": {
"REQ": "9f2a...c41e",
"STKE": "1b88...07ad",
"PRIN": "44e7...bc92"
},
...
}The map is populated by the orchestrator (Bash ) immediately after a target validates in step 5 — workers don't compute hashes.
sha256sumcomplete每个已完成目标的状态条目会增加一个映射,键为依赖ID,值为SHA-256:
input_hashesjson
"RISK": {
"status": "complete",
"path": "projects/001-arckit-saas/ARC-001-RISK-v1.0.md",
"input_hashes": {
"REQ": "9f2a...c41e",
"STKE": "1b88...07ad",
"PRIN": "44e7...bc92"
},
...
}该映射由编排器(Bash )在目标验证为的步骤5后立即填充——工作节点不计算哈希。
sha256sumcompleteStaleness rules (skipped if --skip-hash-check
)
--skip-hash-check过期规则(如果使用--skip-hash-check
则跳过)
--skip-hash-checkAt work-list computation (step 7 of the run order):
- Start with .
done = { t ∈ state.targets : t.status == "complete" AND test -f t.path } - Direct staleness: for each , recompute SHA-256 for every entry in
t ∈ done. If any current hash differs from the recorded value (or the input file is now missing),t.input_hashesis stale — move it fromtback into pending and clear it fromdone(setstate.targets[t].status)."stale" - Propagated staleness: walk the DAG; any target whose deps (transitively) include a stale target is itself stale. Apply in topological order so a single REQ edit cascades to RISK, HLD, SOBC, PLAN, TRACE, …
- Targets explicitly named in are marked stale unconditionally (existing behaviour — overrides hash check).
--refresh NAME - With , skip steps 2–3 entirely.
--skip-hash-checkis whatever survives thedonefilter.test -f
Print the staleness reason in the output so users can see why a target rebuilt:
--plantext
Wave 1: REQ
(stale) REQ ← file edited since last build (sha mismatch)
Wave 3: RISK, HLD, STRATEGY, ...
(stale-cascade) RISK ← REQ changed since 2026-05-12T10:14:03Z在工作列表计算(运行顺序的步骤7)时:
- 初始。
done = { t ∈ state.targets : t.status == "complete" AND test -f t.path } - 直接过期:对于每个,重新计算
t ∈ done中每个条目的SHA-256。如果当前哈希与记录值不同(或输入文件现在缺失),则t.input_hashes为过期——将其从t移回pending,并将done清空(设置为state.targets[t].status)。"stale" - 传播过期:遍历DAG;任何依赖(传递性)包含过期目标的目标本身也会过期。按拓扑顺序应用,因此单个REQ编辑会级联到RISK、HLD、SOBC、PLAN、TRACE等。
- 明确指定的目标会无条件标记为过期(现有行为——覆盖哈希检查)。
--refresh NAME - 如果使用,则完全跳过步骤2–3。
--skip-hash-check是通过done过滤后的结果。test -f
在输出中打印过期原因,以便用户了解为何目标会被重建:
--plantext
Wave 1: REQ
(stale) REQ ← file edited since last build (sha mismatch)
Wave 3: RISK, HLD, STRATEGY, ...
(stale-cascade) RISK ← REQ changed since 2026-05-12T10:14:03ZPerformance note
性能说明
SHA-256 of typical ArcKit artefacts (≤500 KB markdown) is sub-millisecond per file. A 50-target project incurs <100 ms of hashing on . Workers do no hashing; only the orchestrator does (single shell loop in step 5/step 7).
--resume典型ArcKit工件(≤500 KB markdown)的SHA-256计算每个文件耗时不到1毫秒。一个50个目标的项目在时的哈希计算耗时<100毫秒。工作节点不进行哈希计算;仅编排器进行(步骤5/步骤7中的单个shell循环)。
--resumeWave plan algorithm
批次计划算法
Standard topological sort with parallelism:
- — where
pending = recipe.targets ∩ enabled - donereflectsenabled/--enableflags and--exclude, andoptional_targets[id].defaultis computed by the staleness rules in § "Input-hash change detection" (i.e.doneANDcompleteAND every input hash matches, unlesstest -fis set). Stale targets stay in--skip-hash-check.pending - from staleness computation above.
done - While pending non-empty:
- (after expanding globs)
wave = { t ∈ pending : deps(t) ⊆ done } - If wave empty → cycle / unresolvable. Halt with error, list involved targets.
- Emit wave; remove its members from pending; (after dispatch + validate) add to done.
Worked example — for project 001 (UK-SaaS recipe) starting from empty state, the algorithm produces something like:
- W0: PRIN
- W1: GLOSSARY, REQ, STKE
- W2: ADR-001..ADR-008 (parallel)
- W3: STRATEGY, WARDLEY, RISK, HLD, DEVOPS, FINOPS
- W4: SOBC, TCOP, SBD, DPIA, DIAG-C4, DIAG-SEQ
- W5: DIAG-DEP, PLAN, OPS, AIP (if enabled)
- W6: ROADMAP
- W7: SVCASS
- W8: TRACE
- W9 (post-build): health, pages
Treat this as illustrative only; the harness recomputes waves at runtime from the recipe DAG.
带并行性的标准拓扑排序:
- ——其中
pending = recipe.targets ∩ enabled - done反映enabled/--enable标志和--exclude,optional_targets[id].default由「输入哈希变更检测」章节中的过期规则计算(即doneANDcompleteAND 每个输入哈希匹配,除非设置了test -f)。过期目标保留在--skip-hash-check中。pending - 来自上述过期计算。
done - 当pending非空时:
- (通配符展开后)
wave = { t ∈ pending : deps(t) ⊆ done } - 如果wave为空→存在循环/无法解析。停止并报错,列出涉及的目标。
- 输出wave;将其成员从pending中移除;(调度+验证后)添加到done。
示例——对于项目001(UK-SaaS方案)从空状态开始,算法会生成类似以下的批次:
- W0: PRIN
- W1: GLOSSARY, REQ, STKE
- W2: ADR-001..ADR-008(并行)
- W3: STRATEGY, WARDLEY, RISK, HLD, DEVOPS, FINOPS
- W4: SOBC, TCOP, SBD, DPIA, DIAG-C4, DIAG-SEQ
- W5: DIAG-DEP, PLAN, OPS, AIP(如果启用)
- W6: ROADMAP
- W7: SVCASS
- W8: TRACE
- W9(构建后): health, pages
此示例仅作说明;管理工具会在运行时根据方案DAG重新计算批次。
Per-wave execution
每批次执行流程
For each wave, in order:
按顺序处理每个批次:
1. Plan dispatch
1. 计划调度
Print:
Wave {N}/{total}: {targets joined}
- estimated agents: {len(wave)}
- estimated duration: ~2-5 min wall-clock per agent (parallel)打印:
Wave {N}/{total}: {targets joined}
- estimated agents: {len(wave)}
- estimated duration: ~2-5 min wall-clock per agent (parallel)2. Single message, multiple Agent calls — all in parallel
2. 单消息多Agent调用——全部并行
Use the Agent tool with . One Agent call per target. All in the same assistant message so they run in parallel.
subagent_type: "general-purpose"Per-agent prompt template (substitute placeholders from the resolved target):
{...}You are an ArcKit artefact worker subagent (orchestrated by arckit-build, wave {WAVE_N}).
Project: {PROJECT_ID} ({PROJECT_NAME})
Target: {TARGET_ID}
Skill to invoke: {SKILL}
Skill args: {ARGS_RESOLVED}
Expected directory: {EXPECTED_DIR} # for orientation only — actual filename is hook-allocated
Inputs you may read (only these):
{INPUT_PATHS_BULLETED}
Steps:
1. Use the Skill tool to invoke `{SKILL}` with the args above verbatim.
**Interactive Q&A handling (CRITICAL — subagents have no user available):**
If the skill calls `AskUserQuestion`, you MUST select the option marked `(Recommended)`
without asking. If no option is marked Recommended, use these defaults:
| Question header | Default |
|-----------------|---------|
| Scope | `Full system` |
| Consultation | `Surveys` |
| Phase | value from skill args, else `alpha` |
| AI mode / scope | derive from REQ FRs (AI-in-scope iff any FR mentions AI/ML/LLM) |
| Risk appetite | `Medium` |
| Anything else | first option in the list |
Document the choice you made in your final report so the orchestrator can record it.
Never block waiting for an answer.
2. Capture the actual file path the skill wrote to. Inside the Write tool call,
the ArcKit `validate-arc-filename.mjs` PreToolUse hook normalizes the path
(allocates the next sequence number for multi-instance types like ADR/DIAG,
moves into the correct subfolder, pads project IDs). The hook returns the
corrected path as `updatedInput.file_path` and the actual write proceeds
there. You will see this corrected path in the Skill tool's result.
Read `ACTUAL_PATH` from that result. Do NOT call `generate-document-id.sh`
yourself or construct paths by string substitution — the hook is the
authoritative path allocator.
3. Sanity check the corrected path via Bash:
- `test -f "$ACTUAL_PATH"` returns success
- `[ "$(wc -l < "$ACTUAL_PATH")" -gt 100 ]`
- `grep -c '^## Document Control\|^| Document ID' "$ACTUAL_PATH"` returns ≥ 1
4. Do NOT git commit. Do NOT modify other files. The orchestrator handles version control.
Report back ≤ 200 words:
- Actual file path written + exact line count
- Top 3 findings, scores, or RAG ratings (whatever the skill produces as headline result)
- Validation result: PASS or FAIL (with reason)
- Any failures, partial completions, or warnings
- AskUserQuestion choices made (if any)
Do NOT include the document content in your report. Just the summary.使用Agent工具,设置。每个目标对应一个Agent调用。所有调用放在同一条助手消息中,以便并行运行。
subagent_type: "general-purpose"每个Agent的提示模板(替换解析后目标的占位符):
{...}You are an ArcKit artefact worker subagent (orchestrated by arckit-build, wave {WAVE_N}).
Project: {PROJECT_ID} ({PROJECT_NAME})
Target: {TARGET_ID}
Skill to invoke: {SKILL}
Skill args: {ARGS_RESOLVED}
Expected directory: {EXPECTED_DIR} # for orientation only — actual filename is hook-allocated
Inputs you may read (only these):
{INPUT_PATHS_BULLETED}
Steps:
1. Use the Skill tool to invoke `{SKILL}` with the args above verbatim.
**Interactive Q&A handling (CRITICAL — subagents have no user available):**
If the skill calls `AskUserQuestion`, you MUST select the option marked `(Recommended)`
without asking. If no option is marked Recommended, use these defaults:
| Question header | Default |
|-----------------|---------|
| Scope | `Full system` |
| Consultation | `Surveys` |
| Phase | value from skill args, else `alpha` |
| AI mode / scope | derive from REQ FRs (AI-in-scope iff any FR mentions AI/ML/LLM) |
| Risk appetite | `Medium` |
| Anything else | first option in the list |
Document the choice you made in your final report so the orchestrator can record it.
Never block waiting for an answer.
2. Capture the actual file path the skill wrote to. Inside the Write tool call,
the ArcKit `validate-arc-filename.mjs` PreToolUse hook normalizes the path
(allocates the next sequence number for multi-instance types like ADR/DIAG,
moves into the correct subfolder, pads project IDs). The hook returns the
corrected path as `updatedInput.file_path` and the actual write proceeds
there. You will see this corrected path in the Skill tool's result.
Read `ACTUAL_PATH` from that result. Do NOT call `generate-document-id.sh`
yourself or construct paths by string substitution — the hook is the
authoritative path allocator.
3. Sanity check the corrected path via Bash:
- `test -f "$ACTUAL_PATH"` returns success
- `[ "$(wc -l < "$ACTUAL_PATH")" -gt 100 ]`
- `grep -c '^## Document Control\|^| Document ID' "$ACTUAL_PATH"` returns ≥ 1
4. Do NOT git commit. Do NOT modify other files. The orchestrator handles version control.
Report back ≤ 200 words:
- Actual file path written + exact line count
- Top 3 findings, scores, or RAG ratings (whatever the skill produces as headline result)
- Validation result: PASS or FAIL (with reason)
- Any failures, partial completions, or warnings
- AskUserQuestion choices made (if any)
Do NOT include the document content in your report. Just the summary.3. Wait for all agents
3. 等待所有Agent返回
When all return, collect summaries.
所有Agent返回后,收集摘要。
4. Validate
4. 验证
For each target in wave:
- File exists at expected path ().
test -f - Line count > 100 ().
wc -l - Document control header present (≥ 1).
grep -c '^## Document Control'
对于批次中的每个目标:
- 文件存在于预期路径()。
test -f - 行数>100()。
wc -l - 存在文档控制头(≥ 1)。
grep -c '^## Document Control'
5. Update state.json
5. 更新state.json
Read , update each target with:
projects/{P}-{NAME}/.arckit/state.jsonjson
{
"<TARGET_ID>": {
"status": "complete",
"path": "{ACTUAL_PATH}",
"built_at": "{ISO_TIMESTAMP}",
"wave": {WAVE_N},
"line_count": {LC},
"skill": "{SKILL}",
"topic": "{TOPIC_OR_NULL}",
"agent_summary": "{≤200-word agent report}",
"input_hashes": {
"<DEP_ID>": "{SHA256_OF_state.targets[DEP_ID].path}"
}
}
}Compute via Bash on each resolved dep's immediately before persisting state. Skip deps whose target has no recorded path (e.g. external inputs). Targets with no deps get .
input_hashessha256sumstate.targets[DEP_ID].pathinput_hashes: {}For failures: , , — do not record for failed targets.
status: "failed"error: "..."wave: {WAVE_N}input_hashes读取,更新每个目标:
projects/{P}-{NAME}/.arckit/state.jsonjson
{
"<TARGET_ID>": {
"status": "complete",
"path": "{ACTUAL_PATH}",
"built_at": "{ISO_TIMESTAMP}",
"wave": {WAVE_N},
"line_count": {LC},
"skill": "{SKILL}",
"topic": "{TOPIC_OR_NULL}",
"agent_summary": "{≤200-word agent report}",
"input_hashes": {
"<DEP_ID>": "{SHA256_OF_state.targets[DEP_ID].path}"
}
}
}在持久化状态前,通过Bash 计算每个解析后依赖的的哈希,填充。跳过没有记录路径的依赖(例如外部输入)。没有依赖的目标的。
sha256sumstate.targets[DEP_ID].pathinput_hashesinput_hashes: {}对于失败的目标:, , ——不为失败目标记录。
status: "failed"error: "..."wave: {WAVE_N}input_hashes6. Git commit
6. Git提交
If not set:
--no-commitbash
git add {OUTPUT_PATHS} projects/{P}-{NAME}/.arckit/state.json
git commit -m "$(cat <<'EOF'
Build wave {N}: {targets joined} via arckit-build
{One-line per target with line count and headline result}
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"如果未设置:
--no-commitbash
git add {OUTPUT_PATHS} projects/{P}-{NAME}/.arckit/state.json
git commit -m "$(cat <<'EOF'
Build wave {N}: {targets joined} via arckit-build
{One-line per target with line count and headline result}
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"7. Halt-on-fail
7. 失败即停止
If any agent in the wave reported or validation failed:
FAIL- DO write state.json — record ,
status: "failed",error: "..."for failed targets, andwave: {WAVE_N}for the targets in the wave that did succeed. State is needed forstatus: "complete".--resume - Do NOT git commit (don't half-commit a wave). Successfully-written artefacts are left in the working tree; they get bundled into the resume commit.
- Surface to user: per-target outcome, error summary, suggested remediation.
- Suggest once fixed.
--resume - Stop the build.
如果批次中任何Agent报告或验证失败:
FAIL- 务必写入state.json——记录失败目标的,
status: "failed",error: "...",以及批次中成功完成的目标的wave: {WAVE_N}。状态是status: "complete"所需的。--resume - 不要进行git提交(不要提交批次的部分成果)。已成功写入的工件保留在工作树中;它们会被包含在恢复提交中。
- 告知用户:每个目标的结果、错误摘要、建议的补救措施。
- 建议修复后使用。
--resume - 停止构建。
8. Move to next wave
8. 进入下一批次
Otherwise, proceed.
否则,继续执行。
State file shape
状态文件结构
projects/{P}-{NAME}/.arckit/state.jsonjson
{
"state_format_version": "0.4",
"project_id": "001",
"project_name": "001-arckit-saas",
"recipe": "uk-saas",
"recipe_path": ".claude/skills/arckit-build/recipes/uk-saas.yaml",
"started_at": "2026-05-03T16:00:00Z",
"last_wave_completed": 5,
"current_wave": 6,
"targets": {
"PRIN": {"status": "complete", "path": "projects/000-global/ARC-000-PRIN-v1.0.md", "wave": 0, "source": "pre-existing", "input_hashes": {}},
"REQ": {"status": "complete", "path": "...", "wave": 1, "source": "pre-existing", "input_hashes": {"PRIN": "44e7...bc92"}},
"RISK": {"status": "complete", "path": "...", "wave": 3, "skill": "arckit:risk", "input_hashes": {"REQ": "9f2a...c41e", "STKE": "1b88...07ad", "PRIN": "44e7...bc92"}},
"SVCASS": {"status": "pending"}
},
"waves": [
{"n": 0, "targets": ["PRIN"], "status": "complete", "completed_at": "..."},
{"n": 3, "targets": ["RISK", "STRATEGY"], "status": "complete", "completed_at": "..."}
]
}State written by older versions () is read-compatible: targets without are treated as if all hashes match (no spurious rebuild on upgrade). The next successful build of any such target records its hashes and migrates the entry to 0.4 in place. The orchestrator rewrites to on first write.
state_format_version: "0.3"input_hashesstate_format_version"0.4"projects/{P}-{NAME}/.arckit/state.jsonjson
{
"state_format_version": "0.4",
"project_id": "001",
"project_name": "001-arckit-saas",
"recipe": "uk-saas",
"recipe_path": ".claude/skills/arckit-build/recipes/uk-saas.yaml",
"started_at": "2026-05-03T16:00:00Z",
"last_wave_completed": 5,
"current_wave": 6,
"targets": {
"PRIN": {"status": "complete", "path": "projects/000-global/ARC-000-PRIN-v1.0.md", "wave": 0, "source": "pre-existing", "input_hashes": {}},
"REQ": {"status": "complete", "path": "...", "wave": 1, "source": "pre-existing", "input_hashes": {"PRIN": "44e7...bc92"}},
"RISK": {"status": "complete", "path": "...", "wave": 3, "skill": "arckit:risk", "input_hashes": {"REQ": "9f2a...c41e", "STKE": "1b88...07ad", "PRIN": "44e7...bc92"}},
"SVCASS": {"status": "pending"}
},
"waves": [
{"n": 0, "targets": ["PRIN"], "status": "complete", "completed_at": "..."},
{"n": 3, "targets": ["RISK", "STRATEGY"], "status": "complete", "completed_at": "..."}
]
}旧版本()写入的状态文件是向前兼容的:没有的目标会被视为所有哈希匹配(升级时不会无故重建)。任何此类目标的下一次成功构建会记录其哈希,并将条目就地迁移到0.4版本。编排器在首次写入时会将重写为。
state_format_version: "0.3"input_hashesstate_format_version"0.4"When invoked, perform these steps in order
调用时按以下顺序执行步骤
-
Parse arguments from skill input (project, --plan, --resume, --recipe, --enable, --exclude, etc.). If project not specified, ask user.
-
Detect project: resolvearg →
<project>. Confirm directory exists.projects/{P}-{slug}/ -
Load recipe: resolve(default
--recipe NAME) against the precedence list. Read the YAML with the Read tool. Validate top-level shape (uk-saas,recipe,schema_version,targets). Halt with a clear error if the recipe file is missing or malformed.defaults.version -
Resolve enabled targets: dropwhose
optional_targetsunlessdefault: falsewas passed; drop--enable IDnamed inoptional_targets. Apply--exclude IDsubstitution to every{P}/{NAME}/{V}/{TOPIC}andargsfield.output.project -
Load state.json at. If absent, scan project dir for existing
projects/{P}-{NAME}/.arckit/state.jsonfiles and infer initial state.ARC-{P}-*-v*.md -
Subagent capability smoke-test (first wave only, skip on): before dispatching the real wave, spawn one throwaway
--resumeAgent with this prompt:general-purpose"Examine your system-reminder messages — they enumerate the skills available in this conversation. Return exactly one line:- if the list contains
AVAILABLE(or any otherarckit:principlesskill).arckit:* - otherwise. Do NOT invoke any skill. Do NOT call any tool other than reading your own context."
NOT_AVAILABLE
This is a metadata check, not a skill invocation — it should complete in seconds. If the response is, halt: subagents in this session do not have access to plugin skills (Failure mode #1). Suggest enabling the plugin at user-scope or running the harness from a session whereNOT_AVAILABLEshows theclaude --print '/skill list'family.arckit:* -
Compute work list: apply the staleness rules from § "Input-hash change detection".= targets where
doneAND file exists AND every recorded input hash still matches AND no transitive dep is stale (steps 2–3 of the staleness rules).status: complete=pending. Stale targets have theirenabled-targets − donerewritten tostate.targets[id].statusand re-enter the wave plan. With"stale", skip the hash + cascade checks (--skip-hash-checkonly).test -f -
If: print plan (each wave + targets + line
--plan), exit.(skip|build) target ← deps -
For each wave (sequential outer loop):
- Print wave header.
- Build the per-agent prompt for each target in wave.
- Send a single assistant message containing N Agent tool calls (one per target, all parallel).
- Collect summaries when all complete.
- Validate each output.
- Update state.json (Write tool).
- git commit (Bash) unless .
--no-commit - Halt if any fail.
-
Post-build hooks: spawn parallel agents — one perentry.
recipe.post_build_hooks[] -
Final report:
- Targets built (with line counts) / skipped / failed.
- Total wall-clock.
- Post-build hook outcomes.
- Next recommended action (e.g., "review pre-GA blockers in TCOP §Critical Issues").
-
解析参数:从Skill输入中解析参数(project、--plan、--resume、--recipe、--enable、--exclude等)。如果未指定project,提示用户输入。
-
检测项目:解析参数 →
<project>。确认目录存在。projects/{P}-{slug}/ -
加载方案:按优先级列表解析(默认
--recipe NAME)。使用Read工具读取YAML。验证顶层结构(uk-saas、recipe、schema_version、targets)。如果方案文件缺失或格式错误,停止并明确报错。defaults.version -
解析启用的目标:移除的
default: false,除非使用了optional_targets;移除--enable ID指定的--exclude ID。对每个optional_targets和args字段应用output.project替换。{P}/{NAME}/{V}/{TOPIC} -
加载state.json:读取。如果不存在,扫描项目目录查找现有的
projects/{P}-{NAME}/.arckit/state.json文件并推断初始状态。ARC-{P}-*-v*.md -
子Agent能力冒烟测试(仅第一个批次,时跳过):在调度实际批次前,生成一个临时的
--resumeAgent,提示如下:general-purpose"检查你的系统提醒消息——它们列出了此对话中可用的Skill。返回恰好一行:- 如果列表包含(或任何其他
arckit:principlesSkill),返回arckit:*。AVAILABLE - 否则返回。 不要调用任何Skill。除了读取自身上下文,不要调用任何工具。"
NOT_AVAILABLE
这是元数据检查,而非Skill调用——应在几秒内完成。如果响应是,停止:此会话中的子Agent无法访问插件Skill(失败模式#1)。建议在用户范围启用插件,或从NOT_AVAILABLE显示claude --print '/skill list'系列Skill的会话中运行管理工具。arckit:* - 如果列表包含
-
计算工作列表:应用「输入哈希变更检测」章节中的过期规则。= 满足
doneAND 文件存在 AND 每个记录的输入哈希仍匹配 AND 没有传递性依赖过期的目标(过期规则的步骤2–3)。status: complete=pending。过期目标的enabled-targets − done会被重写为state.targets[id].status并重新进入批次计划。如果使用"stale",跳过哈希+级联检查(仅--skip-hash-check)。test -f -
如果使用:打印计划(每个批次+目标+
--plan行),退出。(skip|build) target ← deps -
处理每个批次(顺序外层循环):
- 打印批次标题。
- 为批次中的每个目标构建Agent提示。
- 发送包含N个Agent工具调用的单条助手消息(每个目标一个,全部并行)。
- 所有完成后收集摘要。
- 验证每个输出。
- 更新state.json(Write工具)。
- 除非使用,否则执行git提交(Bash)。
--no-commit - 如果任何失败,停止。
-
构建后钩子:生成并行Agent——每个条目对应一个Agent。
recipe.post_build_hooks[] -
最终报告:
- 已构建(带行数)/跳过/失败的目标。
- 总耗时。
- 构建后钩子结果。
- 下一步建议操作(例如"查看TCOP §Critical Issues中的GA前阻塞项")。
Pairing with /goal
(Claude Code v2.1.139+)
/goal与/goal
配合使用(Claude Code v2.1.139+)
/goal/goal- "Build until APPROVED" — , then run
/goal every artefact under projects/001-*/ has Document Control Status: APPROVED and no Next Review Date in the past. The harness rebuilds stale targets;/arckit:build 001 --recipe uk-saas --resumekeeps re-running it until the post-condition holds./goal - "Refresh a stale slice" — , then
/goal no artefact under projects/001-*/ has been flagged by the stale-artifact-scan monitor(or whichever target the monitor flagged)./arckit:build 001 --refresh REQ - "Drive a project to GA" — wrap the build under a goal that also requires zero open violations and a green
/arckit:conformancescan;/arckit:healthwill sequence/goaluntil clean.build → conformance → health → refresh-violator → build
Caveats:
- is Claude Code only (not exposed in Codex / OpenCode / Gemini). Document the manual loop ("re-run
/goaluntil state.json shows all targets complete") for non-Claude runtimes./arckit:build --resume - Stop-hook block cap (v2.1.143, default 8) applies — if a Stop hook keeps blocking inside the goal loop the turn ends with a warning. ArcKit's Stop hooks (,
session-learner) are observational and never block, so the cap should not interfere.session-end-stamp - One per session; don't nest. The harness's own halt-on-fail still fires inside the goal loop.
/goal
/goal- "构建直到APPROVED" — ,然后运行
/goal every artefact under projects/001-*/ has Document Control Status: APPROVED and no Next Review Date in the past。管理工具会重建过期目标;/arckit:build 001 --recipe uk-saas --resume会持续重新运行,直到后置条件满足。/goal - "刷新过期切片" — ,然后运行
/goal no artefact under projects/001-*/ has been flagged by the stale-artifact-scan monitor(或监控标记的任何目标)。/arckit:build 001 --refresh REQ - "推动项目到GA" — 将构建包装在一个目标中,该目标还要求零个未解决的违规和绿色的
/arckit:conformance扫描;/arckit:health会按顺序执行/goal,直到全部通过。build → conformance → health → refresh-violator → build
注意事项:
- 仅适用于Claude Code(未在Codex/OpenCode/Gemini中提供)。对于非Claude运行时,记录手动循环步骤("重新运行
/goal直到state.json显示所有目标完成")。/arckit:build --resume - 停止钩子块限制(v2.1.143,默认8)适用——如果停止钩子在目标循环中持续阻塞,对话会以警告结束。ArcKit的停止钩子(、
session-learner)是观察性的,从不阻塞,因此限制不应造成干扰。session-end-stamp - 每个会话一个;不要嵌套。管理工具自身的失败即停止机制在目标循环中仍会生效。
/goal
Failure modes to watch for
需要关注的失败模式
- Subagent doesn't have access to skills — detected by the smoke-test in step 6 of the run order; halts the build before any wave dispatches. Workaround if smoke-test fails: load the skill prompt in main context once, pass as plain text to agent (deferred to v0.4+).
arckit:* - Recipe file missing or malformed — halt at step 3 with the exact YAML parse error and the precedence list of paths checked. If a community recipe is requested but the corresponding community plugin isn't installed, surface a concrete install command: . The orchestrator maps recipe name to expected plugin via the built-in recipes table; recipes the table doesn't know about fall back to the generic precedence-list error.
"Recipe 'uae-federal-ai' not found. It ships in the arckit-uae community plugin. Install with: claude plugin install arckit-uae" - Skill expects interactive Q&A — the worker prompt's defaults table covers this. The recipe's field should be specific enough to skip interaction in the first place.
args - Output path collision — two targets writing to same path. Recipe must have unique tuples for non-multi-instance targets, and unique
(output.project, output.type, output.subfolder, multi_instance)s for multi-instance ones.id - State drift — user manually deletes/edits artefacts after build. Deletions are caught by . Edits are caught by the SHA-256 hash check (§ "Input-hash change detection") — the edited artefact's downstream targets are marked stale and rebuilt in dep order. Use
test -fto bypass.--skip-hash-check - Cycle in dependencies — wave algorithm halts with "unresolvable cycle" error and lists the involved targets. Glob deps () are expanded before cycle detection.
ADR-*
- 子Agent无法访问Skill — 由运行顺序步骤6中的冒烟测试检测到;在调度任何批次前停止构建。如果冒烟测试失败的解决方法:在主上下文加载一次Skill提示,作为纯文本传递给Agent(推迟到v0.4+)。
arckit:* - 方案文件缺失或格式错误 — 在步骤3停止,返回确切的YAML解析错误和检查的优先级路径列表。如果请求的社区方案对应的社区插件未安装,显示具体的安装命令:。编排器通过内置方案表将方案名称映射到预期插件;表中未知的方案回退到通用优先级列表错误。
"Recipe 'uae-federal-ai' not found. It ships in the arckit-uae community plugin. Install with: claude plugin install arckit-uae" - Skill需要交互式问答 — 工作节点提示的默认值表覆盖了这种情况。方案的字段应足够具体以避免交互。
args - 输出路径冲突 — 两个目标写入同一路径。对于非多实例目标,方案必须有唯一的元组;对于多实例目标,必须有唯一的
(output.project, output.type, output.subfolder, multi_instance)。id - 状态漂移 — 用户在构建后手动删除/编辑工件。删除会被检测到。编辑会被SHA-256哈希检查(「输入哈希变更检测」章节)检测到——编辑工件的下游目标会被标记为过期并按依赖顺序重建。使用
test -f可以绕过。--skip-hash-check - 依赖循环 — 批次算法停止并报错"无法解析循环",列出涉及的目标。通配符依赖()在循环检测前展开。
ADR-*
Future versions
未来版本
- v0.4 (remaining): orchestrator-side fallback for skills inaccessible to subagents — load skill prompts in main context once and inline them in worker prompts when the smoke-test returns
arckit:*. (File-hash change detection shipped in v0.4 — see § "Input-hash change detection".)NOT_AVAILABLE - v0.5: cross-reference + schema validators between waves; recipe inheritance (); hash external inputs (e.g.
extends: uk-saas) in addition to dep artefacts.external/policies/*.md - v0.6: CI mode (for GitHub Actions).
--validate-only - v1.0: skills declare I/O in frontmatter; harness reads frontmatter directly; dedicated subagent type; recipe "Expected output path" computed from skill metadata (single source of truth).
arckit:artefact-worker
- v0.4(剩余功能):子Agent无法访问Skill时的编排器端回退——在主上下文加载一次Skill提示,当冒烟测试返回
arckit:*时,将其内联到工作节点提示中。(文件哈希变更检测已在v0.4中发布——见「输入哈希变更检测」章节。)NOT_AVAILABLE - v0.5:批次间的交叉引用+schema验证器;方案继承();除依赖工件外,还计算外部输入(例如
extends: uk-saas)的哈希。external/policies/*.md - v0.6:CI模式(GitHub Actions的)。
--validate-only - v1.0:Skill在前置声明I/O;管理工具直接读取前置内容;专用的子Agent类型;从Skill元数据计算方案的"预期输出路径"(单一事实来源)。
arckit:artefact-worker