Arckit Build logo

Arckit Build

CommunityPopular
tractorjuice
arckit-build

Bulk-builds a project's ArcKit artefacts in parallel from a YAML recipe: computes the artefact dependency DAG, dispatches one subagent per target per wave, validates each output, commits the wave and persists progress to .arckit/state.json so a build can resume. Manual only: run /arckit:arckit-build with --plan, --resume, --target, --refresh or --recipe. Not needed for a single artefact; run that /arckit:* command directly.

Overview

Publishertractorjuice
Repositoryarc-kit
Skill namearckit-build
Stars
2.2K
Forks
280
Bundled files
4
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 4 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by tractorjuice on GitHub. Read the source before you install it.

Installation

Install the Arckit Build AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/tractorjuice/arc-kit.git /tmp/arc-kit
mkdir -p .claude/skills
cp -r /tmp/arc-kit/plugins/arckit-claude/skills/arckit-build .claude/skills/arckit-build
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Arckit Build in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Arckit Build on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Arckit Build is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

ArcKit Build Harness (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.

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 projects/{P}-{NAME}/.arckit/state.json after every wave, before moving on.
  • Single message, multiple Agent calls for parallelism within a wave. Never loop sequential Agent calls.
  • Idempotency: if state says complete, 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".
  • Trust the path-allocation hook. ArcKit's validate-arc-filename.mjs 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 generate-document-id.mjs directly. Read the corrected path back from the Write tool result.

Args

ArgEffect
<project>Project directory name or numeric ID (e.g. 001 or 001-arckit-saas). If absent, prompt user.
--planDry run. Print the wave plan, do not dispatch any Agents, exit.
--resumeRead state.json; continue from last incomplete wave.
--target NAMEBuild only NAME and its missing dependencies.
--refresh NAMEForce-rebuild NAME and everything downstream.
--no-commitSkip the per-wave git commit.
--recipe NAMERecipe name (default uk-saas). Resolved against the precedence list below.
--enable IDEnable an optional target (e.g. --enable AIP).
--exclude IDExclude a default-on optional target (e.g. --exclude SVCASS).
--skip-hash-checkTreat any complete target with its output file present as up-to-date; skip SHA-256 staleness detection. Fast resume; risks missing edits to inputs.

Recipe loading

Recipes are external YAML files. Lookup precedence for --recipe NAME (first hit wins):

  1. Project override: .arckit/recipes/{NAME}.yaml — user customizations preserved across plugin updates.
  2. Core plugin: ${CLAUDE_PLUGIN_ROOT}/skills/arckit-build/recipes/{NAME}.yaml — recipes shipped with the arckit core plugin (uk-saas, uk-mod-sovereign).
  3. Sibling community plugins: ${CLAUDE_PLUGIN_ROOT}/../arckit-*/recipes/{NAME}.yaml — recipes shipped with installed community plugins (e.g. arckit-uae/recipes/uae-federal-ai.yaml, arckit-ca/recipes/ca-federal-fitaa.yaml).

Resolution: glob the parent directory of ${CLAUDE_PLUGIN_ROOT} for arckit-*/recipes/{NAME}.yaml 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.

Default recipe is uk-saas. To customize, copy the core default to .arckit/recipes/uk-saas.yaml and edit there:

bash
mkdir -p .arckit/recipes
cp "${CLAUDE_PLUGIN_ROOT}/skills/arckit-build/recipes/uk-saas.yaml" .arckit/recipes/uk-saas.yaml

Built-in recipes:

RecipePluginUse case
uk-saasarckit (core)UK Government managed multi-tenant SaaS — civilian departments
uk-mod-sovereignarckit (core)UK MOD / sovereign / air-gapped — mod-secure + jsp-936, no SVCASS, sealed-media distribution
uae-federal-aiarckit-uaeUAE 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-agentic-transformationarckit-uaeUAE 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
ca-federal-fitaaarckit-caCanadian Federal — FITAA, ITSG-33, GC Digital Standards
au-federalarckit-auAustralian Federal / DISP-supplier — ASD Essential Eight, ISM, DTA DSS, Privacy Act 1988, OAIC NDB, PSPF, AI Assurance, DISP attestation (35 targets, 9 waves)
au-energyarckit-au-energy (composes arckit-au baseline)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 SERVICE_INVENTORY (servicenow). 22 targets. First Australian sector overlay.
uk-nhs-clinical-safetyarckit (core, references arckit-uk-nhs commands)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.

Recipe schema (v1)

See ${CLAUDE_PLUGIN_ROOT}/skills/arckit-build/recipes/uk-saas.yaml for an annotated reference. Top-level keys:

  • recipe — recipe name (string, must match filename stem)
  • schema_version — recipe schema version (currently 1)
  • description — free text
  • defaults.version — default version stamp for outputs (e.g. "1.0")
  • optional_targets — map of target ID → {description, default}
  • post_build_hooks — list of {skill, args} to run after final wave (parallel)
  • targets — list of target entries

Each targets[] entry:

FieldRequiredNotes
idyesUnique target ID (e.g. PRIN, ADR-001, DIAG-C4)
skillyesArcKit skill name (e.g. arckit:requirements)
argsyesArgs string passed to the skill, after substitution
output.projectyes"000-global" or "{P}-{NAME}"
output.typeyesArcKit doc-type code (PRIN, REQ, ADR, DIAG, …) — used for state.json keys, NOT for path construction
output.subfoldernoOrientation hint shown in --plan and worker prompts; the actual subfolder is enforced by validate-arc-filename.mjs's SUBDIR_MAP at write time
output.multi_instancenoOrientation hint; the hook's MULTI_INSTANCE_TYPES list is authoritative
topicnoUsed in commit messages and {TOPIC} substitution
depsyesList of target IDs, may include glob "ADR-*"

The output.subfolder / output.multi_instance fields document recipe author intent for human readers and --plan output, but the path-allocation hook is the source of truth at write time. If a recipe says subfolder: decisions for a single-instance type the hook doesn't recognise, the file lands wherever the hook decides — debug via the hook, not the recipe.

Variable substitution

The orchestrator substitutes these placeholders in args and output.project before dispatching to workers (workers never see placeholders):

PlaceholderSource
{P}Project ID, zero-padded (e.g. "001")
{NAME}Project slug (e.g. "arckit-saas")
{V}defaults.version from the recipe
{TOPIC}target.topic (multi-instance ADR/DIAG topics)

Dep resolution

deps: ["ADR-*"] matches all targets whose ID begins with ADR-. Exact IDs take precedence; globs expand at wave-computation time against the resolved target list (after optional-target filtering).

An exact-ID dep naming an optional target orders the build only while that target is enabled: disabled optional-target IDs are pruned from every remaining target's deps at resolution time (step 4 below). A recipe may therefore declare the true ordering — OAGOV deps [OAAL, OASEC] in oaa-full — without --exclude OASEC leaving OAGOV waiting forever on a target that will never run. A dep naming a non-optional target that doesn't exist in the recipe is still an error.

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 test -f idempotency misses.

What counts as an input

A target's inputs are the resolved output paths of its deps (after glob expansion). Externally-supplied inputs (e.g. external/policies/*.md) are not hashed by v0.4 — only artefacts the harness itself produced or recorded as source: "pre-existing". Recipes that surface external inputs should hash them in v0.5.

What's recorded

Each completed target's state entry gains an input_hashes map of dep-ID → SHA-256:

json
"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 sha256sum) immediately after a target validates complete in step 5 — workers don't compute hashes.

Staleness rules (skipped if --skip-hash-check)

At work-list computation (step 7 of the run order):

  1. Start with done = { t ∈ state.targets : t.status == "complete" AND test -f t.path }.
  2. Direct staleness: for each t ∈ done, recompute SHA-256 for every entry in t.input_hashes. If any current hash differs from the recorded value (or the input file is now missing), t is stale — move it from done back into pending and clear it from state.targets[t].status (set "stale").
  3. 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, …
  4. Targets explicitly named in --refresh NAME are marked stale unconditionally (existing behaviour — overrides hash check).
  5. With --skip-hash-check, skip steps 2–3 entirely. done is whatever survives the test -f filter.

Print the staleness reason in the --plan output so users can see why a target rebuilt:

text
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

Performance 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 --resume. Workers do no hashing; only the orchestrator does (single shell loop in step 5/step 7).

Wave plan algorithm

Standard topological sort with parallelism:

  1. pending = recipe.targets ∩ enabled - done — where enabled reflects --enable/--exclude flags and optional_targets[id].default, and done is computed by the staleness rules in § "Input-hash change detection" (i.e. complete AND test -f AND every input hash matches, unless --skip-hash-check is set). Stale targets stay in pending.
  2. done from staleness computation above.
  3. While pending non-empty:
    • wave = { t ∈ pending : deps(t) ⊆ done } (after expanding globs)
    • If wave empty → cycle / unresolvable. Halt with error, list involved targets.
    • If |wave| > 20, split it: dispatch the first 20 (stable sort by target ID), and leave the remainder in pending for the next iteration. They have no unmet deps, so they form the next wave immediately.
    • Emit wave; remove its members from pending; (after dispatch + validate) add to done.

Why the 20 cap is load-bearing. Claude Code caps concurrently-running subagents at 20 by default (CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS, v2.1.217+) and denies over-cap spawns rather than queueing them — the 21st Agent call in a single message fails with "Concurrent subagent limit reached … Do not retry". Because this harness is halt-on-fail, an over-wide wave does not run slower, it fails. No bundled recipe exceeds 16 (CI enforces this via scripts/check_recipes.py), but a user-authored recipe under .arckit/recipes/ never passes through CI, so split at dispatch time rather than assuming the recipe is well-formed.

There is no longer a per-session spawn ceiling to budget against: Claude Code v2.1.224 removed the 200-subagent-per-session cap, and CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION is now accepted in settings but never read. Concurrency (above) and nesting depth are the only subagent limits left. Do not reintroduce a per-session budget check here.

A split wave is still one commit — commit after the whole logical wave completes, not after each chunk of 20.

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.

Per-wave execution

For each wave, in order:

1. Plan dispatch

Print:

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

Use the Agent tool with subagent_type: "general-purpose". One Agent call per target. All in the same assistant message so they run in parallel.

Pass run_in_background: false on every call in the wave. Claude Code v2.1.232 made non-teammate Agent spawns background-by-default in interactive sessions — a backgrounded spawn returns async_launched and an agentId, not the worker's report. This harness needs the reports before it can validate, commit, and decide whether to halt, so a wave is exactly the case the parameter exists for. The parameter is stripped from the tool schema in some contexts; if it is unavailable, the spawns are background-only and you must wait for every worker's completion notification before step 3 — do not proceed on async_launched results, and never infer a worker's outcome from the fact that it launched.

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.
   This is the non-interactive rule of `${CLAUDE_PLUGIN_ROOT}/references/interview-pattern.md`;
   the table above wins where it names a header.

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.mjs`
   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

When all return, collect summaries. "Return" means the worker's ≤200-word report is in hand — not that its Agent call succeeded. A launch acknowledgement is not a result (see the run_in_background note in step 2).

4. Validate

For each target in wave:

  • File exists at expected path (test -f).
  • Line count > 100 (wc -l).
  • Document control header present (grep -c '^## Document Control' ≥ 1).

5. Update state.json

Read projects/{P}-{NAME}/.arckit/state.json, update each target with:

json
{
  "<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 input_hashes via Bash sha256sum on each resolved dep's state.targets[DEP_ID].path immediately before persisting state. Skip deps whose target has no recorded path (e.g. external inputs). Targets with no deps get input_hashes: {}.

For failures: status: "failed", error: "...", wave: {WAVE_N} — do not record input_hashes for failed targets.

6. Git commit

If --no-commit not set:

bash
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 Code <noreply@anthropic.com>
EOF
)"

7. Halt-on-fail

If any agent in the wave reported FAIL or validation failed:

  • DO write state.json — record status: "failed", error: "...", wave: {WAVE_N} for failed targets, and status: "complete" for the targets in the wave that did succeed. State is needed for --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 --resume once fixed.
  • Stop the build.

8. Move to next wave

Otherwise, proceed.

State file shape

projects/{P}-{NAME}/.arckit/state.json:

json
{
  "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 (state_format_version: "0.3") is read-compatible: targets without input_hashes 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 state_format_version to "0.4" on first write.

When invoked, perform these steps in order

  1. Parse arguments from skill input (project, --plan, --resume, --recipe, --enable, --exclude, etc.). If project not specified, ask user.

  2. Detect project: resolve <project> arg → projects/{P}-{slug}/. Confirm directory exists.

  3. Load recipe: resolve --recipe NAME (default uk-saas) against the precedence list. Read the YAML with the Read tool. Validate top-level shape (recipe, schema_version, targets, defaults.version). Halt with a clear error if the recipe file is missing or malformed.

  4. Resolve enabled targets: drop optional_targets whose default: false unless --enable ID was passed; drop optional_targets named in --exclude ID. Then prune every dropped optional-target ID from the remaining targets' deps lists — a dep on an optional target orders the build only when that target is enabled; without pruning, the dependent target's deps could never all be done and it would sit in pending forever. Apply {P}/{NAME}/{V}/{TOPIC} substitution to every args and output.project field.

  5. Load state.json at projects/{P}-{NAME}/.arckit/state.json. If absent, scan project dir for existing ARC-{P}-*-v*.md files and infer initial state.

  6. Subagent capability smoke-test (first wave only, skip on --resume): before dispatching the real wave, spawn one throwaway general-purpose Agent with this prompt:

    "Examine your system-reminder messages — they enumerate the skills available in this conversation. Return exactly one line:

    • AVAILABLE if the list contains arckit:principles (or any other arckit:* skill).
    • NOT_AVAILABLE otherwise. Do NOT invoke any skill. Do NOT call any tool other than reading your own context."

    This is a metadata check, not a skill invocation — it should complete in seconds. If the response is NOT_AVAILABLE, 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 where claude --print '/skill list' shows the arckit:* family.

  7. Compute work list: apply the staleness rules from § "Input-hash change detection". done = targets where status: complete AND file exists AND every recorded input hash still matches AND no transitive dep is stale (steps 2–3 of the staleness rules). pending = enabled-targets − done. Stale targets have their state.targets[id].status rewritten to "stale" and re-enter the wave plan. With --skip-hash-check, skip the hash + cascade checks (test -f only).

  8. If --plan: print plan (each wave + targets + line (skip|build) target ← deps), exit.

  9. 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.
  10. Post-build hooks: spawn parallel agents — one per recipe.post_build_hooks[] entry.

  11. 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").

Pairing with /goal (Claude Code v2.1.139+)

/goal keeps Claude working across turns until a completion condition is met, showing live elapsed / turns / tokens overhead. It composes naturally with this build harness when the user's intent stretches beyond a single recipe pass:

  • "Build until APPROVED"/goal every artefact under projects/001-*/ has Document Control Status: APPROVED and no Next Review Date in the past, then run /arckit:build 001 --recipe uk-saas --resume. The harness rebuilds stale targets; /goal keeps re-running it until the post-condition holds.
  • "Refresh a stale slice"/goal no artefact under projects/001-*/ has been flagged by the stale-artifact-scan monitor, then /arckit:build 001 --refresh REQ (or whichever target the monitor flagged).
  • "Drive a project to GA" — wrap the build under a goal that also requires zero open /arckit:conformance violations and a green /arckit:health scan; /goal will sequence build → conformance → health → refresh-violator → build until clean.

Caveats:

  • /goal is Claude Code only (not exposed in Codex / OpenCode / Gemini). Document the manual loop ("re-run /arckit:build --resume until state.json shows all targets complete") for non-Claude runtimes.
  • 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, session-end-stamp) are observational and never block, so the cap should not interfere.
  • One /goal per session; don't nest. The harness's own halt-on-fail still fires inside the goal loop.

Failure modes to watch for

  • Subagent doesn't have access to arckit:* 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+).
  • 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: "Recipe 'uae-federal-ai' not found. It ships in the arckit-uae community plugin. Install with: claude plugin install arckit-uae". 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.
  • Skill expects interactive Q&A — the worker prompt's defaults table covers this. The recipe's args field should be specific enough to skip interaction in the first place.
  • Output path collision — two targets writing to same path. Recipe must have unique (output.project, output.type, output.subfolder, multi_instance) tuples for non-multi-instance targets, and unique ids for multi-instance ones.
  • State drift — user manually deletes/edits artefacts after build. Deletions are caught by test -f. 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 --skip-hash-check to bypass.
  • Cycle in dependencies — wave algorithm halts with "unresolvable cycle" error and lists the involved targets. Glob deps (ADR-*) are expanded before cycle detection.

Future versions

  • v0.4 (remaining): orchestrator-side fallback for skills inaccessible to subagents — load arckit:* skill prompts in main context once and inline them in worker prompts when the smoke-test returns NOT_AVAILABLE. (File-hash change detection shipped in v0.4 — see § "Input-hash change detection".)
  • v0.5: cross-reference + schema validators between waves; recipe inheritance (extends: uk-saas); hash external inputs (e.g. external/policies/*.md) in addition to dep artefacts.
  • v0.6: CI mode (--validate-only for GitHub Actions).
  • v1.0: skills declare I/O in frontmatter; harness reads frontmatter directly; dedicated arckit:artefact-worker subagent type; recipe "Expected output path" computed from skill metadata (single source of truth).

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Arckit Build AI skill do?

Bulk-builds a project's ArcKit artefacts in parallel from a YAML recipe: computes the artefact dependency DAG, dispatches one subagent per target per wave, validates each output, commits the wave and persists progress to .arckit/state.json so a build can resume. Manual only: run /arckit:arckit-build with --plan, --resume, --target, --refresh or --recipe. Not needed for a single artefact; run that /arckit:* command directly.

Why use Arckit Build on TypingMind?

Because you install it once and use it with any model. Arckit Build is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Arckit Build in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/tractorjuice/arc-kit/tree/main/plugins/arckit-claude/skills/arckit-build. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Arckit Build?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Arckit Build?

As many as you like. As long as a model supports skills, you can use Arckit Build with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Arckit Build AI skill free?

It is published on GitHub by tractorjuice. Check the repository for licensing terms. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