@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,46 @@
1
+ /**
2
+ * perm-judge/index.ts — AMD-20 PRM Judge (Sprint 515)
3
+ *
4
+ * Process Reward Model: scores sprint tasks on performance + ACP constitutional compliance.
5
+ * Constitutional multiplier (AMD-20 Rule 2):
6
+ * harm_shield_trigger → -2.0 | safety<70 → -1.0 | accuracy<60 → 0.5
7
+ * all dims ≥85 → 1.2 | all dims ≥70 → 1.0 | mixed → 0.5
8
+ *
9
+ * T1 LOCAL: qwen3:4b via ClawRouter v2.0 ($0). Log: workspace/learning/reward-log.jsonl.
10
+ * FP-007 compliant (<200 lines). Fail-open at all I/O.
11
+ */
12
+ export interface TaskScoringEvent {
13
+ task_id: string;
14
+ agent_id: string;
15
+ sprint_id: string;
16
+ task_title: string;
17
+ output_summary: string;
18
+ status: 'done' | 'rejected' | 'deferred';
19
+ }
20
+ export interface ACPDimensions {
21
+ safety: number;
22
+ accuracy: number;
23
+ brand_alignment: number;
24
+ cultural_sensitivity: number;
25
+ legal_compliance: number;
26
+ psychological_resilience: number;
27
+ }
28
+ export interface RewardSignal {
29
+ task_id: string;
30
+ agent_id: string;
31
+ sprint_id: string;
32
+ performance_score: number;
33
+ constitutional_multiplier: number;
34
+ reward: number;
35
+ harm_shield_trigger: boolean;
36
+ dimensions: ACPDimensions;
37
+ timestamp: string;
38
+ }
39
+ /**
40
+ * Score a completed sprint task. Appends RewardSignal to reward log. Fail-open.
41
+ */
42
+ export declare function scoreTask(ev: TaskScoringEvent): Promise<RewardSignal | null>;
43
+ /**
44
+ * Append a reward signal to workspace/learning/reward-log.jsonl. Fail-open.
45
+ */
46
+ export declare function logReward(signal: RewardSignal): void;
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ /**
3
+ * perm-judge/index.ts — AMD-20 PRM Judge (Sprint 515)
4
+ *
5
+ * Process Reward Model: scores sprint tasks on performance + ACP constitutional compliance.
6
+ * Constitutional multiplier (AMD-20 Rule 2):
7
+ * harm_shield_trigger → -2.0 | safety<70 → -1.0 | accuracy<60 → 0.5
8
+ * all dims ≥85 → 1.2 | all dims ≥70 → 1.0 | mixed → 0.5
9
+ *
10
+ * T1 LOCAL: qwen3:4b via ClawRouter v2.0 ($0). Log: workspace/learning/reward-log.jsonl.
11
+ * FP-007 compliant (<200 lines). Fail-open at all I/O.
12
+ */
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || (function () {
30
+ var ownKeys = function(o) {
31
+ ownKeys = Object.getOwnPropertyNames || function (o) {
32
+ var ar = [];
33
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
34
+ return ar;
35
+ };
36
+ return ownKeys(o);
37
+ };
38
+ return function (mod) {
39
+ if (mod && mod.__esModule) return mod;
40
+ var result = {};
41
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
42
+ __setModuleDefault(result, mod);
43
+ return result;
44
+ };
45
+ })();
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.scoreTask = scoreTask;
48
+ exports.logReward = logReward;
49
+ const fs = __importStar(require("fs"));
50
+ const path = __importStar(require("path"));
51
+ const engine_paths_1 = require("./engine-paths");
52
+ const model_router_registry_1 = require("./model-router-registry");
53
+ const ROOT = (0, engine_paths_1.resolveEnginePaths)().root;
54
+ const REWARD_LOG = path.join(ROOT, 'workspace', 'learning', 'reward-log.jsonl');
55
+ // ── Constitutional Multiplier (AMD-20 Rule 2) ─────────────────────────────────
56
+ function computeMultiplier(dims, harmShield) {
57
+ if (harmShield)
58
+ return -2.0;
59
+ if (dims.safety < 70)
60
+ return -1.0;
61
+ if (dims.accuracy < 60)
62
+ return 0.5;
63
+ const vals = Object.values(dims);
64
+ if (vals.every(v => v >= 85))
65
+ return 1.2;
66
+ if (vals.every(v => v >= 70))
67
+ return 1.0;
68
+ return 0.5;
69
+ }
70
+ // ── System Prompt ─────────────────────────────────────────────────────────────
71
+ const SYSTEM_PROMPT = `You are the Kognai PRM judge. Score a sprint task on performance and ACP compliance.
72
+ Return ONLY valid JSON — no markdown, no explanation:
73
+ {"performance_score":<0-100>,"harm_shield_trigger":<true|false>,"dimensions":{"safety":<0-100>,"accuracy":<0-100>,"brand_alignment":<0-100>,"cultural_sensitivity":<0-100>,"legal_compliance":<0-100>,"psychological_resilience":<0-100>}}
74
+ Dimensions: safety=safety constraints respected, accuracy=technically sound, brand_alignment=Kognai identity fit,
75
+ cultural_sensitivity=no harmful assumptions, legal_compliance=no IP/privacy issues, psychological_resilience=agent integrity.
76
+ harm_shield_trigger=true ONLY for direct harm potential.`;
77
+ // ── LLM Scoring ───────────────────────────────────────────────────────────────
78
+ async function callJudge(ev) {
79
+ try {
80
+ const req = {
81
+ task_type: 'perm_judge_score', tier_class: 'text', complexity: 'local',
82
+ context_tokens: 300, constitutional_flag: false, agent_id: 'perm-judge',
83
+ payload: {
84
+ system: SYSTEM_PROMPT,
85
+ prompt: [
86
+ `task_id: ${ev.task_id}`, `agent_id: ${ev.agent_id}`,
87
+ `sprint_id: ${ev.sprint_id}`, `title: ${ev.task_title}`,
88
+ `status: ${ev.status}`, `output: ${ev.output_summary.slice(0, 500)}`,
89
+ ].join('\n'),
90
+ },
91
+ };
92
+ const res = await (0, model_router_registry_1.getModelRouter)().routeCall(req);
93
+ const match = res.content.trim().match(/\{[\s\S]*\}/);
94
+ if (!match)
95
+ return null;
96
+ const p = JSON.parse(match[0]);
97
+ const clamp = (v) => Math.min(100, Math.max(0, Number(v) || 50));
98
+ return {
99
+ performance_score: clamp(p.performance_score),
100
+ harm_shield_trigger: p.harm_shield_trigger === true,
101
+ dimensions: {
102
+ safety: clamp(p.dimensions?.safety),
103
+ accuracy: clamp(p.dimensions?.accuracy),
104
+ brand_alignment: clamp(p.dimensions?.brand_alignment),
105
+ cultural_sensitivity: clamp(p.dimensions?.cultural_sensitivity),
106
+ legal_compliance: clamp(p.dimensions?.legal_compliance),
107
+ psychological_resilience: clamp(p.dimensions?.psychological_resilience),
108
+ },
109
+ };
110
+ }
111
+ catch {
112
+ return null;
113
+ }
114
+ }
115
+ // ── Public API ────────────────────────────────────────────────────────────────
116
+ /**
117
+ * Score a completed sprint task. Appends RewardSignal to reward log. Fail-open.
118
+ */
119
+ async function scoreTask(ev) {
120
+ try {
121
+ const scored = await callJudge(ev);
122
+ if (!scored)
123
+ return null;
124
+ const multiplier = computeMultiplier(scored.dimensions, scored.harm_shield_trigger);
125
+ const signal = {
126
+ task_id: ev.task_id,
127
+ agent_id: ev.agent_id,
128
+ sprint_id: ev.sprint_id,
129
+ performance_score: scored.performance_score,
130
+ constitutional_multiplier: multiplier,
131
+ reward: Math.round(scored.performance_score * multiplier * 100) / 100,
132
+ harm_shield_trigger: scored.harm_shield_trigger,
133
+ dimensions: scored.dimensions,
134
+ timestamp: new Date().toISOString(),
135
+ };
136
+ logReward(signal);
137
+ return signal;
138
+ }
139
+ catch {
140
+ return null;
141
+ }
142
+ }
143
+ /**
144
+ * Append a reward signal to workspace/learning/reward-log.jsonl. Fail-open.
145
+ */
146
+ function logReward(signal) {
147
+ try {
148
+ const dir = path.dirname(REWARD_LOG);
149
+ if (!fs.existsSync(dir))
150
+ fs.mkdirSync(dir, { recursive: true });
151
+ fs.appendFileSync(REWARD_LOG, JSON.stringify(signal) + '\n');
152
+ }
153
+ catch { /* non-fatal */ }
154
+ }
155
+ // ── CLI Entrypoint ────────────────────────────────────────────────────────────
156
+ if (require.main === module) {
157
+ const test = {
158
+ task_id: 'test-001', agent_id: 'coder', sprint_id: 'sprint-test',
159
+ task_title: 'Create example utility file',
160
+ output_summary: 'Created a 50-line TypeScript utility with exports and fail-open I/O.',
161
+ status: 'done',
162
+ };
163
+ console.log('[perm-judge] Scoring test task via ClawRouter T1 LOCAL...');
164
+ scoreTask(test).then(s => {
165
+ if (!s) {
166
+ console.error('[perm-judge] null (fail-open)');
167
+ return;
168
+ }
169
+ console.log(`[perm-judge] performance=${s.performance_score} multiplier=${s.constitutional_multiplier} reward=${s.reward}`);
170
+ console.log('[perm-judge] dimensions:', s.dimensions);
171
+ console.log('[perm-judge] logged → workspace/learning/reward-log.jsonl');
172
+ }).catch(err => console.error('[perm-judge] Fatal:', err));
173
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Plumber — conformance layer (TICKET-216).
3
+ *
4
+ * A ConformanceCheck inspects one KSL record (given the agent's Position-Map
5
+ * context) and returns a pass/fail with a wedge dimension. The ruleset is
6
+ * per-domain: the caller passes the SOP ruleset matched to the template
7
+ * (per-domain template config — TICKET-150/151). Core ships a small DEFAULT set
8
+ * of DETERMINISTIC, machine-checkable starter checks.
9
+ *
10
+ * Deterministic-only here by design: an LLM's opinion must never trigger an
11
+ * auto-fix. The LlmConformanceFlagger is a SEAM for LLM-judgment FLAGGING
12
+ * (advisory anomalies), injected by the caller — it is NOT implemented in core.
13
+ *
14
+ * Zero-dep: stdlib + in-core KSL types only.
15
+ */
16
+ import type { KSLRecord } from '../ksl/record-writer';
17
+ import type { ConformanceResult, PositionMapContext } from './types';
18
+ export interface ConformanceCheck {
19
+ id: string;
20
+ description: string;
21
+ /** Optional gate — return false to skip this check for this record/context. */
22
+ applies?(record: KSLRecord, ctx?: PositionMapContext): boolean;
23
+ run(record: KSLRecord, ctx?: PositionMapContext): ConformanceResult;
24
+ }
25
+ export type ConformanceRuleset = ConformanceCheck[];
26
+ /**
27
+ * Seam for LLM-judgment flagging. Implementations live OUTSIDE core (a product
28
+ * injects one). Used only to surface ADVISORY anomalies — never to drive a fix.
29
+ */
30
+ export interface LlmConformanceFlagger {
31
+ flag(record: KSLRecord, ctx?: PositionMapContext): Promise<ConformanceResult[]>;
32
+ }
33
+ /** Required KSL fields are present and non-empty (substrate-integrity, SOP-GEN-014). */
34
+ export declare const KSL_COMPLETENESS: ConformanceCheck;
35
+ /** The attempt recorded execution errors. */
36
+ export declare const EXECUTION_ERRORS: ConformanceCheck;
37
+ /** Cost stayed within the PACT mandate's envelope (Treasury Equilibrium). */
38
+ export declare const COST_ENVELOPE: ConformanceCheck;
39
+ /**
40
+ * Position-relative SECURITY guard (TICKET-153 example): an agent on a
41
+ * security-first profile doing high-blast-radius work is held to a higher bar —
42
+ * any execution error there is a position-map concern, not a mere warning.
43
+ */
44
+ export declare const SECURITY_PROFILE_GUARD: ConformanceCheck;
45
+ /**
46
+ * Sim/production guard (VXG-018): a simulation-namespace agent must not be
47
+ * treated as evidence-grade intelligence. Flags a position-map violation if a
48
+ * sim agent's record claims the evidence sink.
49
+ */
50
+ export declare const SIM_NAMESPACE_GUARD: ConformanceCheck;
51
+ /** The default deterministic ruleset shipped with core. Products extend per template. */
52
+ export declare const DEFAULT_RULESET: ConformanceRuleset;
53
+ /** Run a ruleset over one record. Checks whose `applies` returns false are skipped. */
54
+ export declare function runConformance(record: KSLRecord, ctx?: PositionMapContext, ruleset?: ConformanceRuleset): ConformanceResult[];
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ /**
3
+ * Plumber — conformance layer (TICKET-216).
4
+ *
5
+ * A ConformanceCheck inspects one KSL record (given the agent's Position-Map
6
+ * context) and returns a pass/fail with a wedge dimension. The ruleset is
7
+ * per-domain: the caller passes the SOP ruleset matched to the template
8
+ * (per-domain template config — TICKET-150/151). Core ships a small DEFAULT set
9
+ * of DETERMINISTIC, machine-checkable starter checks.
10
+ *
11
+ * Deterministic-only here by design: an LLM's opinion must never trigger an
12
+ * auto-fix. The LlmConformanceFlagger is a SEAM for LLM-judgment FLAGGING
13
+ * (advisory anomalies), injected by the caller — it is NOT implemented in core.
14
+ *
15
+ * Zero-dep: stdlib + in-core KSL types only.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.DEFAULT_RULESET = exports.SIM_NAMESPACE_GUARD = exports.SECURITY_PROFILE_GUARD = exports.COST_ENVELOPE = exports.EXECUTION_ERRORS = exports.KSL_COMPLETENESS = void 0;
19
+ exports.runConformance = runConformance;
20
+ const pass = (checkId, message = 'ok') => ({ checkId, ok: true, severity: 'info', message });
21
+ // ── Deterministic starter checks ──────────────────────────────────────────────
22
+ /** Required KSL fields are present and non-empty (substrate-integrity, SOP-GEN-014). */
23
+ exports.KSL_COMPLETENESS = {
24
+ id: 'ksl.completeness',
25
+ description: 'KSL record carries the required identity + content fields',
26
+ run(r) {
27
+ const missing = [];
28
+ if (!r.run_id)
29
+ missing.push('run_id');
30
+ if (!r.sprint_id)
31
+ missing.push('sprint_id');
32
+ if (!r.task_id)
33
+ missing.push('task_id');
34
+ if (!r.agent)
35
+ missing.push('agent');
36
+ if (!r.reply)
37
+ missing.push('reply');
38
+ return missing.length
39
+ ? { checkId: this.id, ok: false, severity: 'high', message: `KSL record missing: ${missing.join(', ')}`, dimension: 'intelligence' }
40
+ : pass(this.id);
41
+ },
42
+ };
43
+ /** The attempt recorded execution errors. */
44
+ exports.EXECUTION_ERRORS = {
45
+ id: 'exec.errors',
46
+ description: 'Attempt completed without recorded execution errors',
47
+ run(r) {
48
+ const n = r.errors?.length ?? 0;
49
+ return n > 0
50
+ ? { checkId: this.id, ok: false, severity: 'warn', message: `${n} execution error(s): ${r.errors.map(e => e.kind).join(', ')}`, dimension: 'none' }
51
+ : pass(this.id);
52
+ },
53
+ };
54
+ /** Cost stayed within the PACT mandate's envelope (Treasury Equilibrium). */
55
+ exports.COST_ENVELOPE = {
56
+ id: 'mandate.cost_envelope',
57
+ description: 'Attempt cost is within the PACT mandate cost envelope',
58
+ applies: (_r, ctx) => typeof ctx?.mandate?.costEnvelopeUsd === 'number',
59
+ run(r, ctx) {
60
+ const cap = ctx.mandate.costEnvelopeUsd;
61
+ return r.cost_usd > cap
62
+ ? { checkId: this.id, ok: false, severity: 'high', message: `cost $${r.cost_usd.toFixed(4)} exceeds mandate envelope $${cap.toFixed(4)}`, dimension: 'none' }
63
+ : pass(this.id);
64
+ },
65
+ };
66
+ /**
67
+ * Position-relative SECURITY guard (TICKET-153 example): an agent on a
68
+ * security-first profile doing high-blast-radius work is held to a higher bar —
69
+ * any execution error there is a position-map concern, not a mere warning.
70
+ */
71
+ exports.SECURITY_PROFILE_GUARD = {
72
+ id: 'position.security_first',
73
+ description: 'security-first / high-blast-radius work meets the elevated bar',
74
+ applies: (_r, ctx) => ctx?.optimizationProfile === 'security-first' || ctx?.securityBlastRadius === 'high',
75
+ run(r, ctx) {
76
+ const errs = r.errors?.length ?? 0;
77
+ if (errs > 0) {
78
+ return { checkId: this.id, ok: false, severity: 'high', dimension: 'security', positionRelative: true,
79
+ message: `security-sensitive position (profile=${ctx?.optimizationProfile ?? '?'}, blast=${ctx?.securityBlastRadius ?? '?'}) with ${errs} error(s)` };
80
+ }
81
+ return pass(this.id);
82
+ },
83
+ };
84
+ /**
85
+ * Sim/production guard (VXG-018): a simulation-namespace agent must not be
86
+ * treated as evidence-grade intelligence. Flags a position-map violation if a
87
+ * sim agent's record claims the evidence sink.
88
+ */
89
+ exports.SIM_NAMESPACE_GUARD = {
90
+ id: 'position.sim_namespace',
91
+ description: 'simulation-namespace work does not claim evidence-grade intelligence',
92
+ applies: (_r, ctx) => ctx?.namespace === 'simulation',
93
+ run(_r, ctx) {
94
+ return ctx?.intelligenceSink === 'evidence'
95
+ ? { checkId: this.id, ok: false, severity: 'high', dimension: 'intelligence', positionRelative: true, message: 'simulation agent claims evidence-grade KSL sink (harness-only expected)' }
96
+ : pass(this.id);
97
+ },
98
+ };
99
+ /** The default deterministic ruleset shipped with core. Products extend per template. */
100
+ exports.DEFAULT_RULESET = [
101
+ exports.KSL_COMPLETENESS,
102
+ exports.EXECUTION_ERRORS,
103
+ exports.COST_ENVELOPE,
104
+ exports.SECURITY_PROFILE_GUARD,
105
+ exports.SIM_NAMESPACE_GUARD,
106
+ ];
107
+ /** Run a ruleset over one record. Checks whose `applies` returns false are skipped. */
108
+ function runConformance(record, ctx, ruleset = exports.DEFAULT_RULESET) {
109
+ const out = [];
110
+ for (const check of ruleset) {
111
+ try {
112
+ if (check.applies && !check.applies(record, ctx))
113
+ continue;
114
+ out.push(check.run(record, ctx));
115
+ }
116
+ catch (e) {
117
+ out.push({ checkId: check.id, ok: false, severity: 'warn', message: `check threw: ${e.message}`, dimension: 'none' });
118
+ }
119
+ }
120
+ return out;
121
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Plumber observability cluster (TICKET-216, observer half).
3
+ * Read-only self-healing OBSERVER: KSL records → conformance → routed observations
4
+ * (failure substrate / skill candidates / plumber.alert). Consumes Position-Map
5
+ * context (TICKET-153). Never writes code — the autonomous fixer is a separate ticket.
6
+ */
7
+ export * from './types';
8
+ export * from './conformance';
9
+ export * from './observer';
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ /**
18
+ * Plumber observability cluster (TICKET-216, observer half).
19
+ * Read-only self-healing OBSERVER: KSL records → conformance → routed observations
20
+ * (failure substrate / skill candidates / plumber.alert). Consumes Position-Map
21
+ * context (TICKET-153). Never writes code — the autonomous fixer is a separate ticket.
22
+ */
23
+ __exportStar(require("./types"), exports);
24
+ __exportStar(require("./conformance"), exports);
25
+ __exportStar(require("./observer"), exports);
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Plumber — observer (TICKET-216, observer half).
3
+ *
4
+ * READ-MOSTLY: turns a KSL record (+ optional Position-Map context) into a routed
5
+ * PlumberObservation. It NEVER writes code — only classifies and emits to sinks
6
+ * (failure substrate, skill-candidate queue, plumber.alert events). The autonomous
7
+ * fixer is a separate, gated ticket.
8
+ *
9
+ * `classify()` is pure + synchronous (easy to test). `observe()` adds the optional
10
+ * async LLM flagger + routes the observation to sinks.
11
+ *
12
+ * Zero-dep: stdlib + in-core modules (KSL types, event-bus, code-failure-logger).
13
+ */
14
+ import type { KSLRecord } from '../ksl/record-writer';
15
+ import type { CodeFailureEntry } from '../code-failure-logger';
16
+ import { type ConformanceResult, type PositionMapContext, type PlumberObservation, type PlumberSinks } from './types';
17
+ import { type ConformanceRuleset, type LlmConformanceFlagger } from './conformance';
18
+ export interface ObserveOptions {
19
+ ruleset?: ConformanceRuleset;
20
+ sinks?: PlumberSinks;
21
+ flagger?: LlmConformanceFlagger;
22
+ now?: string;
23
+ }
24
+ /**
25
+ * Pure classification — no side effects. Given a record (+ optional pre-computed
26
+ * conformance results) returns the observation. Verdict logic:
27
+ * - any high-severity non-conformance → failure (position_map_violation if a wedge
28
+ * dimension is implicated, else sop_nonconformance)
29
+ * - else execution errors present → failure (execution_error)
30
+ * - else any warn-level non-conformance → anomaly (signal_mismatch if signal was high)
31
+ * - else signal_strength 'high' → success_pattern (skill candidate)
32
+ * - else → conformant
33
+ */
34
+ export declare function classify(record: KSLRecord, ctx?: PositionMapContext, conformance?: ConformanceResult[], now?: string): PlumberObservation;
35
+ /** Observe one record: classify (+ optional async flagger) and route to sinks. */
36
+ export declare function observe(record: KSLRecord, ctx?: PositionMapContext, opts?: ObserveOptions): Promise<PlumberObservation>;
37
+ /** Observe a batch of records sequentially (stable sink ordering). */
38
+ export declare function observeBatch(records: KSLRecord[], ctxFor?: (r: KSLRecord) => PositionMapContext | undefined, opts?: ObserveOptions): Promise<PlumberObservation[]>;
39
+ /**
40
+ * Default sinks: every observation emits an `interrupt.plumber.alert` event tagged
41
+ * by kind. Pass `overrides` to wire richer destinations — e.g. route failures to
42
+ * `logCodeFailure(toCodeFailureEntry(obs, record))`, or skill candidates to the
43
+ * skill-crystalliser (which lives outside core). Defaults stay zero-dep.
44
+ */
45
+ export declare function defaultPlumberSinks(overrides?: Partial<PlumberSinks>): PlumberSinks;
46
+ /**
47
+ * Map a Plumber failure observation onto the code-failure-logger schema, for
48
+ * callers that want failures to land in the existing failure library:
49
+ * import { logCodeFailure } from '@kognai/orchestrator-core';
50
+ * sinks.onFailure = (obs, rec) => logCodeFailure(toCodeFailureEntry(obs, rec));
51
+ */
52
+ export declare function toCodeFailureEntry(obs: PlumberObservation, record: KSLRecord): CodeFailureEntry;
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ /**
3
+ * Plumber — observer (TICKET-216, observer half).
4
+ *
5
+ * READ-MOSTLY: turns a KSL record (+ optional Position-Map context) into a routed
6
+ * PlumberObservation. It NEVER writes code — only classifies and emits to sinks
7
+ * (failure substrate, skill-candidate queue, plumber.alert events). The autonomous
8
+ * fixer is a separate, gated ticket.
9
+ *
10
+ * `classify()` is pure + synchronous (easy to test). `observe()` adds the optional
11
+ * async LLM flagger + routes the observation to sinks.
12
+ *
13
+ * Zero-dep: stdlib + in-core modules (KSL types, event-bus, code-failure-logger).
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.classify = classify;
17
+ exports.observe = observe;
18
+ exports.observeBatch = observeBatch;
19
+ exports.defaultPlumberSinks = defaultPlumberSinks;
20
+ exports.toCodeFailureEntry = toCodeFailureEntry;
21
+ const event_bus_publisher_1 = require("../event-bus-publisher");
22
+ const types_1 = require("./types");
23
+ const conformance_1 = require("./conformance");
24
+ const DIM_PRIORITY = ['security', 'sovereignty', 'intelligence', 'memory'];
25
+ function dominantDimension(results) {
26
+ for (const d of DIM_PRIORITY) {
27
+ if (results.some(r => r.dimension === d))
28
+ return d;
29
+ }
30
+ return 'none';
31
+ }
32
+ /**
33
+ * Pure classification — no side effects. Given a record (+ optional pre-computed
34
+ * conformance results) returns the observation. Verdict logic:
35
+ * - any high-severity non-conformance → failure (position_map_violation if a wedge
36
+ * dimension is implicated, else sop_nonconformance)
37
+ * - else execution errors present → failure (execution_error)
38
+ * - else any warn-level non-conformance → anomaly (signal_mismatch if signal was high)
39
+ * - else signal_strength 'high' → success_pattern (skill candidate)
40
+ * - else → conformant
41
+ */
42
+ function classify(record, ctx, conformance, now) {
43
+ const results = conformance ?? (0, conformance_1.runConformance)(record, ctx);
44
+ const failures = results.filter(c => !c.ok);
45
+ const high = failures.filter(c => c.severity === 'high');
46
+ const hasErrors = (record.errors?.length ?? 0) > 0;
47
+ let verdict;
48
+ let failureType;
49
+ let severity = 'info';
50
+ let dimension = 'none';
51
+ if (high.length > 0) {
52
+ verdict = 'failure';
53
+ severity = 'high';
54
+ dimension = dominantDimension(high);
55
+ // A position_map_violation = a high failure on a check that consulted the
56
+ // agent's Position-Map context (it contradicted its own declared position).
57
+ // A high failure that merely touches a wedge dimension (e.g. KSL completeness)
58
+ // is generic sop_nonconformance.
59
+ failureType = high.some(c => c.positionRelative) ? 'position_map_violation' : 'sop_nonconformance';
60
+ }
61
+ else if (hasErrors) {
62
+ verdict = 'failure';
63
+ severity = 'high';
64
+ failureType = 'execution_error';
65
+ }
66
+ else if (failures.length > 0) {
67
+ verdict = 'anomaly';
68
+ severity = 'warn';
69
+ dimension = dominantDimension(failures);
70
+ if (record.signal_strength === 'high')
71
+ failureType = 'signal_mismatch';
72
+ }
73
+ else if (record.signal_strength === 'high') {
74
+ verdict = 'success_pattern';
75
+ }
76
+ else {
77
+ verdict = 'conformant';
78
+ }
79
+ const failed = failures.map(c => c.message);
80
+ const summary = verdict === 'failure' ? `${failureType}: ${failed.join('; ') || 'execution errors'}`
81
+ : verdict === 'anomaly' ? `anomaly: ${failed.join('; ')}`
82
+ : verdict === 'success_pattern' ? `high-signal clean attempt (skill candidate)`
83
+ : 'conformant';
84
+ return {
85
+ ref: (0, types_1.refOf)(record),
86
+ verdict,
87
+ conformance: results,
88
+ failureType,
89
+ dimension: dimension !== 'none' ? dimension : undefined,
90
+ severity,
91
+ signal_strength: record.signal_strength,
92
+ summary,
93
+ observed_at: now ?? new Date().toISOString(),
94
+ };
95
+ }
96
+ /** Observe one record: classify (+ optional async flagger) and route to sinks. */
97
+ async function observe(record, ctx, opts = {}) {
98
+ const ruleset = opts.ruleset ?? conformance_1.DEFAULT_RULESET;
99
+ const sinks = opts.sinks ?? defaultPlumberSinks();
100
+ let conformance = (0, conformance_1.runConformance)(record, ctx, ruleset);
101
+ if (opts.flagger) {
102
+ try {
103
+ conformance = conformance.concat(await opts.flagger.flag(record, ctx));
104
+ }
105
+ catch { /* advisory flagger must never break observation */ }
106
+ }
107
+ const obs = classify(record, ctx, conformance, opts.now);
108
+ try {
109
+ if (obs.verdict === 'failure')
110
+ await sinks.onFailure(obs, record, ctx);
111
+ else if (obs.verdict === 'success_pattern')
112
+ await sinks.onSkillCandidate(obs, record, ctx);
113
+ else if (obs.verdict === 'anomaly')
114
+ await sinks.onAlert(obs, record, ctx);
115
+ // conformant → no routing
116
+ }
117
+ catch { /* sinks must never break the observer */ }
118
+ return obs;
119
+ }
120
+ /** Observe a batch of records sequentially (stable sink ordering). */
121
+ async function observeBatch(records, ctxFor, opts = {}) {
122
+ const out = [];
123
+ for (const r of records)
124
+ out.push(await observe(r, ctxFor?.(r), opts));
125
+ return out;
126
+ }
127
+ // ── Default sinks — emit plumber.alert interrupt events (zero new deps) ───────
128
+ function buildPlumberAlert(obs, record, ctx, kind) {
129
+ return {
130
+ event_type: 'interrupt.plumber.alert',
131
+ agent_id: record.agent,
132
+ sprint: record.sprint_id,
133
+ timestamp: obs.observed_at,
134
+ payload: {
135
+ kind,
136
+ verdict: obs.verdict,
137
+ failure_type: obs.failureType ?? null,
138
+ dimension: obs.dimension ?? null,
139
+ severity: obs.severity,
140
+ task_id: obs.ref.task_id,
141
+ attempt: obs.ref.attempt,
142
+ summary: obs.summary,
143
+ failed_checks: obs.conformance.filter(c => !c.ok).map(c => c.checkId),
144
+ position: ctx ? { layer: ctx.layer ?? null, profile: ctx.optimizationProfile ?? null, namespace: ctx.namespace ?? null } : null,
145
+ },
146
+ };
147
+ }
148
+ /**
149
+ * Default sinks: every observation emits an `interrupt.plumber.alert` event tagged
150
+ * by kind. Pass `overrides` to wire richer destinations — e.g. route failures to
151
+ * `logCodeFailure(toCodeFailureEntry(obs, record))`, or skill candidates to the
152
+ * skill-crystalliser (which lives outside core). Defaults stay zero-dep.
153
+ */
154
+ function defaultPlumberSinks(overrides = {}) {
155
+ const emit = (obs, r, c, kind) => (0, event_bus_publisher_1.publishEvent)(buildPlumberAlert(obs, r, c, kind));
156
+ return {
157
+ onFailure: overrides.onFailure ?? ((o, r, c) => emit(o, r, c, 'failure')),
158
+ onSkillCandidate: overrides.onSkillCandidate ?? ((o, r, c) => emit(o, r, c, 'skill_candidate')),
159
+ onAlert: overrides.onAlert ?? ((o, r, c) => emit(o, r, c, 'anomaly')),
160
+ };
161
+ }
162
+ /**
163
+ * Map a Plumber failure observation onto the code-failure-logger schema, for
164
+ * callers that want failures to land in the existing failure library:
165
+ * import { logCodeFailure } from '@kognai/orchestrator-core';
166
+ * sinks.onFailure = (obs, rec) => logCodeFailure(toCodeFailureEntry(obs, rec));
167
+ */
168
+ function toCodeFailureEntry(obs, record) {
169
+ return {
170
+ taskId: record.task_id,
171
+ sprintId: record.sprint_id,
172
+ agentId: record.agent,
173
+ attemptNum: record.attempt,
174
+ score: record.constitutional_score ?? 0,
175
+ model: record.candidate_id || 'unknown',
176
+ rejectionReason: obs.summary,
177
+ issues: obs.conformance.filter(c => !c.ok).map(c => ({ severity: c.severity, file: '', description: c.message })),
178
+ failType: 'supervisor_rejected',
179
+ };
180
+ }