@kognai/orchestrator-core 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -59,5 +59,7 @@ export * from './lib/task-contract-checker';
59
59
  export { CTOApprovalResult, requestCTOApproval, batchCTOReview } from './lib/cto-approval-gate';
60
60
  export * from './lib/citizen-score-contract';
61
61
  export * from './lib/citizen-score-registry';
62
+ export * from './lib/sovereign-agent-factory';
62
63
  export { runOrchestrator } from './lib/orchestrate-engine';
64
+ export type { OrchestratorConfig, SpawnGate, SpawnGateResult, AgentSpawnSpec, } from './lib/orchestrate-engine';
63
65
  export { runSprintCycle, SprintRunnerOpts } from './lib/sprint-runner-engine';
package/dist/index.js CHANGED
@@ -167,6 +167,10 @@ Object.defineProperty(exports, "batchCTOReview", { enumerable: true, get: functi
167
167
  // Kognai monitoring (event-bus / kognai_events) and is Plumber-observable.
168
168
  __exportStar(require("./lib/citizen-score-contract"), exports);
169
169
  __exportStar(require("./lib/citizen-score-registry"), exports);
170
+ // TICKET-223: Sovereign Agent Factory — all agent spawns go through here.
171
+ // Constitutional basis: Charter Article II + founder ruling 2026-06-03.
172
+ // Supersedes AGENTS.md manual Messi+Tarek approval rule.
173
+ __exportStar(require("./lib/sovereign-agent-factory"), exports);
170
174
  // TICKET-215 Wave D split step 2: engine + sprint-runner entry points.
171
175
  // Inject seams via kognai-bootstrap (side-effect import) before calling.
172
176
  var orchestrate_engine_1 = require("./lib/orchestrate-engine");
@@ -21,5 +21,27 @@
21
21
  * Flow: CEO plans → MiniMax codes → Dual Supervisor review (DeepSeek + Haiku)
22
22
  * → CEO resolves conflicts → CTO analyzes → CMO reports → CEO daily report
23
23
  */
24
- declare function main(): Promise<void>;
24
+ export interface AgentSpawnSpec {
25
+ name: string;
26
+ role: string;
27
+ llm: 'minimax' | 'anthropic';
28
+ trigger: string;
29
+ prompt_summary: string;
30
+ }
31
+ export interface SpawnGateResult {
32
+ approved: boolean;
33
+ /** Human-readable reason when not approved (rejected or pending). */
34
+ rejection_reason?: string;
35
+ /** True when the spawn is suspended awaiting an out-of-band (e.g. human) approval. */
36
+ pending_approval?: boolean;
37
+ /** Optional one-line audit string logged on an approved decision. */
38
+ audit?: string;
39
+ }
40
+ export type SpawnGate = (spec: AgentSpawnSpec) => SpawnGateResult;
41
+ /** TICKET-225: engine config supplied by the consuming template. */
42
+ export interface OrchestratorConfig {
43
+ /** Optional template-carried spawn governance gate (Kognai → SAF). */
44
+ spawnGate?: SpawnGate;
45
+ }
46
+ declare function main(config?: OrchestratorConfig): Promise<void>;
25
47
  export { main as runOrchestrator };
@@ -1518,9 +1518,31 @@ Rules: Be specific — reference task IDs, rejection counts, concrete patterns.
1518
1518
  }
1519
1519
  }
1520
1520
  }
