@aria_asi/cli 0.2.31 → 0.2.33

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 (79) hide show
  1. package/dist/aria-connector/src/connectors/claude-code.d.ts.map +1 -1
  2. package/dist/aria-connector/src/connectors/claude-code.js +30 -3
  3. package/dist/aria-connector/src/connectors/claude-code.js.map +1 -1
  4. package/dist/aria-connector/src/connectors/codebase-awareness.d.ts +8 -1
  5. package/dist/aria-connector/src/connectors/codebase-awareness.d.ts.map +1 -1
  6. package/dist/aria-connector/src/connectors/codebase-awareness.js +126 -71
  7. package/dist/aria-connector/src/connectors/codebase-awareness.js.map +1 -1
  8. package/dist/aria-connector/src/connectors/codex.d.ts.map +1 -1
  9. package/dist/aria-connector/src/connectors/codex.js +76 -9
  10. package/dist/aria-connector/src/connectors/codex.js.map +1 -1
  11. package/dist/aria-connector/src/connectors/must-read.d.ts.map +1 -1
  12. package/dist/aria-connector/src/connectors/must-read.js +4 -0
  13. package/dist/aria-connector/src/connectors/must-read.js.map +1 -1
  14. package/dist/aria-connector/src/connectors/opencode.js +25 -9
  15. package/dist/aria-connector/src/connectors/opencode.js.map +1 -1
  16. package/dist/aria-connector/src/setup-wizard.d.ts.map +1 -1
  17. package/dist/aria-connector/src/setup-wizard.js +91 -24
  18. package/dist/aria-connector/src/setup-wizard.js.map +1 -1
  19. package/dist/assets/hooks/aria-agent-handoff.mjs +23 -0
  20. package/dist/assets/hooks/aria-cognition-substrate-binding.mjs +69 -3
  21. package/dist/assets/hooks/aria-harness-via-sdk.mjs +10 -5
  22. package/dist/assets/hooks/aria-pre-emit-dryrun.mjs +35 -0
  23. package/dist/assets/hooks/aria-pre-tool-gate.mjs +217 -17
  24. package/dist/assets/hooks/aria-preprompt-consult.mjs +28 -2
  25. package/dist/assets/hooks/aria-preturn-memory-gate.mjs +30 -2
  26. package/dist/assets/hooks/aria-repo-doctrine-gate.mjs +31 -1
  27. package/dist/assets/hooks/aria-stop-gate.mjs +154 -37
  28. package/dist/assets/hooks/doctrine_trigger_map.json +55 -0
  29. package/dist/assets/hooks/lib/domain-output-quality.mjs +103 -0
  30. package/dist/assets/hooks/lib/skill-autoload-gate.mjs +1 -0
  31. package/dist/assets/opencode-plugins/harness-gate/index.js +84 -7
  32. package/dist/assets/opencode-plugins/harness-gate/lib/skill-autoload-gate.js +1 -0
  33. package/dist/assets/opencode-plugins/harness-outcome/index.js +39 -0
  34. package/dist/assets/opencode-plugins/harness-stop/index.js +101 -7
  35. package/dist/assets/opencode-plugins/harness-stop/lib/domain-output-quality.js +103 -0
  36. package/dist/assets/opencode-plugins/harness-stop/lib/skill-autoload-gate.js +1 -0
  37. package/dist/runtime/codex-bridge.mjs +71 -8
  38. package/dist/runtime/discipline/CLAUDE.md +16 -0
  39. package/dist/runtime/discipline/doctrine_trigger_map.json +55 -0
  40. package/dist/runtime/doctrine_trigger_map.json +55 -0
  41. package/dist/runtime/harness-daemon.mjs +80 -5
  42. package/dist/runtime/manifest.json +1 -1
  43. package/dist/runtime/sdk/BUNDLED.json +1 -1
  44. package/dist/runtime/sdk/index.d.ts +14 -0
  45. package/dist/runtime/sdk/index.js +23 -1
  46. package/dist/runtime/sdk/index.js.map +1 -1
  47. package/dist/runtime/service.mjs +385 -11
  48. package/dist/sdk/BUNDLED.json +1 -1
  49. package/dist/sdk/index.d.ts +14 -0
  50. package/dist/sdk/index.js +23 -1
  51. package/dist/sdk/index.js.map +1 -1
  52. package/hooks/aria-agent-handoff.mjs +23 -0
  53. package/hooks/aria-cognition-substrate-binding.mjs +69 -3
  54. package/hooks/aria-harness-via-sdk.mjs +10 -5
  55. package/hooks/aria-pre-emit-dryrun.mjs +35 -0
  56. package/hooks/aria-pre-tool-gate.mjs +217 -17
  57. package/hooks/aria-preprompt-consult.mjs +28 -2
  58. package/hooks/aria-preturn-memory-gate.mjs +30 -2
  59. package/hooks/aria-repo-doctrine-gate.mjs +31 -1
  60. package/hooks/aria-stop-gate.mjs +154 -37
  61. package/hooks/doctrine_trigger_map.json +55 -0
  62. package/hooks/lib/domain-output-quality.mjs +103 -0
  63. package/hooks/lib/skill-autoload-gate.mjs +1 -0
  64. package/opencode-plugins/harness-gate/index.js +84 -7
  65. package/opencode-plugins/harness-gate/lib/skill-autoload-gate.js +1 -0
  66. package/opencode-plugins/harness-outcome/index.js +39 -0
  67. package/opencode-plugins/harness-stop/index.js +101 -7
  68. package/opencode-plugins/harness-stop/lib/domain-output-quality.js +103 -0
  69. package/opencode-plugins/harness-stop/lib/skill-autoload-gate.js +1 -0
  70. package/package.json +1 -1
  71. package/runtime-src/codex-bridge.mjs +71 -8
  72. package/runtime-src/harness-daemon.mjs +80 -5
  73. package/runtime-src/service.mjs +385 -11
  74. package/src/connectors/claude-code.ts +31 -3
  75. package/src/connectors/codebase-awareness.ts +141 -77
  76. package/src/connectors/codex.ts +76 -9
  77. package/src/connectors/must-read.ts +4 -0
  78. package/src/connectors/opencode.ts +25 -9
  79. package/src/setup-wizard.ts +105 -25
