Skip to content

Install and Lifecycle

The native release channel installs an aidlc command and one or more harness runtimes. aidlc config then creates or refreshes a project from that local runtime. The installed command and config path do not require Bun or Node.js. GitHub CLI (gh) is optional. A compatible version adds signed attestation verification; missing or older versions do not block installation.

This chapter describes the native install lifecycle available in this release. The planned aidlc setup experience, npm package, and package-manager formulas are not available yet. Manual-copy users install Bun and take the versioned, Bun-invoking runtime from aidlc-copy-runtime-X.Y.Z.tar.gz; they do not need the native aidlc command.

Install

Release assets cover:

  • macOS x64 and arm64
  • Linux x64 and arm64, with glibc and musl builds
  • Windows x64

Native installs are per-user. The Unix installer refuses root and does not need sudo. Windows installation targets the account running PowerShell. Run it from a normal PowerShell window. A window opened with "Run as administrator" under UAC is warned that installing as administrator is less safe, because another program running as the same account could interfere with files the elevated installer runs, and asked to confirm. -Yes confirms without a prompt; a non-interactive run without -Yes (including -Json and -Quiet) stops with that guidance. aidlc uninstall gives the same warning in its confirmation, or in its result with --yes. Sessions that already hold a full administrator token without UAC elevation, such as the built-in Administrator on Windows Server, see no warning. Running PowerShell with another account's credentials installs for that account. There is no all-users mode.

Alpine Linux's musl asset follows Bun's own runtime contract: Bun's musl build, like Node.js, requires the system libgcc and libstdc++ packages. Fully static Bun musl compile targets remain an upstream-tracked feature rather than an available target today. Install the prerequisites before running the installer or binary:

apk add libgcc libstdc++

This prerequisite applies to both x64 and arm64 Alpine systems. Installing the system packages may require administrator rights, but the AI-DLC install itself still runs as the target user. The installer detects the corresponding loader failure and prints the command above; it never runs apk or installs system packages. The upstream Bun tracking includes oven-sh/bun#15829 and oven-sh/bun#29681.

The installer includes claude, kiro, kiro-ide, codex, and opencode together:

tmp="$(mktemp -d)"
curl -fsSL \
  https://github.com/awslabs/aidlc-workflows/releases/latest/download/install.sh \
  -o "$tmp/install.sh"
sh "$tmp/install.sh"
rm -rf "$tmp"

macOS and Linux

tmp="$(mktemp -d)"
curl -fsSL \
  https://github.com/awslabs/aidlc-workflows/releases/latest/download/install.sh \
  -o "$tmp/install.sh"
sh "$tmp/install.sh"
rm -rf "$tmp"
export PATH="$HOME/.local/bin:$PATH"

An online run needs curl or wget; every run needs sha256sum or shasum. GitHub CLI is optional and used only when it supports the release's required attestation flags. It installs versions under ${XDG_DATA_HOME:-$HOME/.local/share}/aidlc/versions/ and links $HOME/.local/bin/aidlc to the active version by default.

The installer does not edit a shell startup file unless --profile <absolute-path-under-$HOME> is explicit. That option writes or updates one BEGIN AI-DLC:PATH block transactionally and preserves the rest of the file. The profile cannot be inside the AI-DLC install or command roots; existing markers must be unique, exact full lines, and ordered begin-before-end. Malformed marker layouts are refused without changing the profile.

Windows PowerShell

$download = Join-Path $env:TEMP "aidlc-install-$PID"
New-Item -ItemType Directory -Force $download | Out-Null
$installer = Join-Path $download install.ps1
Invoke-WebRequest `
  -Uri https://github.com/awslabs/aidlc-workflows/releases/latest/download/install.ps1 `
  -OutFile $installer
& $installer
Remove-Item -Recurse -Force $download

Windows installs versions under %LOCALAPPDATA%\aidlc\versions\ and keeps a stable %LOCALAPPDATA%\aidlc\bin\aidlc.cmd shim. After successful verification and installation, the installer registers that bin directory in the current account's persistent User PATH, preserving existing entries and avoiding duplicates on reruns. It also updates the current PowerShell process and notifies Windows of the environment change for new terminals. If another session cannot find aidlc, open a new terminal; restart the terminal app or IDE if needed. It does not change Machine PATH or edit a PowerShell profile.

Successful human output starts with Installed, the version, the account, and the installed command path. Next, run aidlc config from your project directory. Restart guidance applies only if another terminal or IDE cannot find the command.

The installer writes windows-path.json under the install root only when it adds a User PATH entry. This ownership record survives reruns, including -NoModifyPath, so uninstall can remove the entry later. An entry that was already present is not claimed. Both aidlc uninstall and aidlc uninstall --purge remove the recorded entry while preserving pre-existing entries and later unrelated PATH changes.

If another aidlc command takes precedence in persistent PATH, the result names it and gives the installed command's full path. Resolve that PATH conflict or invoke the installed command directly. If PATH registration fails, the installer reports that the files were installed but PATH still needs configuration, with a recovery instruction and exit code 1.

To skip both persistent and current-process PATH changes, replace & $installer above with & $installer -NoModifyPath. The installer prints a direct command to run without PATH registration. For the default location:

& "$env:LOCALAPPDATA\aidlc\bin\aidlc.cmd" config

Use the printed command path if you changed the install location. Rerun the installer without -NoModifyPath to enable automatic PATH registration. The switch does not undo an earlier registration or erase its ownership record.

PowerShell installer parameters use their native names, such as -Version, -From, -Offline, -ReleaseBaseUrl, -CaBundle, -NoModifyPath, -Yes, -Quiet, -Json, and -NoColor.

An installer downloaded from a versioned release URL defaults to that exact release, including previews. The latest/download installer continues to select the latest stable release. An explicit --version / -Version selection overrides the packaged default, while --from / -From reads the version from the local release manifest.

Automation

Installation asks no harness question. Human and non-interactive runs install the same binary plus all harness runtimes.

For temporary or isolated Windows installs, pass -NoModifyPath and invoke the reported aidlc.cmd path directly to keep the temporary bin directory out of User PATH and the current process.

PowerShell -Json emits one result with schemaVersion: 1, ok, code, status, and message. After the files are installed, data contains:

Field Meaning
installed true, including when the subsequent PATH step fails
ready Whether the recommended command is ready to use; false for a PATH conflict or failure
version, account, installRoot, command Installed version, Windows account, install root, and full command path
path.scope "user"
path.status "updated", "unchanged", "skipped", "conflict", or "failed"
path.changed Whether this run changed persistent User PATH
path.owned Whether this run confirmed installer ownership; null when -NoModifyPath leaves an earlier record unassessed
nextSteps An array of instructions, including project configuration or PATH recovery

Successful registration or an existing matching PATH normally uses status: "ok" and exit code 0. If Windows cannot notify other applications, the result uses status: "warning" with data.ready: true and a conditional sign-out instruction. A persistent command conflict uses status: "warning", exit code 0, and data.ready: false; automation should inspect readiness as well as the exit code. -NoModifyPath uses status: "ok", path.status: "skipped", and data.ready: true, with a direct command in nextSteps. A PATH failure after installation uses status: "failed", exit code 1, data.installed: true, and data.ready: false.

Installer Options

