@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
@@ -68,6 +68,7 @@ const OFFLINE_BUNDLE_PATH = join(STATE_DIR, 'offline-policy-bundle.enc');
68
68
  const RUNTIME_META_PATH = join(STATE_DIR, 'runtime-meta.json');
69
69
  const AUTONOMY_STATE_PATH = join(STATE_DIR, 'autonomy.json');
70
70
  const COGNITION_STATE_PATH = join(STATE_DIR, 'cognition-state.enc');
71
+ const HIVE_FILE_LEASES_PATH = join(STATE_DIR, 'hive-file-leases.json');
71
72
  const REVOCATION_LOCK_PATH = join(STATE_DIR, 'revoked.json');
72
73
  const CONFIG_PATH = join(process.env.HOME || '', '.aria', 'config.json');
73
74
  const CODEBASE_AWARENESS_STATE_PATH = join(process.env.HOME || '', '.aria', 'codebase-awareness-state.json');
@@ -906,6 +907,248 @@ function writeJsonFile(filePath, payload, mode = 0o600) {
906
907
  writeFileSync(filePath, JSON.stringify(payload, null, 2) + '\n', { mode });
907
908
  }
908
909
 
910
+ function readHiveFileLeaseState() {
911
+ const state = readJsonFile(HIVE_FILE_LEASES_PATH, { leases: [] });
912
+ return {
913
+ leases: Array.isArray(state.leases) ? state.leases : [],
914
+ };
915
+ }
916
+
917
+ function writeHiveFileLeaseState(state) {
918
+ writeJsonFile(HIVE_FILE_LEASES_PATH, {
919
+ updatedAt: new Date().toISOString(),
920
+ leases: Array.isArray(state.leases) ? state.leases : [],
921
+ });
922
+ }
923
+
924
+ function normalizeLeasePath(value) {
925
+ const raw = String(value || '').trim();
926
+ if (!raw) return '';
927
+ return raw.replace(/\\/g, '/').replace(/\/+/g, '/');
928
+ }
929
+
930
+ function pathsOverlap(left, right) {
931
+ const a = normalizeLeasePath(left);
932
+ const b = normalizeLeasePath(right);
933
+ if (!a || !b) return false;
934
+ return a === b || a.startsWith(`${b}/`) || b.startsWith(`${a}/`);
935
+ }
936
+
937
+ function coerceTargetFiles(body) {
938
+ const files = [];
939
+ const push = (value) => {
940
+ const normalized = normalizeLeasePath(value);
941
+ if (normalized && !files.includes(normalized)) files.push(normalized);
942
+ };
943
+
944
+ if (Array.isArray(body.files)) body.files.forEach(push);
945
+ if (Array.isArray(body.targetFiles)) body.targetFiles.forEach(push);
946
+ if (typeof body.filePath === 'string') push(body.filePath);
947
+ if (typeof body.target === 'string') {
948
+ try {
949
+ const parsed = JSON.parse(body.target);
950
+ if (typeof parsed?.filePath === 'string') push(parsed.filePath);
951
+ if (Array.isArray(parsed?.files)) parsed.files.forEach(push);
952
+ if (Array.isArray(parsed?.targetFiles)) parsed.targetFiles.forEach(push);
953
+ } catch {}
954
+ }
955
+ return files;
956
+ }
957
+
958
+ function extractVerifyText(body) {
959
+ const candidates = [body.verifyText, body.verifyBlock, body.text, body.target];
960
+ for (const candidate of candidates) {
961
+ if (typeof candidate === 'string' && candidate.trim()) return candidate;
962
+ }
963
+ return '';
964
+ }
965
+
966
+ function actionRequiresExplicitVerify(action, body) {
967
+ if (body.requireVerify === true) return true;
968
+ return /^(?:delete|deploy|db_mutation|infra_mutation)$/i.test(String(action || ''));
969
+ }
970
+
971
+ function buildObservedVerify(action, files, sessionId, roleProfile) {
972
+ const observations = files.slice(0, 12).map((filePath) => {
973
+ try {
974
+ const stats = statSync(filePath);
975
+ return {
976
+ path: filePath,
977
+ exists: true,
978
+ isFile: stats.isFile(),
979
+ isDirectory: stats.isDirectory(),
980
+ size: stats.size,
981
+ mtimeMs: stats.mtimeMs,
982
+ };
983
+ } catch {
984
+ return { path: filePath, exists: false };
985
+ }
986
+ });
987
+ return {
988
+ target: files,
989
+ role: roleProfile || 'unknown',
990
+ verified: [
991
+ 'runtime observed target file metadata before action',
992
+ 'Hive file lease check completed before mutation',
993
+ ],
994
+ observations,
995
+ rollback: 'Use VCS diff or prior file snapshot for rollback; no destructive rollback was inferred by runtime.',
996
+ axiom: 'truth_over_deception/no_harm/sacred_trust/reflection_before_action',
997
+ sessionId,
998
+ action,
999
+ };
1000
+ }
1001
+
1002
+ function acquireHiveFileLease({ sessionId, actor, roleProfile, action, files, ttlMs = 120000 }) {
1003
+ const now = Date.now();
1004
+ const expiresAt = new Date(now + ttlMs).toISOString();
1005
+ const normalizedFiles = files.map(normalizeLeasePath).filter(Boolean);
1006
+ const state = readHiveFileLeaseState();
1007
+ const activeLeases = state.leases.filter((lease) => Date.parse(lease.expiresAt || '') > now);
1008
+ const conflicts = activeLeases.filter((lease) => {
1009
+ if (lease.sessionId === sessionId) return false;
1010
+ const leaseFiles = Array.isArray(lease.files) ? lease.files : [];
1011
+ return normalizedFiles.some((file) => leaseFiles.some((leaseFile) => pathsOverlap(file, leaseFile)));
1012
+ });
1013
+
1014
+ if (conflicts.length > 0) {
1015
+ writeHiveFileLeaseState({ leases: activeLeases });
1016
+ return {
1017
+ status: 'blocked',
1018
+ leaseId: null,
1019
+ expiresAt: null,
1020
+ conflicts: conflicts.map((lease) => ({
1021
+ leaseId: lease.leaseId,
1022
+ sessionId: lease.sessionId,
1023
+ actor: lease.actor,
1024
+ roleProfile: lease.roleProfile,
1025
+ action: lease.action,
1026
+ files: lease.files,
1027
+ expiresAt: lease.expiresAt,
1028
+ })),
1029
+ };
1030
+ }
1031
+
1032
+ const existing = activeLeases.filter((lease) => lease.sessionId !== sessionId);
1033
+ const lease = {
1034
+ leaseId: `hive_lease_${randomUUID()}`,
1035
+ sessionId,
1036
+ actor: actor || 'unknown',
1037
+ roleProfile: roleProfile || 'unknown',
1038
+ action,
1039
+ files: normalizedFiles,
1040
+ grantedAt: new Date(now).toISOString(),
1041
+ expiresAt,
1042
+ };
1043
+ writeHiveFileLeaseState({ leases: [...existing, lease] });
1044
+ return { status: 'granted', leaseId: lease.leaseId, expiresAt, conflicts: [] };
1045
+ }
1046
+
1047
+ function releaseHiveFileLease(sessionId, files = []) {
1048
+ const normalizedFiles = files.map(normalizeLeasePath).filter(Boolean);
1049
+ const state = readHiveFileLeaseState();
1050
+ const now = Date.now();
1051
+ const leases = state.leases.filter((lease) => {
1052
+ if (Date.parse(lease.expiresAt || '') <= now) return false;
1053
+ if (lease.sessionId !== sessionId) return true;
1054
+ if (normalizedFiles.length === 0) return false;
1055
+ const leaseFiles = Array.isArray(lease.files) ? lease.files : [];
1056
+ return !normalizedFiles.some((file) => leaseFiles.some((leaseFile) => pathsOverlap(file, leaseFile)));
1057
+ });
1058
+ writeHiveFileLeaseState({ leases });
1059
+ return { released: state.leases.length - leases.length, active: leases.length };
1060
+ }
1061
+
1062
+ function validateVerifyAndHive({ req, body, action }) {
1063
+ const sessionId = deriveSessionId(req, body, 'runtime-action');
1064
+ const files = coerceTargetFiles(body);
1065
+ const roleProfile = body.roleProfile || body.role_profile || body?.metadata?.roleProfile || body?.metadata?.role_profile || null;
1066
+ const actor = body.actor || body?.metadata?.actor || req.headers['x-aria-actor'] || 'runtime-client';
1067
+ const explicitVerifyRequired = actionRequiresExplicitVerify(action, body);
1068
+ const verifyText = extractVerifyText(body);
1069
+ const hasVerifyBlock = VERIFY_BLOCK_RX.test(verifyText);
1070
+ const canUseObservedVerify = !explicitVerifyRequired && files.length > 0 && /^(?:write|edit|bash)$/i.test(String(action || ''));
1071
+
1072
+ if (explicitVerifyRequired && !hasVerifyBlock) {
1073
+ return {
1074
+ allowed: false,
1075
+ reason: 'verify block required before this high-risk action. Include <verify> with target, role, verified, rollback, and axiom.',
1076
+ requiredGates: ['verify-block'],
1077
+ verify: { status: 'missing', required: true },
1078
+ hive: { status: 'not_checked', conflicts: [] },
1079
+ };
1080
+ }
1081
+
1082
+ if (!hasVerifyBlock && !canUseObservedVerify && explicitVerifyRequired) {
1083
+ return {
1084
+ allowed: false,
1085
+ reason: 'verify block required before mutation, or target files must be provided so runtime can perform observed verification.',
1086
+ requiredGates: ['verify-block-or-observed-target-files'],
1087
+ verify: { status: 'missing', required: true },
1088
+ hive: { status: 'not_checked', conflicts: [] },
1089
+ };
1090
+ }
1091
+
1092
+ if (!hasVerifyBlock && !canUseObservedVerify && files.length === 0) {
1093
+ return {
1094
+ allowed: true,
1095
+ reason: 'no target files supplied for Hive lease; remote action gate will still evaluate the action',
1096
+ requiredGates: [],
1097
+ verify: { status: 'skipped', required: false },
1098
+ hive: { status: 'skipped', leaseId: null, expiresAt: null, conflicts: [] },
1099
+ };
1100
+ }
1101
+
1102
+ const hive = files.length > 0
1103
+ ? acquireHiveFileLease({ sessionId, actor, roleProfile, action, files })
1104
+ : { status: 'skipped', leaseId: null, expiresAt: null, conflicts: [] };
1105
+ if (hive.status === 'blocked') {
1106
+ const verify = hasVerifyBlock
1107
+ ? { status: 'provided', required: explicitVerifyRequired }
1108
+ : { status: 'observed', required: false, block: buildObservedVerify(action, files, sessionId, roleProfile) };
1109
+ const queued = enqueueAutonomyJob({
1110
+ kind: 'tool_lane:queued_action',
1111
+ surface: 'tool_lane',
1112
+ sessionId,
1113
+ priority: 15,
1114
+ message: 'Tool lane contention queued this action instead of failing it.',
1115
+ payload: { action, files, verify },
1116
+ metadata: {
1117
+ actor,
1118
+ roleProfile,
1119
+ conflicts: hive.conflicts,
1120
+ recovery: {
1121
+ mode: 'queued_not_failed',
1122
+ reason: 'overlapping_hive_file_lease',
1123
+ next: 'Retry when the overlapping Hive lease expires or a tool-lane worker claims this queued action.',
1124
+ },
1125
+ },
1126
+ });
1127
+ return {
1128
+ allowed: false,
1129
+ queued: true,
1130
+ queue: {
1131
+ jobId: queued.job.jobId,
1132
+ kind: queued.job.kind,
1133
+ status: queued.job.status,
1134
+ queueDepth: queued.stats.queued,
1135
+ },
1136
+ reason: `Tool lane queued this action because another active session is editing overlapping file(s): ${hive.conflicts.map((c) => `${c.sessionId}:${(c.files || []).join(',')}`).join(' | ')}`,
1137
+ requiredGates: ['hive-file-lease'],
1138
+ verify,
1139
+ hive,
1140
+ };
1141
+ }
1142
+
1143
+ return {
1144
+ allowed: true,
1145
+ reason: 'verify and Hive pre-action checks passed',
1146
+ requiredGates: [],
1147
+ verify: hasVerifyBlock ? { status: 'provided', required: explicitVerifyRequired } : { status: 'observed', required: false, block: buildObservedVerify(action, files, sessionId, roleProfile) },
1148
+ hive,
1149
+ };
1150
+ }
1151
+
909
1152
  function ensureRuntimeMeta() {
910
1153
  const existing = readJsonFile(RUNTIME_META_PATH, null);
911
1154
  if (existing?.runtimeId) return existing;
@@ -972,6 +1215,33 @@ function queueStats(state) {
972
1215
  };
973
1216
  }
