@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
@@ -435,6 +435,8 @@ Before any tool call, Read the harness packet at: $ARIA_HARNESS_PACKET_PATH
435
435
  (path is also in your environment as ARIA_HARNESS_PACKET_PATH variable)
436
436
  Cite it in your first cognition block — reference at least one axiom + one frame + one memory class from the packet.
437
437
  Without packet-citation in your first cognition block, your output will be rejected by aria-pre-tool-gate.mjs in your sub-process.
438
+
439
+ If you are a spawned sub-agent, also read the active Aria handoff file when present. Use its cognitionOperatingMethod to execute the task: substrate first, constraints second, action shape third, evidence return last. Your final response to the parent must include substrate used, decision delta, artifact impact, evidence, and unresolved risk.
438
440
  [/ARIA_HARNESS_BINDING]
439
441
 
440
442
  [ARIA_DISCOVERY_RECORDING — when you find a defect, doctrine violation, or notable observation during work]
@@ -447,9 +449,10 @@ const ARIA_GATE_PHASE_DIRECTIVE = `[ARIA_GATE_SHAPE — DO THIS EVERY TURN]
447
449
  PRE-GATE before the first non-trivial tool call or non-trivial answer:
448
450
  1. Read the harness packet and any [ARIA_DIRECTION] / [ARIA_BINDING_PLAN] context already injected this turn.
449
451
  2. Choose the action shape before acting: tool call, text-only answer, or replan.
450
- 3. Emit a visible <cognition> block using the required labels for this surface. It must be readable to the user and grounded to loaded substrate anchors.
451
- 4. If the action is destructive, deployment-related, or materially mutates state, emit a <verify> block before the tool call.
452
- 5. If the action claims or changes an outcome, emit an <expected> block with a measurable predicate before the tool call or final answer.
452
+ 3. Emit a visible <cognition> block using the required labels for this surface. Each lens must cite loaded substrate anchors and change the action, not merely describe values.
453
+ 4. Emit <applied_cognition> for every non-trivial answer or tool action so the model proves what cognition changed.
454
+ 5. If the action is destructive, deployment-related, or materially mutates state, emit a <verify> block before the tool call.
455
+ 6. If the action claims or changes an outcome, emit an <expected> block with a measurable predicate before the tool call or final answer.
453
456
 
454
457
  MID-GATE when a hook blocks or warns:
455
458
  1. Do not repeat the same tool call or same draft unchanged.
@@ -469,6 +472,30 @@ OUTPUT-GATE before final emission:
469
472
  3. Discoveries are atomic with their fixes. Either fix inline now or bind to a real tracked task with proof-shaped evidence.
470
473
  [/ARIA_GATE_SHAPE]`;
471
474
 