Unix PowerShell Meaning
--version <version> -Version <version> Install one exact release instead of latest: a stable x.y.z or a preview x.y.z-preview.YYYYMMDD.N id
--from <dir> -From <dir> Read a flat release set locally and imply offline mode
--offline -Offline Forbid network access; requires --from / -From
--release-base-url <url> -ReleaseBaseUrl <url> Use a compatible release mirror
--ca-bundle <absolute-path> -CaBundle <absolute-path> Use a custom CA bundle
--profile <absolute-path> Not available Transactionally add the Unix PATH block
Not available -NoModifyPath Skip persistent User PATH and current-process PATH changes; print a direct command
--yes -Yes Automation mode; it does not bypass integrity checks
--quiet -Quiet Suppress progress and emit one result line
--json -Json Suppress progress and emit one schema-versioned JSON result
--no-color -NoColor Disable color output
--help Not exposed Print Unix installer usage

AIDLC_RELEASE_BASE_URL and AIDLC_CA_BUNDLE provide installer defaults; explicit options win. AIDLC_RELEASE_REPOSITORY selects both the GitHub repository used for default downloads and the repository trusted by provenance verification. It defaults to awslabs/aidlc-workflows. AIDLC_RELEASE_WORKFLOW overrides the trusted signer workflow. By default, installers select <AIDLC_RELEASE_REPOSITORY>/.github/workflows/release.yml for stable versions and <AIDLC_RELEASE_REPOSITORY>/.github/workflows/preview-release.yml for preview versions. Set the override explicitly for a fork or mirror whose workflow path differs, together with its release base URL; changing the download URL alone does not change the provenance trust root. AIDLC_GH_BIN selects an explicit GitHub CLI executable for both installers. If that executable is missing or lacks --signer-workflow, --source-ref, or --source-digest, provenance verification is skipped while checksum verification remains mandatory.

Fork releases need no GitHub App or additional repository. The tag workflow publishes to the same repository with its short-lived GITHUB_TOKEN. Its final job uses the release environment, which can require reviewer approval before publication.

AIDLC_INSTALL_ROOT and AIDLC_BIN_DIR override the machine and command locations. Those paths must be absolute on Unix. On Windows, the selected bin directory is registered in the current account's User PATH unless -NoModifyPath is set. The PowerShell installer also honors AIDLC_OFFLINE=1; the Unix installer requires the explicit --offline or --from spelling.

Release Authentication

The installer:

  1. Downloads or reads version.json, checksums.txt, and aidlc-release.intoto.jsonl.
  2. When a compatible GitHub CLI is available, verifies the checksums.txt attestation against the repository and signer workflow.
  3. Verifies the version.json SHA-256, reads its version id and source identity, and rejects an explicit version mismatch before downloading or executing a release binary.
  4. Requires sourceRef to equal refs/tags/v<version> for stable releases or refs/heads/main for previews and, when provenance verification is available, re-verifies the attestation against that ref and the authenticated sourceDigest.
  5. Verifies the selected binary and harness archives by SHA-256 and declared byte length.
  6. Lets the verified binary validate and transactionally install the release.

To authenticate the bootstrap script itself before execution, use a current GitHub CLI:

tmp="$(mktemp -d)"
tag="$(gh release view --repo awslabs/aidlc-workflows --json tagName --jq .tagName)"
gh release download "$tag" --repo awslabs/aidlc-workflows --dir "$tmp" \
  --pattern install.sh --pattern aidlc-release.intoto.jsonl
gh attestation verify "$tmp/install.sh" \
  --bundle "$tmp/aidlc-release.intoto.jsonl" \
  --repo awslabs/aidlc-workflows \
  --signer-workflow awslabs/aidlc-workflows/.github/workflows/release.yml \
  --source-ref "refs/tags/$tag"
sh "$tmp/install.sh" --version "${tag#v}"
rm -rf "$tmp"

Metadata is limited to 1 MiB and individual release assets to 1 GiB. Asset names cannot contain paths. Archive extraction rejects links, special files, path traversal, absolute paths, duplicate entries, and oversized expansion.

The release workflow assembles the candidate once. Staging and Unix/Windows lifecycle jobs verify checksums.txt and test those bytes without signing permissions. They add a job-local verifier fixture because the real attestation is created after those tests. The fixture is never uploaded. publish re-verifies the candidate, attests it, exports aidlc-release.intoto.jsonl, validates the complete inventory, and uploads one workflow artifact. release rechecks the tag and checksums, creates the GitHub Release in this repository with GITHUB_TOKEN, and compares the local and remote asset inventories. The bundle remains outside version.json and checksums.txt: those files cover the installable artifacts, while the bundle is its own Sigstore trust channel. Online transport enforces TLS and every install enforces SHA-256; compatible GitHub CLI versions add signed provenance verification. OS code-signing and notarization are not part of the release. See Supply-Chain Security.

The installer refuses an existing mixed-ownership command. It also yields to an existing Homebrew or Nix command instead of replacing it. This project does not yet ship those package-manager channels; use the owning manager or choose an explicit empty AIDLC_BIN_DIR.

Configure or Refresh a Project

Run config before opening the harness:

cd your-project
aidlc config --dry-run --json
aidlc config
aidlc doctor

aidlc config is local-only and transactional. It creates the selected harness tree, the aidlc/ workspace shell, root integrations, a projection stamp, and an ownership baseline. It does not create a workflow intent.

When more than one harness is present, every aidlc config invocation must include --harness <name>, including previews and refreshes. See Root Integrations and Ownership for which harnesses can coexist and how their shipped .gitignore entries are combined.

After a successful scaffold or refresh, config runs a cheap installed-result sweep. It checks only the non-interactive hook PATH, host trust files, and recorded provider actions; it does not spawn the harness CLI or contact a provider. The transaction still exits 0. Non-TTY human output names every outstanding item and the exact aidlc config runtime, aidlc config trust, or aidlc config providers --check follow-up. JSON includes data.outstandingActions. Quiet output stays one line when clean and appends one outstanding-actions line when follow-up is required.

On a human TTY, a bare first run starts with detection rather than questions: installed harness CLIs on PATH, project state, local AWS credentials and regions, and the non-interactive hook runtime. With one detected harness, the wizard names it and offers three choices: recommended defaults, six-step customization, or exit with nothing written. Multiple detected harnesses get a numbered harness picker first; no detected harness gets the complete picker without a default.

Recommended defaults preserve the harness's current model provider. Customization walks Harness, Model provider, Model effort preset, Plugins, MCP servers, and the model-preset settings layer. The provider step offers keeping the current provider first and Amazon Bedrock second. Every numbered prompt has a bracketed default, invalid input re-asks in place, and each answer is echoed. A check-your-answers table accepts Enter to apply or a step number to edit. No files are written before that final gate. After apply, gerund receipts name the project files and model-preset settings layer, genuinely blocking actions follow, then the wizard prints the exact harness launch and first workflow command.

Step 3 also offers a fourth option, unchanged, which records no preset and preserves existing model settings; projects without model policy use shipped defaults. balanced remains the recommended default.

