provisioning/docs/book/architecture/multi-repo-strategy.html
Jesús Pérez 6a59d34bb1
chore: update provisioning configuration and documentation
Update configuration files, templates, and internal documentation
for the provisioning repository system.

Configuration Updates:
- KMS configuration modernization
- Plugin system settings
- Service port mappings
- Test cluster topologies
- Installation configuration examples
- VM configuration defaults
- Cedar authorization policies

Documentation Updates:
- Library module documentation
- Extension API guides
- AI system documentation
- Service management guides
- Test environment setup
- Plugin usage guides
- Validator configuration documentation

All changes are backward compatible.
2025-12-11 21:50:42 +00:00

1123 lines
47 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE HTML>
<html lang="en" class="ayu sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Multi-Repo Strategy - Provisioning Platform Documentation</title>
<!-- Custom HTML head -->
<meta name="description" content="Complete documentation for the Provisioning Platform - Infrastructure automation with Nushell, KCL, and Rust">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" id="highlight-css" href="../highlight.css">
<link rel="stylesheet" id="tomorrow-night-css" href="../tomorrow-night.css">
<link rel="stylesheet" id="ayu-highlight-css" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<!-- Provide site root and default themes to javascript -->
<script>
const path_to_root = "../";
const default_light_theme = "ayu";
const default_dark_theme = "navy";
</script>
<!-- Start loading toc.js asap -->
<script src="../toc.js"></script>
</head>
<body>
<div id="mdbook-help-container">
<div id="mdbook-help-popup">
<h2 class="mdbook-help-title">Keyboard shortcuts</h2>
<div>
<p>Press <kbd></kbd> or <kbd></kbd> to navigate between chapters</p>
<p>Press <kbd>S</kbd> or <kbd>/</kbd> to search in the book</p>
<p>Press <kbd>?</kbd> to show this help</p>
<p>Press <kbd>Esc</kbd> to hide this help</p>
</div>
</div>
</div>
<div id="body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
let theme = localStorage.getItem('mdbook-theme');
let sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
let theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('ayu')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
let sidebar = null;
const sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
</noscript>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="default_theme">Auto</button></li>
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search (`/`)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="/ s" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Provisioning Platform Documentation</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/provisioning/provisioning-platform" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://github.com/provisioning/provisioning-platform/edit/main/provisioning/docs/src/architecture/multi-repo-strategy.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="multi-repository-strategy-analysis"><a class="header" href="#multi-repository-strategy-analysis">Multi-Repository Strategy Analysis</a></h1>
<p><strong>Date:</strong> 2025-10-01
<strong>Status:</strong> Strategic Analysis
<strong>Related:</strong> <a href="repo-dist-analysis.html">Repository Distribution Analysis</a></p>
<h2 id="executive-summary"><a class="header" href="#executive-summary">Executive Summary</a></h2>
<p>This document analyzes a <strong>multi-repository strategy</strong> as an alternative to the monorepo approach. After careful consideration of the provisioning systems architecture, a <strong>hybrid approach with 4 core repositories</strong> is recommended, avoiding submodules in favor of a cleaner package-based dependency model.</p>
<hr />
<h2 id="repository-architecture-options"><a class="header" href="#repository-architecture-options">Repository Architecture Options</a></h2>
<h3 id="option-a-pure-monorepo-original-recommendation"><a class="header" href="#option-a-pure-monorepo-original-recommendation">Option A: Pure Monorepo (Original Recommendation)</a></h3>
<p><strong>Single repository:</strong> <code>provisioning</code></p>
<p><strong>Pros:</strong></p>
<ul>
<li>Simplest development workflow</li>
<li>Atomic cross-component changes</li>
<li>Single version number</li>
<li>One CI/CD pipeline</li>
</ul>
<p><strong>Cons:</strong></p>
<ul>
<li>Large repository size</li>
<li>Mixed language tooling (Rust + Nushell)</li>
<li>All-or-nothing updates</li>
<li>Unclear ownership boundaries</li>
</ul>
<h3 id="option-b-multi-repo-with-submodules--not-recommended"><a class="header" href="#option-b-multi-repo-with-submodules--not-recommended">Option B: Multi-Repo with Submodules (❌ Not Recommended)</a></h3>
<p><strong>Repositories:</strong></p>
<ul>
<li><code>provisioning-core</code> (main, contains submodules)</li>
<li><code>provisioning-platform</code> (submodule)</li>
<li><code>provisioning-extensions</code> (submodule)</li>
<li><code>provisioning-workspace</code> (submodule)</li>
</ul>
<p><strong>Why Not Recommended:</strong></p>
<ul>
<li>Submodule hell: complex, error-prone workflows</li>
<li>Detached HEAD issues</li>
<li>Update synchronization nightmares</li>
<li>Clone complexity for users</li>
<li>Difficult to maintain version compatibility</li>
<li>Poor developer experience</li>
</ul>
<h3 id="option-c-multi-repo-with-package-dependencies--recommended"><a class="header" href="#option-c-multi-repo-with-package-dependencies--recommended">Option C: Multi-Repo with Package Dependencies (✅ RECOMMENDED)</a></h3>
<p><strong>Independent repositories with package-based integration:</strong></p>
<ul>
<li><code>provisioning-core</code> - Nushell libraries and KCL schemas</li>
<li><code>provisioning-platform</code> - Rust services (orchestrator, control-center, MCP)</li>
<li><code>provisioning-extensions</code> - Extension marketplace/catalog</li>
<li><code>provisioning-workspace</code> - Project templates and examples</li>
<li><code>provisioning-distribution</code> - Release automation and packaging</li>
</ul>
<p><strong>Why Recommended:</strong></p>
<ul>
<li>Clean separation of concerns</li>
<li>Independent versioning and release cycles</li>
<li>Language-specific tooling and workflows</li>
<li>Clear ownership boundaries</li>
<li>Package-based dependencies (no submodules)</li>
<li>Easier community contributions</li>
</ul>
<hr />
<h2 id="recommended-multi-repo-architecture"><a class="header" href="#recommended-multi-repo-architecture">Recommended Multi-Repo Architecture</a></h2>
<h3 id="repository-1-provisioning-core"><a class="header" href="#repository-1-provisioning-core">Repository 1: <code>provisioning-core</code></a></h3>
<p><strong>Purpose:</strong> Core Nushell infrastructure automation engine</p>
<p><strong>Contents:</strong></p>
<pre><code>provisioning-core/
├── nulib/ # Nushell libraries
│ ├── lib_provisioning/ # Core library functions
│ ├── servers/ # Server management
│ ├── taskservs/ # Task service management
│ ├── clusters/ # Cluster management
│ └── workflows/ # Workflow orchestration
├── cli/ # CLI entry point
│ └── provisioning # Pure Nushell CLI
├── kcl/ # KCL schemas
│ ├── main.k
│ ├── settings.k
│ ├── server.k
│ ├── cluster.k
│ └── workflows.k
├── config/ # Default configurations
│ └── config.defaults.toml
├── templates/ # Core templates
├── tools/ # Build and packaging tools
├── tests/ # Core tests
├── docs/ # Core documentation
├── LICENSE
├── README.md
├── CHANGELOG.md
└── version.toml # Core version file
</code></pre>
<p><strong>Technology:</strong> Nushell, KCL
<strong>Primary Language:</strong> Nushell
<strong>Release Frequency:</strong> Monthly (stable)
<strong>Ownership:</strong> Core team
<strong>Dependencies:</strong> None (foundation)</p>
<p><strong>Package Output:</strong></p>
<ul>
<li><code>provisioning-core-{version}.tar.gz</code> - Installable package</li>
<li>Published to package registry</li>
</ul>
<p><strong>Installation Path:</strong></p>
<pre><code>/usr/local/
├── bin/provisioning
├── lib/provisioning/
└── share/provisioning/
</code></pre>
<hr />
<h3 id="repository-2-provisioning-platform"><a class="header" href="#repository-2-provisioning-platform">Repository 2: <code>provisioning-platform</code></a></h3>
<p><strong>Purpose:</strong> High-performance Rust platform services</p>
<p><strong>Contents:</strong></p>
<pre><code>provisioning-platform/
├── orchestrator/ # Rust orchestrator
│ ├── src/
│ ├── tests/
│ ├── benches/
│ └── Cargo.toml
├── control-center/ # Web control center (Leptos)
│ ├── src/
│ ├── tests/
│ └── Cargo.toml
├── mcp-server/ # Model Context Protocol server
│ ├── src/
│ ├── tests/
│ └── Cargo.toml
├── api-gateway/ # REST API gateway
│ ├── src/
│ ├── tests/
│ └── Cargo.toml
├── shared/ # Shared Rust libraries
│ ├── types/
│ └── utils/
├── docs/ # Platform documentation
├── Cargo.toml # Workspace root
├── Cargo.lock
├── LICENSE
├── README.md
└── CHANGELOG.md
</code></pre>
<p><strong>Technology:</strong> Rust, WebAssembly
<strong>Primary Language:</strong> Rust
<strong>Release Frequency:</strong> Bi-weekly (fast iteration)
<strong>Ownership:</strong> Platform team
<strong>Dependencies:</strong></p>
<ul>
<li><code>provisioning-core</code> (runtime integration, loose coupling)</li>
</ul>
<p><strong>Package Output:</strong></p>
<ul>
<li><code>provisioning-platform-{version}.tar.gz</code> - Binaries</li>
<li>Binaries for: Linux (x86_64, arm64), macOS (x86_64, arm64)</li>
</ul>
<p><strong>Installation Path:</strong></p>
<pre><code>/usr/local/
├── bin/
│ ├── provisioning-orchestrator
│ └── provisioning-control-center
└── share/provisioning/platform/
</code></pre>
<p><strong>Integration with Core:</strong></p>
<ul>
<li>Platform services call <code>provisioning</code> CLI via subprocess</li>
<li>No direct code dependencies</li>
<li>Communication via REST API and file-based queues</li>
<li>Core and Platform can be deployed independently</li>
</ul>
<hr />
<h3 id="repository-3-provisioning-extensions"><a class="header" href="#repository-3-provisioning-extensions">Repository 3: <code>provisioning-extensions</code></a></h3>
<p><strong>Purpose:</strong> Extension marketplace and community modules</p>
<p><strong>Contents:</strong></p>
<pre><code>provisioning-extensions/
├── registry/ # Extension registry
│ ├── index.json # Searchable index
│ └── catalog/ # Extension metadata
├── providers/ # Additional cloud providers
│ ├── azure/
│ ├── gcp/
│ ├── digitalocean/
│ └── hetzner/
├── taskservs/ # Community task services
│ ├── databases/
│ │ ├── mongodb/
│ │ ├── redis/
│ │ └── cassandra/
│ ├── development/
│ │ ├── gitlab/
│ │ ├── jenkins/
│ │ └── sonarqube/
│ └── observability/
│ ├── prometheus/
│ ├── grafana/
│ └── loki/
├── clusters/ # Cluster templates
│ ├── ml-platform/
│ ├── data-pipeline/
│ └── gaming-backend/
├── workflows/ # Workflow templates
├── tools/ # Extension development tools
├── docs/ # Extension development guide
├── LICENSE
└── README.md
</code></pre>
<p><strong>Technology:</strong> Nushell, KCL
<strong>Primary Language:</strong> Nushell
<strong>Release Frequency:</strong> Continuous (per-extension)
<strong>Ownership:</strong> Community + Core team
<strong>Dependencies:</strong></p>
<ul>
<li><code>provisioning-core</code> (extends core functionality)</li>
</ul>
<p><strong>Package Output:</strong></p>
<ul>
<li>Individual extension packages: <code>provisioning-ext-{name}-{version}.tar.gz</code></li>
<li>Registry index for discovery</li>
</ul>
<p><strong>Installation:</strong></p>
<pre><code class="language-bash"># Install extension via core CLI
provisioning extension install mongodb
provisioning extension install azure-provider
</code></pre>
<p><strong>Extension Structure:</strong>
Each extension is self-contained:</p>
<pre><code>mongodb/
├── manifest.toml # Extension metadata
├── taskserv.nu # Implementation
├── templates/ # Templates
├── kcl/ # KCL schemas
├── tests/ # Tests
└── README.md
</code></pre>
<hr />
<h3 id="repository-4-provisioning-workspace"><a class="header" href="#repository-4-provisioning-workspace">Repository 4: <code>provisioning-workspace</code></a></h3>
<p><strong>Purpose:</strong> Project templates and starter kits</p>
<p><strong>Contents:</strong></p>
<pre><code>provisioning-workspace/
├── templates/ # Workspace templates
│ ├── minimal/ # Minimal starter
│ ├── kubernetes/ # Full K8s cluster
│ ├── multi-cloud/ # Multi-cloud setup
│ ├── microservices/ # Microservices platform
│ ├── data-platform/ # Data engineering
│ └── ml-ops/ # MLOps platform
├── examples/ # Complete examples
│ ├── blog-deployment/
│ ├── e-commerce/
│ └── saas-platform/
├── blueprints/ # Architecture blueprints
├── docs/ # Template documentation
├── tools/ # Template scaffolding
│ └── create-workspace.nu
├── LICENSE
└── README.md
</code></pre>
<p><strong>Technology:</strong> Configuration files, KCL
<strong>Primary Language:</strong> TOML, KCL, YAML
<strong>Release Frequency:</strong> Quarterly (stable templates)
<strong>Ownership:</strong> Community + Documentation team
<strong>Dependencies:</strong></p>
<ul>
<li><code>provisioning-core</code> (templates use core)</li>
<li><code>provisioning-extensions</code> (may reference extensions)</li>
</ul>
<p><strong>Package Output:</strong></p>
<ul>
<li><code>provisioning-templates-{version}.tar.gz</code></li>
</ul>
<p><strong>Usage:</strong></p>
<pre><code class="language-bash"># Create workspace from template
provisioning workspace init my-project --template kubernetes
# Or use separate tool
gh repo create my-project --template provisioning-workspace
cd my-project
provisioning workspace init
</code></pre>
<hr />
<h3 id="repository-5-provisioning-distribution"><a class="header" href="#repository-5-provisioning-distribution">Repository 5: <code>provisioning-distribution</code></a></h3>
<p><strong>Purpose:</strong> Release automation, packaging, and distribution infrastructure</p>
<p><strong>Contents:</strong></p>
<pre><code>provisioning-distribution/
├── release-automation/ # Automated release workflows
│ ├── build-all.nu # Build all packages
│ ├── publish.nu # Publish to registries
│ └── validate.nu # Validation suite
├── installers/ # Installation scripts
│ ├── install.nu # Nushell installer
│ ├── install.sh # Bash installer
│ └── install.ps1 # PowerShell installer
├── packaging/ # Package builders
│ ├── core/
│ ├── platform/
│ └── extensions/
├── registry/ # Package registry backend
│ ├── api/ # Registry REST API
│ └── storage/ # Package storage
├── ci-cd/ # CI/CD configurations
│ ├── github/ # GitHub Actions
│ ├── gitlab/ # GitLab CI
│ └── jenkins/ # Jenkins pipelines
├── version-management/ # Cross-repo version coordination
│ ├── versions.toml # Version matrix
│ └── compatibility.toml # Compatibility matrix
├── docs/ # Distribution documentation
│ ├── release-process.md
│ └── packaging-guide.md
├── LICENSE
└── README.md
</code></pre>
<p><strong>Technology:</strong> Nushell, Bash, CI/CD
<strong>Primary Language:</strong> Nushell, YAML
<strong>Release Frequency:</strong> As needed
<strong>Ownership:</strong> Release engineering team
<strong>Dependencies:</strong> All repositories (orchestrates releases)</p>
<p><strong>Responsibilities:</strong></p>
<ul>
<li>Build packages from all repositories</li>
<li>Coordinate multi-repo releases</li>
<li>Publish to package registries</li>
<li>Manage version compatibility</li>
<li>Generate release notes</li>
<li>Host package registry</li>
</ul>
<hr />
<h2 id="dependency-and-integration-model"><a class="header" href="#dependency-and-integration-model">Dependency and Integration Model</a></h2>
<h3 id="package-based-dependencies-not-submodules"><a class="header" href="#package-based-dependencies-not-submodules">Package-Based Dependencies (Not Submodules)</a></h3>
<pre><code>┌─────────────────────────────────────────────────────────────┐
│ provisioning-distribution │
│ (Release orchestration &amp; registry) │
└──────────────────────────┬──────────────────────────────────┘
│ publishes packages
┌──────────────┐
│ Registry │
└──────┬───────┘
┌──────────────────┼──────────────────┐
↓ ↓ ↓
┌───────────────┐ ┌──────────────┐ ┌──────────────┐
│ provisioning │ │ provisioning │ │ provisioning │
│ -core │ │ -platform │ │ -extensions │
└───────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
│ │ depends on │ extends
│ └─────────┐ │
│ ↓ │
└───────────────────────────────────→┘
runtime integration
</code></pre>
<h3 id="integration-mechanisms"><a class="header" href="#integration-mechanisms">Integration Mechanisms</a></h3>
<h4 id="1-core--platform-integration"><a class="header" href="#1-core--platform-integration">1. <strong>Core ↔ Platform Integration</strong></a></h4>
<p><strong>Method:</strong> Loose coupling via CLI + REST API</p>
<pre><code class="language-nushell"># Platform calls Core CLI (subprocess)
def create-server [name: string] {
# Orchestrator executes Core CLI
^provisioning server create $name --infra production
}
# Core calls Platform API (HTTP)
def submit-workflow [workflow: record] {
http post http://localhost:9090/workflows/submit $workflow
}
</code></pre>
<p><strong>Version Compatibility:</strong></p>
<pre><code class="language-toml"># platform/Cargo.toml
[package.metadata.provisioning]
core-version = "^3.0" # Compatible with core 3.x
</code></pre>
<h4 id="2-core--extensions-integration"><a class="header" href="#2-core--extensions-integration">2. <strong>Core ↔ Extensions Integration</strong></a></h4>
<p><strong>Method:</strong> Plugin/module system</p>
<pre><code class="language-nushell"># Extension manifest
# extensions/mongodb/manifest.toml
[extension]
name = "mongodb"
version = "1.0.0"
type = "taskserv"
core-version = "^3.0"
[dependencies]
provisioning-core = "^3.0"
# Extension installation
# Core downloads and validates extension
provisioning extension install mongodb
# → Downloads from registry
# → Validates compatibility
# → Installs to ~/.provisioning/extensions/mongodb
</code></pre>
<h4 id="3-workspace-templates"><a class="header" href="#3-workspace-templates">3. <strong>Workspace Templates</strong></a></h4>
<p><strong>Method:</strong> Git templates or package templates</p>
<pre><code class="language-bash"># Option 1: GitHub template repository
gh repo create my-infra --template provisioning-workspace
cd my-infra
provisioning workspace init
# Option 2: Template package
provisioning workspace create my-infra --template kubernetes
# → Downloads template package
# → Scaffolds workspace
# → Initializes configuration
</code></pre>
<hr />
<h2 id="version-management-strategy"><a class="header" href="#version-management-strategy">Version Management Strategy</a></h2>
<h3 id="semantic-versioning-per-repository"><a class="header" href="#semantic-versioning-per-repository">Semantic Versioning Per Repository</a></h3>
<p>Each repository maintains independent semantic versioning:</p>
<pre><code>provisioning-core: 3.2.1
provisioning-platform: 2.5.3
provisioning-extensions: (per-extension versioning)
provisioning-workspace: 1.4.0
</code></pre>
<h3 id="compatibility-matrix"><a class="header" href="#compatibility-matrix">Compatibility Matrix</a></h3>
<p><strong><code>provisioning-distribution/version-management/versions.toml</code>:</strong></p>
<pre><code class="language-toml"># Version compatibility matrix
[compatibility]
# Core versions and compatible platform versions
[compatibility.core]
"3.2.1" = { platform = "^2.5", extensions = "^1.0", workspace = "^1.0" }
"3.2.0" = { platform = "^2.4", extensions = "^1.0", workspace = "^1.0" }
"3.1.0" = { platform = "^2.3", extensions = "^0.9", workspace = "^1.0" }
# Platform versions and compatible core versions
[compatibility.platform]
"2.5.3" = { core = "^3.2", min-core = "3.2.0" }
"2.5.0" = { core = "^3.1", min-core = "3.1.0" }
# Release bundles (tested combinations)
[bundles]
[bundles.stable-3.2]
name = "Stable 3.2 Bundle"
release-date = "2025-10-15"
core = "3.2.1"
platform = "2.5.3"
extensions = ["mongodb@1.2.0", "redis@1.1.0", "azure@2.0.0"]
workspace = "1.4.0"
[bundles.lts-3.1]
name = "LTS 3.1 Bundle"
release-date = "2025-09-01"
lts-until = "2026-09-01"
core = "3.1.5"
platform = "2.4.8"
workspace = "1.3.0"
</code></pre>
<h3 id="release-coordination"><a class="header" href="#release-coordination">Release Coordination</a></h3>
<p><strong>Coordinated releases</strong> for major versions:</p>
<pre><code class="language-bash"># Major release: All repos release together
provisioning-core: 3.0.0
provisioning-platform: 2.0.0
provisioning-workspace: 1.0.0
# Minor/patch releases: Independent
provisioning-core: 3.1.0 (adds features, platform stays 2.0.x)
provisioning-platform: 2.1.0 (improves orchestrator, core stays 3.1.x)
</code></pre>
<hr />
<h2 id="development-workflow"><a class="header" href="#development-workflow">Development Workflow</a></h2>
<h3 id="working-on-single-repository"><a class="header" href="#working-on-single-repository">Working on Single Repository</a></h3>
<pre><code class="language-bash"># Developer working on core only
git clone https://github.com/yourorg/provisioning-core
cd provisioning-core
# Install dependencies
just install-deps
# Development
just dev-check
just test
# Build package
just build
# Test installation locally
just install-dev
</code></pre>
<h3 id="working-across-repositories"><a class="header" href="#working-across-repositories">Working Across Repositories</a></h3>
<pre><code class="language-bash"># Scenario: Adding new feature requiring core + platform changes
# 1. Clone both repositories
git clone https://github.com/yourorg/provisioning-core
git clone https://github.com/yourorg/provisioning-platform
# 2. Create feature branches
cd provisioning-core
git checkout -b feat/batch-workflow-v2
cd ../provisioning-platform
git checkout -b feat/batch-workflow-v2
# 3. Develop with local linking
cd provisioning-core
just install-dev # Installs to /usr/local/bin/provisioning
cd ../provisioning-platform
# Platform uses system provisioning CLI (local dev version)
cargo run
# 4. Test integration
cd ../provisioning-core
just test-integration
cd ../provisioning-platform
cargo test
# 5. Create PRs in both repositories
# PR #123 in provisioning-core
# PR #456 in provisioning-platform (references core PR)
# 6. Coordinate merge
# Merge core PR first, cut release 3.3.0
# Update platform dependency to core 3.3.0
# Merge platform PR, cut release 2.6.0
</code></pre>
<h3 id="testing-cross-repo-integration"><a class="header" href="#testing-cross-repo-integration">Testing Cross-Repo Integration</a></h3>
<pre><code class="language-bash"># Integration tests in provisioning-distribution
cd provisioning-distribution
# Test specific version combination
just test-integration \
--core 3.3.0 \
--platform 2.6.0
# Test bundle
just test-bundle stable-3.3
</code></pre>
<hr />
<h2 id="distribution-strategy"><a class="header" href="#distribution-strategy">Distribution Strategy</a></h2>
<h3 id="individual-repository-releases"><a class="header" href="#individual-repository-releases">Individual Repository Releases</a></h3>
<p>Each repository releases independently:</p>
<pre><code class="language-bash"># Core release
cd provisioning-core
git tag v3.2.1
git push --tags
# → GitHub Actions builds package
# → Publishes to package registry
# Platform release
cd provisioning-platform
git tag v2.5.3
git push --tags
# → GitHub Actions builds binaries
# → Publishes to package registry
</code></pre>
<h3 id="bundle-releases-coordinated"><a class="header" href="#bundle-releases-coordinated">Bundle Releases (Coordinated)</a></h3>
<p>Distribution repository creates tested bundles:</p>
<pre><code class="language-bash">cd provisioning-distribution
# Create bundle
just create-bundle stable-3.2 \
--core 3.2.1 \
--platform 2.5.3 \
--workspace 1.4.0
# Test bundle
just test-bundle stable-3.2
# Publish bundle
just publish-bundle stable-3.2
# → Creates meta-package with all components
# → Publishes bundle to registry
# → Updates documentation
</code></pre>
<h3 id="user-installation-options"><a class="header" href="#user-installation-options">User Installation Options</a></h3>
<h4 id="option-1-bundle-installation-recommended-for-users"><a class="header" href="#option-1-bundle-installation-recommended-for-users">Option 1: Bundle Installation (Recommended for Users)</a></h4>
<pre><code class="language-bash"># Install stable bundle (easiest)
curl -fsSL https://get.provisioning.io | sh
# Installs:
# - provisioning-core 3.2.1
# - provisioning-platform 2.5.3
# - provisioning-workspace 1.4.0
</code></pre>
<h4 id="option-2-individual-component-installation"><a class="header" href="#option-2-individual-component-installation">Option 2: Individual Component Installation</a></h4>
<pre><code class="language-bash"># Install only core (minimal)
curl -fsSL https://get.provisioning.io/core | sh
# Add platform later
provisioning install platform
# Add extensions
provisioning extension install mongodb
</code></pre>
<h4 id="option-3-custom-combination"><a class="header" href="#option-3-custom-combination">Option 3: Custom Combination</a></h4>
<pre><code class="language-bash"># Install specific versions
provisioning install core@3.1.0
provisioning install platform@2.4.0
</code></pre>
<hr />
<h2 id="repository-ownership-and-contribution-model"><a class="header" href="#repository-ownership-and-contribution-model">Repository Ownership and Contribution Model</a></h2>
<h3 id="core-team-ownership"><a class="header" href="#core-team-ownership">Core Team Ownership</a></h3>
<div class="table-wrapper"><table><thead><tr><th>Repository</th><th>Primary Owner</th><th>Contribution Model</th></tr></thead><tbody>
<tr><td><code>provisioning-core</code></td><td>Core Team</td><td>Strict review, stable API</td></tr>
<tr><td><code>provisioning-platform</code></td><td>Platform Team</td><td>Fast iteration, performance focus</td></tr>
<tr><td><code>provisioning-extensions</code></td><td>Community + Core</td><td>Open contributions, moderated</td></tr>
<tr><td><code>provisioning-workspace</code></td><td>Docs Team</td><td>Template contributions welcome</td></tr>
<tr><td><code>provisioning-distribution</code></td><td>Release Engineering</td><td>Core team only</td></tr>
</tbody></table>
</div>
<h3 id="contribution-workflow"><a class="header" href="#contribution-workflow">Contribution Workflow</a></h3>
<p><strong>For Core:</strong></p>
<ol>
<li>Create issue in <code>provisioning-core</code></li>
<li>Discuss design</li>
<li>Submit PR with tests</li>
<li>Strict code review</li>
<li>Merge to <code>main</code></li>
<li>Release when ready</li>
</ol>
<p><strong>For Extensions:</strong></p>
<ol>
<li>Create extension in <code>provisioning-extensions</code></li>
<li>Follow extension guidelines</li>
<li>Submit PR</li>
<li>Community review</li>
<li>Merge and publish to registry</li>
<li>Independent versioning</li>
</ol>
<p><strong>For Platform:</strong></p>
<ol>
<li>Create issue in <code>provisioning-platform</code></li>
<li>Implement with benchmarks</li>
<li>Submit PR</li>
<li>Performance review</li>
<li>Merge and release</li>
</ol>
<hr />
<h2 id="cicd-strategy"><a class="header" href="#cicd-strategy">CI/CD Strategy</a></h2>
<h3 id="per-repository-cicd"><a class="header" href="#per-repository-cicd">Per-Repository CI/CD</a></h3>
<p><strong>Core CI (<code>provisioning-core/.github/workflows/ci.yml</code>):</strong></p>
<pre><code class="language-yaml">name: Core CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Nushell
run: cargo install nu
- name: Run tests
run: just test
- name: Validate KCL schemas
run: just validate-kcl
package:
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v3
- name: Build package
run: just build
- name: Publish to registry
run: just publish
env:
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
</code></pre>
<p><strong>Platform CI (<code>provisioning-platform/.github/workflows/ci.yml</code>):</strong></p>
<pre><code class="language-yaml">name: Platform CI
on: [push, pull_request]
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Build
run: cargo build --release
- name: Test
run: cargo test --workspace
- name: Benchmark
run: cargo bench
cross-compile:
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v3
- name: Build for Linux x86_64
run: cargo build --release --target x86_64-unknown-linux-gnu
- name: Build for Linux arm64
run: cargo build --release --target aarch64-unknown-linux-gnu
- name: Publish binaries
run: just publish-binaries
</code></pre>
<h3 id="integration-testing-distribution-repo"><a class="header" href="#integration-testing-distribution-repo">Integration Testing (Distribution Repo)</a></h3>
<p><strong>Distribution CI (<code>provisioning-distribution/.github/workflows/integration.yml</code>):</strong></p>
<pre><code class="language-yaml">name: Integration Tests
on:
schedule:
- cron: '0 0 * * *' # Daily
workflow_dispatch:
jobs:
test-bundle:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install bundle
run: |
nu release-automation/install-bundle.nu stable-3.2
- name: Run integration tests
run: |
nu tests/integration/test-all.nu
- name: Test upgrade path
run: |
nu tests/integration/test-upgrade.nu 3.1.0 3.2.1
</code></pre>
<hr />
<h2 id="file-and-directory-structure-comparison"><a class="header" href="#file-and-directory-structure-comparison">File and Directory Structure Comparison</a></h2>
<h3 id="monorepo-structure"><a class="header" href="#monorepo-structure">Monorepo Structure</a></h3>
<pre><code>provisioning/ (One repo, ~500MB)
├── core/ (Nushell)
├── platform/ (Rust)
├── extensions/ (Community)
├── workspace/ (Templates)
└── distribution/ (Build)
</code></pre>
<h3 id="multi-repo-structure"><a class="header" href="#multi-repo-structure">Multi-Repo Structure</a></h3>
<pre><code>provisioning-core/ (Repo 1, ~50MB)
├── nulib/
├── cli/
├── kcl/
└── tools/
provisioning-platform/ (Repo 2, ~150MB with target/)
├── orchestrator/
├── control-center/
├── mcp-server/
└── Cargo.toml
provisioning-extensions/ (Repo 3, ~100MB)
├── registry/
├── providers/
├── taskservs/
└── clusters/
provisioning-workspace/ (Repo 4, ~20MB)
├── templates/
├── examples/
└── blueprints/
provisioning-distribution/ (Repo 5, ~30MB)
├── release-automation/
├── installers/
├── packaging/
└── registry/
</code></pre>
<hr />
<h2 id="decision-matrix"><a class="header" href="#decision-matrix">Decision Matrix</a></h2>
<div class="table-wrapper"><table><thead><tr><th>Criterion</th><th>Monorepo</th><th>Multi-Repo</th></tr></thead><tbody>
<tr><td><strong>Development Complexity</strong></td><td>Simple</td><td>Moderate</td></tr>
<tr><td><strong>Clone Size</strong></td><td>Large (~500MB)</td><td>Small (50-150MB each)</td></tr>
<tr><td><strong>Cross-Component Changes</strong></td><td>Easy (atomic)</td><td>Moderate (coordinated)</td></tr>
<tr><td><strong>Independent Releases</strong></td><td>Difficult</td><td>Easy</td></tr>
<tr><td><strong>Language-Specific Tooling</strong></td><td>Mixed</td><td>Clean</td></tr>
<tr><td><strong>Community Contributions</strong></td><td>Harder (big repo)</td><td>Easier (focused repos)</td></tr>
<tr><td><strong>Version Management</strong></td><td>Simple (one version)</td><td>Complex (matrix)</td></tr>
<tr><td><strong>CI/CD Complexity</strong></td><td>Simple (one pipeline)</td><td>Moderate (multiple)</td></tr>
<tr><td><strong>Ownership Clarity</strong></td><td>Unclear</td><td>Clear</td></tr>
<tr><td><strong>Extension Ecosystem</strong></td><td>Monolithic</td><td>Modular</td></tr>
<tr><td><strong>Build Time</strong></td><td>Long (build all)</td><td>Short (build one)</td></tr>
<tr><td><strong>Testing Isolation</strong></td><td>Difficult</td><td>Easy</td></tr>
</tbody></table>
</div>
<hr />
<h2 id="recommended-approach-multi-repo"><a class="header" href="#recommended-approach-multi-repo">Recommended Approach: Multi-Repo</a></h2>
<h3 id="why-multi-repo-wins-for-this-project"><a class="header" href="#why-multi-repo-wins-for-this-project">Why Multi-Repo Wins for This Project</a></h3>
<ol>
<li>
<p><strong>Clear Separation of Concerns</strong></p>
<ul>
<li>Nushell core vs Rust platform are different domains</li>
<li>Different teams can own different repos</li>
<li>Different release cadences make sense</li>
</ul>
</li>
<li>
<p><strong>Language-Specific Tooling</strong></p>
<ul>
<li><code>provisioning-core</code>: Nushell-focused, simple testing</li>
<li><code>provisioning-platform</code>: Rust workspace, Cargo tooling</li>
<li>No mixed tooling confusion</li>
</ul>
</li>
<li>
<p><strong>Community Contributions</strong></p>
<ul>
<li>Extensions repo is easier to contribute to</li>
<li>Dont need to clone entire monorepo</li>
<li>Clearer contribution guidelines per repo</li>
</ul>
</li>
<li>
<p><strong>Independent Versioning</strong></p>
<ul>
<li>Core can stay stable (3.x for months)</li>
<li>Platform can iterate fast (2.x weekly)</li>
<li>Extensions have own lifecycles</li>
</ul>
</li>
<li>
<p><strong>Build Performance</strong></p>
<ul>
<li>Only build what changed</li>
<li>Faster CI/CD per repo</li>
<li>Parallel builds across repos</li>
</ul>
</li>
<li>
<p><strong>Extension Ecosystem</strong></p>
<ul>
<li>Extensions repo becomes marketplace</li>
<li>Third-party extensions can live separately</li>
<li>Registry becomes discovery mechanism</li>
</ul>
</li>
</ol>
<h3 id="implementation-strategy"><a class="header" href="#implementation-strategy">Implementation Strategy</a></h3>
<p><strong>Phase 1: Split Repositories (Week 1-2)</strong></p>
<ol>
<li>Create 5 new repositories</li>
<li>Extract code from monorepo</li>
<li>Set up CI/CD for each</li>
<li>Create initial packages</li>
</ol>
<p><strong>Phase 2: Package Integration (Week 3)</strong></p>
<ol>
<li>Implement package registry</li>
<li>Create installers</li>
<li>Set up version compatibility matrix</li>
<li>Test cross-repo integration</li>
</ol>
<p><strong>Phase 3: Distribution System (Week 4)</strong></p>
<ol>
<li>Implement bundle system</li>
<li>Create release automation</li>
<li>Set up package hosting</li>
<li>Document release process</li>
</ol>
<p><strong>Phase 4: Migration (Week 5)</strong></p>
<ol>
<li>Migrate existing users</li>
<li>Update documentation</li>
<li>Archive monorepo</li>
<li>Announce new structure</li>
</ol>
<hr />
<h2 id="conclusion"><a class="header" href="#conclusion">Conclusion</a></h2>
<p><strong>Recommendation: Multi-Repository Architecture with Package-Based Integration</strong></p>
<p>The multi-repo approach provides:</p>
<ul>
<li>✅ Clear separation between Nushell core and Rust platform</li>
<li>✅ Independent release cycles for different components</li>
<li>✅ Better community contribution experience</li>
<li>✅ Language-specific tooling and workflows</li>
<li>✅ Modular extension ecosystem</li>
<li>✅ Faster builds and CI/CD</li>
<li>✅ Clear ownership boundaries</li>
</ul>
<p><strong>Avoid:</strong> Submodules (complexity nightmare)</p>
<p><strong>Use:</strong> Package-based dependencies with version compatibility matrix</p>
<p>This architecture scales better for your projects growth, supports a community extension ecosystem, and provides professional-grade separation of concerns while maintaining integration through a well-designed package system.</p>
<hr />
<h2 id="next-steps"><a class="header" href="#next-steps">Next Steps</a></h2>
<ol>
<li><strong>Approve multi-repo strategy</strong></li>
<li><strong>Create repository split plan</strong></li>
<li><strong>Set up GitHub organizations/teams</strong></li>
<li><strong>Implement package registry</strong></li>
<li><strong>Begin repository extraction</strong></li>
</ol>
<p>Would you like me to create a detailed <strong>repository split implementation plan</strong> next?</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../architecture/integration-patterns.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../architecture/orchestrator-integration-model.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../architecture/integration-patterns.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../architecture/orchestrator-integration-model.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<!-- Livereload script (if served using the cli tool) -->
<script>
const wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsAddress = wsProtocol + "//" + location.host + "/" + "__livereload";
const socket = new WebSocket(wsAddress);
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<script>
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js"></script>
<script src="../mark.min.js"></script>
<script src="../searcher.js"></script>
<script src="../clipboard.min.js"></script>
<script src="../highlight.js"></script>
<script src="../book.js"></script>
<!-- Custom JS scripts -->
</div>
</body>
</html>