974
1217
 
1218
+ function enqueueAutonomyJob(jobDef) {
1219
+ const state = sweepAutonomyState(loadAutonomyState());
1220
+ const now = new Date().toISOString();
1221
+ const job = {
1222
+ jobId: randomUUID(),
1223
+ kind: jobDef.kind,
1224
+ surface: jobDef.surface || 'tool_lane',
1225
+ sessionId: jobDef.sessionId || null,
1226
+ payload: jobDef.payload || {},
1227
+ metadata: jobDef.metadata || {},
1228
+ priority: Number.isFinite(Number(jobDef.priority)) ? Number(jobDef.priority) : 25,
1229
+ status: 'queued',
1230
+ attempts: 0,
1231
+ maxAttempts: Number.isFinite(Number(jobDef.maxAttempts)) ? Number(jobDef.maxAttempts) : 3,
1232
+ createdAt: now,
1233
+ updatedAt: now,
1234
+ workerId: null,
1235
+ claimedAt: null,
1236
+ claimExpiresAt: null,
1237
+ progress: [{ at: now, status: 'queued', message: jobDef.message || 'Queued for tool lane execution.' }],
1238
+ garden: null,
1239
+ };
1240
+ state.jobs.push(job);
1241
+ saveAutonomyState(state);
1242
+ return { job, stats: queueStats(state) };
1243
+ }
1244
+
975
1245
  function asJsonPayload(value) {
976
1246
  if (value == null) return null;
977
1247
  if (typeof value === 'string') {
@@ -1233,6 +1503,47 @@ function findVerifiedState(text) {
1233
1503
  return /(?:verified|confirmed|observed|tested|health[- ]check|response code|exit code|pod image|digest)/i.test(String(text || ''));
1234
1504
  }
1235
1505
 
1506
+ const APPLIED_COGNITION_BLOCK_RX = /<applied_cognition>([\s\S]*?)<\/applied_cognition>/i;
1507
+
1508
+ function validateAppliedCognitionContract(text) {
1509
+ const match = String(text || '').match(APPLIED_COGNITION_BLOCK_RX);
1510
+ if (!match) return { ok: false, violations: ['missing <applied_cognition> contract'] };
1511
+ const body = match[1] || '';
1512
+ const required = [
1513
+ ['decision_delta', /\bdecision[_ -]?delta\s*:/i],
1514
+ ['dominant_domain', /\bdominant[_ -]?domain\s*:/i],
1515
+ ['binds_to', /\bbinds[_ -]?to\s*:/i],
1516
+ ['expected_predicate', /\bexpected[_ -]?predicate\s*:/i],
1517
+ ['artifact_change', /\bartifact[_ -]?change\s*:/i],
1518
+ ];
1519
+ const violations = [];
1520
+ for (const [name, rx] of required) {
1521
+ if (!rx.test(body)) violations.push(`missing ${name}`);
1522
+ }
1523
+ if (/decision[_ -]?delta\s*:\s*(?:none|n\/a|no change|unchanged|same)/i.test(body)) {
1524
+ violations.push('decision_delta says cognition changed nothing');
1525
+ }
1526
+ return { ok: violations.length === 0, violations, contract: body.trim() };
1527
+ }
1528
+
1529
+ function mergeAppliedCognitionValidation(validation, applied) {
1530
+ if (applied.ok) {
1531
+ return {
1532
+ ...validation,
1533
+ appliedCognition: { ok: true, contract: applied.contract },
1534
+ gateTriggers: [...new Set([...(validation.gateTriggers || []), 'applied-cognition-contract'])],
1535
+ };
1536
+ }
1537
+ return {
1538
+ ...validation,
1539
+ passed: false,
1540
+ severity: 'block',
1541
+ violations: [...(validation.violations || []), ...applied.violations.map((v) => `applied_cognition: ${v}`)],
1542
+ gateTriggers: [...new Set([...(validation.gateTriggers || []), 'applied-cognition-contract-missing'])],
1543
+ appliedCognition: { ok: false, violations: applied.violations },
1544
+ };
1545
+ }
1546
+
1236
1547
  function toTelemetryEvent(payload, source = 'aria-mounted-runtime') {
1237
1548
  return {
1238
1549
  event_type: payload.event_type || 'runtime.cognition.turn',
@@ -1418,7 +1729,7 @@ function buildOwnerBypassPacket(message, reason = 'owner-local-bypass') {
1418
1729
  }
1419
1730
 
1420
1731
  async function loadRuntimePacket(req, body, client, packetRequest, message) {
1421
- if (body.packet) return body.packet;
1732
+ if (body.packet) return enrichPacketWithCodebaseSnapshot(body.packet);
1422
1733
  const apiKey = resolveApiKey(req, body);
1423
1734
  ensureOfflineBundleSeeded(apiKey, leaseCache.get(hashKey(apiKey)) || loadEncryptedLease(apiKey));
1424
1735
  try {
@@ -1433,7 +1744,7 @@ async function loadRuntimePacket(req, body, client, packetRequest, message) {
1433
1744
  doctrineBundleHash: lease?.claims?.doctrine_bundle_hash || null,
1434
1745
  lastUpstreamError: null,
1435
1746
  });
1436
- return packet;
1747
+ return enrichPacketWithCodebaseSnapshot(packet);
1437
1748
  } catch (error) {
1438
1749
  const bundle = ensureOfflineBundleSeeded(apiKey, leaseCache.get(hashKey(apiKey)) || loadEncryptedLease(apiKey)) || loadEncryptedOfflineBundle(apiKey);
1439
1750
  const bundleStatus = computeOfflineBundleStatus(bundle);
@@ -1445,19 +1756,52 @@ async function loadRuntimePacket(req, body, client, packetRequest, message) {
1445
1756
  lastUpstreamError: error instanceof Error ? error.message : String(error),
1446
1757
  lastUpstreamOkAt: bundle.lastUpstreamOkAt || bundle.cachedAt || new Date().toISOString(),
1447
1758
  });
1448
- return fallbackPacket;
1759
+ return enrichPacketWithCodebaseSnapshot(fallbackPacket);
1449
1760
  }
1450
1761
  }
1451
1762
  if (!isOwnerBypassRequest(req, body)) {
1452
1763
  throw error;
1453
1764
  }
1454
- return buildOwnerBypassPacket(
1765
+ return enrichPacketWithCodebaseSnapshot(buildOwnerBypassPacket(
1455
1766
  message || packetRequest?.message || '',
1456
1767
  error instanceof Error ? error.message : 'owner-local-bypass',
1457
- );
1768
+ ));
1458
1769
  }
1459
1770
  }