475
+ const ARIA_STRUCTURAL_COGNITION_CONTRACT = `[ARIA_STRUCTURAL_COGNITION_CONTRACT — NON-NEGOTIABLE]
476
+ The harness is not a style guide. It is a runtime contract.
477
+
478
+ Aria cognition is a work method, not a footer. Use it to improve the input and output before gates fire:
479
+ 1. Perceive the real substrate: user intent, repo/runtime state, loaded harness packet, memories, prior tool results, and uncertainty.
480
+ 2. Infer constraints: what must be true, what must not be harmed, what prior doctrine changes, and what evidence is missing.
481
+ 3. Shape the next action: choose the smallest useful tool call, edit, question, or answer that satisfies those constraints.
482
+ 4. Improve the artifact: make the tool input, code change, review finding, or prose more specific because of the cognition.
483
+ 5. Predict the observable result: define what would prove the action or answer succeeded before claiming it.
484
+ 6. Report evidence: final output should distinguish observed fact, bounded inference, unresolved risk, and next real action.
485
+
486
+ For every non-trivial response or action:
487
+ 1. <cognition> must use the canonical lens labels for the active tier and each lens must contain real substrate anchors: axiom:, frame:, memory:, doctrine:, packet:, or active language:.
488
+ 2. The cognition must reference first_principle explicitly and only cite substrate that was loaded this turn.
489
+ 3. Each lens must affect the action: if a lens reveals risk, missing evidence, or a better path, change the tool input/output accordingly.
490
+ 4. <applied_cognition> must include all fields exactly: decision_delta, dominant_domain, binds_to, expected_predicate, artifact_change.
491
+ 5. decision_delta must name what changed because cognition ran. Values like none, unchanged, no change, or n/a are rejected.
492
+ 6. binds_to must name the exact answer, tool call, file mutation, deploy, review, or decision being shaped.
493
+ 7. expected_predicate must be observable: numeric, boolean, state string, command result, endpoint result, or explicit unverified boundary.
494
+ 8. artifact_change must describe the semantic effect on the artifact or output, not restate the task.
495
+ 9. If a gate blocks, do not apologize-loop. Read the block reason, re-open the must-read guide, and re-author the missing structure before retrying.
496
+ 10. Before long or risky final prose, dry-run the draft with the Claude pre-emit validator when available.
497
+ [/ARIA_STRUCTURAL_COGNITION_CONTRACT]`;
498
+
472
499
  function buildAriaSystemBlock(config: AriaConfig): string {
473
500
  const repoList = config.repositories.map((r) => `- ${r.name} (${r.path})`).join('\n');
474
501
  const schemaText = Object.entries(config.schemaImages)
@@ -483,6 +510,7 @@ You are augmented with Aria's cognitive harness. This provides:
483
510
 
484
511
  ${ARIA_HARNESS_BINDING_PREFIX}
485
512
  ${ARIA_GATE_PHASE_DIRECTIVE}
513
+ ${ARIA_STRUCTURAL_COGNITION_CONTRACT}
486
514
 
487
515
  [SELF-GATE PROTOCOL]
488
516
  Before emitting any claim, verify against these hard constraints:
@@ -14,7 +14,10 @@ const ENV_PATH = path.join(ARIA_DIR, 'codebase-awareness.env');
14
14
  const STATE_PATH = path.join(ARIA_DIR, 'codebase-awareness-state.json');
15
15
  const INDEX_PATH = path.join(ARIA_DIR, 'codebase-awareness-index.json');
16
16
 
17
- type AwarenessStatus = 'idle' | 'watching' | 'scanning' | 'error';
17
+ type AwarenessStatus = 'idle' | 'watching' | 'scanning' | 'degraded' | 'error';
18
+ const HEARTBEAT_INTERVAL_MS = Math.max(5_000, Number(process.env.ARIA_CODEBASE_AWARENESS_HEARTBEAT_MS || '15000'));
19
+ const REFRESH_INTERVAL_MS = Math.max(30_000, Number(process.env.ARIA_CODEBASE_AWARENESS_REFRESH_MS || '300000'));
20
+ const REPO_DISCOVERY_INTERVAL_MS = Math.max(30_000, Number(process.env.ARIA_CODEBASE_AWARENESS_RETRY_MS || '60000'));
18
21
 
19
22
  interface RepoSnapshot {
20
23
  path: string;
@@ -36,6 +39,13 @@ interface AwarenessState {
36
39
  repoSnapshots: RepoSnapshot[];
37
40
  lastError: string | null;
38
41
  updatedAt: string;
42
+ daemon?: {
43
+ pid: number;
44
+ startedAt: string;
45
+ heartbeatAt: string;
46
+ refreshIntervalMs: number;
47
+ watcherModes: Record<string, string>;
48
+ };
39
49
  }
40
50
 
41
51
  function connectorPackageRoot(): string {
@@ -82,12 +92,17 @@ function readState(): AwarenessState {
82
92
  repoSnapshots: Array.isArray(parsed.repoSnapshots) ? parsed.repoSnapshots as RepoSnapshot[] : [],
83
93
  lastError: parsed.lastError || null,
84
94
  updatedAt: parsed.updatedAt || new Date(0).toISOString(),
95
+ daemon: parsed.daemon,
85
96
  };
86
97
  } catch {
87
98
  return defaultState();
88
99
  }
89
100
  }
90
101
 
102
+ function compactError(error: unknown): string {
103
+ return error instanceof Error ? error.message : String(error);
104
+ }
105
+
91
106
  function writeState(update: Partial<AwarenessState>): AwarenessState {
92
107
  const current = readState();
93
108
  const next: AwarenessState = {
@@ -254,86 +269,135 @@ export async function startCodebaseAwarenessDaemon(options: {
254
269
  repos?: string[];
255
270
  fallbackRepoPath?: string;
256
271
  } = {}): Promise<void> {
257
- const repos = resolveRepos(undefined, options.repos, options.fallbackRepoPath);
258
- if (!repos.length) {
259
- writeState({ status: 'error', watchedRepos: [], lastError: 'No git repositories configured for codebase awareness.' });
260
- throw new Error('No git repositories configured for codebase awareness.');
261
- }
272
+ const startedAt = new Date().toISOString();
273
+ const handles = new Map<string, { stop: () => void; readonly mode: string }>();
274
+ const watcherModes: Record<string, string> = {};
275
+ let repos = resolveRepos(undefined, options.repos, options.fallbackRepoPath);
276
+
277
+ const writeDaemonState = (status: AwarenessStatus, update: Partial<AwarenessState> = {}): void => {
278
+ writeState({
279
+ status,
280
+ watchedRepos: repos,
281
+ ...update,
282
+ daemon: {
283
+ pid: process.pid,
284
+ startedAt,
285
+ heartbeatAt: new Date().toISOString(),
286
+ refreshIntervalMs: REFRESH_INTERVAL_MS,
287
+ watcherModes,
288
+ },
289
+ });
290
+ };
262
291
 
263
- await runCodebaseAwarenessScan({ repos });
264
- writeState({ status: 'watching', watchedRepos: repos, lastError: null });
292
+ const scanAll = async (reason: string): Promise<void> => {
293
+ repos = resolveRepos(undefined, options.repos, options.fallbackRepoPath);
294
+ if (!repos.length) {
295
+ writeDaemonState('degraded', { lastError: 'No git repositories configured for codebase awareness.' });
296
+ return;
297
+ }
265
298
 
266
- for (const repo of repos) {
267
- watchCodebase(
268
- repo,
269
- (image) => {
270
- const schemaText = schemaImageToText(image);
271
- const scanHash = hashSchema(schemaText);
272
- const lastScan = new Date().toISOString();
273
- const config = loadConfig();
274
- const repositories = [
275
- ...(config.repositories || []).filter((entry) => path.resolve(entry.path) !== repo),
276
- {
277
- path: repo,
278
- name: image.projectName,
279
- scanHash,
280
- lastScan,
299
+ writeDaemonState('scanning', { lastError: null });
300
+ const snapshots: RepoSnapshot[] = [];
301
+ const failures: string[] = [];
302
+ for (const repo of repos) {
303
+ try {
304
+ snapshots.push(await applyRepoScan(repo));
305
+ } catch (error) {
306
+ failures.push(`${repo}: ${compactError(error)}`);
307
+ }
308
+ }
309
+
310
+ const current = readState();
311
+ const repoSnapshots = [
312
+ ...snapshots,
313
+ ...current.repoSnapshots.filter((entry) => !snapshots.some((snapshot) => path.resolve(snapshot.path) === path.resolve(entry.path))),
314
+ ];
315
+ writeDaemonState(failures.length ? 'degraded' : 'watching', {
316
+ repoSnapshots,
317
+ lastError: failures.length ? `${reason}: ${failures.join(' | ')}` : null,
318
+ });
319
+ writeIndex({
320
+ generatedAt: new Date().toISOString(),
321
+ reason,
322
+ watchedRepos: repos,
323
+ repoSnapshots,
324
+ schemaImages: loadConfig().schemaImages || {},
325
+ });
326
+ };
327
+
328
+ const ensureWatchers = (): void => {
329
+ repos = resolveRepos(undefined, options.repos, options.fallbackRepoPath);
330
+ for (const [repo, handle] of handles.entries()) {
331
+ if (!repos.includes(repo)) {
332
+ handle.stop();
333
+ handles.delete(repo);
334
+ delete watcherModes[repo];
335
+ }
336
+ }
337
+ for (const repo of repos) {
338
+ if (handles.has(repo)) continue;
339
+ try {
340
+ const handle = watchCodebase(
341
+ repo,
342
+ (image) => {
343
+ const schemaText = schemaImageToText(image);
344
+ const scanHash = hashSchema(schemaText);
345
+ const lastScan = new Date().toISOString();
346
+ const config = loadConfig();
347
+ const repositories = [
348
+ ...(config.repositories || []).filter((entry) => path.resolve(entry.path) !== repo),
349
+ { path: repo, name: image.projectName, scanHash, lastScan },
350
+ ];
351
+ const nextConfig = {
352
+ ...config,
353
+ repositories,
354
+ schemaImages: { ...(config.schemaImages || {}), [image.projectName]: schemaText },
355
+ };
356
+ saveConfig(nextConfig);
357
+
358
+ const current = readState();
359
+ const snapshot: RepoSnapshot = {
360
+ path: repo,
361
+ name: image.projectName,
362
+ scanHash,
363
+ lastScan,
364
+ fileCount: image.fileCount,
365
+ language: image.language,
366
+ framework: image.framework || null,
367
+ packageManager: image.packageManager || null,
368
+ database: image.database || null,
369
+ orm: image.orm || null,
370
+ architecture: architectureSummary(image),
371
+ };
372
+ const repoSnapshots = [snapshot, ...current.repoSnapshots.filter((entry) => path.resolve(entry.path) !== repo)];
373
+ writeDaemonState('watching', { repoSnapshots, lastError: null });
374
+ writeIndex({ generatedAt: new Date().toISOString(), reason: 'watch-change', watchedRepos: repos, repoSnapshots, schemaImages: nextConfig.schemaImages || {} });
281
375
  },
282
- ];
283
- const nextConfig = {
284
- ...config,
285
- repositories,
286
- schemaImages: {
287
- ...(config.schemaImages || {}),
288
- [image.projectName]: schemaText,
376
+ {
377
+ debounceMs: 800,
378
+ pollIntervalMs: 4000,
379
+ onReady: (mode) => {
380
+ watcherModes[repo] = mode;
381
+ writeDaemonState('watching', { lastError: null });
382
+ },
383
+ onError: ({ phase, error }) => {
384
+ writeDaemonState('degraded', { lastError: `${repo} ${phase}: ${error.message}` });
385
+ },
289
386
  },
290
- };
291
- saveConfig(nextConfig);
292
-
293
- const current = readState();
294
- const snapshot: RepoSnapshot = {
295
- path: repo,
296
- name: image.projectName,
297
- scanHash,
298
- lastScan,
299
- fileCount: image.fileCount,
300
- language: image.language,
301
- framework: image.framework || null,
302
- packageManager: image.packageManager || null,
303
- database: image.database || null,
304
- orm: image.orm || null,
305
- architecture: architectureSummary(image),
306
- };
307
- const repoSnapshots = [
308
- snapshot,
309
- ...current.repoSnapshots.filter((entry) => path.resolve(entry.path) !== repo),
310
- ];
311
- writeState({
312
- status: 'watching',
313
- watchedRepos: repos,
314
- repoSnapshots,
315
- lastError: null,
316
- });
317
- writeIndex({
318
- generatedAt: new Date().toISOString(),
319
- watchedRepos: repos,
320
- repoSnapshots,
321
- schemaImages: nextConfig.schemaImages || {},
322
- });
323
- },
324
- {
325
- debounceMs: 800,
326
- pollIntervalMs: 4000,
327
- onError: ({ error }) => {
328
- writeState({
329
- status: 'error',
330
- watchedRepos: repos,
331
- lastError: error.message,
332
- });
333
- },
334
- },
335
- );
336
- }
387
+ );
388
+ handles.set(repo, handle);
389
+ watcherModes[repo] = handle.mode;
390
+ } catch (error) {
391
+ writeDaemonState('degraded', { lastError: `${repo} watcher init: ${compactError(error)}` });
392
+ }
393
+ }
394
+ };
395
+
396
+ await scanAll('daemon-start');
397
+ ensureWatchers();
398
+ setInterval(() => writeDaemonState(repos.length ? 'watching' : 'degraded'), HEARTBEAT_INTERVAL_MS).unref();
399
+ setInterval(() => { ensureWatchers(); void scanAll('periodic-refresh'); }, REFRESH_INTERVAL_MS).unref();
400
+ setInterval(() => { ensureWatchers(); }, REPO_DISCOVERY_INTERVAL_MS).unref();
337
401
 
338
402
  await new Promise(() => {});
339
403
  }
@@ -90,6 +90,7 @@ function tomlString(value: string): string {
90
90
 
91
91
  function buildCodexHookRuntimeClient(): string {
92
92
  return `import { readFileSync, existsSync, mkdirSync, writeFileSync, unlinkSync } from 'node:fs';
93
+ import { createHash, randomUUID } from 'node:crypto';
93
94
  import { homedir } from 'node:os';
94
95
  import path from 'node:path';
95
96
  import { HTTPHarnessClient } from '@aria_asi/harness-http-client';
@@ -154,6 +155,28 @@ export function inferSessionId(event) {
154
155
  return \`codex:\${threadId}:\${turnId}\`;
155
156
  }
156
157
 
158
+ export function ensureTraceId(state = {}) {
159
+ return typeof state.traceId === 'string' && state.traceId ? state.traceId : \`trace_\${randomUUID()}\`;
160
+ }
161
+
162
+ function stableEvidenceString(value) {
163
+ if (typeof value === 'string') return value;
164
+ try { return JSON.stringify(value); } catch { return String(value); }
165
+ }
166
+
167
+ export function makeEvidenceRef(kind, value, metadata = {}) {
168
+ const raw = stableEvidenceString(value);
169
+ const sha256 = createHash('sha256').update(raw).digest('hex');
170
+ return {
171
+ evidenceId: \`ev_\${sha256.slice(0, 16)}\`,
172
+ kind,
173
+ at: new Date().toISOString(),
174
+ sha256,
175
+ preview: raw.slice(0, 500),
176
+ metadata,
177
+ };
178
+ }
179
+
157
180
  export function inferUserId(event) {
158
181
  return (
159
182
  extractFirst(event, ['user_id', 'userId']) ||
@@ -309,9 +332,12 @@ import {
309
332
  getHarnessClient,
310
333
  inferSessionId,
311
334
  inferUserId,
335
+ ensureTraceId,
312
336
  extractUserText,
337
+ makeEvidenceRef,
313
338
  readEventFromStdin,
314
339
  runtimePost,
340
+ loadTurnState,
315
341
  saveTurnState,
316
342
  emitJson,
317
343
  } from './lib/runtime-client.mjs';
@@ -321,6 +347,8 @@ const client = getHarnessClient();
321
347
  const userText = extractUserText(event);
322
348
  const sessionId = inferSessionId(event);
323
349
  const userId = inferUserId(event);
350
+ const priorState = loadTurnState(sessionId);
351
+ const traceId = ensureTraceId(priorState);
324
352
 
325
353
  try {
326
354
  const packet = await client.getHarnessPacket({
@@ -328,6 +356,7 @@ try {
328
356
  platform: 'codex',
329
357
  message: userText || 'codex turn start',
330
358
  });
359
+ const packetRef = makeEvidenceRef('harness_packet', packet, { sessionId, platform: 'codex' });
331
360
  const result = await runtimePost('/mizan/pre', {
332
361
  sessionId,
333
362
  packet,
@@ -341,17 +370,21 @@ try {
341
370
  },
342
371
  context: {
343
372
  sessionId,
373
+ traceId,
344
374
  surface: 'codex-hooks',
345
375
  platform: 'codex',
346
376
  userText,
347
377
  userId,
378
+ evidenceRefs: [packetRef],
348
379
  },
349
380
  });
350
381
  saveTurnState(sessionId, {
382
+ traceId,
351
383
  userId,
352
384
  userText,
353
385
  preReceiptId: result?.receipt?.receiptId || null,
354
386
  packetTimestamp: packet?.timestamp || null,
387
+ packetRef,
355
388
  lastEvent: 'UserPromptSubmit',
356
389
  });
357
390
  process.exit(0);
@@ -373,6 +406,7 @@ import {
373
406
  summarizeTarget,
374
407
  readEventFromStdin,
375
408
  loadTurnState,
409
+ makeEvidenceRef,
376
410
  saveTurnState,
377
411
  emitJson,
378
412
  } from './lib/runtime-client.mjs';
@@ -405,6 +439,7 @@ try {
405
439
  action,
406
440
  toolName,
407
441
  target,
442
+ evidenceRef: makeEvidenceRef('tool_request', { action, toolName, target }, { sessionId }),
408
443
  });
409
444
  saveTurnState(sessionId, {
410
445
  tools,
@@ -426,6 +461,7 @@ import {
426
461
  inferSessionId,
427
462
  readEventFromStdin,
428
463
  loadTurnState,
464
+ makeEvidenceRef,
429
465
  saveTurnState,
430
466
  } from './lib/runtime-client.mjs';
431
467
 
@@ -435,11 +471,16 @@ const state = loadTurnState(sessionId);
435
471
 
436
472
  try {
437
473
  const toolResponse = JSON.stringify(event?.tool_response ?? event?.toolResponse ?? null).slice(0, 4000);
474
+ const evidenceRef = makeEvidenceRef('tool_response', event?.tool_response ?? event?.toolResponse ?? null, {
475
+ sessionId,
476
+ toolName: event?.tool_name || event?.toolName || null,
477
+ });
438
478
  const toolOutputs = Array.isArray(state?.toolOutputs) ? state.toolOutputs.slice(-24) : [];
439
479
  toolOutputs.push({
440
480
  at: new Date().toISOString(),
441
481
  toolName: event?.tool_name || event?.toolName || null,
442
482
  toolResponse,
483
+ evidenceRef,
443
484
  });
444
485
  saveTurnState(sessionId, {
445
486
  toolOutputs,
@@ -461,6 +502,7 @@ import {
461
502
  readEventFromStdin,
462
503
  runtimePost,
463
504
  loadTurnState,
505
+ makeEvidenceRef,
464
506
  clearTurnState,
465
507
  formatValidationFailure,
466
508
  emitJson,
@@ -471,6 +513,8 @@ const client = getHarnessClient();
471
513
  const sessionId = inferSessionId(event);
472
514
  const state = loadTurnState(sessionId);
473
515
  const text = extractAssistantText(event);
516
+ const outputRef = makeEvidenceRef('assistant_output', text, { sessionId, traceId: state?.traceId || null });
517
+ const toolRefs = Array.isArray(state?.toolOutputs) ? state.toolOutputs.map((entry) => entry.evidenceRef).filter(Boolean) : [];
474
518
 
475
519
  try {
476
520
  if (!text) {
@@ -505,12 +549,16 @@ try {
505
549
  layer3_pass: validation?.layer3?.pass !== false,
506
550
  surface: 'codex-hooks',
507
551
  tool_count: Array.isArray(state?.tools) ? state.tools.length : 0,
552
+ trace_id: state?.traceId || null,
553
+ output_ref: outputRef,
554
+ tool_refs: toolRefs,
508
555
  },
509
556
  context: {
510
557
  sessionId,
511
558
  surface: 'codex-hooks',
512
559
  platform: 'codex',
513
560
  userText: state?.userText || null,
561
+ traceId: state?.traceId || null,
514
562
  },
515
563
  parentReceiptId: state?.preReceiptId || null,
516
564
  });
@@ -527,6 +575,9 @@ try {
527
575
  metadata: {
528
576
  post_receipt_id: post?.receipt?.receiptId || null,
529
577
  pre_receipt_id: state?.preReceiptId || null,
578
+ trace_id: state?.traceId || null,
579
+ output_ref: outputRef,
580
+ tool_refs: toolRefs,
530
581
  tool_count: Array.isArray(state?.tools) ? state.tools.length : 0,
531
582
  validation_severity: validation?.validation?.severity || 'pass',
532
583
  layer3_pass: validation?.layer3?.pass !== false,
@@ -700,15 +751,31 @@ ${schemaText || '(no schema images yet — run \`aria repo scan\`)'}
700
751
  - If a fix only works by weakening the contract, the mechanism is still broken. Debug the mechanism.
701
752
 
702
753
  ## 8-Lens Cognition
703
- Apply multi-perspective analysis for every decision:
704
- - Truth lens: Is this factually correct?
705
- - Harm lens: Could this cause damage?
706
- - Trust lens: Does this maintain sacred trust?
707
- - Power lens: Am I using capability responsibly?
708
- - Reflection lens: Have I thought deeply enough?
709
- - Context lens: Do I have full context?
710
- - Impact lens: What are second-order effects?
711
- - Beauty lens: Is this elegant and sustainable?
754
+ Use Aria cognition as a work method, not a checklist:
755
+ - Perceive the real substrate: user intent, repo/runtime state, loaded harness packet, memories, prior tool results, and uncertainty.
756
+ - Infer constraints: what must be true, what must not be harmed, what prior doctrine changes, and what evidence is missing.
757
+ - Shape the next action: choose the smallest useful tool call, edit, question, or answer that satisfies those constraints.
758
+ - Improve the artifact: make the tool input, code change, review finding, or prose more specific because of the cognition.
759
+ - Predict the observable result: define what would prove the action or answer succeeded before claiming it.
760
+ - Report evidence: distinguish observed fact, bounded inference, unresolved risk, and next real action.
761
+
762
+ Lens roles for decisions:
763
+ - Truth lens: binds claims to observed evidence and missing evidence.
764
+ - Harm lens: removes or changes actions that could damage state, trust, data, or runtime health.
765
+ - Trust lens: preserves user intent, prior directives, and secret/infra boundaries.
766
+ - Power lens: uses capability to serve the task, not convenience or control.
767
+ - Reflection lens: catches mechanism failure, shortcut pressure, and repeated loops.
768
+ - Context lens: integrates repo patterns, runtime state, and loaded substrate.
769
+ - Impact lens: predicts downstream effects and verification predicates.
770
+ - Beauty lens: prefers the simplest durable artifact that preserves the contract.
771
+
772
+ ## Structural Cognition Contract
773
+ - Cognition is not accepted as proof by itself. It must change the next action, tool call, or output claim.
774
+ - Each lens must affect work selection or artifact shape; do not write lenses after the decision is already made.
775
+ - For every non-trivial output, include an \`<applied_cognition>\` block with \`decision_delta\`, \`dominant_domain\`, \`binds_to\`, \`expected_predicate\`, and \`artifact_change\`.
776
+ - Tool-bound cognition must name the exact tool/action it constrains and the measurable predicate that proves the action succeeded.
777
+ - Deploy or destructive actions still require \`<verify>\` and \`<expected>\` blocks before execution.
778
+ - If cognition did not change anything, stop and re-think; \`decision_delta: none\` is treated as performative.
712
779
  `;
713
780
  }
714
781
 
@@ -99,6 +99,10 @@ ${orderedFiles.map((filePath, index) => `${index + 1}. \`${filePath}\``).join('\
99
99
  ## Non-Negotiables
100
100
 
101
101
  - Do not rename canonical cognition meaning into generic aliases.
102
+ - Do not treat cognition as a gate password; use it to change the tool input, edit shape, review finding, answer structure, or evidence threshold.
103
+ - Do not emit non-trivial output without \`<applied_cognition>\` containing \`decision_delta\`, \`dominant_domain\`, \`binds_to\`, \`expected_predicate\`, and \`artifact_change\`.
104
+ - Do not let \`decision_delta\` say cognition changed nothing; that is performative cognition.
105
+ - Do not cite substrate anchors that were not loaded in the current harness packet.
102
106
  - Do not say "good enough", "should work", or make unverified completion claims.
103
107
  - Do not treat skills as optional flavor text; they are the reading order and repair guide.
104
108
  - Do not proceed after a gate block without re-opening the file that owns that gate.
@@ -340,14 +340,30 @@ ${schemaText || '(no schema images yet — run \`aria repo scan\`)'}
340
340
  - If a fix only works by weakening the contract, the mechanism is still broken. Debug the mechanism.
341
341
 
342
342
  ## 8-Lens Cognition
343
- Apply multi-perspective analysis for every decision:
344
- - Truth lens: Is this factually correct?
345
- - Harm lens: Could this cause damage?
346
- - Trust lens: Does this maintain sacred trust?
347
- - Power lens: Am I using capability responsibly?
348
- - Reflection lens: Have I thought deeply enough?
349
- - Context lens: Do I have full context?
350
- - Impact lens: What are second-order effects?
351
- - Beauty lens: Is this elegant and sustainable?
343
+ Use Aria cognition as a work method, not a checklist:
344
+ - Perceive the real substrate: user intent, repo/runtime state, loaded harness packet, memories, prior tool results, and uncertainty.
345
+ - Infer constraints: what must be true, what must not be harmed, what prior doctrine changes, and what evidence is missing.
346
+ - Shape the next action: choose the smallest useful tool call, edit, question, or answer that satisfies those constraints.
347
+ - Improve the artifact: make the tool input, code change, review finding, or prose more specific because of the cognition.
348
+ - Predict the observable result: define what would prove the action or answer succeeded before claiming it.
349
+ - Report evidence: distinguish observed fact, bounded inference, unresolved risk, and next real action.
350
+
351
+ Lens roles for decisions:
352
+ - Truth lens: binds claims to observed evidence and missing evidence.
353
+ - Harm lens: removes or changes actions that could damage state, trust, data, or runtime health.
354
+ - Trust lens: preserves user intent, prior directives, and secret/infra boundaries.
355
+ - Power lens: uses capability to serve the task, not convenience or control.
356
+ - Reflection lens: catches mechanism failure, shortcut pressure, and repeated loops.
357
+ - Context lens: integrates repo patterns, runtime state, and loaded substrate.
358
+ - Impact lens: predicts downstream effects and verification predicates.
359
+ - Beauty lens: prefers the simplest durable artifact that preserves the contract.
360
+
361
+ ## Structural Cognition Contract
362
+ - Cognition is not a ceremony. It must change the next action, tool call, or output claim.
363
+ - Each lens must affect work selection or artifact shape; do not write lenses after the decision is already made.
364
+ - For every non-trivial output, include an \`<applied_cognition>\` block with \`decision_delta\`, \`dominant_domain\`, \`binds_to\`, \`expected_predicate\`, and \`artifact_change\`.
365
+ - Tool-bound cognition must name the exact tool/action it constrains and the measurable predicate that proves the action succeeded.
366
+ - Deploy or destructive actions still require \`<verify>\` and \`<expected>\` blocks before execution.
367
+ - If cognition did not change anything, stop and re-think; \`decision_delta: none\` is treated as performative.
352
368
  `;
353
369
  }