002 — Monorepo Consolidation
Context
The RENEWA team works across ~15 repos on GitHub, Azure DevOps, and Bitbucket. While setting up the shared knowledge base (see 001-knowledge-base-setup), several pain points with multi-repo separation surfaced:
-
Cross-repo friction for Claude sessions. Adding a 5-line CLAUDE.md section to 4 repos required 4 branches, 3 PRs, 1 manual Azure DevOps push, different auth mechanisms, and different branch protection rules.
-
Scheduled ingestion is fragmented. A Claude sweep to update the knowledge base needs to authenticate to multiple repos, clone each, traverse different structures, merge findings, then push to yet another repo. Every additional repo multiplies auth surface and failure modes.
-
Linear integration is wired to bookish-broccoli + fluffy-doodle, but the knowledge base lives in renewa-knowledge-base. Cross-repo event propagation (issue closed → wiki updated) requires webhooks or scheduled sweeps across repo boundaries.
-
Design specs and plans are repo-specific (bookish-broccoli’s
.planning/,docs/superpowers/specs/). The knowledge base can’t see them directly — it needs a separate Claude session to read, summarize, and push. -
Issue tracking is split between bookish-broccoli and fluffy-doodle (“check both repos” is an explicit rule in CLAUDE.md). This exists because non-dev team members needed issue access without GitHub seats — but Linear now serves that role.
-
The triage bot (MS Teams → fluffy-doodle → Linear) posts GitHub URLs that colleagues can’t access without paid seats. Flipping this to Teams → Linear directly gives everyone usable URLs.
Why separation made sense historically
- Humans can’t hold context across many repos simultaneously — clear boundaries reduce cognitive overload
- Mixed concerns (app code + docs + infra) create noisy git history and CI coupling
- Different access control needs (devs vs. non-devs, sensitive infra vs. public docs)
Why the ground has shifted
- Claude eliminates the cognitive overload argument. It reads, greps, and navigates a large repo instantly. Multi-repo creates MORE work for Claude (auth, sync, cross-repo references) than a single large repo.
- Path-filtered CI (
on: push: paths: ['backend/**']) eliminates the CI coupling concern. A wiki commit doesn’t trigger app CI and vice versa. - Nested CLAUDE.md files allow per-directory context. Each subdirectory gets its own CLAUDE.md with scope-specific rules — no giant monolithic file needed.
- GitHub CODEOWNERS provides per-directory access control within a single repo.
- Linear replaces GitHub Issues as the team-facing interface, removing the need for a separate issues-only repo (fluffy-doodle).
- Auto-merge workflows solve path-scoped branch protection. Wiki-only PRs get auto-approved and auto-merged (~30 seconds), while app code PRs require real review.
Options considered
Option 1: Keep separate repos (status quo)
Pros: clear boundaries, independent CI, independent access control. Cons: cross-repo friction for every Claude session, scheduled sweep complexity, fragmented issue tracking, auth multiplication for remote agents.
Option 2: Git submodules
Pros: repos appear together in one directory.
Cons: worst of both worlds — still separate repos underneath (same auth friction), plus submodule-specific pain (pinned SHAs, --recurse-submodules on every clone, detached HEAD on branch switch, worktree incompatibility). Solves a different problem (vendoring versioned dependencies).
Option 3: Git subtree
Pros: real files in one repo, can push changes back to source repo. Cons: bidirectional sync adds cognitive overhead. If consolidating, pushing back to the source is unnecessary — just work in the monorepo. Marginal benefit over a clean move.
Option 4: Incremental monorepo consolidation (chosen)
Pros: one repo = one auth = one clone for Claude sessions. Path-filtered CI. Nested CLAUDE.md. Auto-merge for wiki-only changes. Linear handles team-facing issue tracking. Cons: Actions tab gets noisier (cosmetic, manageable with naming prefixes). GitHub doesn’t support path-scoped branch protection natively (solved by auto-merge workflow).
Decision
Incremental monorepo consolidation. Move repos into bookish-broccoli one at a time. Each phase is a single, reversible change. No big-bang migration.
Phased approach
Phase 0 (done): Knowledge base launched as standalone repo renewa-gmbh/renewa-knowledge-base. Proves the concept, establishes conventions, deployed to wiki.renewa.de.
Phase 1 (next): Consolidate issue tracking.
- Update triage bot: MS Teams → Linear (directly), not MS Teams → fluffy-doodle → Linear. Bot replies with Linear URLs (accessible to everyone, no GitHub seat needed).
- Migrate open fluffy-doodle issues to bookish-broccoli.
- Update Linear sync to point at bookish-broccoli only.
- Remove “check both repos” rule from bookish-broccoli’s CLAUDE.md.
- Archive fluffy-doodle.
Phase 2 (when Phase 1 is stable): Consolidate knowledge base.
- Move
renewa-knowledge-basecontent intobookish-broccoli/knowledge-base/as a directory. - Add nested
knowledge-base/CLAUDE.mdwith wiki-specific rules. - Update Cloudflare Pages to build from the subdirectory.
- Add auto-merge GitHub Action for wiki-only PRs.
- Archive the standalone renewa-knowledge-base repo.
Phase 3 (when Phase 2 is stable): Evaluate remaining repos.
- Assess whether
config(Cloudflare/Terraform IaC) belongs in the monorepo. Likely stays separate — different security requirements (Terraform state, cloud credentials, blast radius). - Assess craftcms — different tech stack (PHP), different team, likely stays separate.
- CRM (Azure DevOps) — stays separate (different platform entirely).
What stays separate (and why)
| Repo | Platform | Why separate |
|---|---|---|
| CRM | Azure DevOps | Different platform, different team, Dataverse ecosystem |
| config | GitHub | IaC security (Terraform state, cloud credentials, high blast radius) |
| craftcms / craftcms-energieheld | GitHub | Different tech stack (PHP), different deployment pipeline |
| google-appscript, jira-automation | Bitbucket | Legacy integrations, minimal active development |
These repos get Knowledge Base sections in their CLAUDE.md files pointing to the consolidated wiki, but they don’t move into the monorepo.
Consequences
- Scheduled Claude remote sessions work with a single repo clone and single auth token
- Knowledge base ingestion becomes local file operations (no cross-repo auth)
- Issue tracking simplified: one GitHub repo + Linear as team interface
- Actions tab gets noisier (~25 workflows) — mitigated by naming prefixes (
[App],[Wiki], etc.) - Path-scoped branch protection gap solved by auto-merge workflow for wiki-only PRs
- Each phase is independently reversible if problems emerge
- Nested CLAUDE.md files keep context scoped and manageable (no giant monolithic CLAUDE.md)
- fluffy-doodle archived (existing URLs in old MS Teams messages still resolve since the repo isn’t deleted, just archived)
Participants
Martin von Schledorn (decision lead), Claude (analysis). 2026-04-17.