Agentic Coding Flywheel Setup (ACFS)

June 26, 2026 Β· View on GitHub

Agentic Coding Flywheel Setup (ACFS) - From zero to fully-configured agentic coding VPS in 30 minutes

Version Platform License Shell

🌐 agent-flywheel.com β€” Interactive setup wizard for beginners

From zero to fully-configured agentic coding VPS in 30 minutes. A complete bootstrapping system that transforms a fresh Ubuntu VPS into a professional AI-powered development environment.

The Vision
Beginner with laptop β†’ Wizard β†’ VPS β†’ Agents coding for you

Quick Install

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/main/install.sh?$(date +%s)" | bash -s -- --yes --mode vibe

The installer is idempotentβ€”if interrupted, simply re-run it. It will automatically resume from the last completed phase without prompts.

Production environments: For stable, reproducible installs, pin to a tagged release or specific commit:

# Preferred: use a tagged release (e.g., v0.5.0)
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/v0.5.0/install.sh" | bash -s -- --yes --mode vibe --ref v0.5.0

# Alternative: pin to a specific commit SHA
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/abc1234/install.sh" | bash -s -- --yes --mode vibe --ref abc1234

Tagged releases are tested and stable. Passing --ref ensures all fetched scripts use the same version.


TL;DR

ACFS is a complete system for bootstrapping agentic coding environments:

Why you'd care:

  • Zero to Hero: Takes complete beginners from "I have a laptop" to "I have Claude/Codex/Antigravity agents writing code for me on a VPS"
  • One-Liner Magic: A single curl | bash command installs 30+ tools, configures everything, and sets up three AI coding agents
  • Vibe Mode: Pre-configured for maximum velocityβ€”passwordless sudo, dangerous agent flags enabled, optimized shell environment
  • Battle-Tested Stack: Includes the complete Dicklesworthstone stack (10 tools + utilities) for agent orchestration, coordination, and safety

What you get:

  • Modern shell (zsh + oh-my-zsh + powerlevel10k)
  • All language runtimes (bun, uv/Python, Rust, Go)
  • Three AI coding agents (Claude Code, Codex CLI, Antigravity CLI)
  • Agent coordination tools (NTM, MCP Agent Mail, SLB)
  • Cloud CLIs (Vault, Wrangler, Supabase, Vercel)
  • And 20+ more developer tools

The ACFS Experience

graph LR
    %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e8f5e9', 'lineColor': '#90a4ae'}}}%%

    subgraph user ["User's Machine"]
        LAPTOP["Laptop"]
        BROWSER["Browser"]
    end

    subgraph wizard ["Wizard Website"]
        STEPS["13-Step Guide"]
    end

    subgraph vps ["Fresh VPS"]
        UBUNTU["Ubuntu 25.10"]
        INSTALLER["install.sh"]
        CONFIGURED["Configured VPS"]
    end

    subgraph agents ["AI Agents"]
        CLAUDE["Claude Code"]
        CODEX["Codex CLI"]
        AGY["Antigravity CLI"]
    end

    LAPTOP --> BROWSER
    BROWSER --> STEPS
    STEPS -->|SSH| UBUNTU
    UBUNTU --> INSTALLER
    INSTALLER --> CONFIGURED
    CONFIGURED --> CLAUDE
    CONFIGURED --> CODEX
    CONFIGURED --> AGY

    classDef user fill:#e3f2fd,stroke:#90caf9,stroke-width:2px
    classDef wizard fill:#fff8e1,stroke:#ffcc80,stroke-width:2px
    classDef vps fill:#f3e5f5,stroke:#ce93d8,stroke-width:2px
    classDef agent fill:#e8f5e9,stroke:#a5d6a7,stroke-width:2px

    class LAPTOP,BROWSER user
    class STEPS wizard
    class UBUNTU,INSTALLER,CONFIGURED vps
    class CLAUDE,CODEX,AGY agent

For Beginners

ACFS includes a step-by-step wizard website at agent-flywheel.com that guides complete beginners through:

  1. Installing a terminal on their local machine
  2. Generating SSH keys (for secure access later)
  3. Renting a VPS from providers like OVH or Contabo
  4. Connecting via SSH with a password (initial setup)
  5. Running the installer (which sets up key-based access)
  6. Reconnecting securely with your SSH key
  7. Starting to code with AI agents

For Developers

ACFS is a one-liner that transforms any fresh Ubuntu VPS into a fully-configured development environment with modern tooling and three AI coding agents ready to go.

For Teams

ACFS provides a reproducible, idempotent setup that ensures every team member's VPS environment is identicalβ€”eliminating "works on my machine" for agentic workflows.


Architecture & Design

ACFS is built around a single source of truth: the manifest file. Everything elseβ€”the installer scripts, doctor checks, website contentβ€”derives from this central definition. This architecture ensures consistency and makes the system easy to extend.

One-Page System Data Flow

flowchart TB
  %% User and website
  subgraph U["User (local machine)"]
    Browser["Browser"]
    Terminal["Terminal / SSH client"]
  end

  subgraph W["Wizard Website (Next.js 16) β€” apps/web"]
    Wizard["Wizard UI (/wizard/*)"]
    InstallRoute["GET /install (302 redirect to raw install.sh)"]
    WebState["State: URL params + localStorage"]
  end

  %% Repo sources
  subgraph R["Repo (source)"]
    Manifest["acfs.manifest.yaml<br/>Modules + install + verify + deps"]
    Generator["packages/manifest<br/>Parser (Zod) + generate.ts"]
    Generated["scripts/generated/* (reference)<br/>category installers + doctor_checks.sh"]
    Installer["install.sh (production one-liner)"]
    Lib["scripts/lib/*<br/>security / doctor / update / services-setup"]
    Configs["acfs/*<br/>zshrc + tmux.conf + onboard lessons"]
    Checksums["checksums.yaml<br/>sha256 for upstream installers"]
    Tests["tests/vm/test_install_ubuntu.sh<br/>Docker integration test"]
  end

  %% Target VPS
  subgraph V["Target VPS (Ubuntu 25.10, auto-upgraded)"]
    Run["Run install.sh"]
    Verify["Verified upstream installers<br/>(security.sh + checksums.yaml)"]
    AcfsHome["~/.acfs/<br/>configs + scripts + state.json"]
    Commands["Commands<br/>acfs doctor / acfs update / acfs services-setup / onboard"]
    Tools["Installed tools<br/>bun/uv/rust/go + tmux/rg/gh + vault + ..."]
    Agents["Agent CLIs<br/>claude / codex / agy"]
    Stack["Stack tools<br/>ntm / mcp_agent_mail / ubs / bv / cass / cm / caam / slb / dcg / ru"]
  end

  %% Website guidance flow
  Browser --> Wizard
  Wizard --> WebState
  Wizard --> InstallRoute
  InstallRoute -->|redirects to| Installer

  %% How users fetch/run the installer
  Terminal -->|curl / bash| Installer
  Terminal -->|SSH| Run

  %% Manifest-driven generation (reference today)
  Manifest --> Generator --> Generated
  Generated -.->|planned: install.sh calls generated install_all.sh| Installer

  %% Installer composition
  Lib --> Installer
  Configs --> Installer
  Checksums --> Installer
  Tests -->|validates| Installer

  %% VPS install results
  Installer --> Run
  Run --> Verify
  Verify --> Tools
  Verify --> Agents
  Verify --> Stack
  Run --> AcfsHome --> Commands
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                            SOURCE OF TRUTH                                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚  acfs.manifest.yaml                                                  β”‚    β”‚
β”‚  β”‚  Tool Definitions β€’ Install Commands β€’ Verification Logic           β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                      β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β–Ό                                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚        CODE GENERATION            β”‚   β”‚        WIZARD WEBSITE             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ TypeScript Parser (Zod)     β”‚  β”‚   β”‚  β”‚ apps/web/ (Next.js 16)      β”‚  β”‚
β”‚  β”‚ generate.ts                 β”‚  β”‚   β”‚  β”‚ agent-flywheel.com          β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚
                    β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     GENERATED OUTPUTS (REFERENCE)                          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚ scripts/generated/ β”‚  β”‚ doctor_checks.sh   β”‚  β”‚ install_all.sh     β”‚   β”‚
β”‚  β”‚ 11 Category Scriptsβ”‚  β”‚ Verification Logic β”‚  β”‚ Master Installer   β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚
                    β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                            INSTALLER                                       β”‚
