Repo topology, baseline overlay, planning docs (PLAN-001/002), ADR-004/005, and the bootstrap/packages/documentation skeleton. Implementation (T00+) not started. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
153 lines
8.9 KiB
Markdown
153 lines
8.9 KiB
Markdown
# 000 — `olsitec-foundation` Repository Topology
|
|
|
|
> **Purpose**: define what lives where under `~/work/olsitec-foundation`, which directories are
|
|
> independent git repositories vs. one mono-repo, and how shared Pulumi modules are vendored now and
|
|
> consumed from the foundation later.
|
|
> **Status**: Active. **Companion**: [ADR-005](decisions/ADR_005_repo_topology.md),
|
|
> [PLAN-002](planning/PLAN-002-foundation-implementation.md).
|
|
|
|
---
|
|
|
|
## 1. The workspace root is NOT a git repo
|
|
|
|
`~/work/olsitec-foundation/` is a **workspace root**, following the Olsitec convention (baseline
|
|
PD-2: "the workspace root is usually not a git repository"). It holds **two** independent git
|
|
repositories:
|
|
|
|
```
|
|
~/work/olsitec-foundation/ # workspace root — NOT a git repo
|
|
├── foundation/ # GIT REPO #1 — the platform mono-repo (the DR unit)
|
|
└── ai-baseline/ # GIT REPO #2 — the cross-project agentic workflow pattern
|
|
```
|
|
|
|
Both repos are hosted in **foundation-Forgejo** once it exists
|
|
(`forge.olsitec.de/olsitec/foundation`, `forge.olsitec.de/olsitec/ai-baseline`). Until then they
|
|
live locally + an offsite git mirror (DR).
|
|
|
|
---
|
|
|
|
## 2. Why two repos (the mono-repo vs single-repo decision)
|
|
|
|
| Repo | Kind | Why this boundary |
|
|
|------|------|-------------------|
|
|
| **`foundation`** | **Mono-repo** (Bun workspaces) | The egg (`bootstrap/`) and the shared Pulumi modules it needs (`packages/`) **must be co-versioned and present without a registry at day-zero** (the registry doesn't exist yet — bootstrap paradox). One `git clone` = the full DR unit. Project docs travel with it. |
|
|
| **`ai-baseline`** | **Single small repo** | Consumed by **every** Olsitec project (foundation + all Layer-1 products), on an **independent release cadence**. It should not drag the platform's weight, and ADR-003 already specced it as standalone. |
|
|
|
|
**What is deliberately NOT in here:** downstream **consumer projects** (the existing olsicloud4 K8s
|
|
platform, products like seaspots, olsitrack2…). They are their own repos and consume the
|
|
foundation's **published** packages — they do not vendor or sit inside this workspace.
|
|
|
|
> Rule of thumb: **co-version what must boot together (mono-repo); separate what is consumed on its
|
|
> own cadence (its own repo + published artifact).**
|
|
|
|
---
|
|
|
|
## 3. `foundation` mono-repo layout
|
|
|
|
```
|
|
foundation/ # GIT REPO #1 (mono-repo, Bun workspaces)
|
|
├── package.json # workspace root (defines packages/* + bootstrap)
|
|
├── VERSIONS # pinned image+tool digests (determinism)
|
|
├── README.md
|
|
├── bootstrap/ # ── THE EGG ── single Pulumi project (DR unit core)
|
|
│ ├── Pulumi.yaml
|
|
│ ├── Pulumi.foundation.yaml # passphrase-encrypted config + secrets
|
|
│ ├── index.ts # phase orchestration
|
|
│ ├── components/ # network, postgres, rustfs, vault, credentials, proxy, forgejo, runner
|
|
│ ├── phases/ lib/ config.ts
|
|
│ └── config/ # template SOURCES (app.ini.tmpl, Caddyfile.tmpl, pg-init.sql)
|
|
├── packages/ # ── SHARED PULUMI MODULES ── each independently publishable
|
|
│ ├── pulumi-docker/ # @olsitec/pulumi-docker
|
|
│ ├── pulumi-vault/ # @olsitec/pulumi-vault
|
|
│ ├── pulumi-tls/ # @olsitec/pulumi-tls
|
|
│ ├── pulumi-hetzner/ # @olsitec/pulumi-hetzner
|
|
│ ├── pulumi-cloudflare/ # @olsitec/pulumi-cloudflare
|
|
│ ├── pulumi-rustfs/ # @olsitec/pulumi-rustfs (new)
|
|
│ ├── pulumi-postgres/ # @olsitec/pulumi-postgres (new)
|
|
│ ├── pulumi-forgejo/ # @olsitec/pulumi-forgejo (new)
|
|
│ ├── pulumi-caddy/ # @olsitec/pulumi-caddy (new)
|
|
│ └── pulumi-runner/ # @olsitec/pulumi-runner (new)
|
|
├── preflight/ # tooling/host validation
|
|
├── backup/ dr/ # backup + disaster-recovery automation
|
|
├── .forgejo/workflows/ # CI (preflight, pulumi preview/up, backup-verify)
|
|
└── documentation/ # ── PROJECT DOCS ── (this folder)
|
|
├── 000_TOPOLOGY.md # this file
|
|
├── 000_baseline.md # thin overlay → ai-baseline + foundation deviations
|
|
├── planning/ # PLAN-001 (vision), PLAN-002 (strategy)
|
|
├── decisions/ # ADRs (004 layered platform, 005 topology, …)
|
|
├── contracts/ agents/ sessions/ knowledge_base/ retrospectives/ _templates/
|
|
```
|
|
|
|
### Why `bootstrap/` and `packages/` share one repo
|
|
Day-zero, the egg cannot pull `@olsitec/pulumi-vault` from a registry — **the registry is part of
|
|
what it is building**. With Bun workspaces, `bootstrap/` resolves `@olsitec/pulumi-*` from
|
|
`packages/*` **locally on disk**. No registry needed to bootstrap. This is the concrete resolution of
|
|
the "registry hosts the modules that build the registry" paradox (PLAN-002 §5.2).
|
|
|
|
---
|
|
|
|
## 4. `ai-baseline` repo layout
|
|
|
|
```
|
|
ai-baseline/ # GIT REPO #2
|
|
├── 000_baseline.md # the CANONICAL full agentic baseline (single source of truth)
|
|
├── _templates/ # ADR, contract, session, snapshot templates
|
|
└── README.md # what this is + how projects consume it
|
|
```
|
|
|
|
This is ADR-003's `ai-baseline`, **re-homed from gitlab.com to foundation-Forgejo**. Every project's
|
|
`documentation/000_baseline.md` becomes a **thin overlay** that references this canonical file and
|
|
lists only project-specific deviations.
|
|
|
|
---
|
|
|
|
## 5. Module vendoring & distribution strategy
|
|
|
|
The lifecycle of a shared module has **three stages**:
|
|
|
|
```
|
|
STAGE 1 VENDOR (now) Copy the existing olsicloud4 module → foundation/packages/pulumi-<x>/.
|
|
Pin it. bootstrap/ consumes it via Bun workspace (local, no registry).
|
|
|
|
STAGE 2 PUBLISH (after egg) Once foundation-Forgejo npm registry is live, CI publishes each package
|
|
as @olsitec/pulumi-<x>@<semver> to it (semantic-release-monorepo,
|
|
Conventional Commits — see memory: olsitec-charts-conventional-commits).
|
|
|
|
STAGE 3 CONSUME (steady) Downstream projects switch their imports from the old
|
|
olsicloud4/pulumi/modules/<x> to @olsitec/pulumi-<x>@<version> pulled
|
|
from the foundation registry. The old modules are frozen, then removed.
|
|
```
|
|
|
|
This is exactly the user's intent: *"a copy placed there… later hosted via the foundation… existing
|
|
uses of vault modules will then use the module hosted from the foundation."*
|
|
|
|
### 5.1 Mapping: existing olsicloud4 module → foundation package
|
|
|
|
| `olsicloud4/pulumi/modules/<x>` | → `foundation/packages/` | Day-zero need | Notes |
|
|
|---|---|---|---|
|
|
| `docker` | `pulumi-docker` | **Yes** | Egg orchestration (`@pulumi/docker` over SSH). Reuse `DockerDeployments` wrapper. |
|
|
| `vault` | `pulumi-vault` | **Yes** | Includes `policy.ts`. Core of the secret layer. |
|
|
| `tls` | `pulumi-tls` | Maybe | Cert helpers; may defer to Caddy/Vault-PKI. |
|
|
| `hetzner` | `pulumi-hetzner` | Phase 0 | VM provisioning + offsite host. |
|
|
| `cloudflare` | `pulumi-cloudflare` | Networking | DNS records + ACME DNS-01 token. |
|
|
| `olsitec` | `pulumi-olsitec` | Partial | The `OlsitecProject` feature-flag component (ADR-002). Layer-1 oriented (K8s); the egg uses a lighter subset. Vendor for reference, refactor for Layer 0. |
|
|
| `minio` | — (superseded) | No | Foundation uses **RustFS**, not MinIO → new `pulumi-rustfs`. |
|
|
| `gitlab` | — (retired) | No | GitLab is what the foundation **replaces**. |
|
|
| `kubernetes`, `k3s`, `libvirt`, `baremetal` | — (Layer 1) | No | Belong to Layer-1 / legacy provisioning, not the egg. |
|
|
|
|
### 5.2 New packages (no existing module)
|
|
`pulumi-rustfs`, `pulumi-postgres`, `pulumi-forgejo`, `pulumi-caddy`, `pulumi-runner` — authored fresh
|
|
as foundation tasks (PLAN-002 §10: T03/T04/T05/T07/T08/T10).
|
|
|
|
> **Do not copy module code yet.** Stage-1 vendoring of `docker` + `vault` (+ `hetzner`, `cloudflare`)
|
|
> is a deliberate task with its own commit, to be done when T00 starts — not blindly bulk-copied with
|
|
> `node_modules`. This doc defines the destinations; the copy is gated on the contracts (T00).
|
|
|
|
---
|
|
|
|
## 6. DR implication
|
|
|
|
The DR unit is **the `foundation` mono-repo + master passphrase + offsite backup bundle** (PLAN-002
|
|
§6). Because `packages/` is inside the mono-repo, a single clone restores both the egg and the exact
|
|
module sources it was built from — no registry, no external module fetch required to recover.
|
|
`ai-baseline` is operationally useful but **not** required to recover the platform.
|