base-demo is the compact representative environment for Base-managed
projects.
It should sit between a toy sample and Banyan Labs. It borrows the shape of a medium-sized engineering organization, but keeps each service intentionally small so the focus stays on Base orchestration, build tools, runtime diversity, and operational workflow.
The three repos have distinct roles:
| Repo | Role |
|---|---|
base |
Workspace and tooling control plane. Base owns setup, activation, project commands, checks, build/test delegation, and repo workflow support. |
base-demo |
Reduced-scale representative environment. It shows how Base manages a credible multi-language, infrastructure-backed project without deep product behavior. |
banyanlabs |
Full platform engineering lab. It is where product behavior, operational depth, observability, delivery, Kubernetes, IaC, and cloud patterns earn their complexity. |
base-demo should build confidence for Banyan Labs without becoming Banyan
Labs. Its services should be boring on purpose: health checks, hello responses,
metadata, documented ports, and simple build/test paths.
A non-trivial Go/Cobra CLI does not belong in the current baseline demo. The baseline already includes a tiny Go HTTP API so Base can demonstrate Go build and test orchestration without adding another required tool shape to first-run setup.
If Base needs a deeper CLI example later, prefer a separate base-demo-go
repository or a clearly optional advanced slice that is not required by
BASE_DEMO_ENV=baseline, Quick Start, or read-only CI. Any later
implementation should use Go's standard toolchain and Cobra only when command
structure is complex enough to justify it.
The target stack is broad enough to feel real and small enough to inspect:
| Area | Representative choice | Intent |
|---|---|---|
| Python | Tiny Python HTTP API on port 8020 plus the existing Python CLI | Demonstrate Python as both project command and app service runtime. |
| Go | Tiny Go HTTP API on port 8010 | Demonstrate Go service development and native test/build flow. |
| Docker | Dockerized Go service through Compose | Make Docker first-class without containerizing every app service. |
| Java | One Gradle service on port 8030 and one Maven service on port 8040 | Demonstrate common Java build tools without Spring-scale complexity. |
| C | Tiny native service on port 8050 | Represent lower-level compiled components. |
| C++ | Tiny native service on port 8060 | Represent C++ service/tooling presence in a mixed environment. |
| JavaScript UI | React + Vite demo console on port 8070 | Provide a common frontend framework and human-facing operational surface. |
| Databases | Postgres and MySQL through Compose | Represent common data dependencies without cross-service dependency complexity. |
| Cache | Redis through Compose | Represent cache infrastructure as a local dependency pattern. |
Each app service should expose the same small HTTP surface when practical:
/healthz/hello/info
The point is not business logic. The point is that Base can see, run, test, build, and explain a realistic mix of tools.
The main operator surface should be one manifest command:
basectl run base-demo services -- status
basectl run base-demo services -- start
basectl run base-demo services -- stop
basectl run base-demo services -- restart
basectl run base-demo services -- check
basectl run base-demo services -- logsThe command should read a catalog rather than hard-code each service in the script. The catalog should be the source of truth for service name, kind, runtime/tooling, port, health URL, start/stop behavior, and whether the service is required for a given environment.
The status view should answer the practical local questions:
- what is supposed to exist
- what is running
- where it is listening
- what runtime or tool it represents
- how health is checked
- where logs live, or how to find them
- when available, since when it has been running
Postgres, MySQL, and Redis should be representative dependencies, not a cross-service architecture exercise.
Only one or two later services may demonstrate a tiny database or cache probe if that makes the infrastructure visible. Most services should remain independent health/hello/info fixtures. This keeps the environment credible while avoiding a fake distributed-system dependency graph.
Compose should manage local infrastructure. The language build tools should still remain visible through native build and test commands.
The local infrastructure layer is:
| Name | Kind | Port | Scope |
|---|---|---|---|
postgres |
Database | 5432 | Local dev, representative dependency |
mysql |
Database | 3306 | Local dev, representative dependency |
redis |
Cache | 6379 | Local dev, representative dependency |
These dependencies are optional for services check until they are started.
That keeps the default validation path stable on machines without Docker while
still giving the main demo a real Compose-backed infrastructure surface.
The first Dockerized application fixture is services/go-api. It exposes
/healthz, /hello, and /info on port 8010 and is registered in both
services/catalog.json and infra/compose.yaml.
The first native process fixture is services/python-api. It exposes the same
endpoint shape on port 8020 using only Python's standard library and is managed
by the services command through a small process lifecycle entry in the
catalog.
The Java fixtures are intentionally split between services/java-gradle-api
and services/java-maven-api. The services both use the JDK built-in HTTP
server and expose the same endpoint shape; the distinction is the build tool,
because both Gradle and Maven are common enough to be first-class in a
representative IT environment.
The native fixtures are services/c-service and services/cpp-service. They
use small Makefiles and command-level health checks to avoid adding C/C++ HTTP
frameworks solely for the demo. Their /healthz, /hello, and /info behavior
is still visible through the compiled binaries and the shared services catalog.
The UI fixture is services/demo-console, a React/Vite operational console that
reads the checked-in service catalog copy generated from services/catalog.json.
It is deliberately a dashboard surface, not a product app; the catalog remains
the source of truth.
base-demo should model three environments:
environments/
dev.json
staging.json
prod.json
Only dev is operational by default. staging and prod are checked-in
configuration examples that demonstrate separation of ports, URLs, image tags,
database/cache names, and logging mode.
The files use JSON so the demo can validate them with Python's standard library instead of adding a YAML dependency solely for configuration parsing.
This is deliberate. A real deployable staging/prod story belongs in Banyan Labs.
base-demo should teach the shape of environment-aware configuration without
requiring cloud accounts, Kubernetes, Terraform, or secret management.
The representative stack should be part of the main demo, not hidden behind an advanced path.
The walkthrough shows:
- Base project discovery and setup.
- Manifest-declared commands.
- Environment configuration.
- Service catalog status.
- Build/test delegation across runtimes.
- Service catalog checks across optional local dependencies and fixtures.
- Local infrastructure and service startup through a dry-run lifecycle path.
- React/Vite console registration as the human-facing view.
- Build-target discovery for every representative service.
The default validation path should remain stable. Heavy checks can be skipped with a clear message when Docker or a language toolchain is unavailable, but the repo shape and command contracts should always be validated.
CI runs the representative BATS suites, validates all environment files, checks
the service catalog through Base, and exercises service startup with
BASE_DEMO_SERVICES_DRY_RUN=1. That gives the main demo and CI the same
operator surface without requiring every dependency to stay running during a
baseline validation run.
The implementation moved one issue at a time:
| Issue | Slice |
|---|---|
| #62 | Define and publish this representative environment direction. |
| #63 | Add the service catalog and services lifecycle command. |
| #64 | Add the dev, staging, and prod environment model. |
| #65 | Add Compose-backed Postgres, MySQL, and Redis. |
| #66 | Add the Go API service and Docker image fixture. |
| #67 | Add the Python API service fixture. |
| #68 | Add Java Gradle and Maven service fixtures. |
| #69 | Add C and C++ service fixtures. |
| #70 | Add the React/Vite service console UI. |
| #71 | Integrate the representative environment into demo validation and CI. |
Each PR should keep the demo runnable, update docs when command behavior
changes, and preserve the issue-first workflow from AGENTS.md.