An existing-project rerun keeps the eight-row map for Harnesses, Models, Runtime, Flags, Project, Providers, Trust, and Workspace. Rows are lowercase [ok] or [needs]; one default-yes gate walks only Models, Runtime, Providers, and Trust findings. Workspace is reported, never walked: a missing aidlc/spaces/default/memory/ shell is repaired by an explicit aidlc config --harness <name> refresh, not by a question, and while the shell is incomplete the gate is not offered at all: its sections would either fail on the missing directory or, with no-op answers, rebuild nothing. The ledger then leads with the rebuild command. On a Bun-invoking projection, one copied from the runtime/<name>/ root of aidlc-copy-runtime-X.Y.Z.tar.gz or from a checkout's dist/<name>/ tree, there is no installed runtime to refresh from, so that command also carries --download, which fetches and verifies the copy runtime for the project's release; a native install refreshes from its installed runtime without it. A missing aidlc/ root is counted once: the Trust section's own workspace-root-missing issue is folded into the Workspace row. The Providers row reads [ok] with no recorded answer on Kiro CLI and Kiro IDE, which provide their own model access. Runtime leads with the immediate action and points to aidlc config runtime --show for diagnostics. The closing ledger is a compact label-to-command list. Section-named commands, non-TTY runs, --dry-run, --json, and --quiet keep their deterministic output and never render the interactive wizard.

Config Options

Option Meaning
--project-dir <path> Target this project instead of the current directory
--harness <name> Select an installed harness runtime
--from <dir-or-tgz> Use local release files instead of an installed runtime: aidlc-copy-runtime-X.Y.Z.tar.gz (checked against a .sha256 beside it), its extracted runtime/ folder, or one projection directory or archive
--download Fetch and verify the release the project needs when this machine lacks it, then finish the command; applying a dry run's plan token needs it again
--mcp defaults\|none Add or omit Claude's optional shipped MCP entries
--dry-run Calculate the complete plan without creating the target directory or changing bytes
--plan-token <token> Apply only the exact plan approved from a JSON dry run
--force Replace locally modified framework-owned files and managed blocks where that policy permits
--yes Confirm an otherwise unrecognized target directory or a section mutation; it does not imply MCP consent or choose a section answer
--json Emit one result object with counts, actions, data.notes, and data.planToken
--quiet Emit one summary or remediation line
--no-color Disable color output

Model Policy

aidlc config models records model policy in the selected settings layer (aidlc.settings.json for --project) and applies it through the normal config plan, confirmation, refresh guard, and transaction. It never contacts a model provider.

The public groups are:

Group Agents Shipped tier
Deciding 9 design, implementation, product, security, and quality agents judgment
Reviewing product lead and architecture reviewer balanced
Writing up delivery, pipeline and deploy, and operations templated

Policy resolves per agent in this order:

  1. Per-agent exception
  2. Group dial, set directly or through a preset
  3. Shipped tier default
  4. Session inherit

Pins bind in both directions. A pinned agent stays pinned if the session later moves to a larger model. The framework never raises an agent above the session on its own. With no recorded policy, Deciding and Writing up inherit; only the measured reviewing tier baseline ships a step-down. The first-run wizard's default choice records the balanced preset, which sets all three groups to medium effort.

aidlc config models --show
aidlc config models --reviewing-effort xhigh --project --yes
aidlc config models --agent architect --effort xhigh --model provider/raw-id --project --yes
aidlc config models --check
aidlc config models --reset --project --yes

--show --json prints every agent's effective model, effort, and provenance. --check is the CI inverse and exits non-zero when the recorded policy is not fully reflected in the harness surfaces.

Model and flag policy resolves leaf-by-leaf through this hierarchy:

  1. Shipped defaults in the tier and preset tables
  2. Machine ${AIDLC_INSTALL_ROOT:-~/.local/share/aidlc}/aidlc.settings.json
  3. Project aidlc.settings.json
  4. Personal aidlc.settings.local.json
  5. Environment variables

The project file is committed team policy. The local file is personal and is added to .gitignore when the config command creates it. Mutations require exactly one of --project, --local, or --global; the interactive wizard asks for the layer and recommends project policy inside a repository. Outside a recognized project only the machine layer is valid, so --global is inferred. --show labels each effective value with its winning source.

All three files use one strict schema. Unknown keys fail closed, and update/release keys such as offline and release-base-url are machine-only. Editors can reference the generated <harness>/tools/data/aidlc-settings.schema.json; no defaults settings file is written.

Three immutable effort-only presets ship:

Preset Deciding Reviewing Writing up
thorough session effort xhigh session effort
balanced (wizard default) medium medium medium
minimal medium medium low

Presets never set model IDs. Explicit group dials and per-agent exceptions can override the preset's efforts.

On upgrade, an install that recorded preset: balanced or preset: minimal picks up these efforts the next time its projections are regenerated. After aidlc update, run aidlc config --yes between workflows to reapply the recorded policy, or explicitly select it with aidlc config models --preset balanced --project --yes (substitute minimal as needed). Update changes only the machine runtime; doctor and aidlc config models --check report issues without applying changes. Installs with no recorded model policy keep the shipped tier defaults and are unaffected.

Derive a project profile from a preset or an existing profile:

aidlc config models --from thorough --reviewing-effort medium \
  --save-as my-profile --project --yes

Presets and profiles contain group efforts only. Raw model IDs are allowed only on per-agent exceptions. --yes confirms a mutation but never chooses a policy. Without decisive flags, a TTY opens the model policy wizard; a non-TTY run fails with usage guidance.

Harnesses receive only settings they can read. Codex clamps max effort down to xhigh. opencode clamps xhigh down to high. Kiro CLI cannot express group effort dials, but a per-agent model exception can carry effort through chat.modelDefaults. Kiro IDE, Cursor, and GitHub Copilot cannot portably pin agent models or effort, so the command records the policy and reports the unsupported fields instead of writing inert keys.

Model policy is agent-scoped. Stage files never carry model or effort keys; scopes continue to own stage criticality.

In-session alias

/aidlc --config [section] is the conversational alias for these same config sections. The conductor reads the current JSON state before asking, gathers only the changes you want, and lands each accepted section through one exact aidlc config <section> <explicit value flags> --yes command. Leaving a section unchanged runs no command. After landing or declining, the alias stops; it never advances or resumes workflow work.

Runtime Diagnostics

aidlc config runtime checks the environment that project hooks actually use. On Linux it derives a non-interactive baseline from getconf PATH plus the PATH lines of /etc/environment, ENV_PATH in /etc/login.defs, and environment.d. On macOS it uses getconf PATH plus /etc/paths and /etc/paths.d. On Windows it reads the User and Machine PATH without loading a shell profile. It then resolves the command required by the installed hook bytes (bun for copy projections or aidlc for native projections) and checks the selected harness CLI.

aidlc config runtime --show
aidlc config runtime --check
aidlc config runtime --record-paths --yes
aidlc config runtime --reset --yes

--record-paths records the resolved answers in harness.json. It does not rewrite hook commands. Host permission rules and Codex hook trust bind the bare bun or aidlc command prefix, so replacing it with an absolute path would invalidate the existing trust contract. When a command is interactive-only or absent, the section gives a platform-specific PATH instruction instead.

The harness CLI check requires claude, kiro-cli, codex >= 0.145.0, or opencode for their matching harnesses. Copilot CLI and the Cursor agent CLI are advisory because those installs may be driven only by VS Code or the IDE. The kiro-ide distribution requires no separate CLI; kiro-cli is optional there, needed only to run AI-DLC from a terminal.

Provider Diagnostics