β”‚  install.sh + scripts/lib/*.sh + checksums.yaml (SHA256 verification)     β”‚
β”‚  (scripts/generated/* are sourced; execution is feature-flagged)            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚
                    β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           TARGET VPS                                       β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚ 30+ Tools    β”‚  β”‚ zsh + p10k   β”‚  β”‚ AI Agents    β”‚  β”‚ ~/.acfs/     β”‚   β”‚
β”‚  β”‚ Installed    β”‚  β”‚ Shell Config β”‚  β”‚ Claude/Codex β”‚  β”‚ Configurationsβ”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Why This Architecture?

Single Source of Truth: The manifest file (acfs.manifest.yaml) defines every toolβ€”its name, description, install commands, and verification logic. When you add or edit a tool in the manifest, the generator automatically updates the generated scripts and manifest-derived checks. The production one-liner installer (install.sh) is still hand-written today, so behavior changes may also require updating install.sh until full migration.

TypeScript + Zod Validation: The manifest parser uses Zod schemas to validate the YAML at parse time. Typos, missing fields, and structural errors are caught immediately during generationβ€”not at runtime on a user's VPS when the installer fails halfway through.

Generated Scripts: Rather than hand-maintaining 11 category installer scripts and keeping them synchronized, the generator produces them from the manifest. This means:

  • A consistent, auditable view of manifest-defined install logic (some modules intentionally emit TODOs)
  • Consistent error handling and logging across all modules
  • A clear path toward future installer integration

Components

ComponentPathTechnologyPurpose
Manifestacfs.manifest.yamlYAMLSingle source of truth for all tools
Generatorpackages/manifest/src/generate.tsTypeScript/BunProduces installer scripts from manifest
Websiteapps/web/Next.js 16 + Tailwind 4Step-by-step wizard for beginners
Installerinstall.shBashOne-liner bootstrap script
Lib Scriptsscripts/lib/BashModular installer functions
Generated Scriptsscripts/generated/BashAuto-generated category installers (sourced by install.sh; execution is feature-flagged)
Configsacfs/Shell/Tmux configsFiles deployed to ~/.acfs/
Onboardingacfs/onboard/Bash + MarkdownInteractive tutorial system
Checksumschecksums.yamlYAMLSHA256 hashes for upstream installers

The Manifest System

acfs.manifest.yaml is the single source of truth for all tools installed by ACFS. It defines what gets installed, how to install it, and how to verify the installation worked.

Manifest Structure

version: "1.0"
meta:
  name: "ACFS"
  description: "Agentic Coding Flywheel Setup"
  version: "0.1.0"

modules:
  base.system:
    description: "Base packages + sane defaults"
    category: base
    install:
      - sudo apt-get update -y
      - sudo apt-get install -y curl git ca-certificates unzip tar xz-utils jq build-essential
    verify:
      - curl --version
      - git --version
      - jq --version

  agents.claude:
    description: "Claude Code"
    category: agents
    install:
      - "Install claude code via official method"
    verify:
      - claude --version || claude --help

Each module specifies:

  • description: Human-readable name
  • category: Grouping for installer organization (base, shell, cli, lang, tools, db, cloud, agents, stack, acfs)
  • install: Commands to run (or descriptions that become TODOs)
  • verify: Commands that must succeed to confirm installation

The Generator Pipeline

The TypeScript generator (packages/manifest/src/generate.ts) reads the manifest and produces:

  1. Category Scripts (scripts/generated/install_base.sh, install_agents.sh, etc.)

    • One script per category with individual install functions
    • Consistent logging and error handling
    • Verification checks after each module
  2. Doctor Checks (scripts/generated/doctor_checks.sh)

    • All verify commands extracted into a runnable health check
    • Tab-delimited format (to safely handle || in shell commands)
    • Reports pass/fail/skip for each module
  3. Master Installer (scripts/generated/install_all.sh)

    • Sources all category scripts
    • Runs them in dependency order
    • Single entry point for running the generated installers

Note: The production one-liner installer (install.sh) defaults to the legacy implementations; generated installers are sourced and can be enabled per-category via feature flags during migration.

To regenerate after manifest changes:

cd packages/manifest
bun run generate        # Generate scripts
bun run generate:dry    # Preview without writing

Why TypeScript for Code Generation?

Shell can parse YAML with yq, but TypeScript + Zod offers:

  • Type safety: The parser knows the exact shape of a manifest
  • Validation: Zod catches malformed YAML with descriptive errors
  • Transformation: Complex logic (sorting by dependencies, escaping) is natural in TypeScript
  • Consistency: All generated code follows the same patterns

The generator itself is ~400 lines of TypeScript. The generated output is ~1000 lines of Bash across 13 files. The trade-off is clearly in favor of maintaining the generator.


Security Verification

ACFS downloads and executes installer scripts from the internet. This is inherently riskyβ€”a compromised upstream could inject malicious code. The security verification system mitigates this risk.

How It Works

The checksums.yaml file contains SHA256 hashes for all upstream installer scripts:

# checksums.yaml
installers:
  bun:
    url: "https://bun.sh/install"
    sha256: "a1b2c3d4..."

  rust:
    url: "https://sh.rustup.rs"
    sha256: "e5f6a7b8..."

The security library (scripts/lib/security.sh) provides:

  1. HTTPS Enforcement: All installer URLs must use HTTPS. Non-HTTPS URLs fail immediately.

  2. Checksum Verification: Before executing a downloaded script, the system:

    • Downloads the content to memory
    • Calculates the SHA256 hash
    • Compares against the stored hash
    • Only executes if they match
  3. Verification Modes:

    ./scripts/lib/security.sh --print              # List all upstream URLs
    ./scripts/lib/security.sh --verify             # Verify all against saved checksums
    ./scripts/lib/security.sh --update-checksums   # Generate new checksums.yaml
    ./scripts/lib/security.sh --checksum URL       # Calculate SHA256 of any URL
    

When Checksums Fail

A checksum mismatch can mean:

  1. Normal update: The upstream maintainer released a new version
  2. Potential compromise: Someone modified the script maliciously

The verification report distinguishes these cases:

  • If multiple checksums fail simultaneously, investigate before updating
  • If a single checksum fails after a known release, update is likely safe

To update after verifying a legitimate upstream change:

./scripts/lib/security.sh --update-checksums > checksums.yaml
git diff checksums.yaml  # Review what changed
git commit -m "chore: update upstream checksums"

Why This Approach?

The curl | bash pattern is controversial but practical. ACFS makes it safer by:

  • Verifying content before execution (not just transport via HTTPS)
  • Making checksums auditable in version control
  • Providing tools to detect and investigate changes
  • Failing closed (no execution on mismatch)

This is defense in depthβ€”HTTPS protects transport, checksums protect content.


The Installer

The installer is the heart of ACFSβ€”a modular Bash script that transforms a fresh Ubuntu VPS into a fully-configured development environment.

Usage

Full vibe mode (recommended for throwaway VPS):

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/main/install.sh?$(date +%s)" | bash -s -- --yes --mode vibe

Interactive mode (asks for confirmation):

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/main/install.sh" | bash

Safe mode (no passwordless sudo, agent confirmations enabled):

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/main/install.sh" | bash -s -- --mode safe

Installer Modes

ModePasswordless SudoAgent FlagsBest For
vibeYes--dangerously-skip-permissionsThrowaway VPS, maximum velocity
safeNoStandard confirmationsProduction-like environments

Installation Phases

graph TD
    %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e8f5e9', 'lineColor': '#90a4ae'}}}%%

    A["Phase 1: User Normalization<br/><small>Create ubuntu user, migrate SSH keys</small>"]
    B["Phase 2: APT Packages<br/><small>Essential system packages</small>"]
    C["Phase 3: Shell Setup<br/><small>zsh, oh-my-zsh, powerlevel10k</small>"]
    D["Phase 4: CLI Tools<br/><small>ripgrep, fzf, lazygit, etc.</small>"]
    E["Phase 5: Language Runtimes<br/><small>bun, uv, rust, go</small>"]
    F["Phase 6: AI Agents<br/><small>claude, codex, agy</small>"]
    G["Phase 7: Cloud Tools<br/><small>vault, wrangler, supabase, vercel</small>"]
    H["Phase 8: Dicklesworthstone Stack<br/><small>ntm, dcg, ru, ubs, mcp_agent_mail, etc.</small>"]
    I["Phase 9: Configuration<br/><small>Deploy acfs.zshrc, tmux.conf</small>"]
    J["Phase 10: Verification<br/><small>acfs doctor</small>"]

    A --> B --> C --> D --> E --> F --> G --> H --> I --> J

    classDef phase fill:#e8f5e9,stroke:#81c784,stroke-width:2px,color:#2e7d32
    class A,B,C,D,E,F,G,H,I,J phase

Key Properties

PropertyDescription
IdempotentSafe to re-run; skips already-installed tools
CheckpointedPhases resume automatically from ~/.acfs/state.json
Pre-flight validatedRun scripts/preflight.sh to catch issues before install
LoggedColored output with progress indicators
ModularEach category is a separate sourceable script

Resume Capability

The installer tracks progress in ~/.acfs/state.json. If interrupted:

  • Re-run the same commandβ€”it resumes from the last completed phase
  • No prompts or confirmations needed (with --yes)
  • Already-installed tools are detected and skipped

To force a fresh reinstall of all tools:

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/main/install.sh" | bash -s -- --yes --mode vibe --force-reinstall

Pre-Flight Check

Before running the full installer, validate your system:

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/main/scripts/preflight.sh" | bash
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/main/scripts/preflight.sh" | bash -s -- --json
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/main/scripts/preflight.sh" | bash -s -- --format toon
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/main/scripts/preflight.sh" | bash -s -- --network=skip

This checks:

  • OS compatibility (Ubuntu 22.04+; installer upgrades to 25.10)
  • Architecture (x86_64 or ARM64)
  • Memory and disk space (minimum 4GB RAM, 10GB free disk)
  • Network connectivity to required URLs
  • Cached checksums.yaml availability for verified upstream installers
  • APT lock status
  • Potential conflicts (nvm, pyenv, existing ACFS)

Network checks performed:

CheckWhat it verifiesFix if failing
DNS resolutionCan resolve github.com, raw.githubusercontent.comCheck provider DNS settings; inspect resolvectl status or /etc/resolv.conf
GitHub HTTPSCan reach github.com:443Check firewall, proxy, or VPN settings
Verified installer URLsCritical upstream installer endpoints from checksums.yaml plus ACFS raw contentMay need to retry; transient failures OK; checksum verification still stays enabled
APT mirrorsDefault Ubuntu mirror reachableCheck /etc/apt/sources.list or try different mirror
Offline/cache mode--network=skip skips live URL checks while still reporting local checksum availabilityRe-run with --network=check when online before a release or difficult install

For checksum-refresh review, compare a generated candidate without changing checksums.yaml:

candidate="/tmp/acfs-checksums.$$.candidate.yaml"
./scripts/lib/security.sh --update-checksums > "$candidate"
./scripts/preflight.sh --checksum-candidate "$candidate"

Common preflight failures:

ErrorCauseSolution
"Cannot resolve github.com"DNS misconfiguredCheck provider DNS settings or reboot; do not overwrite managed resolver files
"Cannot reach github.com"Firewall blocking HTTPSAllow outbound port 443
"timeout contacting github.com"Network, proxy, or provider route is slowRetry with --network=check; if it persists after install bootstrap, run acfs support-bundle
"APT mirror slow or unreachable"Regional mirror downEdit /etc/apt/sources.list to use archive.ubuntu.com
"checksum candidate differs"Upstream verified installer content changedReview the diff; do not install from unverified fallback sources
"APT lock held"Another apt process runningWait for it to finish; reboot and resume if it remains stuck
"Insufficient disk space"Less than 10GB freeClean up with sudo apt autoremove or expand disk

Console Output

The installer uses semantic colors for progress visibility:

[1/8] Installing essential packages...     # Blue: progress steps
    Installing zsh, git, curl...           # Gray: details
⚠️  May take a few minutes                 # Yellow: warnings
βœ– Failed to install package               # Red: errors
βœ” Shell setup complete                    # Green: success

Automatic Ubuntu Upgrade

ACFS automatically upgrades Ubuntu to version 25.10 before installation when running on older versions. This ensures compatibility with the latest packages and optimal performance.

How it works:

  1. Detects your current Ubuntu version
  2. Calculates the upgrade path (e.g., 24.04 β†’ 25.04 β†’ 25.10)
  3. Performs sequential do-release-upgrade operations
  4. Reboots after each upgrade (handled automatically)
  5. Resumes via systemd service after reboot
  6. Continues ACFS installation once at target version

Expected timeline:

  • Each version hop takes 30-60 minutes
  • Full chain from 24.04 β†’ 25.10 takes 1.5-3 hours
  • SSH sessions disconnect during reboots (reconnect to monitor)

To skip automatic upgrade:

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/main/install.sh" | bash -s -- --yes --mode vibe --skip-ubuntu-upgrade

To specify a different target version:

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/main/install.sh" | bash -s -- --yes --mode vibe --target-ubuntu=25.04

Monitoring upgrade progress:

# Check current status
/var/lib/acfs/check_status.sh

# View upgrade logs
journalctl -u acfs-upgrade-resume -f

# View detailed logs
tail -f /var/log/acfs/upgrade_resume.log

Important notes:

  • Create a VM snapshot before upgrading (recommended but not required)
  • Upgrades cannot be undone without restoring from snapshot
  • The system will reboot multiple times automatically
  • EOL interim releases (like 24.10) may be skipped automatically if they are no longer offered by do-release-upgrade
  • Reconnect via SSH after each reboot to monitor progress

The Update Command

After installation, keeping tools current is handled by acfs-update. It provides a unified interface for updating all installed components.

Usage

acfs-update                  # Update apt, runtimes, shell, agents, cloud CLIs, and stack tools
acfs-update --agents-only    # Only update coding agents
acfs-update --runtime-only   # Only update runtimes (bun, rust, uv, go)
acfs-update --dry-run        # Preview changes without making them
acfs-update --yes --quiet --no-self-update
                             # Automated mode that avoids changing the ACFS tree itself
acfs-update --bootstrap-self-update
                             # Explicitly convert a non-git ACFS install into a git checkout

What Gets Updated

CategoryToolsMethod
Systemapt packagesapt update && apt upgrade
ShellOMZ, P10K, pluginsgit pull on each repo
ShellAtuin, ZoxideRe-run upstream installers
RuntimeBunbun upgrade
RuntimeRustrustup update stable
Runtimeuv (Python)uv self update
RuntimeGoapt upgrade (if apt-managed)
AgentsClaude Codeclaude update --channel latest
AgentsCodexbun install -g @latest
AgentsAntigravityagy update (or verified installer with --force)
CloudWrangler, Vercelbun install -g @latest
CloudSupabaseGitHub release tarball (sha256 checksums)
Stackntm, slb, ubs, dcg, ru, etc.Re-run upstream installers

Options

Category Selection:

--apt-only       Only update system packages
--agents-only    Only update coding agents
--cloud-only     Only update cloud CLIs
--shell-only     Only update shell tools (OMZ, P10K, plugins, Atuin, Zoxide)
--runtime-only   Only update runtimes (bun, rust, uv, go)
--stack          Include Dicklesworthstone stack (enabled by default)

Skip Categories:

--no-apt         Skip apt updates
--no-agents      Skip agent updates
--no-cloud       Skip cloud CLI updates
--no-shell       Skip shell tool updates
--no-runtime     Skip runtime updates (bun, rust, uv, go)

Behavior:

--force            Install missing tools (not just update existing)
--dry-run          Preview changes without making them
--yes, -y          Non-interactive mode (skip prompts)
--quiet, -q        Minimal output (only errors and summary)
--verbose, -v      Show detailed command output
--abort-on-failure Stop on first failure (default: continue)

Logs

Update logs are automatically saved to ~/.acfs/logs/updates/ with timestamps:

# View most recent log
cat ~/.acfs/logs/updates/$(ls -1t ~/.acfs/logs/updates | head -1)

# Follow a running update
tail -f ~/.acfs/logs/updates/$(ls -1t ~/.acfs/logs/updates | head -1)

Why Separate from the Installer?

The installer transforms a fresh VPS. The update command maintains an existing installation. Separating them allows:

  • Focused updates: Update just agents without touching system packages
  • Dry-run previews: See what would change before committing
  • Skip flags: Temporarily exclude categories that are working fine
  • Stack control: Stack updates are included by default; skip with --no-stack
  • Automated updates: Run via cron with --yes --quiet

ACFS CLI Commands

After installation, the acfs command provides a unified interface for managing your environment. Each subcommand is designed to be fast, informative, and scriptable.

Quick Reference

acfs info                    # Lightning-fast system overview
acfs cheatsheet              # Discover installed aliases
acfs dashboard generate      # Generate HTML status page
acfs doctor                  # Health checks
acfs newproj                 # Create a new project (TUI or CLI)
acfs update                  # Update all tools
acfs services-setup          # Configure agent credentials
acfs continue                # View upgrade progress after reboot

acfs newproj β€” New Project Wizard

Create a new project directory with ACFS defaults (git init, optional br/beads, Claude settings, AGENTS.md). The interactive wizard is recommended for beginners.

Interactive wizard (recommended):

acfs newproj --interactive
acfs newproj -i
acfs newproj -i myapp         # Prefill project name

The wizard guides you through:

  • Project naming and location
  • Tech stack detection/selection
  • Feature selection (br/beads, Claude settings, AGENTS.md, UBS ignore)
  • AGENTS.md customization preview
TUI Wizard Screenshots

Welcome Screen:

    ╔═══════════════════════════════════════════════════════╗
    β•‘                                                       β•‘
    β•‘      β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—                β•‘
    β•‘     β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β• β–ˆβ–ˆβ•”β•β•β•β•β• β–ˆβ–ˆβ•”β•β•β•β•β•                β•‘
    β•‘     β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘      β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—                β•‘
    β•‘     β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘      β–ˆβ–ˆβ•”β•β•β•   β•šβ•β•β•β•β–ˆβ–ˆβ•‘                β•‘
    β•‘     β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘      β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘                β•‘
    β•‘     β•šβ•β•  β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β•      β•šβ•β•β•β•β•β•β•                β•‘
    β•‘                                                       β•‘
    β•‘          Agentic Coding Flywheel Setup                β•‘
    β•‘                                                       β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

This wizard will help you set up a new project with:

  βœ“ Project directory structure
  βœ“ Git repository initialization
  βœ“ AGENTS.md for AI coding assistants
  βœ“ Beads issue tracking (optional)
  βœ“ Claude Code settings (optional)

Confirmation Screen:

──────────────────── Review & Confirm ────────────────────
                                              Step 7 of 9

Please review your selections before creating the project.

Project Summary
──────────────────────────────────────────────────────────
  Name:       myapp
  Location:   /home/user/projects/myapp
  Tech:       Node.js, TypeScript

Features
──────────────────────────────────────────────────────────
  βœ“ Beads tracking
  βœ“ Claude Code settings
  βœ“ AGENTS.md
  βœ“ UBS ignore

Files to Create
──────────────────────────────────────────────────────────
myapp/
β”œβ”€β”€ .git/
β”œβ”€β”€ AGENTS.md
β”œβ”€β”€ .beads/
β”‚   └── beads.db
β”œβ”€β”€ .claude/
β”‚   └── settings.local.json
β”œβ”€β”€ .ubsignore
β”œβ”€β”€ README.md
└── .gitignore

Options:
  [Enter/c]   Create project
  [e]         Edit selections (go back)
  [q/Esc]     Cancel

CLI mode (automation):

acfs newproj myapp
acfs newproj myapp /custom/path
acfs newproj myapp --no-br

Notes:

  • The TUI uses gum when available (arrow keys, Space to toggle, Enter to confirm). Without gum, it falls back to numbered prompts.
  • Minimum terminal size: 60x15.
  • CLI mode skips existing AGENTS.md; the wizard overwrites it, so move it aside if you want to keep the old one.

acfs info β€” System Overview

Displays installation status in under 1 second by reading cached state (no verification).

acfs info                # Terminal output (default)
acfs info --json         # JSON output for scripting
acfs info --html         # Self-contained HTML page
acfs info --minimal      # Just essentials (IP, key commands)

Example output:

╔══════════════════════════════════════════════════════════════╗
β•‘                    ACFS System Info                           β•‘
╠══════════════════════════════════════════════════════════════╣
β•‘  Host: vps-12345.contabo.net                                  β•‘
β•‘  IP: 192.168.1.100                                            β•‘
β•‘  User: ubuntu                                                 β•‘
β•‘  Uptime: 3 days, 4 hours                                      β•‘
β•‘                                                               β•‘
β•‘  Quick Commands:                                              β•‘
β•‘    cc    β†’ Claude Code (dangerous mode)                       β•‘
β•‘    cod   β†’ Codex CLI (dangerous mode)                         β•‘
β•‘    agy   β†’ Antigravity CLI (Gemini 3.1 Pro High)              β•‘
β•‘    ntm   β†’ Named Tmux Manager                                 β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

Design Philosophy:

  • Speed: Must complete in <1 second
  • Read-only: Never verifies or tests (that's doctor's job)
  • Offline: No network calls required
  • Fallback: Graceful degradation if data missing

acfs cheatsheet β€” Alias Discovery

Parses ~/.acfs/zsh/acfs.zshrc to show all installed aliases and commands.

acfs cheatsheet              # List all aliases
acfs cheatsheet git          # Filter by category or search term
acfs cheatsheet --category Agents
acfs cheatsheet --search docker
acfs cheatsheet --json       # JSON output for tooling

Example output:

╔═══════════════════════════════════════════════════════════════╗
β•‘  ACFS Cheatsheet                                               β•‘
╠═══════════════════════════════════════════════════════════════╣
β•‘  Agents                                                        β•‘
β•‘    cc   β†’ claude --dangerously-skip-permissions                β•‘
β•‘    cod  β†’ codex --dangerously-bypass-approvals-and-sandbox     β•‘
β•‘    agy  β†’ agy --model 'Gemini 3.1 Pro (High)'                  β•‘
β•‘                                                                β•‘
β•‘  Git                                                           β•‘
β•‘    gs   β†’ git status                                           β•‘
β•‘    gp   β†’ git push                                             β•‘
β•‘    gl   β†’ git pull                                             β•‘
β•‘    gco  β†’ git checkout                                         β•‘
β•‘                                                                β•‘
β•‘  Modern CLI                                                    β•‘
β•‘    ls   β†’ lsd --inode --long --all                             β•‘
β•‘    cat  β†’ bat                                                  β•‘
β•‘    grep β†’ rg                                                   β•‘
β•‘    lg   β†’ lazygit                                              β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

acfs dashboard β€” HTML Status Page

Generates a self-contained HTML dashboard and optionally serves it.

acfs dashboard generate              # Generate ~/.acfs/dashboard/index.html
acfs dashboard generate --force      # Force regeneration
acfs dashboard serve                 # Serve on localhost:8080
acfs dashboard serve --port 3000     # Custom port
acfs dashboard serve --public        # Bind to 0.0.0.0

The dashboard provides:

  • System health at a glance
  • Tool versions and status
  • Quick command reference
  • Recent activity summary

acfs services-setup β€” Credential Configuration

Interactive wizard for configuring AI agent credentials and cloud service logins.

acfs services-setup          # Run full setup wizard

Guides you through:

  • Claude Code: API key configuration
  • Codex CLI: ChatGPT account login
  • Antigravity CLI: Google account authentication
  • GitHub CLI: gh auth login
  • Cloud CLIs: Wrangler, Supabase, Vercel authentication

Also offers to install DCG (Destructive Command Guard), a Claude Code hook that blocks destructive commands like rm -rf /.

acfs continue β€” Upgrade Progress

After an Ubuntu upgrade reboot, view installation progress:

acfs continue                # Show current upgrade status

Displays:

  • Original Ubuntu version
  • Target version
  • Current upgrade stage
  • Next steps after completion

Learning Hub (Web)

In addition to the terminal-based onboarding, ACFS provides a comprehensive web-based Learning Hub at agent-flywheel.com/learn.

Web Lessons

The Learning Hub provides interactive lessons with progress tracking:

#LessonDurationTopics
0Welcome & Overview5 minWhat's installed, mental model
1Linux Navigation8 minFilesystem structure, essential commands
2SSH & Persistence6 minSecure connections, staying connected
3tmux Basics7 minSessions, windows, panes, survival
4Git Essentials10 minVersion control, dangerous operations
5GitHub CLI8 minIssues, PRs, releases via gh
6Agent Commands10 minClaude, Codex, Antigravity usage
7NTM Command Center8 minSession orchestration
8NTM Prompt Palette6 minQuick command access
9The Flywheel Loop8 minHow all 10 tools work together

Features:

  • Progress tracking in localStorage
  • Code blocks with copy buttons
  • Expandable deep-dive sections
  • Practical exercises

Command Reference

The Command Reference documents every installed tool:

CategoryCommands
Agentscc, cod, agy
Searchrg, fd, sg, fzf
Gitlg, gh, git-lfs
Systemz, bat, lsd, atuin, tmux
Stackntm, bv, am, cass, cm, ubs, slb, caam, dcg, ru
Languagesbun, uv, cargo, go
Cloudwrangler, supabase, vercel, vault

Technical Glossary

The Glossary defines 100+ technical terms with:

  • One-liner: Quick tooltip definition
  • Full explanation: Plain language description
  • Analogy: "Think of it like..."
  • Why we use it: Problem it solves
  • Related terms: For context

Example entry:

RAM (Random Access Memory)
β”œβ”€β”€ Short: Fast temporary storage your computer uses while working
β”œβ”€β”€ Long: RAM is your computer's short-term memory...
β”œβ”€β”€ Analogy: Like your desk space while working
β”œβ”€β”€ Why: More RAM = run more programs simultaneously
└── Related: vCPU, VPS, NVMe

Flywheel Visualization

The Flywheel page visualizes tool interactions:

Plan (Beads) ──> Coordinate (Agent Mail) ──> Execute (NTM + Agents)
      ^                                              β”‚
      β”‚                                              v
      └──── Remember (CASS Memory) <──── Scan (UBS) β”˜

Workflow Scenarios:

ScenarioDescriptionTime
Daily Parallel Progress3+ projects moving simultaneously3+ hours
Agents Reviewing AgentsCross-review before merging30 min
Memory-Augmented DebuggingPast solutions for current bugs15 min
Coordinated Feature DevMultiple agents, one feature2+ hours

Tool Status Page

The Tool Status page provides a searchable catalog of all installed tools:

  • Search & Filter: Find tools by name, CLI command, features, or tech stack
  • Category Browsing: Filter by "Flywheel Stack" (core agentic tools) or "Utilities"
  • Tool Details: Each card shows the tool name, CLI command, GitHub stars, features, and tech stack
  • Live Data: Content is auto-generated from acfs.manifest.yaml β€” never manually edited

This page helps users discover tools they may not know about and understand how each fits into the agentic coding workflow.

Interactive Website Components

The wizard website includes specialized components for guiding beginners:

ConnectionCheck Component: A prominent visual that helps users verify they're connected to their VPS before running commands:

  • Side-by-side comparison: "Wrong (laptop)" vs "Right (VPS)"
  • Terminal prompt examples for Windows, Mac, and Linux
  • Clear "STOP!" warning with color-coded styling

CommandCard Component: CLI instruction cards with:

  • Syntax-highlighted code blocks
  • One-click copy button
  • Platform-specific variations (bash/zsh/PowerShell)
  • Expandable explanations

Jargon Component (Responsive Technical Terms): A sophisticated tooltip system that adapts to device capabilities:

Desktop behavior:

  • Hover reveals floating tooltip with term definition
  • Radix UI Tooltip for accessible ARIA-compliant overlays
  • Viewport-aware positioning (auto-flips when near edges)
  • 200ms hover delay prevents tooltip spam

Mobile behavior:

  • Tap opens bottom sheet drawer (Vaul library)
  • Full definition visible without tiny tap targets
  • Swipe-to-dismiss gesture support
  • Snap points for partial/full expansion

Visual features:

  • Gradient underline indicates tappable term
  • Each term gets unique gradient based on slug hash
  • Consistent color scheme with OKLCH tokens

Content structure per term:

{
  term: "VPS",
  short: "Virtual Private Server - a remote computer you rent",
  long: "A VPS is your own slice of a powerful computer...",
  analogy: "Think of it like renting an apartment in a building",
  whyWeUseIt: "You get root access, dedicated resources...",
  relatedTerms: ["SSH", "Ubuntu", "RAM"]
}

Confetti Celebration: On lesson completion:

  • Burst of celebratory confetti particles
  • Randomized encouraging messages
  • Special celebration for completing all lessons
  • Respects prefers-reduced-motion setting

Stepper Component: Multi-step progress indicator:

  • Visual step-by-step progress
  • Clickable navigation
  • Completion checkmarks
  • Mobile-responsive design

Expanded Lesson Library

The Learning Hub includes specialized lessons for each tool in the Dicklesworthstone stack:

LessonTopics
UBS (Bug Scanner)Scan workflow, severity levels, CI integration
Agent MailRegistration, messaging, file reservations
CASS (Session Search)Indexing, searching, cross-agent queries
CASS Memory (cm)Rule extraction, playbook management
BeadsIssue tracking, graph metrics, priorities
SLB (Safety)Two-person rule, dangerous command approval
Prompt EngineeringEffective prompts, context management
Real-World Case StudyEnd-to-end feature development walkthrough

Each lesson includes:

  • Conceptual introduction
  • Practical commands with examples
  • Interactive exercises
  • Common pitfalls to avoid
  • Links to tool documentation

Interactive Onboarding (TUI)

After installation, users can learn the ACFS workflow through an interactive terminal-based tutorial. The onboarding TUI discovers lesson markdown files dynamically from acfs/onboard/lessons, so the curriculum can grow as new tools and workflows are added without changing the launcher.

Running Onboarding

onboard                # Launch interactive menu
onboard status         # Show completion status
onboard --list         # Alias for status
onboard 3              # Jump to lesson 3
onboard reset          # Reset progress and start fresh
onboard --reset        # Alias for reset

Lessons

Run onboard --help to see the currently discovered lesson list. The curriculum currently spans Linux basics, SSH, tmux, agent login, NTM, the flywheel workflow, updating, Beads, RCH, and other ACFS tools. Because lessons are discovered by filename, adding a new NN_name.md file automatically extends the tutorial.

Progress Tracking

Progress is saved in ~/.acfs/onboard_progress.json:

{
  "completed": [0, 1, 2],
  "current": 3,
  "started_at": "2024-12-20T10:30:00-05:00"
}

The TUI shows completion status for each lesson and suggests the next one to take. Users can jump to any lesson or re-take completed ones.

Enhanced UX with Gum

If Charmbracelet Gum is installed, the onboarding system uses it for enhanced terminal UIβ€”selection menus, styled prompts, and better formatting. Without Gum, it falls back to simple numbered menus that work everywhere.


Tools Installed

ACFS installs a comprehensive suite of 30+ tools organized into categories:

Shell & Terminal UX

ToolCommandDescription
zshzshModern shell
oh-my-zsh-zsh plugin framework
powerlevel10k-Fast, customizable prompt
lsdls (aliased)Modern ls with icons
atuinCtrl+RShell history with search
fzffzfFuzzy finder
zoxidezSmarter cd
direnv-Directory-specific env vars

Languages & Package Managers

ToolCommandDescription
bunbunFast JS/TS runtime + package manager
uvuvFast Python package manager
RustcargoRust toolchain
GogoGo toolchain

Dev Tools

ToolCommandDescription
tmuxtmuxTerminal multiplexer
ripgreprgFast recursive grep
ast-grepsgStructural code search
lazygitlg (aliased)Git TUI
GitHub CLIghGitHub auth, issues, PRs
Git LFSgit-lfsLarge file support for Git
batcat (aliased)Cat with syntax highlighting
neovimnvimModern vim
jqjqJSON processor
rsyncrsyncFast file sync/copy
lsoflsofDebug open files/ports
dnsutilsdigDNS debugging
netcatncNetwork debugging
stracestraceSyscall tracing

Networking

ToolCommandDescription
TailscaletailscaleZero-config mesh VPN

Tailscale Integration:

Tailscale provides secure, encrypted networking between your devices without complex firewall configuration:

# Authenticate and join your tailnet
tailscale up

# Check connection status
tailscale status

# Get your Tailscale IP
tailscale ip

# SSH over Tailscale (bypasses firewalls)
ssh ubuntu@your-vps.tailnet-name.ts.net

Benefits for agentic workflows:

  • Firewall-free access: Connect even when behind NAT or restrictive firewalls
  • MagicDNS: Access your VPS by hostname instead of IP
  • SSH keys over Tailscale: Use tailscale ssh for key-free authentication
  • ACLs: Fine-grained access control for team environments

AI Coding Agents

AgentCommandAlias (Vibe Mode)
Claude Codeclaudecc (dangerous mode)
Codex CLIcodexcod (dangerous mode)
Antigravity CLIagyagy (model-pinned, dangerous mode)
Gemini CLI (legacy)geminigmi (retired 2026-06-18; routes to locked agy)

Vibe Mode Aliases:

# Claude Code with max memory (background tasks enabled by default)
alias cc='NODE_OPTIONS="--max-old-space-size=32768" claude --dangerously-skip-permissions'

# Codex with bypass and dangerous filesystem access
alias cod='codex --dangerously-bypass-approvals-and-sandbox'

# Antigravity CLI, model/settings/DCG locked by the ACFS launcher
alias agy='$HOME/.local/bin/agy-locked'
alias gmi='$HOME/.local/bin/agy-locked'

Installation & Updates: Claude Code should be installed and updated using its native mechanisms:

  • Install: ACFS uses the official native installer (claude.ai/install.sh), checksum-verified via checksums.yaml (installs to ~/.local/bin/claude)
  • Update: Use claude update --channel latest (built-in) or run acfs update --agents-only

This ensures proper authentication handling and avoids issues with alternative package manager builds. ACFS updates Codex with Bun global package updates and Antigravity with its native agy update path.

Cloud & Database

ToolCommandDescription
PostgreSQL 18psqlDatabase
HashiCorp VaultvaultSecrets management
WranglerwranglerCloudflare CLI
Supabase CLIsupabaseSupabase management
Vercel CLIvercelVercel deployment

Vault is installed by default (skip with --skip-vault). ACFS installs the Vault CLI so you have a real secrets tool available early; it does not automatically configure a Vault server for you.

Supabase networking note: some Supabase projects expose the direct Postgres host over IPv6-only (often on free tiers). If your VPS/network is IPv4-only, use the Supabase pooler connection string instead (or upgrade/configure networking for direct IPv4).

Dicklesworthstone Stack (10 Tools)

The complete suite of tools for professional agentic workflows:

#ToolCommandDescription
1Named Tmux ManagerntmAgent cockpitβ€”spawn, orchestrate, monitor tmux sessions
2MCP Agent MailamAgent coordination via mail-like messaging (Rust binary)
3Ultimate Bug ScannerubsBug scanning with guardrails
4Beads ViewerbvTask management TUI with graph analysis
5Coding Agent Session SearchcassUnified agent history search
6CASS Memory SystemcmProcedural memory for agents
7Coding Agent Account ManagercaamAgent auth switching
8Simultaneous Launch ButtonslbTwo-person rule for dangerous commands
9Destructive Command GuarddcgClaude Code hook blocking dangerous git/fs commands
10Repo UpdaterruMulti-repo sync + AI-driven commit automation

Bundled Utilities

Additional productivity tools installed alongside the stack:

ToolCommandDescription
Get Image from Internet LinkgiilDownload images from iCloud, Dropbox, Google Photos for visual debugging
Chat Shared Conversation to FilecsctfConvert AI share links (ChatGPT, Gemini, Claude) to Markdown/HTML

Doctor Command

acfs doctor performs comprehensive health checks on your installation:

$ acfs doctor

╔══════════════════════════════════════════════════════════════╗
β•‘                    ACFS Health Check                          β•‘
╠══════════════════════════════════════════════════════════════╣
β•‘ Identity                                                      β•‘
β•‘   βœ” Running as ubuntu user                                    β•‘
β•‘   βœ” Passwordless sudo enabled                                 β•‘
β•‘                                                               β•‘
β•‘ Workspace                                                     β•‘
β•‘   βœ” /data/projects exists                                     β•‘
β•‘                                                               β•‘
β•‘ Shell                                                         β•‘
β•‘   βœ” zsh installed                                             β•‘
β•‘   βœ” oh-my-zsh installed                                       β•‘
β•‘   βœ” powerlevel10k installed                                   β•‘
β•‘   βœ” acfs.zshrc sourced                                        β•‘
β•‘                                                               β•‘
β•‘ Core Tools                                                    β•‘
β•‘   βœ” bun 1.2.16                                                β•‘
β•‘   βœ” uv 0.5.14                                                 β•‘
β•‘   βœ” cargo 1.84.0                                              β•‘
β•‘   βœ” go 1.23.4                                                 β•‘
β•‘   βœ” ripgrep 14.1.0                                            β•‘
β•‘   βœ” ast-grep 0.30.1                                           β•‘
β•‘                                                               β•‘
β•‘ Agents                                                        β•‘
β•‘   βœ” claude 1.0.24                                             β•‘
β•‘   βœ” codex 0.1.2504252326                                      β•‘
β•‘   βœ” agy 1.0.12                                                β•‘
β•‘                                                               β•‘
β•‘ Cloud                                                         β•‘
β•‘   βœ” vault 1.18.3                                              β•‘
β•‘   βœ” wrangler 4.16.0                                           β•‘
β•‘   βœ” supabase 2.23.4                                           β•‘
β•‘   βœ” vercel 41.7.6                                             β•‘
β•‘                                                               β•‘
β•‘ Dicklesworthstone Stack                                       β•‘
β•‘   βœ” ntm 0.3.2                                                 β•‘
β•‘   βœ” slb 0.2.1                                                 β•‘
β•‘   βœ” ubs 0.1.8                                                 β•‘
β•‘   βœ” bv 0.9.4                                                  β•‘
β•‘   βœ” cass 0.4.2                                                β•‘
β•‘   βœ” cm 0.1.3                                                  β•‘
β•‘   βœ” caam 0.2.0                                                β•‘
β•‘   βœ” dcg 0.1.0                                                 β•‘
β•‘   βœ” ru 1.2.0                                                  β•‘
β•‘   ⚠ mcp_agent_mail (not running)                              β•‘
β•‘                                                               β•‘
β•‘ Utilities                                                     β•‘
β•‘   βœ” giil 3.0.0                                                β•‘
β•‘   βœ” csctf 1.0.0                                               β•‘
╠══════════════════════════════════════════════════════════════╣
β•‘ Overall: 35/36 checks passed                                  β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

Generated Doctor Checks

Doctor checks are generated from the manifest (scripts/generated/doctor_checks.sh) to keep verification logic close to acfs.manifest.yaml. The acfs doctor command automatically sources these generated checks to verify all manifest-defined tools.

How it works:

  1. The manifest generator creates doctor_checks.sh with verify commands for each module
  2. acfs doctor sources this file and runs each verification check
  3. Failed checks display a fix suggestion with the exact command to reinstall

Example output with fix suggestion:

  βœ— tools.lazygit - Lazygit terminal UI not found
    Fix: acfs install --only tools.lazygit

This architecture ensures doctor checks stay in sync with the installerβ€”if a tool is in the manifest, it will be verified.

Options

acfs doctor              # Interactive colorful output
acfs doctor --json       # Machine-readable JSON output
acfs doctor --quiet      # Exit code only (0=healthy, 1=issues)
acfs doctor --deep       # Run functional tests (auth, connections)
acfs doctor --fix        # Apply safe fixes for failed checks
acfs doctor --dry-run    # Preview fixes without applying
acfs doctor --no-cache   # Skip cache, run all checks fresh

Deep Checks (--deep)

The --deep flag runs functional tests beyond binary existence:

CategoryChecks
Agent AuthClaude config, Codex OAuth, Antigravity credentials
DatabasePostgreSQL connection, ubuntu role exists
Cloud CLIsgh auth status, wrangler whoami, Supabase/Vercel tokens
VaultVAULT_ADDR configured

Deep checks use 5-second timeouts to avoid hanging on network issues. Results are cached for 5 minutes to speed up repeated runs.

Example output:

Deep Checks
  βœ” Claude auth configured
  βœ” PostgreSQL connection working
  ⚠ Codex not authenticated (run: codex login)
  βœ” GitHub CLI authenticated

8/9 functional tests passed in 3.2s

Auto-Fix Mode (--fix)

The --fix flag automatically applies safe, deterministic fixes for common issues:

acfs doctor --fix             # Apply safe fixes
acfs doctor --fix --dry-run   # Preview fixes without applying

Safe Auto-Fixers

These fixes are applied automatically when --fix is used:

Fix IDDescriptionUndo Strategy
fix.path.orderingPrepend ACFS directories to PATH in .zshrcRestore backup
fix.config.copyCopy missing ~/.acfs config filesRemove copied file
fix.dcg.hookInstall DCG pre-tool-use hookRun dcg uninstall
fix.symlink.createCreate missing tool symlinksRemove symlink
fix.plugin.cloneClone missing zsh pluginsRemove cloned directory
fix.acfs.sourcingAdd ACFS sourcing to .zshrcRestore backup

Safety Guarantees

  • Never deletes user files β€” Only creates, modifies, or symlinks
  • Backups before modify β€” SHA256-verified backups of all modified files
  • Idempotent β€” Safe to run multiple times
  • Logged β€” All changes recorded to ~/.local/share/acfs/doctor.log
  • Reversible β€” Every fix has an undo command

Example Dry-Run Output

DRY-RUN: acfs doctor --fix

Would apply the following fixes:

  [fix.path.ordering]
    Action: Prepend PATH directories to ~/.zshrc
    File: ~/.zshrc
    Backup: Yes (SHA256 verified)

  [fix.acfs.sourcing]
    Action: Add ACFS sourcing to .zshrc
    File: ~/.zshrc
    Backup: Yes (SHA256 verified)

Fixes that require manual action:
  [shell.ohmyzsh]
    Status: FAIL
    Suggestion: curl -fsSL https://install.ohmyz.sh/ | bash

Summary: 2 auto-fixes, 0 prompted, 1 manual

Manual-Only Fixes

Some operations are never auto-fixed and instead provide suggestions:

  • Package manager operations (apt install ...)
  • Anything requiring sudo
  • File deletions
  • Complex shell configuration changes

Undoing Changes

All changes made by --fix can be undone:

acfs undo --list      # List all changes
acfs undo chg_0001    # Undo specific change
acfs undo --all       # Undo all changes from last session

The Wizard Website

The wizard guides beginners through a 13-step journey from "I have a laptop" to "AI agents are coding for me":

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  ACFS Wizard                                                   [Step 3/13]  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  STEP 3: Generate SSH Key                                              β”‚ β”‚
β”‚  β”‚  ──────────────────────────────────────────────────────────────────    β”‚ β”‚
β”‚  β”‚                                                                        β”‚ β”‚
β”‚  β”‚  Run this command in your terminal:                                    β”‚ β”‚
β”‚  β”‚                                                                        β”‚ β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚ β”‚
β”‚  β”‚  β”‚ ssh-keygen -t ed25519 -C "your-email@example.com"         [πŸ“‹] β”‚  β”‚ β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚ β”‚
β”‚  β”‚                                                                        β”‚ β”‚
β”‚  β”‚  ☐ I ran this command                                                  β”‚ β”‚
β”‚  β”‚                                                                        β”‚ β”‚
β”‚  β”‚  [← Previous]                                        [Next Step β†’]     β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                                             β”‚
β”‚  Progress: ●●●○○○○○○○○○○                                                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Wizard Steps

StepTitleWhat Happens
1Choose Your OSSelect Mac, Windows, or Linux (auto-detected)
2Install TerminalGet a proper terminal application set up
3Generate SSH KeyCreate an ed25519 key for VPS access
4Rent a VPSChoose a VPS provider and plan
5Create VPS InstanceLaunch your VPS and confirm SSH access
6SSH Into Your VPSFirst connection with troubleshooting tips
7Set Up AccountsCreate accounts for the services you'll use
8Pre-Flight CheckVerify your VPS is ready before installing
9Run InstallerThe curl | bash one-liner
10Reconnect as UbuntuPost-install reconnection
11Verify Key ConnectionReconnect using your SSH key and confirm it works
12Status CheckRun acfs doctor to verify
13Launch OnboardingStart the interactive tutorial

Key Features

  • OS Detection: Auto-detects Mac vs Windows for tailored instructions
  • Copy-to-Clipboard: One-click copy for all commands
  • Handoff Runbook: Downloadable JSON/Markdown artifact for the installer command and recovery steps
  • Progress Tracking: localStorage persistence across browser sessions
  • Confirmation Checkboxes: "I ran this command" acknowledgments
  • Troubleshooting: Expandable help for common issues

Wizard Handoff Runbook

Step 9 can download a local handoff runbook in JSON or Markdown. The runbook is meant for the user and support loop when an SSH session drops, an install is interrupted, or the user needs to remember the exact command they ran.

Schema: acfs.handoff-runbook.v1

FieldPurpose
wizardSelectionsLocal OS, install mode, source ref, and normalized target user
targetHostRedacted host kind and target-host assumptions
sshExpected SSH key paths and redacted reconnect command templates
installExact installer command generated from the shared command builder
recoveryCommandsCopy/paste-safe reconnect, retry, doctor, and support-bundle commands
supportDeterministic acfs support-bundle reference and review artifacts
privacyExplicit redaction policy for host data and exact-command inclusion

Host addresses are not written into the runbook. The installer command stays exact so a user can paste it back into the VPS session, and the artifact points to support-report.md and manifest.json for support-bundle review.

Technology Stack

Next.js 16 (App Router)
β”œβ”€β”€ React 19
β”œβ”€β”€ Tailwind CSS 4 (OKLCH colors)
β”œβ”€β”€ shadcn/ui components
β”œβ”€β”€ Radix UI primitives
└── Lucide icons

No backend required. All state is stored in:

  • URL query parameters
  • localStorage (agent-flywheel-user-os, agent-flywheel-vps-ip, agent-flywheel-wizard-completed-steps)

Wizard State Management

The wizard uses TanStack Query for state management with optimistic updates and cross-tab synchronization:

Architecture:

// Query-based state with localStorage persistence
const { data: steps } = useQuery({
  queryKey: ['wizardSteps', 'completed'],
  queryFn: getCompletedSteps,  // Reads from localStorage
  staleTime: 0,                // Always check for updates
  gcTime: Infinity,            // Never garbage collect
});

Optimistic Updates with Rollback:

const mutation = useMutation({
  mutationFn: async (stepId) => {
    const newSteps = addCompletedStep(currentSteps, stepId);
    setCompletedSteps(newSteps);  // Persist to localStorage
    return newSteps;
  },
  onMutate: (stepId) => {
    // Optimistically update cache immediately
    const previousSteps = queryClient.getQueryData(queryKey);
    queryClient.setQueryData(queryKey, addCompletedStep(baseSteps, stepId));
    return { previousSteps };  // For rollback
  },
  onError: (_err, _stepId, context) => {
    // Rollback on failure
    queryClient.setQueryData(queryKey, context.previousSteps);
  },
});

Cross-Tab Synchronization: The wizard maintains sync across browser tabs via two mechanisms:

  1. Custom DOM events for same-tab coordination between components
  2. Storage events for cross-tab updates when localStorage changes
// Same-tab: custom event dispatch
window.dispatchEvent(new CustomEvent('acfs:wizard:completed-steps-changed', {
  detail: { steps }
}));

// Cross-tab: storage event listener
window.addEventListener('storage', (event) => {
  if (event.key === COMPLETED_STEPS_KEY) {
    queryClient.setQueryData(queryKey, getCompletedSteps());
  }
});

Safe localStorage Utilities: All localStorage access is wrapped in safe utilities that handle SSR, private browsing, and quota exceeded errors:

// Safe read (returns null on any error)
export function safeGetJSON<T>(key: string): T | null;

// Safe write (returns boolean success)
export function safeSetJSON(key: string, value: unknown): boolean;

// URL preservation for state fallback
export function withCurrentSearch(path: string): string;

This architecture ensures the wizard progress survives browser refreshes, works across tabs, and degrades gracefully when localStorage is unavailable.


Configuration Files

ACFS deploys optimized configuration files to ~/.acfs/ on the target VPS.

~/.acfs/zsh/acfs.zshrc

A comprehensive zsh configuration that's sourced by ~/.zshrc:

Oh-My-Zsh Plugins (14 total):

PluginCategoryWhat It Provides
gitVCS150+ git aliases (gs, gp, gl, gco, gcm, etc.)
sudoShellDouble-tap Esc to prefix previous command with sudo
colored-man-pagesShellColorized man pages for better readability
command-not-foundShellSuggests packages when command not found
dockerContainersDocker command completion and aliases
docker-composeContainersdocker-compose completion and aliases
pythonLangPython aliases (pyfind, pyclean, pygrep)
pipLangpip completion and cache management
tmuxTerminaltmux aliases (ta, tad, ts, tl, tkss)
tmuxinatorTerminaltmuxinator project completion
systemdSystemsystemctl aliases (sc-status, sc-start, sc-stop)
rsyncToolsrsync completion and common flag aliases
zsh-autosuggestionsUXFish-like autosuggestions from history
zsh-syntax-highlightingUXReal-time command syntax highlighting

Note: zsh-autosuggestions and zsh-syntax-highlighting are custom plugins installed from GitHub. They must be listed last for optimal performance.

Path Configuration:

export PATH="$HOME/.local/bin:$PATH"
export PATH="$HOME/.cargo/bin:$PATH"
export PATH="$HOME/go/bin:$PATH"
export PATH="$HOME/.bun/bin:$PATH"

Atuin is still installed, but ACFS keeps it behind the guarded ~/.local/bin/atuin shim instead of putting ~/.atuin/bin at the front of interactive shell PATH.

Modern CLI Aliases:

alias ls='lsd --inode --long --all'
alias ll='lsd -l'
alias tree='lsd --tree'
alias cat='bat'
alias grep='rg'
alias vim='nvim'
alias lg='lazygit'

Tool Integrations:

# Zoxide (smarter cd)
eval "$(zoxide init zsh)"

# direnv (directory env vars)
eval "$(direnv hook zsh)"

# fzf (fuzzy finder)
source /usr/share/doc/fzf/examples/key-bindings.zsh

Shell Keybindings (Quality of Life):

KeybindActionNotes
Ctrl+β†’Forward wordNavigate by word
Ctrl+←Backward wordNavigate by word
Alt+β†’Forward wordAlternative binding
Alt+←Backward wordAlternative binding
Ctrl+BackspaceDelete word backwardFast deletion
Ctrl+DeleteDelete word forwardFast deletion
HomeBeginning of lineWorks in all terminals
EndEnd of lineWorks in all terminals
Ctrl+RShell history searchUses the active shell/editor binding

Atuin History Bindings: ACFS intentionally does not enable Atuin's zsh preexec/precmd integration by default. Atuin's searchable CLI remains available as atuin search, but the automatic shell hook can record every coding-agent command and grow the Atuin database fast enough to make shells laggy.

~/.acfs/tmux/tmux.conf

A tmux configuration specifically optimized for NTM and multi-agent workflows:

Key Bindings:

Prefix: Ctrl+a (not Ctrl+b - more ergonomic)
Split horizontal: |  (preserves working directory)
Split vertical: -    (preserves working directory)
Navigate panes: h/j/k/l (vim-style)
Resize panes: H/J/K/L (repeatable with -r flag)
Reload config: r
New window: c (preserves working directory)

Copy Mode (vim-style):

Enter copy mode: prefix + [
Begin selection: v
Rectangle selection: r
Copy and exit: y

Agent Workflow Optimizations:

SettingValuePurpose
history-limit50,000Extended scrollback for long agent sessions
escape-time10msFaster key response (reduced from default 500ms)
focus-eventsonEnables vim/neovim autoread in agent windows
detach-on-destroyoffNTM compatibilityβ€”don't detach when session ends
monitor-activityonTrack agent window activity
visual-activityoffSilent monitoring (no bell)

Catppuccin-Inspired Theme:

# Status bar (top position, less intrusive)
status-style: bg=#1e1e2e, fg=#cdd6f4

# Session indicator (blue accent)
status-left: #[fg=#89b4fa,bold] #S

# Active window highlight (pink accent)
window-status-current-format: #[fg=#f5c2e7,bold] #I:#W

# Pane borders
pane-border-style: fg=#313244
pane-active-border-style: fg=#89b4fa  # Blue highlight

Local Overrides: The config sources ~/.tmux.conf.local if it exists, allowing personal customizations without modifying ACFS defaults.


Library Modules

The installer is organized into modular Bash libraries in scripts/lib/:

logging.sh

Colored console output utilities:

log_step "1/8" "Installing packages..."  # Blue step indicator
log_detail "Installing zsh..."           # Gray indented detail
log_success "Complete"                    # Green checkmark
log_warn "May take a while"              # Yellow warning
log_error "Failed"                        # Red error
log_fatal "Cannot continue"              # Red error + exit 1

security.sh

HTTPS enforcement and checksum verification:

enforce_https "$url"                     # Fail if not HTTPS
verify_checksum "$url" "$sha256" "$name" # Verify before execute
fetch_and_run "$url" "$sha256" "$name"   # Verify + execute in one

os_detect.sh

OS detection and validation:

detect_os()      # Sets OS_ID, OS_VERSION, OS_CODENAME
validate_os()    # Checks for Ubuntu 25.10 (or upgrade path)
is_fresh_vps()   # Heuristic detection of fresh VPS
get_arch()       # Returns amd64/arm64
is_wsl()         # Detects WSL
is_docker()      # Detects Docker container

user.sh

User account normalization:

ensure_user()              # Creates ubuntu user if missing
enable_passwordless_sudo() # Adds NOPASSWD to sudoers
migrate_ssh_keys()         # Copies keys from root to ubuntu
normalize_user()           # Full normalization sequence

update.sh

Component update logic with version tracking and logging:

update_apt()       # apt update/upgrade with lock detection
update_bun()       # bun upgrade with version tracking
update_agents()    # Claude, Codex, Antigravity (version before/after)
update_cloud()     # Wrangler, Supabase, Vercel (Supabase uses verified release tarball)
update_rust()      # rustup update stable
update_uv()        # uv self update
update_go()        # Go toolchain update
update_shell()     # OMZ, P10K, plugins, Atuin, Zoxide
update_stack()     # Dicklesworthstone stack tools

# Features:
# - Automatic logging to ~/.acfs/logs/updates/
# - Version tracking (before/after for each tool)
# - APT lock detection and warning
# - Reboot-required detection for kernel updates
# - Dry-run mode with --dry-run flag

gum_ui.sh

Enhanced terminal UI using Charmbracelet Gum:

print_banner()           # ASCII art ACFS banner
gum_step/gum_detail      # Styled output
gum_success/warn/error   # Colored messages
gum_spin                 # Spinner for long operations
gum_confirm              # Yes/No prompt
gum_choose               # Selection menu

Falls back to basic echo if Gum is not installed.

error_tracking.sh

Sophisticated error collection and reporting:

track_error "phase" "step" "error_message"
track_warning "phase" "step" "warning_message"
get_error_report                    # Generate structured error report
get_error_count                     # Count of tracked errors
has_errors                          # Boolean check for any errors

Features:

  • Collects errors without aborting execution
  • Associates errors with phase and step context
  • Generates end-of-run summary reports
  • Distinguishes warnings from errors

state.sh

State machine management for installation progress (v3 schema):

state_init                          # Initialize state file
state_get_phase                     # Current phase
state_set_phase "phase_name"        # Set current phase
state_mark_complete "phase_name"    # Mark phase complete
state_has_completed "phase_name"    # Check if phase done
state_save                          # Persist to disk (atomic)
state_load                          # Load from disk

The state file (~/.acfs/state.json) uses atomic writes to prevent corruption.

contract.sh

Runtime contract validation for generated scripts:

acfs_require_contract "module_id"   # Assert environment is ready
acfs_check_contract                 # Non-fatal contract check

Validates that required environment variables and functions exist before execution:

  • TARGET_USER, TARGET_HOME, MODE
  • ACFS_BOOTSTRAP_DIR, ACFS_LIB_DIR
  • Logging functions: log_detail, log_success, etc.

smoke_test.sh

Post-install verification that runs automatically after installation:

run_smoke_test                      # Execute all smoke tests

Critical Checks (must pass):

  • Running as ubuntu user
  • Passwordless sudo enabled
  • Zsh is default shell
  • Core tools accessible (bun, uv, cargo)

Non-Critical Checks (warnings only):

  • Agent authentication configured
  • Cloud CLIs authenticated
  • Optional tools installed

Example output:

[Smoke Test]
  βœ… Running as ubuntu user
  βœ… Passwordless sudo enabled
  βœ… Zsh is default shell
  βœ… bun --version works
  ⚠️  Codex not authenticated (run: codex login)
  βœ… 8/9 checks passed

session.sh

Agent session export functionality for sharing and replay:

session_export "claude-code" "session_id" "/output/path"
session_list                        # List exportable sessions
session_validate "/export/file.json"

Implements the Session Export Schema for cross-agent sharing:

interface SessionExport {
  schema_version: 1;
  exported_at: string;              // ISO8601
  session_id: string;
  agent: "claude-code" | "codex" | "agy";
  model: string;
  summary: string;
  duration_minutes: number;
  stats: {
    turns: number;
    files_created: number;
    files_modified: number;
    commands_run: number;
  };
  outcomes: Array<{
    type: "file_created" | "file_modified" | "command_run";
    path?: string;
    description: string;
  }>;
  key_prompts: string[];            // Notable prompts for learning
  sanitized_transcript: Array<{
    role: "user" | "assistant";
    content: string;
    timestamp: string;
  }>;
}

tailscale.sh

Zero-config VPN setup for secure remote access:

install_tailscale                   # Install via official APT repo
verify_tailscale                    # Check installation
tailscale_status                    # Get connection status

Tailscale provides:

  • Secure mesh networking between your devices
  • SSH over Tailscale for firewall-free access
  • MagicDNS for hostname-based addressing
  • ACL-based access control

After installation, run tailscale up to authenticate and join your tailnet.

ubuntu_upgrade.sh

Multi-reboot Ubuntu version upgrade automation:

start_ubuntu_upgrade                # Begin upgrade chain
check_upgrade_status                # Current upgrade state
resume_upgrade_after_reboot         # Continue after reboot

Handles the complex multi-step Ubuntu upgrade process:

  1. Detects current version
  2. Calculates upgrade path (e.g., 24.04 β†’ 25.04 β†’ 25.10)
  3. Performs sequential do-release-upgrade operations
  4. Installs systemd service for post-reboot resume
  5. Continues ACFS installation after reaching target

MCP Agent Mail Integration

ACFS includes integration with MCP Agent Mail for multi-agent coordination:

What Agent Mail Provides

  • Identities: Each agent registers with a unique name
  • Inbox/Outbox: Message-based communication between agents
  • File Reservations: Advisory leases to prevent agents from clobbering each other's work
  • Searchable Threads: Full-text search across all messages
  • Git Persistence: All artifacts stored in git for human auditability

Core Patterns

1. Register Identity:

# In your agent, call:
mcp.ensure_project(project_key="/data/projects/my-project")
mcp.register_agent(project_key=..., program="claude-code", model="opus-4.5")

2. Reserve Files Before Editing:

mcp.file_reservation_paths(
    project_key=...,
    agent_name="BlueLake",
    paths=["src/**"],
    ttl_seconds=3600,
    exclusive=true
)

3. Communicate:

mcp.send_message(
    project_key=...,
    sender_name="BlueLake",
    to=["GreenCastle"],
    subject="Review needed",
    body_md="Please review the auth changes..."
)

Macros for Speed

When speed matters more than fine-grained control:

mcp.macro_start_session(...)      # Ensure project + register + fetch inbox
mcp.macro_prepare_thread(...)     # Align with existing thread
mcp.macro_file_reservation_cycle(...)  # Reserve + work + release
mcp.macro_contact_handshake(...)  # Request contact permissions

Destructive Command Guard (dcg)

dcg is a high-performance Claude Code hook that blocks dangerous git and filesystem commands before they execute. Built in Rust for sub-millisecond latency, it provides mechanical enforcement of safety rules that instructions alone cannot guarantee.

Why dcg Exists

On December 17, 2025, an AI agent ran git checkout -- on files containing hours of uncommitted work from a parallel coding session. The files were recovered via git fsck --lost-found, but the incident made one thing clear: instructions in AGENTS.md don't prevent execution. dcg provides mechanical enforcement.

What Gets Blocked

CategoryCommands
Git Resetgit reset --hard, git reset --merge
File Discardgit checkout -- <files>, git restore <files>
Force Pushgit push --force / -f (allows --force-with-lease)
Cleangit clean -f (allows -n dry-run)
Branch Deletegit branch -D (allows -d)
Stash Lossgit stash drop, git stash clear
Filesystemrm -rf

What Gets Allowed

Safe variants are allowlisted:

  • git checkout -b <branch> β€” Creates branch, doesn't touch files
  • git restore --staged β€” Only unstages, doesn't discard
  • git clean -n β€” Dry-run preview
  • Temp directory cleanup still requires explicit human approval when an agent would delete files

Installation

acfs update --stack-only

Claude Code Configuration

Add to ~/.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [{"type": "command", "command": "dcg"}]
      }
    ]
  }
}

Modular Pack System

dcg uses a modular pack system for extensibility. Enable additional packs in ~/.config/dcg/config.toml:

[packs]
enabled = [
    "database.postgresql",
    "containers.docker",
    "kubernetes",
]

Available packs: database.*, containers.*, kubernetes.*, cloud.*, infrastructure.*, system.*, package_managers.


Repo Updater (ru)

ru is a production-grade CLI tool for synchronizing collections of GitHub repositories and automating commit workflows across dirty repos with AI assistance.

Core Features

  • Multi-repo sync: Clone missing repos, pull updates, detect conflicts
  • Agent sweep: AI-driven commit automation across repositories with uncommitted changes
  • AI code review: Orchestrate Claude Code review sessions for open issues/PRs
  • Work-stealing queue: Parallel execution with load-balanced workers
  • NTM integration: Session management via Named Tmux Manager

Quick Start

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/repo_updater/main/install.sh?ru_cb=$(date +%s)" | bash

Initialize configuration:

# Initialize configuration
ru init --example

# Sync all repositories
ru sync

# Check status without changes
ru status

Agent Sweep Workflow

The agent-sweep command automates commits across dirty repositories:

# Preview repos to process
ru agent-sweep --dry-run

# Full automation with AI
ru agent-sweep --parallel 4

# Include release automation
ru agent-sweep --with-release

Three-Phase Workflow:

  1. Planning: Claude Code analyzes changes, generates commit message
  2. Commit: Validates plan, stages files, runs quality gates
  3. Release: (Optional) Creates version tag and GitHub release

Configuration

# ~/.config/ru/config
PROJECTS_DIR=/data/projects
LAYOUT=flat                   # flat|owner-repo|full
UPDATE_STRATEGY=ff-only       # ff-only|rebase|merge
PARALLEL=4

Repo list format (~/.config/ru/repos.d/public.txt):

owner/repo
owner/repo@develop            # Pin to branch
owner/repo as custom-name     # Custom directory name

giil downloads full-resolution images from cloud photo shares to your terminal. Essential for remote debugging workflows where you need to analyze screenshots in SSH sessions.

Supported Platforms

PlatformMethodSpeed
iCloud4-tier capture strategy5-15s
DropboxDirect curl download1-2s
Google PhotosNetwork interception5-15s
Google DriveMulti-tier with auth detection5-15s

Usage

# Basic download
giil "https://share.icloud.com/photos/02cD9okNHvVd-uuDnPCH3ZEEA"
# Output: /current/dir/icloud_20240115_143245.jpg

# Download to specific directory
giil "..." --output ~/Downloads

# Get JSON metadata
giil "..." --json

# Download all photos from album
giil "..." --all --output ~/album

Installation

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/giil/main/install.sh?v=3.0.0" | bash

Visual Debugging Workflow

  1. Screenshot UI bug on iPhone
  2. Wait for iCloud sync to Mac
  3. Share via Photos.app β†’ Copy iCloud Link
  4. Paste link into remote terminal running Claude Code
  5. giil fetches the image locally
  6. AI assistant analyzes the screenshot

Chat Shared Conversation to File (csctf)

csctf converts public AI conversation share links into clean, searchable Markdown and HTML transcripts. Perfect for archiving AI conversations, building knowledge bases, and sharing with teams.

Supported Providers

ProviderURL Pattern
ChatGPTchatgpt.com/share/*
Geminigemini.google.com/share/*
Grokgrok.com/share/*
Claudeclaude.ai/share/*

Usage

# Basic conversion
csctf https://chatgpt.com/share/69343092-91ac-800b-996c-7552461b9b70
# Creates: <slug>.md and <slug>.html

# Markdown only
csctf "..." --md-only

# Publish to GitHub Pages
csctf "..." --publish-to-gh-pages --yes

# JSON metadata output
csctf "..." --json

Installation

curl -fsSL https://raw.githubusercontent.com/Dicklesworthstone/chat_shared_conversation_to_file/main/install.sh | bash

Output Features

  • Markdown: Clean formatting with preserved code blocks and language hints
  • HTML: Zero-JavaScript static page with syntax highlighting
  • Deterministic filenames: <slug>_YYYYMMDD.md for reliable archival
  • Collision handling: Auto-increments suffix to avoid overwrites

CI/CD

ACFS uses GitHub Actions for continuous integration:

Installer Testing (installer.yml)

# Runs on every push and PR
jobs:
  shellcheck:
    - Lints all bash scripts with ShellCheck

  integration:
    - Matrix tests across Ubuntu 24.04, 25.04, 25.10
    - Runs full installation in Docker
    - Verifies all tools installed correctly
    - Runs acfs doctor to confirm health

  factory-e2e:
    - Runs the literal public curl|bash installer on QEMU/KVM or a fresh real Ubuntu host
    - Requires systemd, SSH, and a disposable factory VM/VPS semantics
    - Verifies ubuntu user creation, SSH key merge, user services, tool health, and idempotency

Docker catches shell and package regressions early. The factory E2E is the authoritative release gate for the real beginner VPS path because it exercises systemd, SSH, login/user-service behavior, and provider image defaults that containers cannot model. A Docker pass is not sufficient release proof by itself.

Local Release Doctor (scripts/release-doctor.sh)

Run the local release gate before tagging or publishing a release candidate:

bash scripts/release-doctor.sh --full --network=check
bash scripts/release-doctor.sh --json --full --network=check > release-doctor.json

For a fast local readiness check while developing:

bash scripts/release-doctor.sh --json

The release doctor composes the maintainer checks that are easy to forget:

  • branch policy and clean worktree status
  • shellcheck install.sh scripts/**/*.sh
  • manifest/generated/checksum drift via scripts/check-manifest-drift.sh --json --quiet
  • verified-installer checksum candidate review with --network=check
  • website type-check, lint, and production build when apps/web changed or --full is set

