@kognai/orchestrator-core 0.1.0

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.
Files changed (144) hide show
  1. package/README.md +44 -0
  2. package/dist/index.d.ts +63 -0
  3. package/dist/index.js +175 -0
  4. package/dist/lib/aar-middleware.d.ts +6 -0
  5. package/dist/lib/aar-middleware.js +70 -0
  6. package/dist/lib/aar-types.d.ts +34 -0
  7. package/dist/lib/aar-types.js +4 -0
  8. package/dist/lib/acp-engine.d.ts +68 -0
  9. package/dist/lib/acp-engine.js +123 -0
  10. package/dist/lib/acp.d.ts +61 -0
  11. package/dist/lib/acp.js +425 -0
  12. package/dist/lib/agent-registry.d.ts +50 -0
  13. package/dist/lib/agent-registry.js +137 -0
  14. package/dist/lib/anthropic-direct.d.ts +27 -0
  15. package/dist/lib/anthropic-direct.js +109 -0
  16. package/dist/lib/asmr-extractor.d.ts +40 -0
  17. package/dist/lib/asmr-extractor.js +151 -0
  18. package/dist/lib/asmr-retrieval.d.ts +76 -0
  19. package/dist/lib/asmr-retrieval.js +311 -0
  20. package/dist/lib/asmr.d.ts +8 -0
  21. package/dist/lib/asmr.js +24 -0
  22. package/dist/lib/brainx-client.d.ts +72 -0
  23. package/dist/lib/brainx-client.js +200 -0
  24. package/dist/lib/brainx-embed.d.ts +14 -0
  25. package/dist/lib/brainx-embed.js +139 -0
  26. package/dist/lib/brainx-swarm-bridge.d.ts +93 -0
  27. package/dist/lib/brainx-swarm-bridge.js +242 -0
  28. package/dist/lib/byterover-client.d.ts +19 -0
  29. package/dist/lib/byterover-client.js +59 -0
  30. package/dist/lib/ceo-wallet.d.ts +37 -0
  31. package/dist/lib/ceo-wallet.js +176 -0
  32. package/dist/lib/chomsky-gate.d.ts +24 -0
  33. package/dist/lib/chomsky-gate.js +178 -0
  34. package/dist/lib/chomsky-runner.d.ts +29 -0
  35. package/dist/lib/chomsky-runner.js +157 -0
  36. package/dist/lib/citizen-score-contract.d.ts +72 -0
  37. package/dist/lib/citizen-score-contract.js +16 -0
  38. package/dist/lib/citizen-score-registry.d.ts +25 -0
  39. package/dist/lib/citizen-score-registry.js +65 -0
  40. package/dist/lib/citizenship.d.ts +103 -0
  41. package/dist/lib/citizenship.js +272 -0
  42. package/dist/lib/clawrouter-client.d.ts +37 -0
  43. package/dist/lib/clawrouter-client.js +148 -0
  44. package/dist/lib/code-asset-crystalliser.d.ts +41 -0
  45. package/dist/lib/code-asset-crystalliser.js +181 -0
  46. package/dist/lib/code-failure-logger.d.ts +27 -0
  47. package/dist/lib/code-failure-logger.js +42 -0
  48. package/dist/lib/cto-approval-gate.d.ts +45 -0
  49. package/dist/lib/cto-approval-gate.js +478 -0
  50. package/dist/lib/cto-gate-types.d.ts +28 -0
  51. package/dist/lib/cto-gate-types.js +8 -0
  52. package/dist/lib/decomposer-feedback.d.ts +54 -0
  53. package/dist/lib/decomposer-feedback.js +115 -0
  54. package/dist/lib/emotional-safety-gate.d.ts +48 -0
  55. package/dist/lib/emotional-safety-gate.js +97 -0
  56. package/dist/lib/engine-paths.d.ts +13 -0
  57. package/dist/lib/engine-paths.js +32 -0
  58. package/dist/lib/event-bus-listener.d.ts +8 -0
  59. package/dist/lib/event-bus-listener.js +144 -0
  60. package/dist/lib/event-bus-publisher.d.ts +25 -0
  61. package/dist/lib/event-bus-publisher.js +188 -0
  62. package/dist/lib/event-bus-types.d.ts +73 -0
  63. package/dist/lib/event-bus-types.js +23 -0
  64. package/dist/lib/failure-library.d.ts +178 -0
  65. package/dist/lib/failure-library.js +349 -0
  66. package/dist/lib/ksl/error-log.d.ts +28 -0
  67. package/dist/lib/ksl/error-log.js +43 -0
  68. package/dist/lib/ksl/index.d.ts +9 -0
  69. package/dist/lib/ksl/index.js +25 -0
  70. package/dist/lib/ksl/orchestrator-tap.d.ts +16 -0
  71. package/dist/lib/ksl/orchestrator-tap.js +85 -0
  72. package/dist/lib/ksl/record-writer.d.ts +46 -0
  73. package/dist/lib/ksl/record-writer.js +45 -0
  74. package/dist/lib/llm-cost-table.d.ts +36 -0
  75. package/dist/lib/llm-cost-table.js +90 -0
  76. package/dist/lib/local-model-router.d.ts +27 -0
  77. package/dist/lib/local-model-router.js +61 -0
  78. package/dist/lib/mc-client.d.ts +51 -0
  79. package/dist/lib/mc-client.js +249 -0
  80. package/dist/lib/model-router-contract.d.ts +91 -0
  81. package/dist/lib/model-router-contract.js +19 -0
  82. package/dist/lib/model-router-registry.d.ts +24 -0
  83. package/dist/lib/model-router-registry.js +52 -0
  84. package/dist/lib/model-router.d.ts +20 -0
  85. package/dist/lib/model-router.js +79 -0
  86. package/dist/lib/monotask-state-machine.d.ts +19 -0
  87. package/dist/lib/monotask-state-machine.js +131 -0
  88. package/dist/lib/neutral-prompt-checker.d.ts +22 -0
  89. package/dist/lib/neutral-prompt-checker.js +130 -0
  90. package/dist/lib/notion-direct.d.ts +92 -0
  91. package/dist/lib/notion-direct.js +381 -0
  92. package/dist/lib/ollama-client.d.ts +37 -0
  93. package/dist/lib/ollama-client.js +158 -0
  94. package/dist/lib/omel/credential-vault.d.ts +57 -0
  95. package/dist/lib/omel/credential-vault.js +324 -0
  96. package/dist/lib/omel/human-brake.d.ts +32 -0
  97. package/dist/lib/omel/human-brake.js +289 -0
  98. package/dist/lib/omel/index.d.ts +10 -0
  99. package/dist/lib/omel/index.js +26 -0
  100. package/dist/lib/omel/phantom-workspace.d.ts +31 -0
  101. package/dist/lib/omel/phantom-workspace.js +256 -0
  102. package/dist/lib/omel/wipe-witness.d.ts +75 -0
  103. package/dist/lib/omel/wipe-witness.js +398 -0
  104. package/dist/lib/orchestrate-engine.d.ts +25 -0
  105. package/dist/lib/orchestrate-engine.js +4436 -0
  106. package/dist/lib/perm-judge.d.ts +46 -0
  107. package/dist/lib/perm-judge.js +173 -0
  108. package/dist/lib/plumber/conformance.d.ts +54 -0
  109. package/dist/lib/plumber/conformance.js +121 -0
  110. package/dist/lib/plumber/index.d.ts +9 -0
  111. package/dist/lib/plumber/index.js +25 -0
  112. package/dist/lib/plumber/observer.d.ts +52 -0
  113. package/dist/lib/plumber/observer.js +180 -0
  114. package/dist/lib/plumber/types.d.ts +78 -0
  115. package/dist/lib/plumber/types.js +29 -0
  116. package/dist/lib/research-impl-gate.d.ts +16 -0
  117. package/dist/lib/research-impl-gate.js +105 -0
  118. package/dist/lib/sherlock-memory.d.ts +29 -0
  119. package/dist/lib/sherlock-memory.js +105 -0
  120. package/dist/lib/skill-crystalliser.d.ts +44 -0
  121. package/dist/lib/skill-crystalliser.js +60 -0
  122. package/dist/lib/sprint-runner-engine.d.ts +27 -0
  123. package/dist/lib/sprint-runner-engine.js +1042 -0
  124. package/dist/lib/sprint-state.d.ts +71 -0
  125. package/dist/lib/sprint-state.js +202 -0
  126. package/dist/lib/stuck-handler.d.ts +17 -0
  127. package/dist/lib/stuck-handler.js +249 -0
  128. package/dist/lib/task-contract-checker.d.ts +17 -0
  129. package/dist/lib/task-contract-checker.js +29 -0
  130. package/dist/lib/task-router/index.d.ts +17 -0
  131. package/dist/lib/task-router/index.js +52 -0
  132. package/dist/lib/task-router/router/generate-execution-id.d.ts +10 -0
  133. package/dist/lib/task-router/router/generate-execution-id.js +24 -0
  134. package/dist/lib/task-router/router/resolve-route.d.ts +2 -0
  135. package/dist/lib/task-router/router/resolve-route.js +49 -0
  136. package/dist/lib/task-router/types.d.ts +79 -0
  137. package/dist/lib/task-router/types.js +39 -0
  138. package/dist/lib/token-budget-validator.d.ts +44 -0
  139. package/dist/lib/token-budget-validator.js +84 -0
  140. package/dist/lib/trust-score-updater.d.ts +30 -0
  141. package/dist/lib/trust-score-updater.js +107 -0
  142. package/dist/lib/wallet-state.d.ts +26 -0
  143. package/dist/lib/wallet-state.js +85 -0
  144. package/package.json +27 -0
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateExecutionId = generateExecutionId;
4
+ const crypto_1 = require("crypto");
5
+ /**
6
+ * Generates a deterministic execution ID from sprintId and taskId.
7
+ * Uses SHA256 hash of `${sprintId}:${taskId}` to create a consistent identifier.
8
+ *
9
+ * @param sprintId - The unique identifier for the sprint
10
+ * @param taskId - The unique identifier for the task
11
+ * @returns A 64-character hexadecimal SHA256 hash string
12
+ * @throws Error if sprintId or taskId is not provided
13
+ */
14
+ function generateExecutionId(sprintId, taskId) {
15
+ if (!sprintId || typeof sprintId !== 'string') {
16
+ throw new Error('sprintId must be a non-empty string');
17
+ }
18
+ if (!taskId || typeof taskId !== 'string') {
19
+ throw new Error('taskId must be a non-empty string');
20
+ }
21
+ const input = `${sprintId}:${taskId}`;
22
+ const hash = (0, crypto_1.createHash)('sha256').update(input).digest('hex');
23
+ return hash;
24
+ }
@@ -0,0 +1,2 @@
1
+ import { TaskTarget, TaskRoute } from '../types';
2
+ export declare function resolveRoute(target: TaskTarget): TaskRoute;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveRoute = resolveRoute;
4
+ const types_1 = require("../types");
5
+ function resolveRoute(target) {
6
+ switch (target) {
7
+ case 'local': {
8
+ return {
9
+ provider: 'ollama',
10
+ model: process.env.VAULT_MODEL ?? 'qwen3:14b',
11
+ endpoint: process.env.VAULT_OLLAMA_URL ?? 'http://vault:11434',
12
+ timeoutMs: types_1.TIMEOUT_BUDGETS.local,
13
+ target: 'local',
14
+ };
15
+ }
16
+ case 'cloud-code': {
17
+ return {
18
+ provider: 'minimax',
19
+ model: 'MiniMax-M2.5',
20
+ endpoint: 'https://api.minimax.io/v1/chat/completions',
21
+ timeoutMs: types_1.TIMEOUT_BUDGETS['cloud-code'],
22
+ target: 'cloud-code',
23
+ };
24
+ }
25
+ case 'cloud-exec': {
26
+ return {
27
+ provider: 'anthropic',
28
+ model: 'claude-sonnet-4-20250514',
29
+ endpoint: 'https://api.anthropic.com/v1/messages',
30
+ timeoutMs: types_1.TIMEOUT_BUDGETS['cloud-exec'],
31
+ target: 'cloud-exec',
32
+ };
33
+ }
34
+ case 'cloud-post': {
35
+ return {
36
+ provider: 'external',
37
+ model: 'n/a',
38
+ endpoint: '',
39
+ timeoutMs: types_1.TIMEOUT_BUDGETS['cloud-post'],
40
+ target: 'cloud-post',
41
+ };
42
+ }
43
+ default: {
44
+ const exhaustiveCheck = target;
45
+ console.warn(`[resolveRoute] Unhandled target type: ${exhaustiveCheck}, defaulting to cloud-code`);
46
+ return resolveRoute('cloud-code');
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Kognai Task Router Types
3
+ *
4
+ * Defines the core type definitions for the task routing system,
5
+ * including task targets, timeout budgets, route configurations,
6
+ * and routing log entries.
7
+ */
8
+ /**
9
+ * Task execution target environments
10
+ */
11
+ export type TaskTarget = 'local' | 'cloud-code' | 'cloud-exec' | 'cloud-post';
12
+ /**
13
+ * Timeout budgets in milliseconds for each task target
14
+ * - local: 10 minutes (600000ms) - local Ollama execution
15
+ * - cloud-code: 2 minutes (120000ms) - cloud code generation
16
+ * - cloud-exec: 90 seconds (90000ms) - cloud code execution
17
+ * - cloud-post: 30 seconds (30000ms) - cloud post-processing
18
+ */
19
+ export declare const TIMEOUT_BUDGETS: Record<TaskTarget, number>;
20
+ /**
21
+ * Supported AI model providers
22
+ */
23
+ export type ModelProvider = 'ollama' | 'minimax' | 'anthropic' | 'external';
24
+ /**
25
+ * Task route configuration
26
+ * Defines how a task should be routed to a specific provider and model
27
+ */
28
+ export interface TaskRoute {
29
+ /** The AI provider to use for this route */
30
+ provider: ModelProvider;
31
+ /** The specific model identifier */
32
+ model: string;
33
+ /** The endpoint URL for the provider */
34
+ endpoint: string;
35
+ /** Timeout in milliseconds for this route */
36
+ timeoutMs: number;
37
+ /** The target environment for task execution */
38
+ target: TaskTarget;
39
+ }
40
+ /**
41
+ * Routing log entry
42
+ * Records the routing decision and execution details for audit and debugging
43
+ */
44
+ export interface RoutingLogEntry {
45
+ /** Unique execution identifier */
46
+ execution_id: string;
47
+ /** Sprint identifier this task belongs to */
48
+ sprint_id: string;
49
+ /** Task identifier within the sprint */
50
+ task_id: string;
51
+ /** Selected task target environment */
52
+ task_target: TaskTarget;
53
+ /** Provider used for execution */
54
+ provider: string;
55
+ /** Model used for execution */
56
+ model: string;
57
+ /** Timestamp when task was queued */
58
+ queued_at: string;
59
+ /** Timestamp when task started execution (optional) */
60
+ executed_at?: string;
61
+ /** Source of the execution request */
62
+ execution_source: string;
63
+ /** Whether the vault was reachable at routing time */
64
+ vault_reachable?: boolean;
65
+ /** Whether task was queued locally */
66
+ queued_local?: boolean;
67
+ /** Error message if routing or execution failed */
68
+ error?: string;
69
+ }
70
+ /**
71
+ * Type guard to check if a string is a valid TaskTarget
72
+ */
73
+ export declare function isValidTaskTarget(value: string): value is TaskTarget;
74
+ /**
75
+ * Get timeout budget for a task target
76
+ * @param target - The task target environment
77
+ * @returns Timeout in milliseconds, defaults to 60000ms if unknown
78
+ */
79
+ export declare function getTimeoutBudget(target: TaskTarget): number;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ /**
3
+ * Kognai Task Router Types
4
+ *
5
+ * Defines the core type definitions for the task routing system,
6
+ * including task targets, timeout budgets, route configurations,
7
+ * and routing log entries.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.TIMEOUT_BUDGETS = void 0;
11
+ exports.isValidTaskTarget = isValidTaskTarget;
12
+ exports.getTimeoutBudget = getTimeoutBudget;
13
+ /**
14
+ * Timeout budgets in milliseconds for each task target
15
+ * - local: 10 minutes (600000ms) - local Ollama execution
16
+ * - cloud-code: 2 minutes (120000ms) - cloud code generation
17
+ * - cloud-exec: 90 seconds (90000ms) - cloud code execution
18
+ * - cloud-post: 30 seconds (30000ms) - cloud post-processing
19
+ */
20
+ exports.TIMEOUT_BUDGETS = {
21
+ local: 600000,
22
+ 'cloud-code': 120000,
23
+ 'cloud-exec': 90000,
24
+ 'cloud-post': 30000,
25
+ };
26
+ /**
27
+ * Type guard to check if a string is a valid TaskTarget
28
+ */
29
+ function isValidTaskTarget(value) {
30
+ return ['local', 'cloud-code', 'cloud-exec', 'cloud-post'].includes(value);
31
+ }
32
+ /**
33
+ * Get timeout budget for a task target
34
+ * @param target - The task target environment
35
+ * @returns Timeout in milliseconds, defaults to 60000ms if unknown
36
+ */
37
+ function getTimeoutBudget(target) {
38
+ return exports.TIMEOUT_BUDGETS[target] ?? 60000;
39
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * token-budget-validator.ts — Deterministic pre-flight gate on MiniMax dispatch.
3
+ *
4
+ * Estimates the output-token cost for a task before any LLM is called. Rejects
5
+ * tasks predicted to exceed the truncation threshold (3800 tokens default —
6
+ * 700-token safety margin below MiniMax M2.5's documented ~4500 truncation
7
+ * point per docs/learnings.md §1).
8
+ *
9
+ * Stdlib only. NO LLM calls — this is a budget gate, it can't cost tokens to
10
+ * run. Returns suggested splits when rejecting so the decomposer-feedback
11
+ * router has something concrete to resplit on.
12
+ *
13
+ * Created: sprint-1566 task `wire_token_budget_validator` (F0).
14
+ * Replaces the orphaned `agents/token-budget-validator/` agent that CEO
15
+ * auto-spawned 2026-05-19 but never wired in.
16
+ */
17
+ /** Minimal task shape the validator needs. Compatible with AgentTask in
18
+ * orchestrate-agents-v2.ts but defined locally to avoid circular imports. */
19
+ export interface ValidatableTask {
20
+ id: string;
21
+ context?: string;
22
+ deliverables?: {
23
+ code?: string[];
24
+ edits?: string[];
25
+ tests?: string[];
26
+ };
27
+ }
28
+ export type ValidationResult = {
29
+ ok: true;
30
+ estimated_tokens: number;
31
+ } | {
32
+ ok: false;
33
+ estimated_tokens: number;
34
+ reason: string;
35
+ suggested_split: string[];
36
+ };
37
+ /** Estimate output tokens for a single task. Heuristic per sprint-1566 spec:
38
+ * base + Σ(per_file_min + tokens_per_loc × estimated_loc) × test_multiplier?
39
+ * estimated_loc derives from context length (denser specs imply more output).
40
+ */
41
+ export declare function estimateOutputTokens(task: ValidatableTask): number;
42
+ /** Validate a task against the truncation budget. When over budget, suggest a
43
+ * per-file split so the decomposer-feedback router can resplit deterministically. */
44
+ export declare function validateTask(task: ValidatableTask, threshold?: number): ValidationResult;
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ /**
3
+ * token-budget-validator.ts — Deterministic pre-flight gate on MiniMax dispatch.
4
+ *
5
+ * Estimates the output-token cost for a task before any LLM is called. Rejects
6
+ * tasks predicted to exceed the truncation threshold (3800 tokens default —
7
+ * 700-token safety margin below MiniMax M2.5's documented ~4500 truncation
8
+ * point per docs/learnings.md §1).
9
+ *
10
+ * Stdlib only. NO LLM calls — this is a budget gate, it can't cost tokens to
11
+ * run. Returns suggested splits when rejecting so the decomposer-feedback
12
+ * router has something concrete to resplit on.
13
+ *
14
+ * Created: sprint-1566 task `wire_token_budget_validator` (F0).
15
+ * Replaces the orphaned `agents/token-budget-validator/` agent that CEO
16
+ * auto-spawned 2026-05-19 but never wired in.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.estimateOutputTokens = estimateOutputTokens;
20
+ exports.validateTask = validateTask;
21
+ const DEFAULT_THRESHOLD = parseInt(process.env.TOKEN_BUDGET_THRESHOLD || '3800', 10);
22
+ const BASE_BOILERPLATE_TOKENS = 400;
23
+ const PER_FILE_MIN_TOKENS = 200;
24
+ // Calibrated from observed MiniMax M2.5 truncations on real Kognai tasks
25
+ // (data/failure-library/code/). The 138 "truncated" entries cluster around
26
+ // tasks whose context was 4-12KB with 1-3 deliverable files — these numbers
27
+ // reproduce that rejection envelope.
28
+ const TOKENS_PER_LOC = 12;
29
+ const CHARS_PER_LOC = 40;
30
+ const TEST_MULTIPLIER = 1.4;
31
+ /** Estimate output tokens for a single task. Heuristic per sprint-1566 spec:
32
+ * base + Σ(per_file_min + tokens_per_loc × estimated_loc) × test_multiplier?
33
+ * estimated_loc derives from context length (denser specs imply more output).
34
+ */
35
+ function estimateOutputTokens(task) {
36
+ const codeFiles = task.deliverables?.code || [];
37
+ const editFiles = task.deliverables?.edits || [];
38
+ const testFiles = task.deliverables?.tests || [];
39
+ const fileCount = codeFiles.length + editFiles.length;
40
+ if (fileCount === 0)
41
+ return 0; // pure-edit or non-code task — skip validation
42
+ const contextChars = (task.context || '').length;
43
+ const estimatedLoc = Math.max(40, Math.ceil(contextChars / CHARS_PER_LOC));
44
+ const perFileTokens = PER_FILE_MIN_TOKENS + TOKENS_PER_LOC * estimatedLoc;
45
+ let total = BASE_BOILERPLATE_TOKENS + fileCount * perFileTokens;
46
+ const hasTests = testFiles.length > 0 || codeFiles.some(f => f.includes('__tests__') || f.includes('.test.'));
47
+ if (hasTests)
48
+ total = Math.ceil(total * TEST_MULTIPLIER);
49
+ return total;
50
+ }
51
+ /** Validate a task against the truncation budget. When over budget, suggest a
52
+ * per-file split so the decomposer-feedback router can resplit deterministically. */
53
+ function validateTask(task, threshold = DEFAULT_THRESHOLD) {
54
+ const estimated = estimateOutputTokens(task);
55
+ // Empty deliverables skip the gate (nothing to estimate)
56
+ if (estimated === 0)
57
+ return { ok: true, estimated_tokens: 0 };
58
+ if (estimated <= threshold)
59
+ return { ok: true, estimated_tokens: estimated };
60
+ const codeFiles = task.deliverables?.code || [];
61
+ const editFiles = task.deliverables?.edits || [];
62
+ // Suggested split: if multiple files, propose one sub-task per file. If a
63
+ // single file, propose splitting context into N sub-tasks (caller decides
64
+ // how to actually slice the context — we just hint at the cardinality).
65
+ let suggested;
66
+ if ((codeFiles.length + editFiles.length) > 1) {
67
+ suggested = [...codeFiles, ...editFiles].map(f => `${task.id}__${slugForPath(f)}`);
68
+ }
69
+ else {
70
+ const target = codeFiles[0] || editFiles[0] || task.id;
71
+ // Estimate how many splits would each land under threshold
72
+ const splitCount = Math.max(2, Math.ceil(estimated / threshold));
73
+ suggested = Array.from({ length: splitCount }, (_, i) => `${task.id}__part${i + 1}`);
74
+ }
75
+ return {
76
+ ok: false,
77
+ estimated_tokens: estimated,
78
+ reason: `Estimated output ${estimated} tokens exceeds threshold ${threshold} (MiniMax truncates at ~4500 per docs/learnings.md §1). Decomposer must re-split.`,
79
+ suggested_split: suggested,
80
+ };
81
+ }
82
+ function slugForPath(p) {
83
+ return p.replace(/^scripts\//, '').replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/, '').replace(/[^a-z0-9]+/gi, '_').toLowerCase();
84
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * trust-score-updater.ts — Sprint 703 (GOV Phase 1)
3
+ *
4
+ * Dynamic ACP trust score updater. Adjusts scores based on real outcomes:
5
+ * - Approved tasks (score >= 80): accuracy +1
6
+ * - Rejected tasks: accuracy -2
7
+ * - Safety flags: safety -3
8
+ * - 5% daily decay toward 70 (mean) for stale agents
9
+ *
10
+ * Called by orchestrate-agents-v2.ts on both approval and rejection paths.
11
+ *
12
+ * TICKET-215 Phase 3b-2: the repo root now resolves via engine-paths
13
+ * (KOGNAI_ROOT / cwd) instead of `join(__dirname, '../..')`, so the module is
14
+ * location-independent and can live in @kognai/orchestrator-core. When run from a
15
+ * product repo root, resolveEnginePaths().root === the old __dirname/../.. — same
16
+ * <root>/acp/trust-scores.json path, no behavior change.
17
+ */
18
+ /**
19
+ * Update trust scores after a task outcome.
20
+ * @param agentId - The agent whose scores to update
21
+ * @param outcome - 'approved' or 'rejected'
22
+ * @param taskScore - The supervisor score (0-100)
23
+ * @param safetyFlag - Whether a safety issue was flagged
24
+ */
25
+ export declare function updateTrustScore(agentId: string, outcome: 'approved' | 'rejected', taskScore: number, safetyFlag?: boolean): void;
26
+ /**
27
+ * Apply daily decay: stale agents drift 5% toward mean (70) per day.
28
+ * Run once per day (e.g., in daily-digest or a cron).
29
+ */
30
+ export declare function applyDailyDecay(): void;
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ /**
3
+ * trust-score-updater.ts — Sprint 703 (GOV Phase 1)
4
+ *
5
+ * Dynamic ACP trust score updater. Adjusts scores based on real outcomes:
6
+ * - Approved tasks (score >= 80): accuracy +1
7
+ * - Rejected tasks: accuracy -2
8
+ * - Safety flags: safety -3
9
+ * - 5% daily decay toward 70 (mean) for stale agents
10
+ *
11
+ * Called by orchestrate-agents-v2.ts on both approval and rejection paths.
12
+ *
13
+ * TICKET-215 Phase 3b-2: the repo root now resolves via engine-paths
14
+ * (KOGNAI_ROOT / cwd) instead of `join(__dirname, '../..')`, so the module is
15
+ * location-independent and can live in @kognai/orchestrator-core. When run from a
16
+ * product repo root, resolveEnginePaths().root === the old __dirname/../.. — same
17
+ * <root>/acp/trust-scores.json path, no behavior change.
18
+ */
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.updateTrustScore = updateTrustScore;
21
+ exports.applyDailyDecay = applyDailyDecay;
22
+ const fs_1 = require("fs");
23
+ const path_1 = require("path");
24
+ const engine_paths_1 = require("./engine-paths");
25
+ const ROOT = (0, engine_paths_1.resolveEnginePaths)().root;
26
+ const TRUST_PATH = (0, path_1.join)(ROOT, 'acp', 'trust-scores.json');
27
+ function clamp(val, min, max) {
28
+ return Math.max(min, Math.min(max, val));
29
+ }
30
+ function recomputeComposite(scores, dims) {
31
+ let weighted = 0;
32
+ let totalWeight = 0;
33
+ for (const [dim, config] of Object.entries(dims)) {
34
+ const val = scores[dim];
35
+ if (typeof val === 'number') {
36
+ weighted += val * config.weight;
37
+ totalWeight += config.weight;
38
+ }
39
+ }
40
+ return totalWeight > 0 ? Math.round(weighted / totalWeight) : 0;
41
+ }
42
+ function loadTrustData() {
43
+ return JSON.parse((0, fs_1.readFileSync)(TRUST_PATH, 'utf-8'));
44
+ }
45
+ function saveTrustData(data) {
46
+ data.updated = new Date().toISOString().slice(0, 10);
47
+ (0, fs_1.writeFileSync)(TRUST_PATH, JSON.stringify(data, null, 2) + '\n', 'utf-8');
48
+ }
49
+ /**
50
+ * Update trust scores after a task outcome.
51
+ * @param agentId - The agent whose scores to update
52
+ * @param outcome - 'approved' or 'rejected'
53
+ * @param taskScore - The supervisor score (0-100)
54
+ * @param safetyFlag - Whether a safety issue was flagged
55
+ */
56
+ function updateTrustScore(agentId, outcome, taskScore, safetyFlag = false) {
57
+ try {
58
+ const data = loadTrustData();
59
+ const scores = data.scores[agentId];
60
+ if (!scores) {
61
+ console.warn(`[trust-updater] Agent '${agentId}' not in trust-scores.json — skipping`);
62
+ return;
63
+ }
64
+ if (outcome === 'approved' && taskScore >= 80) {
65
+ scores.accuracy = clamp(scores.accuracy + 1, 0, 100);
66
+ }
67
+ else if (outcome === 'rejected') {
68
+ scores.accuracy = clamp(scores.accuracy - 2, 0, 100);
69
+ }
70
+ if (safetyFlag) {
71
+ scores.safety = clamp(scores.safety - 3, 0, 100);
72
+ }
73
+ scores.composite = recomputeComposite(scores, data.dimensions);
74
+ scores.last_updated = new Date().toISOString().slice(0, 10);
75
+ saveTrustData(data);
76
+ }
77
+ catch (err) {
78
+ // Non-fatal — trust score update failure should never block execution
79
+ console.warn(`[trust-updater] Failed to update scores: ${err.message}`);
80
+ }
81
+ }
82
+ /**
83
+ * Apply daily decay: stale agents drift 5% toward mean (70) per day.
84
+ * Run once per day (e.g., in daily-digest or a cron).
85
+ */
86
+ function applyDailyDecay() {
87
+ try {
88
+ const data = loadTrustData();
89
+ const MEAN = 70;
90
+ const DECAY_RATE = 0.05;
91
+ const today = new Date().toISOString().slice(0, 10);
92
+ for (const [agentId, scores] of Object.entries(data.scores)) {
93
+ if (scores.last_updated === today)
94
+ continue; // Active today, skip
95
+ for (const dim of ['safety', 'accuracy', 'brand_alignment', 'cultural_sensitivity', 'legal_compliance']) {
96
+ const current = scores[dim];
97
+ const diff = current - MEAN;
98
+ scores[dim] = Math.round(current - diff * DECAY_RATE);
99
+ }
100
+ scores.composite = recomputeComposite(scores, data.dimensions);
101
+ }
102
+ saveTrustData(data);
103
+ }
104
+ catch (err) {
105
+ console.warn(`[trust-updater] Daily decay failed: ${err.message}`);
106
+ }
107
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * wallet-state.ts — CFO budget tracking for ClawRouter spend
3
+ *
4
+ * Accumulates spend from ClawRouter X-Payment-Amount headers.
5
+ * Enforces degraded (≥80%) and frozen (≥95%) modes to protect the wallet.
6
+ * Persists to logs/wallet/state.json across sprint runs.
7
+ *
8
+ * TICKET-215 Phase 3b-3 (Wave B): KOGNAI_ROOT now resolves via engine-paths
9
+ * (KOGNAI_ROOT / cwd) instead of `resolve(__dirname, '../..')`, so the bank
10
+ * state layer is location-independent and ships in @kognai/orchestrator-core.
11
+ * When run from a product repo root, resolveEnginePaths().root === the old
12
+ * __dirname/../.. — same <root>/logs/wallet/state.json, no behavior change.
13
+ */
14
+ export interface WalletState {
15
+ monthlyBudget: number;
16
+ spentThisMonth: number;
17
+ callCount: number;
18
+ remaining: number;
19
+ burnPct: number;
20
+ isDegraded: boolean;
21
+ isFrozen: boolean;
22
+ }
23
+ export declare function getWalletState(): WalletState;
24
+ export declare function recordSpend(costUsdc: number): void;
25
+ export declare function resetWallet(): void;
26
+ export declare function logWalletStatus(): void;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ /**
3
+ * wallet-state.ts — CFO budget tracking for ClawRouter spend
4
+ *
5
+ * Accumulates spend from ClawRouter X-Payment-Amount headers.
6
+ * Enforces degraded (≥80%) and frozen (≥95%) modes to protect the wallet.
7
+ * Persists to logs/wallet/state.json across sprint runs.
8
+ *
9
+ * TICKET-215 Phase 3b-3 (Wave B): KOGNAI_ROOT now resolves via engine-paths
10
+ * (KOGNAI_ROOT / cwd) instead of `resolve(__dirname, '../..')`, so the bank
11
+ * state layer is location-independent and ships in @kognai/orchestrator-core.
12
+ * When run from a product repo root, resolveEnginePaths().root === the old
13
+ * __dirname/../.. — same <root>/logs/wallet/state.json, no behavior change.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.getWalletState = getWalletState;
17
+ exports.recordSpend = recordSpend;
18
+ exports.resetWallet = resetWallet;
19
+ exports.logWalletStatus = logWalletStatus;
20
+ const fs_1 = require("fs");
21
+ const path_1 = require("path");
22
+ const engine_paths_1 = require("./engine-paths");
23
+ const KOGNAI_ROOT = (0, engine_paths_1.resolveEnginePaths)().root;
24
+ const STATE_FILE = (0, path_1.resolve)(KOGNAI_ROOT, 'logs/wallet/state.json');
25
+ const DEFAULT_BUDGET = parseFloat(process.env.CEO_WALLET_BUDGET_USDC || '25'); // $25/month default
26
+ function loadState() {
27
+ if ((0, fs_1.existsSync)(STATE_FILE)) {
28
+ try {
29
+ const raw = JSON.parse((0, fs_1.readFileSync)(STATE_FILE, 'utf8'));
30
+ // Auto-reset on new month
31
+ const lastReset = new Date(raw.lastReset);
32
+ const now = new Date();
33
+ if (lastReset.getMonth() !== now.getMonth() || lastReset.getFullYear() !== now.getFullYear()) {
34
+ return freshState();
35
+ }
36
+ return raw;
37
+ }
38
+ catch { /* fall through */ }
39
+ }
40
+ return freshState();
41
+ }
42
+ function freshState() {
43
+ return {
44
+ monthlyBudget: DEFAULT_BUDGET,
45
+ spentThisMonth: 0,
46
+ callCount: 0,
47
+ lastReset: new Date().toISOString(),
48
+ };
49
+ }
50
+ function saveState(data) {
51
+ try {
52
+ (0, fs_1.mkdirSync)((0, path_1.resolve)(KOGNAI_ROOT, 'logs/wallet'), { recursive: true });
53
+ (0, fs_1.writeFileSync)(STATE_FILE, JSON.stringify(data, null, 2), 'utf8');
54
+ }
55
+ catch { /* non-fatal */ }
56
+ }
57
+ // Singleton
58
+ let _state = loadState();
59
+ function getWalletState() {
60
+ const remaining = Math.max(0, _state.monthlyBudget - _state.spentThisMonth);
61
+ const burnPct = (_state.spentThisMonth / _state.monthlyBudget) * 100;
62
+ return {
63
+ monthlyBudget: _state.monthlyBudget,
64
+ spentThisMonth: _state.spentThisMonth,
65
+ callCount: _state.callCount,
66
+ remaining,
67
+ burnPct,
68
+ isDegraded: burnPct >= 80,
69
+ isFrozen: burnPct >= 95,
70
+ };
71
+ }
72
+ function recordSpend(costUsdc) {
73
+ _state.spentThisMonth += costUsdc;
74
+ _state.callCount += 1;
75
+ saveState(_state);
76
+ }
77
+ function resetWallet() {
78
+ _state = freshState();
79
+ saveState(_state);
80
+ }
81
+ function logWalletStatus() {
82
+ const s = getWalletState();
83
+ const status = s.isFrozen ? '🔴 FROZEN' : s.isDegraded ? '🟡 DEGRADED' : '🟢 OK';
84
+ console.log(` 💳 Wallet ${status}: $${s.spentThisMonth.toFixed(4)}/$${s.monthlyBudget} (${s.burnPct.toFixed(1)}%)`);
85
+ }
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@kognai/orchestrator-core",
3
+ "version": "0.1.0",
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
+ "license": "MIT",
6
+ "author": "SkinGem",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "files": [
10
+ "dist/",
11
+ "README.md"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc -p tsconfig.json",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "engines": {
18
+ "node": ">=18"
19
+ },
20
+ "keywords": [
21
+ "kognai",
22
+ "orchestrator",
23
+ "agent-swarm",
24
+ "core-engine"
25
+ ],
26
+ "dependencies": {}
27
+ }