aidlc config providers records provider answers for this project install. Keeping the provider already configured in the harness is the default answer. Amazon Bedrock is an explicit opt-in. Kiro CLI and Kiro IDE are not asked because model access comes with Kiro. other remains available for a manually configured provider and carries an acknowledgement reminder.

aidlc config providers --provider current --yes
aidlc config providers --provider amazon-bedrock \
  --region us-east-1 --profile default --yes
aidlc config providers --show --json
aidlc config providers --check
aidlc config providers --mark-done bedrock-model-access --yes
aidlc config providers --reset --yes

--region, --profile, and --opencode-default apply only when the recorded or selected provider is amazon-bedrock.

Credential detection is offline only. It inspects AWS environment variables, ~/.aws/config, ~/.aws/credentials, role and container credential variables, and the AWS SSO cache. It never calls STS, Bedrock, a model endpoint, or any other network service.

Recorded Bedrock answers apply through the normal staged config transaction:

Harness Recorded answer application
Claude Code Enables Bedrock and writes AWS_REGION plus optional AWS_PROFILE in .claude/settings.json; also keeps the AWS MCP URL and AWS_REGION metadata in .mcp.json on the same region
Codex CLI Records the choice and instructs the user to keep provider, credentials, and model in ~/.codex/config.toml
Kiro CLI No provider answer; model access comes with Kiro
Kiro IDE No provider answer; model access comes with Kiro
opencode Offers to write provider.amazon-bedrock.options.region/profile to opencode.json; --opencode-default yes|no records the answer
GitHub Copilot Records acknowledgement of the manual BYOK environment setup
Cursor Records acknowledgement of the manual provider and model-picker setup

Bedrock model access and IAM permission verification cannot be automated offline. The record therefore carries named pending actions. --show lists them, --check stays non-zero while they are pending, and --mark-done <id> records completion. Codex provider setup remains explicitly self-attested after completion because the effective user configuration and alternate credential channels cannot be resolved offline; --check returns success with that warning instead of describing the setup as verified. --provider current preserves the harness's configured provider and removes only Bedrock values AI-DLC can attribute to its shipped defaults or the previous record from Claude, Codex, or opencode project files. Customized Claude model aliases are preserved. A customized legacy Codex Bedrock block is also preserved; --check reports a warning when it still names that provider instead of calling the configuration clean. --provider other records a manually configured non-Bedrock provider and reports that setup as pending until --acknowledge is supplied. --reset removes exact legacy AI-DLC Bedrock defaults or values written for the previous recorded answer from Claude, Codex, and opencode project files; unproven values are preserved.

The question is worded for the harness in front of you, so each install offers the two paths that actually exist for it:

Harness amazon-bedrock records
Claude Code the AWS region and profile in settings.json, and the AWS MCP region in .mcp.json when present
Codex CLI the AWS region and profile in the project record, then guides user-level provider setup in $CODEX_HOME/config.toml
OpenCode the AWS region and profile, and offers to write them to opencode.json
GitHub Copilot that you set the Copilot BYOK provider variables yourself
Cursor that you configure the provider in Cursor yourself

Kiro CLI and Kiro IDE provide their own model access, so AI-DLC configures no model provider for them. Both the first-run wizard and aidlc config providers state that model access comes with Kiro and ask nothing. Provider flags are refused, and the Providers row reads [ok] regardless of a legacy record. aidlc config providers --reset --yes clears a record left by an earlier build. builtin records from the previous build still load and read as harness-managed, with no pending actions. Legacy Kiro Bedrock records are also ignored, including their pending actions, and nothing is written from them. The aws-mcp region in .kiro/settings/mcp.json is plain MCP configuration, not a model-provider answer: whatever region that file carries, whether an earlier build's Bedrock answer put it there or you did, is kept across refreshes, and --reset leaves the file alone.

Every other harness asks whether to keep its current provider or opt in to Amazon Bedrock. Keeping the current provider is the default, including when AWS credentials are detected. Copilot and Cursor reach Bedrock through their own BYOK or provider settings, which AI-DLC tracks as a pending action rather than performs.

On Kiro, --check says no answer is needed and exits zero even with a legacy record. On every other unrecorded section it names that state instead of reporting a verified answer, and still exits zero because the shipped fallback bytes remain valid.

On these harnesses keep current is the first answer and the default. amazon-bedrock is the second answer. Re-entering the section with the recorded answer preserves it: Bedrock keeps its region and profile unless you explicitly replace them, while other keeps its pending manual-setup action. Pending actions can still be completed with --mark-done.

Trust Diagnostics

aidlc config trust reads and verifies host-native trust. It never regenerates trust seeds, permission rules, or IDE settings.

aidlc config trust --show
aidlc config trust --check
aidlc config trust --acknowledge --yes
aidlc config trust --reset --yes

For Codex, the check requires the complete project-specific trust seed entry set in $CODEX_HOME/config.toml. The two supported remedies are one TUI Trust all and continue pass or replacing <PROJECT_DIR> and merging the complete seed. Until then zero Codex hooks fire. --dangerously-bypass-hook-trust does not fire untrusted hooks, and appending a second seed set produces invalid TOML.

For the kiro-ide distribution, trust ships in the conductor's permissions (.kiro/agents/aidlc.md), so the check adds nothing there; Kiro IDE 1.x no longer reads .vscode/settings.json kiroAgent.trustedCommands. --show lists the selected harness's trust and allowlist files.

The trust check also verifies the project siblings that copy installs often miss: aidlc/ for every harness, .agents/ for Codex, and the .aidlc/ engine for opencode and Copilot.

Doctor also classifies the installed instruction file against the config ownership baseline. An intact managed block reports block present, user content preserved; a missing block or file says to run aidlc config; a hand-modified managed block or framework-owned whole file reports a conflict. The row follows the invoking harness when more than one harness tree is present.

Project Flags

aidlc config flags records project answers for default scope, swarm mode, hook debug, sensor timeout, question retention, and explicit guard bypasses or ceremony kill switches:

aidlc config flags --default-scope <installed-scope> \
  --swarm on --hook-debug off --sensor-timeout-ms 90000 \
  --question-retention-days 30 --project --yes
aidlc config flags --bypass AIDLC_SKIP_ARTIFACT_GUARD --local --yes
aidlc config flags --show
aidlc config flags --check
aidlc config flags --reset --project --yes

Real environment variables always win. Existing tools and hooks first read the environment and then resolve local, project, and machine settings when the variable is absent. This keeps CI and one-shot shell exports scriptable.

--question-retention-days <days|unlimited> controls how long AI-DLC keeps its copy of a request for a question that was never answered. The default is unlimited unless a positive integer is recorded. With a value set, copies older than that many days are removed the next time AI-DLC does work (status, help, and other queries never remove anything), and an expired question is refused if it is answered. Passing unlimited removes the value from the selected settings layer without changing other flags. AIDLC_QUESTION_RETENTION_DAYS is the matching environment override.

Default scope names are read from the installed scope files. The section does not branch on a built-in scope name, so scope renames and plugin scopes remain data. On Claude Code, config also rewrites the staged AWS_AIDLC_DEFAULT_SCOPE value in .claude/settings.json; otherwise the shipped session environment would shadow the lower-precedence record.

