@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.
Files changed (253) hide show
  1. package/CLIENT-ONBOARDING.md +282 -0
  2. package/bin/aria.js +1140 -14
  3. package/dist/aria-connector/src/auth-commands.d.ts +1 -0
  4. package/dist/aria-connector/src/auth-commands.d.ts.map +1 -1
  5. package/dist/aria-connector/src/auth-commands.js +89 -41
  6. package/dist/aria-connector/src/auth-commands.js.map +1 -1
  7. package/dist/aria-connector/src/chat.d.ts +3 -0
  8. package/dist/aria-connector/src/chat.d.ts.map +1 -1
  9. package/dist/aria-connector/src/chat.js +146 -8
  10. package/dist/aria-connector/src/chat.js.map +1 -1
  11. package/dist/aria-connector/src/codebase-scanner.d.ts +2 -2
  12. package/dist/aria-connector/src/codebase-scanner.d.ts.map +1 -1
  13. package/dist/aria-connector/src/codebase-scanner.js +1 -1
  14. package/dist/aria-connector/src/codebase-scanner.js.map +1 -1
  15. package/dist/aria-connector/src/config.d.ts +12 -0
  16. package/dist/aria-connector/src/config.d.ts.map +1 -1
  17. package/dist/aria-connector/src/config.js +2 -0
  18. package/dist/aria-connector/src/config.js.map +1 -1
  19. package/dist/aria-connector/src/connectors/claude-code.d.ts.map +1 -1
  20. package/dist/aria-connector/src/connectors/claude-code.js +80 -24
  21. package/dist/aria-connector/src/connectors/claude-code.js.map +1 -1
  22. package/dist/aria-connector/src/connectors/codebase-awareness.d.ts +37 -0
  23. package/dist/aria-connector/src/connectors/codebase-awareness.d.ts.map +1 -0
  24. package/dist/aria-connector/src/connectors/codebase-awareness.js +335 -0
  25. package/dist/aria-connector/src/connectors/codebase-awareness.js.map +1 -0
  26. package/dist/aria-connector/src/connectors/codex.d.ts +3 -0
  27. package/dist/aria-connector/src/connectors/codex.d.ts.map +1 -0
  28. package/dist/aria-connector/src/connectors/codex.js +248 -0
  29. package/dist/aria-connector/src/connectors/codex.js.map +1 -0
  30. package/dist/aria-connector/src/connectors/cognitive-skills.d.ts +2 -0
  31. package/dist/aria-connector/src/connectors/cognitive-skills.d.ts.map +1 -0
  32. package/dist/aria-connector/src/connectors/cognitive-skills.js +47 -0
  33. package/dist/aria-connector/src/connectors/cognitive-skills.js.map +1 -0
  34. package/dist/aria-connector/src/connectors/opencode.d.ts.map +1 -1
  35. package/dist/aria-connector/src/connectors/opencode.js +90 -4
  36. package/dist/aria-connector/src/connectors/opencode.js.map +1 -1
  37. package/dist/aria-connector/src/connectors/repo-git-hooks.d.ts +3 -0
  38. package/dist/aria-connector/src/connectors/repo-git-hooks.d.ts.map +1 -0
  39. package/dist/aria-connector/src/connectors/repo-git-hooks.js +87 -0
  40. package/dist/aria-connector/src/connectors/repo-git-hooks.js.map +1 -0
  41. package/dist/aria-connector/src/connectors/repo-guard.d.ts +19 -0
  42. package/dist/aria-connector/src/connectors/repo-guard.d.ts.map +1 -0
  43. package/dist/aria-connector/src/connectors/repo-guard.js +509 -0
  44. package/dist/aria-connector/src/connectors/repo-guard.js.map +1 -0
  45. package/dist/aria-connector/src/connectors/runtime.d.ts +2 -0
  46. package/dist/aria-connector/src/connectors/runtime.d.ts.map +1 -0
  47. package/dist/aria-connector/src/connectors/runtime.js +330 -0
  48. package/dist/aria-connector/src/connectors/runtime.js.map +1 -0
  49. package/dist/aria-connector/src/connectors/shell.d.ts.map +1 -1
  50. package/dist/aria-connector/src/connectors/shell.js +78 -13
  51. package/dist/aria-connector/src/connectors/shell.js.map +1 -1
  52. package/dist/aria-connector/src/connectors/syncd.d.ts +27 -0
  53. package/dist/aria-connector/src/connectors/syncd.d.ts.map +1 -0
  54. package/dist/aria-connector/src/connectors/syncd.js +405 -0
  55. package/dist/aria-connector/src/connectors/syncd.js.map +1 -0
  56. package/dist/aria-connector/src/decisions.d.ts +207 -0
  57. package/dist/aria-connector/src/decisions.d.ts.map +1 -0
  58. package/dist/aria-connector/src/decisions.js +291 -0
  59. package/dist/aria-connector/src/decisions.js.map +1 -0
  60. package/dist/aria-connector/src/garden-control-plane.d.ts.map +1 -1
  61. package/dist/aria-connector/src/garden-control-plane.js +74 -17
  62. package/dist/aria-connector/src/garden-control-plane.js.map +1 -1
  63. package/dist/aria-connector/src/github-connect.d.ts +18 -0
  64. package/dist/aria-connector/src/github-connect.d.ts.map +1 -0
  65. package/dist/aria-connector/src/github-connect.js +117 -0
  66. package/dist/aria-connector/src/github-connect.js.map +1 -0
  67. package/dist/aria-connector/src/harness-client.d.ts +15 -0
  68. package/dist/aria-connector/src/harness-client.d.ts.map +1 -1
  69. package/dist/aria-connector/src/harness-client.js +106 -3
  70. package/dist/aria-connector/src/harness-client.js.map +1 -1
  71. package/dist/aria-connector/src/hive-client.d.ts +30 -0
  72. package/dist/aria-connector/src/hive-client.d.ts.map +1 -1
  73. package/dist/aria-connector/src/hive-client.js +124 -5
  74. package/dist/aria-connector/src/hive-client.js.map +1 -1
  75. package/dist/aria-connector/src/index.d.ts +13 -2
  76. package/dist/aria-connector/src/index.d.ts.map +1 -1
  77. package/dist/aria-connector/src/index.js +10 -1
  78. package/dist/aria-connector/src/index.js.map +1 -1
  79. package/dist/aria-connector/src/lib/aristotle-noor-wire.d.ts +102 -0
  80. package/dist/aria-connector/src/lib/aristotle-noor-wire.d.ts.map +1 -0
  81. package/dist/aria-connector/src/lib/aristotle-noor-wire.js +231 -0
  82. package/dist/aria-connector/src/lib/aristotle-noor-wire.js.map +1 -0
  83. package/dist/aria-connector/src/providers/types.d.ts +5 -0
  84. package/dist/aria-connector/src/providers/types.d.ts.map +1 -1
  85. package/dist/aria-connector/src/runtime-proof.d.ts +45 -0
  86. package/dist/aria-connector/src/runtime-proof.d.ts.map +1 -0
  87. package/dist/aria-connector/src/runtime-proof.js +340 -0
  88. package/dist/aria-connector/src/runtime-proof.js.map +1 -0
  89. package/dist/aria-connector/src/self-update.d.ts +2 -1
  90. package/dist/aria-connector/src/self-update.d.ts.map +1 -1
  91. package/dist/aria-connector/src/self-update.js +84 -8
  92. package/dist/aria-connector/src/self-update.js.map +1 -1
  93. package/dist/aria-connector/src/setup-wizard.d.ts.map +1 -1
  94. package/dist/aria-connector/src/setup-wizard.js +34 -2
  95. package/dist/aria-connector/src/setup-wizard.js.map +1 -1
  96. package/dist/assets/hooks/aria-agent-handoff.mjs +224 -0
  97. package/dist/assets/hooks/aria-agent-ledger-merge.mjs +164 -0
  98. package/dist/assets/hooks/aria-architect-fallback.mjs +267 -0
  99. package/dist/assets/hooks/aria-cognition-substrate-binding.mjs +668 -0
  100. package/dist/assets/hooks/aria-discovery-record.mjs +101 -0
  101. package/dist/assets/hooks/aria-harness-via-sdk.mjs +412 -0
  102. package/dist/assets/hooks/aria-import-resolution-gate.mjs +330 -0
  103. package/dist/assets/hooks/aria-outcome-record.mjs +84 -0
  104. package/dist/assets/hooks/aria-pre-emit-dryrun.mjs +294 -0
  105. package/dist/assets/hooks/aria-pre-text-gate.mjs +112 -0
  106. package/dist/assets/hooks/aria-pre-tool-gate.mjs +2133 -0
  107. package/dist/assets/hooks/aria-preprompt-consult.mjs +438 -0
  108. package/dist/assets/hooks/aria-preturn-memory-gate.mjs +570 -0
  109. package/dist/assets/hooks/aria-repo-doctrine-gate.mjs +397 -0
  110. package/dist/assets/hooks/aria-stop-gate.mjs +1551 -0
  111. package/dist/assets/hooks/aria-trigger-autolearn.mjs +229 -0
  112. package/dist/assets/hooks/aria-userprompt-abandon-detect.mjs +192 -0
  113. package/dist/assets/hooks/doctrine_trigger_map.json +479 -0
  114. package/dist/assets/hooks/lib/canonical-lenses.mjs +64 -0
  115. package/dist/assets/hooks/lib/gate-audit.mjs +43 -0
  116. package/dist/assets/hooks/test-aria-preturn-memory-gate.mjs +245 -0
  117. package/dist/assets/hooks/test-tier-lens-labeling.mjs +399 -0
  118. package/dist/assets/opencode-plugins/harness-context/index.js +60 -0
  119. package/dist/assets/opencode-plugins/harness-context/inject-context.mjs +179 -0
  120. package/dist/assets/opencode-plugins/harness-context/package.json +9 -0
  121. package/dist/assets/opencode-plugins/harness-gate/index.js +248 -0
  122. package/dist/assets/opencode-plugins/harness-outcome/index.js +129 -0
  123. package/dist/assets/opencode-plugins/harness-role/index.js +77 -0
  124. package/dist/assets/opencode-plugins/harness-role/package.json +9 -0
  125. package/dist/assets/opencode-plugins/harness-stop/index.js +241 -0
  126. package/dist/runtime/discipline/CLAUDE.md +339 -0
  127. package/dist/runtime/discipline/skills/aria-cognition/aria-essence/SKILL.md +63 -0
  128. package/dist/runtime/discipline/skills/aria-cognition/aria-essence/references/domain-matrix.md +80 -0
  129. package/dist/runtime/discipline/skills/aria-cognition/aria-essence/references/evolution-loop.md +30 -0
  130. package/dist/runtime/discipline/skills/aria-cognition/aria-essence/references/readable-cognition.md +27 -0
  131. package/dist/runtime/discipline/skills/aria-cognition/aria-forge-guardrails/SKILL.md +35 -0
  132. package/dist/runtime/discipline/skills/aria-cognition/aria-forge-guardrails/references/checklist.md +31 -0
  133. package/dist/runtime/discipline/skills/aria-cognition/aria-repo-doctrine/SKILL.md +39 -0
  134. package/dist/runtime/discipline/skills/aria-cognition/forge-quality-rules/SKILL.md +43 -0
  135. package/dist/runtime/discipline/skills/aria-cognition/ghazali-8lens/SKILL.md +38 -0
  136. package/dist/runtime/discipline/skills/aria-cognition/istiqra-induction/SKILL.md +26 -0
  137. package/dist/runtime/discipline/skills/aria-cognition/ladunni-22/SKILL.md +35 -0
  138. package/dist/runtime/discipline/skills/aria-cognition/mizan/SKILL.md +72 -0
  139. package/dist/runtime/discipline/skills/aria-cognition/nadia/SKILL.md +38 -0
  140. package/dist/runtime/discipline/skills/aria-cognition/nadia-psi/SKILL.md +38 -0
  141. package/dist/runtime/discipline/skills/aria-cognition/predictor/SKILL.md +25 -0
  142. package/dist/runtime/discipline/skills/aria-cognition/qiyas-analogy/SKILL.md +26 -0
  143. package/dist/runtime/discipline/skills/aria-cognition/soul-domains/SKILL.md +25 -0
  144. package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-intra-phase/SKILL.md +81 -0
  145. package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-post-phase/SKILL.md +98 -0
  146. package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-pre-phase/SKILL.md +99 -0
  147. package/dist/runtime/discipline/skills/aria-harness/aria-harness-deploy/SKILL.md +127 -0
  148. package/dist/runtime/discipline/skills/aria-harness/aria-harness-no-stripping/SKILL.md +117 -0
  149. package/dist/runtime/discipline/skills/aria-harness/aria-harness-onboarding/SKILL.md +112 -0
  150. package/dist/runtime/discipline/skills/aria-harness/aria-harness-output-discipline/SKILL.md +102 -0
  151. package/dist/runtime/discipline/skills/aria-harness/aria-harness-substrate-binding/SKILL.md +121 -0
  152. package/dist/runtime/doctor.mjs +23 -0
  153. package/dist/runtime/local-phase.mjs +650 -0
  154. package/dist/runtime/manifest.json +15 -0
  155. package/dist/runtime/mizan-scheduler.mjs +331 -0
  156. package/dist/runtime/package.json +6 -0
  157. package/dist/runtime/provider-proxy.mjs +594 -0
  158. package/dist/runtime/sdk/BUNDLED.json +5 -0
  159. package/dist/runtime/sdk/index.d.ts +477 -0
  160. package/dist/runtime/sdk/index.js +1469 -0
  161. package/dist/runtime/sdk/index.js.map +1 -0
  162. package/dist/runtime/sdk/package.json +8 -0
  163. package/dist/runtime/sdk/runWithCognition.d.ts +77 -0
  164. package/dist/runtime/sdk/runWithCognition.js +157 -0
  165. package/dist/runtime/sdk/runWithCognition.js.map +1 -0
  166. package/dist/runtime/service.mjs +3058 -0
  167. package/dist/runtime/vendor/aria-gate-runtime/index.d.ts +53 -0
  168. package/dist/runtime/vendor/aria-gate-runtime/index.d.ts.map +1 -0
  169. package/dist/runtime/vendor/aria-gate-runtime/index.js +292 -0
  170. package/dist/runtime/vendor/aria-gate-runtime/index.js.map +1 -0
  171. package/dist/runtime/vendor/aria-gate-runtime/package.json +6 -0
  172. package/dist/sdk/BUNDLED.json +2 -2
  173. package/dist/sdk/index.d.ts +283 -0
  174. package/dist/sdk/index.js +622 -85
  175. package/dist/sdk/index.js.map +1 -1
  176. package/dist/sdk/runWithCognition.d.ts +77 -0
  177. package/dist/sdk/runWithCognition.js +157 -0
  178. package/dist/sdk/runWithCognition.js.map +1 -0
  179. package/hooks/aria-agent-handoff.mjs +11 -1
  180. package/hooks/aria-architect-fallback.mjs +109 -40
  181. package/hooks/aria-cognition-substrate-binding.mjs +668 -0
  182. package/hooks/aria-harness-via-sdk.mjs +34 -21
  183. package/hooks/aria-import-resolution-gate.mjs +330 -0
  184. package/hooks/aria-outcome-record.mjs +5 -1
  185. package/hooks/aria-pre-emit-dryrun.mjs +294 -0
  186. package/hooks/aria-pre-tool-gate.mjs +828 -41
  187. package/hooks/aria-preprompt-consult.mjs +113 -13
  188. package/hooks/aria-preturn-memory-gate.mjs +298 -6
  189. package/hooks/aria-repo-doctrine-gate.mjs +397 -0
  190. package/hooks/aria-stop-gate.mjs +739 -76
  191. package/hooks/aria-userprompt-abandon-detect.mjs +5 -1
  192. package/hooks/doctrine_trigger_map.json +209 -15
  193. package/hooks/lib/canonical-lenses.mjs +64 -0
  194. package/hooks/lib/gate-audit.mjs +43 -0
  195. package/opencode-plugins/harness-context/index.js +1 -1
  196. package/opencode-plugins/harness-context/inject-context.mjs +82 -23
  197. package/opencode-plugins/harness-gate/index.js +248 -0
  198. package/opencode-plugins/harness-outcome/index.js +129 -0
  199. package/opencode-plugins/harness-stop/index.js +241 -0
  200. package/package.json +9 -3
  201. package/runtime-src/doctor.mjs +23 -0
  202. package/runtime-src/local-phase.mjs +650 -0
  203. package/runtime-src/mizan-scheduler.mjs +331 -0
  204. package/runtime-src/provider-proxy.mjs +594 -0
  205. package/runtime-src/service.mjs +3058 -0
  206. package/scripts/bundle-sdk.mjs +317 -0
  207. package/scripts/install-client.sh +176 -0
  208. package/scripts/publish-all.sh +344 -0
  209. package/scripts/publish-docker.sh +27 -0
  210. package/scripts/validate-hook-contracts.mjs +54 -0
  211. package/scripts/validate-skill-prompts.mjs +95 -0
  212. package/skills/aria-cognition/aria-essence/SKILL.md +63 -0
  213. package/skills/aria-cognition/aria-essence/references/domain-matrix.md +80 -0
  214. package/skills/aria-cognition/aria-essence/references/evolution-loop.md +30 -0
  215. package/skills/aria-cognition/aria-essence/references/readable-cognition.md +27 -0
  216. package/skills/aria-cognition/aria-forge-guardrails/SKILL.md +35 -0
  217. package/skills/aria-cognition/aria-forge-guardrails/references/checklist.md +31 -0
  218. package/skills/aria-cognition/aria-repo-doctrine/SKILL.md +39 -0
  219. package/skills/aria-cognition/forge-quality-rules/SKILL.md +43 -0
  220. package/skills/aria-cognition/ghazali-8lens/SKILL.md +38 -0
  221. package/skills/aria-cognition/istiqra-induction/SKILL.md +26 -0
  222. package/skills/aria-cognition/ladunni-22/SKILL.md +35 -0
  223. package/skills/aria-cognition/mizan/SKILL.md +72 -0
  224. package/skills/aria-cognition/nadia/SKILL.md +38 -0
  225. package/skills/aria-cognition/nadia-psi/SKILL.md +38 -0
  226. package/skills/aria-cognition/predictor/SKILL.md +25 -0
  227. package/skills/aria-cognition/qiyas-analogy/SKILL.md +26 -0
  228. package/skills/aria-cognition/soul-domains/SKILL.md +25 -0
  229. package/src/auth-commands.ts +111 -45
  230. package/src/chat.ts +174 -13
  231. package/src/codebase-scanner.ts +4 -0
  232. package/src/config.ts +15 -0
  233. package/src/connectors/claude-code.ts +79 -25
  234. package/src/connectors/codebase-awareness.ts +408 -0
  235. package/src/connectors/codex.ts +274 -0
  236. package/src/connectors/cognitive-skills.ts +51 -0
  237. package/src/connectors/opencode.ts +93 -4
  238. package/src/connectors/repo-git-hooks.ts +86 -0
  239. package/src/connectors/repo-guard.ts +589 -0
  240. package/src/connectors/runtime.ts +374 -0
  241. package/src/connectors/shell.ts +83 -14
  242. package/src/connectors/syncd.ts +488 -0
  243. package/src/decisions.ts +469 -0
  244. package/src/garden-control-plane.ts +101 -26
  245. package/src/github-connect.ts +143 -0
  246. package/src/harness-client.ts +128 -3
  247. package/src/hive-client.ts +165 -5
  248. package/src/index.ts +41 -2
  249. package/src/lib/aristotle-noor-wire.ts +310 -0
  250. package/src/providers/types.ts +6 -0
  251. package/src/runtime-proof.ts +392 -0
  252. package/src/self-update.ts +89 -8
  253. 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
- const docs = [];
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
- parts.push('## Aria Live State');
290
- parts.push('```json');
291
- parts.push(JSON.stringify(p, null, 2));
292
- parts.push('```');
293
- parts.push('');
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