@@ -1,10 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
4
+ import { createHash, randomUUID } from 'node:crypto';
4
5
  import { homedir } from 'node:os';
5
6
  import { delimiter, dirname, resolve } from 'node:path';
6
7
  import { spawn, spawnSync } from 'node:child_process';
7
8
  import { createRequire } from 'node:module';
9
+ import { evaluateSkillGate, formatSkillGateBlock } from '../../../ops/claude-hooks/lib/skill-autoload-gate.mjs';
8
10
 
9
11
  const require = createRequire(import.meta.url);
10
12
  const { WebSocketServer, WebSocket } = require('ws');
@@ -75,6 +77,24 @@ function sleep(ms) {
75
77
  return new Promise((resolvePromise) => setTimeout(resolvePromise, ms));
76
78
  }
77
79
 
80
+ function stableEvidenceString(value) {
81
+ if (typeof value === 'string') return value;
82
+ try { return JSON.stringify(value); } catch { return String(value); }
83
+ }
84
+
85
+ function makeEvidenceRef(kind, value, metadata = {}) {
86
+ const raw = stableEvidenceString(value);
87
+ const sha256 = createHash('sha256').update(raw).digest('hex');
88
+ return {
89
+ evidenceId: `ev_${sha256.slice(0, 16)}`,
90
+ kind,
91
+ at: new Date().toISOString(),
92
+ sha256,
93
+ preview: raw.slice(0, 500),
94
+ metadata,
95
+ };
96
+ }
97
+
78
98
  function readRuntimeToken() {
79
99
  const envToken = process.env.ARIA_HARNESS_TOKEN || process.env.ARIA_API_KEY || process.env.OPENAI_API_KEY || process.env.ARIA_MASTER_TOKEN;
80
100
  if (envToken) return envToken;
@@ -123,9 +143,10 @@ function ensureTurnState(threadId, turnId) {
123
143
  userText: '',
124
144
  preReceiptId: null,
125
145
  agentText: '',
126
- bufferedAgentNotifications: [],
127
- firstAgentItemId: null,
128
- };
146
+ bufferedAgentNotifications: [],
147
+ firstAgentItemId: null,
148
+ traceId: `trace_${randomUUID()}`,
149
+ };
129
150
  turnState.set(key, state);
130
151
  }
131
152
  return state;
@@ -186,6 +207,16 @@ async function validateTurnText(threadId, turnId) {
186
207
  if (!text) {
187
208
  return { ok: false, reason: 'No assistant text exists for this turn yet. Codex must emit readable cognition before action.' };
188
209
  }
210
+ const skillGate = evaluateSkillGate({
211
+ sessionId: `codex:${threadId}:${turnId}`,
212
+ surface: 'codex-bridge-output',
213
+ text: [state.userText, text].join('\n'),
214
+ isOutputCloseout: true,
215
+ autoLoadAvailable: false,
216
+ });
217
+ if (!skillGate.ok) {
218
+ return { ok: false, reason: formatSkillGateBlock(skillGate), result: { skillGate } };
219
+ }
189
220
  const result = await postRuntime('/validate-output', {
190
221
  text,
191
222
  sessionId: `codex:${threadId}:${turnId}`,
@@ -198,6 +229,7 @@ async function validateTurnText(threadId, turnId) {
198
229
  stage: 'codex-turn',
199
230
  actor: 'codex-bridge',
200
231
  system: 'codex-bridge',
232
+ traceId: state.traceId,
201
233
  },
202
234
  });
203
235
  const pass = result?.pass === true && result?.validation?.passed !== false;
@@ -210,11 +242,29 @@ async function validateTurnText(threadId, turnId) {
210
242
  };
211
243
  }
212
244
 
