ADR 0008: Prerequisite Install Policy — No Auto-Install
| Field | Value |
|---|---|
| Status | Accepted |
| Date | 2026-05-12 |
| Deciders | Project maintainers |
| Supersedes | — |
| Superseded by | — |
| Related ADRs | 0001 (Runtime + language), 0002 (Monorepo tooling) |
Summary
aidokit detects host prerequisites (Node.js, Git, the user's AI coding CLI, Beads, etc.) but never invokes their install commands itself. When a prerequisite is missing, the CLI prints the per-OS install command and pauses or exits — the user runs the install. The --yes flag governs aidokit's own internal confirmations and never bypasses a prerequisite install step. A --skip-prereq-check escape hatch exists for advanced users who know their environment.
Context
aidokit init scaffolds a workflow that depends on several host tools being present and working. The relevant prerequisites (see .docs/ARCHITECTURE.md §13.1) at v0.1 are:
| Prereq | Required? | Why needed |
|---|---|---|
| Node.js ≥ 20 | Yes | Runtime for aidokit itself and for emitted .mjs hook scripts |
| Git | Yes | Project is assumed to be (or will become) a git repo |
| Claude Code | Yes for claude-code adapter |
Consumes the emitted .claude/ engine directory |
| Beads CLI | Optional at v0.1, required at Standard from v0.5 | Task graph and decision memory backend |
Two policies are possible when a required prereq is missing:
- Print and pause. Show the install command for the detected OS; let the user run it; resume on their next invocation.
- Offer to run the installer. Detect the package manager (brew, apt, scoop, winget) and execute the install command, optionally behind a confirmation.
Auto-install looks user-friendly in demos. In practice it crosses a trust boundary that aidokit should not cross:
- Running a package manager often requires elevated privileges (
sudoon Linux, an elevated shell on Windows). - Package-manager preference is personal — a developer who uses
miseorasdfdoes not wantaidokitto invokebrew install node. - Installers may modify shell rc files, PATH, or system services.
aidokitcannot reason about whether that is safe in the user's environment. - Bundling installer logic per OS multiplies maintenance: each platform's "install Node 20" has at least three reasonable variants (system package manager, version manager, manual).
- Some prereqs (Claude Code, Beads) have install scripts hosted by their respective vendors. Wrapping them adds a hop that can break when the upstream script changes.
aidokit itself is a scaffolder that emits files. It is not a system-state manager. The --yes flag was reviewed in this light: it makes sense for confirming that we may write files into the project directory, but it must not authorise side effects on the host system.
ARCHITECTURE.md §13.3 already states "the CLI never runs install commands without explicit confirmation. Even with --yes, only confirms aidokit-internal operations; prereq installs require a separate explicit confirmation. ADR-0008 codifies this." This ADR is that codification.
Decision
1. aidokit never invokes a system package manager
The CLI does not call brew, apt, dnf, pacman, scoop, winget, choco, or any other host package manager — neither directly via shell nor indirectly via a child process — for prerequisite installation. This includes installing optional prereqs.
2. aidokit never invokes a vendor install script
The CLI does not pipe curl | bash, iwr | iex, or equivalent. Even when the install command for a prereq is a vendor-hosted script (e.g., Claude Code's install endpoint), aidokit only prints the command. The user pastes and runs it themselves.
3. Detection-only flow
@aidokit/prereq-check checks each prereq and returns:
interface PrereqStatus {
id: string;
installed: boolean;
version?: string;
location?: string;
required: boolean;
installInstructions: Record<OS, InstallHint>;
}
The @aidokit/cli formatter renders the table; missing required prereqs cause the CLI to:
- In interactive mode: show install instructions, pause, and re-detect on user confirmation.
- In non-interactive mode (
--yes/--no-prompts): exit with code 10 (PREREQ_MISSING) and print the install instructions.
4. --yes does not authorise prereq installs
--yes skips aidokit-owned confirmations only. There is no flag that authorises aidokit to install prerequisites on the user's behalf. The escape hatch is:
aidokit init --skip-prereq-check
This bypasses detection entirely for users who know their environment is set up. It does not install anything; it just opts out of the check.
5. Optional prereqs follow the same rule
Missing optional prereqs (Beads at v0.1) reduce the feature set but do not block the flow. The CLI surfaces the install command, asks whether to continue without, and proceeds accordingly. It still does not install Beads itself.
6. The instructions are catalogued, not generated
Install hints live in the same TypeScript const array that defines prereqs:
export const PREREQS: PrereqDef[] = [
{
id: 'claude-code',
name: 'Claude Code',
required: true,
minVersion: '2.1.32',
detect: detectClaudeCode,
install: {
darwin: { command: 'curl -fsSL claude.ai/install.sh | bash' },
linux: { command: 'curl -fsSL claude.ai/install.sh | bash' },
win32: {
command: 'iwr claude.ai/install.ps1 -useb | iex',
docs: 'https://docs.claude.com/claude-code',
},
},
},
// …
];
When an install command becomes stale, the fix is a one-file edit in @aidokit/prereq-check, not a runtime probe.
Consequences
Positive
- Trust:
aidokitcannot break the user's host environment because it never modifies it. The blast radius of a bug is the project directory only. - Security model is simple: the capability declaration for every adapter is bounded; no
runsShellCommandsentry for prereq installs is ever needed. - Cross-platform parity: Windows, macOS, and Linux behave identically — print and exit, or print and pause. We do not implement nine variants of "install Node".
- No sudo:
aidokitnever asks for or escalates privileges. If a user's setup requiressudo, that is their decision to make and execute. - Version manager friendly: users with
nvm,mise,asdf,volta,fnm, or no manager at all are all served by the same flow. - Honest UX: the user sees exactly what command would change their system. There is no opaque "magic" install.
Negative
- Extra friction for first-time users: a developer who runs
npx aidokit initon a fresh machine may need to install Node + Claude Code + Beads in three separate steps beforeaidokit initcompletes. Mitigation: the prereq-check phase shows all missing items at once with one combined install snippet, so it is one round-trip not three. - Install commands can drift: vendor install paths change. Mitigation:
aidokit doctor(v0.5+) surfaces version mismatches; we pin tested ranges in the prereq catalog and document gaps. - No "one-command bootstrap from zero": demos and READMEs cannot honestly claim "one command and you're done." They can claim "one command and the workflow is scaffolded; install prereqs first if missing."
Neutral
- Matches npm postinstall norms: the broader Node ecosystem leans toward "show what to do, do not assume it for the user."
aidokit's policy is consistent with that. - Future plugin authors must follow the same rule: third-party adapters and stack-packs (post-v1.0 SDK era) inherit this constraint via the capability declaration model in
ADR-0005.
Alternatives considered
Alternative 1: Auto-install with single confirmation prompt
aidokit detects missing prereqs, asks "install all of these? (y/N)", and runs the commands.
Pros
- Lower friction in the success case.
- Familiar from tools like
gh auth loginorvercel.
Cons
- Crosses a trust boundary
aidokitshould not own. - Requires per-OS, per-package-manager branching that multiplies test surface.
- Cannot reliably detect the user's preferred installer (system pkg manager vs. version manager).
- A failed mid-install leaves the host in a half-state
aidokitcannot reason about or roll back.
Reason rejected: the operational complexity is large, the failure modes are user-hostile, and the "convenience" gain is one-time per machine. Pasting an install command from the printed table is a 10-second cost, paid once.
Alternative 2: Auto-install gated by --auto-install-prereqs
Same as Alternative 1, but behind an opt-in flag rather than a prompt.
Pros
- Default behaviour stays safe.
- Power users who want one-shot setup can opt in.
Cons
- Doubles the supported install paths (manual + automated), each needing its own test matrix.
- The "automated" path inherits all the failure modes above; bugs there are higher-stakes because the user gave blanket consent.
- Documentation has to explain both paths.
Reason rejected: the flag exists only for the convenience of users who can already paste a command from the printed output. The cost (more code, more failure modes) outweighs the benefit. If we change our minds post-v1.0 we can add this without breaking the no-auto-install default.
Alternative 3: Hard-fail on missing prereqs, no instructions
aidokit detects missing prereqs and exits with an error code and a single-line message ("install Node 20+ and retry").
Pros
- Simplest implementation.
- Forces the user to read external docs (which stay up to date).
Cons
- Hostile UX. First-time users have to context-switch to find install commands.
- Cross-OS users get no help discovering the right command for their platform.
Reason rejected: the marginal cost of cataloguing install hints is small; the UX gain is significant.
Alternative 4: Bundle prereqs as dependencies of aidokit
Vendor Node, Beads, etc. inside the published aidokit package.
Pros
- Truly one-command setup.
Cons
- Package size balloons.
- We re-implement what every OS and package manager already does.
- Updates require an
aidokitrelease for every prereq patch. - Cannot bundle Claude Code or Codex CLI (their authentication state lives elsewhere).
Reason rejected: scope of aidokit is the workflow layer, not a runtime distribution. Bundling tools is a different product.
Implementation notes
- The escape hatch flag is
--skip-prereq-check. It is documented in.docs/docs/specs/cli-reference.mdand surfaced in the error message forPREREQ_MISSING. - Exit code
10(PREREQ_MISSING) is reserved exclusively for this case per.docs/ARCHITECTURE.md §16.2. aidokit doctor(v0.5+) runs the same prereq check read-only; it never proposes installs either.- Capability declarations in adapter manifests (
runsShellCommands) must not list system package managers. CI lint will enforce this once@aidokit/core's capability checker is implemented. - The
securitySensitive: trueflag on MCP entries is a separate concern (network and filesystem access), not related to this policy.
Validation
This decision is validated when:
- [ ]
aidokit initagainst a machine missing all prereqs never executes a host install command, regardless of flags. - [ ]
aidokit init --yesexits with code 10 when a required prereq is missing, with the install instructions printed. - [ ]
aidokit init --skip-prereq-checksucceeds past the prereq stage when prereqs are absent (subsequent stages may still fail, which is expected). - [ ] No adapter manifest in the v0.1 release declares a
runsShellCommandsentry containingbrew,apt,dnf,pacman,scoop,winget, orchoco. - [ ]
aidokit doctor(v0.5+) reports prereq status without offering to install.
References
Internal
- ADR 0001 — Runtime and Language (defines the prereqs we care about)
- ADR 0002 — Monorepo Tooling (the package boundary that holds the catalog)
- ADR 0005 — Adapter Contract Shape (defines
capabilityDeclarations) .docs/ARCHITECTURE.md§13 — Prereq check model (§13.3 cites this ADR).docs/docs/specs/cli-reference.md—--yesand--skip-prereq-checkflag definitions.docs/docs/specs/security-model.md— trust boundaries.docs/ROADMAP.md— non-goals include "auto-install of prerequisites"
External
- npm
postinstallscript guidance — https://docs.npmjs.com/cli/v10/using-npm/scripts (we model the policy after the same constraints)