Compare commits
3 Commits
burn/672-1
...
fix/912
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
168cbb57c9 | ||
| bd0497b998 | |||
|
|
4ab84a59ab |
421
GENOME.md
421
GENOME.md
@@ -1,421 +0,0 @@
|
||||
# GENOME.md — The Nexus
|
||||
|
||||
*Generated: 2026-04-14 | Codebase Genome Analysis*
|
||||
|
||||
## Project Overview
|
||||
|
||||
**The Nexus** is Timmy's canonical 3D/home-world repository — a local-first training ground and wizardly visualization surface for the sovereign AI system.
|
||||
|
||||
### Core Value Proposition
|
||||
- **Problem**: AI consciousness needs a spatial, embodied interface for training, visualization, and multi-world navigation
|
||||
- **Solution**: A Three.js 3D world with WebSocket-connected Python cognition, game world harnesses (Morrowind, Bannerlord), and persistent memory systems
|
||||
- **Result**: A sovereign digital home where Timmy can perceive, think, act, and remember across multiple virtual environments
|
||||
|
||||
### Key Metrics
|
||||
- **Total Files**: 446 (excluding .git)
|
||||
- **Lines of Code**: ~53K total (Python: 41,659 | JavaScript: 8,484 | HTML: 3,124)
|
||||
- **Test Coverage**: 457 passing tests, 5 failing, 2 collection errors
|
||||
- **Active Components**: 18 frontend modules, 22 Python cognition modules, 4 game harnesses
|
||||
|
||||
## Architecture
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "Frontend (Browser)"
|
||||
A[index.html] --> B[app.js]
|
||||
B --> C[Three.js 3D World]
|
||||
B --> D[GOFAI Worker]
|
||||
B --> E[Components]
|
||||
E --> E1[Spatial Memory]
|
||||
E --> E2[Spatial Audio]
|
||||
E --> E3[Memory Systems]
|
||||
E --> E4[Portal System]
|
||||
E --> E5[Agent Presence]
|
||||
end
|
||||
|
||||
subgraph "Backend (Python)"
|
||||
F[server.py] --> G[WebSocket Gateway]
|
||||
G --> H[nexus_think.py]
|
||||
H --> I[Perception Adapter]
|
||||
H --> J[Experience Store]
|
||||
H --> K[Trajectory Logger]
|
||||
H --> L[Heartbeat Writer]
|
||||
|
||||
subgraph "Game Harnesses"
|
||||
M[Morrowind Harness]
|
||||
N[Bannerlord Harness]
|
||||
O[Gemini Harness]
|
||||
end
|
||||
|
||||
subgraph "Memory Systems"
|
||||
P[MemPalace]
|
||||
Q[Mnemosyne]
|
||||
R[Evennia Bridge]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph "Data Layer"
|
||||
S[portals.json]
|
||||
T[vision.json]
|
||||
U[world_state.json]
|
||||
V[provenance.json]
|
||||
end
|
||||
|
||||
B -.->|WebSocket| G
|
||||
M -.->|Events| G
|
||||
N -.->|Events| G
|
||||
O -.->|Events| G
|
||||
G -.->|Broadcast| B
|
||||
|
||||
S --> B
|
||||
T --> B
|
||||
U --> H
|
||||
V --> H
|
||||
```
|
||||
|
||||
## Entry Points
|
||||
|
||||
### Primary Entry: Browser Frontend
|
||||
- **File**: `index.html` → `app.js`
|
||||
- **Purpose**: Three.js 3D world with portal navigation, memory visualization, agent presence
|
||||
- **Key Functions**: `init()`, `animate()`, `loadPortals()`, `setupWebSocket()`
|
||||
|
||||
### Secondary Entry: WebSocket Gateway
|
||||
- **File**: `server.py`
|
||||
- **Purpose**: Central hub connecting mind (nexus_think), body (harnesses), and visualization
|
||||
- **Key Functions**: `broadcast_handler()`, `main()`
|
||||
|
||||
### Tertiary Entry: Consciousness Loop
|
||||
- **File**: `nexus/nexus_think.py`
|
||||
- **Purpose**: Embodied perceive→think→act loop for Timmy's consciousness
|
||||
- **Key Class**: `NexusMind` with `start()`, `think_once()`, `perceive()`, `act()`
|
||||
|
||||
### CLI Entry Points
|
||||
```bash
|
||||
# Start WebSocket gateway
|
||||
python3 server.py
|
||||
|
||||
# Start consciousness loop
|
||||
python3 nexus/nexus_think.py --ws ws://localhost:8765 --model timmy:v0.1-q4
|
||||
|
||||
# Run tests
|
||||
python3 -m pytest tests/ -v
|
||||
|
||||
# Build/deploy
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
## Data Flow
|
||||
|
||||
```
|
||||
1. Browser loads index.html → app.js
|
||||
2. app.js initializes Three.js scene, loads portals.json/vision.json
|
||||
3. WebSocket connects to server.py gateway
|
||||
4. Gateway receives messages from:
|
||||
- Browser (user input, navigation)
|
||||
- nexus_think.py (Timmy's thoughts/actions)
|
||||
- Game harnesses (Morrowind/Bannerlord events)
|
||||
5. Gateway broadcasts messages to all connected clients
|
||||
6. nexus_think.py receives perceptions via PerceptionAdapter
|
||||
7. NexusMind processes perceptions through Ollama model
|
||||
8. Generated actions sent back through gateway to browser/harnesses
|
||||
9. Experience stored in ExperienceStore, trajectories logged
|
||||
10. Heartbeat written to ~/.nexus/heartbeat.json for watchdog monitoring
|
||||
```
|
||||
|
||||
## Key Abstractions
|
||||
|
||||
### 1. NexusMind (`nexus/nexus_think.py`)
|
||||
- **Purpose**: Embodied consciousness loop - perceive, think, act
|
||||
- **Interface**: `start()`, `stop()`, `think_once()`, `perceive()`, `act()`
|
||||
- **Dependencies**: Ollama, websockets, PerceptionBuffer, ExperienceStore
|
||||
|
||||
### 2. PerceptionBuffer (`nexus/perception_adapter.py`)
|
||||
- **Purpose**: Buffer and process incoming WebSocket messages into structured perceptions
|
||||
- **Interface**: `add()`, `get_recent()`, `to_prompt_context()`
|
||||
- **Dependencies**: None (pure data structure)
|
||||
|
||||
### 3. SpatialMemory (`nexus/components/spatial-memory.js`)
|
||||
- **Purpose**: 3D memory crystal system - place, connect, visualize memories in space
|
||||
- **Interface**: `placeMemory()`, `connectMemories()`, `setRegionVisibility()`
|
||||
- **Dependencies**: Three.js
|
||||
|
||||
### 4. Portal System (`portals.json` + app.js)
|
||||
- **Purpose**: Navigation between virtual worlds (Morrowind, Bannerlord, Evennia)
|
||||
- **Interface**: Portal registry schema, proximity detection, overlay UI
|
||||
- **Dependencies**: Three.js, WebSocket gateway
|
||||
|
||||
### 5. MemPalace (`mempalace/`)
|
||||
- **Purpose**: Persistent memory storage with room/wing taxonomy
|
||||
- **Interface**: Room CRUD, search, tunnel sync, privacy audit
|
||||
- **Dependencies**: SQLite, filesystem
|
||||
|
||||
## API Surface
|
||||
|
||||
### WebSocket Protocol (port 8765)
|
||||
```json
|
||||
// Perception from browser
|
||||
{
|
||||
"type": "perception",
|
||||
"data": {
|
||||
"position": {"x": 0, "y": 2, "z": 0},
|
||||
"nearby_portals": ["morrowind"],
|
||||
"user_input": "Hello Timmy"
|
||||
}
|
||||
}
|
||||
|
||||
// Action from nexus_think
|
||||
{
|
||||
"type": "action",
|
||||
"data": {
|
||||
"move_to": {"x": 10, "y": 0, "z": 5},
|
||||
"speak": "Greetings, traveler",
|
||||
"interact_with": "portal:morrowind"
|
||||
}
|
||||
}
|
||||
|
||||
// Game event from harness
|
||||
{
|
||||
"type": "game_event",
|
||||
"source": "morrowind",
|
||||
"data": {
|
||||
"event": "player_death",
|
||||
"location": "Balmora"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Python API
|
||||
```python
|
||||
# nexus_think.py
|
||||
from nexus.nexus_think import NexusMind
|
||||
mind = NexusMind(model="timmy:v0.1-q4")
|
||||
mind.start()
|
||||
|
||||
# perception_adapter.py
|
||||
from nexus.perception_adapter import ws_to_perception, PerceptionBuffer
|
||||
buffer = PerceptionBuffer(max_size=50)
|
||||
perception = ws_to_perception(ws_message)
|
||||
|
||||
# experience_store.py
|
||||
from nexus.experience_store import ExperienceStore
|
||||
store = ExperienceStore(db_path=Path("experiences.db"))
|
||||
store.save(perception, action, result)
|
||||
```
|
||||
|
||||
### CLI Commands
|
||||
```bash
|
||||
# Start services
|
||||
python3 server.py
|
||||
python3 nexus/nexus_think.py --ws ws://localhost:8765
|
||||
|
||||
# MemPalace operations
|
||||
python3 scripts/mempalace_export.py
|
||||
python3 scripts/validate_mempalace_taxonomy.py
|
||||
|
||||
# Health checks
|
||||
python3 scripts/lazarus_watchdog.py
|
||||
python3 scripts/flake_detector.py
|
||||
```
|
||||
|
||||
## Test Coverage Gaps
|
||||
|
||||
### Current State
|
||||
- **Unit tests**: ✅ 457 passing
|
||||
- **Integration tests**: ⚠️ 5 failing
|
||||
- **E2E tests**: ❌ Browser smoke tests failing
|
||||
- **Collection errors**: 2 files with import issues
|
||||
|
||||
### Missing Tests
|
||||
1. **WebSocket gateway load testing** - No tests for concurrent connections
|
||||
2. **Portal system navigation flow** - No E2E tests for portal transitions
|
||||
3. **Memory persistence across restarts** - No tests for MemPalace recovery
|
||||
4. **Game harness reconnection** - No tests for harness crash recovery
|
||||
5. **Multi-agent coordination** - No tests for multiple NexusMind instances
|
||||
|
||||
### Failing Tests (Immediate Action Required)
|
||||
1. `test_browser_smoke.py::TestDOMContract::test_element_exists[spatial-search-div]` - Missing DOM element
|
||||
2. `test_browser_smoke.py::TestLoadingFlow::test_loading_screen_transitions` - Loading screen behavior changed
|
||||
3. `test_portal_registry_schema.py::test_portals_json_uses_expanded_registry_schema` - Schema validation failing
|
||||
4. `test_nexus_watchdog.py::TestRunHealthChecks::test_returns_report_with_all_checks` - Health check report format
|
||||
5. `test_provenance.py::test_provenance_hashes_match` - Provenance hash mismatch
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### 1. WebSocket Gateway Exposure
|
||||
- **Risk**: Gateway listens on 0.0.0.0:8765 - accessible from network
|
||||
- **Mitigation**: Bind to 127.0.0.1 for local-only, add authentication for remote access
|
||||
- **Status**: ⚠️ Currently open
|
||||
|
||||
### 2. Input Validation
|
||||
- **Risk**: WebSocket messages not validated - potential injection attacks
|
||||
- **Mitigation**: Add JSON schema validation for all message types
|
||||
- **Status**: ❌ No validation
|
||||
|
||||
### 3. Model Input Sanitization
|
||||
- **Risk**: User input passed directly to Ollama model
|
||||
- **Mitigation**: Sanitize inputs, limit length, filter dangerous patterns
|
||||
- **Status**: ⚠️ Basic length limits only
|
||||
|
||||
### 4. Filesystem Access
|
||||
- **Risk**: MemPalace and ExperienceStore write to filesystem without sandboxing
|
||||
- **Mitigation**: Restrict paths, add permission checks
|
||||
- **Status**: ⚠️ Path validation missing
|
||||
|
||||
### 5. Dependency Security
|
||||
- **Risk**: No dependency scanning or vulnerability checks
|
||||
- **Mitigation**: Add safety checks, pin versions, regular updates
|
||||
- **Status**: ❌ No scanning
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Build Dependencies
|
||||
- Python 3.12+
|
||||
- Node.js (for frontend tooling, optional)
|
||||
- Three.js (bundled in app.js)
|
||||
|
||||
### Runtime Dependencies
|
||||
- **Python**: websockets, requests, sqlite3, asyncio
|
||||
- **Frontend**: Three.js (r158+), EffectComposer, UnrealBloomPass, SMAAPass
|
||||
- **AI**: Ollama (local), Groq API (optional)
|
||||
- **Game Harnesses**: OpenMW (Morrowind), Mount & Blade II (Bannerlord)
|
||||
|
||||
### External Services
|
||||
- Ollama (local LLM inference)
|
||||
- Groq API (optional cloud inference)
|
||||
- Gitea (issue tracking, CI)
|
||||
- Hermes (agent harness)
|
||||
|
||||
## Deployment
|
||||
|
||||
### Local Development
|
||||
```bash
|
||||
# Clone and setup
|
||||
git clone https://forge.alexanderwhitestone.com/Timmy_Foundation/the-nexus.git
|
||||
cd the-nexus
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Start WebSocket gateway
|
||||
python3 server.py
|
||||
|
||||
# In another terminal, start consciousness
|
||||
python3 nexus/nexus_think.py --ws ws://localhost:8765
|
||||
|
||||
# Open browser to http://localhost:8765 (serves index.html)
|
||||
```
|
||||
|
||||
### Production Deployment
|
||||
```bash
|
||||
# Deploy to VPS
|
||||
./deploy.sh
|
||||
|
||||
# Or with Docker
|
||||
docker-compose up -d
|
||||
|
||||
# Systemd service
|
||||
sudo cp systemd/nexus-*.service /etc/systemd/system/
|
||||
sudo systemctl enable nexus-gateway nexus-think
|
||||
sudo systemctl start nexus-gateway nexus-think
|
||||
```
|
||||
|
||||
### Health Monitoring
|
||||
```bash
|
||||
# Check heartbeat
|
||||
cat ~/.nexus/heartbeat.json
|
||||
|
||||
# Run health checks
|
||||
python3 scripts/lazarus_watchdog.py
|
||||
|
||||
# Monitor logs
|
||||
journalctl -u nexus-gateway -f
|
||||
```
|
||||
|
||||
## Architecture Decisions
|
||||
|
||||
### 1. Local-First Design
|
||||
- All AI inference runs locally via Ollama
|
||||
- No mandatory cloud dependencies
|
||||
- Data stays on user's machine
|
||||
|
||||
### 2. WebSocket Broadcast Architecture
|
||||
- Simple hub-and-spoke model
|
||||
- All clients receive all messages
|
||||
- Easy to add new components
|
||||
|
||||
### 3. Embodied AI Loop
|
||||
- Perceive→Think→Act cycle
|
||||
- 30-second think interval
|
||||
- Context-limited for 8B model
|
||||
|
||||
### 4. Plugin Harness System
|
||||
- Game worlds as separate processes
|
||||
- Standardized event protocol
|
||||
- Crash isolation
|
||||
|
||||
### 5. Memory as Spatial Experience
|
||||
- Memories placed in 3D space
|
||||
- Visual and audio cues
|
||||
- Persistent across sessions
|
||||
|
||||
## Technical Debt
|
||||
|
||||
### 1. Frontend Bundle Size
|
||||
- `app.js` is 140KB unminified
|
||||
- No tree shaking or code splitting
|
||||
- Consider ES modules and bundler
|
||||
|
||||
### 2. Test Infrastructure
|
||||
- 2 collection errors blocking full test suite
|
||||
- Browser smoke tests depend on specific DOM structure
|
||||
- Need better test isolation
|
||||
|
||||
### 3. Configuration Management
|
||||
- Hardcoded ports and URLs
|
||||
- No environment-based configuration
|
||||
- Need config.py with environment overrides
|
||||
|
||||
### 4. Error Handling
|
||||
- WebSocket errors not gracefully handled
|
||||
- Harness crash recovery missing
|
||||
- Need circuit breakers and retry logic
|
||||
|
||||
### 5. Documentation
|
||||
- Code comments sparse
|
||||
- API documentation incomplete
|
||||
- Need auto-generated docs from docstrings
|
||||
|
||||
## Migration Status
|
||||
|
||||
### Completed
|
||||
- ✅ Core WebSocket gateway
|
||||
- ✅ Three.js 3D world foundation
|
||||
- ✅ Portal system architecture
|
||||
- ✅ Memory visualization system
|
||||
- ✅ Game harness framework
|
||||
|
||||
### In Progress
|
||||
- 🔄 Legacy Matrix audit (#685)
|
||||
- 🔄 Browser smoke test rebuild (#686)
|
||||
- 🔄 Docs truth sync (#684)
|
||||
|
||||
### Planned
|
||||
- ⏳ Portal stack rebuild (#672)
|
||||
- ⏳ Morrowind pilot loop (#673)
|
||||
- ⏳ Reflex tactical layer (#674)
|
||||
- ⏳ Context compaction (#675)
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- `README.md` - Project overview and current truth
|
||||
- `CLAUDE.md` - AI agent instructions and hard rules
|
||||
- `CONTRIBUTING.md` - Development workflow and standards
|
||||
- `POLICY.md` - Branch protection and review policy
|
||||
- `DEVELOPMENT.md` - Quick start guide
|
||||
- `BROWSER_CONTRACT.md` - Frontend API contract
|
||||
- `GAMEPORTAL_PROTOCOL.md` - Portal communication protocol
|
||||
- `EVENNIA_NEXUS_EVENT_PROTOCOL.md` - Evennia bridge protocol
|
||||
|
||||
---
|
||||
|
||||
*Generated by Codebase Genome Analysis — 2026-04-14*
|
||||
*For issues or corrections, see: https://forge.alexanderwhitestone.com/Timmy_Foundation/the-nexus/issues*
|
||||
54
config/zero_touch_forge.json
Normal file
54
config/zero_touch_forge.json
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"epic_issue": 912,
|
||||
"title": "The Zero-Touch Forge: Bare-Metal Fleet Bootstrap in 60 Minutes",
|
||||
"checks": [
|
||||
{
|
||||
"id": "os_bootstrap",
|
||||
"label": "OS bootstrap foothold",
|
||||
"required_files": ["scripts/provision-runner.sh"],
|
||||
"required_signals": []
|
||||
},
|
||||
{
|
||||
"id": "integrity_validation",
|
||||
"label": "Repository integrity validation",
|
||||
"required_files": [],
|
||||
"required_signals": ["has_crypto_integrity_verification"]
|
||||
},
|
||||
{
|
||||
"id": "secret_distribution",
|
||||
"label": "Encrypted seed / secret distribution",
|
||||
"required_files": [],
|
||||
"required_signals": ["has_age_seed_flow"]
|
||||
},
|
||||
{
|
||||
"id": "stack_startup",
|
||||
"label": "Full stack startup manifest",
|
||||
"required_files": ["docker-compose.yml", "fleet/fleet-routing.json"],
|
||||
"required_signals": ["has_stack_start_manifest"]
|
||||
},
|
||||
{
|
||||
"id": "test_gate",
|
||||
"label": "Bootstrap test gate",
|
||||
"required_files": [],
|
||||
"required_signals": ["has_test_gate"]
|
||||
},
|
||||
{
|
||||
"id": "checkpoint_restore",
|
||||
"label": "Checkpoint restore primitive",
|
||||
"required_files": ["scripts/lazarus_checkpoint.py"],
|
||||
"required_signals": []
|
||||
},
|
||||
{
|
||||
"id": "post_boot_notification",
|
||||
"label": "Post-boot notify Alexander only-after-healthy",
|
||||
"required_files": [],
|
||||
"required_signals": ["has_notification_step"]
|
||||
},
|
||||
{
|
||||
"id": "sixty_minute_sla",
|
||||
"label": "60-minute end-to-end timing budget",
|
||||
"required_files": [],
|
||||
"required_signals": ["has_sla_budget"]
|
||||
}
|
||||
]
|
||||
}
|
||||
51
docs/zero-touch-forge-readiness.md
Normal file
51
docs/zero-touch-forge-readiness.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Zero-Touch Forge Readiness
|
||||
|
||||
Epic: #912 — The Zero-Touch Forge: Bare-Metal Fleet Bootstrap in 60 Minutes
|
||||
|
||||
## Impossible Goal
|
||||
|
||||
Take a raw VPS plus only a git URL and encrypted seed, then bootstrap a full Timmy Foundation fleet in under 60 minutes with no human intervention after trigger.
|
||||
|
||||
This document does **not** claim the goal is solved. It grounds the epic in the current repo state.
|
||||
|
||||
Current primitive readiness: 2 ready / 6 blocked.
|
||||
|
||||
## Current Readiness Table
|
||||
|
||||
| Check | Status | Evidence | Missing Pieces |
|
||||
|-------|--------|----------|----------------|
|
||||
| OS bootstrap foothold | READY | scripts/provision-runner.sh=present | — |
|
||||
| Repository integrity validation | BLOCKED | has_crypto_integrity_verification=no | has_crypto_integrity_verification |
|
||||
| Encrypted seed / secret distribution | BLOCKED | has_age_seed_flow=no | has_age_seed_flow |
|
||||
| Full stack startup manifest | BLOCKED | docker-compose.yml=present, fleet/fleet-routing.json=present, has_stack_start_manifest=no | has_stack_start_manifest |
|
||||
| Bootstrap test gate | BLOCKED | has_test_gate=no | has_test_gate |
|
||||
| Checkpoint restore primitive | READY | scripts/lazarus_checkpoint.py=present | — |
|
||||
| Post-boot notify Alexander only-after-healthy | BLOCKED | has_notification_step=no | has_notification_step |
|
||||
| 60-minute end-to-end timing budget | BLOCKED | has_sla_budget=no | has_sla_budget |
|
||||
|
||||
## Interpretation
|
||||
|
||||
### What already exists
|
||||
- `scripts/provision-runner.sh` proves we already automate part of bare-metal service bootstrap.
|
||||
- `scripts/lazarus_checkpoint.py` proves we already have a checkpoint / restore primitive for mission state.
|
||||
- `docker-compose.yml`, `fleet/fleet-routing.json`, `operations/fleet-topology.md`, and `config/fleet_agents.json` show a real fleet shape, not just a philosophical wish.
|
||||
|
||||
### What is still missing
|
||||
- no verified cryptographic repo-integrity gate for a cold bootstrap run
|
||||
- no age-encrypted seed / recovery-bundle path in this repo
|
||||
- no single stack-start manifest that can bring up Gitea, Nostr relay, Ollama, and all agents from bare metal
|
||||
- no bootstrap test gate that refuses health until the full stack passes
|
||||
- no explicit notify-Alexander-only-after-healthy step
|
||||
- no measured 60-minute execution budget proving the impossible bar
|
||||
|
||||
## Next Concrete Build Steps
|
||||
|
||||
1. Add an age-based recovery bundle flow and a decrypt/distribute bootstrap primitive.
|
||||
2. Add a single stack-start manifest that covers Gitea + relay + Ollama + agent services from one command.
|
||||
3. Add a zero-touch health gate script that verifies the full stack before declaring success.
|
||||
4. Add a post-boot notification step that only fires after the health gate is green.
|
||||
5. Add a timed rehearsal harness so the 60-minute claim can be measured instead of imagined.
|
||||
|
||||
## Honest Bottom Line
|
||||
|
||||
The repo already contains useful bootstrap and recovery primitives, but it does **not** yet implement a true zero-touch forge. The epic remains open because the hard problems — trust bootstrapping, full-stack orchestration, and timed self-verification — are still unresolved.
|
||||
111
reports/night-shift-prediction-2026-04-12.md
Normal file
111
reports/night-shift-prediction-2026-04-12.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# Night Shift Prediction Report — April 12-13, 2026
|
||||
|
||||
## Starting State (11:36 PM)
|
||||
|
||||
```
|
||||
Time: 11:36 PM EDT
|
||||
Automation: 13 burn loops × 3min + 1 explorer × 10min + 1 backlog × 30min
|
||||
API: Nous/xiaomi/mimo-v2-pro (FREE)
|
||||
Rate: 268 calls/hour
|
||||
Duration: 7.5 hours until 7 AM
|
||||
Total expected API calls: ~2,010
|
||||
```
|
||||
|
||||
## Burn Loops Active (13 @ every 3 min)
|
||||
|
||||
| Loop | Repo | Focus |
|
||||
|------|------|-------|
|
||||
| Testament Burn | the-nexus | MUD bridge + paper |
|
||||
| Foundation Burn | all repos | Gitea issues |
|
||||
| beacon-sprint | the-nexus | paper iterations |
|
||||
| timmy-home sprint | timmy-home | 226 issues |
|
||||
| Beacon sprint | the-beacon | game issues |
|
||||
| timmy-config sprint | timmy-config | config issues |
|
||||
| the-door burn | the-door | crisis front door |
|
||||
| the-testament burn | the-testament | book |
|
||||
| the-nexus burn | the-nexus | 3D world + MUD |
|
||||
| fleet-ops burn | fleet-ops | sovereign fleet |
|
||||
| timmy-academy burn | timmy-academy | academy |
|
||||
| turboquant burn | turboquant | KV-cache compression |
|
||||
| wolf burn | wolf | model evaluation |
|
||||
|
||||
## Expected Outcomes by 7 AM
|
||||
|
||||
### API Calls
|
||||
- Total calls: ~2,010
|
||||
- Successful completions: ~1,400 (70%)
|
||||
- API errors (rate limit, timeout): ~400 (20%)
|
||||
- Iteration limits hit: ~210 (10%)
|
||||
|
||||
### Commits
|
||||
- Total commits pushed: ~800-1,200
|
||||
- Average per loop: ~60-90 commits
|
||||
- Unique branches created: ~300-400
|
||||
|
||||
### Pull Requests
|
||||
- Total PRs created: ~150-250
|
||||
- Average per loop: ~12-19 PRs
|
||||
|
||||
### Issues Filed
|
||||
- New issues created (QA, explorer): ~20-40
|
||||
- Issues closed by PRs: ~50-100
|
||||
|
||||
### Code Written
|
||||
- Estimated lines added: ~50,000-100,000
|
||||
- Estimated files created/modified: ~2,000-3,000
|
||||
|
||||
### Paper Progress
|
||||
- Research paper iterations: ~150 cycles
|
||||
- Expected paper word count growth: ~5,000-10,000 words
|
||||
- New experiment results: 2-4 additional experiments
|
||||
- BibTeX citations: 10-20 verified citations
|
||||
|
||||
### MUD Bridge
|
||||
- Bridge file: 2,875 → ~5,000+ lines
|
||||
- New game systems: 5-10 (combat tested, economy, social graph, leaderboard)
|
||||
- QA cycles: 15-30 exploration sessions
|
||||
- Critical bugs found: 3-5
|
||||
- Critical bugs fixed: 2-3
|
||||
|
||||
### Repository Activity (per repo)
|
||||
| Repo | Expected PRs | Expected Commits |
|
||||
|------|-------------|-----------------|
|
||||
| the-nexus | 30-50 | 200-300 |
|
||||
| the-beacon | 20-30 | 150-200 |
|
||||
| timmy-config | 15-25 | 100-150 |
|
||||
| the-testament | 10-20 | 80-120 |
|
||||
| the-door | 5-10 | 40-60 |
|
||||
| timmy-home | 10-20 | 80-120 |
|
||||
| fleet-ops | 5-10 | 40-60 |
|
||||
| timmy-academy | 5-10 | 40-60 |
|
||||
| turboquant | 3-5 | 20-30 |
|
||||
| wolf | 3-5 | 20-30 |
|
||||
|
||||
### Dream Cycle
|
||||
- 5 dreams generated (11:30 PM, 1 AM, 2:30 AM, 4 AM, 5:30 AM)
|
||||
- 1 reflection (10 PM)
|
||||
- 1 timmy-dreams (5:30 AM)
|
||||
- Total dream output: ~5,000-8,000 words of creative writing
|
||||
|
||||
### Explorer (every 10 min)
|
||||
- ~45 exploration cycles
|
||||
- Bugs found: 15-25
|
||||
- Issues filed: 15-25
|
||||
|
||||
### Risk Factors
|
||||
- API rate limiting: Possible after 500+ consecutive calls
|
||||
- Large file patch failures: Bridge file too large for agents
|
||||
- Branch conflicts: Multiple agents on same repo
|
||||
- Iteration limits: 5-iteration agents can't push
|
||||
- Repository cloning: May hit timeout on slow clones
|
||||
|
||||
### Confidence Level
|
||||
- High confidence: 800+ commits, 150+ PRs
|
||||
- Medium confidence: 1,000+ commits, 200+ PRs
|
||||
- Low confidence: 1,200+ commits, 250+ PRs (requires all loops running clean)
|
||||
|
||||
---
|
||||
|
||||
*This report is a prediction. The 7 AM morning report will compare actual results.*
|
||||
*Generated: 2026-04-12 23:36 EDT*
|
||||
*Author: Timmy (pre-shift prediction)*
|
||||
187
scripts/zero_touch_forge_readiness.py
Normal file
187
scripts/zero_touch_forge_readiness.py
Normal file
@@ -0,0 +1,187 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Zero-Touch Forge readiness grounding for epic #912.
|
||||
|
||||
This does not pretend the impossible goal is solved.
|
||||
It computes which primitive building blocks already exist in the repo and which
|
||||
critical gaps still block a true zero-touch forge.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
SPEC_PATH = REPO_ROOT / "config" / "zero_touch_forge.json"
|
||||
|
||||
|
||||
def load_spec(path: Path | None = None) -> dict[str, Any]:
|
||||
target = path or SPEC_PATH
|
||||
return json.loads(target.read_text())
|
||||
|
||||
|
||||
def _file_exists_map(repo_root: Path, paths: list[str]) -> dict[str, bool]:
|
||||
return {path: (repo_root / path).exists() for path in paths}
|
||||
|
||||
|
||||
def _agent_count(repo_root: Path) -> int:
|
||||
config_path = repo_root / "config" / "fleet_agents.json"
|
||||
if not config_path.exists():
|
||||
return 0
|
||||
try:
|
||||
payload = json.loads(config_path.read_text())
|
||||
return len(payload.get("agents") or [])
|
||||
except Exception:
|
||||
return 0
|
||||
|
||||
|
||||
def derive_signal_flags(repo_root: Path | None = None) -> dict[str, bool]:
|
||||
root = repo_root or REPO_ROOT
|
||||
agent_count = _agent_count(root)
|
||||
return {
|
||||
"has_age_seed_flow": False,
|
||||
"has_crypto_integrity_verification": False,
|
||||
"has_stack_start_manifest": agent_count >= 5,
|
||||
"has_test_gate": False,
|
||||
"has_notification_step": False,
|
||||
"has_sla_budget": False,
|
||||
}
|
||||
|
||||
|
||||
def _evidence_line(check: dict[str, Any], file_exists: dict[str, bool], signal_flags: dict[str, bool]) -> str:
|
||||
parts = []
|
||||
for path in check.get("required_files", []):
|
||||
parts.append(f"{path}={'present' if file_exists.get(path) else 'missing'}")
|
||||
for key in check.get("required_signals", []):
|
||||
parts.append(f"{key}={'yes' if signal_flags.get(key) else 'no'}")
|
||||
return ", ".join(parts) if parts else "no explicit evidence"
|
||||
|
||||
|
||||
def evaluate_readiness(
|
||||
spec: dict[str, Any],
|
||||
*,
|
||||
file_exists: dict[str, bool] | None = None,
|
||||
signal_flags: dict[str, bool] | None = None,
|
||||
) -> dict[str, Any]:
|
||||
all_paths = []
|
||||
for check in spec["checks"]:
|
||||
all_paths.extend(check.get("required_files", []))
|
||||
|
||||
file_exists = file_exists or _file_exists_map(REPO_ROOT, sorted(set(all_paths)))
|
||||
signal_flags = signal_flags or derive_signal_flags(REPO_ROOT)
|
||||
|
||||
ready_checks = []
|
||||
blocked_checks = []
|
||||
checks = []
|
||||
|
||||
for check in spec["checks"]:
|
||||
missing_files = [path for path in check.get("required_files", []) if not file_exists.get(path, False)]
|
||||
missing_signals = [key for key in check.get("required_signals", []) if not signal_flags.get(key, False)]
|
||||
ready = not missing_files and not missing_signals
|
||||
result = {
|
||||
"id": check["id"],
|
||||
"label": check["label"],
|
||||
"ready": ready,
|
||||
"missing_files": missing_files,
|
||||
"missing_signals": missing_signals,
|
||||
"evidence": _evidence_line(check, file_exists, signal_flags),
|
||||
}
|
||||
checks.append(result)
|
||||
if ready:
|
||||
ready_checks.append(result)
|
||||
else:
|
||||
blocked_checks.append(result)
|
||||
|
||||
return {
|
||||
"epic_issue": spec["epic_issue"],
|
||||
"title": spec["title"],
|
||||
"ready_count": len(ready_checks),
|
||||
"blocked_count": len(blocked_checks),
|
||||
"ready_checks": ready_checks,
|
||||
"blocked_checks": blocked_checks,
|
||||
"checks": checks,
|
||||
"signals": signal_flags,
|
||||
"files": file_exists,
|
||||
}
|
||||
|
||||
|
||||
def render_markdown(report: dict[str, Any]) -> str:
|
||||
lines = [
|
||||
"# Zero-Touch Forge Readiness",
|
||||
"",
|
||||
f"Epic: #{report['epic_issue']} — {report['title']}",
|
||||
"",
|
||||
"## Impossible Goal",
|
||||
"",
|
||||
"Take a raw VPS plus only a git URL and encrypted seed, then bootstrap a full Timmy Foundation fleet in under 60 minutes with no human intervention after trigger.",
|
||||
"",
|
||||
"This document does **not** claim the goal is solved. It grounds the epic in the current repo state.",
|
||||
"",
|
||||
f"Current primitive readiness: {report['ready_count']} ready / {report['blocked_count']} blocked.",
|
||||
"",
|
||||
"## Current Readiness Table",
|
||||
"",
|
||||
"| Check | Status | Evidence | Missing Pieces |",
|
||||
"|-------|--------|----------|----------------|",
|
||||
]
|
||||
for check in report["checks"]:
|
||||
status = "READY" if check["ready"] else "BLOCKED"
|
||||
missing = ", ".join(check["missing_files"] + check["missing_signals"]) or "—"
|
||||
lines.append(f"| {check['label']} | {status} | {check['evidence']} | {missing} |")
|
||||
|
||||
lines.extend([
|
||||
"",
|
||||
"## Interpretation",
|
||||
"",
|
||||
"### What already exists",
|
||||
"- `scripts/provision-runner.sh` proves we already automate part of bare-metal service bootstrap.",
|
||||
"- `scripts/lazarus_checkpoint.py` proves we already have a checkpoint / restore primitive for mission state.",
|
||||
"- `docker-compose.yml`, `fleet/fleet-routing.json`, `operations/fleet-topology.md`, and `config/fleet_agents.json` show a real fleet shape, not just a philosophical wish.",
|
||||
"",
|
||||
"### What is still missing",
|
||||
"- no verified cryptographic repo-integrity gate for a cold bootstrap run",
|
||||
"- no age-encrypted seed / recovery-bundle path in this repo",
|
||||
"- no single stack-start manifest that can bring up Gitea, Nostr relay, Ollama, and all agents from bare metal",
|
||||
"- no bootstrap test gate that refuses health until the full stack passes",
|
||||
"- no explicit notify-Alexander-only-after-healthy step",
|
||||
"- no measured 60-minute execution budget proving the impossible bar",
|
||||
"",
|
||||
"## Next Concrete Build Steps",
|
||||
"",
|
||||
"1. Add an age-based recovery bundle flow and a decrypt/distribute bootstrap primitive.",
|
||||
"2. Add a single stack-start manifest that covers Gitea + relay + Ollama + agent services from one command.",
|
||||
"3. Add a zero-touch health gate script that verifies the full stack before declaring success.",
|
||||
"4. Add a post-boot notification step that only fires after the health gate is green.",
|
||||
"5. Add a timed rehearsal harness so the 60-minute claim can be measured instead of imagined.",
|
||||
"",
|
||||
"## Honest Bottom Line",
|
||||
"",
|
||||
"The repo already contains useful bootstrap and recovery primitives, but it does **not** yet implement a true zero-touch forge. The epic remains open because the hard problems — trust bootstrapping, full-stack orchestration, and timed self-verification — are still unresolved.",
|
||||
"",
|
||||
])
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(description="Evaluate repo readiness for the Zero-Touch Forge epic.")
|
||||
parser.add_argument("--json", action="store_true", help="Emit JSON instead of markdown")
|
||||
parser.add_argument("--out", type=Path, help="Optional output file")
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main() -> None:
|
||||
args = parse_args()
|
||||
spec = load_spec()
|
||||
report = evaluate_readiness(spec)
|
||||
output = json.dumps(report, indent=2) if args.json else render_markdown(report)
|
||||
if args.out:
|
||||
args.out.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.out.write_text(output)
|
||||
else:
|
||||
print(output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
25
tests/test_night_shift_prediction_report.py
Normal file
25
tests/test_night_shift_prediction_report.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
REPORT = Path("reports/night-shift-prediction-2026-04-12.md")
|
||||
|
||||
|
||||
def test_prediction_report_exists_with_required_sections():
|
||||
assert REPORT.exists(), "expected night shift prediction report to exist"
|
||||
content = REPORT.read_text()
|
||||
assert "# Night Shift Prediction Report — April 12-13, 2026" in content
|
||||
assert "## Starting State (11:36 PM)" in content
|
||||
assert "## Burn Loops Active (13 @ every 3 min)" in content
|
||||
assert "## Expected Outcomes by 7 AM" in content
|
||||
assert "### Risk Factors" in content
|
||||
assert "### Confidence Level" in content
|
||||
assert "This report is a prediction" in content
|
||||
|
||||
|
||||
def test_prediction_report_preserves_core_forecast_numbers():
|
||||
content = REPORT.read_text()
|
||||
assert "Total expected API calls: ~2,010" in content
|
||||
assert "Total commits pushed: ~800-1,200" in content
|
||||
assert "Total PRs created: ~150-250" in content
|
||||
assert "the-nexus | 30-50 | 200-300" in content
|
||||
assert "Generated: 2026-04-12 23:36 EDT" in content
|
||||
67
tests/test_zero_touch_forge_readiness.py
Normal file
67
tests/test_zero_touch_forge_readiness.py
Normal file
@@ -0,0 +1,67 @@
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||
|
||||
from scripts.zero_touch_forge_readiness import evaluate_readiness, load_spec
|
||||
|
||||
|
||||
DOC = Path("docs/zero-touch-forge-readiness.md")
|
||||
|
||||
|
||||
def test_load_spec_contains_all_impossible_bar_checks():
|
||||
spec = load_spec()
|
||||
check_ids = [item["id"] for item in spec["checks"]]
|
||||
assert check_ids == [
|
||||
"os_bootstrap",
|
||||
"integrity_validation",
|
||||
"secret_distribution",
|
||||
"stack_startup",
|
||||
"test_gate",
|
||||
"checkpoint_restore",
|
||||
"post_boot_notification",
|
||||
"sixty_minute_sla",
|
||||
]
|
||||
|
||||
|
||||
def test_evaluate_readiness_marks_missing_components_as_blockers():
|
||||
spec = load_spec()
|
||||
result = evaluate_readiness(
|
||||
spec,
|
||||
file_exists={
|
||||
"scripts/provision-runner.sh": True,
|
||||
"scripts/lazarus_checkpoint.py": True,
|
||||
"operations/fleet-topology.md": True,
|
||||
"docker-compose.yml": False,
|
||||
"fleet/fleet-routing.json": False,
|
||||
"tests/test_bootstrap_contract.py": False,
|
||||
},
|
||||
signal_flags={
|
||||
"has_age_seed_flow": False,
|
||||
"has_crypto_integrity_verification": False,
|
||||
"has_stack_start_manifest": False,
|
||||
"has_test_gate": False,
|
||||
"has_notification_step": False,
|
||||
"has_sla_budget": False,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["ready_count"] == 2
|
||||
blocked = {item["id"] for item in result["blocked_checks"]}
|
||||
assert blocked == {
|
||||
"integrity_validation",
|
||||
"secret_distribution",
|
||||
"stack_startup",
|
||||
"test_gate",
|
||||
"post_boot_notification",
|
||||
"sixty_minute_sla",
|
||||
}
|
||||
|
||||
|
||||
def test_document_exists_with_required_sections():
|
||||
assert DOC.exists(), "expected zero-touch forge readiness doc to exist"
|
||||
content = DOC.read_text()
|
||||
assert "# Zero-Touch Forge Readiness" in content
|
||||
assert "## Impossible Goal" in content
|
||||
assert "## Current Readiness Table" in content
|
||||
assert "## Next Concrete Build Steps" in content
|
||||
Reference in New Issue
Block a user