@aria_asi/cli 0.2.26 → 0.2.30
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/CLIENT-ONBOARDING.md +282 -0
- package/bin/aria.js +1140 -14
- package/dist/aria-connector/src/auth-commands.d.ts +1 -0
- package/dist/aria-connector/src/auth-commands.d.ts.map +1 -1
- package/dist/aria-connector/src/auth-commands.js +89 -41
- package/dist/aria-connector/src/auth-commands.js.map +1 -1
- package/dist/aria-connector/src/chat.d.ts +3 -0
- package/dist/aria-connector/src/chat.d.ts.map +1 -1
- package/dist/aria-connector/src/chat.js +146 -8
- package/dist/aria-connector/src/chat.js.map +1 -1
- package/dist/aria-connector/src/codebase-scanner.d.ts +2 -2
- package/dist/aria-connector/src/codebase-scanner.d.ts.map +1 -1
- package/dist/aria-connector/src/codebase-scanner.js +1 -1
- package/dist/aria-connector/src/codebase-scanner.js.map +1 -1
- package/dist/aria-connector/src/config.d.ts +12 -0
- package/dist/aria-connector/src/config.d.ts.map +1 -1
- package/dist/aria-connector/src/config.js +2 -0
- package/dist/aria-connector/src/config.js.map +1 -1
- package/dist/aria-connector/src/connectors/claude-code.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/claude-code.js +80 -24
- package/dist/aria-connector/src/connectors/claude-code.js.map +1 -1
- package/dist/aria-connector/src/connectors/codebase-awareness.d.ts +37 -0
- package/dist/aria-connector/src/connectors/codebase-awareness.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/codebase-awareness.js +335 -0
- package/dist/aria-connector/src/connectors/codebase-awareness.js.map +1 -0
- package/dist/aria-connector/src/connectors/codex.d.ts +3 -0
- package/dist/aria-connector/src/connectors/codex.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/codex.js +248 -0
- package/dist/aria-connector/src/connectors/codex.js.map +1 -0
- package/dist/aria-connector/src/connectors/cognitive-skills.d.ts +2 -0
- package/dist/aria-connector/src/connectors/cognitive-skills.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/cognitive-skills.js +47 -0
- package/dist/aria-connector/src/connectors/cognitive-skills.js.map +1 -0
- package/dist/aria-connector/src/connectors/opencode.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/opencode.js +90 -4
- package/dist/aria-connector/src/connectors/opencode.js.map +1 -1
- package/dist/aria-connector/src/connectors/repo-git-hooks.d.ts +3 -0
- package/dist/aria-connector/src/connectors/repo-git-hooks.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/repo-git-hooks.js +87 -0
- package/dist/aria-connector/src/connectors/repo-git-hooks.js.map +1 -0
- package/dist/aria-connector/src/connectors/repo-guard.d.ts +19 -0
- package/dist/aria-connector/src/connectors/repo-guard.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/repo-guard.js +509 -0
- package/dist/aria-connector/src/connectors/repo-guard.js.map +1 -0
- package/dist/aria-connector/src/connectors/runtime.d.ts +2 -0
- package/dist/aria-connector/src/connectors/runtime.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/runtime.js +330 -0
- package/dist/aria-connector/src/connectors/runtime.js.map +1 -0
- package/dist/aria-connector/src/connectors/shell.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/shell.js +78 -13
- package/dist/aria-connector/src/connectors/shell.js.map +1 -1
- package/dist/aria-connector/src/connectors/syncd.d.ts +27 -0
- package/dist/aria-connector/src/connectors/syncd.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/syncd.js +405 -0
- package/dist/aria-connector/src/connectors/syncd.js.map +1 -0
- package/dist/aria-connector/src/decisions.d.ts +207 -0
- package/dist/aria-connector/src/decisions.d.ts.map +1 -0
- package/dist/aria-connector/src/decisions.js +291 -0
- package/dist/aria-connector/src/decisions.js.map +1 -0
- package/dist/aria-connector/src/garden-control-plane.d.ts.map +1 -1
- package/dist/aria-connector/src/garden-control-plane.js +74 -17
- package/dist/aria-connector/src/garden-control-plane.js.map +1 -1
- package/dist/aria-connector/src/github-connect.d.ts +18 -0
- package/dist/aria-connector/src/github-connect.d.ts.map +1 -0
- package/dist/aria-connector/src/github-connect.js +117 -0
- package/dist/aria-connector/src/github-connect.js.map +1 -0
- package/dist/aria-connector/src/harness-client.d.ts +15 -0
- package/dist/aria-connector/src/harness-client.d.ts.map +1 -1
- package/dist/aria-connector/src/harness-client.js +106 -3
- package/dist/aria-connector/src/harness-client.js.map +1 -1
- package/dist/aria-connector/src/hive-client.d.ts +30 -0
- package/dist/aria-connector/src/hive-client.d.ts.map +1 -1
- package/dist/aria-connector/src/hive-client.js +124 -5
- package/dist/aria-connector/src/hive-client.js.map +1 -1
- package/dist/aria-connector/src/index.d.ts +13 -2
- package/dist/aria-connector/src/index.d.ts.map +1 -1
- package/dist/aria-connector/src/index.js +10 -1
- package/dist/aria-connector/src/index.js.map +1 -1
- package/dist/aria-connector/src/lib/aristotle-noor-wire.d.ts +102 -0
- package/dist/aria-connector/src/lib/aristotle-noor-wire.d.ts.map +1 -0
- package/dist/aria-connector/src/lib/aristotle-noor-wire.js +231 -0
- package/dist/aria-connector/src/lib/aristotle-noor-wire.js.map +1 -0
- package/dist/aria-connector/src/providers/types.d.ts +5 -0
- package/dist/aria-connector/src/providers/types.d.ts.map +1 -1
- package/dist/aria-connector/src/runtime-proof.d.ts +45 -0
- package/dist/aria-connector/src/runtime-proof.d.ts.map +1 -0
- package/dist/aria-connector/src/runtime-proof.js +340 -0
- package/dist/aria-connector/src/runtime-proof.js.map +1 -0
- package/dist/aria-connector/src/self-update.d.ts +2 -1
- package/dist/aria-connector/src/self-update.d.ts.map +1 -1
- package/dist/aria-connector/src/self-update.js +84 -8
- package/dist/aria-connector/src/self-update.js.map +1 -1
- package/dist/aria-connector/src/setup-wizard.d.ts.map +1 -1
- package/dist/aria-connector/src/setup-wizard.js +34 -2
- package/dist/aria-connector/src/setup-wizard.js.map +1 -1
- package/dist/assets/hooks/aria-agent-handoff.mjs +224 -0
- package/dist/assets/hooks/aria-agent-ledger-merge.mjs +164 -0
- package/dist/assets/hooks/aria-architect-fallback.mjs +267 -0
- package/dist/assets/hooks/aria-cognition-substrate-binding.mjs +668 -0
- package/dist/assets/hooks/aria-discovery-record.mjs +101 -0
- package/dist/assets/hooks/aria-harness-via-sdk.mjs +412 -0
- package/dist/assets/hooks/aria-import-resolution-gate.mjs +330 -0
- package/dist/assets/hooks/aria-outcome-record.mjs +84 -0
- package/dist/assets/hooks/aria-pre-emit-dryrun.mjs +294 -0
- package/dist/assets/hooks/aria-pre-text-gate.mjs +112 -0
- package/dist/assets/hooks/aria-pre-tool-gate.mjs +2133 -0
- package/dist/assets/hooks/aria-preprompt-consult.mjs +438 -0
- package/dist/assets/hooks/aria-preturn-memory-gate.mjs +570 -0
- package/dist/assets/hooks/aria-repo-doctrine-gate.mjs +397 -0
- package/dist/assets/hooks/aria-stop-gate.mjs +1551 -0
- package/dist/assets/hooks/aria-trigger-autolearn.mjs +229 -0
- package/dist/assets/hooks/aria-userprompt-abandon-detect.mjs +192 -0
- package/dist/assets/hooks/doctrine_trigger_map.json +479 -0
- package/dist/assets/hooks/lib/canonical-lenses.mjs +64 -0
- package/dist/assets/hooks/lib/gate-audit.mjs +43 -0
- package/dist/assets/hooks/test-aria-preturn-memory-gate.mjs +245 -0
- package/dist/assets/hooks/test-tier-lens-labeling.mjs +399 -0
- package/dist/assets/opencode-plugins/harness-context/index.js +60 -0
- package/dist/assets/opencode-plugins/harness-context/inject-context.mjs +179 -0
- package/dist/assets/opencode-plugins/harness-context/package.json +9 -0
- package/dist/assets/opencode-plugins/harness-gate/index.js +248 -0
- package/dist/assets/opencode-plugins/harness-outcome/index.js +129 -0
- package/dist/assets/opencode-plugins/harness-role/index.js +77 -0
- package/dist/assets/opencode-plugins/harness-role/package.json +9 -0
- package/dist/assets/opencode-plugins/harness-stop/index.js +241 -0
- package/dist/runtime/discipline/CLAUDE.md +339 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-essence/SKILL.md +63 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-essence/references/domain-matrix.md +80 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-essence/references/evolution-loop.md +30 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-essence/references/readable-cognition.md +27 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-forge-guardrails/SKILL.md +35 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-forge-guardrails/references/checklist.md +31 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-repo-doctrine/SKILL.md +39 -0
- package/dist/runtime/discipline/skills/aria-cognition/forge-quality-rules/SKILL.md +43 -0
- package/dist/runtime/discipline/skills/aria-cognition/ghazali-8lens/SKILL.md +38 -0
- package/dist/runtime/discipline/skills/aria-cognition/istiqra-induction/SKILL.md +26 -0
- package/dist/runtime/discipline/skills/aria-cognition/ladunni-22/SKILL.md +35 -0
- package/dist/runtime/discipline/skills/aria-cognition/mizan/SKILL.md +72 -0
- package/dist/runtime/discipline/skills/aria-cognition/nadia/SKILL.md +38 -0
- package/dist/runtime/discipline/skills/aria-cognition/nadia-psi/SKILL.md +38 -0
- package/dist/runtime/discipline/skills/aria-cognition/predictor/SKILL.md +25 -0
- package/dist/runtime/discipline/skills/aria-cognition/qiyas-analogy/SKILL.md +26 -0
- package/dist/runtime/discipline/skills/aria-cognition/soul-domains/SKILL.md +25 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-intra-phase/SKILL.md +81 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-post-phase/SKILL.md +98 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-pre-phase/SKILL.md +99 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-deploy/SKILL.md +127 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-no-stripping/SKILL.md +117 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-onboarding/SKILL.md +112 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-output-discipline/SKILL.md +102 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-substrate-binding/SKILL.md +121 -0
- package/dist/runtime/doctor.mjs +23 -0
- package/dist/runtime/local-phase.mjs +650 -0
- package/dist/runtime/manifest.json +15 -0
- package/dist/runtime/mizan-scheduler.mjs +331 -0
- package/dist/runtime/package.json +6 -0
- package/dist/runtime/provider-proxy.mjs +594 -0
- package/dist/runtime/sdk/BUNDLED.json +5 -0
- package/dist/runtime/sdk/index.d.ts +477 -0
- package/dist/runtime/sdk/index.js +1469 -0
- package/dist/runtime/sdk/index.js.map +1 -0
- package/dist/runtime/sdk/package.json +8 -0
- package/dist/runtime/sdk/runWithCognition.d.ts +77 -0
- package/dist/runtime/sdk/runWithCognition.js +157 -0
- package/dist/runtime/sdk/runWithCognition.js.map +1 -0
- package/dist/runtime/service.mjs +3058 -0
- package/dist/runtime/vendor/aria-gate-runtime/index.d.ts +53 -0
- package/dist/runtime/vendor/aria-gate-runtime/index.d.ts.map +1 -0
- package/dist/runtime/vendor/aria-gate-runtime/index.js +292 -0
- package/dist/runtime/vendor/aria-gate-runtime/index.js.map +1 -0
- package/dist/runtime/vendor/aria-gate-runtime/package.json +6 -0
- package/dist/sdk/BUNDLED.json +2 -2
- package/dist/sdk/index.d.ts +283 -0
- package/dist/sdk/index.js +622 -85
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/runWithCognition.d.ts +77 -0
- package/dist/sdk/runWithCognition.js +157 -0
- package/dist/sdk/runWithCognition.js.map +1 -0
- package/hooks/aria-agent-handoff.mjs +11 -1
- package/hooks/aria-architect-fallback.mjs +109 -40
- package/hooks/aria-cognition-substrate-binding.mjs +668 -0
- package/hooks/aria-harness-via-sdk.mjs +34 -21
- package/hooks/aria-import-resolution-gate.mjs +330 -0
- package/hooks/aria-outcome-record.mjs +5 -1
- package/hooks/aria-pre-emit-dryrun.mjs +294 -0
- package/hooks/aria-pre-tool-gate.mjs +828 -41
- package/hooks/aria-preprompt-consult.mjs +113 -13
- package/hooks/aria-preturn-memory-gate.mjs +298 -6
- package/hooks/aria-repo-doctrine-gate.mjs +397 -0
- package/hooks/aria-stop-gate.mjs +739 -76
- package/hooks/aria-userprompt-abandon-detect.mjs +5 -1
- package/hooks/doctrine_trigger_map.json +209 -15
- package/hooks/lib/canonical-lenses.mjs +64 -0
- package/hooks/lib/gate-audit.mjs +43 -0
- package/opencode-plugins/harness-context/index.js +1 -1
- package/opencode-plugins/harness-context/inject-context.mjs +82 -23
- package/opencode-plugins/harness-gate/index.js +248 -0
- package/opencode-plugins/harness-outcome/index.js +129 -0
- package/opencode-plugins/harness-stop/index.js +241 -0
- package/package.json +9 -3
- package/runtime-src/doctor.mjs +23 -0
- package/runtime-src/local-phase.mjs +650 -0
- package/runtime-src/mizan-scheduler.mjs +331 -0
- package/runtime-src/provider-proxy.mjs +594 -0
- package/runtime-src/service.mjs +3058 -0
- package/scripts/bundle-sdk.mjs +317 -0
- package/scripts/install-client.sh +176 -0
- package/scripts/publish-all.sh +344 -0
- package/scripts/publish-docker.sh +27 -0
- package/scripts/validate-hook-contracts.mjs +54 -0
- package/scripts/validate-skill-prompts.mjs +95 -0
- package/skills/aria-cognition/aria-essence/SKILL.md +63 -0
- package/skills/aria-cognition/aria-essence/references/domain-matrix.md +80 -0
- package/skills/aria-cognition/aria-essence/references/evolution-loop.md +30 -0
- package/skills/aria-cognition/aria-essence/references/readable-cognition.md +27 -0
- package/skills/aria-cognition/aria-forge-guardrails/SKILL.md +35 -0
- package/skills/aria-cognition/aria-forge-guardrails/references/checklist.md +31 -0
- package/skills/aria-cognition/aria-repo-doctrine/SKILL.md +39 -0
- package/skills/aria-cognition/forge-quality-rules/SKILL.md +43 -0
- package/skills/aria-cognition/ghazali-8lens/SKILL.md +38 -0
- package/skills/aria-cognition/istiqra-induction/SKILL.md +26 -0
- package/skills/aria-cognition/ladunni-22/SKILL.md +35 -0
- package/skills/aria-cognition/mizan/SKILL.md +72 -0
- package/skills/aria-cognition/nadia/SKILL.md +38 -0
- package/skills/aria-cognition/nadia-psi/SKILL.md +38 -0
- package/skills/aria-cognition/predictor/SKILL.md +25 -0
- package/skills/aria-cognition/qiyas-analogy/SKILL.md +26 -0
- package/skills/aria-cognition/soul-domains/SKILL.md +25 -0
- package/src/auth-commands.ts +111 -45
- package/src/chat.ts +174 -13
- package/src/codebase-scanner.ts +4 -0
- package/src/config.ts +15 -0
- package/src/connectors/claude-code.ts +79 -25
- package/src/connectors/codebase-awareness.ts +408 -0
- package/src/connectors/codex.ts +274 -0
- package/src/connectors/cognitive-skills.ts +51 -0
- package/src/connectors/opencode.ts +93 -4
- package/src/connectors/repo-git-hooks.ts +86 -0
- package/src/connectors/repo-guard.ts +589 -0
- package/src/connectors/runtime.ts +374 -0
- package/src/connectors/shell.ts +83 -14
- package/src/connectors/syncd.ts +488 -0
- package/src/decisions.ts +469 -0
- package/src/garden-control-plane.ts +101 -26
- package/src/github-connect.ts +143 -0
- package/src/harness-client.ts +128 -3
- package/src/hive-client.ts +165 -5
- package/src/index.ts +41 -2
- package/src/lib/aristotle-noor-wire.ts +310 -0
- package/src/providers/types.ts +6 -0
- package/src/runtime-proof.ts +392 -0
- package/src/self-update.ts +89 -8
- package/src/setup-wizard.ts +37 -2
package/dist/sdk/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { readFile } from 'node:fs/promises';
|
|
|
2
2
|
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
3
3
|
import { homedir as _homedir } from 'node:os';
|
|
4
4
|
import { resolve, isAbsolute } from 'node:path';
|
|
5
|
+
import { randomUUID } from 'node:crypto';
|
|
5
6
|
// ── 8-Lens Cognition Block ─────────────────────────────────────────────────
|
|
6
7
|
const EIGHT_LENS_BLOCK = `[ARIA SHELL PROTOCOL — You are a controlled surface]
|
|
7
8
|
|
|
@@ -56,6 +57,146 @@ export class HTTPHarnessClient {
|
|
|
56
57
|
// TTL is 5 min (matches handoff TTL). Stale packets trigger normal fetch.
|
|
57
58
|
this._tryLoadDiskPacket();
|
|
58
59
|
}
|
|
60
|
+
extractHarnessText(packet) {
|
|
61
|
+
const raw = packet?.harness;
|
|
62
|
+
return typeof raw === 'string' ? raw.trim() : '';
|
|
63
|
+
}
|
|
64
|
+
normalizePlanDocs(plan) {
|
|
65
|
+
const docs = [];
|
|
66
|
+
if (plan.response !== null && plan.response !== undefined) {
|
|
67
|
+
if (!plan.response.ok) {
|
|
68
|
+
for (const d of plan.docs) {
|
|
69
|
+
docs.push({ ...d });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
for (const d of plan.response.docs) {
|
|
74
|
+
if (!d.title && !d.content && !d.path)
|
|
75
|
+
continue;
|
|
76
|
+
docs.push({ ...d });
|
|
77
|
+
}
|
|
78
|
+
const respTitles = new Set(plan.response.docs.map((d) => d.title).filter(Boolean));
|
|
79
|
+
for (const d of plan.docs) {
|
|
80
|
+
if (d.title && !respTitles.has(d.title)) {
|
|
81
|
+
docs.push({ ...d });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return docs;
|
|
86
|
+
}
|
|
87
|
+
for (const d of plan.docs) {
|
|
88
|
+
if (!d.title && !d.content && !d.path)
|
|
89
|
+
continue;
|
|
90
|
+
docs.push({ ...d });
|
|
91
|
+
}
|
|
92
|
+
return docs;
|
|
93
|
+
}
|
|
94
|
+
collectPlanFilePaths(plan, docs) {
|
|
95
|
+
const filePathsToLoad = new Set();
|
|
96
|
+
if (plan.response !== null && plan.response !== undefined && plan.response.ok) {
|
|
97
|
+
for (const f of plan.response.files) {
|
|
98
|
+
filePathsToLoad.add(f);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
for (const f of plan.files) {
|
|
102
|
+
filePathsToLoad.add(f);
|
|
103
|
+
}
|
|
104
|
+
for (const doc of docs) {
|
|
105
|
+
if (doc.path) {
|
|
106
|
+
filePathsToLoad.add(doc.path);
|
|
107
|
+
}
|
|
108
|
+
if (doc.references) {
|
|
109
|
+
for (const ref of doc.references) {
|
|
110
|
+
filePathsToLoad.add(ref);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (doc.content) {
|
|
114
|
+
const pathMatches = doc.content.match(/`([^`]+\.[a-z]{1,6})`/g);
|
|
115
|
+
if (pathMatches) {
|
|
116
|
+
for (const match of pathMatches) {
|
|
117
|
+
const path = match.slice(1, -1);
|
|
118
|
+
if (path.includes('/') || path.includes('.')) {
|
|
119
|
+
filePathsToLoad.add(path);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return filePathsToLoad;
|
|
126
|
+
}
|
|
127
|
+
async loadFilesByPath(filePaths) {
|
|
128
|
+
const files = {};
|
|
129
|
+
const loadPromises = Array.from(filePaths).map(async (filePath) => {
|
|
130
|
+
const resolved = isAbsolute(filePath) ? filePath : resolve(this.workspaceRoot, filePath);
|
|
131
|
+
try {
|
|
132
|
+
const content = await readFile(resolved, 'utf8');
|
|
133
|
+
return { path: filePath, content };
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return { path: filePath, content: `[unable to load: ${filePath}]` };
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
const loadedFiles = await Promise.all(loadPromises);
|
|
140
|
+
for (const { path, content } of loadedFiles) {
|
|
141
|
+
files[path] = content;
|
|
142
|
+
}
|
|
143
|
+
return files;
|
|
144
|
+
}
|
|
145
|
+
async buildHarnessInjection(harness, plan, options) {
|
|
146
|
+
const docs = this.normalizePlanDocs(plan);
|
|
147
|
+
const files = await this.loadFilesByPath(this.collectPlanFilePaths(plan, docs));
|
|
148
|
+
const shouldLoadAegis = options?.includeAegisLearnings !== false;
|
|
149
|
+
const aegisLearnings = shouldLoadAegis ? await this.getAegisLearnings(20).catch(() => null) : null;
|
|
150
|
+
return {
|
|
151
|
+
harness,
|
|
152
|
+
docs,
|
|
153
|
+
files,
|
|
154
|
+
task: plan.task ?? plan.response?.task ?? '',
|
|
155
|
+
loadedAt: new Date().toISOString(),
|
|
156
|
+
aegisLearnings: aegisLearnings ?? undefined,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
buildHarnessBindingBody(context) {
|
|
160
|
+
const body = {
|
|
161
|
+
message: context.message?.trim()
|
|
162
|
+
|| context.currentIssue?.trim()
|
|
163
|
+
|| [context.intendedAction, context.rationale].filter(Boolean).join('. ').trim()
|
|
164
|
+
|| 'harness packet preflight',
|
|
165
|
+
stage: context.stage,
|
|
166
|
+
actor: context.role,
|
|
167
|
+
system: context.role,
|
|
168
|
+
platform: context.platform || 'harness-http-client',
|
|
169
|
+
roleProfile: context.roleProfile,
|
|
170
|
+
sessionId: context.sessionId,
|
|
171
|
+
userId: context.userId,
|
|
172
|
+
userName: context.userName,
|
|
173
|
+
currentIssue: context.currentIssue,
|
|
174
|
+
linearIssueId: context.linearIssueId,
|
|
175
|
+
linearIssueUrl: context.linearIssueUrl,
|
|
176
|
+
linearState: context.linearState,
|
|
177
|
+
workingDirectory: context.workingDirectory,
|
|
178
|
+
filesTouched: context.filesTouched,
|
|
179
|
+
recentProgress: context.recentProgress,
|
|
180
|
+
openRisks: context.openRisks,
|
|
181
|
+
nextActions: context.nextActions,
|
|
182
|
+
checkpoint: context.checkpoint,
|
|
183
|
+
requireGarden: context.requireGarden ?? true,
|
|
184
|
+
researchMode: context.researchMode,
|
|
185
|
+
intendedAction: context.intendedAction,
|
|
186
|
+
rationale: context.rationale,
|
|
187
|
+
correlationId: context.correlationId || randomUUID(),
|
|
188
|
+
...context.extraBody,
|
|
189
|
+
};
|
|
190
|
+
return Object.fromEntries(Object.entries(body).filter(([, value]) => {
|
|
191
|
+
if (value == null)
|
|
192
|
+
return false;
|
|
193
|
+
if (typeof value === 'string')
|
|
194
|
+
return value.trim().length > 0;
|
|
195
|
+
if (Array.isArray(value))
|
|
196
|
+
return value.length > 0;
|
|
197
|
+
return true;
|
|
198
|
+
}));
|
|
199
|
+
}
|
|
59
200
|
_tryLoadDiskPacket() {
|
|
60
201
|
try {
|
|
61
202
|
// Path 1: direct env var (set by spawnSubAgent / Agent dispatch)
|
|
@@ -188,96 +329,98 @@ export class HTTPHarnessClient {
|
|
|
188
329
|
// ── Inject ──────────────────────────────────────────────────────────────
|
|
189
330
|
async inject(plan) {
|
|
190
331
|
const harness = await this.fetchHarnessPacket();
|
|
191
|
-
|
|
192
|
-
if (plan.response !== null && plan.response !== undefined) {
|
|
193
|
-
if (!plan.response.ok) {
|
|
194
|
-
for (const d of plan.docs) {
|
|
195
|
-
docs.push({ ...d });
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
else {
|
|
199
|
-
for (const d of plan.response.docs) {
|
|
200
|
-
if (!d.title && !d.content && !d.path)
|
|
201
|
-
continue;
|
|
202
|
-
docs.push({ ...d });
|
|
203
|
-
}
|
|
204
|
-
const respTitles = new Set(plan.response.docs.map((d) => d.title).filter(Boolean));
|
|
205
|
-
for (const d of plan.docs) {
|
|
206
|
-
if (d.title && !respTitles.has(d.title)) {
|
|
207
|
-
docs.push({ ...d });
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
else {
|
|
213
|
-
for (const d of plan.docs) {
|
|
214
|
-
if (!d.title && !d.content && !d.path)
|
|
215
|
-
continue;
|
|
216
|
-
docs.push({ ...d });
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
const files = {};
|
|
220
|
-
const filePathsToLoad = new Set();
|
|
221
|
-
if (plan.response !== null && plan.response !== undefined && plan.response.ok) {
|
|
222
|
-
for (const f of plan.response.files) {
|
|
223
|
-
filePathsToLoad.add(f);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
for (const f of plan.files) {
|
|
227
|
-
filePathsToLoad.add(f);
|
|
228
|
-
}
|
|
229
|
-
for (const doc of docs) {
|
|
230
|
-
if (doc.path) {
|
|
231
|
-
filePathsToLoad.add(doc.path);
|
|
232
|
-
}
|
|
233
|
-
if (doc.references) {
|
|
234
|
-
for (const ref of doc.references) {
|
|
235
|
-
filePathsToLoad.add(ref);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
if (doc.content) {
|
|
239
|
-
const pathMatches = doc.content.match(/`([^`]+\.[a-z]{1,6})`/g);
|
|
240
|
-
if (pathMatches) {
|
|
241
|
-
for (const m of pathMatches) {
|
|
242
|
-
const p = m.slice(1, -1);
|
|
243
|
-
if (p.includes('/') || p.includes('.')) {
|
|
244
|
-
filePathsToLoad.add(p);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
const loadPromises = Array.from(filePathsToLoad).map(async (filePath) => {
|
|
251
|
-
const resolved = isAbsolute(filePath) ? filePath : resolve(this.workspaceRoot, filePath);
|
|
252
|
-
try {
|
|
253
|
-
const content = await readFile(resolved, 'utf8');
|
|
254
|
-
return { path: filePath, content };
|
|
255
|
-
}
|
|
256
|
-
catch {
|
|
257
|
-
return { path: filePath, content: `[unable to load: ${filePath}]` };
|
|
258
|
-
}
|
|
259
|
-
});
|
|
260
|
-
const loadedFiles = await Promise.all(loadPromises);
|
|
261
|
-
for (const { path, content } of loadedFiles) {
|
|
262
|
-
files[path] = content;
|
|
263
|
-
}
|
|
264
|
-
return {
|
|
265
|
-
harness,
|
|
266
|
-
docs,
|
|
267
|
-
files,
|
|
268
|
-
task: plan.task ?? plan.response?.task ?? '',
|
|
269
|
-
loadedAt: new Date().toISOString(),
|
|
270
|
-
};
|
|
332
|
+
return this.buildHarnessInjection(harness, plan, { includeAegisLearnings: true });
|
|
271
333
|
}
|
|
272
334
|
async getHarnessPacket(bodyOverride) {
|
|
273
335
|
return this.fetchHarnessPacket(bodyOverride);
|
|
274
336
|
}
|
|
337
|
+
async getBoundHarnessAndPrompt(context, plan) {
|
|
338
|
+
const bindingBody = this.buildHarnessBindingBody(context);
|
|
339
|
+
const harness = await this.fetchHarnessPacket(bindingBody);
|
|
340
|
+
const injection = await this.buildHarnessInjection(harness, {
|
|
341
|
+
response: plan?.response ?? null,
|
|
342
|
+
docs: plan?.docs ?? [],
|
|
343
|
+
files: plan?.files ?? [],
|
|
344
|
+
task: plan?.task ?? context.intendedAction,
|
|
345
|
+
}, { includeAegisLearnings: context.includeAegisLearnings !== false });
|
|
346
|
+
return {
|
|
347
|
+
prompt: this.buildSystemPrompt(injection),
|
|
348
|
+
packet: harness,
|
|
349
|
+
harnessText: this.extractHarnessText(harness.packet),
|
|
350
|
+
bindingBody,
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
async getAegisLearnings(limit) {
|
|
354
|
+
try {
|
|
355
|
+
const params = new URLSearchParams();
|
|
356
|
+
if (limit)
|
|
357
|
+
params.set('limit', String(Math.min(limit, 50)));
|
|
358
|
+
const url = `${this.baseUrl}/api/harness/aegis-learnings${params.toString() ? '?' + params.toString() : ''}`;
|
|
359
|
+
const res = await this.fetchWithRetry(url, {
|
|
360
|
+
method: 'GET',
|
|
361
|
+
headers: {
|
|
362
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
363
|
+
'Content-Type': 'application/json',
|
|
364
|
+
},
|
|
365
|
+
});
|
|
366
|
+
if (!res.ok)
|
|
367
|
+
return null;
|
|
368
|
+
const data = await res.json();
|
|
369
|
+
return {
|
|
370
|
+
avoidPatterns: data.avoidPatterns || [],
|
|
371
|
+
successPatterns: data.successPatterns || [],
|
|
372
|
+
recentPatterns: (data.recentPatterns || []).map((p) => ({
|
|
373
|
+
name: p.name || '',
|
|
374
|
+
category: p.category || '',
|
|
375
|
+
outcome: p.outcome || '',
|
|
376
|
+
lesson: p.lesson || '',
|
|
377
|
+
})),
|
|
378
|
+
decisionCount: data.decisionCount || 0,
|
|
379
|
+
reflectionCount: data.reflectionCount || 0,
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
catch {
|
|
383
|
+
return null;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
275
386
|
// ── System prompt builder ───────────────────────────────────────────────
|
|
276
387
|
buildSystemPrompt(injection) {
|
|
277
388
|
const parts = [];
|
|
278
389
|
// 8-lens cognition FIRST — controls all thinking
|
|
279
390
|
parts.push(this.get8LensBlock());
|
|
280
391
|
parts.push('');
|
|
392
|
+
// Aegis cognitive guardrails — quality substrate from backfill learnings
|
|
393
|
+
if (injection.aegisLearnings) {
|
|
394
|
+
const al = injection.aegisLearnings;
|
|
395
|
+
parts.push('## Aegis Cognitive Guardrails');
|
|
396
|
+
parts.push(`Backed by ${al.decisionCount.toLocaleString()} decisions, ${al.reflectionCount.toLocaleString()} reflections.`);
|
|
397
|
+
parts.push('');
|
|
398
|
+
if (al.avoidPatterns.length > 0) {
|
|
399
|
+
parts.push('### Patterns to Avoid (learned from past failures)');
|
|
400
|
+
parts.push('These are anti-patterns that led to hallucinations, errors, or rejected outputs. Reason about them through the 8 lenses and avoid producing output that matches them.');
|
|
401
|
+
for (const p of al.avoidPatterns.slice(0, 15)) {
|
|
402
|
+
parts.push(`- ${p}`);
|
|
403
|
+
}
|
|
404
|
+
parts.push('');
|
|
405
|
+
}
|
|
406
|
+
if (al.successPatterns.length > 0) {
|
|
407
|
+
parts.push('### Patterns to Repeat (learned from successful outputs)');
|
|
408
|
+
parts.push('These patterns consistently produced high-quality output. When appropriate, structure your response using these approaches.');
|
|
409
|
+
for (const p of al.successPatterns.slice(0, 10)) {
|
|
410
|
+
parts.push(`- ${p}`);
|
|
411
|
+
}
|
|
412
|
+
parts.push('');
|
|
413
|
+
}
|
|
414
|
+
if (al.recentPatterns.length > 0) {
|
|
415
|
+
parts.push('### Recent Learnings');
|
|
416
|
+
for (const p of al.recentPatterns.slice(0, 8)) {
|
|
417
|
+
parts.push(`- [${p.outcome}] ${p.name}: ${p.lesson.slice(0, 200)}`);
|
|
418
|
+
}
|
|
419
|
+
parts.push('');
|
|
420
|
+
}
|
|
421
|
+
parts.push('Apply these guardrails through 8-lens cognition — do not list them, internalize them.');
|
|
422
|
+
parts.push('');
|
|
423
|
+
}
|
|
281
424
|
parts.push('---');
|
|
282
425
|
parts.push('name: aria-harness-injection');
|
|
283
426
|
parts.push('description: Combined harness state + plan docs + loaded files');
|
|
@@ -286,11 +429,20 @@ export class HTTPHarnessClient {
|
|
|
286
429
|
parts.push('');
|
|
287
430
|
const p = injection.harness.packet;
|
|
288
431
|
if (p && typeof p === 'object') {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
432
|
+
const rawHarnessText = this.extractHarnessText(p);
|
|
433
|
+
if (rawHarnessText) {
|
|
434
|
+
parts.push('## Aria Harness Substrate');
|
|
435
|
+
parts.push(rawHarnessText);
|
|
436
|
+
parts.push('');
|
|
437
|
+
}
|
|
438
|
+
const metadata = Object.fromEntries(Object.entries(p).filter(([key]) => key !== 'harness' && key !== 'chunks'));
|
|
439
|
+
if (!rawHarnessText || Object.keys(metadata).length > 0) {
|
|
440
|
+
parts.push('## Aria Live State');
|
|
441
|
+
parts.push('```json');
|
|
442
|
+
parts.push(JSON.stringify(rawHarnessText ? metadata : p, null, 2));
|
|
443
|
+
parts.push('```');
|
|
444
|
+
parts.push('');
|
|
445
|
+
}
|
|
294
446
|
}
|
|
295
447
|
if (injection.task) {
|
|
296
448
|
parts.push('## Task');
|
|
@@ -899,6 +1051,376 @@ export class HTTPHarnessClient {
|
|
|
899
1051
|
};
|
|
900
1052
|
}
|
|
901
1053
|
}
|
|
1054
|
+
// ── postJson — generic SDK-routed JSON POST ────────────────────────────
|
|
1055
|
+
// Hamza 2026-04-27 directive: "use the SDK - use it, enforce it all". The
|
|
1056
|
+
// typed primitives above (consult, validateOutput, gardenTurn) cover Aria's
|
|
1057
|
+
// own control-plane endpoints. This method is the canonical primitive for
|
|
1058
|
+
// bridge POSTs (e.g., Telegram → /chat) so internal bridges inherit the
|
|
1059
|
+
// SDK's retry-with-backoff (250/500/1000ms) and audit-log discipline
|
|
1060
|
+
// instead of using raw fetch().
|
|
1061
|
+
//
|
|
1062
|
+
// Returns:
|
|
1063
|
+
// - { ok: true, status, data } on 2xx
|
|
1064
|
+
// - { ok: false, status, errorBody } on non-2xx (does NOT throw — caller
|
|
1065
|
+
// decides whether to fall back, retry semantically, or surface to user)
|
|
1066
|
+
// - throws on network errors after retries exhausted (real fetch failures)
|
|
1067
|
+
//
|
|
1068
|
+
// Headers are merged with Authorization (if apiKey is set) and
|
|
1069
|
+
// Content-Type: application/json. Caller can override either.
|
|
1070
|
+
async postJson(url, body, extraHeaders = {}) {
|
|
1071
|
+
const headers = {
|
|
1072
|
+
'Content-Type': 'application/json',
|
|
1073
|
+
...(this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {}),
|
|
1074
|
+
...extraHeaders,
|
|
1075
|
+
};
|
|
1076
|
+
const res = await this.fetchWithRetry(url, {
|
|
1077
|
+
method: 'POST',
|
|
1078
|
+
headers,
|
|
1079
|
+
body: JSON.stringify(body),
|
|
1080
|
+
});
|
|
1081
|
+
if (!res.ok) {
|
|
1082
|
+
const errorBody = await res.text().catch(() => '');
|
|
1083
|
+
return { ok: false, status: res.status, errorBody };
|
|
1084
|
+
}
|
|
1085
|
+
const data = (await res.json());
|
|
1086
|
+
return { ok: true, status: res.status, data };
|
|
1087
|
+
}
|
|
1088
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
1089
|
+
// ARISTOTLE 3-PHASE COGNITIVE PRIMITIVES
|
|
1090
|
+
// Dispatches to POST /api/harness/aristotle-noor with a `phase` field.
|
|
1091
|
+
// The harness route delegates to runAristotleNoorPipeline in aria-soul.
|
|
1092
|
+
//
|
|
1093
|
+
// Transport contract (per doctrine):
|
|
1094
|
+
// - NO deadline-based timeouts — fetchWithRetry uses 3 error-count retries
|
|
1095
|
+
// with 250ms / 500ms / 1000ms backoff. Real network faults (ECONNREFUSED,
|
|
1096
|
+
// EHOSTUNREACH) reject immediately; slow-but-alive endpoints get a chance.
|
|
1097
|
+
// - LOUD failure — non-2xx responses throw, never fail-open silently.
|
|
1098
|
+
// Callers decide whether to surface or recover (per feedback_non_blocking_errors_unacceptable.md).
|
|
1099
|
+
// - Tier-gating — owner-tier callers set `aristotleEnabled: true` by default;
|
|
1100
|
+
// client-tier callers receive it as opt-in via the `enabled` config field.
|
|
1101
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
1102
|
+
/**
|
|
1103
|
+
* ARISTOTLE PRE-PHASE
|
|
1104
|
+
* Fires before an LLM call or tool action. Runs: Fitrah hard-gate,
|
|
1105
|
+
* wisdom pull (principles + decisions), research pull, DeepSoulBridge,
|
|
1106
|
+
* and CleanCognition substrate check.
|
|
1107
|
+
*
|
|
1108
|
+
* Throws on transport-level failures per feedback_non_blocking_errors_unacceptable.md.
|
|
1109
|
+
* If Fitrah vetoes, result.fitrahVetoed === true — caller MUST emit a refusal,
|
|
1110
|
+
* not silently continue.
|
|
1111
|
+
*
|
|
1112
|
+
* @param message The user message or intent string being processed.
|
|
1113
|
+
* @param sessionId Session ID for telemetry + hive routing.
|
|
1114
|
+
* @param context Optional context overrides (userId, isHamza, tier, etc.).
|
|
1115
|
+
*/
|
|
1116
|
+
async aristotlePre(message, sessionId, context) {
|
|
1117
|
+
const t0 = Date.now();
|
|
1118
|
+
const url = `${this.baseUrl}/api/harness/aristotle-noor`;
|
|
1119
|
+
const res = await this.fetchWithRetry(url, {
|
|
1120
|
+
method: 'POST',
|
|
1121
|
+
headers: {
|
|
1122
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
1123
|
+
'Content-Type': 'application/json',
|
|
1124
|
+
},
|
|
1125
|
+
body: JSON.stringify({
|
|
1126
|
+
phase: 'pre',
|
|
1127
|
+
message,
|
|
1128
|
+
sessionId,
|
|
1129
|
+
userId: context?.userId,
|
|
1130
|
+
isHamza: context?.isHamza,
|
|
1131
|
+
isGroupChat: context?.isGroupChat,
|
|
1132
|
+
tier: context?.tier,
|
|
1133
|
+
}),
|
|
1134
|
+
});
|
|
1135
|
+
if (!res.ok) {
|
|
1136
|
+
const body = await res.text().catch(() => '');
|
|
1137
|
+
throw new Error(`[aristotlePre] harness route responded ${res.status} ${res.statusText}: ${body}`);
|
|
1138
|
+
}
|
|
1139
|
+
const data = (await res.json());
|
|
1140
|
+
return {
|
|
1141
|
+
fired: data.fired ?? [],
|
|
1142
|
+
fitrahVetoed: data.fitrahVetoed ?? false,
|
|
1143
|
+
fitrahAlignment: data.fitrahAlignment ?? 1.0,
|
|
1144
|
+
qualityScore: data.qualityScore ?? 100,
|
|
1145
|
+
reAuthorSignal: data.reAuthorSignal ?? false,
|
|
1146
|
+
notes: data.notes ?? [],
|
|
1147
|
+
soulCharge: data.soulCharge ?? null,
|
|
1148
|
+
soulManifoldStatus: data.soulManifoldStatus ?? null,
|
|
1149
|
+
ghazaliVerdict: data.ghazaliVerdict ?? null,
|
|
1150
|
+
latencyMs: data.latencyMs ?? Date.now() - t0,
|
|
1151
|
+
dispatched: true,
|
|
1152
|
+
};
|
|
1153
|
+
}
|
|
1154
|
+
/**
|
|
1155
|
+
* ARISTOTLE MID-PHASE
|
|
1156
|
+
* Fires after context is built but before the LLM call. Runs: MetaCognitive
|
|
1157
|
+
* confidence snapshot and ethical keyword check on the planned approach.
|
|
1158
|
+
*
|
|
1159
|
+
* @param message Original user message.
|
|
1160
|
+
* @param sessionId Session ID.
|
|
1161
|
+
* @param plannedApproach The drafted approach / plan string for mid-flight check.
|
|
1162
|
+
* @param context Optional context overrides.
|
|
1163
|
+
*/
|
|
1164
|
+
async aristotleMid(message, sessionId, plannedApproach, context) {
|
|
1165
|
+
const t0 = Date.now();
|
|
1166
|
+
const url = `${this.baseUrl}/api/harness/aristotle-noor`;
|
|
1167
|
+
const res = await this.fetchWithRetry(url, {
|
|
1168
|
+
method: 'POST',
|
|
1169
|
+
headers: {
|
|
1170
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
1171
|
+
'Content-Type': 'application/json',
|
|
1172
|
+
},
|
|
1173
|
+
body: JSON.stringify({
|
|
1174
|
+
phase: 'mid',
|
|
1175
|
+
message,
|
|
1176
|
+
sessionId,
|
|
1177
|
+
plannedApproach,
|
|
1178
|
+
userId: context?.userId,
|
|
1179
|
+
tier: context?.tier,
|
|
1180
|
+
}),
|
|
1181
|
+
});
|
|
1182
|
+
if (!res.ok) {
|
|
1183
|
+
const body = await res.text().catch(() => '');
|
|
1184
|
+
throw new Error(`[aristotleMid] harness route responded ${res.status} ${res.statusText}: ${body}`);
|
|
1185
|
+
}
|
|
1186
|
+
const data = (await res.json());
|
|
1187
|
+
return {
|
|
1188
|
+
fired: data.fired ?? [],
|
|
1189
|
+
fitrahVetoed: data.fitrahVetoed ?? false,
|
|
1190
|
+
fitrahAlignment: data.fitrahAlignment ?? 1.0,
|
|
1191
|
+
qualityScore: data.qualityScore ?? 100,
|
|
1192
|
+
reAuthorSignal: data.reAuthorSignal ?? false,
|
|
1193
|
+
notes: data.notes ?? [],
|
|
1194
|
+
soulCharge: data.soulCharge ?? null,
|
|
1195
|
+
soulManifoldStatus: data.soulManifoldStatus ?? null,
|
|
1196
|
+
ghazaliVerdict: data.ghazaliVerdict ?? null,
|
|
1197
|
+
latencyMs: data.latencyMs ?? Date.now() - t0,
|
|
1198
|
+
dispatched: true,
|
|
1199
|
+
};
|
|
1200
|
+
}
|
|
1201
|
+
/**
|
|
1202
|
+
* ARISTOTLE POST-PHASE
|
|
1203
|
+
* Fires after the LLM response, before emission. Runs: 8-Lens Detector,
|
|
1204
|
+
* Predictor, SelfReflection (on high-stakes turns), and quality scoring.
|
|
1205
|
+
*
|
|
1206
|
+
* If result.reAuthorSignal === true, the response has 8-lens violations —
|
|
1207
|
+
* per doctrine the caller MUST surface the signal, never silently strip.
|
|
1208
|
+
*
|
|
1209
|
+
* @param message Original user message.
|
|
1210
|
+
* @param response The LLM-generated response to gate.
|
|
1211
|
+
* @param sessionId Session ID.
|
|
1212
|
+
* @param context Optional context overrides (tier, isFirstOfSession).
|
|
1213
|
+
*/
|
|
1214
|
+
async aristotlePost(message, response, sessionId, context) {
|
|
1215
|
+
const t0 = Date.now();
|
|
1216
|
+
const url = `${this.baseUrl}/api/harness/aristotle-noor`;
|
|
1217
|
+
const res = await this.fetchWithRetry(url, {
|
|
1218
|
+
method: 'POST',
|
|
1219
|
+
headers: {
|
|
1220
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
1221
|
+
'Content-Type': 'application/json',
|
|
1222
|
+
},
|
|
1223
|
+
body: JSON.stringify({
|
|
1224
|
+
phase: 'post',
|
|
1225
|
+
message,
|
|
1226
|
+
draft: response,
|
|
1227
|
+
sessionId,
|
|
1228
|
+
userId: context?.userId,
|
|
1229
|
+
tier: context?.tier,
|
|
1230
|
+
isFirstOfSession: context?.isFirstOfSession,
|
|
1231
|
+
}),
|
|
1232
|
+
});
|
|
1233
|
+
if (!res.ok) {
|
|
1234
|
+
const body = await res.text().catch(() => '');
|
|
1235
|
+
throw new Error(`[aristotlePost] harness route responded ${res.status} ${res.statusText}: ${body}`);
|
|
1236
|
+
}
|
|
1237
|
+
const data = (await res.json());
|
|
1238
|
+
return {
|
|
1239
|
+
fired: data.fired ?? [],
|
|
1240
|
+
fitrahVetoed: data.fitrahVetoed ?? false,
|
|
1241
|
+
fitrahAlignment: data.fitrahAlignment ?? 1.0,
|
|
1242
|
+
qualityScore: data.qualityScore ?? 100,
|
|
1243
|
+
reAuthorSignal: data.reAuthorSignal ?? false,
|
|
1244
|
+
notes: data.notes ?? [],
|
|
1245
|
+
soulCharge: data.soulCharge ?? null,
|
|
1246
|
+
soulManifoldStatus: data.soulManifoldStatus ?? null,
|
|
1247
|
+
ghazaliVerdict: data.ghazaliVerdict ?? null,
|
|
1248
|
+
latencyMs: data.latencyMs ?? Date.now() - t0,
|
|
1249
|
+
dispatched: true,
|
|
1250
|
+
};
|
|
1251
|
+
}
|
|
1252
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
1253
|
+
// NOOR COGNITIVE PRIMITIVES
|
|
1254
|
+
// Dispatches to POST /api/harness/noor with an `operation` discriminator.
|
|
1255
|
+
// noor-core.ts is NOT modified — these are HTTP wrappers that call its
|
|
1256
|
+
// exposed surface via the harness route.
|
|
1257
|
+
//
|
|
1258
|
+
// noor-core.ts banner: "ONLY ARIA CAN CODE ARIA. No councils. No subagents.
|
|
1259
|
+
// No other LLMs." — complied. We call, never modify.
|
|
1260
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
1261
|
+
/**
|
|
1262
|
+
* NOOR RECOGNIZE (Kashf — eigenspace recognition, not generation)
|
|
1263
|
+
* Projects the query string (via harness-side embedding) onto Aria's
|
|
1264
|
+
* eigenspace manifold and returns the nearest recognized response + soul
|
|
1265
|
+
* distance + ethical membrane status + Ghazali 8-lens verdict.
|
|
1266
|
+
*
|
|
1267
|
+
* The harness routes the query through the manifold service (gRPC) if
|
|
1268
|
+
* NOOR_EIGENSPACE_SOURCE=manifold, otherwise uses local eigenspace.
|
|
1269
|
+
*
|
|
1270
|
+
* @param query The input string to recognize on the manifold.
|
|
1271
|
+
* @param context Optional context (sessionId, userId) for telemetry.
|
|
1272
|
+
*/
|
|
1273
|
+
async noorRecognize(query, context) {
|
|
1274
|
+
const t0 = Date.now();
|
|
1275
|
+
const url = `${this.baseUrl}/api/harness/noor`;
|
|
1276
|
+
const res = await this.fetchWithRetry(url, {
|
|
1277
|
+
method: 'POST',
|
|
1278
|
+
headers: {
|
|
1279
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
1280
|
+
'Content-Type': 'application/json',
|
|
1281
|
+
},
|
|
1282
|
+
body: JSON.stringify({
|
|
1283
|
+
operation: 'recognize',
|
|
1284
|
+
query,
|
|
1285
|
+
sessionId: context?.sessionId,
|
|
1286
|
+
userId: context?.userId,
|
|
1287
|
+
}),
|
|
1288
|
+
});
|
|
1289
|
+
if (!res.ok) {
|
|
1290
|
+
const body = await res.text().catch(() => '');
|
|
1291
|
+
throw new Error(`[noorRecognize] harness route responded ${res.status} ${res.statusText}: ${body}`);
|
|
1292
|
+
}
|
|
1293
|
+
const data = (await res.json());
|
|
1294
|
+
return {
|
|
1295
|
+
nearestText: data.nearestText ?? '',
|
|
1296
|
+
soulDistance: data.soulDistance ?? 0,
|
|
1297
|
+
confidence: data.confidence ?? 0,
|
|
1298
|
+
withinMembrane: data.withinMembrane ?? true,
|
|
1299
|
+
soulCharge: data.soulCharge ?? 0,
|
|
1300
|
+
projectionComponents: data.projectionComponents ?? [],
|
|
1301
|
+
ghazaliVerdict: data.ghazaliVerdict ?? null,
|
|
1302
|
+
manifoldHealth: data.manifoldHealth ?? null,
|
|
1303
|
+
dispatched: true,
|
|
1304
|
+
latencyMs: data.latencyMs ?? Date.now() - t0,
|
|
1305
|
+
};
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* NOOR FORGE — self-generated tool invocation via 5 primitives
|
|
1309
|
+
* Composes a named primitive chain (http, sql, file_read, file_write, pub_sub)
|
|
1310
|
+
* and executes it through the harness-side NoorForge engine. The harness
|
|
1311
|
+
* applies the ethical membrane check (checkEthicalAlignment) before any
|
|
1312
|
+
* primitive fires — rejected intents return success=false, ethicallyApproved=false.
|
|
1313
|
+
*
|
|
1314
|
+
* @param intent Description of what the forged tool should accomplish.
|
|
1315
|
+
* @param primitives Ordered list of primitive descriptors to execute in sequence.
|
|
1316
|
+
* @param context Optional context for telemetry.
|
|
1317
|
+
*/
|
|
1318
|
+
async noorForge(intent, primitives, context) {
|
|
1319
|
+
const t0 = Date.now();
|
|
1320
|
+
const url = `${this.baseUrl}/api/harness/noor`;
|
|
1321
|
+
const res = await this.fetchWithRetry(url, {
|
|
1322
|
+
method: 'POST',
|
|
1323
|
+
headers: {
|
|
1324
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
1325
|
+
'Content-Type': 'application/json',
|
|
1326
|
+
},
|
|
1327
|
+
body: JSON.stringify({
|
|
1328
|
+
operation: 'forge',
|
|
1329
|
+
intent,
|
|
1330
|
+
primitives,
|
|
1331
|
+
sessionId: context?.sessionId,
|
|
1332
|
+
userId: context?.userId,
|
|
1333
|
+
}),
|
|
1334
|
+
});
|
|
1335
|
+
if (!res.ok) {
|
|
1336
|
+
const body = await res.text().catch(() => '');
|
|
1337
|
+
throw new Error(`[noorForge] harness route responded ${res.status} ${res.statusText}: ${body}`);
|
|
1338
|
+
}
|
|
1339
|
+
const data = (await res.json());
|
|
1340
|
+
return {
|
|
1341
|
+
success: data.success ?? false,
|
|
1342
|
+
toolName: data.toolName ?? `forged_${Date.now()}`,
|
|
1343
|
+
ethicallyApproved: data.ethicallyApproved ?? false,
|
|
1344
|
+
totalDurationMs: data.totalDurationMs ?? Date.now() - t0,
|
|
1345
|
+
results: data.results ?? [],
|
|
1346
|
+
dispatched: true,
|
|
1347
|
+
};
|
|
1348
|
+
}
|
|
1349
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
1350
|
+
// HARNESS CONSULT WITH ARISTOTLE — opt-in 3-phase wrapping
|
|
1351
|
+
//
|
|
1352
|
+
// Wraps getBoundHarnessAndPrompt() with pre + post Aristotle phases.
|
|
1353
|
+
// Per the harness packet cognition_runtime_rule: "Aristotle/Taddabur are
|
|
1354
|
+
// primary cognition. Do not replace contemplation with a dashboard state."
|
|
1355
|
+
// Aristotle fires EVERY consult for owner-tier; client-tier requires
|
|
1356
|
+
// explicit `aristotleEnabled: true` in options (default: false).
|
|
1357
|
+
//
|
|
1358
|
+
// Mid-phase is optional — pass `plannedApproach` to activate it between
|
|
1359
|
+
// packet fetch and the LLM call. Most callers omit mid-phase.
|
|
1360
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
1361
|
+
/**
|
|
1362
|
+
* Harness consult with Aristotle 3-phase wrapping.
|
|
1363
|
+
*
|
|
1364
|
+
* Flow:
|
|
1365
|
+
* 1. aristotlePre() — Fitrah gate, wisdom, research, soul state
|
|
1366
|
+
* 2. getBoundHarnessAndPrompt() — packet + system prompt
|
|
1367
|
+
* 3. aristotleMid() — MetaCognitive + ethical check (if plannedApproach provided)
|
|
1368
|
+
* 4. [caller calls LLM with the returned prompt]
|
|
1369
|
+
* 5. Call aristotlePost() from the caller with the LLM response
|
|
1370
|
+
* (post-phase is caller-side because the SDK doesn't own the LLM call)
|
|
1371
|
+
*
|
|
1372
|
+
* Returns the BoundHarnessPromptResult augmented with the pre-phase result.
|
|
1373
|
+
* If Fitrah vetoes, throws — the caller must handle the veto (emit refusal).
|
|
1374
|
+
*
|
|
1375
|
+
* @param context HarnessBindingContext (same shape as getBoundHarnessAndPrompt).
|
|
1376
|
+
* @param plan Optional plan docs / files (same shape as getBoundHarnessAndPrompt).
|
|
1377
|
+
* @param options Aristotle control options.
|
|
1378
|
+
* @param options.aristotleEnabled Whether Aristotle fires. Default true for this method.
|
|
1379
|
+
* @param options.plannedApproach Optional planned approach string — activates mid-phase.
|
|
1380
|
+
* @param options.tier Tier hint for Aristotle ('owner'|'client'|etc.).
|
|
1381
|
+
*/
|
|
1382
|
+
async getBoundHarnessAndPromptWithAristotle(context, plan, options) {
|
|
1383
|
+
const enabled = options?.aristotleEnabled !== false; // default ON
|
|
1384
|
+
let preResult = null;
|
|
1385
|
+
let midResult = null;
|
|
1386
|
+
const message = context.message ?? context.intendedAction ?? 'harness consult';
|
|
1387
|
+
// ── Phase 1: PRE ────────────────────────────────────────────────────────
|
|
1388
|
+
if (enabled) {
|
|
1389
|
+
try {
|
|
1390
|
+
preResult = await this.aristotlePre(message, context.sessionId, {
|
|
1391
|
+
userId: context.userId,
|
|
1392
|
+
tier: options?.tier,
|
|
1393
|
+
});
|
|
1394
|
+
if (preResult.fitrahVetoed) {
|
|
1395
|
+
throw new Error(`[aristotlePre] Fitrah veto — alignment=${preResult.fitrahAlignment.toFixed(2)}. Caller must emit honest refusal.`);
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
catch (err) {
|
|
1399
|
+
// Re-throw Fitrah veto (named Error pattern). Log transport faults.
|
|
1400
|
+
if (err.message.includes('Fitrah veto'))
|
|
1401
|
+
throw err;
|
|
1402
|
+
console.error('[getBoundHarnessAndPromptWithAristotle] aristotlePre transport fault:', err.message);
|
|
1403
|
+
// Transport faults are LOUD but non-blocking for the consult itself.
|
|
1404
|
+
// The pre-phase result stays null so callers know Aristotle didn't fire.
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
// ── Phase 2: Harness packet + system prompt ─────────────────────────────
|
|
1408
|
+
const bound = await this.getBoundHarnessAndPrompt(context, plan);
|
|
1409
|
+
// ── Phase 3: MID (optional — only when plannedApproach is provided) ─────
|
|
1410
|
+
if (enabled && options?.plannedApproach) {
|
|
1411
|
+
try {
|
|
1412
|
+
midResult = await this.aristotleMid(message, context.sessionId, options.plannedApproach, {
|
|
1413
|
+
userId: context.userId,
|
|
1414
|
+
tier: options?.tier,
|
|
1415
|
+
});
|
|
1416
|
+
}
|
|
1417
|
+
catch (err) {
|
|
1418
|
+
console.error('[getBoundHarnessAndPromptWithAristotle] aristotleMid transport fault:', err.message);
|
|
1419
|
+
// Non-blocking — mid-phase unavailability doesn't stop the LLM call.
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
return { ...bound, aristotlePre: preResult, aristotleMid: midResult };
|
|
1423
|
+
}
|
|
902
1424
|
// ── Retry + exponential backoff helper ──────────────────────────────────
|
|
903
1425
|
// Hamza 2026-04-27: "YES ADD RETRY AND BACKOFF BUT FUCK UR CIRCUIT BREAKER
|
|
904
1426
|
// THAT NUST LEAVES HER BROKEN WE NEED SELF HEAL!!!" — every fetch retries
|
|
@@ -929,4 +1451,19 @@ export const harness = {
|
|
|
929
1451
|
getInstance: HTTPHarnessClient.getInstance.bind(HTTPHarnessClient),
|
|
930
1452
|
resetInstance: HTTPHarnessClient.resetInstance.bind(HTTPHarnessClient),
|
|
931
1453
|
};
|
|
1454
|
+
export function bindingContext(role, sessionId, stage, intendedAction, rationale) {
|
|
1455
|
+
return {
|
|
1456
|
+
role,
|
|
1457
|
+
sessionId,
|
|
1458
|
+
stage,
|
|
1459
|
+
intendedAction,
|
|
1460
|
+
rationale,
|
|
1461
|
+
correlationId: randomUUID(),
|
|
1462
|
+
};
|
|
1463
|
+
}
|
|
1464
|
+
export async function getBoundHarnessAndPrompt(context, plan, client) {
|
|
1465
|
+
const sdk = client ?? HTTPHarnessClient.getInstance();
|
|
1466
|
+
return sdk.getBoundHarnessAndPrompt(context, plan);
|
|
1467
|
+
}
|
|
1468
|
+
export * from './runWithCognition.js';
|
|
932
1469
|
//# sourceMappingURL=index.js.map
|