Base
September 1, 2026 · View on GitHub
Base is an AI-ready GitHub workspace control plane for repository setup, local development, and verified pull requests.
Base is the local operating contract you add to a repository set so its readiness, trusted execution, onboarding, and handoff stop depending on private maintainer memory. It makes a project workspace explicit and repeatable. It gives developers and platform engineers a shared way to prepare repositories, inspect readiness, approve trusted project commands, and hand off work across one or more independent Git repositories.
Use Base when you need to:
- create or configure a GitHub repository and its local workspace;
- make setup, readiness, tests, builds, and trusted execution inspectable before work starts;
- carry enough evidence from issue and implementation work to a verified, handoff-ready pull request.
Base owns workspace orchestration, policy, trust, readiness, and handoff. Your repositories own their source code, tests, and project behavior; GitHub owns hosting and pull requests; environment managers and AI tools remain adapters. That boundary lets Base coordinate the workflow without turning your projects into a monorepo or moving project-specific logic into Base.
inventory -> prepare -> verify -> trust -> onboard -> hand off
Quickstart
For the canonical source-checkout install commands, see the source checkout install recipe. Then run the trust-conscious project proof:
# After completing the canonical source-checkout install recipe.
~/work/base/bin/basectl setup --dry-run
~/work/base/bin/basectl projects list --workspace ~/work
~/work/base/bin/basectl trust status base
Review the manifest identity and digest printed by trust status before
running the exact basectl trust allow base --manifest-sha256 ... command it
provides. This path lets you inspect and verify Base before adding it to shell
startup files. See Start Here for the demo walkthrough and install
choices.
See Base Run
The shortest proof is the real self-demo:
basectl demo base -- --non-interactive
This excerpt is from that manifest-declared run; local paths are shortened so the workflow is easy to scan:
$ basectl demo base -- --non-interactive
Base Self-Demo
== Step 1: Runtime Contract ==
BASE_PROJECT=base
== Step 2: Manifest Contract ==
11:demo:
12: script: ./demo/demo.sh
== Step 4: Check And Doctor ==
Base CLI environment and project 'base' check passed.
Base doctor found no blocking issues for project 'base'.
== Step 6: Run And Test Delegation ==
[DRY-RUN] Would run command test for project base: ./bin/base-test
[DRY-RUN] Would run tests for project base: ./bin/base-test
Base self-demo complete.
Play the full asciinema-compatible capture.
Tool Comparison
| Tool | Primary responsibility | Base relationship |
|---|---|---|
| Base | Repository contracts, readiness, trust, onboarding, and handoff | Owns the local operating contract across participating repositories |
| mise | Machine and project bootstrap, tool versions, environments, and tasks | Base delegates; choose mise when convergence is the primary outcome |
| mani | Git repository inventory, synchronization, worktrees, filters, and tasks | Base coexists; choose mani when repository-set management is the primary need |
See Tool Boundaries for the maintained comparison, including where Base should delegate, integrate, or stay out of the way.
Contents
- Quickstart
- See Base Run
- Why Base Exists
- What Base Is Responsible For
- What Base Is Not Responsible For
- Mental Model
- Likely Workspace Shape
- Design Principles
- Source Control And Forge Support
- Start Here
- How Base Fits
- Product Layers And Shipped Commands
- Public Command Surface
- Installation Details
- Version Identity
- Documentation
- Compatibility
- Shell Startup Files
- Optional Utility Tools
- Current Status
- License
Why Base Exists
Every engineering project accumulates setup steps, readiness rules, trusted commands, and handoff context that can become scattered across READMEs, shell state, and maintainer memory. That problem exists within a single repository and becomes more visible when work spans several repositories. Base gives a project or participating repository set one explicit local contract for answering: what belongs here, what is ready, what is missing, what may run, and what the next person or agent needs to know.
In this product promise, deterministic is deliberately narrow. Base makes declared inputs, inspection order, findings, and next actions explicit and repeatable. It does not promise hermetic builds, byte-for-byte environments, or transactional mutation across every repository and external tool.
For a concise evaluator view of where Base fits, what it gives a project or multi-repo workspace, and how it compares with adjacent tools, see Why Base. For a candid maintained assessment of Base's originality, usefulness, adoption potential, and engineering evidence, see Product Assessment.
Common first-run and product questions are answered in FAQ.md. Contributions should follow CONTRIBUTING.md. Report security issues and handle detected credentials according to SECURITY.md. Release notes are tracked in CHANGELOG.md.
What Base Is Responsible For
Base owns the local operating contract for participating repositories.
That means Base should be responsible for:
- inventorying participating repositories and their declared contracts
- preparing and verifying local readiness through explicit commands
- enforcing Base's local trust boundary for manifest-declared execution
- making onboarding state and handoff evidence inspectable
- providing the execution conventions and diagnostics that support that outcome
Repository/GitHub/release workflow packs and environment/IDE/container/AI adapters support this contract, but they do not redefine the core product.
What Base Is Not Responsible For
Base should not absorb project-specific logic that belongs inside individual repositories.
Each project repo should still own:
- its own source code
- its own business logic
- its own build details
- its own runtime details
- its own tests
- its own project-specific setup steps
Base should orchestrate those things, not replace them.
Mental Model
Think of Base as the local operating contract for a project, whether that project is one repository or a set of independent Git repositories.
A single repository can use Base to make setup, readiness, trusted execution, and handoff explicit. When a project spans several repositories, Base extends the same contract across the repository set. Each project repo remains independent; Base sits beside those repos and offers:
- one declared way to inventory, prepare, and verify local readiness
- one explicit trust boundary for project-owned commands
- one onboarding story and a growing set of local handoff evidence
That gives a multi-repo setup some of the ergonomic benefits people often reach for in a monorepo, without forcing unrelated codebases into a single repository.
Likely Workspace Shape
The target shape looks roughly like this:
work/ ← shared workspace root (`workspace.root`)
base/ ← Base repository (`BASE_HOME` for source installs)
project-a/ ← peer project with `base_manifest.yaml`
project-b/ ← peer project with `base_manifest.yaml`
infra/ ← another peer repo that can opt into Base
Projects opt into Base with minimal coupling:
- Base discovers projects in the shared workspace
- projects expose a small contract through
base_manifest.yaml - Base provides common orchestration on top
Design Principles
Base follows a few simple principles.
- Keep project repos independent.
- Prefer explicit conventions over hidden shell magic.
- Keep wrappers thin but reliable.
- Make setup and test flows idempotent where possible.
- Make findings and next actions stable enough for human and automated handoff.
- Let Base provide the common layer without turning into a dumping ground for project-specific behavior.
Source Control And Forge Support
Base assumes Git. Mercurial, Perforce, Subversion, and other non-Git SCMs are out of scope.
Base is GitHub-primary rather than forge-independent. GitHub is the only
first-class forge automation target today for repository creation,
configuration, Issues, pull requests, Projects, Actions intake, and release
publishing. A GitLab, Bitbucket, internal Git, or local Git repository can
still use Base's local project loop once it is checked out locally and declares
base_manifest.yaml.
See Source Control And Forge Support for the command-by-command compatibility contract and non-GitHub Git workflow.
Start Here
Trust-Conscious Proof, No Dotfile Changes
The canonical no-dotfile proof is in Quickstart. It runs
basectl trust status base before the final basectl demo base -- --non-interactive;
review the manifest identity and digest, then run the exact basectl trust allow base --manifest-sha256 ... command it provides. This path
lets you inspect and verify Base before adding it to shell startup files.
Until shell-profile setup puts basectl on PATH, replace its leading
basectl with ~/work/base/bin/basectl; keep the project and printed digest
unchanged.
To inspect a small, real Base-managed project, clone
basefoundry/base-demo next to
Base and run its walkthrough:
git clone https://github.com/basefoundry/base-demo.git ~/work/base-demo
~/work/base/bin/basectl setup base-demo
~/work/base/bin/basectl trust status base-demo
Review the reported command surfaces, then run the exact command it prints:
basectl trust allow base-demo --manifest-sha256 .... Only then launch the
demo:
~/work/base/bin/basectl demo base-demo
The demo sequence is separate from the canonical Quickstart proof; both keep manifest trust review ahead of execution.
Shell Startup Is Explicit
Run update-profile only after you want basectl on PATH, shell
completions, and basectl activate <project> available in new interactive
shells:
~/work/base/bin/basectl update-profile --dry-run
~/work/base/bin/basectl update-profile
exec "$SHELL" -l
update-profile manages only marked Base sections in Bash and Zsh startup
files and preserves non-Base content. See Shell Startup Files
for the full dotfile boundary.
Choose An Install Path
Choose Homebrew when you want Base managed like an installed consumer tool, or a source checkout when you want to contribute to or dogfood Base. The consolidated Installation Details section below summarizes the supported bootstrap, Homebrew, source-checkout, and standalone-installer paths. See First-Mile Bootstrap for the complete recipes and safety checks.
New Or Uncertain Machine?
Use the First-Mile Bootstrap guide when Homebrew, Git, or a supported Bash may be missing. The concise verified handoff is:
curl -fsSL https://raw.githubusercontent.com/basefoundry/base/HEAD/bootstrap.sh | bash
For a reviewed Homebrew installer, provide both checksum variables before running that command:
BASE_BOOTSTRAP_HOMEBREW_INSTALLER_URL=file:///path/to/homebrew-install.sh \
BASE_BOOTSTRAP_HOMEBREW_INSTALLER_SHA256=<sha256> \
curl -fsSL https://raw.githubusercontent.com/basefoundry/base/HEAD/bootstrap.sh | bash
Use --ensure-bash --dry-run and --ensure-bash --yes for the narrower
Bash-repair path; use --source, --brew, or
--source --dry-run for explicit mode selection and Ubuntu/Debian review.
The same installer pin can use BASE_HOMEBREW_INSTALLER_URL and
BASE_HOMEBREW_INSTALLER_SHA256. The supported paths are summarized in
Installation Details, with complete recipes and edge
cases in First-Mile Bootstrap.
Team Or Security-Conscious Rollout
Review installer plans with --dry-run and pin remote installer content when
your workstation policy requires it. The complete checksum, consent,
Ubuntu/Debian, tap-trust, and project-installer guidance lives in
First-Mile Bootstrap and
Remote Installer Policy.
After Base is installed, the common development loop is:
basectl projects list
basectl setup <project>
basectl check <project>
basectl doctor <project>
basectl test <project>
basectl demo [project]
basectl run [project] <command>
basectl export-context <project>
basectl docs
basectl activate <project>
For Base itself, run the self-demo or the dogfood test contract:
basectl demo base -- --non-interactive
basectl test base
How Base Fits
Base coordinates the systems that already own their domains:
- Homebrew still owns ordinary macOS packages and Brewfiles.
- mise owns its configuration model, including language/runtime management and
its broader machine and project bootstrap behavior. When a Base manifest
points to a mise config, Base checks mise's config trust and missing tools,
runs
mise install, and delegatesmise run. On Debian-family Linux, Base can install a missing mise CLI after--dry-runreview and--yesconsent under its remote-installer policy. Base does not invoke or interpretmise bootstrap. - Project repositories still own their source code, tests, installers, service definitions, and product-specific onboarding.
Repository discovery, clone or synchronization, status, and command fan-out are
shared ecosystem primitives rather than Base's differentiation. See
Tool Boundaries for the dated comparison, including
when to choose mise, mani, gita, vcs2l, Android Repo, or west instead.
Reusable Bash Libraries
Base's reusable Bash libraries are also available as a standalone package for scripts that want Base's Bash helper conventions without adopting the Base local operating contract:
brew trust basefoundry/base
brew install basefoundry/base/base-bash-libs
Base consumes reusable Bash libraries from an external base-bash-libs checkout
or Homebrew package. The resolution order, standalone usage path, and
post-migration boundary are documented in
Base Bash Libraries.
Product Layers And Shipped Commands
The full command and runtime reference lives in the focused documentation:
- Command Quick Reference — current commands, flags, output formats, and detailed command behavior.
- Technical Overview — product model, workspace shape, manifest contract, architecture, and implementation boundaries.
This README keeps the product overview and first-run path above; use the focused references when you need command or runtime detail.
The top-level public command inventory remains visible here:
basectl setup [project]basectl checkbasectl doctorbasectl clean --older-than <age>basectl config <path|show|doctor>basectl update-profilebasectl updatebasectl projects listbasectl workspace <status|check|doctor|onboarding|agent-brief|clone|pull|update|init|configure|setup>basectl trust <status|allow|revoke>basectl repo <init|clone|check|configure|agent-guidance|installer-template>basectl gh <area> <command>basectl release <check|plan|notes|publish>basectl prompt <list|product-self-review>basectl activate <project>basectl test [project]basectl build [project] [target...]basectl demo [project]basectl run [project] <command>basectl export-context [project]basectl devcontainer [project]basectl devenv-report [project]basectl docsbasectl onboardbasectl history [--report]basectl version
Public Command Surface
Base exposes its own commands through $BASE_HOME/bin. That directory is added
to PATH by Base's managed shell startup snippets.
bin/basectl is the control-plane command. Additional Base-owned public
commands, when needed, are tiny real launcher files in bin/ that delegate to
basectl; their implementation remains under
cli/bash/commands/<command>/ or, in the future,
cli/python/commands/<command>/.
Example launcher for a hypothetical Base-owned Bash command:
#!/usr/bin/env bash
exec "$(dirname "\$0")/basectl" example "$@"
Projects expose their own commands through $PROJECT_ROOT/bin. When
basectl activate <project> starts a project runtime shell, Base adds that
directory to PATH if it exists, behind $BASE_HOME/bin and behind any
detected optional Base Platform Tools checkout. Project Python command packages
should be treated as implementation details unless a project-owned launcher
exposes them from bin/.
Optional utility commands live in
basefoundry/base-platform-tools.
When that repository is checked out next to Base as base-platform-tools, Base
adds its bin/ directory to PATH in new Bash/Zsh shells and Base runtime
shells. This is detected dynamically by the sourced shell snippets; users do not
need to rerun basectl update-profile after checking out the optional repo.
Project launchers that need to run Python packages should delegate through
base-wrapper so they use the selected project virtual environment and Base's
Python library roots:
#!/usr/bin/env bash
exec "$BASE_HOME/bin/base-wrapper" --project "${BASE_PROJECT:-example}" example_cli "$@"
basectl setup deliberately pins its default Homebrew Python formula so setup is
reproducible across machines. The current default is python@3.13. Override it
with BASE_SETUP_PYTHON_FORMULA when a workspace needs a different formula.
After this Bash bootstrap layer creates Base's own Python environment, setup
installs Base bootstrap Python packages into that environment. Shell-only
project reconciliation runs from that Base runtime and does not copy those
packages into a project venv. Projects that explicitly declare python: or a
python-package artifact keep the project-runtime path: Base first seeds the
target project venv with bootstrap: true default artifacts and then invokes
the Python project setup layer through base-wrapper --project <project>.
Prerequisite profiles are opt-in. Use --profile dev to install Base
contributor tools from lib/base/dev_manifest.yaml. On macOS that includes
Homebrew-managed BATS, GitHub CLI, and ShellCheck. On Ubuntu/Debian it installs
Base-owned apt-backed tools such as BATS and ShellCheck. It installs GitHub CLI
from GitHub CLI's official Debian/Ubuntu apt repository/keyring instead of the
default distro package; authentication remains user-owned. Use --profile sre
for the initial site-reliability profile in
lib/base/sre_manifest.yaml, which installs local diagnostic tools such as
kubectl, helm, k9s, httpie, grpcurl, jq, yq, nmap, and mtr.
Use --profile ai for optional AI coding tools: Codex CLI and Claude Code.
Use --profile linux-lab on a macOS host to install and check Multipass for
local Ubuntu lab VMs. Profiles compose with a comma-separated list.
basectl setup --profile dev
basectl setup --profile sre
basectl setup --profile ai
basectl setup --profile linux-lab --dry-run
basectl setup --profile linux-lab
basectl setup --profile dev,sre
basectl setup --profile dev,ai
basectl setup --profile dev,linux-lab
basectl check --profile sre
basectl check --profile ai
basectl check --profile linux-lab
basectl doctor --profile sre
basectl doctor --profile ai
basectl doctor --profile linux-lab
AI coding tools are intentionally not part of the plain dev or sre profile.
basectl setup --profile ai uses official remote installers only when that
profile is explicitly requested. Base checks tool presence and version output,
but it does not manage accounts, credentials, model access, or organization
policy.
The linux-lab profile is intentionally host-scoped. It installs or checks the
Multipass CLI on macOS through brew install --cask multipass, but Base does
not create, start, mount, or delete Multipass instances during setup. Review
the planned install with --dry-run, then create lab VMs with
multipass launch when you are ready.
For the complete Homebrew, Codex CLI, Claude Code, uv, and mise installer inventory; the distinction between consent and integrity; dry-run behavior; and managed-device checksum guidance, see Remote Installer Policy.
Setup intentionally stays serial for mutating installers and state writes until
Base has a setup-plan/preflight layer that can prove safe concurrency boundaries.
See basectl setup parallelism.
On macOS, basectl setup sends a best-effort notification when setup completes
or fails after running for at least 30 seconds. Notifications are skipped during
--dry-run and never change the setup exit status. Use basectl setup --notify
to force a notification for quick runs, basectl setup --no-notify or
BASE_SETUP_NOTIFY=false to disable notifications, and
BASE_SETUP_NOTIFY_MIN_SECONDS to tune the default threshold. When --notify
is requested on macOS, Base warns if osascript is not available.
Installation Details
This is the canonical README summary of the supported installation paths. For complete, copy-pasteable recipes, safety disclosures, and edge cases, see First-Mile Bootstrap.
First-Mile Bootstrap
Use bootstrap.sh on a blank or uncertain macOS machine. It can select an
existing Base install, install through Homebrew, or prepare a source checkout.
On Ubuntu/Debian it prints the manual source-checkout handoff instead of running
apt automatically. Review the --dry-run output before applying system or
remote-installer changes; use --source, --brew, or the narrower
--ensure-bash mode when needed.
Homebrew
Use the full formula name basefoundry/base/base for Homebrew installs and
upgrades. If Homebrew asks you to trust the tap, run brew trust basefoundry/base before retrying. Homebrew owns the installed files while
Base's local runtime remains under ~/.base.d; basectl update delegates
Base upgrades to Homebrew.
See the Homebrew install recipe and Remote Installer Policy for the complete trust and upgrade contract.
Source Checkout
Use a source checkout for contribution or dogfooding. The canonical recipe
installs from ~/work/base (or a chosen path) and keeps profile integration
opt-in. For a stable no-Homebrew install, pin the published release:
curl -fsSL https://raw.githubusercontent.com/basefoundry/base/v1.8.0/install.sh \
| bash -s -- --branch v1.8.0
Contributor installs may explicitly follow HEAD/main. See the
stable source install recipe,
source checkout install recipe,
and First-Mile Bootstrap for the exact commands.
After Installation
All installation paths prepare the local Base runtime under ~/.base.d and
leave shell startup integration opt-in. Setup creates
~/.base.d/config.yaml with a default workspace.root of ~/work; set it
to the shared directory that contains your repositories. Add Base to future
interactive shells only after reviewing the marked-section behavior of
basectl update-profile; see Shell Startup Files.
Version Identity
VERSION is the latest published release identity. DEVELOPMENT_VERSION is
the numeric next development line. A clean tagged release or packaged install
reports the clean VERSION, while a mutable Git checkout—including a dirty
checkout based on a release tag—reports
DEVELOPMENT_VERSION-dev+g<short-sha> and appends .dirty when local changes
are present. For example, Base 1.8.0 and mutable development code targeting
1.9.0 cannot report the same identity.
Project-specific onboarding should live in project installers that call Base
internally. basectl onboard [project] can run Base's setup/check/doctor flow
for a selected project, but product-specific setup still belongs in scripts such
as banyanlabs/install.sh. See Project Installers
for the recommended boundary.
Documentation
The top-level README is the product overview and first-run guide. The docs README is the map for architecture, runtime behavior, feature designs, and ecosystem boundary decisions.
Key starting points:
- FAQ
- Command Quick Reference
- Technical Overview
- Base Newcomer Orientation
- Architecture
- Clean macOS Install Validation
- Execution Model
- Runtime Environment
- Tool Boundaries
- Doctor Finding IDs
- IDE Bootstrapping
- Local Config
- Project Demo Workflow
Compatibility
Base is macOS-first, with Ubuntu/Debian runtime support now included in the tested support contract.
Intended supported platforms are:
- macOS 14 Sonoma or newer on Apple Silicon
- macOS 14 Sonoma or newer on Intel Macs
- Ubuntu/Debian runtime environments with apt-backed Base setup
The supported macOS version floor is macOS 14 Sonoma. Support means Base is tested and expected to work on macOS 14 or newer with Homebrew's supported install contract, Xcode Command Line Tools, a Homebrew-managed Bash, Git, and Python installed through Base setup. Older macOS releases may work from source, but they are outside Base's tested support contract.
Ubuntu/Debian support currently covers runtime checks, project diagnostics, source-checkout validation, and apt-backed setup for the simple prerequisites Base owns. Linux setup remains narrower than macOS setup and should stay behind the platform-policy boundary described in docs/linux-support.md. Windows is out of scope.
The macOS CI floor runs on GitHub's macos-14 runner. Newer macOS runners may
be added for coverage, but the floor job should stay until Base intentionally
raises the support floor.
OS-specific behavior should stay isolated behind small helpers instead of being
scattered through command code. For example, the Base runtime prompt can prefer
macOS scutil names while still falling back to generic hostname.
Shell Startup Files
Base integrates with Bash and Zsh through marked sections in your real dotfiles;
it never takes over whole files. basectl update-profile creates or refreshes
the managed sections, preserving unrelated content and writing a timestamped
sibling backup before changing an existing file.
By default, it updates ~/.bash_profile, ~/.bashrc, ~/.zprofile, and
~/.zshrc. Use basectl update-profile --remove to remove only Base-managed
sections, or --dry-run to preview changes. The detailed file-by-file contract,
debugging guidance, and optional defaults are in
Shell Startup Files.
Optional Utility Tools
Base no longer owns general-purpose utility CLIs such as caff and
sort-in-place. Those tools live in
basefoundry/base-platform-tools,
which is the optional platform/SRE utility layer for Base-managed workspaces.
Check it out next to Base to make its launchers available automatically in new
shells:
git clone https://github.com/basefoundry/base-platform-tools.git ~/work/base-platform-tools
exec "$SHELL" -l
The Base control-plane surface remains basectl.
Current Status
Base 1.8.0 is the current release. The implemented command surface covers
setup, checks, diagnostics, project discovery, project activation, project test
execution, manifest-declared mise trust/missing-tool checks plus mise install
and mise run delegation, cleanup, updates, onboarding, repository baseline
creation, CI-safe setup/check/doctor entry points, release readiness inspection,
guarded GitHub release publishing, GitHub workflow helpers, workspace
status/check/doctor/onboarding/init/clone/pull/configure flows, privacy-conscious
history reports, local AI context exports, repo-owned prompt rendering, the
basectl docs documentation shortcut, external reusable Bash library
consumption, and explicit prerequisite profiles for developer, SRE, AI tooling,
and local Linux lab setup. The basectl setup, basectl check, and basectl doctor flows are platform-aware for macOS and Ubuntu/Debian, including
apt-backed prerequisite handling on Ubuntu/Debian; macOS diagnostics also warn
when Homebrew reports outdated or incomplete Xcode Command Line Tools.
For the documentation map and naming convention, see
docs/README.md. For accepted product requirements, see
docs/product-requirements.md. For the
architecture and product direction, see
docs/architecture.md. For the current basectl runtime
and dispatch contract, see docs/execution-model.md.
For ecosystem boundary and integration decisions, see
docs/tool-boundaries.md.
Release notes are tracked in CHANGELOG.md, and upcoming work is tracked in GitHub Issues using the workflow in docs/github-workflow.md.
License
Base is licensed under Apache-2.0 starting with v1.9.0.
Versions v1.0.1 through v1.8.0 remain available under AGPL-3.0-or-later, and versions through v1.0.0 remain available under the MIT License as originally published. See LICENSE for the current license terms.