The recordable bypass set includes the documented recovery and ceremony switches:

  • AIDLC_SKIP_ARTIFACT_GUARD
  • AIDLC_SKIP_HUMAN_PRESENCE_GUARD
  • AIDLC_SKIP_REVISION_BACKSTOP
  • AIDLC_SKIP_SUMMARY_CONFIRMATION_GUARD
  • AIDLC_DISABLE_ENSEMBLE_EVIDENCE
  • AIDLC_DISABLE_PLAN_APPROVAL_GUARD
  • AIDLC_DISABLE_REVIEWER_SCOPE_HOOK
  • AIDLC_DISABLE_REVIEW_FREEZE_HOOK
  • AIDLC_DISABLE_USAGE_TRACKING
  • AIDLC_DISABLE_SENSORS — disables sensor execution and sensor gate checks
  • AIDLC_DISABLE_LEARNINGS — disables the stage learnings ritual
  • AIDLC_DISABLE_SUMMARY_CONFIRMATION — disables the separate summary-confirmation checkpoint, not stage approval

The wizard never offers bypasses. They require an explicit --bypass <name>; --show surfaces every enabled bypass and its guard-weakening consequence.

Four of these switch off a fence for the whole machine. When the problem is one piece of work rather than one machine, /aidlc config set guard.<fence> off lowers a single fence for that work only, records it, and puts it back for the next piece of work. See Guard Policy and The five fences.

Project Choices

aidlc config project records the installed plugin selection, MCP consent, and the shell-completion answer:

aidlc config project --plugins aidlc,test-pro --mcp none \
  --completions zsh --yes
aidlc config project --show --json
aidlc config project --check
aidlc config project --reset --yes

On a copy-channel projection, config project applies plugin, MCP, and completion choices from the project's own files at the release it already has, so it needs no download. It needs the release only when the project is pinned to another one, or when MCP is turned back on after the shipped server list was removed; it then asks at a terminal, and scripts add --download. --from <path> instead uses files you downloaded: aidlc-copy-runtime-X.Y.Z.tar.gz, its extracted runtime/ folder, or one harness root. Servers you added to .mcp.json yourself are never recorded or removed.

Plugin names are discovered from the installed graph, scopes, and plugin sidecars. They are not hardcoded. The selection continues to use the existing top-level plugins array in harness.json, so graph and runner regeneration use the same selection seam as plugin composition. Project mutations run through the refresh safety guard and refuse while a workflow is active. Add --dry-run to the same command to preview its plan without changing project or settings files. The preview remains available during an active workflow; applying the change still requires completing that workflow.

MCP consent remains defaults or none. A non-interactive project mutation with no earlier consent records none; --yes only confirms the mutation and never adds MCP entries.

On Claude Code, .mcp.json is the consent-managed surface: --check verifies both defaults and none, and later plain config refreshes reapply the answer. Kiro CLI always ships .kiro/settings/mcp.json; defaults is satisfied by that file and its five shipped servers, while none is an instruct-only preference and does not remove a framework-owned file. The current Codex, opencode, Copilot, Kiro IDE, and Cursor distributions ship no MCP surface, so their recorded answer is informational and does not make --check permanently red. --show names the actual MCP file whenever one exists.

Completions are instruction-only and write no machine files. Native installs print commands such as:

eval "$(aidlc system completions bash)"

Copy-channel installs print the matching Bun invocation, for example:

eval "$(bun .claude/tools/aidlc.ts system completions bash)"

Fish uses ... completions fish | source; PowerShell uses ... completions powershell | Out-String | Invoke-Expression.

An existing project stamp fixes the harness for a refresh. A fresh interactive project prompts for a harness; a non-interactive run requires --harness. If .aidlc-version exists, config requires a source at that exact version with the matching project harness.

Config recognizes directories containing .git, package.json, Cargo.toml, go.mod, or pyproject.toml. Outside those shapes, interactive mode asks for confirmation and non-interactive mode requires --project-dir.

Claude's optional MCP integration defaults to none without a TTY. A human TTY is prompted when no prior choice exists. --yes and --json do not grant MCP consent. Reliable automation supplies --project-dir, --harness, and --mcp defaults|none explicitly; JSON controls output but does not disable TTY prompts by itself.

For exact scripted approval:

token=$(
  aidlc config --project-dir "$PWD" --harness claude --mcp none \
    --dry-run --json | jq -r .data.planToken
)
aidlc config --project-dir "$PWD" --harness claude --mcp none \
  --plan-token "$token" --json

Use identical source and behavior options for both calls. Source bytes, options, or project state changing after the preview changes the token and the apply fails closed.

Refresh Safety

A refresh changes project engine and graph files, so config refuses while any workflow in any space is not complete. Parked workflows still count as active. Complete every workflow named in the error, then rerun config.

The check runs once while planning and again under the workspace audit lock immediately before commit. --force, --yes, and --plan-token do not bypass it. aidlc update and aidlc use remain safe during a workflow because they only change machine state.

Refresh preserves:

  • all workspace records, audit shards, knowledge, and other project files absent from the shipped projection
  • existing aidlc/active-space and space memory files, which are project-owned seeds
  • every non-identity sibling key in mutable tools/data/harness.json, including plugin selection and future policy records
  • plugin-composed files and recorded stage contributions, then regenerates graph, runner, scope, and compiled table surfaces
  • upstream-authored orchestrator prose while rebuilding its compiled stage and scope regions from the preserved project composition

Under aidlc/, install and refresh copy only those seeds. The clone identity, sessions, engine health, and other per-machine state are never copied from the installed runtime or recorded in the install baseline.

Locally modified framework-owned files conflict against the prior baseline. --force replaces those files with the refreshed candidate, including local edits to hand-authored orchestrator prose. It does not claim unrelated project content.

Provider, scope, and model answers preserve project-owned fields in .claude/settings.json and .codex/config.toml. The Claude companyAnnouncements, permissions, statusLine, and hooks keys remain framework-owned. The Codex [shell_environment_policy], [sandbox_workspace_write], [agents], [features], [tools], and [tui] tables also remain framework-owned. Local edits to those entries conflict against the baseline, and --force restores the shipped entries while retaining unrelated project-owned fields. An explicit --from selects that source instead of the project's copy.

opencode.json provider answers edit their attributed keys in place. An ordinary release refresh still applies the whole-file ownership policy.

Root Integrations and Ownership

Surface Harnesses Policy
.gitignore All Own one marked AI-DLC block containing the union of installed harnesses' shipped entries; preserve every byte outside it
.mcp.json / mcpServers Claude Add or remove only consented, baseline-owned entries; preserve user keys and overrides
AGENTS.md Kiro CLI, Kiro IDE, Codex, Cursor, OpenCode, Copilot One marked block; harness-neutral and shared (shared: "identical") except Copilot, whose block carries its @-imports; preserve project instructions
opencode.json OpenCode Record-only answers edit the current file in place; ordinary release refresh still requires an unchanged file baseline or exact shipped signature