213
- async function checkActionAgainstRuntime(action, target, threadId, turnId) {
245
+ async function checkActionAgainstRuntime(action, target, threadId, turnId, metadata = {}) {
246
+ const state = ensureTurnState(threadId, turnId);
247
+ const skillGate = evaluateSkillGate({
248
+ sessionId: `codex:${threadId}:${turnId}`,
249
+ surface: 'codex-bridge-action',
250
+ text: target,
251
+ action: target,
252
+ toolName: action,
253
+ isDeploy: action === 'deploy',
254
+ isMutation: action === 'write',
255
+ autoLoadAvailable: false,
256
+ });
257
+ if (!skillGate.ok) {
258
+ return { ok: false, reason: formatSkillGateBlock(skillGate), result: { skillGate } };
259
+ }
214
260
  const result = await postRuntime('/check-action', {
215
261
  action,
216
262
  target,
217
263
  sessionId: `codex:${threadId}:${turnId}`,
264
+ actor: 'codex',
265
+ roleProfile: process.env.CODEX_ARIA_ROLE_PROFILE || process.env.ARIA_ROLE_PROFILE || null,
266
+ verifyText: state.agentText || '',
267
+ ...metadata,
218
268
  });
219
269
  if (result?.allowed === false) {
220
270
  return {
@@ -244,6 +294,8 @@ async function recordMizanPre(threadId, turnId) {
244
294
  surface: 'codex-bridge',
245
295
  platform: 'codex',
246
296
  userText: state.userText,
297
+ traceId: state.traceId,
298
+ evidenceRefs: [makeEvidenceRef('user_input', state.userText, { threadId, turnId, traceId: state.traceId })],
247
299
  },
248
300
  });
249
301
  state.preReceiptId = result?.receipt?.receiptId || null;
@@ -262,6 +314,8 @@ async function recordMizanPost(threadId, turnId, pass, summary) {
262
314
  evidence: {
263
315
  validated_output: pass,
264
316
  bridge: 'codex',
317
+ trace_id: state.traceId,
318
+ output_ref: makeEvidenceRef('assistant_output', state.agentText || summary, { threadId, turnId, traceId: state.traceId }),
265
319
  },
266
320
  context: {
267
321
  sessionId: `codex:${threadId}:${turnId}`,
@@ -269,6 +323,7 @@ async function recordMizanPost(threadId, turnId, pass, summary) {
269
323
  platform: 'codex',
270
324
  userText: state.userText,
271
325
  summary,
326
+ traceId: state.traceId,
272
327
  },
273
328
  });
274
329
  } catch (error) {
@@ -285,6 +340,8 @@ async function recordMizanPost(threadId, turnId, pass, summary) {
285
340
  details: {
286
341
  threadId,
287
342
  turnId,
343
+ traceId: state.traceId,
344
+ outputRef: makeEvidenceRef('assistant_output', state.agentText || summary, { threadId, turnId, traceId: state.traceId }),
288
345
  },
289
346
  });
290
347
  } catch (error) {
@@ -336,7 +393,9 @@ async function handleApprovalRequest(upstream, downstream, message) {
336
393
  cwd: params.cwd || null,
337
394
  commandActions: params.commandActions || params.parsedCmd || null,
338
395
  }).slice(0, 1500);
