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 ────────────────────────────────────────────
|
||||
let _scene = null;
|
||||
let _regionMarkers = {};
|
||||
@@ -183,6 +189,8 @@ const SpatialMemory = (() => {
|
||||
_drawConnections(mem.id, mem.connections);
|
||||
}
|
||||
|
||||
_dirty = true;
|
||||
saveToStorage();
|
||||
console.info('[Mnemosyne] Spatial memory placed:', mem.id, 'in', region.label);
|
||||
return crystal;
|
||||
}
|
||||
@@ -247,6 +255,8 @@ const SpatialMemory = (() => {
|
||||
}
|
||||
|
||||
delete _memoryObjects[memId];
|
||||
_dirty = true;
|
||||
saveToStorage();
|
||||
}
|
||||
|
||||
// ─── ANIMATE ─────────────────────────────────────────
|
||||
@@ -286,7 +296,9 @@ const SpatialMemory = (() => {
|
||||
_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;
|
||||
}
|
||||
|
||||
@@ -320,6 +332,99 @@ const SpatialMemory = (() => {
|
||||
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 ─────────────────────────────────────
|
||||
function exportIndex() {
|
||||
return {
|
||||
@@ -369,7 +474,8 @@ const SpatialMemory = (() => {
|
||||
return {
|
||||
init, placeMemory, removeMemory, update,
|
||||
getMemoryAtPosition, getRegionAtPosition, getMemoriesInRegion, getAllMemories,
|
||||
exportIndex, importIndex, searchNearby, REGIONS
|
||||
exportIndex, importIndex, searchNearby, REGIONS,
|
||||
saveToStorage, loadFromStorage, clearStorage
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user