More than one harness in a project. Harnesses may coexist when their engine directories differ and they do not share an exclusive managed block. AGENTS.md is neutral and byte-identical (shared: "identical") across Kiro CLI, Kiro IDE, Codex, Cursor, and OpenCode, so any of those with distinct engine directories may coexist. Codex's harness-specific onboarding is injected through developer_instructions in the project .codex/config.toml when the project is trusted, with .codex/onboarding.md as its readable copy. Claude Code may coexist with any other harness. Copilot's AGENTS.md stays exclusive: pairing it with another harness that ships that block is refused with cannot coexist in one project, regardless of which is installed first. Kiro CLI and Kiro IDE still share .kiro/, and OpenCode and Copilot share .aidlc/, so those pairs cannot coexist. For an older installed harness whose root block is not shared, the predates shared onboarding error suggests refreshing it with aidlc config --harness <name> first. This is a hint for an older sibling, not a promise that refreshing enables coexistence: if it still refuses afterwards, the sibling's block is exclusive. Copilot's block stays exclusive after refresh. A refresh source that no longer declares AGENTS.md shared is also refused while another installed harness shares it: refusing to refresh <harness> from a release whose AGENTS.md is not shared. Use a release that declares the block shared; --force cannot bypass this guard. A shared AGENTS.md block owned by a sibling from a different release is a conflict, not a deferred update. The error names the refresh order: refresh the selected harness from the same release as its sibling, or refresh the sibling from the selected release first. Cursor's manual-copy installer is single-harness (private AIDLC CURSOR markers, no aidlc config ownership baseline); multi-harness projects must add Cursor with aidlc config --harness cursor instead.

.gitignore declares shared: "union", so aidlc config writes one block combining every installed harness's shipped entries; extra entries appear under # <harness> harness. Adding a harness combines an unchanged sibling-owned block when that sibling's shipped block copy is available (merge (combined with <harness>)); older installs without that copy keep ownership until refreshed. Each harness records the same combined block hash on its next config invocation. Once more than one harness is present, every aidlc config invocation needs --harness <name>.

Known unmarked files and JSON entries from historical shipped projections are adopted only when their exact recorded SHA-256 signature matches. Modified lookalikes remain ambiguous and are refused.

--force can replace a modified, baseline-owned managed block or managed harness file. It cannot adopt ambiguous unmarked content, overwrite a user-owned JSON value, or replace an unowned or locally modified opencode.json during an ordinary release refresh. Malformed JSON, malformed or duplicate markers, non-regular-file targets, and retired owned content whose integrity cannot be proved are hard conflicts.

Every planned path receives one action:

Action Meaning
create Add an absent framework path
update Refresh framework-owned bytes
merge Reconcile a managed block, JSON map, or JSON array
preserve Keep current or project-owned bytes
remove Remove content previously owned by the baseline and retired upstream
conflict Refuse because ownership or integrity cannot be proved

Successful config prints the host-specific next step:

Harness Next step
Claude Code Open Claude Code and run /aidlc --doctor
Kiro CLI Run kiro-cli chat, then /aidlc --doctor
Kiro IDE Open this project in Kiro IDE; if the Restricted Mode banner shows at the top of the window, select Manage on it, then Trust; run Developer: Reload Window from the Command Palette (Ctrl+Shift+P, or Cmd+Shift+P on macOS), choose the aidlc agent in the chat panel's agent picker, then run /aidlc --doctor (in Kiro CLI, start kiro-cli in the project instead and run /aidlc --doctor)
Codex CLI Run codex, then $aidlc --doctor
OpenCode Run opencode, then /aidlc --doctor

Update and Version Selection

Command Public options and behavior
aidlc update Install the newest release of the machine's channel with the complete all-harness runtime, then atomically activate. Accepts --version <version>, --channel <stable\|preview>, --from <release-dir>, --release-base-url <url>, --release-api-url <url>, --ca-bundle <path>, --offline, and --dry-run.
aidlc update --check Refresh update metadata for the channel without installing. Returns 5 when behind (or when the binary belongs to the other channel), 0 when current, 3 when unavailable/offline, and 1 when checks are disabled.
aidlc use <version> Install the exact stable or preview version when it is not retained, then make it machine-active without changing project files.
aidlc config --channel [stable\|preview] Set the machine release channel, or print it when no value is given.
aidlc config --pin <version> Install and validate the exact version when needed, then atomically write .aidlc-version, record its machine-local resolved target, and register the project pin without changing the machine-active pointer.
aidlc config --unpin Remove .aidlc-version, its machine-local resolved target, and its registry entry.
aidlc config ... --download Let any config command fetch the release the project needs when this machine lacks it: the pinned release, otherwise the one its files already have. Natively it installs and registers that release, as --pin does; on a copied project it downloads aidlc-copy-runtime-X.Y.Z.tar.gz. It verifies the checksum, and the release attestation when gh is installed, then finishes the command. --release-base-url and --ca-bundle choose a mirror. At a terminal config asks instead; scripts need the flag.

Human lifecycle output states each completed fact. Update reports the old-to-new version check, verified download, atomic switch, retained prior version, any pruned unprotected releases, and the project-refresh courtesy. A no-op says You're on the latest version of aidlc (<version>).; --dry-run says Would update aidlc from <old> to <new>., or You're on the latest version of aidlc (<version>); nothing to update. when nothing would change. On the preview channel the update lines say preview releases and latest preview version, and an update that crosses channels adds Switched release channel from <a> to <b>.. aidlc use distinguishes Now using from Already using, and uninstall states exactly which machine state was removed or kept. JSON and quiet messages retain their stable machine contracts; update JSON carries channel and, on a switch, channelSwitch.

Update downloads and fully validates a candidate before changing the active pointer. Failed updates automatically restore the prior consistent installation. A successful update retains the prior active version and every registered project pin, then prunes older unprotected versions automatically. There is no public rollback or retained-version management command.

Release Channels

main is the shared development branch. The stable channel publishes a selected commit as a GitHub release tagged vX.Y.Z. The preview channel lets users try changes from main before the next stable release as a GitHub prerelease that is never marked "latest". Source versions and changelog entries are updated during release preparation.

Scheduled and manual runs share one serialized publication queue. A run skips when the source is unchanged since the latest published preview. When main advances more than once on the same UTC date, each changed source can publish a new preview with the next build counter.

A preview still publishes when its nightly tests fail. Its release notes then open with a warning and end with a Full Suite failure report (failed jobs and any failing tests), so check it before relying on a preview.

A preview id is <x.y.(z+1)>-preview.<YYYYMMDD>.<N>: the next patch after the source tree's current stable version, the UTC build date chosen during planning, and a retry counter (1 initially). The workflow calculates the preview version without editing the source version. Drafts and tags left by failed attempts reserve ids. A retry or another changed source on the same date advances N past those occupied ids.

Stable ids stay exactly x.y.z, and nothing else is accepted anywhere a version appears (installer flags, use, pins, .aidlc-version, retained version directories). Ids order numerically on x.y.z; at an equal base the stable release sorts above every preview built from it, and previews order by build date then counter. Inside a preview artifact aidlc version, version.json, and doctor bundles all report the preview id; the source tree is never modified.

aidlc config --channel preview   # follow the preview stream
aidlc update                     # newest published preview
aidlc update --check             # 5 when a newer preview exists
aidlc config --channel stable    # back to the stable stream
aidlc update                     # newest stable, reported as a channel switch

The channel is machine-local: aidlc config --channel writes a channel marker beside the update cache and pins.json under the install root (stable when the marker is absent), aidlc uninstall preserves it with the other machine settings, and --purge removes it. aidlc update --channel <c> overrides the marker for one run; --version and --from select an exact release regardless of channel. Stable discovery is unchanged (the latest/download redirect). Preview discovery lists the releases of the repository behind the release base URL through the GitHub API, keeps the newest published prerelease by preview version id, and installs it through the exact-version path. Drafts and tags without a published release are ignored. For github.com base URLs the API endpoint is derived; for any other host set --release-api-url <url> or AIDLC_RELEASE_API_URL. An API failure, a rate limit, or a repository with no published preview is reported as unavailable (exit 3); the client never falls back to the stable release. The update cache records the channel it was refreshed for, so a cached preview result never answers a stable check or the reverse.