1521
- // ===== Agent Creator (creates new agents from CEO-approved CTO proposals) =====
1522
1521
  class AgentCreator {
1522
+ spawnGate;
1523
+ constructor(spawnGate) {
1524
+ this.spawnGate = spawnGate;
1525
+ }
1523
1526
  createAgent(spec) {
1527
+ // TICKET-225 — template-carried spawn governance. If the consuming template
1528
+ // supplied a SpawnGate (Kognai wires SAF here), consult it BEFORE creating
1529
+ // anything on disk. Approval/rejection only; the citizenship logic below is
1530
+ // unchanged (its extraction is tracked separately as TICKET-226).
1531
+ if (this.spawnGate) {
1532
+ const decision = this.spawnGate(spec);
1533
+ if (!decision.approved) {
1534
+ const why = decision.rejection_reason ? `: ${decision.rejection_reason}` : '';
1535
+ if (decision.pending_approval) {
1536
+ log(c.yellow, ` ⏸ Spawn of ${spec.name} pending approval${why}`);
1537
+ }
1538
+ else {
1539
+ log(c.red, ` ✗ Spawn of ${spec.name} blocked${why}`);
1540
+ }
1541
+ return '';
1542
+ }
1543
+ if (decision.audit)
1544
+ log(c.gray, ` ✓ ${decision.audit}`);
1545
+ }
1524
1546
  const agentDir = `./agents/${spec.name}`;
1525
1547
  (0, fs_1.mkdirSync)(agentDir, { recursive: true });
1526
1548
  // Founder rule 2026-05-27: every spawned agent is born as a Kognai
@@ -2939,6 +2961,7 @@ ${originalContent}
2939
2961
  }
2940
2962
  // ===== Orchestrator (Dynamic Agent Pipeline) =====
2941
2963
  class Orchestrator {
2964
+ spawnGate;
2942
2965
  ceo;
2943
2966
  cto;
2944
2967
  supervisor;
@@ -3046,7 +3069,10 @@ class Orchestrator {
3046
3069
  (0, fs_1.writeFileSync)(sprintFile, JSON.stringify(sprintRaw, null, 2));
3047
3070
  log(c.green, ` [inject] Added ${injected} split sub-tasks to ${sprintFile} (in-memory + on-disk)`);
3048
3071
  }
3049
- constructor() {
3072
+ // TICKET-225: optional template-supplied spawn governance gate, threaded
3073
+ // from runOrchestrator(config) down to AgentCreator. Undefined = no gate.
3074
+ constructor(spawnGate) {
3075
+ this.spawnGate = spawnGate;
3050
3076
  log(c.bold, '\n╔══════════════════════════════════════════════════════════╗');
3051
3077
  log(c.bold, '║ Kognai Swarm Orchestrator v2.17 — V17 Architecture ║');
3052
3078
  log(c.bold, '║ Local-first · ClawRouter cloud · DeepSeek reviews ║');
@@ -4163,7 +4189,7 @@ ONLY output the JSON array. No markdown, no explanation.`;
4163
4189
  // Persist CEO decisions for CTO feedback loop + approved proposals tracking
4164
4190
  persistCEODecisions(ctoDecisions, ctoReport);
4165
4191
  // Handle approved new_agent proposals
4166
- const agentCreator = new AgentCreator();
4192
+ const agentCreator = new AgentCreator(this.spawnGate);
4167
4193
  for (const proposal of ctoReport.proposals) {
4168
4194
  if (proposal.category === 'new_agent' && proposal.agent_spec) {
4169
4195
  // Check if CEO approved this specific proposal
@@ -4414,8 +4440,7 @@ async function postSprintSmokeTest() {
4414
4440
  // Disabled — Invoica-specific endpoints (health/invoices/settlements) not applicable to Kognai
4415
4441
  // Removed Sprint 205: was always returning HTTP 404 + flooding Telegram with false alerts
4416
4442
  }
4417
- // ===== Main Entry =====
4418
- async function main() {
4443
+ async function main(config = {}) {
4419
4444
  // S67-005: Startup env check (OMEL AMD-13: via CredentialVault — hasSecret never logs value)
4420
4445
  if (!credential_vault_1.credentialVault.hasSecret('ANTHROPIC_API_KEY', 'orchestrator')) {
4421
4446
  log(c.yellow, '⚠ ANTHROPIC_API_KEY not set — Anthropic CEO + Sup2 Haiku will be unavailable.');
@@ -4425,7 +4450,7 @@ async function main() {
4425
4450
  log(c.yellow, '⚠ MINIMAX_API_KEY not set — cloud-code tasks will fail.');
4426
4451
  }
4427
4452
  try {
4428
- const orchestrator = new Orchestrator();
4453
+ const orchestrator = new Orchestrator(config.spawnGate);
4429
4454
  await orchestrator.run();
4430
4455
  }
4431
4456
  catch (error) {
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Sovereign Agent Factory (SAF) — TICKET-223
3
+ *
4
+ * Constitutional basis:
5
+ * - Founding Charter Article II: Founder holds final authority on Agent Spawn.
6
+ * - AGENTS.md waiver: SAF supersedes the "Messi + Tarek manual approval" rule.
7
+ * All spawns now go through SAF which encodes that approval chain.
8
+ * - Article V: Spawns suspended in Orange (<60) / Critical (<45) health zones.
9
+ * - Three Founding Principles: SAF is the citizenship registration point.
10
+ *
11
+ * Governance chain (from founder ruling 2026-06-03):
12
+ * Human → Prime CEO (one per Invoica wallet, future TICKET-224) → agents
13
+ * Swarm CEO → governed by the CEO above it
14
+ * SAF governors: CEO + CTO + Founder (escalating)
15
+ *
16
+ * Every spawn emits:
17
+ * 1. KSL record (spawn_request + spawn_decision)
18
+ * 2. Voxight market intelligence signal (spawn classification = demand signal)
19
+ */
20
+ /** All possible classifications for a spawn request. */
21
+ export type SpawnClass = 'UTILITY' | 'SPECIALIST' | 'CITIZEN' | 'EXTERNAL' | 'PRIME';
22
+ export type GovernancePath = 'auto' | 'ceo_review' | 'cto_review' | 'founder_required' | 'blocked';
23
+ export interface SpawnRequest {
24
+ requester_did: string;
25
+ requested_role: string;
26
+ requested_capabilities: string[];
27
+ purpose: string;
28
+ task_context?: {
29
+ sprint_id?: string;
30
+ task_id?: string;
31
+ task_type?: string;
32
+ };
33
+ classification_hint?: SpawnClass;
34
+ governance_override?: 'cto_review' | 'founder_required';
35
+ batch_id?: string;
36
+ }
37
+ export interface SpawnAnalysis {
38
+ classification: SpawnClass;
39
+ risk_level: 'low' | 'medium' | 'high' | 'constitutional';
40
+ constitutional_check: 'pass' | 'fail' | 'conditional';
41
+ constitutional_findings: string[];
42
+ governance_path: GovernancePath;
43
+ recommended_initial_acp: number;
44
+ health_gate: 'pass' | 'blocked';
45
+ health_score?: number;
46
+ voxight_signal: SpawnSignal;
47
+ }
48
+ export interface SpawnSignal {
49
+ ts: string;
50
+ requester_did: string;
51
+ classification: SpawnClass;
52
+ capabilities_requested: string[];
53
+ purpose_summary: string;
54
+ batch_id?: string;
55
+ }
56
+ export interface SpawnDecision {
57
+ approved: boolean;
58
+ rejection_reason?: string;
59
+ citizen_did?: string;
60
+ initial_acp_score: number;
61
+ governance_authority: GovernancePath;
62
+ governance_audit: string[];
63
+ ksl_record_id: string;
64
+ spawn_ts: string;
65
+ pending_approval?: boolean;
66
+ }
67
+ export interface SpawnRecord {
68
+ id: string;
69
+ request: SpawnRequest;
70
+ analysis: SpawnAnalysis;
71
+ decision: SpawnDecision;
72
+ ts: string;
73
+ }
74
+ /**
75
+ * Analyze a spawn request — classifies, checks constitutional gates, determines
76
+ * governance path. Does NOT commit; call decide() or spawn() to commit.
77
+ */
78
+ export declare function analyzeSpawnRequest(req: SpawnRequest): SpawnAnalysis;
79
+ /**
80
+ * Issue a spawn decision given a pre-computed analysis.
81
+ * This is the commitment step — logs to KSL and publishes to Voxight.
82
+ */
83
+ export declare function issueSpawnDecision(req: SpawnRequest, analysis: SpawnAnalysis): SpawnDecision;
84
+ /**
85
+ * Full pipeline: analyze → decide → log. The canonical entry point.
86
+ *
87
+ * Usage:
88
+ * const decision = sovereignSpawn({
89
+ * requester_did: 'did:kognai:harvey',
90
+ * requested_role: 'coder',
91
+ * requested_capabilities: ['typescript', 'file_write'],
92
+ * purpose: 'Execute sprint task v4_scaffold — landing page port',
93
+ * task_context: { sprint_id: 'sprint-1628', task_id: 'v4_scaffold' },
94
+ * });
95
+ * if (!decision.approved) throw new Error(`Spawn blocked: ${decision.rejection_reason}`);
96
+ */
97
+ export declare function sovereignSpawn(req: SpawnRequest): SpawnDecision;
98
+ /**
99
+ * Emergency bypass — Founder only. Overrides all gates including health and
100
+ * constitutional conditional findings. Logs prominently to KSL.
101
+ * NOT available to CEO or CTO.
102
+ */
103
+ export declare function founderEmergencySpawn(req: SpawnRequest, founder_justification: string): SpawnDecision;
104
+ /** Read the in-process spawn registry. For audit and monitoring. */
105
+ export declare function getSpawnRegistry(): readonly SpawnRecord[];
106
+ /**
107
+ * Batch spawn — classifies all requests, groups by governance path,
108
+ * processes low-risk in parallel and escalates high-risk appropriately.
109
+ */
110
+ export declare function batchSpawn(requests: SpawnRequest[]): SpawnDecision[];
@@ -0,0 +1,290 @@
1
+ "use strict";
2
+ /**
3
+ * Sovereign Agent Factory (SAF) — TICKET-223
4
+ *
5
+ * Constitutional basis:
6
+ * - Founding Charter Article II: Founder holds final authority on Agent Spawn.
7
+ * - AGENTS.md waiver: SAF supersedes the "Messi + Tarek manual approval" rule.
8
+ * All spawns now go through SAF which encodes that approval chain.
9
+ * - Article V: Spawns suspended in Orange (<60) / Critical (<45) health zones.
10
+ * - Three Founding Principles: SAF is the citizenship registration point.
11
+ *
12
+ * Governance chain (from founder ruling 2026-06-03):
13
+ * Human → Prime CEO (one per Invoica wallet, future TICKET-224) → agents
14
+ * Swarm CEO → governed by the CEO above it
15
+ * SAF governors: CEO + CTO + Founder (escalating)
16
+ *
17
+ * Every spawn emits:
18
+ * 1. KSL record (spawn_request + spawn_decision)
19
+ * 2. Voxight market intelligence signal (spawn classification = demand signal)
20
+ */
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.analyzeSpawnRequest = analyzeSpawnRequest;
23
+ exports.issueSpawnDecision = issueSpawnDecision;
24
+ exports.sovereignSpawn = sovereignSpawn;
25
+ exports.founderEmergencySpawn = founderEmergencySpawn;
26
+ exports.getSpawnRegistry = getSpawnRegistry;
27
+ exports.batchSpawn = batchSpawn;
28
+ const engine_paths_1 = require("./engine-paths");
29
+ const event_bus_publisher_1 = require("./event-bus-publisher");
30
+ // ─── Constitutional health zones ──────────────────────────────────────────────
31
+ /** Thresholds from Founding Charter Article V. */
32
+ const HEALTH_ORANGE = 60;
33
+ const HEALTH_CRITICAL = 45;
34
+ // ─── Classification rules ──────────────────────────────────────────────────────
35
+ const UTILITY_ROLES = new Set([
36
+ 'summariser', 'formatter', 'tokenizer', 'validator', 'router',
37
+ 'classifier', 'splitter', 'merger', 'transformer',
38
+ ]);
39
+ const CITIZEN_ROLES = new Set([
40
+ 'ceo', 'cto', 'cfo', 'supervisor', 'orchestrator',
41
+ ]);
42
+ function classifyRequest(req) {
43
+ if (req.classification_hint)
44
+ return req.classification_hint;
45
+ const role = req.requested_role.toLowerCase();
46
+ if (role === 'prime_ceo')
47
+ return 'PRIME';
48
+ if (req.requester_did.startsWith('did:external:'))
49
+ return 'EXTERNAL';
50
+ if (CITIZEN_ROLES.has(role))
51
+ return 'CITIZEN';
52
+ if (UTILITY_ROLES.has(role))
53
+ return 'UTILITY';
54
+ return 'SPECIALIST';
55
+ }
56
+ function initialAcp(cls) {
57
+ switch (cls) {
58
+ case 'PRIME': return 0.85;
59
+ case 'CITIZEN': return 0.70;
60
+ case 'SPECIALIST': return 0.70;
61
+ case 'UTILITY': return 0.65;
62
+ case 'EXTERNAL': return 0.30;
63
+ }
64
+ }
65
+ function governanceFor(cls, risk, override) {
66
+ if (override)
67
+ return override;
68
+ if (cls === 'PRIME' || cls === 'EXTERNAL')
69
+ return 'founder_required';
70
+ if (cls === 'CITIZEN' || risk === 'constitutional')
71
+ return 'cto_review';
72
+ if (risk === 'high')
73
+ return 'ceo_review';
74
+ return 'auto';
75
+ }
76
+ function constitutionalCheck(req, cls) {
77
+ const findings = [];
78
+ if (!req.requester_did)
79
+ findings.push('requester_did is required — all spawns must have a traceable origin');
80
+ if (!req.purpose || req.purpose.trim().length < 10)
81
+ findings.push('purpose too vague — SAF requires meaningful justification per Transparency Covenant');
82
+ if (cls === 'PRIME' && req.requester_did !== 'did:kognai:founder') {
83
+ findings.push('PRIME citizen may only be spawned by the Founder (did:kognai:founder)');
84
+ }
85
+ return {
86
+ result: findings.length === 0 ? 'pass' : findings.some(f => f.includes('only be spawned')) ? 'fail' : 'conditional',
87
+ findings,
88
+ };
89
+ }
90
+ // ─── Health gate ───────────────────────────────────────────────────────────────
91
+ function readHealthScore() {
92
+ try {
93
+ const paths = (0, engine_paths_1.resolveEnginePaths)();
94
+ const { readFileSync } = require('fs');
95
+ const { join } = require('path');
96
+ const report = JSON.parse(readFileSync(join(paths.root, 'reports', 'system-health.json'), 'utf-8'));
97
+ return typeof report?.score === 'number' ? report.score : undefined;
98
+ }
99
+ catch {
100
+ return undefined;
101
+ }
102
+ }
103
+ function healthGate(cls) {
104
+ if (cls === 'PRIME')
105
+ return { gate: 'pass' };
106
+ const score = readHealthScore();
107
+ if (score === undefined)
108
+ return { gate: 'pass' };
109
+ if (score < HEALTH_CRITICAL)
110
+ return { gate: 'blocked', score };
111
+ if (score < HEALTH_ORANGE && cls !== 'UTILITY')
112
+ return { gate: 'blocked', score };
113
+ return { gate: 'pass', score };
114
+ }
115
+ // ─── KSL + Voxight ────────────────────────────────────────────────────────────
116
+ let _recordCounter = 0;
117
+ function nextRecordId() {
118
+ return `saf_${Date.now()}_${++_recordCounter}`;
119
+ }
120
+ function emitKsl(req, analysis, decision) {
121
+ try {
122
+ const { appendFileSync, mkdirSync } = require('fs');
123
+ const { join } = require('path');
124
+ const paths = (0, engine_paths_1.resolveEnginePaths)();
125
+ const dir = join(paths.root, 'logs', 'saf');
126
+ mkdirSync(dir, { recursive: true });
127
+ const line = JSON.stringify({
128
+ ts: decision.spawn_ts,
129
+ ksl_record_id: decision.ksl_record_id,
130
+ requester_did: req.requester_did,
131
+ requested_role: req.requested_role,
132
+ classification: analysis.classification,
133
+ governance: decision.governance_authority,
134
+ approved: decision.approved,
135
+ rejection_reason: decision.rejection_reason,
136
+ health_score: analysis.health_score,
137
+ constitutional_check: analysis.constitutional_check,
138
+ batch_id: req.batch_id,
139
+ });
140
+ appendFileSync(join(dir, 'spawn-events.jsonl'), line + '\n');
141
+ }
142
+ catch { /* KSL is observability — never block spawn on KSL failure */ }
143
+ }
144
+ function emitVoxight(signal) {
145
+ try {
146
+ (0, event_bus_publisher_1.publishEvent)({
147
+ type: 'data.spawn_request',
148
+ source: 'sovereign_agent_factory',
149
+ payload: signal,
150
+ });
151
+ }
152
+ catch { /* Voxight feed is non-blocking */ }
153
+ }
154
+ // ─── Factory ──────────────────────────────────────────────────────────────────
155
+ const _registry = [];
156
+ /**
157
+ * Analyze a spawn request — classifies, checks constitutional gates, determines
158
+ * governance path. Does NOT commit; call decide() or spawn() to commit.
159
+ */
160
+ function analyzeSpawnRequest(req) {
161
+ const classification = classifyRequest(req);
162
+ const { gate, score } = healthGate(classification);
163
+ const { result: constitutionalResult, findings } = constitutionalCheck(req, classification);
164
+ const risk = classification === 'PRIME' || classification === 'EXTERNAL' ? 'constitutional'
165
+ : classification === 'CITIZEN' ? 'high'
166
+ : classification === 'SPECIALIST' ? 'medium'
167
+ : 'low';
168
+ const governance = gate === 'blocked' || constitutionalResult === 'fail'
169
+ ? 'blocked'
170
+ : governanceFor(classification, risk, req.governance_override);
171
+ const signal = {
172
+ ts: new Date().toISOString(),
173
+ requester_did: req.requester_did,
174
+ classification,
175
+ capabilities_requested: req.requested_capabilities,
176
+ purpose_summary: req.purpose.slice(0, 120),
177
+ batch_id: req.batch_id,
178
+ };
179
+ return {
180
+ classification,
181
+ risk_level: risk,
182
+ constitutional_check: constitutionalResult,
183
+ constitutional_findings: findings,
184
+ governance_path: governance,
185
+ recommended_initial_acp: initialAcp(classification),
186
+ health_gate: gate,
187
+ health_score: score,
188
+ voxight_signal: signal,
189
+ };
190
+ }
191
+ /**
192
+ * Issue a spawn decision given a pre-computed analysis.
193
+ * This is the commitment step — logs to KSL and publishes to Voxight.
194
+ */
195
+ function issueSpawnDecision(req, analysis) {
196
+ const ksl_record_id = nextRecordId();
197
+ const spawn_ts = new Date().toISOString();
198
+ const auditTrail = [];
199
+ if (analysis.health_gate === 'blocked') {
200
+ auditTrail.push(`Health score ${analysis.health_score} below spawn threshold — blocked by Article V`);
201
+ }
202
+ if (analysis.constitutional_check === 'fail') {
203
+ auditTrail.push(`Constitutional check failed: ${analysis.constitutional_findings.join('; ')}`);
204
+ }
205
+ if (analysis.governance_path === 'founder_required') {
206
+ auditTrail.push('Founder approval required — spawn suspended pending human authorization');
207
+ }
208
+ const approved = analysis.governance_path !== 'blocked' &&
209
+ analysis.constitutional_check !== 'fail' &&
210
+ analysis.governance_path !== 'founder_required';
211
+ const decision = {
212
+ approved,
213
+ rejection_reason: approved ? undefined : auditTrail.join(' | '),
214
+ initial_acp_score: analysis.recommended_initial_acp,
215
+ governance_authority: analysis.governance_path,
216
+ governance_audit: auditTrail,
217
+ ksl_record_id,
218
+ spawn_ts,
219
+ pending_approval: analysis.governance_path === 'founder_required' ? true : undefined,
220
+ };
221
+ // Side-effects: KSL + Voxight (non-blocking)
222
+ emitKsl(req, analysis, decision);
223
+ emitVoxight(analysis.voxight_signal);
224
+ // Registry
225
+ const record = {
226
+ id: ksl_record_id,
227
+ request: req,
228
+ analysis,
229
+ decision,
230
+ ts: spawn_ts,
231
+ };
232
+ _registry.push(record);
233
+ return decision;
234
+ }
235
+ /**
236
+ * Full pipeline: analyze → decide → log. The canonical entry point.
237
+ *
238
+ * Usage:
239
+ * const decision = sovereignSpawn({
240
+ * requester_did: 'did:kognai:harvey',
241
+ * requested_role: 'coder',
242
+ * requested_capabilities: ['typescript', 'file_write'],
243
+ * purpose: 'Execute sprint task v4_scaffold — landing page port',
244
+ * task_context: { sprint_id: 'sprint-1628', task_id: 'v4_scaffold' },
245
+ * });
246
+ * if (!decision.approved) throw new Error(`Spawn blocked: ${decision.rejection_reason}`);
247
+ */
248
+ function sovereignSpawn(req) {
249
+ const analysis = analyzeSpawnRequest(req);
250
+ return issueSpawnDecision(req, analysis);
251
+ }
252
+ /**
253
+ * Emergency bypass — Founder only. Overrides all gates including health and
254
+ * constitutional conditional findings. Logs prominently to KSL.
255
+ * NOT available to CEO or CTO.
256
+ */
257
+ function founderEmergencySpawn(req, founder_justification) {
258
+ const ksl_record_id = nextRecordId();
259
+ const spawn_ts = new Date().toISOString();
260
+ const decision = {
261
+ approved: true,
262
+ initial_acp_score: initialAcp(classifyRequest(req)),
263
+ governance_authority: 'founder_required',
264
+ governance_audit: [`EMERGENCY BYPASS by Founder. Justification: ${founder_justification}`],
265
+ ksl_record_id,
266
+ spawn_ts,
267
+ };
268
+ emitKsl(req, analyzeSpawnRequest(req), decision);
269
+ emitVoxight({
270
+ ts: spawn_ts,
271
+ requester_did: req.requester_did,
272
+ classification: classifyRequest(req),
273
+ capabilities_requested: req.requested_capabilities,
274
+ purpose_summary: `[EMERGENCY] ${req.purpose.slice(0, 100)}`,
275
+ batch_id: req.batch_id,
276
+ });
277
+ _registry.push({ id: ksl_record_id, request: req, analysis: analyzeSpawnRequest(req), decision, ts: spawn_ts });
278
+ return decision;
279
+ }
280
+ /** Read the in-process spawn registry. For audit and monitoring. */
281
+ function getSpawnRegistry() {
282
+ return _registry;
283
+ }
284
+ /**
285
+ * Batch spawn — classifies all requests, groups by governance path,
286
+ * processes low-risk in parallel and escalates high-risk appropriately.
287
+ */
288
+ function batchSpawn(requests) {
289
+ return requests.map(req => sovereignSpawn(req));
290
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kognai/orchestrator-core",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Kognai sovereign orchestrator — core engine (template-agnostic). Shared by all products (Kognai/coding, Voxight/market-intel, Invoica/fin-compliance); each supplies only its template. Replaces per-repo forks of orchestrate-agents-v2 / sprint-runner / lib.",
5
5
  "license": "MIT",
6
6
  "author": "SkinGem",