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:

  1. Print and pause. Show the install command for the detected OS; let the user run it; resume on their next invocation.
  2. 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:

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:

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

Negative

Neutral


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

Cons

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

Cons

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

Cons

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

Cons

Reason rejected: scope of aidokit is the workflow layer, not a runtime distribution. Bundling tools is a different product.


Implementation notes


Validation

This decision is validated when:


References

Internal

External