Switching back is aidlc config --channel stable then aidlc update. Even if the newest stable id sorts below the preview you are running, update installs it and reports a channel switch. Preview retention is a bounded window on top of the protection every release has (active, rollback, in use, pinned): after an update the two newest complete previews stay, and every older preview without its own protection is pruned; stable retention is unchanged.

Version pruning also uses recorded file lists and empty-directory cleanup. If a selected version contains unowned or changed paths, pruning is refused and the files are kept for review.

Project pins keep overriding the machine channel: aidlc config --pin <id> and .aidlc-version accept preview ids, and a pinned project dispatches to that exact retained version whatever the machine follows.

Previews are main as it stands, including project state-schema changes. A preview that raises the state schema writes project state a stable build does not understand, and the code refuses to open state newer than the build; that project cannot be walked back to stable until a stable release ships the same schema. Use the preview channel on projects you can recreate, or pin them.

Project Pins and CI

aidlc config --pin 2.5.45
git add .aidlc-version

aidlc config --pin <version> installs and validates the version if needed, writes .aidlc-version, records the absolute binary target under the gitignored aidlc/.aidlc-sessions/ runtime directory, and registers the real project path in machine-local pins.json. Registry reads canonicalize filesystem aliases (including macOS /var and /private/var) and JSON output reports the canonical project path. Equivalent keys with the same version collapse; conflicting equivalents fail closed until config --pin or config --unpin reconciles every alias for that project.

Commit only .aidlc-version. The stable aidlc launcher starts the integrity-checked active binary, whose dispatcher validates the complete pinned binary and runtime before selecting it. A missing, malformed, tampered, or unavailable target fails closed with aidlc config --pin <version> remediation, and aidlc doctor reports the same condition. Machine lifecycle commands use the active binary; doctor, config, and use are never trapped behind a broken pin. When a teammate commits a pin to a release this machine lacks, a config command on the project names it, and --download (or a yes at the terminal) installs and registers it as config --pin would, then finishes the command. An installed pinned release is used without asking, and files behind it are updated first.

A fresh clone or CI runner installs the committed version before config:

version=$(cat .aidlc-version)
tag="v$version"
tmp="$(mktemp -d)"
gh release download "$tag" --repo awslabs/aidlc-workflows --dir "$tmp" \
  --pattern install.sh --pattern aidlc-release.intoto.jsonl
gh attestation verify "$tmp/install.sh" \
  --bundle "$tmp/aidlc-release.intoto.jsonl" \
  --repo awslabs/aidlc-workflows \
  --signer-workflow awslabs/aidlc-workflows/.github/workflows/release.yml \
  --source-ref "refs/tags/$tag"
sh "$tmp/install.sh" --version "$version" --quiet --yes
rm -rf "$tmp"
aidlc config --pin "$version" --project-dir "$PWD" --quiet
aidlc config --project-dir "$PWD" --harness claude --mcp none --quiet
aidlc doctor --project-dir "$PWD" --quiet

Harness Selection

Harness selection belongs to aidlc config --harness <name>. Machine-level harness management is not a public command.

Offline Packages

The release asset set is the offline package. It includes aidlc-release.intoto.jsonl alongside the binaries, runtime, installers, version.json, and checksums.txt. Download one complete release on a connected machine and transfer that directory unchanged. Local installation fails closed if the bundle is missing or does not authenticate checksums.txt:

gh release download v2.5.45 --repo awslabs/aidlc-workflows --dir ./aidlc-offline

Install on the disconnected machine:

bash ./aidlc-offline/install.sh \
  --from ./aidlc-offline --offline
