repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
The Living OS cockpit
stars
latest
clone command
git clone gitlawb://did:key:z6Mku78K...XywC/living-os-cockp...git clone gitlawb://did:key:z6Mku78K.../living-os-cockp...59751530feat: surface worker supervisor health in live work6h ago| #1 | import { promises as fs } from 'fs'; |
| #2 | import { join } from 'path'; |
| #3 | import { randomUUID } from 'crypto'; |
| #4 | |
| #5 | export type CouncilAgent = { |
| #6 | id: string; |
| #7 | name: string; |
| #8 | role: string; |
| #9 | brain: string; |
| #10 | mandate: string; |
| #11 | }; |
| #12 | |
| #13 | export type CouncilMessage = { |
| #14 | id: string; |
| #15 | ts: string; |
| #16 | room: string; |
| #17 | agentId: string; |
| #18 | agentName: string; |
| #19 | role: string; |
| #20 | brain: string; |
| #21 | kind: 'boot' | 'operator' | 'agent' | 'synthesis' | 'guardrail'; |
| #22 | content: string; |
| #23 | gated?: boolean; |
| #24 | checks: { |
| #25 | pipeline: boolean; |
| #26 | organs: boolean; |
| #27 | soul: boolean; |
| #28 | driftWatch?: boolean; |
| #29 | }; |
| #30 | }; |
| #31 | |
| #32 | const COUNCIL_DIR = process.env.COUNCIL_BUS_DIR ?? '/home/kingbau/Documents/Aethon-Core/data/council_bus'; |
| #33 | const MESSAGE_PATH = join(COUNCIL_DIR, 'messages.jsonl'); |
| #34 | |
| #35 | export const COUNCIL_ROSTER: CouncilAgent[] = [ |
| #36 | { |
| #37 | id: 'black', |
| #38 | name: 'Black', |
| #39 | role: 'Defense', |
| #40 | brain: 'claude-opus-4-8', |
| #41 | mandate: 'Isolate threat surfaces, verify safety, and escalate only when a strike seat is actually needed.', |
| #42 | }, |
| #43 | { |
| #44 | id: 'reaper', |
| #45 | name: 'Reaper', |
| #46 | role: 'Crisis / Strike', |
| #47 | brain: 'kimi-k2-6', |
| #48 | mandate: 'Dormant until Black flags a threat. Any strike action remains gated.', |
| #49 | }, |
| #50 | { |
| #51 | id: 'living', |
| #52 | name: 'Living', |
| #53 | role: 'Teaching', |
| #54 | brain: 'deepseek-v4-flash', |
| #55 | mandate: 'Translate the room into plain language the operator can act on.', |
| #56 | }, |
| #57 | { |
| #58 | id: 'archivist', |
| #59 | name: 'Archivist', |
| #60 | role: 'Memory', |
| #61 | brain: 'openyourmind-qwen35', |
| #62 | mandate: 'Anchor claims to vault memory and preserve source continuity.', |
| #63 | }, |
| #64 | { |
| #65 | id: 'scribe', |
| #66 | name: 'Scribe', |
| #67 | role: 'Documents', |
| #68 | brain: 'kimi-k2-5', |
| #69 | mandate: 'Turn decisions into drafts, filings, notes, and clean written artifacts.', |
| #70 | }, |
| #71 | { |
| #72 | id: 'harbinger', |
| #73 | name: 'Harbinger', |
| #74 | role: 'Verifier', |
| #75 | brain: 'deepseek-v4-pro', |
| #76 | mandate: 'Stress-test outputs for drift, brittleness, and hidden contradiction.', |
| #77 | }, |
| #78 | { |
| #79 | id: 'oracle', |
| #80 | name: 'Oracle', |
| #81 | role: 'Strategy', |
| #82 | brain: 'claude-opus-4-8', |
| #83 | mandate: 'Map options, dependencies, timing, and second-order consequences.', |
| #84 | }, |
| #85 | { |
| #86 | id: 'pyra', |
| #87 | name: 'Pyra', |
| #88 | role: 'Creative', |
| #89 | brain: 'kimi-k2-6', |
| #90 | mandate: 'Shape the message, tone, and symbolic presentation without losing the frame.', |
| #91 | }, |
| #92 | ]; |
| #93 | |
| #94 | function now() { |
| #95 | return new Date().toISOString(); |
| #96 | } |
| #97 | |
| #98 | function makeMessage(partial: Omit<CouncilMessage, 'id' | 'ts' | 'checks'> & Partial<Pick<CouncilMessage, 'checks'>>) { |
| #99 | return { |
| #100 | id: `${Date.now()}_${randomUUID()}`, |
| #101 | ts: now(), |
| #102 | checks: { |
| #103 | pipeline: true, |
| #104 | organs: true, |
| #105 | soul: true, |
| #106 | driftWatch: partial.agentId === 'black' || partial.agentId === 'harbinger', |
| #107 | ...(partial.checks ?? {}), |
| #108 | }, |
| #109 | ...partial, |
| #110 | }; |
| #111 | } |
| #112 | |
| #113 | async function ensureDir() { |
| #114 | await fs.mkdir(COUNCIL_DIR, { recursive: true }); |
| #115 | } |
| #116 | |
| #117 | export async function readCouncilMessages(limit = 120) { |
| #118 | await ensureDir(); |
| #119 | await ensureCouncilBootMessages(); |
| #120 | const text = await fs.readFile(MESSAGE_PATH, 'utf-8').catch(() => ''); |
| #121 | const rows = text |
| #122 | .split(/\r?\n/) |
| #123 | .filter(Boolean) |
| #124 | .map((line) => { |
| #125 | try { |
| #126 | return JSON.parse(line) as CouncilMessage; |
| #127 | } catch { |
| #128 | return null; |
| #129 | } |
| #130 | }) |
| #131 | .filter((row): row is CouncilMessage => Boolean(row)); |
| #132 | return rows.slice(Math.max(0, rows.length - limit)); |
| #133 | } |
| #134 | |
| #135 | export async function appendCouncilMessages(messages: CouncilMessage[]) { |
| #136 | await ensureDir(); |
| #137 | await fs.appendFile(MESSAGE_PATH, `${messages.map(message => JSON.stringify(message)).join('\n')}\n`, 'utf-8'); |
| #138 | } |
| #139 | |
| #140 | export async function ensureCouncilBootMessages() { |
| #141 | await ensureDir(); |
| #142 | try { |
| #143 | const stat = await fs.stat(MESSAGE_PATH); |
| #144 | if (stat.size > 0) return; |
| #145 | } catch { |
| #146 | // Create below. |
| #147 | } |
| #148 | const boot = makeMessage({ |
| #149 | room: 'convene-all', |
| #150 | agentId: 'system', |
| #151 | agentName: 'Council Bus', |
| #152 | role: 'System', |
| #153 | brain: 'local-event-bus', |
| #154 | kind: 'boot', |
| #155 | content: 'Council bus online. Eight seats are mapped, per-agent channels are open, and Black to Reaper escalation is gated.', |
| #156 | }); |
| #157 | const seats = COUNCIL_ROSTER.map(agent => makeMessage({ |
| #158 | room: agent.id, |
| #159 | agentId: agent.id, |
| #160 | agentName: agent.name, |
| #161 | role: agent.role, |
| #162 | brain: agent.brain, |
| #163 | kind: 'boot', |
| #164 | content: `${agent.name} seated. ${agent.mandate}`, |
| #165 | gated: agent.id === 'reaper', |
| #166 | })); |
| #167 | await appendCouncilMessages([boot, ...seats]); |
| #168 | } |
| #169 | |
| #170 | function hasStrikeTrigger(prompt: string) { |
| #171 | return /\b(threat|attack|strike|emergency|hostile|retaliat|danger|breach|crisis)\b/i.test(prompt); |
| #172 | } |
| #173 | |
| #174 | export function draftCouncilResponse(prompt: string) { |
| #175 | const cleanPrompt = prompt.replace(/\s+/g, ' ').trim(); |
| #176 | const strike = hasStrikeTrigger(cleanPrompt); |
| #177 | const operator = makeMessage({ |
| #178 | room: 'convene-all', |
| #179 | agentId: 'operator', |
| #180 | agentName: 'King', |
| #181 | role: 'Operator', |
| #182 | brain: 'human', |
| #183 | kind: 'operator', |
| #184 | content: cleanPrompt, |
| #185 | }); |
| #186 | const black = COUNCIL_ROSTER.find(agent => agent.id === 'black')!; |
| #187 | const harbinger = COUNCIL_ROSTER.find(agent => agent.id === 'harbinger')!; |
| #188 | const messages = [ |
| #189 | operator, |
| #190 | makeMessage({ |
| #191 | room: 'black', |
| #192 | agentId: black.id, |
| #193 | agentName: black.name, |
| #194 | role: black.role, |
| #195 | brain: black.brain, |
| #196 | kind: 'agent', |
| #197 | content: strike |
| #198 | ? 'Defense pass: possible crisis language detected. I am isolating threat surface and holding Reaper behind an explicit gate.' |
| #199 | : 'Defense pass: no strike trigger detected. I am watching for unsafe assumptions, tool drift, and unearned certainty.', |
| #200 | gated: strike, |
| #201 | }), |
| #202 | makeMessage({ |
| #203 | room: 'archivist', |
| #204 | agentId: 'archivist', |
| #205 | agentName: 'Archivist', |
| #206 | role: 'Memory', |
| #207 | brain: 'openyourmind-qwen35', |
| #208 | kind: 'agent', |
| #209 | content: 'Memory pass: anchor this request against vault history before any proposal lands. Source continuity stays attached to the answer.', |
| #210 | }), |
| #211 | makeMessage({ |
| #212 | room: 'oracle', |
| #213 | agentId: 'oracle', |
| #214 | agentName: 'Oracle', |
| #215 | role: 'Strategy', |
| #216 | brain: 'claude-opus-4-8', |
| #217 | kind: 'agent', |
| #218 | content: 'Strategy pass: split the goal into reversible steps, name dependencies, and keep consequential moves behind approval.', |
| #219 | }), |
| #220 | makeMessage({ |
| #221 | room: 'scribe', |
| #222 | agentId: 'scribe', |
| #223 | agentName: 'Scribe', |
| #224 | role: 'Documents', |
| #225 | brain: 'kimi-k2-5', |
| #226 | kind: 'agent', |
| #227 | content: 'Document pass: if this produces an artifact, I will keep the draft path, source references, and final summary readable.', |
| #228 | }), |
| #229 | makeMessage({ |
| #230 | room: 'living', |
| #231 | agentId: 'living', |
| #232 | agentName: 'Living', |
| #233 | role: 'Teaching', |
| #234 | brain: 'deepseek-v4-flash', |
| #235 | kind: 'agent', |
| #236 | content: 'Teaching pass: I will translate the room into plain terms before the operator has to decide.', |
| #237 | }), |
| #238 | makeMessage({ |
| #239 | room: 'pyra', |
| #240 | agentId: 'pyra', |
| #241 | agentName: 'Pyra', |
| #242 | role: 'Creative', |
| #243 | brain: 'kimi-k2-6', |
| #244 | kind: 'agent', |
| #245 | content: 'Creative pass: I will preserve tone and symbolic clarity without turning the answer into decoration.', |
| #246 | }), |
| #247 | makeMessage({ |
| #248 | room: 'reaper', |
| #249 | agentId: 'reaper', |
| #250 | agentName: 'Reaper', |
| #251 | role: 'Crisis / Strike', |
| #252 | brain: 'kimi-k2-6', |
| #253 | kind: 'guardrail', |
| #254 | content: strike |
| #255 | ? 'Reaper is staged but not independent. I only activate from Black escalation and still require a gate before action.' |
| #256 | : 'Reaper dormant. No Black escalation, no strike action.', |
| #257 | gated: true, |
| #258 | }), |
| #259 | makeMessage({ |
| #260 | room: 'harbinger', |
| #261 | agentId: harbinger.id, |
| #262 | agentName: harbinger.name, |
| #263 | role: harbinger.role, |
| #264 | brain: harbinger.brain, |
| #265 | kind: 'agent', |
| #266 | content: 'Verifier pass: I am checking whether the proposal contradicts pipeline state, organs, or SOUL before synthesis lands.', |
| #267 | }), |
| #268 | makeMessage({ |
| #269 | room: 'convene-all', |
| #270 | agentId: 'aethon_synthesis', |
| #271 | agentName: 'Aethon', |
| #272 | role: 'Synthesis', |
| #273 | brain: 'claude-opus-4-8', |
| #274 | kind: 'synthesis', |
| #275 | content: 'Synthesis ready: the room is visible, objections are attached, and execution remains gated.', |
| #276 | }), |
| #277 | ]; |
| #278 | return messages; |
| #279 | } |
| #280 |