@aria_asi/cli 0.2.30 → 0.2.32
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 +115 -20
- package/dist/aria-connector/src/connectors/claude-code.js.map +1 -1
- package/dist/aria-connector/src/connectors/codex.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/codex.js +551 -11
- package/dist/aria-connector/src/connectors/codex.js.map +1 -1
- package/dist/aria-connector/src/connectors/doctrine-trigger-map.d.ts +7 -0
- package/dist/aria-connector/src/connectors/doctrine-trigger-map.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/doctrine-trigger-map.js +87 -0
- package/dist/aria-connector/src/connectors/doctrine-trigger-map.js.map +1 -0
- package/dist/aria-connector/src/connectors/must-read.d.ts +4 -0
- package/dist/aria-connector/src/connectors/must-read.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/must-read.js +115 -0
- package/dist/aria-connector/src/connectors/must-read.js.map +1 -0
- package/dist/aria-connector/src/connectors/opencode.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/opencode.js +27 -9
- package/dist/aria-connector/src/connectors/opencode.js.map +1 -1
- package/dist/aria-connector/src/connectors/runtime.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/runtime.js +231 -19
- package/dist/aria-connector/src/connectors/runtime.js.map +1 -1
- package/dist/aria-connector/src/connectors/shell.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/shell.js +76 -3
- package/dist/aria-connector/src/connectors/shell.js.map +1 -1
- package/dist/assets/hooks/aria-agent-handoff.mjs +23 -0
- package/dist/assets/hooks/aria-cognition-substrate-binding.mjs +121 -28
- package/dist/assets/hooks/aria-harness-via-sdk.mjs +126 -12
- package/dist/assets/hooks/aria-pre-emit-dryrun.mjs +35 -0
- package/dist/assets/hooks/aria-pre-tool-gate.mjs +383 -93
- package/dist/assets/hooks/aria-preprompt-consult.mjs +28 -2
- package/dist/assets/hooks/aria-preturn-memory-gate.mjs +93 -16
- package/dist/assets/hooks/aria-repo-doctrine-gate.mjs +33 -1
- package/dist/assets/hooks/aria-stop-gate.mjs +346 -81
- package/dist/assets/hooks/doctrine_trigger_map.json +55 -0
- package/dist/assets/hooks/lib/canonical-lenses.mjs +6 -5
- package/dist/assets/hooks/lib/gate-loop-state.mjs +50 -0
- package/dist/assets/hooks/lib/hook-message-window.mjs +121 -0
- package/dist/assets/hooks/test-tier-lens-labeling.mjs +26 -58
- package/dist/assets/opencode-plugins/harness-gate/index.js +40 -5
- package/dist/assets/opencode-plugins/harness-stop/index.js +133 -10
- package/dist/runtime/auth-middleware.mjs +251 -0
- package/dist/runtime/codex-bridge.mjs +644 -0
- package/dist/runtime/discipline/CLAUDE.md +28 -0
- package/dist/runtime/discipline/doctrine_trigger_map.json +534 -0
- package/dist/runtime/doctrine_trigger_map.json +534 -0
- package/dist/runtime/fleet-engine.mjs +231 -0
- package/dist/runtime/harness-daemon.mjs +460 -0
- package/dist/runtime/manifest.json +1 -1
- package/dist/runtime/metering.mjs +100 -0
- package/dist/runtime/onboarding-engine.mjs +89 -0
- package/dist/runtime/plugin-engine.mjs +196 -0
- package/dist/runtime/sdk/BUNDLED.json +1 -1
- package/dist/runtime/sdk/index.d.ts +12 -0
- package/dist/runtime/sdk/index.js +120 -14
- package/dist/runtime/sdk/index.js.map +1 -1
- package/dist/runtime/service.mjs +1140 -48
- package/dist/runtime/workflow-engine.mjs +322 -0
- package/dist/sdk/BUNDLED.json +1 -1
- package/dist/sdk/index.d.ts +12 -0
- package/dist/sdk/index.js +120 -14
- package/dist/sdk/index.js.map +1 -1
- package/hooks/aria-agent-handoff.mjs +23 -0
- package/hooks/aria-cognition-substrate-binding.mjs +121 -28
- package/hooks/aria-harness-via-sdk.mjs +126 -12
- package/hooks/aria-pre-emit-dryrun.mjs +35 -0
- package/hooks/aria-pre-tool-gate.mjs +383 -93
- package/hooks/aria-preprompt-consult.mjs +28 -2
- package/hooks/aria-preturn-memory-gate.mjs +93 -16
- package/hooks/aria-repo-doctrine-gate.mjs +33 -1
- package/hooks/aria-stop-gate.mjs +346 -81
- package/hooks/doctrine_trigger_map.json +55 -0
- package/hooks/lib/canonical-lenses.mjs +6 -5
- package/hooks/lib/gate-loop-state.mjs +50 -0
- package/hooks/lib/hook-message-window.mjs +121 -0
- package/hooks/test-tier-lens-labeling.mjs +26 -58
- package/opencode-plugins/harness-gate/index.js +40 -5
- package/opencode-plugins/harness-stop/index.js +133 -10
- package/package.json +1 -1
- package/runtime-src/auth-middleware.mjs +251 -0
- package/runtime-src/codex-bridge.mjs +644 -0
- package/runtime-src/fleet-engine.mjs +231 -0
- package/runtime-src/harness-daemon.mjs +460 -0
- package/runtime-src/metering.mjs +100 -0
- package/runtime-src/onboarding-engine.mjs +89 -0
- package/runtime-src/plugin-engine.mjs +196 -0
- package/runtime-src/service.mjs +1140 -48
- package/runtime-src/workflow-engine.mjs +322 -0
- package/scripts/bundle-sdk.mjs +5 -0
- package/src/connectors/claude-code.ts +126 -20
- package/src/connectors/codex.ts +559 -10
- package/src/connectors/doctrine-trigger-map.ts +112 -0
- package/src/connectors/must-read.ts +117 -0
- package/src/connectors/opencode.ts +28 -9
- package/src/connectors/runtime.ts +241 -21
- package/src/connectors/shell.ts +78 -3
- package/dist/cli-0.2.0.tgz +0 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {
|
|
2
|
+
existsSync,
|
|
3
|
+
mkdirSync,
|
|
4
|
+
readFileSync,
|
|
5
|
+
statSync,
|
|
6
|
+
writeFileSync,
|
|
7
|
+
} from 'fs';
|
|
8
|
+
import { homedir } from 'os';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
import { fileURLToPath } from 'node:url';
|
|
11
|
+
|
|
12
|
+
export interface DoctrineMapSyncResult {
|
|
13
|
+
sourcePath: string | null;
|
|
14
|
+
targetCount: number;
|
|
15
|
+
updatedCount: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface DoctrineMapCandidate {
|
|
19
|
+
path: string;
|
|
20
|
+
mtimeMs: number;
|
|
21
|
+
data: Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function bundledDoctrineTriggerMapCandidates(): string[] {
|
|
25
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
26
|
+
return [
|
|
27
|
+
path.resolve(here, '..', '..', '..', '..', 'hooks', 'doctrine_trigger_map.json'),
|
|
28
|
+
path.resolve(here, '..', '..', '..', 'assets', 'hooks', 'doctrine_trigger_map.json'),
|
|
29
|
+
];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function installedDoctrineTriggerMapTargets(): string[] {
|
|
33
|
+
const home = homedir();
|
|
34
|
+
return [
|
|
35
|
+
path.join(home, '.aria', 'runtime', 'discipline', 'doctrine_trigger_map.json'),
|
|
36
|
+
path.join(home, '.aria', 'runtime', 'doctrine_trigger_map.json'),
|
|
37
|
+
path.join(home, '.claude', 'hooks', 'doctrine_trigger_map.json'),
|
|
38
|
+
path.join(home, '.claude', 'projects', '-home-hamzaibrahim1', 'memory', 'doctrine_trigger_map.json'),
|
|
39
|
+
path.join(home, '.codex', 'doctrine_trigger_map.json'),
|
|
40
|
+
path.join(home, '.opencode', 'doctrine_trigger_map.json'),
|
|
41
|
+
];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function readCandidate(targetPath: string): DoctrineMapCandidate | null {
|
|
45
|
+
if (!existsSync(targetPath)) return null;
|
|
46
|
+
try {
|
|
47
|
+
const data = JSON.parse(readFileSync(targetPath, 'utf8')) as Record<string, unknown>;
|
|
48
|
+
if (!Array.isArray(data.triggers)) return null;
|
|
49
|
+
return {
|
|
50
|
+
path: targetPath,
|
|
51
|
+
mtimeMs: statSync(targetPath).mtimeMs,
|
|
52
|
+
data,
|
|
53
|
+
};
|
|
54
|
+
} catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function normalizeDoctrineMap(data: Record<string, unknown>): string {
|
|
60
|
+
return JSON.stringify(data, null, 2) + '\n';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function syncDoctrineTriggerMap(logs: string[] = []): DoctrineMapSyncResult {
|
|
64
|
+
const targets = installedDoctrineTriggerMapTargets();
|
|
65
|
+
const readableCandidates = [
|
|
66
|
+
...bundledDoctrineTriggerMapCandidates(),
|
|
67
|
+
...targets,
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
const candidates = readableCandidates
|
|
71
|
+
.map((targetPath) => readCandidate(targetPath))
|
|
72
|
+
.filter((candidate): candidate is DoctrineMapCandidate => candidate !== null)
|
|
73
|
+
.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
74
|
+
|
|
75
|
+
if (candidates.length === 0) {
|
|
76
|
+
logs.push('⚠ doctrine trigger map missing from bundle and all installed targets');
|
|
77
|
+
return {
|
|
78
|
+
sourcePath: null,
|
|
79
|
+
targetCount: targets.length,
|
|
80
|
+
updatedCount: 0,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const source = candidates[0];
|
|
85
|
+
const normalized = normalizeDoctrineMap(source.data);
|
|
86
|
+
let updatedCount = 0;
|
|
87
|
+
|
|
88
|
+
for (const targetPath of targets) {
|
|
89
|
+
try {
|
|
90
|
+
const dirPath = path.dirname(targetPath);
|
|
91
|
+
if (!existsSync(dirPath)) {
|
|
92
|
+
mkdirSync(dirPath, { recursive: true, mode: 0o755 });
|
|
93
|
+
}
|
|
94
|
+
const current = existsSync(targetPath) ? readFileSync(targetPath, 'utf8') : null;
|
|
95
|
+
if (current === normalized) continue;
|
|
96
|
+
writeFileSync(targetPath, normalized, { mode: 0o644 });
|
|
97
|
+
updatedCount++;
|
|
98
|
+
} catch (error) {
|
|
99
|
+
logs.push(`⚠ doctrine trigger map sync failed at ${targetPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
logs.push(
|
|
104
|
+
`Synced doctrine trigger map from ${source.path} to ${targets.length} installed target(s)`,
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
sourcePath: source.path,
|
|
109
|
+
targetCount: targets.length,
|
|
110
|
+
updatedCount,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
export type MustReadSurface = 'claude' | 'codex' | 'opencode';
|
|
2
|
+
|
|
3
|
+
function surfaceRoot(surface: MustReadSurface): string {
|
|
4
|
+
if (surface === 'claude') return '~/.claude';
|
|
5
|
+
if (surface === 'codex') return '~/.codex';
|
|
6
|
+
return '~/.aria';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function doctrineMapPath(surface: MustReadSurface): string {
|
|
10
|
+
if (surface === 'claude') return '~/.claude/hooks/doctrine_trigger_map.json';
|
|
11
|
+
if (surface === 'codex') return '~/.codex/doctrine_trigger_map.json';
|
|
12
|
+
return '~/.opencode/doctrine_trigger_map.json';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function surfaceSpecificFiles(surface: MustReadSurface): string[] {
|
|
16
|
+
if (surface === 'claude') {
|
|
17
|
+
return [
|
|
18
|
+
'~/.claude/hooks/aria-harness-via-sdk.mjs',
|
|
19
|
+
'~/.claude/hooks/aria-preprompt-consult.mjs',
|
|
20
|
+
'~/.claude/hooks/aria-pre-tool-gate.mjs',
|
|
21
|
+
'~/.claude/hooks/aria-preturn-memory-gate.mjs',
|
|
22
|
+
'~/.claude/hooks/aria-cognition-substrate-binding.mjs',
|
|
23
|
+
'~/.claude/hooks/aria-stop-gate.mjs',
|
|
24
|
+
'~/.claude/hooks/aria-pre-text-gate.mjs',
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
if (surface === 'codex') {
|
|
28
|
+
return [
|
|
29
|
+
'~/.codex/AGENTS.md',
|
|
30
|
+
'~/.codex/config.toml',
|
|
31
|
+
'~/.aria/wrappers/codex',
|
|
32
|
+
'~/.aria/runtime/service.mjs',
|
|
33
|
+
'~/.codex/skills/aria-http-harness-client/SKILL.md',
|
|
34
|
+
'~/.codex/skills/aria-cognition/aria-repo-doctrine/SKILL.md',
|
|
35
|
+
'~/.codex/skills/aria-cognition/ghazali-8lens/SKILL.md',
|
|
36
|
+
'~/.codex/skills/aria-cognition/mizan/SKILL.md',
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
return [
|
|
40
|
+
'~/.aria/AGENTS.md',
|
|
41
|
+
'~/.aria/runtime/discipline/skills/aria-harness/aria-harness-onboarding/SKILL.md',
|
|
42
|
+
'~/.aria/runtime/discipline/skills/aria-cognition/aria-repo-doctrine/SKILL.md',
|
|
43
|
+
'~/.aria/runtime/discipline/skills/aria-cognition/ghazali-8lens/SKILL.md',
|
|
44
|
+
'~/.aria/runtime/discipline/skills/aria-cognition/mizan/SKILL.md',
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function buildMustReadGuide(surface: MustReadSurface): string {
|
|
49
|
+
const root = surfaceRoot(surface);
|
|
50
|
+
const coreFiles = [
|
|
51
|
+
`${root}/ARIA_MUST_READ.md`,
|
|
52
|
+
'~/.aria/runtime/discipline/CLAUDE.md',
|
|
53
|
+
'~/.aria/runtime/discipline/skills/aria-harness/aria-harness-onboarding/SKILL.md',
|
|
54
|
+
'~/.aria/runtime/discipline/skills/aria-harness/aria-harness-substrate-binding/SKILL.md',
|
|
55
|
+
doctrineMapPath(surface),
|
|
56
|
+
];
|
|
57
|
+
const orderedFiles = [...coreFiles, ...surfaceSpecificFiles(surface)];
|
|
58
|
+
|
|
59
|
+
return `# Aria Agent Must-Read Order
|
|
60
|
+
|
|
61
|
+
This file exists because weaker models and long sessions drift unless the reading order is explicit.
|
|
62
|
+
Read these files in order before the first non-trivial action, and re-open the relevant gate file whenever a block fires.
|
|
63
|
+
|
|
64
|
+
## Required Read Order
|
|
65
|
+
|
|
66
|
+
${orderedFiles.map((filePath, index) => `${index + 1}. \`${filePath}\``).join('\n')}
|
|
67
|
+
|
|
68
|
+
## What Each File Teaches
|
|
69
|
+
|
|
70
|
+
1. \`${root}/ARIA_MUST_READ.md\`
|
|
71
|
+
The cross-surface reading order, recovery rules, and what to re-open after compaction or a block.
|
|
72
|
+
|
|
73
|
+
2. \`~/.aria/runtime/discipline/CLAUDE.md\`
|
|
74
|
+
The full harness doctrine: L1/L2/L3, cognition requirements, deploy verify contract, drift triggers, and anti-loop rules.
|
|
75
|
+
|
|
76
|
+
3. \`~/.aria/runtime/discipline/skills/aria-harness/aria-harness-onboarding/SKILL.md\`
|
|
77
|
+
The harness model in practical terms: packet, bind, and live gates.
|
|
78
|
+
|
|
79
|
+
4. \`~/.aria/runtime/discipline/skills/aria-harness/aria-harness-substrate-binding/SKILL.md\`
|
|
80
|
+
The cognition contract and anchor discipline. Re-open this whenever cognition or stop-gate fails.
|
|
81
|
+
|
|
82
|
+
5. \`${doctrineMapPath(surface)}\`
|
|
83
|
+
The live doctrine trigger map. This is what the runtime and stop gates actually match against.
|
|
84
|
+
|
|
85
|
+
## Surface-Specific Re-Open Rules
|
|
86
|
+
|
|
87
|
+
- If a pre-tool or write block fires:
|
|
88
|
+
Re-open the pre-tool surface file for this client plus \`aria-harness-substrate-binding\`.
|
|
89
|
+
|
|
90
|
+
- If an output or stop-gate block fires:
|
|
91
|
+
Re-open \`~/.aria/runtime/discipline/CLAUDE.md\`, the doctrine trigger map, and the substrate-binding skill before re-authoring.
|
|
92
|
+
|
|
93
|
+
- If transcript compaction or ledger deadlock happens:
|
|
94
|
+
Re-open items 1 through 4 first, then inspect the exact current hook or runtime file causing the block. Do not guess from stale memory.
|
|
95
|
+
|
|
96
|
+
- If the model starts repeating itself:
|
|
97
|
+
Stop, re-open this file, and repair from the gate evidence instead of restating intent.
|
|
98
|
+
|
|
99
|
+
## Non-Negotiables
|
|
100
|
+
|
|
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.
|
|
106
|
+
- Do not say "good enough", "should work", or make unverified completion claims.
|
|
107
|
+
- Do not treat skills as optional flavor text; they are the reading order and repair guide.
|
|
108
|
+
- Do not proceed after a gate block without re-opening the file that owns that gate.
|
|
109
|
+
`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function mustReadIntro(surface: MustReadSurface): string {
|
|
113
|
+
const root = surfaceRoot(surface);
|
|
114
|
+
return `## Must Read Order
|
|
115
|
+
Read \`${root}/ARIA_MUST_READ.md\` before the first non-trivial action and re-open it after any gate block, compaction, or repeated drift.
|
|
116
|
+
`;
|
|
117
|
+
}
|
|
@@ -16,6 +16,8 @@ import * as path from 'path';
|
|
|
16
16
|
import { fileURLToPath } from 'node:url';
|
|
17
17
|
import type { AriaConfig } from '../config.js';
|
|
18
18
|
import { connectShell } from './shell.js';
|
|
19
|
+
import { syncDoctrineTriggerMap } from './doctrine-trigger-map.js';
|
|
20
|
+
import { buildMustReadGuide, mustReadIntro } from './must-read.js';
|
|
19
21
|
|
|
20
22
|
// ── Bundled OpenCode plugins ────────────────────────────────────────────────
|
|
21
23
|
//
|
|
@@ -139,6 +141,7 @@ export async function connectOpenCode(config: AriaConfig): Promise<string[]> {
|
|
|
139
141
|
copyPluginDir(srcDir, dstDir, logs);
|
|
140
142
|
installedPaths.push(dstDir);
|
|
141
143
|
}
|
|
144
|
+
syncDoctrineTriggerMap(logs);
|
|
142
145
|
|
|
143
146
|
// ── Wire ~/.opencode/config.json ──────────────────────────────────────────
|
|
144
147
|
const configPath = path.join(opencodeDir, 'config.json');
|
|
@@ -337,14 +340,30 @@ ${schemaText || '(no schema images yet — run \`aria repo scan\`)'}
|
|
|
337
340
|
- If a fix only works by weakening the contract, the mechanism is still broken. Debug the mechanism.
|
|
338
341
|
|
|
339
342
|
## 8-Lens Cognition
|
|
340
|
-
|
|
341
|
-
-
|
|
342
|
-
-
|
|
343
|
-
-
|
|
344
|
-
-
|
|
345
|
-
-
|
|
346
|
-
-
|
|
347
|
-
|
|
348
|
-
|
|
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.
|
|
349
368
|
`;
|
|
350
369
|
}
|
|
@@ -7,12 +7,14 @@ import {
|
|
|
7
7
|
chmodSync,
|
|
8
8
|
rmSync,
|
|
9
9
|
writeFileSync,
|
|
10
|
+
readFileSync,
|
|
10
11
|
} from 'fs';
|
|
11
12
|
import { execFileSync } from 'child_process';
|
|
12
13
|
import { homedir } from 'os';
|
|
13
14
|
import * as path from 'path';
|
|
14
15
|
import { fileURLToPath } from 'node:url';
|
|
15
16
|
import { loadConfig, saveConfig } from '../config.js';
|
|
17
|
+
import { syncDoctrineTriggerMap } from './doctrine-trigger-map.js';
|
|
16
18
|
|
|
17
19
|
function packageRuntimeDir(): string {
|
|
18
20
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -50,6 +52,39 @@ function writeWrapper(binPath: string, targetScript: string): void {
|
|
|
50
52
|
try { chmodSync(binPath, 0o755); } catch {}
|
|
51
53
|
}
|
|
52
54
|
|
|
55
|
+
function trimUrl(value: string): string {
|
|
56
|
+
return value.trim().replace(/\/+$/, '');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function isLocalHarnessDaemonUrl(value: string): boolean {
|
|
60
|
+
const normalized = trimUrl(value);
|
|
61
|
+
return normalized === 'http://127.0.0.1:8790' || normalized === 'http://localhost:8790';
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function canonicalUpstreamHarnessUrl(): string {
|
|
65
|
+
const localSoulCandidates = existsSync('/etc/rancher/k3s/k3s.yaml')
|
|
66
|
+
? ['http://127.0.0.1:30080', 'http://192.168.4.25:30080']
|
|
67
|
+
: [];
|
|
68
|
+
const candidates = [
|
|
69
|
+
process.env.ARIA_UPSTREAM_HARNESS_URL || '',
|
|
70
|
+
process.env.ARIA_HIVE_UPSTREAM_URL || '',
|
|
71
|
+
...localSoulCandidates,
|
|
72
|
+
process.env.ARIA_SOUL_URL || '',
|
|
73
|
+
process.env.ARIAS_SOUL_URL || '',
|
|
74
|
+
process.env.ARIA_SOUL_BASE_URL || '',
|
|
75
|
+
...(process.env.ARIA_HARNESS_FALLBACK_URLS || '').split(','),
|
|
76
|
+
'https://harness.ariasos.com',
|
|
77
|
+
]
|
|
78
|
+
.map((entry) => trimUrl(String(entry || '')))
|
|
79
|
+
.filter(Boolean);
|
|
80
|
+
|
|
81
|
+
for (const candidate of candidates) {
|
|
82
|
+
if (!isLocalHarnessDaemonUrl(candidate)) return candidate;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return 'https://harness.ariasos.com';
|
|
86
|
+
}
|
|
87
|
+
|
|
53
88
|
function writeRuntimeEnv(runtimeDst: string): string {
|
|
54
89
|
const envPath = path.join(runtimeDst, 'runtime.env');
|
|
55
90
|
const config = loadConfig();
|
|
@@ -59,24 +94,46 @@ function writeRuntimeEnv(runtimeDst: string): string {
|
|
|
59
94
|
const deepModel = runtimeProfiles.deepModel || 'deepseek-v4-pro';
|
|
60
95
|
const xaiFallbackModel = runtimeProfiles.xaiFallbackModel || 'grok-4-2-reasoning';
|
|
61
96
|
const nimFallbackModel = runtimeProfiles.nimFallbackModel || 'qwen/qwen3.5-122b-a10b';
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
process.env.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
process.env.
|
|
69
|
-
|
|
70
|
-
|
|
97
|
+
const localHarnessUrl = 'http://127.0.0.1:8790';
|
|
98
|
+
const upstreamHarnessUrl = canonicalUpstreamHarnessUrl();
|
|
99
|
+
const harnessFallbackUrls = [
|
|
100
|
+
process.env.ARIA_HARNESS_FALLBACK_URLS || '',
|
|
101
|
+
process.env.ARIA_SOUL_URL || '',
|
|
102
|
+
process.env.ARIAS_SOUL_URL || '',
|
|
103
|
+
process.env.ARIA_SOUL_BASE_URL || '',
|
|
104
|
+
upstreamHarnessUrl,
|
|
105
|
+
'http://127.0.0.1:30080',
|
|
106
|
+
'http://192.168.4.25:30080',
|
|
107
|
+
'https://arias-soul-6zp3gtk2ca-uc.a.run.app',
|
|
108
|
+
'https://harness.ariasos.com',
|
|
109
|
+
]
|
|
110
|
+
.flatMap((entry) => String(entry || '').split(','))
|
|
111
|
+
.map((entry) => trimUrl(String(entry || '')))
|
|
112
|
+
.filter((entry) => entry && !isLocalHarnessDaemonUrl(entry));
|
|
113
|
+
const forgeServiceUrl = `${localHarnessUrl}/api/forge/psi`;
|
|
114
|
+
const upstreamForgeServiceUrl =
|
|
115
|
+
process.env.ARIA_UPSTREAM_FORGE_SERVICE_URL ||
|
|
116
|
+
process.env.ARIA_FORGE_UPSTREAM_URL ||
|
|
117
|
+
`${upstreamHarnessUrl}/api/forge/psi`;
|
|
71
118
|
writeFileSync(
|
|
72
119
|
envPath,
|
|
73
120
|
[
|
|
74
121
|
'ARIA_RUNTIME_HOST=127.0.0.1',
|
|
75
122
|
'ARIA_RUNTIME_PORT=4319',
|
|
76
123
|
'ARIA_RUNTIME_URL=http://127.0.0.1:4319',
|
|
77
|
-
|
|
78
|
-
|
|
124
|
+
'ARIA_HARNESS_DAEMON_HOST=127.0.0.1',
|
|
125
|
+
'ARIA_HARNESS_DAEMON_PORT=8790',
|
|
126
|
+
`ARIA_HARNESS_DAEMON_URL=${localHarnessUrl}`,
|
|
127
|
+
'ARIA_CODEX_BRIDGE_HOST=127.0.0.1',
|
|
128
|
+
'ARIA_CODEX_BRIDGE_PORT=4320',
|
|
129
|
+
'ARIA_CODEX_DOWNSTREAM_PORT=4321',
|
|
130
|
+
`ARIA_HIVE_RUNTIME_URL=${localHarnessUrl}`,
|
|
131
|
+
`ARIA_HARNESS_BASE_URL=${localHarnessUrl}`,
|
|
132
|
+
`ARIA_HARNESS_URL=${localHarnessUrl}`,
|
|
133
|
+
`ARIA_UPSTREAM_HARNESS_URL=${upstreamHarnessUrl}`,
|
|
134
|
+
`ARIA_HARNESS_FALLBACK_URLS=${Array.from(new Set(harnessFallbackUrls)).join(',')}`,
|
|
79
135
|
`ARIA_FORGE_SERVICE_URL=${forgeServiceUrl}`,
|
|
136
|
+
`ARIA_UPSTREAM_FORGE_SERVICE_URL=${upstreamForgeServiceUrl}`,
|
|
80
137
|
'ARIA_QDRANT_URL=http://127.0.0.1:6333',
|
|
81
138
|
'ARIA_QDRANT_COLLECTION=aria_garden_memory',
|
|
82
139
|
`ARIA_RUNTIME_DEFAULT_PROVIDER=${defaultProvider}`,
|
|
@@ -230,7 +287,8 @@ function installSystemdUserService(ariaDir: string, logs: string[]): void {
|
|
|
230
287
|
const unit = [
|
|
231
288
|
'[Unit]',
|
|
232
289
|
'Description=Aria Mounted Runtime',
|
|
233
|
-
'After=network.target',
|
|
290
|
+
'After=network.target aria-harnessd.service',
|
|
291
|
+
'Requires=aria-harnessd.service',
|
|
234
292
|
'',
|
|
235
293
|
'[Service]',
|
|
236
294
|
'Type=simple',
|
|
@@ -256,13 +314,154 @@ function installSystemdUserService(ariaDir: string, logs: string[]): void {
|
|
|
256
314
|
}
|
|
257
315
|
}
|
|
258
316
|
|
|
317
|
+
function installHarnessDaemonSystemdUserService(ariaDir: string, logs: string[]): void {
|
|
318
|
+
const systemctlPath = '/bin/systemctl';
|
|
319
|
+
if (process.platform !== 'linux' || !existsSync(systemctlPath)) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const serviceDir = path.join(homedir(), '.config', 'systemd', 'user');
|
|
324
|
+
const servicePath = path.join(serviceDir, 'aria-harnessd.service');
|
|
325
|
+
mkdirSync(serviceDir, { recursive: true, mode: 0o755 });
|
|
326
|
+
|
|
327
|
+
const unit = [
|
|
328
|
+
'[Unit]',
|
|
329
|
+
'Description=Aria Local Harness Daemon',
|
|
330
|
+
'After=network.target',
|
|
331
|
+
'',
|
|
332
|
+
'[Service]',
|
|
333
|
+
'Type=simple',
|
|
334
|
+
`EnvironmentFile=-${path.join(ariaDir, 'runtime', 'runtime.env')}`,
|
|
335
|
+
`ExecStart=${path.join(ariaDir, 'bin', 'aria-harnessd')}`,
|
|
336
|
+
'Restart=always',
|
|
337
|
+
'RestartSec=2',
|
|
338
|
+
'',
|
|
339
|
+
'[Install]',
|
|
340
|
+
'WantedBy=default.target',
|
|
341
|
+
'',
|
|
342
|
+
].join('\n');
|
|
343
|
+
|
|
344
|
+
writeFileSync(servicePath, unit, { mode: 0o644 });
|
|
345
|
+
logs.push(`Installed systemd user unit → ${servicePath}`);
|
|
346
|
+
|
|
347
|
+
try {
|
|
348
|
+
execFileSync(systemctlPath, ['--user', 'daemon-reload'], { stdio: 'ignore' });
|
|
349
|
+
execFileSync(systemctlPath, ['--user', 'enable', '--now', 'aria-harnessd.service'], { stdio: 'ignore' });
|
|
350
|
+
logs.push('Enabled and started systemd user service: aria-harnessd.service');
|
|
351
|
+
} catch (error) {
|
|
352
|
+
logs.push(`⚠ local harness daemon installed but not activated: ${error instanceof Error ? error.message : String(error)}`);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function retireLegacySoulPortForwardServices(logs: string[]): void {
|
|
357
|
+
const systemctlPath = '/bin/systemctl';
|
|
358
|
+
if (process.platform !== 'linux' || !existsSync(systemctlPath)) {
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const serviceDir = path.join(homedir(), '.config', 'systemd', 'user');
|
|
363
|
+
const legacyUnits = ['aria-soul-portforward.service', 'aria-soul-forward.service'];
|
|
364
|
+
const dependencyNeedles = new Set(legacyUnits);
|
|
365
|
+
|
|
366
|
+
if (existsSync(serviceDir)) {
|
|
367
|
+
for (const name of readdirSync(serviceDir)) {
|
|
368
|
+
if (!name.endsWith('.service')) continue;
|
|
369
|
+
const unitPath = path.join(serviceDir, name);
|
|
370
|
+
if (!statSync(unitPath).isFile()) continue;
|
|
371
|
+
let current = '';
|
|
372
|
+
try {
|
|
373
|
+
current = readFileSync(unitPath, 'utf8');
|
|
374
|
+
} catch {
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
let next = current;
|
|
378
|
+
for (const needle of dependencyNeedles) {
|
|
379
|
+
next = next.replaceAll(needle, 'aria-harnessd.service');
|
|
380
|
+
}
|
|
381
|
+
if (next !== current) {
|
|
382
|
+
writeFileSync(unitPath, next, { mode: 0o644 });
|
|
383
|
+
logs.push(`Rebound legacy 8790 dependency → ${unitPath}`);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
for (const unit of legacyUnits) {
|
|
389
|
+
const unitPath = path.join(serviceDir, unit);
|
|
390
|
+
const backupPath = `${unitPath}.legacy-disabled.bak`;
|
|
391
|
+
const disabledPath = `${unitPath}.disabled`;
|
|
392
|
+
try {
|
|
393
|
+
if (existsSync(unitPath) && statSync(unitPath).isFile() && !existsSync(backupPath)) {
|
|
394
|
+
copyFileSync(unitPath, backupPath);
|
|
395
|
+
logs.push(`Backed up legacy 8790 unit → ${backupPath}`);
|
|
396
|
+
}
|
|
397
|
+
} catch {}
|
|
398
|
+
try {
|
|
399
|
+
if (existsSync(unitPath) && statSync(unitPath).isFile()) {
|
|
400
|
+
rmSync(disabledPath, { force: true });
|
|
401
|
+
copyFileSync(unitPath, disabledPath);
|
|
402
|
+
rmSync(unitPath, { force: true });
|
|
403
|
+
logs.push(`Retired legacy 8790 unit file → ${disabledPath}`);
|
|
404
|
+
}
|
|
405
|
+
} catch {}
|
|
406
|
+
try {
|
|
407
|
+
execFileSync(systemctlPath, ['--user', 'disable', '--now', unit], { stdio: 'ignore' });
|
|
408
|
+
logs.push(`Disabled legacy 8790 unit: ${unit}`);
|
|
409
|
+
} catch {}
|
|
410
|
+
try {
|
|
411
|
+
execFileSync(systemctlPath, ['--user', 'mask', '--force', unit], { stdio: 'ignore' });
|
|
412
|
+
logs.push(`Masked legacy 8790 unit: ${unit}`);
|
|
413
|
+
} catch {}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
try {
|
|
417
|
+
execFileSync(systemctlPath, ['--user', 'daemon-reload'], { stdio: 'ignore' });
|
|
418
|
+
} catch {}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function installCodexBridgeSystemdUserService(ariaDir: string, logs: string[]): void {
|
|
422
|
+
const systemctlPath = '/bin/systemctl';
|
|
423
|
+
if (process.platform !== 'linux' || !existsSync(systemctlPath)) {
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
const serviceDir = path.join(homedir(), '.config', 'systemd', 'user');
|
|
428
|
+
const servicePath = path.join(serviceDir, 'aria-codex-bridge.service');
|
|
429
|
+
mkdirSync(serviceDir, { recursive: true, mode: 0o755 });
|
|
430
|
+
|
|
431
|
+
const unit = [
|
|
432
|
+
'[Unit]',
|
|
433
|
+
'Description=Aria Codex Enforcement Bridge',
|
|
434
|
+
'After=network.target aria-mounted-runtime.service',
|
|
435
|
+
'Requires=aria-mounted-runtime.service',
|
|
436
|
+
'',
|
|
437
|
+
'[Service]',
|
|
438
|
+
'Type=simple',
|
|
439
|
+
`EnvironmentFile=-${path.join(ariaDir, 'runtime', 'runtime.env')}`,
|
|
440
|
+
`ExecStart=${path.join(ariaDir, 'bin', 'aria-codex-bridge')}`,
|
|
441
|
+
'Restart=always',
|
|
442
|
+
'RestartSec=2',
|
|
443
|
+
'',
|
|
444
|
+
'[Install]',
|
|
445
|
+
'WantedBy=default.target',
|
|
446
|
+
'',
|
|
447
|
+
].join('\n');
|
|
448
|
+
|
|
449
|
+
writeFileSync(servicePath, unit, { mode: 0o644 });
|
|
450
|
+
logs.push(`Installed systemd user unit → ${servicePath}`);
|
|
451
|
+
|
|
452
|
+
try {
|
|
453
|
+
execFileSync(systemctlPath, ['--user', 'daemon-reload'], { stdio: 'ignore' });
|
|
454
|
+
execFileSync(systemctlPath, ['--user', 'enable', '--now', 'aria-codex-bridge.service'], { stdio: 'ignore' });
|
|
455
|
+
logs.push('Enabled and started systemd user service: aria-codex-bridge.service');
|
|
456
|
+
} catch (error) {
|
|
457
|
+
logs.push(`⚠ codex bridge service installed but not activated: ${error instanceof Error ? error.message : String(error)}`);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
259
461
|
function installLaunchAgent(ariaDir: string, logs: string[]): void {
|
|
260
462
|
if (process.platform !== 'darwin') return;
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
process.env.ARIA_HARNESS_BASE_URL ||
|
|
264
|
-
process.env.ARIA_HARNESS_URL ||
|
|
265
|
-
'https://harness.ariasos.com';
|
|
463
|
+
const localHarnessUrl = 'http://127.0.0.1:8790';
|
|
464
|
+
const upstreamHarnessUrl = canonicalUpstreamHarnessUrl();
|
|
266
465
|
|
|
267
466
|
const launchAgentDir = path.join(homedir(), 'Library', 'LaunchAgents');
|
|
268
467
|
const plistPath = path.join(launchAgentDir, 'com.aria.mounted-runtime.plist');
|
|
@@ -286,10 +485,20 @@ function installLaunchAgent(ariaDir: string, logs: string[]): void {
|
|
|
286
485
|
<string>4319</string>
|
|
287
486
|
<key>ARIA_RUNTIME_URL</key>
|
|
288
487
|
<string>http://127.0.0.1:4319</string>
|
|
289
|
-
|
|
290
|
-
<string>${
|
|
291
|
-
|
|
292
|
-
<string>${
|
|
488
|
+
<key>ARIA_HARNESS_DAEMON_URL</key>
|
|
489
|
+
<string>${localHarnessUrl}</string>
|
|
490
|
+
<key>ARIA_HIVE_RUNTIME_URL</key>
|
|
491
|
+
<string>${localHarnessUrl}</string>
|
|
492
|
+
<key>ARIA_HARNESS_BASE_URL</key>
|
|
493
|
+
<string>${localHarnessUrl}</string>
|
|
494
|
+
<key>ARIA_HARNESS_URL</key>
|
|
495
|
+
<string>${localHarnessUrl}</string>
|
|
496
|
+
<key>ARIA_UPSTREAM_HARNESS_URL</key>
|
|
497
|
+
<string>${upstreamHarnessUrl}</string>
|
|
498
|
+
<key>ARIA_FORGE_SERVICE_URL</key>
|
|
499
|
+
<string>${localHarnessUrl}/api/forge/psi</string>
|
|
500
|
+
<key>ARIA_UPSTREAM_FORGE_SERVICE_URL</key>
|
|
501
|
+
<string>${upstreamHarnessUrl}/api/forge/psi</string>
|
|
293
502
|
</dict>
|
|
294
503
|
<key>RunAtLoad</key>
|
|
295
504
|
<true/>
|
|
@@ -351,20 +560,31 @@ export async function installSharedRuntime(): Promise<string[]> {
|
|
|
351
560
|
}
|
|
352
561
|
|
|
353
562
|
const startWrapper = path.join(binDir, 'aria-runtime');
|
|
563
|
+
const harnessDaemonWrapper = path.join(binDir, 'aria-harnessd');
|
|
564
|
+
const codexBridgeWrapper = path.join(binDir, 'aria-codex-bridge');
|
|
354
565
|
const doctorWrapper = path.join(binDir, 'aria-runtime-doctor');
|
|
355
566
|
writeWrapper(startWrapper, path.join(runtimeDst, 'service.mjs'));
|
|
567
|
+
writeWrapper(harnessDaemonWrapper, path.join(runtimeDst, 'harness-daemon.mjs'));
|
|
568
|
+
writeWrapper(codexBridgeWrapper, path.join(runtimeDst, 'codex-bridge.mjs'));
|
|
356
569
|
writeWrapper(doctorWrapper, path.join(runtimeDst, 'doctor.mjs'));
|
|
357
570
|
const envPath = writeRuntimeEnv(runtimeDst);
|
|
358
571
|
installDisciplinePack(runtimeDst, logs);
|
|
572
|
+
syncDoctrineTriggerMap(logs);
|
|
359
573
|
installLocalQdrantService(ariaDir, logs);
|
|
574
|
+
retireLegacySoulPortForwardServices(logs);
|
|
575
|
+
installHarnessDaemonSystemdUserService(ariaDir, logs);
|
|
360
576
|
installSystemdUserService(ariaDir, logs);
|
|
577
|
+
installCodexBridgeSystemdUserService(ariaDir, logs);
|
|
361
578
|
installLaunchAgent(ariaDir, logs);
|
|
362
579
|
|
|
363
580
|
logs.push(`Installed shared Aria runtime → ${runtimeDst}`);
|
|
364
581
|
logs.push(`Installed runtime wrapper → ${startWrapper}`);
|
|
582
|
+
logs.push(`Installed harness daemon wrapper → ${harnessDaemonWrapper}`);
|
|
583
|
+
logs.push(`Installed Codex bridge wrapper → ${codexBridgeWrapper}`);
|
|
365
584
|
logs.push(`Installed runtime doctor → ${doctorWrapper}`);
|
|
366
585
|
logs.push(`Installed runtime env → ${envPath}`);
|
|
367
586
|
logs.push('Mount any client against ARIA_RUNTIME_URL=http://127.0.0.1:4319');
|
|
587
|
+
logs.push('Harness packet and local validation are served by aria-harnessd on http://127.0.0.1:8790.');
|
|
368
588
|
logs.push('Local Qdrant memory is mounted at http://127.0.0.1:6333 for garden pulse persistence.');
|
|
369
589
|
logs.push('Runtime lease is encrypted at rest and revalidated against /api/license/heartbeat');
|
|
370
590
|
logs.push('Forge synthesis is relayed through the canonical Aria endpoint unless ARIA_FORGE_SERVICE_URL overrides it.');
|