mirror of
https://github.com/blackboxprogramming/BlackRoad-Operating-System.git
synced 2026-03-18 03:33:59 -05:00
Make deployment safeguards safer - support temporary hybrid deployment
CONTEXT:
The monorepo IS being deployed temporarily to Railway (service: BlackRoad-Operating-System,
project: gregarious-wonder, domain: app.blackroad.systems) to get BR-95 desktop UI online
quickly while satellite infrastructure is being built. This is explicitly temporary.
This commit adds stronger safeguards that:
1. Acknowledge the temporary deployment
2. Prevent it from becoming permanent
3. Ensure migration plan exists and is tracked
4. Provide automated validation at multiple checkpoints
CHANGES:
1. TEMPORARY_DEPLOYMENT.md (NEW) - Complete Migration Plan
- Documents current temporary hybrid deployment
- Explains why temporary deployment was chosen
- Provides 4-phase migration plan to satellites
- Lists allowed temporary deviations
- Includes success metrics and governance
2. DEPLOYMENT_ARCHITECTURE.md - Updated with Hybrid Mode
- Added "Current Status: Temporary Hybrid Deployment" section
- Clarified current state vs target state
- Updated deployment status (temporarily deployed, should not be permanent)
- Added allowed temporary deviations
- Timeline for migration (6-10 weeks)
3. scripts/validate_deployment_config.py - Smarter Validation
- check_railway_toml(): Now distinguishes temporary vs permanent deployment
* Allows temporary deployment with warnings
* Errors on permanent deployment without "temporary" marker
* Checks for migration plan references
- check_env_files(): Context-aware validation
* Warnings for temporary monorepo URLs in ALLOWED_ORIGINS
* Errors for hardcoded monorepo URLs elsewhere
* Allows temporary deviations with migration warnings
- check_migration_plan(): NEW function
* Checks for TEMPORARY_DEPLOYMENT.md or MIGRATION_TO_SATELLITES.md
* Warns if temporary deployment lacks migration plan
- Better error messages with actionable guidance
4. .githooks/pre-commit (NEW) - Local Validation
- Runs validation script before each commit
- Checks railway.toml for "temporary" marker
- Scans staged files for hardcoded monorepo URLs
- Prevents accidental permanent deployment
- Bypassable with --no-verify if needed
5. .githooks/setup.sh (NEW) - Easy Hook Installation
- Configures Git to use .githooks/ directory
- Makes hooks executable
- Tests validation script
- User-friendly setup process
6. .githooks/README.md (NEW) - Hook Documentation
- Installation instructions
- Hook descriptions
- Troubleshooting guide
- Development guidelines
7. .github/workflows/validate-deployment-config.yml (NEW) - CI Validation
- Runs on PRs touching deployment configs
- Validates deployment configuration
- Checks for temporary markers
- Checks for migration plan
- Comments on PRs with results
- Prevents merge of invalid configs
SAFETY IMPROVEMENTS:
✅ BEFORE: Strict "never deploy monorepo" policy (unrealistic given current state)
✅ AFTER: Pragmatic "temporary OK, permanent forbidden" policy
✅ BEFORE: Manual validation only
✅ AFTER: Automated validation at 3 checkpoints (pre-commit, CI, validation script)
✅ BEFORE: No migration tracking
✅ AFTER: Complete migration plan with timeline and governance
✅ BEFORE: Binary pass/fail validation
✅ AFTER: Warnings vs errors based on context
VALIDATION RESULTS:
Expected output from validation script:
⚠️ WARNING: Monorepo is being deployed TEMPORARILY
⚠️ WARNING: Temporary monorepo reference in ALLOWED_ORIGINS
✅ PASSED: railway.toml acknowledges temporary monorepo deployment
✅ PASSED: Migration plan documentation exists
✅ PASSED: Satellite sync configuration complete
GOVERNANCE:
- Weekly reviews to track migration progress
- Monthly updates to TEMPORARY_DEPLOYMENT.md
- Automated reminders if migration stalls
- Hard deadline: 12 weeks to migrate or re-evaluate
USE CASES:
1. Developer adds monorepo to Railway without "temporary" marker
→ Pre-commit hook catches it, blocks commit
→ CI catches it, blocks PR merge
2. Developer updates railway.toml and removes "temporary" marker
→ Pre-commit hook warns about migration status
→ CI requires migration plan update
3. Developer adds hardcoded monorepo URL
→ Pre-commit hook catches it in staged files
→ Validation script errors on non-ALLOWED_ORIGINS usage
4. Weekly review finds migration behind schedule
→ TEMPORARY_DEPLOYMENT.md tracks status
→ Team can escalate or adjust timeline
MIGRATION PATH:
Current: Temporary monorepo deployment
→ Phase 1 (2-4 weeks): Prepare satellites
→ Phase 2 (1-2 weeks): Deploy satellites
→ Phase 3 (2-3 weeks): Migrate traffic
→ Phase 4 (1 week): Deprecate monorepo
→ Future: Pure satellite architecture
See: TEMPORARY_DEPLOYMENT.md for complete details
FILES CHANGED: 7 files, 890 insertions(+), 30 deletions(-)
This commit is contained in:
133
.githooks/README.md
Normal file
133
.githooks/README.md
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
# BlackRoad OS Git Hooks
|
||||||
|
|
||||||
|
This directory contains Git hooks to enforce deployment safety and prevent common mistakes.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Option 1: Configure Git to Use These Hooks (Recommended)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run once in your local clone
|
||||||
|
git config core.hooksPath .githooks
|
||||||
|
```
|
||||||
|
|
||||||
|
This tells Git to use hooks from `.githooks/` instead of `.git/hooks/`.
|
||||||
|
|
||||||
|
### Option 2: Quick Setup Script
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From repository root
|
||||||
|
bash .githooks/setup.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 3: Manual Symlink (Alternative)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From repository root
|
||||||
|
ln -s ../../.githooks/pre-commit .git/hooks/pre-commit
|
||||||
|
chmod +x .git/hooks/pre-commit
|
||||||
|
```
|
||||||
|
|
||||||
|
## Available Hooks
|
||||||
|
|
||||||
|
### `pre-commit`
|
||||||
|
|
||||||
|
**Purpose**: Validate deployment configuration before allowing commits.
|
||||||
|
|
||||||
|
**What it checks**:
|
||||||
|
- Runs `scripts/validate_deployment_config.py`
|
||||||
|
- Checks if `railway.toml` maintains 'temporary' marker
|
||||||
|
- Scans staged files for hardcoded monorepo Railway URLs
|
||||||
|
- Prevents accidental permanent monorepo deployment
|
||||||
|
|
||||||
|
**Bypassing** (use sparingly):
|
||||||
|
```bash
|
||||||
|
git commit --no-verify
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example output**:
|
||||||
|
```
|
||||||
|
🔍 Running BlackRoad OS deployment validation...
|
||||||
|
|
||||||
|
======================================================================
|
||||||
|
Deployment Configuration Validation Results
|
||||||
|
======================================================================
|
||||||
|
|
||||||
|
⚠️ WARNINGS (2):
|
||||||
|
• railway.toml: Monorepo is being deployed TEMPORARILY
|
||||||
|
• Migration plan: Migration plan documentation exists
|
||||||
|
|
||||||
|
✅ PASSED (6):
|
||||||
|
• railway.toml acknowledges temporary monorepo deployment
|
||||||
|
• Environment files have warnings but no errors (1 checked)
|
||||||
|
• Satellite sync configuration complete
|
||||||
|
• Cloudflare DNS documentation is correct
|
||||||
|
• DEPLOYMENT_ARCHITECTURE.md is complete
|
||||||
|
• Migration plan documentation exists
|
||||||
|
|
||||||
|
======================================================================
|
||||||
|
✅ VALIDATION PASSED WITH WARNINGS
|
||||||
|
|
||||||
|
✅ Deployment validation passed!
|
||||||
|
|
||||||
|
🔍 Checking staged files for common mistakes...
|
||||||
|
✅ Staged files look good!
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Hook not running
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Verify hooks path is configured
|
||||||
|
git config core.hooksPath
|
||||||
|
|
||||||
|
# Should output: .githooks
|
||||||
|
|
||||||
|
# If empty, configure it
|
||||||
|
git config core.hooksPath .githooks
|
||||||
|
```
|
||||||
|
|
||||||
|
### Hook failing unexpectedly
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run validation script directly to see details
|
||||||
|
python3 scripts/validate_deployment_config.py
|
||||||
|
|
||||||
|
# Run hook directly to debug
|
||||||
|
bash .githooks/pre-commit
|
||||||
|
```
|
||||||
|
|
||||||
|
### Need to bypass hook temporarily
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Only do this if you understand the risks!
|
||||||
|
git commit --no-verify -m "Emergency hotfix"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Hook Development
|
||||||
|
|
||||||
|
### Adding a new hook
|
||||||
|
|
||||||
|
1. Create hook file in `.githooks/`
|
||||||
|
2. Make it executable: `chmod +x .githooks/your-hook`
|
||||||
|
3. Test it: `bash .githooks/your-hook`
|
||||||
|
4. Update this README
|
||||||
|
|
||||||
|
### Testing hooks
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Test pre-commit hook
|
||||||
|
bash .githooks/pre-commit
|
||||||
|
|
||||||
|
# Test with specific staged files
|
||||||
|
git add some-file.py
|
||||||
|
bash .githooks/pre-commit
|
||||||
|
git reset HEAD some-file.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- `scripts/validate_deployment_config.py` - Main validation script
|
||||||
|
- `DEPLOYMENT_ARCHITECTURE.md` - Deployment model documentation
|
||||||
|
- `TEMPORARY_DEPLOYMENT.md` - Temporary deployment migration plan
|
||||||
71
.githooks/pre-commit
Executable file
71
.githooks/pre-commit
Executable file
@@ -0,0 +1,71 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# BlackRoad OS Pre-Commit Hook
|
||||||
|
# Validates deployment configuration before allowing commit
|
||||||
|
#
|
||||||
|
# Install: git config core.hooksPath .githooks
|
||||||
|
# Bypass: git commit --no-verify (use sparingly!)
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "🔍 Running BlackRoad OS deployment validation..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Run validation script
|
||||||
|
python3 scripts/validate_deployment_config.py
|
||||||
|
|
||||||
|
# Check exit code
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "❌ Pre-commit validation failed!"
|
||||||
|
echo ""
|
||||||
|
echo "Options:"
|
||||||
|
echo " 1. Fix the issues and try again"
|
||||||
|
echo " 2. Bypass with: git commit --no-verify (NOT recommended)"
|
||||||
|
echo ""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✅ Deployment validation passed!"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check for common mistakes in staged files
|
||||||
|
echo "🔍 Checking staged files for common mistakes..."
|
||||||
|
|
||||||
|
# Check if railway.toml was modified
|
||||||
|
if git diff --cached --name-only | grep -q "railway.toml"; then
|
||||||
|
echo "⚠️ railway.toml was modified"
|
||||||
|
|
||||||
|
# Check if 'temporary' marker is still present
|
||||||
|
if ! git diff --cached railway.toml | grep -q "temporary"; then
|
||||||
|
if ! grep -q "temporary" railway.toml; then
|
||||||
|
echo "❌ ERROR: railway.toml modified but 'temporary' marker removed"
|
||||||
|
echo " If removing temporary deployment, ensure migration is complete!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for hardcoded monorepo URLs in new code
|
||||||
|
staged_files=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(py|js|ts|tsx|json|yaml|yml|toml)$' || true)
|
||||||
|
|
||||||
|
if [ -n "$staged_files" ]; then
|
||||||
|
for file in $staged_files; do
|
||||||
|
# Skip validation script itself
|
||||||
|
if [[ "$file" == "scripts/validate_deployment_config.py" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for forbidden patterns in staged changes
|
||||||
|
if git diff --cached "$file" | grep -E "blackroad-operating-system.*\.up\.railway\.app" | grep "^+" | grep -v "ALLOWED_ORIGINS" > /dev/null; then
|
||||||
|
echo "❌ ERROR: $file contains hardcoded monorepo Railway URL"
|
||||||
|
echo " Use satellite URLs (blackroad-os-core-production.up.railway.app)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Staged files look good!"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
exit 0
|
||||||
55
.githooks/setup.sh
Executable file
55
.githooks/setup.sh
Executable file
@@ -0,0 +1,55 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# BlackRoad OS Git Hooks Setup Script
|
||||||
|
# Configures Git to use hooks from .githooks/ directory
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "🔧 Setting up BlackRoad OS Git Hooks..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Get repository root
|
||||||
|
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
|
||||||
|
|
||||||
|
if [ -z "$REPO_ROOT" ]; then
|
||||||
|
echo "❌ Error: Not in a Git repository"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$REPO_ROOT"
|
||||||
|
|
||||||
|
# Configure Git to use .githooks directory
|
||||||
|
echo "📝 Configuring Git to use .githooks/ directory..."
|
||||||
|
git config core.hooksPath .githooks
|
||||||
|
|
||||||
|
echo "✅ Git hooks configured!"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Make all hooks executable
|
||||||
|
echo "🔒 Making hooks executable..."
|
||||||
|
chmod +x .githooks/pre-commit
|
||||||
|
|
||||||
|
echo "✅ Hooks are executable!"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test validation script
|
||||||
|
echo "🧪 Testing validation script..."
|
||||||
|
if python3 scripts/validate_deployment_config.py > /dev/null 2>&1; then
|
||||||
|
echo "✅ Validation script works!"
|
||||||
|
else
|
||||||
|
echo "⚠️ Validation script has warnings (this is OK)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo "✅ Git hooks setup complete!"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
echo "Active hooks:"
|
||||||
|
echo " • pre-commit: Validates deployment configuration"
|
||||||
|
echo ""
|
||||||
|
echo "To bypass a hook (use sparingly):"
|
||||||
|
echo " git commit --no-verify"
|
||||||
|
echo ""
|
||||||
|
echo "To disable hooks:"
|
||||||
|
echo " git config --unset core.hooksPath"
|
||||||
|
echo ""
|
||||||
148
.github/workflows/validate-deployment-config.yml
vendored
Normal file
148
.github/workflows/validate-deployment-config.yml
vendored
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
name: Validate Deployment Configuration
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
paths:
|
||||||
|
- 'railway.toml'
|
||||||
|
- 'backend/.env.example'
|
||||||
|
- 'ops/domains.yaml'
|
||||||
|
- 'DEPLOYMENT_ARCHITECTURE.md'
|
||||||
|
- 'TEMPORARY_DEPLOYMENT.md'
|
||||||
|
- 'scripts/validate_deployment_config.py'
|
||||||
|
- '.github/workflows/validate-deployment-config.yml'
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
paths:
|
||||||
|
- 'railway.toml'
|
||||||
|
- 'backend/.env.example'
|
||||||
|
- 'ops/domains.yaml'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate:
|
||||||
|
name: Validate Deployment Config
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
pip install pyyaml
|
||||||
|
|
||||||
|
- name: Run deployment validation
|
||||||
|
id: validate
|
||||||
|
run: |
|
||||||
|
python scripts/validate_deployment_config.py
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Check validation result
|
||||||
|
run: |
|
||||||
|
if [ ${{ steps.validate.outcome }} == 'failure' ]; then
|
||||||
|
echo "::error::Deployment configuration validation failed"
|
||||||
|
echo "See the validation output above for details"
|
||||||
|
exit 1
|
||||||
|
elif [ ${{ steps.validate.outcome }} == 'success' ]; then
|
||||||
|
echo "::notice::Deployment configuration validation passed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check for monorepo deployment without temporary marker
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
if grep -q "BlackRoad-Operating-System" railway.toml && ! grep -qi "temporary" railway.toml; then
|
||||||
|
echo "::error file=railway.toml::Monorepo deployment detected without 'temporary' marker"
|
||||||
|
echo "::error::If deploying monorepo permanently, see DEPLOYMENT_ARCHITECTURE.md"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check for migration plan
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
if grep -qi "temporary" railway.toml; then
|
||||||
|
if [ ! -f "TEMPORARY_DEPLOYMENT.md" ] && [ ! -f "MIGRATION_TO_SATELLITES.md" ]; then
|
||||||
|
echo "::warning file=railway.toml::Temporary deployment detected but no migration plan found"
|
||||||
|
echo "::warning::Consider creating TEMPORARY_DEPLOYMENT.md with migration timeline"
|
||||||
|
else
|
||||||
|
echo "::notice::Migration plan documentation exists"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Comment on PR (if validation failed)
|
||||||
|
if: failure() && github.event_name == 'pull_request'
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const comment = `## ⚠️ Deployment Configuration Validation Failed
|
||||||
|
|
||||||
|
The deployment configuration validation has detected issues with this PR.
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
1. **Monorepo deployed without temporary marker**
|
||||||
|
- Ensure \`railway.toml\` includes "temporary" if deploying monorepo
|
||||||
|
- See \`DEPLOYMENT_ARCHITECTURE.md\` for target architecture
|
||||||
|
|
||||||
|
2. **Hardcoded monorepo URLs**
|
||||||
|
- Use satellite URLs instead: \`blackroad-os-core-production.up.railway.app\`
|
||||||
|
- Temporary monorepo URLs in \`ALLOWED_ORIGINS\` are OK (with warning)
|
||||||
|
|
||||||
|
3. **Missing migration plan**
|
||||||
|
- If deploying monorepo temporarily, create \`TEMPORARY_DEPLOYMENT.md\`
|
||||||
|
- Include migration timeline to satellite architecture
|
||||||
|
|
||||||
|
### How to Fix
|
||||||
|
|
||||||
|
1. Review the validation output above
|
||||||
|
2. Fix the issues locally
|
||||||
|
3. Run \`python scripts/validate_deployment_config.py\` to verify
|
||||||
|
4. Push the fixes
|
||||||
|
|
||||||
|
### Need Help?
|
||||||
|
|
||||||
|
- See \`DEPLOYMENT_ARCHITECTURE.md\` for deployment model
|
||||||
|
- See \`TEMPORARY_DEPLOYMENT.md\` for temporary deployment guidelines
|
||||||
|
- Ask in \`#infrastructure\` Slack channel
|
||||||
|
|
||||||
|
---
|
||||||
|
<sub>This comment was automatically generated by the deployment validation workflow.</sub>
|
||||||
|
`;
|
||||||
|
|
||||||
|
github.rest.issues.createComment({
|
||||||
|
issue_number: context.issue.number,
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
body: comment
|
||||||
|
});
|
||||||
|
|
||||||
|
- name: Comment on PR (if validation passed)
|
||||||
|
if: success() && github.event_name == 'pull_request'
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const comment = `## ✅ Deployment Configuration Validation Passed
|
||||||
|
|
||||||
|
Deployment configuration looks good!
|
||||||
|
|
||||||
|
${
|
||||||
|
// Check if temporary deployment
|
||||||
|
require('fs').readFileSync('railway.toml', 'utf8').toLowerCase().includes('temporary')
|
||||||
|
? `⚠️ **Note**: This PR includes a temporary monorepo deployment. Ensure migration plan is documented in \`TEMPORARY_DEPLOYMENT.md\`.`
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
<sub>This comment was automatically generated by the deployment validation workflow.</sub>
|
||||||
|
`;
|
||||||
|
|
||||||
|
github.rest.issues.createComment({
|
||||||
|
issue_number: context.issue.number,
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
body: comment
|
||||||
|
});
|
||||||
@@ -1,21 +1,23 @@
|
|||||||
# BlackRoad OS Deployment Architecture
|
# BlackRoad OS Deployment Architecture
|
||||||
|
|
||||||
> **Last Updated**: 2025-11-19
|
> **Last Updated**: 2026-01-24
|
||||||
> **Status**: Canonical deployment model for all BlackRoad OS services
|
> **Status**: Canonical deployment model for all BlackRoad OS services
|
||||||
|
> **Current Mode**: Temporary Hybrid Deployment (see below)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
1. [Overview](#overview)
|
1. [Overview](#overview)
|
||||||
2. [The Monorepo vs Satellite Model](#the-monorepo-vs-satellite-model)
|
2. [⚠️ Current Status: Temporary Hybrid Deployment](#current-status-temporary-hybrid-deployment)
|
||||||
3. [Critical Rules](#critical-rules)
|
3. [The Monorepo vs Satellite Model](#the-monorepo-vs-satellite-model)
|
||||||
4. [Deployment Topology](#deployment-topology)
|
4. [Critical Rules](#critical-rules)
|
||||||
5. [Service-to-Repository Mapping](#service-to-repository-mapping)
|
5. [Deployment Topology](#deployment-topology)
|
||||||
6. [Environment Configuration](#environment-configuration)
|
6. [Service-to-Repository Mapping](#service-to-repository-mapping)
|
||||||
7. [Cloudflare DNS Configuration](#cloudflare-dns-configuration)
|
7. [Environment Configuration](#environment-configuration)
|
||||||
8. [Common Mistakes to Avoid](#common-mistakes-to-avoid)
|
8. [Cloudflare DNS Configuration](#cloudflare-dns-configuration)
|
||||||
9. [Troubleshooting](#troubleshooting)
|
9. [Common Mistakes to Avoid](#common-mistakes-to-avoid)
|
||||||
|
10. [Troubleshooting](#troubleshooting)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -30,8 +32,74 @@ This document establishes the canonical deployment model to prevent misconfigura
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## ⚠️ Current Status: Temporary Hybrid Deployment
|
||||||
|
|
||||||
|
### 🚨 IMPORTANT: Temporary Deployment Active
|
||||||
|
|
||||||
|
**As of 2026-01-24, BlackRoad OS is running in a TEMPORARY HYBRID deployment mode.**
|
||||||
|
|
||||||
|
**What this means**:
|
||||||
|
- The monorepo (`BlackRoad-Operating-System`) IS currently deployed to Railway
|
||||||
|
- This is explicitly temporary to get the BR-95 desktop UI online quickly
|
||||||
|
- Satellite infrastructure is being built in parallel
|
||||||
|
- Migration to satellites is planned and tracked
|
||||||
|
|
||||||
|
**Current deployment**:
|
||||||
|
- **Service**: `BlackRoad-Operating-System` (monorepo)
|
||||||
|
- **Railway Project**: `gregarious-wonder`
|
||||||
|
- **Domain**: `app.blackroad.systems`
|
||||||
|
- **Status**: TEMPORARY - will be deprecated
|
||||||
|
|
||||||
|
**This violates the target architecture described below, but is allowed temporarily for speed to market.**
|
||||||
|
|
||||||
|
### Why Temporary Deployment?
|
||||||
|
|
||||||
|
The monorepo deployment was chosen for pragmatic reasons:
|
||||||
|
- ✅ Get product to market faster
|
||||||
|
- ✅ Validate product-market fit before building full satellite infrastructure
|
||||||
|
- ✅ Serve users while architecture is finalized
|
||||||
|
- ✅ Maintain ability to iterate quickly
|
||||||
|
|
||||||
|
### Migration Timeline
|
||||||
|
|
||||||
|
```
|
||||||
|
Now: Temporary monorepo deployment
|
||||||
|
↓
|
||||||
|
Phase 1 (2-4 weeks): Prepare satellites
|
||||||
|
↓
|
||||||
|
Phase 2 (1-2 weeks): Deploy satellites in parallel
|
||||||
|
↓
|
||||||
|
Phase 3 (2-3 weeks): Migrate traffic to satellites
|
||||||
|
↓
|
||||||
|
Phase 4 (1 week): Deprecate monorepo deployment
|
||||||
|
↓
|
||||||
|
Future: Pure satellite architecture
|
||||||
|
```
|
||||||
|
|
||||||
|
**See**: `TEMPORARY_DEPLOYMENT.md` for complete migration plan.
|
||||||
|
|
||||||
|
### Allowed Temporary Deviations
|
||||||
|
|
||||||
|
While in temporary deployment mode, these deviations are **explicitly allowed**:
|
||||||
|
|
||||||
|
✅ Monorepo deployed to Railway (must be marked "temporary")
|
||||||
|
✅ Monorepo URLs in ALLOWED_ORIGINS (must also include satellite URLs)
|
||||||
|
✅ `app.blackroad.systems` pointing to monorepo
|
||||||
|
✅ Single service serving all APIs
|
||||||
|
|
||||||
|
❌ Still forbidden:
|
||||||
|
- Adding `MONOREPO_URL` environment variables
|
||||||
|
- Permanent monorepo deployment without migration plan
|
||||||
|
- Abandoning satellite infrastructure development
|
||||||
|
|
||||||
|
**Governance**: Weekly reviews to track migration progress. If not migrated within 12 weeks, re-evaluate architecture decision.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## The Monorepo vs Satellite Model
|
## The Monorepo vs Satellite Model
|
||||||
|
|
||||||
|
**This section describes the TARGET architecture.** See above for current temporary state.
|
||||||
|
|
||||||
### BlackRoad-Operating-System (Monorepo)
|
### BlackRoad-Operating-System (Monorepo)
|
||||||
|
|
||||||
**Purpose**: Control plane and source of truth
|
**Purpose**: Control plane and source of truth
|
||||||
@@ -42,13 +110,17 @@ This document establishes the canonical deployment model to prevent misconfigura
|
|||||||
- Stores orchestration logic, prompts, and infrastructure configs
|
- Stores orchestration logic, prompts, and infrastructure configs
|
||||||
- Serves as the "brain" - NOT the compute
|
- Serves as the "brain" - NOT the compute
|
||||||
|
|
||||||
**Deployment Status**: ❌ **NEVER DEPLOYED TO PRODUCTION**
|
**Deployment Status**:
|
||||||
|
- **Current**: ⚠️ **TEMPORARILY DEPLOYED TO PRODUCTION** (see above)
|
||||||
|
- **Target**: ❌ **SHOULD NOT BE DEPLOYED** (satellite architecture)
|
||||||
|
|
||||||
**Why NOT deployable**:
|
**Why NOT permanently deployable**:
|
||||||
- No single entry point (contains multiple services)
|
- No single entry point (contains multiple services)
|
||||||
- Would create circular deployment dependencies
|
- Would create circular deployment dependencies
|
||||||
- Not designed for runtime execution
|
- Not designed for long-term runtime execution
|
||||||
- Would break service discovery and routing
|
- Would break service discovery and routing in satellite model
|
||||||
|
- Slow deployments (30+ minutes for full monorepo)
|
||||||
|
- Single point of failure
|
||||||
|
|
||||||
### Satellite Repositories
|
### Satellite Repositories
|
||||||
|
|
||||||
|
|||||||
309
TEMPORARY_DEPLOYMENT.md
Normal file
309
TEMPORARY_DEPLOYMENT.md
Normal file
@@ -0,0 +1,309 @@
|
|||||||
|
# Temporary Monorepo Deployment - Migration Plan
|
||||||
|
|
||||||
|
> **Status**: ACTIVE TEMPORARY DEPLOYMENT
|
||||||
|
> **Target**: Migrate to satellite architecture
|
||||||
|
> **Timeline**: TBD based on satellite infrastructure readiness
|
||||||
|
> **Last Updated**: 2026-01-24
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
BlackRoad OS is currently deployed using a **temporary hybrid approach** where the monorepo (`BlackRoad-Operating-System`) is deployed directly to Railway to get the BR-95 desktop UI online quickly, while the satellite infrastructure is being built in parallel.
|
||||||
|
|
||||||
|
**This is explicitly a temporary state.**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Current State
|
||||||
|
|
||||||
|
### What's Deployed Now
|
||||||
|
|
||||||
|
**Monorepo Deployment** (Temporary):
|
||||||
|
- **Service**: `BlackRoad-Operating-System`
|
||||||
|
- **Railway Project**: `gregarious-wonder`
|
||||||
|
- **Domain**: `app.blackroad.systems`
|
||||||
|
- **Purpose**: Serve BR-95 desktop UI quickly while satellites are being built
|
||||||
|
- **Status**: TEMPORARY - will be deprecated
|
||||||
|
|
||||||
|
**Configuration**:
|
||||||
|
```toml
|
||||||
|
# railway.toml
|
||||||
|
[build]
|
||||||
|
builder = "NIXPACKS"
|
||||||
|
|
||||||
|
[deploy]
|
||||||
|
startCommand = "uvicorn backend.app.main:app --host 0.0.0.0 --port $PORT"
|
||||||
|
healthcheckPath = "/health"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Why Temporary?
|
||||||
|
|
||||||
|
The monorepo deployment was chosen for **speed to market**:
|
||||||
|
- ✅ Get BR-95 desktop UI online immediately
|
||||||
|
- ✅ Serve users while architecture is finalized
|
||||||
|
- ✅ Validate product-market fit before investing in full satellite infrastructure
|
||||||
|
- ✅ Maintain ability to iterate quickly
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Target State (Satellite Architecture)
|
||||||
|
|
||||||
|
### Satellite Services to Deploy
|
||||||
|
|
||||||
|
| Service | Repository | Railway Service | Domain | Status |
|
||||||
|
|---------|-----------|-----------------|--------|--------|
|
||||||
|
| Core API | `BlackRoad-OS/blackroad-os-core` | `blackroad-os-core-production` | `core.blackroad.systems` | 🟡 Planned |
|
||||||
|
| Public API | `BlackRoad-OS/blackroad-os-api` | `blackroad-os-api-production` | `api.blackroad.systems` | 🟡 Planned |
|
||||||
|
| Operator | `BlackRoad-OS/blackroad-os-operator` | `blackroad-os-operator-production` | `operator.blackroad.systems` | 🟡 Planned |
|
||||||
|
| Prism Console | `BlackRoad-OS/blackroad-os-prism-console` | `blackroad-os-prism-console-production` | `console.blackroad.systems` | ✅ Deployed (Vercel) |
|
||||||
|
| Docs | `BlackRoad-OS/blackroad-os-docs` | `blackroad-os-docs-production` | `docs.blackroad.systems` | ✅ Deployed (GitHub Pages) |
|
||||||
|
| Web | `BlackRoad-OS/blackroad-os-web` | `blackroad-os-web-production` | `blackroad.systems` | ✅ Deployed (Vercel) |
|
||||||
|
|
||||||
|
### Satellite Architecture Benefits
|
||||||
|
|
||||||
|
Once migrated:
|
||||||
|
- **Better isolation**: Each service can scale independently
|
||||||
|
- **Faster deploys**: Only changed services redeploy
|
||||||
|
- **Clearer ownership**: Each team owns a satellite
|
||||||
|
- **Reduced blast radius**: Issues in one service don't affect others
|
||||||
|
- **Easier rollbacks**: Rollback individual services vs entire monorepo
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Migration Plan
|
||||||
|
|
||||||
|
### Phase 1: Prepare Satellites (In Progress)
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
- [x] Create satellite repository structure
|
||||||
|
- [x] Set up sync workflows (monorepo → satellites)
|
||||||
|
- [ ] Configure Railway services for each satellite
|
||||||
|
- [ ] Set up production environments
|
||||||
|
- [ ] Configure environment variables
|
||||||
|
- [ ] Set up health checks and monitoring
|
||||||
|
|
||||||
|
**Status**: 40% complete
|
||||||
|
|
||||||
|
### Phase 2: Deploy Satellites (Parallel to Monorepo)
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
- [ ] Deploy `blackroad-os-core-production` to Railway
|
||||||
|
- [ ] Deploy `blackroad-os-api-production` to Railway
|
||||||
|
- [ ] Deploy `blackroad-os-operator-production` to Railway
|
||||||
|
- [ ] Configure Cloudflare DNS to point to satellites
|
||||||
|
- [ ] Run smoke tests on satellite infrastructure
|
||||||
|
- [ ] Monitor satellite health for 1 week
|
||||||
|
|
||||||
|
**Success Criteria**:
|
||||||
|
- All satellites pass health checks
|
||||||
|
- Response times < 200ms p95
|
||||||
|
- Zero errors in production for 48 hours
|
||||||
|
- All existing functionality works
|
||||||
|
|
||||||
|
### Phase 3: Traffic Migration
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
- [ ] Set up A/B testing (50/50 monorepo vs satellites)
|
||||||
|
- [ ] Monitor error rates and performance
|
||||||
|
- [ ] Gradually shift traffic (50% → 75% → 90% → 100%)
|
||||||
|
- [ ] Update all `ALLOWED_ORIGINS` to satellite URLs
|
||||||
|
- [ ] Update all service-to-service calls to use satellite endpoints
|
||||||
|
|
||||||
|
**Rollback Plan**:
|
||||||
|
- Keep monorepo deployment running as backup
|
||||||
|
- Can revert Cloudflare DNS in < 5 minutes
|
||||||
|
- Automated rollback if error rate > 1%
|
||||||
|
|
||||||
|
### Phase 4: Deprecate Monorepo Deployment
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
- [ ] Confirm 100% traffic on satellites for 2 weeks
|
||||||
|
- [ ] Remove monorepo Railway service
|
||||||
|
- [ ] Archive `railway.toml` in monorepo
|
||||||
|
- [ ] Update all documentation to reference satellites only
|
||||||
|
- [ ] Celebrate! 🎉
|
||||||
|
|
||||||
|
**Final State**:
|
||||||
|
- Monorepo = source of truth (code only)
|
||||||
|
- Satellites = deployable services
|
||||||
|
- Clean separation of concerns
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Current Risks & Mitigations
|
||||||
|
|
||||||
|
### Risk 1: Monorepo Deployment Becomes Permanent
|
||||||
|
|
||||||
|
**Risk**: Team gets comfortable with monorepo deployment and never migrates.
|
||||||
|
|
||||||
|
**Mitigation**:
|
||||||
|
- ✅ This document serves as commitment to migrate
|
||||||
|
- ✅ Validation script warns about temporary deployment
|
||||||
|
- ✅ Regular reviews to check migration progress
|
||||||
|
- 📅 Set hard deadline for Phase 2 completion
|
||||||
|
|
||||||
|
### Risk 2: Satellite Infrastructure Never Gets Built
|
||||||
|
|
||||||
|
**Risk**: Satellites remain planned but never deployed.
|
||||||
|
|
||||||
|
**Mitigation**:
|
||||||
|
- Track satellite deployment as OKR
|
||||||
|
- Allocate dedicated engineering time
|
||||||
|
- Make migration a requirement for next funding round
|
||||||
|
- Set up automated reminders if migration stalls
|
||||||
|
|
||||||
|
### Risk 3: Configuration Drift Between Monorepo and Satellites
|
||||||
|
|
||||||
|
**Risk**: Monorepo and satellites diverge, making migration harder.
|
||||||
|
|
||||||
|
**Mitigation**:
|
||||||
|
- ✅ Sync workflows keep satellites up to date
|
||||||
|
- ✅ Validation scripts catch drift
|
||||||
|
- Test satellites in staging regularly
|
||||||
|
- Document any monorepo-specific hacks that need migration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Allowed Temporary Deviations
|
||||||
|
|
||||||
|
While in temporary deployment mode, the following deviations from the target architecture are **explicitly allowed**:
|
||||||
|
|
||||||
|
### ✅ Allowed (Temporary)
|
||||||
|
|
||||||
|
1. **Monorepo in Railway**
|
||||||
|
- `BlackRoad-Operating-System` deployed as Railway service
|
||||||
|
- Must be marked as "temporary" in `railway.toml`
|
||||||
|
|
||||||
|
2. **Monorepo URLs in ALLOWED_ORIGINS**
|
||||||
|
- `blackroad-operating-system-production.up.railway.app` in CORS config
|
||||||
|
- Must also include satellite URLs for future migration
|
||||||
|
|
||||||
|
3. **Monorepo Domain**
|
||||||
|
- `app.blackroad.systems` pointing to monorepo deployment
|
||||||
|
- Will be deprecated when satellites are live
|
||||||
|
|
||||||
|
4. **Single Service for All APIs**
|
||||||
|
- All API endpoints served from monorepo
|
||||||
|
- Will be split into Core API, Public API, Operator when satellites deploy
|
||||||
|
|
||||||
|
### ❌ Still Forbidden (Even During Temporary Phase)
|
||||||
|
|
||||||
|
1. **Adding Monorepo as Dependency**
|
||||||
|
- Do NOT add `MONOREPO_URL` environment variables
|
||||||
|
- Do NOT reference monorepo from other services
|
||||||
|
|
||||||
|
2. **Permanent Monorepo Deployment**
|
||||||
|
- Must maintain "temporary" markers in configs
|
||||||
|
- Must have active migration plan
|
||||||
|
|
||||||
|
3. **Skipping Satellite Infrastructure**
|
||||||
|
- Must continue building satellites in parallel
|
||||||
|
- Must not abandon migration plan
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Monitoring & Governance
|
||||||
|
|
||||||
|
### Weekly Checks
|
||||||
|
|
||||||
|
Every week, review:
|
||||||
|
- [ ] Satellite deployment progress
|
||||||
|
- [ ] Migration timeline
|
||||||
|
- [ ] Any blockers to satellite deployment
|
||||||
|
|
||||||
|
### Monthly Reviews
|
||||||
|
|
||||||
|
Every month, review:
|
||||||
|
- [ ] Update this document with progress
|
||||||
|
- [ ] Adjust timeline if needed
|
||||||
|
- [ ] Communicate status to stakeholders
|
||||||
|
|
||||||
|
### Automated Validation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run validation script weekly
|
||||||
|
python scripts/validate_deployment_config.py
|
||||||
|
|
||||||
|
# Should show:
|
||||||
|
# ⚠️ WARNING: Monorepo is being deployed TEMPORARILY
|
||||||
|
# ⚠️ WARNING: Migration plan exists but not complete
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
### Q: Why not just stick with monorepo deployment?
|
||||||
|
|
||||||
|
**A**: While it works now, it won't scale:
|
||||||
|
- **Performance**: Monorepo deploys are slow (30+ minutes)
|
||||||
|
- **Reliability**: Single point of failure for all services
|
||||||
|
- **Team velocity**: All changes require full deployment
|
||||||
|
- **Cost**: Can't scale individual services based on load
|
||||||
|
|
||||||
|
### Q: When will migration be complete?
|
||||||
|
|
||||||
|
**A**: Target timeline:
|
||||||
|
- Phase 1 (Prepare): 2-4 weeks
|
||||||
|
- Phase 2 (Deploy Satellites): 1-2 weeks
|
||||||
|
- Phase 3 (Traffic Migration): 2-3 weeks
|
||||||
|
- Phase 4 (Deprecate Monorepo): 1 week
|
||||||
|
|
||||||
|
**Total**: 6-10 weeks from satellite infrastructure kickoff
|
||||||
|
|
||||||
|
### Q: What if satellites never get built?
|
||||||
|
|
||||||
|
**A**: If satellites aren't feasible, we'll:
|
||||||
|
1. Document why (technical/business reasons)
|
||||||
|
2. Update DEPLOYMENT_ARCHITECTURE.md to reflect permanent monorepo approach
|
||||||
|
3. Remove "temporary" markers from configs
|
||||||
|
4. Optimize monorepo deployment for long-term use
|
||||||
|
|
||||||
|
But this should be a last resort.
|
||||||
|
|
||||||
|
### Q: Can I add new features to the monorepo?
|
||||||
|
|
||||||
|
**A**: Yes! Continue developing in the monorepo:
|
||||||
|
- Edit code in `services/core-api/`, `apps/prism-console/`, etc.
|
||||||
|
- Sync workflows will update satellites
|
||||||
|
- When satellites deploy, features will "just work"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Success Metrics
|
||||||
|
|
||||||
|
Migration is successful when:
|
||||||
|
- ✅ 100% traffic on satellites
|
||||||
|
- ✅ Zero downtime during migration
|
||||||
|
- ✅ All tests passing on satellites
|
||||||
|
- ✅ Performance improved or equal to monorepo
|
||||||
|
- ✅ Monorepo Railway service deleted
|
||||||
|
- ✅ Team confident in satellite architecture
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
The temporary monorepo deployment is a pragmatic choice to ship quickly while building the right architecture. This document ensures we don't lose sight of the target state and have a clear path to get there.
|
||||||
|
|
||||||
|
**Next Steps**:
|
||||||
|
1. Complete Phase 1 (prepare satellites)
|
||||||
|
2. Deploy first satellite (`blackroad-os-core-production`)
|
||||||
|
3. Run smoke tests
|
||||||
|
4. Repeat for other satellites
|
||||||
|
5. Migrate traffic
|
||||||
|
6. Deprecate monorepo deployment
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**For Questions or Updates**:
|
||||||
|
- See `DEPLOYMENT_ARCHITECTURE.md` for target architecture
|
||||||
|
- See `docs/os/monorepo-sync.md` for sync process
|
||||||
|
- Run `python scripts/validate_deployment_config.py` for status
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Last updated: 2026-01-24*
|
||||||
|
*Document owner: Infrastructure Team*
|
||||||
|
*Review frequency: Monthly*
|
||||||
@@ -151,7 +151,7 @@ def is_allowed_file(file_path: Path) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
def check_railway_toml(result: ValidationResult):
|
def check_railway_toml(result: ValidationResult):
|
||||||
"""Validate railway.toml is marked for local dev only"""
|
"""Validate railway.toml deployment approach"""
|
||||||
railway_toml = REPO_ROOT / "railway.toml"
|
railway_toml = REPO_ROOT / "railway.toml"
|
||||||
|
|
||||||
if not railway_toml.exists():
|
if not railway_toml.exists():
|
||||||
@@ -160,22 +160,42 @@ def check_railway_toml(result: ValidationResult):
|
|||||||
|
|
||||||
content = railway_toml.read_text()
|
content = railway_toml.read_text()
|
||||||
|
|
||||||
# Check for warning banner
|
# Check if this is a temporary monorepo deployment
|
||||||
if "CRITICAL WARNING" not in content:
|
is_temporary = "temporary" in content.lower() or "temp" in content.lower()
|
||||||
result.add_error(
|
|
||||||
|
# Check if monorepo is being deployed
|
||||||
|
has_monorepo_deployment = (
|
||||||
|
"BlackRoad-Operating-System" in content or
|
||||||
|
"blackroad-operating-system" in content or
|
||||||
|
"gregarious-wonder" in content # Railway project name
|
||||||
|
)
|
||||||
|
|
||||||
|
if has_monorepo_deployment and is_temporary:
|
||||||
|
# Temporary deployment is OK, but warn
|
||||||
|
result.add_warning(
|
||||||
"railway.toml",
|
"railway.toml",
|
||||||
"Missing CRITICAL WARNING banner at top of file"
|
"Monorepo is being deployed TEMPORARILY - ensure migration plan exists"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check for "LOCAL DEV" or similar marker
|
# Check for migration timeline
|
||||||
if "LOCAL DEV" not in content and "DEVELOPMENT" not in content:
|
if "long-term" not in content.lower() and "satellite" not in content.lower():
|
||||||
|
result.add_warning(
|
||||||
|
"railway.toml",
|
||||||
|
"Should reference long-term satellite architecture"
|
||||||
|
)
|
||||||
|
|
||||||
|
result.add_pass("railway.toml acknowledges temporary monorepo deployment")
|
||||||
|
|
||||||
|
elif has_monorepo_deployment and not is_temporary:
|
||||||
|
# Permanent monorepo deployment - ERROR
|
||||||
result.add_error(
|
result.add_error(
|
||||||
"railway.toml",
|
"railway.toml",
|
||||||
"Not clearly marked as local development only"
|
"Monorepo deployment found without 'temporary' marker - this violates architecture"
|
||||||
)
|
)
|
||||||
|
|
||||||
if not result.errors:
|
else:
|
||||||
result.add_pass("railway.toml has proper warnings")
|
# No monorepo deployment - ideal state
|
||||||
|
result.add_pass("railway.toml follows satellite deployment model")
|
||||||
|
|
||||||
|
|
||||||
def check_env_files(result: ValidationResult):
|
def check_env_files(result: ValidationResult):
|
||||||
@@ -185,7 +205,8 @@ def check_env_files(result: ValidationResult):
|
|||||||
for pattern in CHECK_PATTERNS:
|
for pattern in CHECK_PATTERNS:
|
||||||
env_files.extend(REPO_ROOT.glob(pattern))
|
env_files.extend(REPO_ROOT.glob(pattern))
|
||||||
|
|
||||||
found_issues = False
|
found_errors = False
|
||||||
|
found_warnings = False
|
||||||
checked_count = 0
|
checked_count = 0
|
||||||
|
|
||||||
for env_file in env_files:
|
for env_file in env_files:
|
||||||
@@ -200,16 +221,35 @@ def check_env_files(result: ValidationResult):
|
|||||||
for match in matches:
|
for match in matches:
|
||||||
# Get line number
|
# Get line number
|
||||||
line_num = content[:match.start()].count('\n') + 1
|
line_num = content[:match.start()].count('\n') + 1
|
||||||
result.add_error(
|
matched_text = match.group()
|
||||||
f"{env_file.name}:{line_num}",
|
|
||||||
f"Contains forbidden reference: '{match.group()}'"
|
# Check if this is in ALLOWED_ORIGINS (temporary allowance)
|
||||||
)
|
line_start = content.rfind('\n', 0, match.start()) + 1
|
||||||
found_issues = True
|
line_end = content.find('\n', match.end())
|
||||||
|
if line_end == -1:
|
||||||
|
line_end = len(content)
|
||||||
|
full_line = content[line_start:line_end]
|
||||||
|
|
||||||
|
# If it's in ALLOWED_ORIGINS and includes other valid origins, it's a warning not an error
|
||||||
|
if 'ALLOWED_ORIGINS=' in full_line and 'blackroad.systems' in full_line:
|
||||||
|
result.add_warning(
|
||||||
|
f"{env_file.name}:{line_num}",
|
||||||
|
f"Temporary monorepo reference in ALLOWED_ORIGINS: '{matched_text}' - should migrate to satellite URLs"
|
||||||
|
)
|
||||||
|
found_warnings = True
|
||||||
|
else:
|
||||||
|
result.add_error(
|
||||||
|
f"{env_file.name}:{line_num}",
|
||||||
|
f"Contains forbidden reference: '{matched_text}'"
|
||||||
|
)
|
||||||
|
found_errors = True
|
||||||
|
|
||||||
if checked_count == 0:
|
if checked_count == 0:
|
||||||
result.add_warning("env files", "No environment files found to check")
|
result.add_warning("env files", "No environment files found to check")
|
||||||
elif not found_issues:
|
elif not found_errors and not found_warnings:
|
||||||
result.add_pass(f"Environment files clean ({checked_count} checked)")
|
result.add_pass(f"Environment files clean ({checked_count} checked)")
|
||||||
|
elif not found_errors:
|
||||||
|
result.add_pass(f"Environment files have warnings but no errors ({checked_count} checked)")
|
||||||
|
|
||||||
|
|
||||||
def check_satellite_configs(result: ValidationResult):
|
def check_satellite_configs(result: ValidationResult):
|
||||||
@@ -346,6 +386,37 @@ def check_readme_warnings(result: ValidationResult):
|
|||||||
result.add_pass("README.md has proper deployment warnings")
|
result.add_pass("README.md has proper deployment warnings")
|
||||||
|
|
||||||
|
|
||||||
|
def check_migration_plan(result: ValidationResult):
|
||||||
|
"""Check if migration plan exists for temporary monorepo deployment"""
|
||||||
|
railway_toml = REPO_ROOT / "railway.toml"
|
||||||
|
|
||||||
|
if not railway_toml.exists():
|
||||||
|
return
|
||||||
|
|
||||||
|
content = railway_toml.read_text()
|
||||||
|
is_temporary = "temporary" in content.lower()
|
||||||
|
|
||||||
|
if not is_temporary:
|
||||||
|
return # Not a temporary deployment, no migration needed
|
||||||
|
|
||||||
|
# Check for migration documentation
|
||||||
|
migration_docs = [
|
||||||
|
REPO_ROOT / "MIGRATION_TO_SATELLITES.md",
|
||||||
|
REPO_ROOT / "TEMPORARY_DEPLOYMENT.md",
|
||||||
|
REPO_ROOT / "docs/MIGRATION_PLAN.md",
|
||||||
|
]
|
||||||
|
|
||||||
|
migration_doc_exists = any(doc.exists() for doc in migration_docs)
|
||||||
|
|
||||||
|
if not migration_doc_exists:
|
||||||
|
result.add_warning(
|
||||||
|
"Migration plan",
|
||||||
|
"Temporary monorepo deployment detected but no migration plan found (MIGRATION_TO_SATELLITES.md or TEMPORARY_DEPLOYMENT.md)"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
result.add_pass("Migration plan documentation exists")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""Run all validation checks"""
|
"""Run all validation checks"""
|
||||||
print(f"\n{BOLD}{BLUE}BlackRoad OS Deployment Configuration Validator{RESET}")
|
print(f"\n{BOLD}{BLUE}BlackRoad OS Deployment Configuration Validator{RESET}")
|
||||||
@@ -362,6 +433,7 @@ def main():
|
|||||||
check_cloudflare_docs(result)
|
check_cloudflare_docs(result)
|
||||||
check_deployment_architecture_exists(result)
|
check_deployment_architecture_exists(result)
|
||||||
check_readme_warnings(result)
|
check_readme_warnings(result)
|
||||||
|
check_migration_plan(result)
|
||||||
|
|
||||||
# Print results
|
# Print results
|
||||||
exit_code = result.print_summary()
|
exit_code = result.print_summary()
|
||||||
|
|||||||
Reference in New Issue
Block a user