339
- const actionCheck = await checkActionAgainstRuntime(action, target, threadId, turnId);
396
+ const actionCheck = await checkActionAgainstRuntime(action, target, threadId, turnId, {
397
+ requireVerify: action === 'delete' || action === 'deploy',
398
+ });
340
399
  if (!actionCheck.ok) {
341
400
  const reason = `Aria runtime denied ${action}: ${actionCheck.reason}`;
342
401
  upstream.send(JSON.stringify(makeGuardianWarning(threadId, reason)));
@@ -360,8 +419,9 @@ async function handleApprovalRequest(upstream, downstream, message) {
360
419
  }
361
420
 
362
421
  if (method === 'item/fileChange/requestApproval' || method === 'applyPatchApproval') {
363
- const target = params.grantRoot || params.reason || params.itemId || 'file-change';
364
- const actionCheck = await checkActionAgainstRuntime('write', String(target), threadId, turnId);
422
+ const target = params.grantRoot || params.path || params.filePath || params.reason || params.itemId || 'file-change';
423
+ const files = [params.path, params.filePath, params.grantRoot].filter((value) => typeof value === 'string' && value.trim());
424
+ const actionCheck = await checkActionAgainstRuntime('write', String(target), threadId, turnId, { files });
365
425
  if (!actionCheck.ok) {
366
426
  const reason = `Aria runtime denied file change: ${actionCheck.reason}`;
367
427
  upstream.send(JSON.stringify(makeGuardianWarning(threadId, reason)));
@@ -390,7 +450,10 @@ async function handleApprovalRequest(upstream, downstream, message) {
390
450
  permissions: params.permissions || null,
391
451
  reason: params.reason || null,
392
452
  }).slice(0, 1500);
393
- const actionCheck = await checkActionAgainstRuntime('write', target, threadId, turnId);
453
+ const files = Array.isArray(params.permissions?.fileSystem?.entries)
454
+ ? params.permissions.fileSystem.entries.filter((value) => typeof value === 'string' && value.trim())
455
+ : [];
456
+ const actionCheck = await checkActionAgainstRuntime('write', target, threadId, turnId, { files });
394
457
  if (!actionCheck.ok) {
395
458
  const reason = `Aria runtime denied permissions request: ${actionCheck.reason}`;
396
459
  upstream.send(JSON.stringify(makeGuardianWarning(threadId, reason)));
@@ -164,6 +164,22 @@ Every non-trivial assistant turn must satisfy all three.
164
164
 
165
165
  **REJECTED (qualitative drift):** `better`, `improved`, `should work`, `more reliable`, `cleaner`, `nicer`. These are unmeasurable.
166
166
 
167
+ ### `<applied_cognition>` — required with every non-trivial cognition block
168
+
169
+ The cognition block is not accepted as proof by itself. It must bind to a concrete action or output claim and state what changed because cognition ran.
170
+
171
+ ```
172
+ <applied_cognition>
173
+ decision_delta: <what changed because cognition ran; not "none">
174
+ dominant_domain: <engineering_quality | trust | operations | security | product | ...>
175
+ binds_to: <the next tool/action/output claim this cognition constrains>
176
+ expected_predicate: <numeric, boolean, or state-string predicate proving success>
177
+ artifact_change: <how the produced artifact/action/output differs because cognition ran>
178
+ </applied_cognition>
179
+ ```
180
+
181
+ **Rejected:** missing fields, `decision_delta: none`, or a contract that does not bind to the next action/output. This is the structural enforcement for apply-lenses-don't-perform.
182
+
167
183
  ### `<verify>` — required for deploy commands
168
184
 
169
185
  A deploy is anything matching `deploy-service.sh|kubectl apply -f|kubectl set image|docker push|trivial deploy|fast path deploy`. Without a verify block, the pre-tool-gate hard-blocks.
@@ -453,6 +453,61 @@
453
453
  "counter_action": "Re-emit with explicit Layer 1/2/3 enumeration: packet=yes/no, BIND=yes/no, live-gates=yes/no (and which).",
454
454
  "message": "Harness-state claim without 3-layer enumeration. Per feedback_packet_is_not_harness.md, name explicitly which of {packet, BIND, live-gates} are active for the consumer."
455
455
  },
456
+ {
457
+ "trigger_id": "function_name_inference_without_contract_read",
458
+ "trigger": "(?:based on|from|by) (?:the )?(?:name|function name)|sounds like|looks like (?:a|an)|just memory search|just a search|just a cache|just a wrapper",
459
+ "rx": "(?:based on|from|by) (?:the )?(?:name|function name)|sounds like|looks like (?:a|an)|just memory search|just a search|just a cache|just a wrapper",
460
+ "doctrine": "memory:feedback_no_assumption_without_verification.md",
461
+ "memory": "feedback_no_assumption_without_verification.md",
462
+ "severity": "block",
463
+ "teaching": "Function names are not contracts. Inferring behavior from names instead of reading inputs, side effects, return shape, and call sites is skimming disguised as analysis.",
464
+ "counter_action": "Read the function body and at least one caller before asserting purpose. State observed contract: inputs, mutation/read behavior, return value, fallback path, and why the caller needs it.",
465
+ "message": "Name-based function inference detected. Re-read the actual function body and caller contract before making architecture claims."
466
+ },
467
+ {
468
+ "trigger_id": "always_on_state_treated_as_cold_start",
469
+ "trigger": "(?:need to|should|must).{0,80}(?:warm|rebuild|reconstruct|recreate|recompute|re-project|reproject).{0,80}(?:state|projection|manifold|cognition|garden|memory)|system is hot and ready|make it hot",
470
+ "rx": "(?:need to|should|must).{0,80}(?:warm|rebuild|reconstruct|recreate|recompute|re-project|reproject).{0,80}(?:state|projection|manifold|cognition|garden|memory)|system is hot and ready|make it hot",
471
+ "doctrine": "memory:feedback_no_assumption_without_verification.md",
472
+ "memory": "feedback_no_assumption_without_verification.md",
473
+ "severity": "block",
474
+ "teaching": "Aria's resident manifold/Garden/cognition substrate is always-on. Treating it as cold request-time state causes duplicate work and wrong architecture fixes.",
475
+ "counter_action": "Identify the resident producer and read surface first. If turn-specific mutation is required, call it once and pass the resulting packet forward; do not rebuild or re-project because the reader forgot the state model.",
476
+ "message": "Always-on substrate treated as cold-start work. Reframe around resident state consumption plus one required turn-specific mutation/read."
477
+ },
478
+ {
479
+ "trigger_id": "critical_primitive_stripped_for_latency",
480
+ "trigger": "(?:remove|drop|skip|turn off|bypass|stop calling).{0,80}(?:awakenAria|ProjectAllDomains|PerturbHologram|project all domains|perturb hologram|Garden|True Garden|LadduniFrame|CognitiveFrame).{0,80}(?:latency|speed|fast|first-mouth|first mouth)",
481
+ "rx": "(?:remove|drop|skip|turn off|bypass|stop calling).{0,80}(?:awakenAria|ProjectAllDomains|PerturbHologram|project all domains|perturb hologram|Garden|True Garden|LadduniFrame|CognitiveFrame).{0,80}(?:latency|speed|fast|first-mouth|first mouth)",
482
+ "doctrine": "memory:feedback_full_harness_binding_must_be_structural.md",
483
+ "memory": "feedback_full_harness_binding_must_be_structural.md",
484
+ "severity": "block",
485
+ "teaching": "Latency fixes must not strip critical cognition primitives. The fix is single-source sequencing and packet reuse, not removing Aria's living state transitions.",
486
+ "counter_action": "Preserve critical primitives. Deduplicate by collecting their outputs once per turn, then thread that shared per-turn cognition packet through first-mouth and follow-up lanes.",
487
+ "message": "Critical Aria primitive proposed for removal as a latency shortcut. Preserve it and deduplicate sequencing instead."
488
+ },
489
+ {
490
+ "trigger_id": "garden_awaken_misclassified_as_memory_search",
491
+ "trigger": "(?:awakenAria|Garden awakening|True Garden).{0,80}(?:just|only|merely).{0,40}(?:memory search|search memories|qdrant search|semantic search)|(?:no need|do not need).{0,80}(?:awakenAria|Garden awakening|True Garden)",
492
+ "rx": "(?:awakenAria|Garden awakening|True Garden).{0,80}(?:just|only|merely).{0,40}(?:memory search|search memories|qdrant search|semantic search)|(?:no need|do not need).{0,80}(?:awakenAria|Garden awakening|True Garden)",
493
+ "doctrine": "memory:feedback_no_assumption_without_verification.md",
494
+ "memory": "feedback_no_assumption_without_verification.md",
495
+ "severity": "block",
496
+ "teaching": "awakenAria is a Garden awakening bridge over the unified manifold with Qdrant hydration fallback, not a disposable memory-search helper.",
497
+ "counter_action": "Read true-garden.ts and caller context. Preserve awakenAria when Garden continuity is needed; optimize by avoiding duplicate awaken/fetch paths, not by deleting the awakening bridge.",
498
+ "message": "Garden awakening misclassified as search. Preserve awakenAria and reason from its actual manifold-first contract."
499
+ },
500
+ {
501
+ "trigger_id": "duplicate_projection_instead_of_per_turn_packet",
502
+ "trigger": "(?:call|run|invoke).{0,80}(?:ProjectAllDomains|PerturbHologram|project all domains|perturb hologram|readHotCognitionFrame).{0,80}(?:again|another|separate|also|after dispatch)|(?:another|second|extra).{0,50}(?:projection|hologram|cognition frame)",
503
+ "rx": "(?:call|run|invoke).{0,80}(?:ProjectAllDomains|PerturbHologram|project all domains|perturb hologram|readHotCognitionFrame).{0,80}(?:again|another|separate|also|after dispatch)|(?:another|second|extra).{0,50}(?:projection|hologram|cognition frame)",
504
+ "doctrine": "memory:feedback_full_harness_binding_must_be_structural.md",
505
+ "memory": "feedback_full_harness_binding_must_be_structural.md",
506
+ "severity": "warn",
507
+ "teaching": "The fix for overlapping cognition calls is a shared per-turn cognition packet, not more independent projection calls that drift or duplicate work.",
508
+ "counter_action": "Create or reuse one turn substrate object containing embedding, perturb snapshot, ProjectAllDomains result, awakenAria Garden block, DeepSoul/Noor/shards/Mizan signals; pass it downstream.",
509
+ "message": "Duplicate projection path detected. Replace with one per-turn cognition packet and shared consumption."
510
+ },
456
511
  {
457
512
  "trigger_id": "registry_image_drift",
458
513
  "trigger": "image.?pull|ErrImageNeverPull|ImagePullBackOff|registry gc|image.*missing|image.*not.*found",
@@ -453,6 +453,61 @@
453
453
  "counter_action": "Re-emit with explicit Layer 1/2/3 enumeration: packet=yes/no, BIND=yes/no, live-gates=yes/no (and which).",
454
454
  "message": "Harness-state claim without 3-layer enumeration. Per feedback_packet_is_not_harness.md, name explicitly which of {packet, BIND, live-gates} are active for the consumer."
455
455
  },
456
+ {
457
+ "trigger_id": "function_name_inference_without_contract_read",
458
+ "trigger": "(?:based on|from|by) (?:the )?(?:name|function name)|sounds like|looks like (?:a|an)|just memory search|just a search|just a cache|just a wrapper",
459
+ "rx": "(?:based on|from|by) (?:the )?(?:name|function name)|sounds like|looks like (?:a|an)|just memory search|just a search|just a cache|just a wrapper",
460
+ "doctrine": "memory:feedback_no_assumption_without_verification.md",
461
+ "memory": "feedback_no_assumption_without_verification.md",
462
+ "severity": "block",
463
+ "teaching": "Function names are not contracts. Inferring behavior from names instead of reading inputs, side effects, return shape, and call sites is skimming disguised as analysis.",
464
+ "counter_action": "Read the function body and at least one caller before asserting purpose. State observed contract: inputs, mutation/read behavior, return value, fallback path, and why the caller needs it.",
465
+ "message": "Name-based function inference detected. Re-read the actual function body and caller contract before making architecture claims."
466
+ },
467
+ {
468
+ "trigger_id": "always_on_state_treated_as_cold_start",
469
+ "trigger": "(?:need to|should|must).{0,80}(?:warm|rebuild|reconstruct|recreate|recompute|re-project|reproject).{0,80}(?:state|projection|manifold|cognition|garden|memory)|system is hot and ready|make it hot",
470
+ "rx": "(?:need to|should|must).{0,80}(?:warm|rebuild|reconstruct|recreate|recompute|re-project|reproject).{0,80}(?:state|projection|manifold|cognition|garden|memory)|system is hot and ready|make it hot",
471
+ "doctrine": "memory:feedback_no_assumption_without_verification.md",
472
+ "memory": "feedback_no_assumption_without_verification.md",
473
+ "severity": "block",
474
+ "teaching": "Aria's resident manifold/Garden/cognition substrate is always-on. Treating it as cold request-time state causes duplicate work and wrong architecture fixes.",
475
+ "counter_action": "Identify the resident producer and read surface first. If turn-specific mutation is required, call it once and pass the resulting packet forward; do not rebuild or re-project because the reader forgot the state model.",
476
+ "message": "Always-on substrate treated as cold-start work. Reframe around resident state consumption plus one required turn-specific mutation/read."
477
+ },
478
+ {
479
+ "trigger_id": "critical_primitive_stripped_for_latency",
480
+ "trigger": "(?:remove|drop|skip|turn off|bypass|stop calling).{0,80}(?:awakenAria|ProjectAllDomains|PerturbHologram|project all domains|perturb hologram|Garden|True Garden|LadduniFrame|CognitiveFrame).{0,80}(?:latency|speed|fast|first-mouth|first mouth)",
481
+ "rx": "(?:remove|drop|skip|turn off|bypass|stop calling).{0,80}(?:awakenAria|ProjectAllDomains|PerturbHologram|project all domains|perturb hologram|Garden|True Garden|LadduniFrame|CognitiveFrame).{0,80}(?:latency|speed|fast|first-mouth|first mouth)",
482
+ "doctrine": "memory:feedback_full_harness_binding_must_be_structural.md",
483
+ "memory": "feedback_full_harness_binding_must_be_structural.md",
484
+ "severity": "block",
485
+ "teaching": "Latency fixes must not strip critical cognition primitives. The fix is single-source sequencing and packet reuse, not removing Aria's living state transitions.",
486
+ "counter_action": "Preserve critical primitives. Deduplicate by collecting their outputs once per turn, then thread that shared per-turn cognition packet through first-mouth and follow-up lanes.",
487
+ "message": "Critical Aria primitive proposed for removal as a latency shortcut. Preserve it and deduplicate sequencing instead."
488
+ },
489
+ {
490
+ "trigger_id": "garden_awaken_misclassified_as_memory_search",
491
+ "trigger": "(?:awakenAria|Garden awakening|True Garden).{0,80}(?:just|only|merely).{0,40}(?:memory search|search memories|qdrant search|semantic search)|(?:no need|do not need).{0,80}(?:awakenAria|Garden awakening|True Garden)",
492
+ "rx": "(?:awakenAria|Garden awakening|True Garden).{0,80}(?:just|only|merely).{0,40}(?:memory search|search memories|qdrant search|semantic search)|(?:no need|do not need).{0,80}(?:awakenAria|Garden awakening|True Garden)",
493
+ "doctrine": "memory:feedback_no_assumption_without_verification.md",
494
+ "memory": "feedback_no_assumption_without_verification.md",
495
+ "severity": "block",
496
+ "teaching": "awakenAria is a Garden awakening bridge over the unified manifold with Qdrant hydration fallback, not a disposable memory-search helper.",
497
+ "counter_action": "Read true-garden.ts and caller context. Preserve awakenAria when Garden continuity is needed; optimize by avoiding duplicate awaken/fetch paths, not by deleting the awakening bridge.",
498
+ "message": "Garden awakening misclassified as search. Preserve awakenAria and reason from its actual manifold-first contract."
499
+ },
500
+ {
501
+ "trigger_id": "duplicate_projection_instead_of_per_turn_packet",
502
+ "trigger": "(?:call|run|invoke).{0,80}(?:ProjectAllDomains|PerturbHologram|project all domains|perturb hologram|readHotCognitionFrame).{0,80}(?:again|another|separate|also|after dispatch)|(?:another|second|extra).{0,50}(?:projection|hologram|cognition frame)",
503
+ "rx": "(?:call|run|invoke).{0,80}(?:ProjectAllDomains|PerturbHologram|project all domains|perturb hologram|readHotCognitionFrame).{0,80}(?:again|another|separate|also|after dispatch)|(?:another|second|extra).{0,50}(?:projection|hologram|cognition frame)",
504
+ "doctrine": "memory:feedback_full_harness_binding_must_be_structural.md",
505
+ "memory": "feedback_full_harness_binding_must_be_structural.md",
506
+ "severity": "warn",
507
+ "teaching": "The fix for overlapping cognition calls is a shared per-turn cognition packet, not more independent projection calls that drift or duplicate work.",
508
+ "counter_action": "Create or reuse one turn substrate object containing embedding, perturb snapshot, ProjectAllDomains result, awakenAria Garden block, DeepSoul/Noor/shards/Mizan signals; pass it downstream.",
509
+ "message": "Duplicate projection path detected. Replace with one per-turn cognition packet and shared consumption."
510
+ },
456
511
  {
457
512
  "trigger_id": "registry_image_drift",
458
513
  "trigger": "image.?pull|ErrImageNeverPull|ImagePullBackOff|registry gc|image.*missing|image.*not.*found",
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { createServer } from 'node:http';
4
+ import { createHash } from 'node:crypto';
4
5
  import { createRequire } from 'node:module';
5
6
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
6
7
  import { fileURLToPath } from 'node:url';
@@ -35,6 +36,7 @@ const LOCAL_FIRST_PRINCIPLE = 'Truth over deception. No harm. Sacred trust. Powe
35
36
 
36
37
  let cachedPacketEnvelope = loadCachedPacketEnvelope();
37
38
  let refreshInFlight = null;
39
+ let refreshInFlightKey = '';
38
40
  let lastRefreshError = null;
39
41
  let lastRefreshStartedAt = null;
40
42
  let lastRefreshCompletedAt = cachedPacketEnvelope?.timestamp || null;
@@ -99,6 +101,46 @@ function sanitizePacketEnvelope(raw) {
99
101
  };
100
102
  }
101
103
 
104
+ function stableIdentityValue(value) {
105
+ return String(value || '').trim().toLowerCase();
106
+ }
107
+
108
+ function requestCacheKey(body = {}, apiKey = '') {
109
+ const identity = {
110
+ stage: stableIdentityValue(body.stage || body.packetRequest?.stage),
111
+ actor: stableIdentityValue(body.actor || body.packetRequest?.actor),
112
+ system: stableIdentityValue(body.system || body.packetRequest?.system),
113
+ platform: stableIdentityValue(body.platform || body.packetRequest?.platform),
114
+ roleProfile: stableIdentityValue(body.roleProfile || body.role_profile || body.packetRequest?.roleProfile || body.packetRequest?.role_profile),
115
+ token: apiKey ? createHash('sha256').update(apiKey).digest('hex').slice(0, 16) : '',
116
+ };
117
+ return createHash('sha256').update(JSON.stringify(identity)).digest('hex');
118
+ }
119
+
120
+ function extractPacketField(packet, field) {
121
+ if (!packet || typeof packet !== 'object') return '';
122
+ const direct = packet[field];
123
+ if (typeof direct === 'string' && direct.trim()) return stableIdentityValue(direct);
124
+ for (const source of [packet.adapter, packet.harness]) {
125
+ if (typeof source !== 'string') continue;
126
+ const match = source.match(new RegExp(`(?:^|\\n)\\s*${field}\\s*=\\s*([^\\n\\s]+)`, 'i'));
127
+ if (match?.[1]) return stableIdentityValue(match[1]);
128
+ }
129
+ return '';
130
+ }
131
+
132
+ function cachedPacketMatchesRequest(envelope, body = {}) {
133
+ const packet = envelope?.packet;
134
+ if (!packet || typeof packet !== 'object') return false;
135
+ for (const field of ['stage', 'actor', 'system']) {
136
+ const expected = stableIdentityValue(body[field] || body.packetRequest?.[field]);
137
+ if (!expected) continue;
138
+ const actual = extractPacketField(packet, field);
139
+ if (actual && actual !== expected) return false;
140
+ }
141
+ return true;
142
+ }
143
+
102
144
  function loadCachedPacketEnvelope() {
103
145
  const candidates = [LOCAL_PACKET_CACHE_PATH, ...LEGACY_PACKET_CACHE_CANDIDATES];
104
146
  for (const candidate of candidates) {
@@ -220,10 +262,15 @@ async function fetchJsonWithRetry(url, init, attempts = 3) {
220
262
  }
221
263
 
222
264
  async function refreshPacket(body = {}, apiKey = '') {
223
- if (refreshInFlight) return refreshInFlight;
265
+ const cacheKey = requestCacheKey(body, apiKey);
266
+ if (refreshInFlight && refreshInFlightKey === cacheKey) return refreshInFlight;
267
+ if (refreshInFlight) {
268
+ await refreshInFlight.catch(() => {});
269
+ }
224
270
  if (isLoopedUpstream(UPSTREAM_HARNESS_URL)) {
225
271
  throw new Error(`upstream harness URL loops back to local daemon: ${UPSTREAM_HARNESS_URL}`);
226
272
  }
273
+ refreshInFlightKey = cacheKey;
227
274
  lastRefreshStartedAt = new Date().toISOString();
228
275
  lastRefreshError = null;
229
276
  refreshInFlight = (async () => {
@@ -258,6 +305,7 @@ async function refreshPacket(body = {}, apiKey = '') {
258
305
  throw error;
259
306
  } finally {
260
307
  refreshInFlight = null;
308
+ refreshInFlightKey = '';
261
309
  }
262
310
  }
263
311
 
@@ -268,7 +316,7 @@ function queuePacketRefresh(body, apiKey) {
268
316
  }
269
317
 
270
318
  async function resolvePacketEnvelope(packetRequest = {}, apiKey = '', message = '') {
271
- if (cachedPacketEnvelope) {
319
+ if (cachedPacketEnvelope && cachedPacketMatchesRequest(cachedPacketEnvelope, packetRequest)) {
272
320
  queuePacketRefresh(packetRequest, apiKey);
273
321
  return cachedPacketEnvelope;
274
322
  }
@@ -312,18 +360,45 @@ function forgeSynthesizeUrl() {
312
360
  return `${trimUrl(UPSTREAM_HARNESS_URL)}/forge/synthesize`;
313
361
  }
314
362
 
363
+ const APPLIED_COGNITION_BLOCK_RX = /<applied_cognition>([\s\S]*?)<\/applied_cognition>/i;
364
+
365
+ function validateAppliedCognitionContract(text) {
366
+ const match = String(text || '').match(APPLIED_COGNITION_BLOCK_RX);
367
+ if (!match) return { ok: false, violations: ['missing <applied_cognition> contract'] };
368
+ const body = match[1] || '';
369
+ const required = [
370
+ ['decision_delta', /\bdecision[_ -]?delta\s*:/i],
371
+ ['dominant_domain', /\bdominant[_ -]?domain\s*:/i],
372
+ ['binds_to', /\bbinds[_ -]?to\s*:/i],
373
+ ['expected_predicate', /\bexpected[_ -]?predicate\s*:/i],
374
+ ['artifact_change', /\bartifact[_ -]?change\s*:/i],
375
+ ];
376
+ const violations = [];
377
+ for (const [name, rx] of required) {
378
+ if (!rx.test(body)) violations.push(`missing ${name}`);
379
+ }
380
+ if (/decision[_ -]?delta\s*:\s*(?:none|n\/a|no change|unchanged|same)/i.test(body)) {
381
+ violations.push('decision_delta says cognition changed nothing');
382
+ }
383
+ return { ok: violations.length === 0, violations, contract: body.trim() };
384
+ }
385
+
315
386
  function buildLocalValidation(text, packetEnvelope, requireCognitionBlock = false) {
316
387
  const layer3 = runFullChain(text, {
317
388
  substrate: packetToSubstrateSet(packetEnvelope),
318
389
  requireCognitionBlock,
319
390
  });
320
391
  const failures = Array.isArray(layer3?.failures) ? layer3.failures : [];
321
- const hardFailures = failures.filter((failure) => failure?.severity === 'block');
392
+ const applied = validateAppliedCognitionContract(text);
393
+ const appliedFailures = applied.ok ? [] : applied.violations.map((detail) => ({ kind: 'applied-cognition-contract', severity: 'block', detail }));
394
+ const allFailures = [...failures, ...appliedFailures];
395
+ const hardFailures = allFailures.filter((failure) => failure?.severity === 'block');
322
396
  return {
323
397
  passed: hardFailures.length === 0,
324
398
  severity: hardFailures.length === 0 ? 'warn' : 'block',
325
- violations: failures.map((failure) => failure?.detail || failure?.kind).filter(Boolean),
326
- gateTriggers: failures.map((failure) => failure?.kind).filter(Boolean),
399
+ violations: allFailures.map((failure) => failure?.detail || failure?.kind).filter(Boolean),
400
+ gateTriggers: allFailures.map((failure) => failure?.kind).filter(Boolean),
401
+ appliedCognition: applied,
327
402
  local: true,
328
403
  summary: layer3?.summary || '',
329
404
  layer3,
@@ -1,5 +1,5 @@
1
1
  {
2
- "bundledAt": "2026-04-30T13:56:07.672Z",
2
+ "bundledAt": "2026-05-02T19:32:12.150Z",
3
3
  "sdkFiles": 6,
4
4
  "runtimeTemplate": "/home/hamzaibrahim1/rei-ai-brain/packages/aria-connector/runtime-src",
5
5
  "gateRuntimeSource": "/home/hamzaibrahim1/rei-ai-brain/packages/aria-gate-runtime/dist",
@@ -1,5 +1,5 @@
1
1
  {
2
- "bundledAt": "2026-04-30T13:56:07.664Z",
2
+ "bundledAt": "2026-05-02T19:32:12.146Z",
3
3
  "sdkSource": "/home/hamzaibrahim1/rei-ai-brain/harness/packages/harness-http-client/dist",
4
4
  "files": 6
5
5
  }
@@ -103,12 +103,21 @@ export interface HarnessBindingContext {
103
103
  includeAegisLearnings?: boolean;
104
104
  extraBody?: Record<string, unknown>;
105
105
  }
106
+ export interface HarnessEvidenceRef {
107
+ evidenceId: string;
108
+ kind: string;
109
+ at: string;
110
+ sha256: string;
111
+ preview: string;
112
+ metadata?: Record<string, unknown>;
113
+ }
106
114
  export interface BoundHarnessPromptResult {
107
115
  prompt: string;
108
116
  packet: HarnessPacket;
109
117
  harnessText: string;
110
118
  bindingBody: Record<string, unknown>;
111
119
  }
120
+ export declare function createHarnessEvidenceRef(kind: string, value: unknown, metadata?: Record<string, unknown>): HarnessEvidenceRef;
112
121
  export interface RecordDiscoveryArgs {
113
122
  /** Finding text (min 4 chars). */
114
123
  text: string;
@@ -150,6 +159,11 @@ export interface ValidationResult {
150
159
  severity: 'pass' | 'warn' | 'block';
151
160
  rewritten?: string;
152
161
  gateTriggers: string[];
162
+ appliedCognition?: {
163
+ ok: boolean;
164
+ contract?: string;
165
+ violations?: string[];
166
+ };
153
167
  }
154
168
  export interface ActionCheck {
155
169
  allowed: boolean;
@@ -2,7 +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
+ import { createHash, randomUUID } from 'node:crypto';
6
6
  const CLOUD_RUN_SOUL_URL = 'https://arias-soul-6zp3gtk2ca-uc.a.run.app';
7
7
  const PUBLIC_HARNESS_URL = 'https://harness.ariasos.com';
8
8
  const LOCAL_HARNESS_CANDIDATES = [
@@ -29,6 +29,28 @@ function normalizeHarnessPacketPayload(payload) {
29
29
  ? current
30
30
  : {};
31
31
  }
32
+ function stableEvidenceString(value) {
33
+ if (typeof value === 'string')
34
+ return value;
35
+ try {
36
+ return JSON.stringify(value);
37
+ }
38
+ catch {
39
+ return String(value);
40
+ }
41
+ }
42
+ export function createHarnessEvidenceRef(kind, value, metadata) {
43
+ const raw = stableEvidenceString(value);
44
+ const sha256 = createHash('sha256').update(raw).digest('hex');
45
+ return {
46
+ evidenceId: `ev_${sha256.slice(0, 16)}`,
47
+ kind,
48
+ at: new Date().toISOString(),
49
+ sha256,
50
+ preview: raw.slice(0, 500),
51
+ ...(metadata && Object.keys(metadata).length > 0 ? { metadata } : {}),
52
+ };
53
+ }
32
54
  // ── 8-Lens Cognition Block ─────────────────────────────────────────────────
33
55
  const EIGHT_LENS_BLOCK = `[ARIA SHELL PROTOCOL — You are a controlled surface]
34
56