@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.
- package/dist/aria-connector/src/connectors/claude-code.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/claude-code.js +30 -3
- package/dist/aria-connector/src/connectors/claude-code.js.map +1 -1
- package/dist/aria-connector/src/connectors/codebase-awareness.d.ts +8 -1
- package/dist/aria-connector/src/connectors/codebase-awareness.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/codebase-awareness.js +126 -71
- package/dist/aria-connector/src/connectors/codebase-awareness.js.map +1 -1
- package/dist/aria-connector/src/connectors/codex.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/codex.js +76 -9
- package/dist/aria-connector/src/connectors/codex.js.map +1 -1
- package/dist/aria-connector/src/connectors/must-read.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/must-read.js +4 -0
- package/dist/aria-connector/src/connectors/must-read.js.map +1 -1
- package/dist/aria-connector/src/connectors/opencode.js +25 -9
- package/dist/aria-connector/src/connectors/opencode.js.map +1 -1
- package/dist/aria-connector/src/setup-wizard.d.ts.map +1 -1
- package/dist/aria-connector/src/setup-wizard.js +91 -24
- package/dist/aria-connector/src/setup-wizard.js.map +1 -1
- package/dist/assets/hooks/aria-agent-handoff.mjs +23 -0
- package/dist/assets/hooks/aria-cognition-substrate-binding.mjs +69 -3
- package/dist/assets/hooks/aria-harness-via-sdk.mjs +10 -5
- package/dist/assets/hooks/aria-pre-emit-dryrun.mjs +35 -0
- package/dist/assets/hooks/aria-pre-tool-gate.mjs +217 -17
- package/dist/assets/hooks/aria-preprompt-consult.mjs +28 -2
- package/dist/assets/hooks/aria-preturn-memory-gate.mjs +30 -2
- package/dist/assets/hooks/aria-repo-doctrine-gate.mjs +31 -1
- package/dist/assets/hooks/aria-stop-gate.mjs +154 -37
- package/dist/assets/hooks/doctrine_trigger_map.json +55 -0
- package/dist/assets/hooks/lib/domain-output-quality.mjs +103 -0
- package/dist/assets/hooks/lib/skill-autoload-gate.mjs +1 -0
- package/dist/assets/opencode-plugins/harness-gate/index.js +84 -7
- package/dist/assets/opencode-plugins/harness-gate/lib/skill-autoload-gate.js +1 -0
- package/dist/assets/opencode-plugins/harness-outcome/index.js +39 -0
- package/dist/assets/opencode-plugins/harness-stop/index.js +101 -7
- package/dist/assets/opencode-plugins/harness-stop/lib/domain-output-quality.js +103 -0
- package/dist/assets/opencode-plugins/harness-stop/lib/skill-autoload-gate.js +1 -0
- package/dist/runtime/codex-bridge.mjs +71 -8
- package/dist/runtime/discipline/CLAUDE.md +16 -0
- package/dist/runtime/discipline/doctrine_trigger_map.json +55 -0
- package/dist/runtime/doctrine_trigger_map.json +55 -0
- package/dist/runtime/harness-daemon.mjs +80 -5
- package/dist/runtime/manifest.json +1 -1
- package/dist/runtime/sdk/BUNDLED.json +1 -1
- package/dist/runtime/sdk/index.d.ts +14 -0
- package/dist/runtime/sdk/index.js +23 -1
- package/dist/runtime/sdk/index.js.map +1 -1
- package/dist/runtime/service.mjs +385 -11
- package/dist/sdk/BUNDLED.json +1 -1
- package/dist/sdk/index.d.ts +14 -0
- package/dist/sdk/index.js +23 -1
- package/dist/sdk/index.js.map +1 -1
- package/hooks/aria-agent-handoff.mjs +23 -0
- package/hooks/aria-cognition-substrate-binding.mjs +69 -3
- package/hooks/aria-harness-via-sdk.mjs +10 -5
- package/hooks/aria-pre-emit-dryrun.mjs +35 -0
- package/hooks/aria-pre-tool-gate.mjs +217 -17
- package/hooks/aria-preprompt-consult.mjs +28 -2
- package/hooks/aria-preturn-memory-gate.mjs +30 -2
- package/hooks/aria-repo-doctrine-gate.mjs +31 -1
- package/hooks/aria-stop-gate.mjs +154 -37
- package/hooks/doctrine_trigger_map.json +55 -0
- package/hooks/lib/domain-output-quality.mjs +103 -0
- package/hooks/lib/skill-autoload-gate.mjs +1 -0
- package/opencode-plugins/harness-gate/index.js +84 -7
- package/opencode-plugins/harness-gate/lib/skill-autoload-gate.js +1 -0
- package/opencode-plugins/harness-outcome/index.js +39 -0
- package/opencode-plugins/harness-stop/index.js +101 -7
- package/opencode-plugins/harness-stop/lib/domain-output-quality.js +103 -0
- package/opencode-plugins/harness-stop/lib/skill-autoload-gate.js +1 -0
- package/package.json +1 -1
- package/runtime-src/codex-bridge.mjs +71 -8
- package/runtime-src/harness-daemon.mjs +80 -5
- package/runtime-src/service.mjs +385 -11
- package/src/connectors/claude-code.ts +31 -3
- package/src/connectors/codebase-awareness.ts +141 -77
- package/src/connectors/codex.ts +76 -9
- package/src/connectors/must-read.ts +4 -0
- package/src/connectors/opencode.ts +25 -9
- package/src/setup-wizard.ts +105 -25
package/dist/runtime/service.mjs
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
3555
|
-
|
|
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) {
|
package/dist/sdk/BUNDLED.json
CHANGED
package/dist/sdk/index.d.ts
CHANGED
|
@@ -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
|
|