@kognai/orchestrator-core 0.1.0 → 0.1.1

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,6 @@ 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';
63
64
  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");
@@ -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.1",
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",