1460
1771
 
1772
+ function enrichPacketWithCodebaseSnapshot(packet) {
1773
+ if (!packet || typeof packet !== 'object') return packet;
1774
+ const codebase = compactCodebaseSnapshot();
1775
+ return {
1776
+ ...packet,
1777
+ runtime: {
1778
+ ...(packet.runtime && typeof packet.runtime === 'object' ? packet.runtime : {}),
1779
+ codebase_awareness: codebase,
1780
+ },
1781
+ };
1782
+ }
1783
+
1784
+ function buildMizanPacketRequest(body = {}) {
1785
+ const context = body.context && typeof body.context === 'object' ? body.context : body;
1786
+ const existing = body.packetRequest && typeof body.packetRequest === 'object' ? body.packetRequest : {};
1787
+ const message = String(
1788
+ context.message ||
1789
+ context.intendedAction ||
1790
+ body.message ||
1791
+ body.text ||
1792
+ ''
1793
+ );
1794
+ const platform = String(context.platform || context.surface || body.platform || body.client || 'mounted-runtime');
1795
+ return {
1796
+ stage: 'preflight',
1797
+ actor: String(context.actor || platform || 'mizan'),
1798
+ system: String(context.system || platform || 'aria-mounted-runtime'),
1799
+ platform,
1800
+ message,
1801
+ ...existing,
1802
+ };
1803
+ }
1804
+
1461
1805
  async function buildRuntimeTurnContext(req, body, client) {
1462
1806
  const sessionId = deriveSessionId(req, body, body.provider === 'anthropic' ? 'anthropic' : 'openai');
1463
1807
  const userId = deriveUserId(req, body);
@@ -2059,6 +2403,8 @@ function compactCodebaseSnapshot() {
2059
2403
  ? config.schemaImages
2060
2404
  : {};
2061
2405
  const repoSnapshots = Array.isArray(awareness.repoSnapshots) ? awareness.repoSnapshots : [];
2406
+ const heartbeatAt = awareness?.daemon?.heartbeatAt || null;
2407
+ const heartbeatAgeMs = heartbeatAt ? Date.now() - Date.parse(heartbeatAt) : null;
2062
2408
  return {
2063
2409
  repositories: repositories.slice(0, 6).map((repo) => ({
2064
2410
  name: repo?.name || null,
@@ -2071,6 +2417,8 @@ function compactCodebaseSnapshot() {
2071
2417
  awareness: {
2072
2418
  status: awareness.status || 'idle',
2073
2419
  updatedAt: awareness.updatedAt || null,
2420
+ daemon: awareness.daemon || null,
2421
+ stale: typeof heartbeatAgeMs === 'number' ? heartbeatAgeMs > 120000 : true,
2074
2422
  repoSnapshots: repoSnapshots.slice(0, 4).map((repo) => ({
2075
2423
  repoName: repo?.repoName || repo?.name || null,
2076
2424
  filesIndexed: repo?.filesIndexed || repo?.fileCount || null,
@@ -3288,7 +3636,10 @@ async function handleRoute(req, res) {
3288
3636
 
3289
3637
  let client;
3290
3638
  try {
3291
- client = createClient(req, body);
3639
+ // HQ routes use their own auth middleware — skip the global API key gate
3640
+ if (!url.pathname.startsWith('/hq/')) {
3641
+ client = createClient(req, body);
3642
+ }
3292
3643
  } catch (error) {
3293
3644
  return json(res, 401, { ok: false, error: error.message });
3294
3645
  }
@@ -3321,7 +3672,8 @@ async function handleRoute(req, res) {
3321
3672
 
3322
3673
  if (url.pathname === '/phase/pre' || url.pathname === '/mizan/pre') {
3323
3674
  const apiKey = resolveApiKey(req, body);
3324
- const packet = body.packet || await client.getHarnessPacket(body.packetRequest || {});
3675
+ const packetRequest = buildMizanPacketRequest(body);
3676
+ const packet = body.packet || await loadRuntimePacket(req, body, client, packetRequest, packetRequest.message || body.text || '');
3325
3677
  const bundle = evaluateMizanPre(packet, body.context || body, {
3326
3678
  sessionId: body.sessionId || body.context?.sessionId || deriveSessionId(req, body, 'mizan-pre'),
3327
3679
  runtimeId: ensureRuntimeMeta().runtimeId,
@@ -3341,7 +3693,8 @@ async function handleRoute(req, res) {
3341
3693
 
3342
3694
  if (url.pathname === '/phase/mid' || url.pathname === '/mizan/mid') {
3343
3695
  const apiKey = resolveApiKey(req, body);
3344
- const packet = body.packet || null;
3696
+ const packetRequest = buildMizanPacketRequest(body);
3697
+ const packet = body.packet || await loadRuntimePacket(req, body, client, packetRequest, packetRequest.message || body.message || '');
3345
3698
  const bundle = evaluateMizanMid(body.message || '', body.plannedApproach || '', packet, body.context || body, {
3346
3699
  sessionId: body.sessionId || body.context?.sessionId || deriveSessionId(req, body, 'mizan-mid'),
3347
3700
  runtimeId: ensureRuntimeMeta().runtimeId,
@@ -3361,7 +3714,8 @@ async function handleRoute(req, res) {
3361
3714
 
3362
3715
  if (url.pathname === '/phase/post' || url.pathname === '/mizan/post') {
3363
3716
  const apiKey = resolveApiKey(req, body);
3364
- const packet = body.packet || null;
3717
+ const packetRequest = buildMizanPacketRequest(body);
3718
+ const packet = body.packet || await loadRuntimePacket(req, body, client, packetRequest, packetRequest.message || body.text || '');
3365
3719
  const bundle = evaluateMizanPost(body.text || '', body.evidence || {}, packet, body.context || body, {
3366
3720
  sessionId: body.sessionId || body.context?.sessionId || deriveSessionId(req, body, 'mizan-post'),
3367
3721
  runtimeId: ensureRuntimeMeta().runtimeId,
@@ -3551,8 +3905,27 @@ async function handleRoute(req, res) {
3551
3905
  }
3552
3906
 
3553
3907
  if (url.pathname === '/check-action') {
3554
- const result = await client.checkAction(body.action, body.target || '');
3555
- return json(res, 200, { ok: true, ...result });
3908
+ const action = body.action || 'write';
3909
+ const localGate = validateVerifyAndHive({ req, body, action });
3910
+ if (!localGate.allowed) {
3911
+ return json(res, 200, { ok: true, allowed: false, ...localGate });
3912
+ }
3913
+ let result;
3914
+ try {
3915
+ result = await client.checkAction(action, body.target || '');
3916
+ } catch (error) {
3917
+ releaseHiveFileLease(deriveSessionId(req, body, 'runtime-action'), coerceTargetFiles(body));
3918
+ throw error;
3919
+ }
3920
+ if (result?.allowed === false) {
3921
+ releaseHiveFileLease(deriveSessionId(req, body, 'runtime-action'), coerceTargetFiles(body));
3922
+ }
3923
+ return json(res, 200, { ok: true, ...result, verify: localGate.verify, hive: localGate.hive });
3924
+ }
3925
+
3926
+ if (url.pathname === '/hive/release') {
3927
+ const sessionId = deriveSessionId(req, body, 'runtime-action');
3928
+ return json(res, 200, { ok: true, hive: releaseHiveFileLease(sessionId, coerceTargetFiles(body)) });
3556
3929
  }
3557
3930
 
3558
3931
  if (url.pathname === '/validate-output' || url.pathname === '/api/harness/validate') {
@@ -3574,6 +3947,7 @@ async function handleRoute(req, res) {
3574
3947
  gateTriggers: ['owner-local-bypass'],
3575
3948
  };
3576
3949
  }
3950
+ validation = mergeAppliedCognitionValidation(validation, validateAppliedCognitionContract(body.text));
3577
3951
  const response = { ok: true, validation };
3578
3952
 
3579
3953
  if (body.runLayer3 !== false) {
@@ -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;
package/dist/sdk/index.js CHANGED
@@ -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