The checksum candidate check uses the canonical updater output. If the generated body differs from checksums.yaml, review the diff before release; if only the timestamp header differs, leave checksums.yaml unchanged. The default --network=skip keeps routine runs offline, and --web=auto runs website checks only when web files changed unless --full or --web=always is provided.

Stack Provenance Report (scripts/stack-provenance-report.sh)

Use the stack provenance report when reviewing Dicklesworthstone stack tool freshness before release:

bash scripts/stack-provenance-report.sh --json
bash scripts/stack-provenance-report.sh --network=check --json

Offline mode reports local manifest/checksum consistency for stack tools. Network mode also checks GitHub latest release metadata and generates a checksum candidate without writing checksums.yaml. Changed stack installer hashes fail the report, unrelated checksum diffs are called out separately, and rch release changes are flagged as mandatory checksum-refresh review items.

Agent Readiness Audit (scripts/agent-readiness-audit.sh)

Run the local agent readiness audit before launching a swarm on a freshly installed VPS:

bash scripts/agent-readiness-audit.sh
bash scripts/agent-readiness-audit.sh --json

The audit checks Claude Code, Codex CLI, Antigravity CLI, and caam without printing token values or auth file contents. It reports CLI presence, version availability, parseable auth/config files, CAAM default profile consistency, and stale CAAM defaults that point at missing profiles.

