chore: scaffold olsitec-foundation mono-repo
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>
This commit is contained in:
commit
f18676e6b3
22 changed files with 1174 additions and 0 deletions
153
documentation/000_TOPOLOGY.md
Normal file
153
documentation/000_TOPOLOGY.md
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
# 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue