# Monorepo Strategy — Patrick's Homelab Workshop

*Written: 2026-04-04 | Authors: Patrick + Lumen*

---

## 1. Why This Document Exists

The repo started as `pi_mcps` — a home for Python MCP servers. Then two older Java web projects arrived: `mss-failsafe` and `Wellmann-Shop`. This is not an accident — it's the beginning of a pattern: a single place to keep all of Patrick's personal engineering work, regardless of language.

This document defines the strategy for the repo so that both of us — human and AI — can navigate it without confusion now and in two years from now.

---

## 2. Philosophy: Polyglot Monorepo, Not a Dump

A **monorepo is not code colocation**. The key principle from [monorepo.tools](https://monorepo.tools/): projects must have **well-defined relationships** and **clear boundaries**. What we are building is closer to a *workshop* — a curated collection of distinct tools and projects under one roof, organized by language/purpose, each independently buildable and deployable.

**We are NOT:**
- Sharing dependencies across Java and Python (they live in entirely separate ecosystems)
- Using a monorepo build tool like Nx or Turborepo (overkill for a personal homelab)
- Creating a monolith (each project is independently deployable)

**We ARE:**
- Keeping one git history (single place to look for all changes)
- Using a clear directory taxonomy to signal *what kind of thing* each project is
- Making it easy for an AI (Lumen) or a new contributor to orient quickly
- Preventing repo sprawl — one Gitea repo instead of a dozen

---

## 3. Repo Rename: `pi_mcps` → `workshop`

The name `pi_mcps` no longer describes what the repo contains. It was named for Raspberry Pi MCP servers — neither of which is accurate anymore (Fedora homelab, not Pi; more than just MCP servers).

**Proposed new name:** `workshop`

Why `workshop`?
- Neutral, language-agnostic
- Conveys personal creative output (not corporate, not framework-specific)
- Short, memorable
- Maps well to `http://192.168.188.119:30008/pplate/workshop`

**Action required:**
1. Rename the Gitea repo at `http://192.168.188.119:30008/pplate/pi_mcps` → `workshop`
2. Update the local remote: `git remote set-url origin http://192.168.188.119:30008/pplate/workshop.git`
3. The local folder on disk can stay as `~/pi_mcps/` or be renamed to `~/workshop/` — Patrick's choice. The folder name and repo name do not need to match.

---

## 4. Directory Taxonomy

Every directory at the repo root belongs to one of three categories:

| Category | Directory | Purpose |
|---|---|---|
| Language group | `mcp/` | Python MCP servers — FastMCP, uv, pytest |
| Language group | `java/` | Java web projects — Maven, Jakarta EE |
| Tooling/Config | `.roo/` | IDE config, Roo mode rules, MCP wiring |
| Tooling/Config | `plans/` | Architecture plans, assessments, strategy docs |
| Root files | `README.md`, `.gitignore` | Navigation index + polyglot ignores |

**Future language groups (when they arrive):**

| Directory | Purpose |
|---|---|
| `ts/` | TypeScript MCP servers or web frontends |
| `go/` | Go utilities or services |
| `scripts/` | Shell/Python one-off automation |

### 4.1 Full Target Structure

```
workshop/
├── mcp/                        # Python MCP servers
│   ├── bigmind/                # BigMind persistent memory server
│   │   ├── src/server.py
│   │   ├── bigmind/            # library code
│   │   ├── tests/
│   │   ├── pyproject.toml
│   │   └── run.sh
│   └── webscraper/             # Web scraping MCP server
│       ├── src/server.py
│       ├── tests/
│       ├── pyproject.toml
│       └── run.sh
│
├── java/                       # Java web projects
│   ├── mss-failsafe/           # MSS Failsafe (Java EE multi-module, WildFly)
│   │   ├── mssfailsafeWeblayer/
│   │   ├── userManagement/
│   │   └── pom.xml
│   └── wellmann-shop/          # Wellmann Shop (JSF/PrimeFaces, Java 8, MySQL)
│       ├── src/
│       └── pom.xml
│
├── plans/                      # Architecture plans and strategy docs
│   └── REPO_STRATEGY.md        # this file
│
├── .roo/                       # Roo Code IDE configuration
│   ├── mcp.json                # MCP server wiring (paths updated post-move)
│   └── rules-*/                # Per-mode Roo rules
│
├── .gitignore                  # Polyglot: Python + Java + Node + OS
└── README.md                   # Navigation index (the front door)
```

---

## 5. Naming Conventions

Consistency matters — both for humans and for AI tools reading directory listings.

| Rule | Convention | Rationale |
|---|---|---|
| Directory names | `kebab-case` | Unix-friendly, consistent across all languages |
| Java project dirs | `kebab-case` matching Maven `artifactId` | No surprise mapping needed |
| Python package dirs | `kebab-case` at group level, `snake_case` inside for Python modules | PEP 8 inside, Unix outside |
| Plan files | `UPPER_SNAKE.md` in `plans/` | Stands out from code files |
| README per project | Required | Each project is independently comprehensible |

**Normalization needed:**
- `Wellmann-Shop/` → `java/wellmann-shop/` (lowercase the W, move under `java/`)
- `mss-failsafe/` → `java/mss-failsafe/` (already correct name, just needs moving)
- `bigmind/` → `mcp/bigmind/`
- `webscraper/` → `mcp/webscraper/`

---

## 6. Language-Specific Rules

### 6.1 Python (mcp/)

- Package manager: **uv** (already standardized)
- Framework: **FastMCP** for all MCP servers
- Testing: **pytest** with `pytest-mock` and `pytest-cov`
- Each server is an **independent Python package** with its own `pyproject.toml` and `.venv`
- No shared `requirements.txt` at root — dependency isolation is a feature
- Run pattern: `cd mcp/bigmind && ./run.sh`

### 6.2 Java (java/)

- Build tool: **Maven** (both existing projects use it)
- Java version: Currently Java 8 (Wellmann-Shop) and unspecified (mss-failsafe — legacy NetBeans project)
- **Future Java projects should target Java 21+** (current LTS)
- Each project has its own `pom.xml` — no shared parent POM at root (cross-language root POMs are an antipattern)
- Target servers: WildFly / Payara / GlassFish (Jakarta EE)
- No shared Maven `settings.xml` needed — use standard `~/.m2/settings.xml`

### 6.3 Future: TypeScript (ts/)

- Package manager: **npm** or **pnpm**
- Framework: **FastMCP** (TypeScript flavor) for MCP servers
- Each project has its own `package.json`

---

## 7. .gitignore Strategy

The root `.gitignore` must cover all languages in the repo. Currently it only covers Python. After the reorganization, it must also cover:

**To add:**
```gitignore
# Java / Maven
target/
*.class
*.war
*.jar
*.ear
*.nar
.classpath
.project
.settings/
nb-configuration.xml
nbactions.xml
*.iml

# Node / TypeScript (future)
node_modules/
dist/
*.js.map
package-lock.json

# Test coverage
.coverage
coverage.xml
htmlcov/
```

**Note:** `nb-configuration.xml` is NetBeans IDE config — already present in `mss-failsafe/` and `Wellmann-Shop/`. It should be in `.gitignore` for new projects but is intentionally tracked here since it carries build configuration for legacy projects.

---

## 8. IDE Wiring: `.roo/mcp.json` After Move

The webscraper path in `.roo/mcp.json` currently points to `/home/pplate/pi_mcps/webscraper`. After moving to `mcp/webscraper/`, it must be updated:

**Before:**
```json
"webscraper": {
  "args": ["run", "--directory", "/home/pplate/pi_mcps/webscraper", "src/server.py"]
}
```

**After:**
```json
"webscraper": {
  "args": ["run", "--directory", "/home/pplate/pi_mcps/mcp/webscraper", "src/server.py"]
}
```

*(If the local folder is also renamed to `workshop/`, the path changes to `/home/pplate/workshop/mcp/webscraper`)*

The same applies to any external MCP configs (e.g., IntelliJ/PyCharm `mcp.json` files stored outside this repo).

---

## 9. README.md — The Front Door

The root `README.md` should function as a **navigation index**, not a tutorial. Readers (Patrick, Lumen, future contributors) should land there and know exactly where to go within 10 seconds.

**Structure:**
```
# Workshop — Patrick Plate's Homelab Monorepo

## What's Here
[table: project name | language | description | status]

## MCP Servers (mcp/)
[short list with links]

## Java Projects (java/)
[short list with links]

## Plans & Architecture
[link to plans/]

## Gitea
[link to homelab Gitea]
```

---

## 10. Migration Plan (Ordered Steps)

```
Step 1: Rename Gitea repo pi_mcps → workshop (Gitea UI)
Step 2: Update local git remote URL
Step 3: Move mcp/bigmind ← bigmind/
Step 4: Move mcp/webscraper ← webscraper/
Step 5: Move java/mss-failsafe ← mss-failsafe/
Step 6: Move java/wellmann-shop ← Wellmann-Shop/ (normalize name)
Step 7: Update .roo/mcp.json webscraper path
Step 8: Update any external MCP configs pointing to old paths
Step 9: Expand .gitignore with Java + Node patterns
Step 10: Rewrite root README.md as navigation index
Step 11: git add -A && git commit -m "chore: reorganize into polyglot monorepo structure"
Step 12: git push origin master
```

**Important:** Git tracks renames as move+add. Using `git mv` preserves file history. Use it for each moved file/directory.

---

## 11. Branching Strategy

### 11.1 The One Rule

**Never commit directly to `main`.** Every session that touches code or plans starts by creating a branch. Branches are cheap. Broken main history is not.

### 11.2 Branch Naming Convention

Format: `type/scope/short-description`

| Type | When |
|---|---|
| `feat` | New feature, new MCP server, new tool |
| `fix` | Bug fix |
| `docs` | Documentation, plans, strategy files only |
| `chore` | Refactoring, config, CI, build tooling |
| `spike` | Experimental / throwaway exploration |

**Scope** = the affected project area:

| Scope | Covers |
|---|---|
| `bigmind` | mcp/bigmind — the memory MCP server |
| `webscraper` | mcp/webscraper |
| `cannamanage` | future CannaManage Java project |
| `workshop` | repo-level changes (README, .gitignore, structure) |
| `roo` | .roo/ — IDE config, modes, skills, rules |
| `plans` | plans/ — architecture docs only |
| `homelab` | TrueNAS, Docker Compose, infrastructure |

**Examples:**
```
feat/bigmind/people-contacts
fix/bigmind/health-check-bugs
docs/plans/cannamanage-strategy
chore/workshop/monorepo-reorganize
feat/webscraper/ssl-cert-fallback
chore/roo/branching-strategy
```

### 11.3 Workflow

```
Session starts
  └─ git checkout -b feat/scope/name     ← ALWAYS first step

Work happens, commits stack up on the branch

Session ends / feature complete
  └─ git push origin feat/scope/name
  └─ (optional) open Gitea PR for review
  └─ git checkout main && git merge --no-ff feat/scope/name
  └─ git push origin main
```

### 11.4 Lumen's Responsibility

In every homelab session, Lumen must:
1. Check `git branch --show-current` before first edit
2. If on `main` → create a branch before touching any file
3. Include the branch name in `memory_announce_focus()`
4. Use the [`gitea-push skill`](.roo/skills/gitea-push/SKILL.md) which enforces the branch guard

The mode rules for `mcp-builder`, `bigmind`, and `homelab` all include this step explicitly.

---

## 12. What We Are NOT Doing

It's worth being explicit about choices we considered and rejected:

| Considered | Decision | Reason |
|---|---|---|
| Separate repo per project | Rejected | Polyrepo tax: fragmented history, harder for AI context |
| Nx / Turborepo monorepo tools | Rejected | Overkill for personal homelab; adds tooling complexity without benefit |
| Shared Maven parent POM at root | Rejected | Java-specific tooling at repo root would confuse Python tooling |
| Keeping `pi_mcps` name | Reconsidered | The name no longer describes the content; `workshop` is future-proof |
| `src/` at root with language subdirs | Rejected | Less clear at a glance than top-level `mcp/`, `java/` groupings |

---

## 13. Visual Overview

```mermaid
graph TD
    Root[workshop/] --> MCP[mcp/]
    Root --> Java[java/]
    Root --> Plans[plans/]
    Root --> Roo[.roo/]
    Root --> GI[.gitignore]
    Root --> RM[README.md]

    MCP --> BM[bigmind/]
    MCP --> WS[webscraper/]
    MCP --> FutMCP[future MCP servers...]

    Java --> MSS[mss-failsafe/]
    Java --> WSh[wellmann-shop/]
    Java --> FutJava[future Java projects...]

    Plans --> STRAT[REPO_STRATEGY.md]
    Plans --> FutPlans[future plans...]
```

---

*This document is the living reference for how this repo is organized. Update it when structure changes.*