Useful options:

bash scripts/agent-readiness-audit.sh --no-version  # Skip CLI --version probes
bash scripts/agent-readiness-audit.sh --home /home/ubuntu --path "$PATH"

Treat failures as launch blockers. Warnings usually mean the CLI is installed but needs a user sign-in or CAAM default profile selection.

Website Deployment (website.yml)

# Builds and deploys the Next.js wizard
jobs:
  build:
    - Type-check TypeScript
    - Run ESLint
    - Build production bundle

  deploy:
    - Deploy to Vercel (production)

Automated Checksum + Drift Repair (checksum-monitor.yml)

ACFS automatically monitors upstream installers for changes, and also repairs generated artifact checksum drift:

# Runs every 15 minutes + on upstream changes
schedule: "*/15 * * * *"
triggers:
  - Schedule (every 15 minutes)
  - Webhook from upstream repos (repository_dispatch)
  - Pushes touching installer/checksum/generator files

How It Works:

  1. Verify Generated Artifact Drift: Runs scripts/check-manifest-drift.sh --json to detect:
    • ACFS_MANIFEST_SHA256 mismatches
    • internal script checksum drift (scripts/generated/internal_checksums.sh)
    • generated installer and web metadata drift via bun run generate:diff
    • semantic manifest contract drift across scripts/generated/doctor_checks.sh, apps/web/lib/generated, acfs/onboard/lessons, README snippets, and checksums.yaml
  2. Auto-Repair Drift: If drift is detected, runs --fix (regenerate + commit + push)
  3. Verify Current Upstream Checksums: Downloads all upstream installers, calculates SHA256
  4. Detect Upstream Changes: Compares against checksums.yaml
  5. Categorize Tools: Separates "trusted" tools (can auto-update) from others
  6. Auto-Update Upstream Checksums: Commits updated checksums.yaml when safe
  7. Alert: For non-trusted tool changes, creates GitHub issue for manual review

The monitor fails closed when verification returns fetch errors or skipped entries; it will not emit partial/placeholder checksum updates.

Trusted Tools (Auto-Update Enabled):

  • Dicklesworthstone stack tools (ntm, cass, cm, ubs, slb, dcg, caam, bv, agent-mail, ru)
  • These are maintained by the same author, so upstream changes are implicitly trusted

Non-Trusted Tools (Manual Review Required):

  • Third-party installers (bun, uv, rust, oh-my-zsh, atuin, zoxide, nvm)
  • Changes trigger a GitHub issue with diff details for human review

This ensures:

  • Security: Third-party changes are reviewed before deployment
  • Velocity: Internal tool updates are deployed automatically
  • Auditability: All changes tracked via git commits

Upstream Repo Dispatch (Fast Path):

  • ACFS-owned tool repos emit a repository_dispatch event (upstream-changed) when their install.sh changes or a release is published.
  • Requires a PAT secret named ACFS_REPO_DISPATCH_TOKEN in each tool repo (repo scope for this org/user).
  • If dispatch fails, the 15-minute scheduled monitor still catches drift (but slower).

Production Smoke Tests (production-smoke.yml)

Validates deployments on real environments:

# Runs after deployment
jobs:
  smoke:
    - Fetches install.sh from production URL
    - Verifies checksum matches repository
    - Validates shell syntax
    - Confirms no uncommitted drift

Installer Canary (Docker) (installer-canary.yml)

Runs the installer inside fresh Ubuntu containers on a daily schedule. This is a fast regression canary, not the final proof of the factory VPS path.

schedule: "30 7 * * *" # daily
jobs:
  canary:
    - Run tests/vm/test_install_ubuntu.sh (vibe mode)
    - Defaults to Ubuntu 25.10; --all covers 24.04, 25.04, and 25.10
    - Uses ACFS_CHECKSUMS_REF=main for freshest hashes

Factory Installer E2E (installer-factory-e2e.yml)

Runs the literal public installer through the authoritative factory harness. The QEMU/KVM backend uses the official Ubuntu cloud image and requires a runner with /dev/kvm; set the repository variable ACFS_FACTORY_RUNNER, the manual runner input, or client_payload.runner to a KVM-capable larger/self-hosted runner. The real-host backend runs against a disposable Ubuntu VPS over SSH and is intended for provider-specific sentinel runs.

schedule: "0 8 * * 0" # weekly QEMU/KVM factory canary when ACFS_FACTORY_RUNNER has /dev/kvm
workflow_dispatch:
  inputs:
    backend: qemu|real-host
    runner: "" # optional override; blank uses ACFS_FACTORY_RUNNER or ubuntu-latest
    ref: main
    mode: vibe
    expect_ubuntu: "25.10"
    expect_final_ubuntu: "25.10"
repository_dispatch:
  types: [acfs-factory-host-ready]
real-host secrets:
  ACFS_FACTORY_SSH_PRIVATE_KEY: private key for real-host backend
  ACFS_FACTORY_SSH_TARGET: optional fallback root@fresh-host for real-host backend

Standard GitHub-hosted runners do not provide a contractual nested-virtualization environment. If the QEMU backend runs without /dev/kvm, the workflow fails at the KVM preflight with an environment-specific error before invoking the installer.

Reusable workflow callers may use the QEMU backend without passing SSH secrets. The real-host backend still needs a private key plus either client_payload.ssh_target for dispatch runs or ACFS_FACTORY_SSH_TARGET as a fallback.

If backend=real-host is requested without those SSH credentials, the workflow fails during configuration resolution. It must never report a green canary when no disposable host was tested.

Workflow artifact directories and uploads include only the current GitHub run id and attempt. That keeps repeated scheduled/manual runs from reusing or uploading old QEMU overlay disks on KVM-capable self-hosted runners with persistent workspaces. The QEMU backend writes its generated private SSH key outside the repository checkout, so upload-artifact and future Git commits never package guest login credentials. Factory diagnostics are redacted before local upload, including installer logs and the remote diagnostic archive.

The target host must be freshly provisioned. By default the harness fails if the ubuntu user already exists before install, because the real beginner path must prove ACFS creates that user automatically. The harness also requires acfs doctor --json to report zero failures and zero warnings, then separately verifies Agent Mail liveness/systemd service state and the ACFS nightly user timer.

For the slower upgrade/resume gate, provision a fresh Ubuntu 24.04 host and run the same workflow or script with --expect-ubuntu 24.04 --expect-final-ubuntu 25.10 --allow-install-reboot.

For provider-specific real VPS sentinels, use an external provisioning job to create a disposable server, wait for root SSH, dispatch acfs-factory-host-ready, and destroy the server after artifact collection. The dispatch payload should include the fresh host address so the repository does not store a stale long-lived VPS as ACFS_FACTORY_SSH_TARGET:

{
  "event_type": "acfs-factory-host-ready",
  "client_payload": {
    "backend": "real-host",
    "ssh_target": "root@203.0.113.10",
    "ref": "main",
    "mode": "vibe",
    "expect_ubuntu": "25.10",
    "expect_final_ubuntu": "25.10"
  }
}

Local QEMU Factory E2E (test_factory_install_qemu.sh)

Runs the same factory-host harness inside a real local VM instead of a Docker container. The wrapper downloads and verifies the official Ubuntu cloud image, boots it with QEMU/KVM and cloud-init, exposes root SSH on a local forwarded port, then delegates to tests/vm/test_factory_install_ubuntu.sh. Generated private SSH keys are kept outside the repository checkout; use --key-dir with a path under /tmp or another non-repo directory when you need a specific local key location for debugging.

sudo apt-get install -y qemu-system-x86 qemu-utils cloud-image-utils openssh-client
./tests/vm/test_factory_install_qemu.sh

Use this when Docker passes but you need local proof for systemd, sshd, cloud-init, kernel, filesystem, and login behavior before spending time on a disposable provider VPS.

Playwright E2E Tests (playwright.yml)

Full browser testing of the wizard website:

# Runs on PR to main
browsers:
  - Chromium
  - Firefox
  - WebKit
  - Mobile Chrome
  - Mobile Safari

tests:
  - Wizard flow completion
  - Step navigation
  - Copy button functionality
  - Responsive design

VPS Providers

ACFS works on any Ubuntu VPS with SSH access and either root password login or a provider console that lets you become root for the first install. Here are recommended providers optimized for multi-agent workloads.

Why 48-64GB RAM? Each AI coding agent uses ~2GB RAM. To run 10-20+ agents simultaneously, you need 48GB+ RAM. Don't bottleneck a $400+/month AI investment to save $20 on hosting.

After installation, run acfs capacity --profile 25-agents --recommend-ntm on the VPS for a local RAM/CPU/disk sizing report with recommended agent counts and copyable NTM launch profiles.

Contabo (Best Value β€” Top Pick)

PlanRAMvCPUStoragePriceNotes
Cloud VPS 5064GB16400GB NVMe~$56/mo (US)Recommended β€” Best for serious multi-agent work
Cloud VPS 4048GB12300GB NVMe~$36/mo (US)Budget option, still comfortable
  • Best specs-to-price ratio on the market
  • Month-to-month pricing, no commitment required
  • US datacenter pricing includes ~$10/month premium

OVH (Great Alternative)

PlanRAMvCoreStoragePriceNotes
VPS-564GB16320GB NVMe~$40/moRecommended β€” Great EU and US datacenters
VPS-448GB12240GB NVMe~$26/moBudget option
  • Anti-DDoS included
  • Month-to-month, 5-15% discount for longer commitments
  • Typically faster activation than Contabo

Requirements

RequirementMinimumRecommended
OSUbuntu 22.04+ (auto-upgraded)Ubuntu 25.10
RAM32GB (tight)48-64GB
Storage250GB NVMe SSD300GB+ NVMe SSD
CPU12 vCPU16 vCPU
Price~$26/mo~$40-56/mo

Other Providers

Any provider with an Ubuntu VPS, SSH access, and a first-login root password or root console works. The wizard at agent-flywheel.com has step-by-step guides.

Provider Setup Guides

ACFS includes detailed step-by-step guides for each supported provider in scripts/providers/:

ProviderGuideKey Sections
Contabocontabo.mdAccount creation, plan selection, data center choice, root password setup
OVHovh.mdControl panel navigation, password authentication, instance configuration, networking
Hetznerhetzner.mdProject setup, firewall rules, console access

Each guide includes:

  • Screenshots for every step (in scripts/providers/screenshots/)
  • Pricing breakdowns with recommendations
  • Region selection guidance (latency, privacy)
  • Password-first login guidance and post-install SSH key recovery specific to that provider
  • Troubleshooting for common provisioning issues

Provider Comparison:

AspectContaboOVHHetzner
Best ForMaximum valueEU data residencyGerman engineering
Provisioning1-3 hours5-30 minutes2-10 minutes
SupportEmail onlyPhone + chat24/7 ticket system
Data CentersEU, US, AsiaGlobalEU only
PaymentMonthlyHourly or monthlyHourly or monthly

Recommendation Flow:

  1. Budget: Contabo (best specs per dollar)
  2. Speed: Hetzner (instant provisioning)
  3. Support: OVH (phone support available)
  4. Privacy: Any EU provider (GDPR compliance)

Project Structure

agentic_coding_flywheel_setup/
β”œβ”€β”€ README.md                     # This file
β”œβ”€β”€ AGENTS.md                     # Development guidelines
β”œβ”€β”€ VERSION                       # Current version (0.7.0)
β”œβ”€β”€ install.sh                    # Main installer entry point
β”œβ”€β”€ acfs.manifest.yaml            # Canonical tool manifest (510 lines)
β”œβ”€β”€ checksums.yaml                # SHA256 hashes for upstream scripts
β”œβ”€β”€ package.json                  # Root monorepo config
β”‚
β”œβ”€β”€ apps/
β”‚   └── web/                      # Next.js 16 wizard website
β”‚       β”œβ”€β”€ app/                  # App Router pages
β”‚       β”‚   β”œβ”€β”€ layout.tsx        # Root layout
β”‚       β”‚   β”œβ”€β”€ page.tsx          # Landing page
β”‚       β”‚   └── wizard/           # Wizard step pages
β”‚       β”œβ”€β”€ components/           # UI components
β”‚       └── lib/                  # Utilities
β”‚
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ manifest/                 # Manifest parser + generator
β”‚   β”‚   └── src/
β”‚   β”‚       β”œβ”€β”€ parser.ts         # YAML parsing
β”‚   β”‚       β”œβ”€β”€ schema.ts         # Zod validation schemas
β”‚   β”‚       β”œβ”€β”€ types.ts          # TypeScript types
β”‚   β”‚       β”œβ”€β”€ utils.ts          # Helper functions
β”‚   β”‚       └── generate.ts       # Script generator
β”‚   └── onboard/                  # Onboard TUI source
β”‚
β”œβ”€β”€ acfs/                         # Files deployed to ~/.acfs/
β”‚   β”œβ”€β”€ zsh/
β”‚   β”‚   └── acfs.zshrc            # Shell configuration
β”‚   β”œβ”€β”€ tmux/
β”‚   β”‚   └── tmux.conf             # Tmux configuration
β”‚   └── onboard/
β”‚       β”œβ”€β”€ onboard.sh            # Onboarding TUI script
β”‚       └── lessons/              # Tutorial markdown (11 files)
β”‚
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ lib/                      # Installer bash libraries
β”‚   β”‚   β”œβ”€β”€ logging.sh            # Console output
β”‚   β”‚   β”œβ”€β”€ security.sh           # HTTPS + checksum verification
β”‚   β”‚   β”œβ”€β”€ os_detect.sh          # OS detection
β”‚   β”‚   β”œβ”€β”€ user.sh               # User management
β”‚   β”‚   β”œβ”€β”€ zsh.sh                # Shell setup
β”‚   β”‚   β”œβ”€β”€ update.sh             # Update command logic
β”‚   β”‚   β”œβ”€β”€ gum_ui.sh             # Enhanced UI
β”‚   β”‚   β”œβ”€β”€ cli_tools.sh          # Tool installation
β”‚   β”‚   └── doctor.sh             # Health checks
β”‚   β”œβ”€β”€ generated/                # Auto-generated from manifest
β”‚   β”‚   β”œβ”€β”€ install_base.sh       # Base packages
β”‚   β”‚   β”œβ”€β”€ install_shell.sh      # Shell tools
β”‚   β”‚   β”œβ”€β”€ install_cli.sh        # CLI tools
β”‚   β”‚   β”œβ”€β”€ install_lang.sh       # Language runtimes
β”‚   β”‚   β”œβ”€β”€ install_agents.sh     # AI coding agents
β”‚   β”‚   β”œβ”€β”€ install_cloud.sh      # Cloud CLIs
β”‚   β”‚   β”œβ”€β”€ install_stack.sh      # Dicklesworthstone stack
β”‚   β”‚   β”œβ”€β”€ install_all.sh        # Top-level installer
β”‚   β”‚   └── doctor_checks.sh      # Verification checks
β”‚   β”œβ”€β”€ providers/                # VPS provider guides
β”‚   β”‚   β”œβ”€β”€ ovh.md
β”‚   β”‚   β”œβ”€β”€ contabo.md
β”‚   β”‚   └── hetzner.md
β”‚   └── sync/
β”‚       └── sync_ntm_palette.sh   # Sync NTM command palette
β”‚
β”œβ”€β”€ .github/
β”‚   └── workflows/
β”‚       β”œβ”€β”€ installer.yml         # ShellCheck + Ubuntu matrix tests
β”‚       └── website.yml           # Next.js build + deploy
β”‚
└── tests/
    └── vm/
        β”œβ”€β”€ test_install_ubuntu.sh # Docker integration test
        β”œβ”€β”€ test_factory_install_ubuntu.sh # Real VM/VPS factory install test
        └── test_factory_install_qemu.sh # Local QEMU/KVM factory install test

Development

Website Development

cd apps/web
bun install           # Install dependencies
bun run dev           # Dev server at http://localhost:3000
bun run build         # Production build
bun run lint          # Lint check
bun run type-check    # TypeScript check

Manifest Development

cd packages/manifest
bun install           # Install dependencies
bun run generate      # Generate installer scripts
bun run generate:dry  # Preview without writing files

Installer Testing

