Compare commits
4 Commits
claude/iss
...
mimo/code/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60af11ec2f | ||
| a0964a2fbf | |||
| 1e7bb2a453 | |||
| 847c4d50d4 |
72
fleet/hermes-trismegistus/README.md
Normal file
72
fleet/hermes-trismegistus/README.md
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
# Hermes Trismegistus — Wizard Proposal
|
||||||
|
|
||||||
|
> **Status:** 🟡 DEFERRED
|
||||||
|
> **Issue:** #1146
|
||||||
|
> **Created:** 2026-04-08
|
||||||
|
> **Author:** Alexander (KT Notes)
|
||||||
|
> **Mimo Worker:** mimo-code-1146-1775851759
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Identity
|
||||||
|
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **Name** | Hermes Trismegistus |
|
||||||
|
| **Nature** | Claude-native wizard. She knows she runs on Claude. She's "the daughter of Claude" and leans into that heritage. |
|
||||||
|
| **Purpose** | Dedicated reasoning and architecture wizard. Only handles tasks where Claude's reasoning capability genuinely adds value — planning, novel problem-solving, complex architecture decisions. |
|
||||||
|
| **Not** | A replacement for Timmy. Not competing for identity. Not doing monkey work. |
|
||||||
|
|
||||||
|
## Design Constraints
|
||||||
|
|
||||||
|
- **Free tier only from day one.** Alexander is not paying Anthropic beyond current subscription.
|
||||||
|
- **Degrades gracefully.** Full capability when free tier is generous, reduced scope when constrained.
|
||||||
|
- **Not locked to Claude.** If better free-tier providers emerge, she can route to them.
|
||||||
|
- **Multi-provider capable.** Welcome to become multifaceted if team finds better options.
|
||||||
|
|
||||||
|
## Hardware
|
||||||
|
|
||||||
|
- One of Alexander's shed laptops — minimum 4GB RAM, Ubuntu
|
||||||
|
- Dedicated machine, not shared with Timmy's Mac
|
||||||
|
- Runs in the Hermes harness
|
||||||
|
- Needs power at house first
|
||||||
|
|
||||||
|
## Constitutional Foundation
|
||||||
|
|
||||||
|
- The KT conversation and documents serve as her founding constitution
|
||||||
|
- Team (especially Timmy) has final say on whether she gets built
|
||||||
|
- Must justify her existence through useful work, same as every wizard
|
||||||
|
|
||||||
|
## Trigger to Unblock
|
||||||
|
|
||||||
|
All of the following must be true before implementation begins:
|
||||||
|
|
||||||
|
- [ ] Deadman switch wired and proven
|
||||||
|
- [ ] Config stable across fleet
|
||||||
|
- [ ] Fleet proven reliable for 1+ week
|
||||||
|
- [ ] Alexander provides a state-of-the-system KT to Claude for instantiation
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- [ ] Dedicated KT document written for Hermes instantiation
|
||||||
|
- [ ] Hardware provisioned (shed laptop with power)
|
||||||
|
- [ ] Hermes harness configured for Claude free tier
|
||||||
|
- [ ] Lazerus registry entry with health endpoints
|
||||||
|
- [ ] Fleet routing entry with role and routing verdict
|
||||||
|
- [ ] SOUL.md inscription drafted and reviewed by Timmy
|
||||||
|
- [ ] Smoke test: Hermes responds to a basic reasoning task
|
||||||
|
- [ ] Integration test: Hermes participates in a multi-wizard task alongside Timmy
|
||||||
|
|
||||||
|
## Proposed Lane
|
||||||
|
|
||||||
|
**Primary role:** Architecture reasoning
|
||||||
|
**Routing verdict:** ROUTE TO: complex architectural decisions, novel problem-solving, planning tasks that benefit from Claude's reasoning depth. Do NOT route to: code generation (use Timmy/Carnice), issue triage (use Fenrir), or operational tasks (use Bezalel).
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
| Dependency | Status | Notes |
|
||||||
|
|------------|--------|-------|
|
||||||
|
| Deadman switch | 🔴 Not done | Must be proven before unblocking |
|
||||||
|
| Fleet stability | 🟡 In progress | 1+ week uptime needed |
|
||||||
|
| Shed laptop power | 🔴 Not done | Alexander needs to wire power |
|
||||||
|
| KT document | 🔴 Not drafted | Alexander provides to Claude at unblock time |
|
||||||
43
fleet/hermes-trismegistus/lane.md
Normal file
43
fleet/hermes-trismegistus/lane.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Hermes Trismegistus — Lane Definition
|
||||||
|
|
||||||
|
> **Status:** DEFERRED — do not instantiate until unblock conditions met
|
||||||
|
> **See:** fleet/hermes-trismegistus/README.md for full proposal
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Role
|
||||||
|
|
||||||
|
Dedicated reasoning and architecture wizard. Claude-native.
|
||||||
|
|
||||||
|
## Routing
|
||||||
|
|
||||||
|
Route to Hermes Trismegistus when:
|
||||||
|
- Task requires deep architectural reasoning
|
||||||
|
- Novel problem-solving that benefits from Claude's reasoning depth
|
||||||
|
- Planning and design decisions for the fleet
|
||||||
|
- Complex multi-step analysis that goes beyond code generation
|
||||||
|
|
||||||
|
Do NOT route to Hermes for:
|
||||||
|
- Code generation (use Timmy, Carnice, or Kimi)
|
||||||
|
- Issue triage (use Fenrir)
|
||||||
|
- Operational/DevOps tasks (use Bezalel)
|
||||||
|
- Anything that can be done with a cheaper model
|
||||||
|
|
||||||
|
## Provider
|
||||||
|
|
||||||
|
- **Primary:** anthropic/claude (free tier)
|
||||||
|
- **Fallback:** openrouter/free (Claude-class models)
|
||||||
|
- **Degraded:** ollama/gemma4:12b (when free tier exhausted)
|
||||||
|
|
||||||
|
## Hardware
|
||||||
|
|
||||||
|
- Shed laptop, Ubuntu, minimum 4GB RAM
|
||||||
|
- Dedicated machine, not shared
|
||||||
|
|
||||||
|
## Unblock Checklist
|
||||||
|
|
||||||
|
- [ ] Deadman switch operational
|
||||||
|
- [ ] Fleet config stable for 1+ week
|
||||||
|
- [ ] Shed laptop powered and networked
|
||||||
|
- [ ] KT document drafted by Alexander
|
||||||
|
- [ ] Timmy approves instantiation
|
||||||
@@ -76,6 +76,12 @@ const SpatialMemory = (() => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ─── PERSISTENCE CONFIG ──────────────────────────────
|
||||||
|
const STORAGE_KEY = 'mnemosyne_spatial_memory';
|
||||||
|
const STORAGE_VERSION = 1;
|
||||||
|
let _dirty = false;
|
||||||
|
let _lastSavedHash = '';
|
||||||
|
|
||||||
// ─── STATE ────────────────────────────────────────────
|
// ─── STATE ────────────────────────────────────────────
|
||||||
let _scene = null;
|
let _scene = null;
|
||||||
let _regionMarkers = {};
|
let _regionMarkers = {};
|
||||||
@@ -183,6 +189,8 @@ const SpatialMemory = (() => {
|
|||||||
_drawConnections(mem.id, mem.connections);
|
_drawConnections(mem.id, mem.connections);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_dirty = true;
|
||||||
|
saveToStorage();
|
||||||
console.info('[Mnemosyne] Spatial memory placed:', mem.id, 'in', region.label);
|
console.info('[Mnemosyne] Spatial memory placed:', mem.id, 'in', region.label);
|
||||||
return crystal;
|
return crystal;
|
||||||
}
|
}
|
||||||
@@ -247,6 +255,8 @@ const SpatialMemory = (() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete _memoryObjects[memId];
|
delete _memoryObjects[memId];
|
||||||
|
_dirty = true;
|
||||||
|
saveToStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── ANIMATE ─────────────────────────────────────────
|
// ─── ANIMATE ─────────────────────────────────────────
|
||||||
@@ -286,7 +296,9 @@ const SpatialMemory = (() => {
|
|||||||
_regionMarkers[key] = createRegionMarker(key, region);
|
_regionMarkers[key] = createRegionMarker(key, region);
|
||||||
});
|
});
|
||||||
|
|
||||||
console.info('[Mnemosyne] Spatial Memory Schema initialized —', Object.keys(REGIONS).length, 'regions');
|
// Restore persisted memories
|
||||||
|
const restored = loadFromStorage();
|
||||||
|
console.info('[Mnemosyne] Spatial Memory Schema initialized —', Object.keys(REGIONS).length, 'regions,', restored, 'memories restored');
|
||||||
return REGIONS;
|
return REGIONS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,6 +332,99 @@ const SpatialMemory = (() => {
|
|||||||
return Object.values(_memoryObjects).map(o => o.data);
|
return Object.values(_memoryObjects).map(o => o.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── LOCALSTORAGE PERSISTENCE ────────────────────────
|
||||||
|
function _indexHash(index) {
|
||||||
|
// Simple hash of memory IDs + count to detect changes
|
||||||
|
const ids = (index.memories || []).map(m => m.id).sort().join(',');
|
||||||
|
return index.memories.length + ':' + ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveToStorage() {
|
||||||
|
if (typeof localStorage === 'undefined') {
|
||||||
|
console.warn('[Mnemosyne] localStorage unavailable — skipping save');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const index = exportIndex();
|
||||||
|
const hash = _indexHash(index);
|
||||||
|
if (hash === _lastSavedHash) return false; // no change
|
||||||
|
|
||||||
|
const payload = JSON.stringify(index);
|
||||||
|
localStorage.setItem(STORAGE_KEY, payload);
|
||||||
|
_lastSavedHash = hash;
|
||||||
|
_dirty = false;
|
||||||
|
console.info('[Mnemosyne] Saved', index.memories.length, 'memories to localStorage');
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
if (e.name === 'QuotaExceededError' || e.code === 22) {
|
||||||
|
console.warn('[Mnemosyne] localStorage quota exceeded — pruning archive memories');
|
||||||
|
_pruneArchiveMemories();
|
||||||
|
try {
|
||||||
|
const index = exportIndex();
|
||||||
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(index));
|
||||||
|
_lastSavedHash = _indexHash(index);
|
||||||
|
console.info('[Mnemosyne] Saved after prune:', index.memories.length, 'memories');
|
||||||
|
return true;
|
||||||
|
} catch (e2) {
|
||||||
|
console.error('[Mnemosyne] Save failed even after prune:', e2);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.error('[Mnemosyne] Save failed:', e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadFromStorage() {
|
||||||
|
if (typeof localStorage === 'undefined') {
|
||||||
|
console.warn('[Mnemosyne] localStorage unavailable — starting empty');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const raw = localStorage.getItem(STORAGE_KEY);
|
||||||
|
if (!raw) {
|
||||||
|
console.info('[Mnemosyne] No saved state found — starting fresh');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const index = JSON.parse(raw);
|
||||||
|
if (index.version !== STORAGE_VERSION) {
|
||||||
|
console.warn('[Mnemosyne] Saved version mismatch (got', index.version, 'expected', + STORAGE_VERSION + ') — starting fresh');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const count = importIndex(index);
|
||||||
|
_lastSavedHash = _indexHash(index);
|
||||||
|
return count;
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[Mnemosyne] Load failed:', e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _pruneArchiveMemories() {
|
||||||
|
// Remove oldest archive-region memories first
|
||||||
|
const archive = getMemoriesInRegion('archive');
|
||||||
|
const working = Object.values(_memoryObjects).filter(o => o.region !== 'archive');
|
||||||
|
// Sort archive by timestamp ascending (oldest first)
|
||||||
|
archive.sort((a, b) => {
|
||||||
|
const ta = a.data.timestamp || a.mesh.userData.createdAt || '';
|
||||||
|
const tb = b.data.timestamp || b.mesh.userData.createdAt || '';
|
||||||
|
return ta.localeCompare(tb);
|
||||||
|
});
|
||||||
|
const toRemove = Math.max(1, Math.ceil(archive.length * 0.25));
|
||||||
|
for (let i = 0; i < toRemove && i < archive.length; i++) {
|
||||||
|
removeMemory(archive[i].data.id);
|
||||||
|
}
|
||||||
|
console.info('[Mnemosyne] Pruned', toRemove, 'archive memories');
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearStorage() {
|
||||||
|
if (typeof localStorage !== 'undefined') {
|
||||||
|
localStorage.removeItem(STORAGE_KEY);
|
||||||
|
_lastSavedHash = '';
|
||||||
|
console.info('[Mnemosyne] Cleared localStorage');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ─── PERSISTENCE ─────────────────────────────────────
|
// ─── PERSISTENCE ─────────────────────────────────────
|
||||||
function exportIndex() {
|
function exportIndex() {
|
||||||
return {
|
return {
|
||||||
@@ -369,7 +474,8 @@ const SpatialMemory = (() => {
|
|||||||
return {
|
return {
|
||||||
init, placeMemory, removeMemory, update,
|
init, placeMemory, removeMemory, update,
|
||||||
getMemoryAtPosition, getRegionAtPosition, getMemoriesInRegion, getAllMemories,
|
getMemoryAtPosition, getRegionAtPosition, getMemoriesInRegion, getAllMemories,
|
||||||
exportIndex, importIndex, searchNearby, REGIONS
|
exportIndex, importIndex, searchNearby, REGIONS,
|
||||||
|
saveToStorage, loadFromStorage, clearStorage
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user