& .\aidlc-offline\install.ps1 `
  -From .\aidlc-offline -Offline

For native commands, --offline, AIDLC_OFFLINE=1, or global offline=true prevents release sockets. A network operation without --from then fails before mutation. Config, doctor, version, and uninstall are local regardless.

Mirrors, Proxies, CAs, and Update Settings

Release settings resolve in explicit option, environment, machine-config, default order:

Setting Environment Machine config
Offline AIDLC_OFFLINE=1 (0 explicitly enables network) aidlc system config global set offline on
Mirror AIDLC_RELEASE_BASE_URL aidlc system config global set release-base-url <url>
Preview releases API AIDLC_RELEASE_API_URL (or aidlc update --release-api-url <url>) derived from the mirror for github.com; not a machine config key
CA bundle AIDLC_CA_BUNDLE aidlc system config global set ca-bundle <absolute-path>

Manage the four machine keys:

aidlc system config global list
aidlc system config global get update-check
aidlc system config global set update-check off
aidlc system config global set offline on
aidlc system config global set release-base-url https://mirror.example/releases
aidlc system config global set ca-bundle /absolute/path/corporate-ca.pem
aidlc system config global clear ca-bundle

The keys are update-check, offline, release-base-url, and ca-bundle. Boolean values accept true|false, on|off, 1|0, or yes|no. aidlc config <get|set|clear|list> ... --global is equivalent.

Mirror base URLs must use HTTPS, except loopback HTTP for local testing, and cannot contain credentials, a query, or a fragment. The native lifecycle client follows at most five redirects; redirected URLs may contain a query but still cannot contain credentials or a fragment. Its errors redact URL credentials, queries, and fragments.

The native release client honors HTTPS_PROXY / https_proxy and NO_PROXY / no_proxy; proxy URLs must use HTTP or HTTPS. It does not read HTTP_PROXY. The bootstrap scripts delegate proxy behavior to curl, wget, or Invoke-WebRequest. On Windows, a custom CA bundle requires curl.exe.

Bare help and management listings never refresh the network. They may display a valid cached update notice. Interactive human aidlc doctor may refresh stale or absent metadata within 750 ms. Non-TTY, --json, and --quiet doctor runs are cache-only unless --check-updates is explicit. doctor --check-updates and update --check use a five-minute metadata backstop. The cache expires after 24 hours; a failed or regressing refresh does not replace a valid cache. update-check=off disables even explicit refreshes but does not prevent an explicit aidlc update.

Plugins

aidlc doctor reports installed-versus-composed plugin state. Plugin changes are project configuration and converge through aidlc config; there is no separate public plugin command.

Output, Automation, and Exit Codes

The public commands support human, --quiet, and --json output where declared by the route registry. --json emits a schema-versioned result with ok, code, status, message, and command-specific data when available. --quiet emits one success line or remediation line. Download progress appears only in human mode.

The native diagnostic form is aidlc doctor [--project-dir <path>] [--verbose] [--json|--quiet] [--check-updates] [--release-base-url <url>] [--ca-bundle <path>] [--offline]. --export writes a redacted diagnostic bundle, with --output <directory> overriding its default project location; export output is additional to the selected live-report mode. Human output groups Machine, Project, and Framework integrity checks. Every section keeps warning/failure rows visible and collapses healthy rows by default; --verbose expands every check. Warnings are advisory and exit 0; any failed check exits 1.

--no-color and NO_COLOR disable ANSI output. --project-dir <path> selects project context without changing the shell directory. Destructive operations such as uninstall prompt on a TTY and require --yes without one. --yes never bypasses ownership, integrity, active-workflow, or release-authentication refusals.

Code Meaning
0 Success
1 Operational failure
2 Usage or invalid machine configuration
3 Required network result or retained runtime unavailable
4 Integrity or ownership refusal
5 Check completed and action is required, such as an available update

Help and Completions

aidlc --help prints exactly the six public commands. Each public command also has side-effect-free command help: aidlc <command> --help (or -h) for config, doctor, version, update, use, and uninstall. Config-level help names all six policy sections; aidlc config <section> --help keeps the section-specific help. aidlc help --all reveals the hidden engine and system namespaces and points to aidlc engine --help / aidlc system --help for their full inventories. The installer places Bash, Zsh, Fish, and PowerShell files under the per-user AI-DLC data root's completions/ directory, generated from the public route registry; there is no public completion-generation verb.

Transactions and Recovery

Project and machine mutations stage on the destination filesystem, validate the candidate, and commit through atomic renames. Concurrent changes detected against planned state abort instead of overwriting new bytes. Abandoned owner-private staging is swept only after lock and ownership checks.

If rollback of an interrupted commit cannot be completed safely, evidence is retained in a named .aidlc-recovery-* quarantine under the machine install root or project root. aidlc doctor reports it. Recover any needed files, ensure no AI-DLC mutation is running, then remove only the listed directory manually. Automatic staging cleanup never deletes quarantines.

Windows uninstall uses a recoverable continuation because a running executable cannot remove its own command shim. A later command resumes a valid pending continuation before doing other work, unless one is still running. A worker that stops without recording a result is resumed at most three times.

When cleanup fails, it records the step that failed and the reason, and aidlc doctor reports both. A failed cleanup is never relaunched by other commands, which keep working, but machine changes stay blocked until the uninstall finishes. Resolve the reported problem and run aidlc uninstall again (with --purge if the original used it):

  • If nothing was removed yet, the failed plan is discarded and uninstall plans again from the files on disk, so a file edited after confirmation is kept.
  • If removal had begun, the same plan resumes. Files edited since are kept.

The aidlc command itself (aidlc.cmd, its shim, the active-version pointers, and the active aidlc.exe) is removed last, after every other file and the User PATH entry, so a failed cleanup still leaves a command to retry it. Because the PATH entry may already be gone, run that command by its full path, which aidlc doctor prints (by default & "$env:LOCALAPPDATA\aidlc\bin\aidlc.cmd" uninstall). If the failure happened while removing those last files and the command no longer runs, run the installer again: it retries the pending cleanup first, so you may need to run it twice.

Copy Channel

The supported manual-copy payload is the versioned aidlc-copy-runtime-X.Y.Z.tar.gz release asset. Download one exact release, extract it, and copy the complete runtime/<harness>/ root so the harness tree, aidlc/ workspace shell, and project-root files stay together. Bun is the runtime prerequisite; the native aidlc executable is not required. Markdown analysis (summary confirmation, Plan Approval tags, and the claim-sources sensor) uses Bun's built-in Bun.markdown renderer, so it needs Bun 1.3.8 or newer and follows the installed Bun's rendering:

tag=vX.Y.Z
tmp="$(mktemp -d)"
runtime_asset="aidlc-copy-runtime-${tag#v}.tar.gz"
runtime_checksum="${runtime_asset}.sha256"
source_repo="${AIDLC_RELEASE_REPOSITORY:-awslabs/aidlc-workflows}"
release_workflow="${AIDLC_RELEASE_WORKFLOW:-$source_repo/.github/workflows/release.yml}"
gh release download "$tag" --repo "$source_repo" --dir "$tmp" \
  --pattern "$runtime_asset" \
  --pattern "$runtime_checksum" \
  --pattern aidlc-release.intoto.jsonl
gh attestation verify "$tmp/$runtime_asset" \
  --bundle "$tmp/aidlc-release.intoto.jsonl" \
  --repo "$source_repo" \
  --signer-workflow "$release_workflow" \
  --source-ref "refs/tags/$tag"
(cd "$tmp" && sha256sum -c "$runtime_checksum")
tar -xzf "$tmp/$runtime_asset" -C "$tmp"
RUNTIME_ROOT="$tmp/runtime"
cp -R "$RUNTIME_ROOT/claude/." your-project/

Later, a copied project fetches releases itself. When a config command needs files the project does not have (a teammate's newer pin, a harness you add, or restored files), it asks at a terminal, or accepts --download in a script, to download that exact aidlc-copy-runtime-X.Y.Z.tar.gz, verify its .sha256 and, when gh is installed, its release attestation, and finish the command. Without network access, the error's offline: line names the file to fetch elsewhere and pass with --from.

The archive is assembled from the freshly regenerated Bun projections under dist/. Its generated hooks and tools invoke the included TypeScript through Bun. The native installers and lifecycle commands instead consume aidlc-runtime-X.Y.Z.tar.gz, assembled from dist-release/; users do not normally download that archive directly.

The copy archive stays outside version.json and checksums.txt so existing 2.8.x native clients can continue to parse release metadata and self-update. Its versioned .sha256 sidecar authenticates the bytes directly, and the release provenance covers both files.

On a copy install, the AI-DLC files in your project are code you run. Its hooks run them through Bun, and on every harness except GitHub Copilot the settings it ships also pre-approve the agent's calls to them; each harness guide describes how its pre-approval behaves. Trusting the project folder therefore means trusting those files: anyone who can change the project can change what those hooks and pre-approved commands run.

When native executables are permitted, prefer aidlc config. It installs the native runtime transactionally and records ownership for later refreshes.

Framework developers may instead clone the source, install dependencies, and materialize ignored local outputs:

bun install --frozen-lockfile
bun scripts/package.ts

That creates the Bun-invoking dist/<harness>/, native dist-release/<harness>/, and plugin projections locally. Neither generated root is committed. Direct bun .../tools/*.ts calls remain source/development and debugging mechanisms, not a second native lifecycle interface.

Uninstall

aidlc uninstall
aidlc uninstall --purge --yes

Uninstall uses an explicit list of installer-owned files and checks their contents before deleting them. It does not recursively remove installation or version directories. Directories are removed only when empty; project trees, unlisted files, changed files, and linked targets are preserved. The result reports unowned or changed paths kept for review.

New installations record a full per-version installed-files.json inventory, whose hash is stored in version.json. Older installations use their verified runtime inventory where available; files without ownership evidence are kept. Without --purge, machine config, update cache, pin registrations, and the default harness are also preserved. --purge selects those known machine records for removal; it does not broaden deletion to unrelated files.

On Windows, both forms remove the User PATH entry recorded in the install root's windows-path.json. Entries that existed before installation and unrelated changes made afterward are preserved. An install without an ownership record leaves User PATH alone. -NoModifyPath on a later installer run preserves an earlier record, so that entry is still removed on uninstall.

Uninstall requires confirmation and refuses filesystem, home, shared-system, and project roots, as well as root-owned, package-manager-owned, or mixed-ownership commands. On Windows, a bound file list and expected checksums are recorded before cleanup is scheduled. The worker rechecks paths and hashes, refuses reparse points, and deletes files individually after the running command exits. An interrupted continuation can resume only with its validated file plan. Older journals without such a plan are refused and left for inspection. See Transactions and Recovery for how a failed cleanup is reported and retried.