# Local lint
shellcheck install.sh scripts/lib/*.sh

# Full installer integration test (Docker, same as CI)
./tests/vm/test_install_ubuntu.sh

# Authoritative factory-host E2E (requires a disposable fresh Ubuntu 25.10 VM/VPS)
./tests/vm/test_factory_install_ubuntu.sh --ssh-target root@203.0.113.10

# Local authoritative VM E2E (QEMU/KVM + official Ubuntu cloud image)
./tests/vm/test_factory_install_qemu.sh

# Slow real-host upgrade/resume gate from Ubuntu 24.04 to 25.10
./tests/vm/test_factory_install_ubuntu.sh --ssh-target root@203.0.113.10 --expect-ubuntu 24.04 --expect-final-ubuntu 25.10 --allow-install-reboot

Security Verification

# Print all upstream URLs
./scripts/lib/security.sh --print

# Verify all checksums
./scripts/lib/security.sh --verify

# Update checksums after reviewing upstream changes
./scripts/lib/security.sh --update-checksums > checksums.yaml

Manifest Validation

The manifest parser includes comprehensive validation beyond basic schema checking:

Validation Error Codes:

CodeDescription
MISSING_DEPENDENCYModule references non-existent dependency
DEPENDENCY_CYCLECircular dependency detected (A→B→C→A)
PHASE_VIOLATIONModule runs before its dependencies
FUNCTION_NAME_COLLISIONTwo modules generate same bash function
RESERVED_NAME_COLLISIONModule uses reserved identifier
INVALID_VERIFIED_INSTALLER_RUNNERRunner not in allowlist (bash/sh only)

Running Validation:

cd packages/manifest
bun run validate              # Full validation
bun run validate --verbose    # Show all checks

Cycle Detection Algorithm:

Tarjan's strongly connected components (SCC):
1. DFS with discovery/low-link tracking
2. Identify SCCs with size > 1 as cycles
3. Report cycle path for human debugging

Test Harness

ACFS includes a comprehensive test harness (tests/vm/lib/test_harness.sh) for integration testing:

# Source the harness
source tests/vm/lib/test_harness.sh

# Initialize test suite
harness_init "ACFS Installation Tests"

# Create test sections
harness_section "Phase 1: Base Packages"

# Run commands with automatic logging
harness_run "Installing curl" apt install -y curl

# Assert results
harness_pass "curl installed successfully"
harness_fail "curl installation failed"
harness_skip "Skipping optional test"

# Generate summary
harness_summary  # Outputs: 15 passed, 0 failed, 2 skipped

Test Files:

TestPurpose
test_install_ubuntu.shFull Docker-based installation
test_factory_install_ubuntu.shReal systemd VM/VPS factory install from public curl|bash
test_factory_install_qemu.shLocal QEMU/KVM factory install using Ubuntu cloud images
test_acfs_update.shUpdate mechanism validation
bootstrap_offline_checks.shOffline system readiness
resume_checks.shState resume validation
selection_checks.shModule selection unit tests
selection_e2e.shEnd-to-end selection flow

Running Tests:

# Full Docker integration test
./tests/vm/test_install_ubuntu.sh

# Full Docker integration matrix
./tests/vm/test_install_ubuntu.sh --all

# Real factory-host integration test
./tests/vm/test_factory_install_ubuntu.sh --ssh-target root@203.0.113.10

# Local QEMU/KVM factory-host integration test
./tests/vm/test_factory_install_qemu.sh

# Real upgrade/resume integration test
./tests/vm/test_factory_install_ubuntu.sh --ssh-target root@203.0.113.10 --expect-ubuntu 24.04 --expect-final-ubuntu 25.10 --allow-install-reboot

# Selection logic tests
./tests/vm/selection_checks.sh

# Web E2E tests
./tests/web/run_e2e.sh

Sync Scripts

Sync scripts keep ACFS documentation aligned with upstream projects:

# Sync NTM command palette from upstream
./scripts/sync/sync_ntm_palette.sh

# Check if update available (without downloading)
./scripts/sync/sync_ntm_palette.sh --check

Current Sync Sources:

ScriptSourceDestination
sync_ntm_palette.shNTM repo command_palette.mdacfs/onboard/docs/ntm/

All sync scripts use the security library for HTTPS enforcement and content hashing.

Website Design System

The website uses a comprehensive design system (apps/web/lib/design-tokens.ts):

Color Tokens (OKLCH Color Space):

// Perceptually uniform colors
colors: {
  cyan:    "oklch(0.75 0.18 195)",   // Primary accent
  pink:    "oklch(0.7 0.2 330)",     // Secondary accent
  purple:  "oklch(0.65 0.18 290)",   // Tertiary
  success: "oklch(0.72 0.19 145)",   // Green
  warning: "oklch(0.78 0.16 75)",    // Yellow
  error:   "oklch(0.65 0.22 25)",    // Red
}

Shadow Tokens:

shadows: {
  cardHover: "0 20px 40px -12px oklch(0.75 0.18 195 / 0.15)",
  cardLifted: "0 25px 50px -12px oklch(0.75 0.18 195 / 0.2)",
  primaryGlow: "0 0 40px -8px oklch(0.75 0.18 195 / 0.3)",
}

Animation Presets:

animations: {
  hover: { scale: 1.02, transition: { duration: 0.2 } },
  tap: { scale: 0.98 },
  fadeIn: { opacity: [0, 1], transition: { duration: 0.3 } },
}

Accessibility:

  • Reduced motion support via useReducedMotion hook
  • Semantic HTML structure
  • ARIA labels on interactive elements
  • Keyboard navigation support

Requirements

  • Runtime: Bun (not npm/yarn/pnpm)
  • Node: Latest
  • Shell: Bash 5+

FAQ

Why "Vibe Mode"?

Vibe mode is designed for throwaway VPS environments where velocity matters more than safety:

  • Passwordless sudo eliminates friction
  • Agent dangerous flags skip confirmation dialogs
  • Pre-configured aliases for maximum speed

Never use vibe mode on production or shared systems.

Can I use this on my local machine?

ACFS is designed for fresh Ubuntu VPS instances. While you could run it locally:

  • It may conflict with existing configurations
  • It assumes root/sudo access
  • It's not designed for macOS or Windows

For local development, use the individual tools directly.

What if the installer fails?

The installer is checkpointed. Simply re-run it:

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/main/install.sh?$(date +%s)" | bash -s -- --yes --mode vibe

It will skip already-completed phases and resume where it left off.

How do I update tools?

Use the built-in update command:

acfs update                  # Update all standard components
acfs update --stack          # Include Dicklesworthstone stack
acfs update --agents-only    # Just update AI agents

How do I uninstall?

There's no uninstall script. To reset:

  1. Delete the VPS instance
  2. Create a new one
  3. Run the installer fresh

This is intentionalβ€”ACFS is designed for ephemeral VPS environments.

Can I customize which tools are installed?

Currently, ACFS installs the full suite. Future versions will support:

  • Manifest-based tool selection
  • Interactive mode for choosing components
  • Modular installation scripts

Why ACFS Exists

The Problem: The Agentic Coding Barrier

The rise of AI coding agents (Claude Code, Codex CLI, Antigravity CLI) has created a new paradigm in software development. These agents can write code, debug issues, and even architect solutionsβ€”but only if they have the right environment.

The barrier isn't the agents themselves. It's the hours of setup required to create an environment where agents can actually be productive:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  TIME INVESTMENT WITHOUT ACFS                                               β”‚
β”‚                                                                              β”‚
β”‚  VPS Setup ..................... 30-60 min                                   β”‚
β”‚  Shell Configuration ........... 20-30 min                                   β”‚
β”‚  Language Runtimes ............. 30-45 min                                   β”‚
β”‚  Dev Tools ..................... 20-30 min                                   β”‚
β”‚  Agent Installation ............ 15-30 min                                   β”‚
β”‚  Agent Configuration ........... 20-40 min                                   β”‚
β”‚  Coordination Tools ............ 30-60 min                                   β”‚
β”‚  Troubleshooting ............... 30-120 min                                  β”‚
β”‚  ─────────────────────────────────────────                                   β”‚
β”‚  TOTAL: 3-7 hours (and that's if everything works)                          β”‚
β”‚                                                                              β”‚
β”‚  TIME INVESTMENT WITH ACFS                                                   β”‚
β”‚                                                                              β”‚
β”‚  Run one command ............... 25-30 min                                   β”‚
β”‚  ─────────────────────────────────────────                                   β”‚
β”‚  TOTAL: 30 minutes                                                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

ACFS eliminates this barrier entirely. One command, 30 minutes, fully configured.

The Deeper Problem: Beginners Can't Start

For experienced developers, the setup is tedious but doable. For beginnersβ€”the people who would benefit most from AI coding assistanceβ€”it's an insurmountable wall:

  • What's SSH? How do I generate keys?
  • What's a VPS? How do I rent one?
  • What's a terminal? Which one should I use?
  • How do I connect to a remote server?
  • What are all these tools and why do I need them?

The wizard website at agent-flywheel.com solves this by providing:

  1. Absolute beginner guidance β€” Explains every concept in plain English
  2. OS-specific instructions β€” Detects Mac vs Windows, shows the right commands
  3. Visual confirmations β€” Checkboxes for each step, copy buttons for commands
  4. Troubleshooting help β€” Expandable sections for common problems
  5. Progress persistence β€” Resume where you left off across browser sessions

The 10x Multiplier Effect

ACFS isn't just a collection of toolsβ€”it's a carefully curated system where each component amplifies the others. The value isn't additive; it's multiplicative.

Tool Synergy Model

                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                              β”‚   PRODUCTIVITY  β”‚
                              β”‚   MULTIPLIER    β”‚
                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                       β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚                             β”‚                             β”‚
         β–Ό                             β–Ό                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  ENVIRONMENT    β”‚         β”‚    AGENTS       β”‚         β”‚  COORDINATION   β”‚
β”‚  LAYER          β”‚         β”‚    LAYER        β”‚         β”‚  LAYER          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€         β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€         β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β€’ zsh + p10k    │────────▢│ β€’ Claude Code   │────────▢│ β€’ Agent Mail    β”‚
β”‚ β€’ tmux          β”‚         β”‚ β€’ Codex CLI     β”‚         β”‚ β€’ NTM           β”‚
β”‚ β€’ Modern CLI    β”‚         β”‚ β€’ Antigravity   β”‚         β”‚ β€’ SLB + DCG     β”‚
β”‚ β€’ Language VMs  β”‚         β”‚                 β”‚         β”‚ β€’ Beads Viewer  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                             β”‚                             β”‚
         β”‚    Each layer enables       β”‚    Agents become more      β”‚
         β”‚    the next layer           β”‚    powerful together       β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Why These Specific Tools?

Every tool in ACFS earns its place through concrete productivity gains:

ToolIndividual ValueSynergy Value
tmuxPersistent sessionsAgents can work while you're disconnected
NTMOrganized sessionsOne command spawns 10 agents in named windows
Agent MailMessage passingAgents coordinate without conflicts
SLBTwo-person ruleDangerous operations require confirmation
DCGCommand guardrailsBlocks destructive commands before execution
Beads ViewerTask trackingAgents can see project state, avoid rework
atuinShell historySearch commands across sessions, share patterns
zoxideSmart cdz proj beats cd ~/projects/my-long-name
ripgrepFast searchAgents find code 100x faster than grep
fzfFuzzy findingInteractive selection instead of typing paths

The Compounding Effect

A single agent with basic tooling is useful. Three agents with:

  • A shared project structure
  • Coordination via Agent Mail
  • Orchestration via NTM
  • Safety guardrails via SLB
  • DCG guard hook (blocks destructive commands before execution)
  • Task visibility via Beads

...can accomplish in one day what would take a solo developer a week.

Tip: run acfs services-setup to configure logins, and enable DCG for destructive-command protection.

This is the flywheel effect in action. Better tools β†’ more capable agents β†’ more code shipped β†’ better understanding of what tools are needed β†’ better tools.


Design Algorithms & Decisions

ACFS implements several algorithmic patterns that ensure reliability and maintainability.

Idempotency Algorithm

Every installation function follows the check-before-install pattern:

install_tool() {
    if command_exists "tool"; then
        log_success "tool already installed"
        return 0
    fi

    # ... installation logic ...

    if command_exists "tool"; then
        log_success "tool installed successfully"
        return 0
    else
        log_error "tool installation failed"
        return 1
    fi
}

This guarantees:

  1. Safe re-runs β€” Running the installer twice doesn't break anything
  2. Resume capability β€” Failures don't require starting over
  3. Declarative intent β€” The end state is defined, not the transition

Checksum Verification Algorithm

The security system uses content-addressable verification:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  VERIFICATION FLOW                                                       β”‚
β”‚                                                                          β”‚
β”‚  1. Download script to memory (not disk)                                 β”‚
β”‚  2. Calculate SHA256 of downloaded content                               β”‚
β”‚  3. Compare against stored hash in checksums.yaml                        β”‚
β”‚  4. If match β†’ execute                                                   β”‚
β”‚  5. If mismatch β†’ refuse execution, report discrepancy                   β”‚
β”‚                                                                          β”‚
β”‚  Key insight: We verify CONTENT, not just transport                      β”‚
β”‚  (HTTPS only protects the channel, not the content at source)            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Manifest-Driven Generation

The generator uses a template expansion pattern:

  1. Parse β€” Read YAML manifest, validate with Zod schemas
  2. Transform β€” Convert manifest entries to installation functions
  3. Group β€” Organize by category (base, shell, cli, lang, agents, etc.)
  4. Generate β€” Emit Bash scripts with consistent structure
  5. Verify β€” Generate doctor checks from verification commands

This ensures the manifest is the single source of truthβ€”no drift between documentation, installer, and verification.

Code Generator Architecture

The manifest generator (packages/manifest/src/generate.ts) is a sophisticated TypeScript program that transforms YAML into bash:

Input Processing:

// 1. Parse YAML with validation
const manifest = parseManifestFile(MANIFEST_PATH);  // Zod-validated

// 2. Load checksums for verified installers
const checksums = parseYaml(readFileSync(CHECKSUMS_PATH));

// 3. Topological sort for dependency order
const sorted = sortModulesByInstallOrder(manifest.modules);

Security-First Code Generation:

// Shell-safe quoting (prevents command injection)
function shellQuote(s: string): string {
  return `'${s.replace(/'/g, "'\\''")}'`;
}

// Allowlisted runners only (belt-and-suspenders)
const ALLOWED_RUNNERS = ['bash', 'sh'] as const;

// Verified installer pipe construction
function buildVerifiedInstallerPipe(module: Module, checksums: Checksums): string {
  // Generates: curl -fsSL "$URL" | verify_checksum "$SHA256" | bash
}

Output Structure:

scripts/generated/
β”œβ”€β”€ install_base.sh        # Base system packages (apt)
β”œβ”€β”€ install_users.sh       # User normalization (ubuntu user)
β”œβ”€β”€ install_filesystem.sh  # Directory structure (/data/projects)
β”œβ”€β”€ install_shell.sh       # zsh + oh-my-zsh + p10k
β”œβ”€β”€ install_cli.sh         # ripgrep, tmux, fzf, lazygit, etc.
β”œβ”€β”€ install_network.sh     # Tailscale
β”œβ”€β”€ install_lang.sh        # bun, uv, rust, go
β”œβ”€β”€ install_tools.sh       # ast-grep, atuin, zoxide
β”œβ”€β”€ install_agents.sh      # claude, codex, agy
β”œβ”€β”€ install_db.sh          # PostgreSQL 18, Vault
β”œβ”€β”€ install_cloud.sh       # wrangler, supabase, vercel
β”œβ”€β”€ install_stack.sh       # Dicklesworthstone 10-tool stack + utilities
β”œβ”€β”€ install_acfs.sh        # ACFS config deployment
β”œβ”€β”€ install_all.sh         # Orchestration helper
β”œβ”€β”€ doctor_checks.sh       # Health verification
└── manifest_index.sh      # Module metadata arrays

Generated Script Structure:

#!/usr/bin/env bash
# AUTO-GENERATED FROM acfs.manifest.yaml - DO NOT EDIT

install_module_id() {
    acfs_require_contract "module.id"  # Validate environment

    if run_installed_check "module.id"; then
        log_step "module.id already installed"
        return 0
    fi

    set_phase "Installing module..."
    run_as_target_shell <<'HEREDOC'
        # Installation commands from manifest
    HEREDOC

    verify_module "module.id"  # Post-install checks
}

Regeneration:

cd packages/manifest
bun run generate           # Full regeneration
bun run generate:dry       # Preview without writing

Generated Manifest Index

The generator produces manifest_index.sh, a comprehensive bash metadata file that provides programmatic access to manifest data at runtime:

Associative Arrays:

# Module metadata lookup
declare -gA ACFS_MODULE_DESC
ACFS_MODULE_DESC["lang.bun"]="Bun JavaScript/TypeScript runtime"
ACFS_MODULE_DESC["agents.claude"]="Claude Code CLI agent"

# Phase mapping (determines install order)
declare -gA ACFS_MODULE_PHASE
ACFS_MODULE_PHASE["base.system"]="1"
ACFS_MODULE_PHASE["lang.bun"]="6"
ACFS_MODULE_PHASE["agents.claude"]="7"

# Dependency relationships (comma-separated)
declare -gA ACFS_MODULE_DEPS
ACFS_MODULE_DEPS["agents.codex"]="lang.bun"
ACFS_MODULE_DEPS["stack.mcp_agent_mail"]="lang.bun,lang.uv"

# Generated function name mapping
declare -gA ACFS_MODULE_FUNC
ACFS_MODULE_FUNC["lang.bun"]="install_lang_bun"

# Category grouping
declare -gA ACFS_MODULE_CATEGORY
ACFS_MODULE_CATEGORY["lang.bun"]="lang"

# Default inclusion in install
declare -gA ACFS_MODULE_DEFAULT
ACFS_MODULE_DEFAULT["lang.bun"]="1"
ACFS_MODULE_DEFAULT["db.postgres18"]="1"

Runtime Access Pattern:

# Iterate modules in deterministic install order
for module in "${ACFS_MODULES_IN_ORDER[@]}"; do
  [[ "${ACFS_MODULE_CATEGORY[$module]}" == "agents" ]] || continue
  printf '%s\n' "$module"
done

# Check if module is default-installed
[[ "${ACFS_MODULE_DEFAULT[tools.vault]:-1}" == "1" ]]

# Get installation phase
printf '%s\n' "${ACFS_MODULE_PHASE[stack.ntm]}"  # 9

Use Cases:

  • acfs doctor queries module metadata for health checks
  • install.sh --list-modules displays available modules
  • --skip <module> validates module existence before skipping
  • --only-phase <n|name> uses phase mapping for selective installs

The manifest index bridges the TypeScript generator with bash runtime, enabling sophisticated module selection logic while keeping the bash scripts simple.

Progressive Disclosure in the Wizard

The wizard website implements progressive disclosure for complexity management:

Level 1: Core instructions (visible by default)
β”œβ”€β”€ Copy this command
β”œβ”€β”€ Paste in terminal
└── Press Enter

Level 2: Troubleshooting (expandable)
β”œβ”€β”€ "Permission denied" β†’ fix instructions
β”œβ”€β”€ "Command not found" β†’ prerequisites
└── "Connection refused" β†’ diagnostics

Level 3: Deep explanations (collapsible "Beginner Guide")
β”œβ”€β”€ What is SSH?
β”œβ”€β”€ What is a VPS?
β”œβ”€β”€ Why these specific steps?
└── What happens under the hood?

This allows beginners to get deep context when needed, while experts can skip straight to the commands.


Multi-Agent Orchestration Model

ACFS is designed for multi-agent workflows where several AI coding agents work on the same project simultaneously.

The Coordination Problem

Without coordination, multiple agents cause chaos:

  • File conflicts β€” Two agents edit the same file
  • Duplicated work β€” Agents solve the same problem independently
  • Communication gaps β€” No visibility into what others are doing
  • Safety risks β€” Dangerous operations without oversight

The ACFS Solution Stack

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         AGENT COORDINATION LAYER                           β”‚
β”‚                                                                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”‚
β”‚  β”‚ Agent Mail  β”‚  β”‚    NTM      β”‚  β”‚  SLB + DCG  β”‚  β”‚   Beads     β”‚       β”‚
β”‚  β”‚ (Messaging) β”‚  β”‚ (Sessions)  β”‚  β”‚ (Safety)    β”‚  β”‚ (Tasks)     β”‚       β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜       β”‚
β”‚         β”‚                β”‚                β”‚                β”‚               β”‚
β”‚         β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β”‚
β”‚         β”‚   β”‚                                                              β”‚
β”‚         β–Ό   β–Ό                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚                      FILE RESERVATION SYSTEM                          β”‚ β”‚
β”‚  β”‚                                                                        β”‚ β”‚
β”‚  β”‚  Agent A reserves: src/auth/**                                         β”‚ β”‚
β”‚  β”‚  Agent B reserves: src/api/**                                          β”‚ β”‚
β”‚  β”‚  Agent C reserves: tests/**                                            β”‚ β”‚
β”‚  β”‚                                                                        β”‚ β”‚
β”‚  β”‚  β†’ No conflicts, parallel progress                                     β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Agent Communication Patterns

1. Direct Messaging (Agent Mail)

Agent A β†’ Agent B: "I finished the auth module, ready for API integration"
Agent B β†’ Agent A: "ACK, starting API integration with auth dependency"

2. Broadcast Updates (Thread Summaries)

Thread: "Sprint 23 Tasks"
β”œβ”€β”€ Agent A: "Claimed user-registration feature"
β”œβ”€β”€ Agent B: "Claimed api-endpoints feature"
β”œβ”€β”€ Agent C: "Claimed test-coverage task"
└── All agents see project state

3. File Reservations (Conflict Prevention)

Agent A: reserve_paths(["src/auth/*"], exclusive=true, ttl=3600)
Agent B: reserve_paths(["src/auth/*"]) β†’ CONFLICT: held by Agent A
Agent B: reserve_paths(["src/api/*"]) β†’ GRANTED

The NTM Orchestration Pattern

Named Tmux Manager (NTM) enables the one-command swarm spawn:

# Spawn 10 agents, each in a named tmux window
ntm spawn \
  --count 10 \
  --prefix "agent-" \
  --command "claude --dangerously-skip-permissions"

Result:

tmux session: acfs-swarm
β”œβ”€β”€ agent-1: Claude working on auth
β”œβ”€β”€ agent-2: Claude working on api
β”œβ”€β”€ agent-3: Claude working on tests
β”œβ”€β”€ agent-4: Codex reviewing PRs
β”œβ”€β”€ agent-5: Antigravity writing docs
└── ...

Dry-Run Swarm Simulation

Before launching any real swarm, ask ACFS for a queue-aware plan:

acfs swarm plan --agents 25 --profile balanced --workload standard

The planner reads the local swarm status and capacity model, incorporates RCH queue pressure, active tmux/NTM sessions, Beads in-progress counts, and host resource headroom, then prints a pass/warn/fail recommendation. It is advisory only: it does not launch agents, mutate Beads, send Agent Mail, force-release reservations, or run build commands. JSON output is available with --json, and fixture replay is available with --status-file.

For multi-host planning, keep a local redacted inventory at ~/.acfs/swarm/hosts.inventory.json:

acfs swarm inventory report
acfs swarm inventory validate --json
acfs swarm inventory export --format json --output inventory.redacted.json
acfs swarm inventory import --input inventory.redacted.json

The inventory commands are local and advisory. They read or write JSON files, preserve unknown fields for future versions, reject sensitive field names such as hostnames, IPs, keys, tokens, passwords, and home paths, and never SSH, launch NTM, run RU, send Agent Mail, mutate Beads, or change RCH config.

For each agent you plan to launch, generate a bounded startup packet from the selected Bead plus current repo instructions and bounded CM/CASS context:

acfs swarm packet --bead bd-1234 --agent-name BlueLake --role implementation
acfs swarm packet --json --bead bd-1234 --agent-name BlueLake

The packet is designed for NTM prompt injection. It prioritizes live AGENTS.md, README.md, Beads, and Agent Mail state over memory-derived hints, includes drift checks, and preserves exact bv --robot-*, br, Agent Mail MCP, rch exec --, and UBS workflow guidance. It is read-only: it does not claim work, reserve files, send messages, start agents, run builds, or edit generated files.

Before launching a large real swarm, ACFS can run an offline simulation of the control plane:

acfs swarm simulate

The default simulation runs 10, 25, and 50 logical-agent scenarios without launching tmux sessions, model CLIs, Beads mutations, Agent Mail writes, or local CPU-heavy builds. It writes artifacts for each scenario: generated launch plan, telemetry JSON, capacity/resource sample, timing, and pass/fail summary. Treat this as a local readiness harness, not a substitute for provider factory tests on real VPS hosts.

After one or more simulation runs, calibrate the static capacity assumptions against those local artifacts:

acfs swarm calibration --artifact-dir ~/.acfs/logs/swarm-simulations
acfs swarm calibration --json --artifact-dir ./swarm-artifacts --rch-file ./rch-timing.json

The calibration report is read-only. It classifies the local evidence as conservative, aligned, or too aggressive, handles missing or partial artifacts with warnings, and never changes capacity defaults, RCH state, NTM sessions, Beads, or Agent Mail.


Philosophy

The Flywheel

The "Agentic Coding Flywheel" is a virtuous cycle:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                                                 β”‚
β”‚    Better Environment β†’ More Agent Productivity β†’               β”‚
β”‚    More Code Written β†’ Better Understanding β†’                   β”‚
β”‚    Better Prompts β†’ Better Environment                          β”‚
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

ACFS kicks off this flywheel by providing the best possible starting environment for agentic coding.

Design Principles

  1. Beginner-Friendly, Expert-Fast: The wizard guides beginners; the one-liner serves experts.

  2. Vibe-First: Optimize for velocity in throwaway environments. Safety features exist in safe mode.

  3. Idempotent: Re-run without fear. The installer handles already-installed tools gracefully.

  4. Single Source of Truth: The manifest defines everything. Installer scripts are generated from it.

  5. Security by Default: HTTPS enforcement, checksum verification, no blind curl | bash.

  6. Modern Defaults: Latest versions, modern tools, optimal configurations out of the box.


The Vibe Coding Manifesto

"Vibe coding" isn't just a catchy nameβ€”it's a philosophy about how humans and AI should collaborate on software development.

What Is Vibe Coding?

Vibe coding is the practice of directing AI agents to write code while you focus on intent, architecture, and quality. Instead of typing every line yourself, you:

  1. Describe what you want in natural language
  2. Review and guide the agent's output
  3. Iterate rapidly through multiple approaches
  4. Ship faster while maintaining quality

The "vibe" comes from the flow state you enter when you're no longer fighting syntax, boilerplate, or implementation detailsβ€”you're just vibing with your AI partner.

The Three Laws of Vibe Coding

1. Velocity Over Ceremony

Traditional development is ceremony-heavy: create branch, write tests first, implement, refactor, write docs, create PR, wait for review, merge, deploy. Each step has friction.

Vibe coding inverts this: ship fast, iterate faster. The AI handles boilerplate while you focus on the 10% that requires human judgment.

Traditional: Think β†’ Plan β†’ Implement β†’ Test β†’ Document β†’ Ship
Vibe:        Describe β†’ Generate β†’ Verify β†’ Ship β†’ Iterate

2. Throwaway Environments Enable Boldness

The magic of vibe coding happens on ephemeral VPS instances. When your environment is disposable:

  • You can experiment without fear
  • Catastrophic failures are just "rebuild the VPS"
  • Agents can have dangerous permissions (they can't break what's disposable)
  • You focus on output, not on protecting your setup

This is why ACFS's "vibe mode" enables passwordless sudo and dangerous agent flagsβ€”on a $5/month throwaway VPS, there's nothing worth protecting.

3. Multi-Agent Is The Default

One agent is useful. Three agents working in parallel are transformative.

Vibe coding assumes you'll run multiple agents simultaneously:

  • Claude for complex reasoning and architecture
  • Codex for rapid prototyping and refactoring
  • Antigravity for documentation and research

ACFS provides the coordination layer (Agent Mail, NTM, SLB) that makes this practical.

The Anti-Patterns

Vibe coding is NOT:

  • Blindly accepting agent output without review
  • Abandoning tests and quality standards
  • Ignoring security on production systems
  • Treating agents as replacements for understanding

The goal is augmented human judgment, not abdicated human judgment.

When NOT to Vibe Code

  • Production systems with real users
  • Security-critical infrastructure
  • Anything involving credentials or secrets
  • Long-running servers (use safe mode)
  • Shared team environments (use coordination tools)

Vibe coding is for greenfield development, prototyping, experimentation, and learning. Use ACFS's safe mode for everything else.


State Machine & Checkpoint System

ACFS implements a robust checkpoint-based state machine that enables reliable resume-from-failure. This section explains how it works under the hood.

State File Format

Progress is tracked in ~/.acfs/state.json:

{
  "schema_version": 3,
  "started_at": "2024-12-21T10:30:00Z",
  "last_updated": "2024-12-21T10:45:23Z",
  "mode": "vibe",
  "completed_phases": ["user_setup", "filesystem", "shell_setup"],
  "current_phase": "cli_tools",
  "current_step": "Installing ripgrep",
  "failed_phase": null,
  "failed_step": null,
  "failed_error": null,
  "skipped_phases": [],
  "phase_timings": {
    "user_setup": 12,
    "filesystem": 8,
    "shell_setup": 145
  }
}

Phase State Transitions

Each phase goes through a defined state machine:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  PHASE STATE MACHINE                                                         β”‚
β”‚                                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                             β”‚
β”‚  β”‚ PENDING  │────▢│ RUNNING  │────▢│ COMPLETE β”‚                             β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                             β”‚
β”‚       β”‚                β”‚                                                     β”‚
β”‚       β”‚                β–Ό                                                     β”‚
β”‚       β”‚          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                              β”‚
β”‚       β”‚          β”‚  FAILED  │────▢│  RETRY   │──┐                           β”‚
β”‚       β”‚          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚                           β”‚
β”‚       β”‚                                β–²        β”‚                           β”‚
β”‚       β”‚                                β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜                           β”‚
β”‚       β”‚                                                                      β”‚
β”‚       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Άβ”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                  β”‚
β”‚          (--skip flag)        β”‚ SKIPPED  β”‚                                  β”‚
β”‚                               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Resume Logic

When the installer runs, it follows this decision tree:

def should_run_phase(phase_id):
    state = load_state_file()

    if phase_id in state.completed_phases:
        return SKIP  # Already done

    if phase_id in state.skipped_phases:
        return SKIP  # User explicitly skipped

    if state.failed_phase == phase_id:
        if user_wants_retry():
            return RUN  # Retry failed phase
        else:
            return ABORT  # Don't continue past failure

    return RUN  # Normal execution

Atomic State Updates

State file updates are atomic to prevent corruption from interrupted writes:

# Write to temp file first
echo "$new_state" > "$state_file.tmp.$$"

# Atomic rename (POSIX guarantees this is atomic on same filesystem)
mv "$state_file.tmp.$$" "$state_file"

This ensures the state file is never partially written, even if the process is killed mid-update.

Recovery from Common Failures

Failure TypeDetectionRecovery
Network timeoutcurl exit code 28Retry with exponential backoff
APT lock held/var/lib/dpkg/lock existsWait and retry up to 60s
Disk fulldf check before writeAbort with clear error
Out of memoryOOM killerResume picks up from last phase
SSH disconnectN/A (session dies)Resume on reconnect
Ctrl+CTrap handlerClean exit, state preserved

Phase Timings & Performance

The state file tracks how long each phase takes. This enables:

  • Accurate progress estimation ("Phase 4/9, ~3 minutes remaining")
  • Performance regression detection across ACFS versions
  • Identifying slow phases that need optimization

Error Handling & Recovery Patterns

ACFS is designed to fail gracefully and recover automatically. This section documents the error handling patterns used throughout the codebase.

The Try-Step Pattern

Every installation step is wrapped in a try_step function that captures errors without aborting:

try_step "Installing ripgrep" install_ripgrep

This pattern provides:

  • Context tracking: Errors include step name, not just exit code
  • Graceful continuation: Non-critical failures don't abort the whole install
  • Structured reporting: Failures are collected and reported at the end

Network Resilience

Network operations implement exponential backoff with jitter:

retry_with_backoff() {
    local max_attempts=5
    local delay=1

    for attempt in $(seq 1 $max_attempts); do
        if "$@"; then
            return 0
        fi

        # Exponential backoff: 1s, 2s, 4s, 8s, 16s
        # With jitter: Β±25% randomization
        local jitter=$(( (RANDOM % 50 - 25) * delay / 100 ))
        sleep $((delay + jitter))
        delay=$((delay * 2))
    done

    return 1
}

APT Lock Handling

The most common installation failure is APT lock contention (another process using apt):

wait_for_apt_lock() {
    local max_wait=60
    local waited=0

    while fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; do
        if [[ $waited -ge $max_wait ]]; then
            log_error "APT lock held for >60s, aborting"
            return 1
        fi
        log_detail "Waiting for apt lock... (${waited}s)"
        sleep 5
        waited=$((waited + 5))
    done

    return 0
}

Graceful Degradation

When a non-critical tool fails to install, ACFS continues with a warning:

Category: Critical    β†’ Failure aborts installation
          Standard    β†’ Failure logged, installation continues
          Optional    β†’ Failure noted, no warning

Examples:
  Critical: bun, zsh, git (can't proceed without these)
  Standard: ast-grep, lazygit (nice to have, not blocking)
  Optional: atuin, zoxide (pure enhancements)

The Error Report

At the end of installation (or on abort), ACFS generates a structured error report:

═══════════════════════════════════════════════════════════════════════════════
  INSTALLATION REPORT
═══════════════════════════════════════════════════════════════════════════════

  Status: PARTIAL SUCCESS (8/9 phases completed)

  βœ“ Completed Phases:
    β€’ User Setup (12s)
    β€’ Filesystem (8s)
    β€’ Shell Setup (2m 25s)
    β€’ CLI Tools (4m 12s)
    β€’ Languages (3m 45s)
    β€’ Agents (1m 30s)
    β€’ Cloud (2m 10s)
    β€’ Stack (5m 20s)

  βœ— Failed Phase: Finalize
    Step: Configuring tmux
    Error: tmux.conf syntax error on line 42

  Suggested Fix:
    Check ~/.acfs/tmux/tmux.conf for syntax errors
    Then run: curl ... | bash -s -- --yes --mode vibe --resume

═══════════════════════════════════════════════════════════════════════════════

Troubleshooting Guide

This section covers common issues and their solutions. For quick debugging, start with acfs doctor.

Installation Fails Immediately

Symptom: Installer exits within seconds of starting.

Common Causes & Solutions:

CauseDetectionFix
Not running as root"Permission denied"sudo bash or use sudo in curl command
Not Ubuntu"Unsupported OS"ACFS only supports Ubuntu 22.04+
No internet"curl: (6) Could not resolve host"Check DNS, try ping google.com
Old bashSyntax errorsUpgrade to bash 4+

Installation Failure Recovery

When the installer fails mid-way through, it provides an auto-resume hint with a precise command to continue from where it left off.

What you'll see on failure:

[ERROR] ACFS installation failed!

To debug:
  1. Check the log: cat /var/log/acfs/install.log
  2. If installed, run: acfs doctor (try as ubuntu)

╔══════════════════════════════════════════════════════════════╗
β•‘  To resume installation from this point:                     β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

  curl -fsSL https://raw.githubusercontent.com/Dicklesworthstone/.../install.sh | bash -s -- --resume --yes

  Failed phase: phase_9
  Failed step: install_stack

Key features of the resume hint:

FeatureDescription
Pinned commitUses exact SHA from original run for reproducibility
Preserved flagsIncludes all original flags (--skip-*, --mode, --strict)
Automatic detectionReads failed phase/step from ~/.acfs/state.json
Copyable commandReady to paste and run immediately

Manual recovery steps:

  1. Review the error:

    # Check the full log
    cat /var/log/acfs/install.log | tail -50
    
    # Or search for ERROR
    grep -i error /var/log/acfs/install.log
    
  2. Run diagnostics:

    # As the target user (ubuntu)
    acfs doctor
    
    # If running as root
    sudo -u ubuntu -i bash -lc 'acfs doctor'
    
  3. Resume installation:

    # Use the exact command from the failure output
    # Or use the generic resume command:
    curl -fsSL https://acfs.sh | bash -s -- --resume --yes --mode vibe
    
  4. Check state file (advanced):

    # View current installation state
    cat ~/.acfs/state.json | jq .
    
    # See the stored resume hint
    jq '.resume_hint' ~/.acfs/state.json
    

Common failure scenarios:

ScenarioTypical CauseRecovery
Network timeoutTransient connectivityWait, then resume
APT lock heldUnattended-upgradesWait 2-3 min, resume
Disk fullInsufficient spaceFree space, resume
SSH disconnectSession timeoutReconnect, resume
Tool install failedUpstream unavailableCheck status, resume

APT Lock Errors

Symptom: E: Could not get lock /var/lib/dpkg/lock-frontend

Solutions:

  1. Wait for unattended-upgrades (most common on fresh VPS):

    # Check what's holding the lock
    sudo lsof /var/lib/dpkg/lock-frontend
    
    # Wait for it to finish (usually 2-3 minutes on fresh VPS)
    # Then re-run installer
    
  2. Inspect and recover if waiting doesn't help:

    sudo fuser -v /var/lib/dpkg/lock-frontend || true
    sudo systemctl status unattended-upgrades --no-pager || true
    
    # If it still looks stuck after several minutes, reboot the VPS,
    # reconnect, then repair interrupted package configuration:
    sudo dpkg --configure -a
    sudo apt-get update
    

Install Logs & Summary JSON

Every ACFS install run produces two artifacts for debugging and tooling:

Log File Location:

~/.acfs/logs/install-YYYYMMDD_HHMMSS.log

The log file captures all stderr output from the installer, with:

  • Header containing version, date, and mode
  • All progress messages and errors
  • ANSI colors stripped after completion
  • Footer with completion timestamp

Summary JSON Location:

~/.acfs/logs/install_summary_YYYYMMDD_HHMMSS.json

Summary JSON Schema (v1):

{
  "schema_version": 1,
  "status": "success",           // "success" or "failure"
  "timestamp": "2026-01-27T...", // ISO 8601
  "total_seconds": 1200,         // Wall clock time
  "environment": {
    "acfs_version": "0.9.0",
    "mode": "vibe",
    "ubuntu_version": "25.04",
    "target_user": "ubuntu",
    "target_home": "/home/ubuntu"
  },
  "phases": [
    {"id": "phase_0", "duration_seconds": 5},
    {"id": "phase_1", "duration_seconds": 45},
    // ... completed phases in order
  ],
  "failure": null,               // null on success, or:
  // "failure": {
  //   "phase": "phase_9",
  //   "step": "install_stack",
  //   "error": "curl failed with exit code 7",
  //   "resume_hint": "curl -fsSL ... | bash -s -- --resume --yes"
  // }
  "log_file": "/home/ubuntu/.acfs/logs/install-20260127_120000.log"
}

Accessing logs:

# Find the latest log
ls -lt ~/.acfs/logs/install-*.log | head -1

# Find the latest summary
ls -lt ~/.acfs/logs/install_summary_*.json | head -1

# Parse summary JSON
jq . ~/.acfs/logs/install_summary_*.json | head -1

# Get failed phase (if any)
jq '.failure // "No failure"' ~/.acfs/logs/install_summary_*.json | tail -1

# Get phase timings
jq '.phases[] | "\(.id): \(.duration_seconds)s"' ~/.acfs/logs/install_summary_*.json | tail -1

Sharing logs for support:

# Create a support bundle (strips sensitive data)
acfs support-bundle > support-bundle.txt

# Or manually share (review for secrets first):
cat ~/.acfs/logs/install-*.log | tail -200  # Last 200 lines
cat ~/.acfs/logs/install_summary_*.json | tail -1  # Latest summary

Support Bundle Command

The acfs support-bundle command collects all diagnostic data into a single archive for troubleshooting.

Usage:

acfs support-bundle [options]

Options:

OptionDescription
--verbose, -vShow detailed output during collection
--output, -o DIROutput directory (default: ~/.acfs/support)
--no-redactDisable secret redaction (WARNING: bundle may contain secrets)
--help, -hShow help

Output files:

~/.acfs/support/<timestamp>/          # Unpacked bundle directory
~/.acfs/support/<timestamp>.tar.gz    # Compressed archive (shareable)
~/.acfs/support/<timestamp>/manifest.json  # Bundle manifest

What's collected:

FileDescription
state.jsonInstallation state and checkpoints
VERSIONACFS version
checksums.yamlUpstream verification checksums
logs/install-*.logRecent install logs (up to 10)
logs/install_summary_*.jsonRecent install summaries
doctor.jsonHealth check results
versions.jsonInstalled tool versions
environment.jsonOS, memory, disk, user info
os-releaseLinux distribution info
journal-acfs.logSystemd journal for ACFS services
config/.zshrcShell configuration

Security & Redaction:

By default, sensitive data is automatically redacted:

PatternExampleRedacted To
OpenAI API keyssk-abc123...<REDACTED:api_key>
AWS keysAKIAIOSFODNN...<REDACTED:aws_key>
GitHub tokensghp_xxxx...<REDACTED:github_token>
Vault tokenshvs.xxxx...<REDACTED:vault_token>
Slack tokensxoxb-xxxx...<REDACTED:slack_token>
Bearer tokensBearer xxx...Bearer <REDACTED:bearer>
JWTseyJhbGc...<REDACTED:jwt>
Passwords"password": "...""password": "<REDACTED:password>"
Private key blocks-----BEGIN ... PRIVATE KEY-----<REDACTED:private_key>

Before launching a large agent swarm or sharing a support bundle, run a local credential preflight:

acfs credential-preflight --json

The preflight scans bounded ACFS state/log files plus shell config/history surfaces and reports only categories, counts, file labels, and remediation guidance. It never prints raw secret values or snippets.

Example workflow:

# Create support bundle
acfs support-bundle

# Output: ~/.acfs/support/20260127_120000.tar.gz

# Share the archive when filing an issue
# The archive is safe to share (secrets redacted)

Disable redaction (use with caution):

# WARNING: Bundle may contain API keys, tokens, and passwords
acfs support-bundle --no-redact

When to use:

  • Installation failed and you need to share logs
  • Filing a GitHub issue about ACFS
  • Diagnosing tool installation problems
  • Sharing system state with support

Shell Not Changing to zsh

Symptom: Still seeing bash prompt after install.

Solutions:

  1. Log out and back in (the change happens at next login)

  2. Manually set shell:

    chsh -s $(which zsh)
    # Then log out and back in
    
  3. Check shell was installed:

    which zsh  # Should show /usr/bin/zsh
    cat /etc/shells  # zsh should be listed
    

Agent Authentication Issues

Start with the safe readiness report:

bash scripts/agent-readiness-audit.sh --json

Claude Code:

# Check auth status
claude --version
ls -la ~/.claude/  # or ~/.config/claude/

# Re-authenticate
claude  # Follow prompts, then use /login inside Claude Code to switch accounts

Codex CLI:

# Check auth status
codex --version

# Re-authenticate (uses ChatGPT account, not API key)
codex  # Follow first-run sign-in prompts

Antigravity CLI:

# Check auth status
agy --version

# Re-authenticate
agy  # Follow Google login flow

"Command Not Found" After Install

Symptom: claude: command not found even though install succeeded.

Solutions:

  1. Reload shell config:

    source ~/.zshrc
    # Or start a new shell
    exec zsh
    
  2. Check PATH:

    echo $PATH | tr ':' '\n' | grep -E "(bun|local|cargo)"
    # Should include: ~/.bun/bin, ~/.local/bin, ~/.cargo/bin
    
  3. Manual path fix:

    export PATH="$HOME/.bun/bin:$HOME/.local/bin:$HOME/.cargo/bin:$PATH"
    

Doctor Shows Missing Tools

Symptom: acfs doctor shows failed checks for tools you expected to be installed.

Understanding doctor output:

Doctor checks are generated directly from the manifest, so they verify the exact same tools the installer provides. When a check fails, doctor shows a copy-pasteable fix command:

  βœ— tools.lazygit - Lazygit terminal UI not found
    Fix: acfs install --only tools.lazygit

Solutions:

  1. Re-run the specific module (use the fix suggestion):

    acfs install --only tools.lazygit   # Install just that tool
    acfs install --only lang.go         # Install a language runtime
    acfs install --only stack.dcg       # Install a stack tool
    
  2. Re-run an entire phase (for multiple failures in one category):

    acfs install --only-phase cli     # Re-run CLI tools
    acfs install --only-phase stack   # Re-run stack tools
    
  3. Run auto-fix mode (applies safe, deterministic fixes):

    acfs doctor --fix
    acfs doctor --fix --dry-run  # Preview fixes first
    

Note: Doctor checks match the manifest verify commands exactly. If a tool was skipped during installation (e.g., using --mode safe), the check will fail. This is expectedβ€”run acfs doctor to see which tools are missing and decide which to install.

Tmux Configuration Errors

Symptom: Tmux won't start or shows config errors.

Solutions:

  1. Check syntax:

    tmux source-file ~/.tmux.conf
    # Will show line number of any errors
    
  2. Reset to ACFS defaults:

    cp ~/.acfs/tmux/tmux.conf ~/.tmux.conf
    
  3. Version mismatch (old tmux, new config):

    tmux -V  # Check version
    # ACFS config requires tmux 3.0+
    

Stack Tools Not Working

Symptom: ntm, slb, dcg, etc. not found or erroring.

Solutions:

  1. Reinstall stack:

    acfs update --stack --force
    
  2. Check cargo install worked:

    ls ~/.cargo/bin/  # Should contain ntm, slb, ru, etc.
    ls ~/.local/bin/  # dcg often installs here
    
  3. Rust not in path:

    source ~/.cargo/env
    

DCG Hook Issues

Symptom: DCG isn't blocking commands or Claude reports hook errors.

Solutions:

  1. Run the built-in health check:

    dcg doctor
    
  2. Re-register the hook:

    dcg install --force
    
  3. Verify hook registration:

    grep -n dcg ~/.claude/settings.json ~/.config/claude/settings.json
    
  4. Reinstall if binary is missing:

    which dcg  # Should return a path
    # If missing, reinstall through the ACFS verified installer path:
    acfs update --stack-only
    dcg install --force  # Register hook after reinstall
    

Complete Reset

When all else fails, the nuclear option:

# Save any important files first!

# Backup ACFS state (recommended)
ts="$(date +%Y%m%d_%H%M%S)"
[ -d ~/.acfs ] && mv ~/.acfs ~/.acfs.backup."$ts"

# Backup installed configs (optional)
for f in ~/.zshrc ~/.tmux.conf ~/.p10k.zsh; do
  [ -f "$f" ] && mv "$f" "$f".backup."$ts"
done

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/main/install.sh?$(date +%s)" | bash -s -- --yes --mode vibe --force-reinstall

Security Threat Model

ACFS takes security seriously while acknowledging the inherent risks of curl | bash installation. This section documents our threat model and mitigations.

What We Protect Against

ThreatMitigation
Man-in-the-middle (MITM)HTTPS enforcement for all downloads
Compromised upstream scriptsSHA256 checksum verification
Malicious package injectionOfficial package sources only (apt, cargo, bun)
Credential exposureNo credentials stored in scripts or configs
Privilege escalationMinimal sudo usage, explicit permission grants
Persistent backdoorsEphemeral VPS model; start fresh if concerned

What We Don't Protect Against

ThreatWhy NotMitigation
Compromised GitHubWould require GitHub-level breachUse release tags, verify commits
Compromised upstream maintainersCan't verify humansTrust + checksum verification
Zero-day in installed toolsBeyond our controlKeep tools updated, follow CVEs
Physical VPS accessProvider responsibilityChoose reputable providers
Vibe mode abuseBy design for throwaway VPSUse safe mode on important systems

The curl | bash Debate

The curl | bash pattern is controversial. Critics argue:

  • You're executing arbitrary code from the internet
  • The download could be swapped mid-stream
  • You can't audit before executing

Our response:

  1. HTTPS prevents mid-stream swapping
  2. Checksums verify content matches known-good versions
  3. Ephemeral environments limit blast radius
  4. Open source allows pre-audit of install.sh

For maximum security, you can:

curl -fsSL "https://..." -o install.sh
less install.sh
bash install.sh --yes --mode vibe

Checksum Verification Deep Dive

Every upstream installer we fetch is verified against known-good checksums:

# checksums.yaml excerpt
installers:
  bun:
    url: "https://bun.sh/install"
    sha256: "a1b2c3d4e5f6..."
    last_verified: "2024-12-15"
    notes: "Official Bun installer"

The verification process:

1. Download script to memory (not disk)
2. Calculate SHA256 of downloaded bytes
3. Compare against stored checksum
4. If match: execute
5. If mismatch: abort with warning

A mismatch could mean:

  • Upstream released a new version (common, usually safe)
  • Upstream was compromised (rare, investigate before updating)

Our update process:

  1. Monitor upstream releases
  2. Review changes in new installer versions
  3. Update checksums only after manual review
  4. Commit with descriptive message explaining what changed

Vibe Mode Security Implications

Vibe mode (--mode vibe) enables:

  • Passwordless sudo for ubuntu user
  • --dangerously-skip-permissions for Claude
  • --dangerously-bypass-approvals-and-sandbox for Codex
  • Always-proceed tool permission for Antigravity (agy)

This is intentionally insecure for velocity. Use only on:

  • Throwaway VPS you don't care about
  • Non-production environments
  • Personal experimentation

Never on:

  • Production servers
  • Shared team infrastructure
  • Systems with sensitive data
  • Long-running servers

Comparison to Alternatives

How does ACFS compare to other ways of setting up a development environment?

vs. Manual Setup

AspectManualACFS
Time3-7 hours30 minutes
ConsistencyVariesIdentical every time
DocumentationYour memoryThis README
Resume on failureStart overAutomatic
UpdatesManual each toolacfs update

When to use manual: When you need to understand every detail, or have highly specific requirements.

vs. Dotfiles Repos

AspectDotfilesACFS
ScopeConfigs onlyFull tool installation
PortabilityMac/LinuxUbuntu-focused
MaintenanceDIYMaintained project
Agent focusNoneCore feature

When to use dotfiles: When you already have tools installed and just want configs.

vs. Nix/NixOS

AspectNixACFS
ReproducibilityPerfectGood
Learning curveSteepGentle
RollbackNativeManual
ComplexityHighLow
AdoptionGrowingEasy

When to use Nix: When you need perfect reproducibility and are willing to invest in learning Nix.

vs. DevContainers

AspectDevContainersACFS
IsolationContainerFull VPS
Resource overheadContainer runtimeNone
IDE integrationVSCode-centricTerminal-native
Agent experienceLimitedNative

When to use DevContainers: When you want isolated project environments within an existing machine.

vs. Ansible/Terraform

AspectAnsible/TFACFS
ScopeInfrastructureDevelopment env
ComplexityHighLow
AudienceDevOpsDevelopers
Learning curveSteepGentle

When to use Ansible/Terraform: When you're managing fleets of servers, not individual dev environments.

The ACFS Sweet Spot

ACFS is optimal when you need:

  • Fast setup of a complete agentic coding environment
  • Fresh Ubuntu VPS as your target
  • AI coding agents as primary tools
  • Throwaway/ephemeral infrastructure mindset
  • Minimal configuration to get started

The Dicklesworthstone Stack Philosophy

The 10-tool stack included in ACFS isn't randomβ€”each tool addresses a specific problem discovered through extensive multi-agent development experience.

The Problems

Running multiple AI coding agents simultaneously surfaces problems that don't exist with single-agent or no-agent development:

  1. Session chaos: Agents in random terminal windows, no organization
  2. File conflicts: Two agents editing the same file simultaneously
  3. No communication: Agents can't coordinate or share findings
  4. Dangerous commands: Agents running git reset --hard or rm -rf without oversight
  5. Lost context: No memory of what agents learned previously
  6. Auth switching: Different projects need different credentials
  7. History fragmentation: Agent conversations scattered across systems
  8. No task visibility: Hard to see what agents are working on
  9. Repo sprawl: Dozens of repos, hard to keep synced, uncommitted work everywhere
  10. Visual debugging gaps: Screenshots on phone, can't view in SSH terminal

The Solutions

Each tool in the stack addresses specific problems:

#ToolProblem SolvedPhilosophy
1NTMSession chaosNamed sessions create order from chaos
2Agent MailNo communication + file conflictsMessage-passing + file reservations
3UBSDangerous commandsGuardrails with intelligence
4Beads ViewerNo task visibilityGraph-based task dependencies
5CASSHistory fragmentationUnified search across all agents
6CMLost contextProcedural memory for agents
7CAAMAuth switchingOne command to switch identities
8SLBDangerous commandsTwo-person rule for nuclear options
9DCGDangerous git/fs commandsSub-millisecond Claude Code hook blocks destructive operations
10RURepo sprawlSync repos + AI-driven commit automation across dirty repos

Bundled Utilities:

ToolProblem SolvedPhilosophy
giilVisual debugging gapsDownload cloud images (iCloud, Dropbox, Google Photos) to terminal
csctfKnowledge captureConvert AI chat shares to searchable Markdown/HTML archives

The Synergy Effect

These tools are designed to work together:

NTM spawns agents β†’ Agents register with Agent Mail β†’
Agent Mail reserves files β†’ DCG blocks dangerous commands β†’
UBS validates operations β†’ Beads tracks tasks β†’
CASS searches history β†’ CM provides memory β†’
CAAM manages auth β†’ SLB gates nuclear operations β†’
RU syncs repos and automates commits

No single tool is transformative alone. Together, they enable workflows that would otherwise be impossible:

  • 10 agents working in parallel without stepping on each other
  • Continuous operation across SSH disconnects
  • Audit trails for every agent action
  • Coordination without manual intervention
  • Safety without sacrificing velocity

Design Principles of the Stack

  1. Unix Philosophy: Each tool does one thing well
  2. Composition: Tools designed to pipe into each other
  3. Terminal-First: TUI over GUI, speed over polish
  4. Agent-Native: Built for AI, not adapted for AI
  5. Git-Friendly: All state is auditable in version control

Advanced Configuration

ACFS supports various configuration mechanisms for advanced users.

Environment Variables

VariableDefaultDescription
ACFS_HOME~/.acfsConfiguration directory
ACFS_REFmainGit ref to install from (tag, branch, or commit SHA)
ACFS_CHECKSUMS_REFmain (when pinned) / ACFS_REF (when branch)Ref used to fetch checksums.yaml
ACFS_LOG_DIR/var/log/acfsLog directory
TARGET_USERubuntuUser to configure
TARGET_HOMEResolved from TARGET_USERUser home directory (or explicit override)

Examples:

# Install from a tagged release (recommended for production)
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/v0.1.0/install.sh" | bash -s -- --yes --mode vibe --ref v0.1.0

# Install from a specific branch (development/testing)
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/feature/new-tool/install.sh" | bash -s -- --yes --mode vibe --ref feature/new-tool

# Install from a specific commit (reproducibility)
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/abc1234/install.sh" | bash -s -- --yes --mode vibe --ref abc1234

# Pin installer version but use latest checksums (avoid stale hash mismatches)
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/agentic_coding_flywheel_setup/v0.5.0/install.sh" | bash -s -- --yes --mode vibe --ref v0.5.0 --checksums-ref main

Tip: Always match the URL path with --ref so the initial script and all subsequently fetched scripts come from the same ref. If you use environment variables in a pipeline, attach them to bash, not curl: curl ... | ACFS_REF=v0.5.0 bash -s -- --yes --mode vibe. Tip: For pinned installs (tags/SHAs), checksums default to main to avoid stale installer hashes. Override with ACFS_CHECKSUMS_REF if you want checksums pinned to the same ref.

Complete Installer CLI Options

The installer supports extensive command-line customization:

Execution Control:

--yes, -y              # Skip all prompts (non-interactive)
--dry-run              # Simulate without making changes
--print                # Print what would be installed
--mode vibe|safe       # Installation mode (default: vibe)
--interactive          # Force interactive mode with prompts
--strict               # Abort on any error (vs. continue with warnings)
--ref <ref>            # Git ref to install from (branch, tag, or commit SHA)
--checksums-ref <ref>  # Fetch checksums.yaml from this ref (default: main for pinned tags/SHAs)

Resume & State:

--resume               # Resume from last checkpoint
--force-reinstall      # Ignore state, reinstall everything
--reset-state          # Clear state.json and start fresh

Ubuntu Upgrade:

--skip-ubuntu-upgrade           # Don't upgrade Ubuntu version
--target-ubuntu=25.10           # Specify target Ubuntu version
--target-ubuntu 25.04           # Alternative syntax

Skip Flags:

--skip-postgres        # Skip PostgreSQL 18
--skip-vault           # Skip HashiCorp Vault
--skip-cloud           # Skip Wrangler, Supabase, Vercel CLIs
--skip-preflight       # Skip pre-flight validation

Module Selection

Fine-grained control over what gets installed using manifest-driven selection:

--list-modules           # List available modules
--print-plan             # Show execution plan without running
--only <module>          # Only run specific module(s)
--only-phase <phase>     # Only run modules in a phase
--skip <module>          # Skip specific module(s)
--no-deps                # Don't auto-include dependencies (⚠️ advanced)

Key behaviors:

  • Dependency closure: --only automatically includes required dependencies (safe by default)
  • Skip safety: --skip fails early if it would break a required dependency chain
  • Deterministic: --print-plan shows exactly what will run, in what order

Examples: Only install agents (plus their dependencies):

curl -fsSL "..." | bash -s -- --yes --only-phase agents

Skip PostgreSQL and Vault:

curl -fsSL "..." | bash -s -- --yes --skip db.postgres18 --skip tools.vault

Preview what would run without executing:

curl -fsSL "..." | bash -s -- --print-plan

Note: Using --no-deps bypasses safety checks and may result in broken installs. Only use if you've already installed dependencies separately.

Custom Post-Install Hooks

Add custom steps by placing scripts in ~/.acfs/hooks/:

mkdir -p ~/.acfs/hooks
cat > ~/.acfs/hooks/post-install.sh << 'EOF'
#!/bin/bash
# Custom post-install steps
echo "Running custom configuration..."
# Your commands here
EOF
chmod +x ~/.acfs/hooks/post-install.sh

ACFS will execute post-install.sh after the main installation completes.

Override Tool Versions

To pin specific tool versions, set environment variables:

export BUN_VERSION="1.1.0"
export UV_VERSION="0.5.0"
# Then run installer

Note: Not all tools support version pinning. Check individual tool documentation.


Future Roadmap

ACFS is actively developed. Here's what's coming:

Near-Term (Q1 2025)

  • Full manifest-driven execution: install.sh consumes generated scripts
  • Tailscale integration: Zero-config VPN for secure remote access βœ“
  • Services setup wizard: Guide users through service account setup (acfs services-setup) βœ“
  • Interactive module selection: Choose what to install via TUI

Mid-Term (Q2 2025)

  • ARM64 optimization: Native Apple Silicon and ARM VPS support
  • Offline mode: Pre-downloaded package bundles
  • Team mode: Shared configurations across team members
  • Plugin system: Third-party tool integrations

Long-Term (2025+)

  • ACFS Cloud: Managed VPS provisioning + ACFS install in one click
  • IDE integrations: VSCode/Cursor extensions for remote ACFS management
  • Agent marketplace: Pre-configured agent personalities and workflows
  • Enterprise features: SSO, audit logging, compliance

Performance Benchmarks

Installation times vary by VPS provider and network conditions. Here are typical benchmarks:

Installation Time by Phase

PhaseTypical DurationNotes
User Setup10-15sFast, mostly checks
Filesystem5-10sCreating directories
Shell Setup2-4 minOh-My-Zsh clone is slow
CLI Tools3-5 minMany apt packages
Languages3-5 minRust compile takes longest
Agents1-2 minFast bun installs
Cloud1-2 minFast bun installs
Stack4-6 minCargo installs
Finalize30-60sConfig deployment
Total15-25 minTypical full install

Factors Affecting Speed

FactorImpactOptimization
Network latencyHighChoose VPS close to package mirrors
Disk I/OMediumSSD/NVMe preferred
CPU coresMediumMore cores = faster compilation
RAMLow4GB is sufficient
ProviderVariableOVH and Contabo offer excellent value

Resume Performance

Resuming from checkpoint is fast because completed phases are skipped:

Full install:     20 minutes
Resume from 50%:  10 minutes
Resume from 90%:  2 minutes

License

MIT License (with OpenAI/Anthropic Rider). See LICENSE for details.



About Contributions

Please don't take this the wrong way, but I do not accept outside contributions for any of my projects. I simply don't have the mental bandwidth to review anything, and it's my name on the thing, so I'm responsible for any problems it causes; thus, the risk-reward is highly asymmetric from my perspective. I'd also have to worry about other "stakeholders," which seems unwise for tools I mostly make for myself for free. Feel free to submit issues, and even PRs if you want to illustrate a proposed fix, but know I won't merge them directly. Instead, I'll have Claude or Codex review submissions via gh and independently decide whether and how to address them. Bug reports in particular are welcome. Sorry if this offends, but I want to avoid wasted time and hurt feelings. I understand this isn't in sync with the prevailing open-source ethos that seeks community contributions, but it's the only way I can move at this velocity and keep my sanity.


Created by Jeffrey Emanuel (@Dicklesworthstone) for the agentic coding community.