@aria_asi/cli 0.2.36 → 0.2.37
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/CLIENT-ONBOARDING.md +4 -2
- package/bin/aria.js +11 -7
- package/dist/aria-connector/src/auth.d.ts +14 -0
- package/dist/aria-connector/src/auth.d.ts.map +1 -1
- package/dist/aria-connector/src/auth.js +103 -1
- package/dist/aria-connector/src/auth.js.map +1 -1
- package/dist/aria-connector/src/chat.d.ts.map +1 -1
- package/dist/aria-connector/src/chat.js +13 -8
- package/dist/aria-connector/src/chat.js.map +1 -1
- package/dist/aria-connector/src/config.d.ts +6 -1
- package/dist/aria-connector/src/config.d.ts.map +1 -1
- package/dist/aria-connector/src/config.js.map +1 -1
- package/dist/aria-connector/src/connectors/claude-code.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/claude-code.js +50 -6
- 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 +310 -10
- package/dist/aria-connector/src/connectors/codex.js.map +1 -1
- package/dist/aria-connector/src/connectors/opencode.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/opencode.js +35 -11
- package/dist/aria-connector/src/connectors/opencode.js.map +1 -1
- package/dist/aria-connector/src/connectors/repo-guard.d.ts +10 -0
- package/dist/aria-connector/src/connectors/repo-guard.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/repo-guard.js +110 -164
- package/dist/aria-connector/src/connectors/repo-guard.js.map +1 -1
- package/dist/aria-connector/src/connectors/runtime.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/runtime.js +17 -7
- 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 +12 -8
- package/dist/aria-connector/src/connectors/shell.js.map +1 -1
- package/dist/aria-connector/src/harness-client.d.ts +3 -1
- package/dist/aria-connector/src/harness-client.d.ts.map +1 -1
- package/dist/aria-connector/src/harness-client.js +7 -20
- package/dist/aria-connector/src/harness-client.js.map +1 -1
- package/dist/aria-connector/src/model-context.d.ts.map +1 -1
- package/dist/aria-connector/src/model-context.js +5 -0
- package/dist/aria-connector/src/model-context.js.map +1 -1
- package/dist/aria-connector/src/providers/types.d.ts +1 -1
- package/dist/aria-connector/src/providers/types.d.ts.map +1 -1
- package/dist/aria-connector/src/providers/xai.d.ts +3 -0
- package/dist/aria-connector/src/providers/xai.d.ts.map +1 -0
- package/dist/aria-connector/src/providers/xai.js +40 -0
- package/dist/aria-connector/src/providers/xai.js.map +1 -0
- package/dist/aria-connector/src/setup-wizard.js +1 -0
- package/dist/aria-connector/src/setup-wizard.js.map +1 -1
- package/dist/aria-connector/src/types.d.ts +2 -0
- package/dist/aria-connector/src/types.d.ts.map +1 -1
- package/dist/assets/hooks/aria-cognition-substrate-binding.mjs +51 -9
- package/dist/assets/hooks/aria-first-class-coach.mjs +129 -0
- package/dist/assets/hooks/aria-harness-via-sdk.mjs +33 -6
- package/dist/assets/hooks/aria-pre-tool-gate.mjs +33 -8
- package/dist/assets/hooks/aria-preprompt-consult.mjs +5 -6
- package/dist/assets/hooks/aria-preturn-memory-gate.mjs +5 -0
- package/dist/assets/hooks/aria-repo-doctrine-gate.mjs +15 -0
- package/dist/assets/hooks/aria-stop-gate.mjs +125 -17
- package/dist/assets/hooks/doctrine_trigger_map.json +11 -0
- package/dist/assets/hooks/lib/emergency-gateoff-impl.mjs +39 -0
- package/dist/assets/hooks/lib/emergency-gateoff.mjs +6 -0
- package/dist/assets/hooks/lib/first-class-coach.mjs +755 -0
- package/dist/assets/hooks/lib/skill-autoload-gate-impl.mjs +103 -0
- package/dist/assets/hooks/lib/skill-autoload-gate.mjs +1 -14
- package/dist/assets/opencode-plugins/harness-context/auth-token.mjs +126 -0
- package/dist/assets/opencode-plugins/harness-context/inject-context.mjs +62 -22
- package/dist/assets/opencode-plugins/harness-context/task-project-ledger.mjs +290 -0
- package/dist/assets/opencode-plugins/harness-gate/index.js +87 -27
- package/dist/assets/opencode-plugins/harness-gate/lib/skill-autoload-gate.js +1 -14
- package/dist/assets/opencode-plugins/harness-outcome/index.js +29 -24
- package/dist/assets/opencode-plugins/harness-stop/index.js +229 -68
- package/dist/assets/opencode-plugins/harness-stop/lib/skill-autoload-gate.js +1 -14
- package/dist/runtime/auth-token.mjs +121 -0
- package/dist/runtime/coach-kernel.mjs +371 -0
- package/dist/runtime/codex-bridge.mjs +440 -69
- package/dist/runtime/discipline/doctrine_trigger_map.json +11 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-essence/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-forge-guardrails/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-repo-doctrine/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/forge-quality-rules/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/ghazali-8lens/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/istiqra-induction/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/ladunni-22/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/mizan/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/nadia/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/nadia-psi/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/predictor/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/qiyas-analogy/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/soul-domains/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-intra-phase/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-post-phase/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-pre-phase/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-deploy/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-no-stripping/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-onboarding/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-output-discipline/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-substrate-binding/SKILL.md +18 -0
- package/dist/runtime/doctrine_trigger_map.json +11 -0
- package/dist/runtime/hooks/aria-cognition-substrate-binding.mjs +51 -9
- package/dist/runtime/hooks/aria-first-class-coach.mjs +129 -0
- package/dist/runtime/hooks/aria-harness-via-sdk.mjs +33 -6
- package/dist/runtime/hooks/aria-pre-tool-gate.mjs +33 -8
- package/dist/runtime/hooks/aria-preprompt-consult.mjs +5 -6
- package/dist/runtime/hooks/aria-preturn-memory-gate.mjs +5 -0
- package/dist/runtime/hooks/aria-repo-doctrine-gate.mjs +15 -0
- package/dist/runtime/hooks/aria-stop-gate.mjs +125 -17
- package/dist/runtime/hooks/doctrine_trigger_map.json +11 -0
- package/dist/runtime/hooks/lib/emergency-gateoff-impl.mjs +39 -0
- package/dist/runtime/hooks/lib/emergency-gateoff.mjs +6 -0
- package/dist/runtime/hooks/lib/first-class-coach.mjs +755 -0
- package/dist/runtime/hooks/lib/skill-autoload-gate-impl.mjs +103 -0
- package/dist/runtime/hooks/lib/skill-autoload-gate.mjs +1 -14
- package/dist/runtime/local-phase.mjs +8 -0
- package/dist/runtime/manifest.json +2 -2
- package/dist/runtime/provider-proxy.mjs +136 -33
- package/dist/runtime/sdk/BUNDLED.json +2 -2
- package/dist/runtime/sdk/auth.d.ts +17 -0
- package/dist/runtime/sdk/auth.js +158 -0
- package/dist/runtime/sdk/auth.js.map +1 -0
- package/dist/runtime/sdk/index.d.ts +8 -1
- package/dist/runtime/sdk/index.js +15 -1
- package/dist/runtime/sdk/index.js.map +1 -1
- package/dist/runtime/service.mjs +1711 -74
- package/dist/runtime/task-project-ledger.mjs +290 -0
- package/dist/sdk/BUNDLED.json +2 -2
- package/dist/sdk/auth.d.ts +17 -0
- package/dist/sdk/auth.js +158 -0
- package/dist/sdk/auth.js.map +1 -0
- package/dist/sdk/index.d.ts +8 -1
- package/dist/sdk/index.js +15 -1
- package/dist/sdk/index.js.map +1 -1
- package/hooks/aria-cognition-substrate-binding.mjs +51 -9
- package/hooks/aria-first-class-coach.mjs +129 -0
- package/hooks/aria-harness-via-sdk.mjs +33 -6
- package/hooks/aria-pre-tool-gate.mjs +33 -8
- package/hooks/aria-preprompt-consult.mjs +5 -6
- package/hooks/aria-preturn-memory-gate.mjs +5 -0
- package/hooks/aria-repo-doctrine-gate.mjs +15 -0
- package/hooks/aria-stop-gate.mjs +125 -17
- package/hooks/doctrine_trigger_map.json +11 -0
- package/hooks/lib/emergency-gateoff-impl.mjs +39 -0
- package/hooks/lib/emergency-gateoff.mjs +6 -0
- package/hooks/lib/first-class-coach.mjs +755 -0
- package/hooks/lib/skill-autoload-gate-impl.mjs +103 -0
- package/hooks/lib/skill-autoload-gate.mjs +1 -14
- package/opencode-plugins/harness-context/auth-token.mjs +126 -0
- package/opencode-plugins/harness-context/inject-context.mjs +62 -22
- package/opencode-plugins/harness-context/task-project-ledger.mjs +290 -0
- package/opencode-plugins/harness-gate/index.js +87 -27
- package/opencode-plugins/harness-gate/lib/skill-autoload-gate.js +1 -14
- package/opencode-plugins/harness-outcome/index.js +29 -24
- package/opencode-plugins/harness-stop/index.js +229 -68
- package/opencode-plugins/harness-stop/lib/skill-autoload-gate.js +1 -14
- package/package.json +8 -2
- package/runtime-src/auth-token.mjs +121 -0
- package/runtime-src/coach-kernel.mjs +371 -0
- package/runtime-src/codex-bridge.mjs +440 -69
- package/runtime-src/local-phase.mjs +8 -0
- package/runtime-src/provider-proxy.mjs +136 -33
- package/runtime-src/service.mjs +1711 -74
- package/scripts/bundle-sdk.mjs +8 -0
- package/scripts/check-client-compatibility.mjs +422 -0
- package/scripts/check-coach-kernel.mjs +204 -0
- package/scripts/check-managed-runtime-ledger.mjs +107 -0
- package/scripts/check-opencode-config-contract.mjs +78 -0
- package/scripts/check-quality-ledger.mjs +121 -0
- package/scripts/self-test-harness-gates.mjs +179 -11
- package/scripts/self-test-repo-guard.mjs +38 -0
- package/scripts/validate-skill-prompts.mjs +14 -1
- package/skills/aria-cognition/aria-essence/SKILL.md +18 -0
- package/skills/aria-cognition/aria-forge-guardrails/SKILL.md +18 -0
- package/skills/aria-cognition/aria-repo-doctrine/SKILL.md +18 -0
- package/skills/aria-cognition/forge-quality-rules/SKILL.md +18 -0
- package/skills/aria-cognition/ghazali-8lens/SKILL.md +18 -0
- package/skills/aria-cognition/istiqra-induction/SKILL.md +18 -0
- package/skills/aria-cognition/ladunni-22/SKILL.md +18 -0
- package/skills/aria-cognition/mizan/SKILL.md +18 -0
- package/skills/aria-cognition/nadia/SKILL.md +18 -0
- package/skills/aria-cognition/nadia-psi/SKILL.md +18 -0
- package/skills/aria-cognition/predictor/SKILL.md +18 -0
- package/skills/aria-cognition/qiyas-analogy/SKILL.md +18 -0
- package/skills/aria-cognition/soul-domains/SKILL.md +18 -0
- package/src/auth.ts +136 -1
- package/src/chat.ts +13 -8
- package/src/config.ts +6 -1
- package/src/connectors/claude-code.ts +62 -18
- package/src/connectors/codex.ts +308 -10
- package/src/connectors/opencode.ts +35 -12
- package/src/connectors/repo-guard.ts +117 -172
- package/src/connectors/runtime.ts +19 -7
- package/src/connectors/shell.ts +12 -8
- package/src/harness-client.ts +8 -22
- package/src/model-context.ts +6 -0
- package/src/providers/types.ts +1 -1
- package/src/providers/xai.ts +55 -0
- package/src/setup-wizard.ts +1 -0
- package/src/types.ts +2 -0
|
@@ -47,8 +47,9 @@
|
|
|
47
47
|
// Future: signed-grant override mechanism at ~/.aria/owner-overrides/<hook>.json
|
|
48
48
|
// with HMAC signature using a secret only Hamza holds. Deferred to next session.
|
|
49
49
|
|
|
50
|
-
import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
50
|
+
import { appendFileSync, readFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
51
51
|
import { dirname } from 'node:path';
|
|
52
|
+
import { createHash } from 'node:crypto';
|
|
52
53
|
import { spawnSync } from 'node:child_process';
|
|
53
54
|
import { appendGateAudit } from './lib/gate-audit.mjs';
|
|
54
55
|
import {
|
|
@@ -61,6 +62,7 @@ import { registerGateBlock } from './lib/gate-loop-state.mjs';
|
|
|
61
62
|
import { collectTurnWindowFromMessages } from './lib/hook-message-window.mjs';
|
|
62
63
|
import { analyzeDomainOutputQuality } from './lib/domain-output-quality.mjs';
|
|
63
64
|
import { evaluateSkillGate, formatSkillGateBlock } from './lib/skill-autoload-gate.mjs';
|
|
65
|
+
import { emergencyGateOffDecision } from './lib/emergency-gateoff.mjs';
|
|
64
66
|
|
|
65
67
|
const HOME = process.env.HOME || '/tmp';
|
|
66
68
|
const RUNTIME_BASE_URL =
|
|
@@ -71,6 +73,15 @@ const AUDIT_PATH = `${HOME}/.claude/aria-stop-gate-audit.jsonl`;
|
|
|
71
73
|
const GATE_LOOP_STATE_PATH = `${HOME}/.claude/.aria-gate-loop-state.json`;
|
|
72
74
|
const MIZAN_RECEIPT_DIR = `${HOME}/.claude/.aria-mizan-receipts`;
|
|
73
75
|
const GOVERNANCE_GATE_PATH = `${HOME}/.aria/bin/aria-governance-gate`;
|
|
76
|
+
const CURRENT_RECOVERY_PATH = `${HOME}/.aria/governance-recovery-current.json`;
|
|
77
|
+
const HANDOFF_MODE_RX = /\b(?:post[_ -]?compact[_ -]?continuation|handoff[_ -]?resume|continuation[_ -]?handoff|post-compact|compact(?:ion)? handoff|post\s+commission)\b/i;
|
|
78
|
+
const HANDOFF_REQUIRED_FIELDS = [
|
|
79
|
+
{ label: 'current objective', rx: /\bcurrent\s+objective\b\s*:/i },
|
|
80
|
+
{ label: 'known blockers', rx: /\bknown\s+blockers\b\s*:/i },
|
|
81
|
+
{ label: 'next executable step', rx: /\bnext\s+executable\s+step\b\s*:/i },
|
|
82
|
+
{ label: 'what not to touch', rx: /\bwhat\s+not\s+to\s+touch\b\s*:/i },
|
|
83
|
+
{ label: 'verification already run', rx: /\bverification\s+already\s+run\b\s*:/i },
|
|
84
|
+
];
|
|
74
85
|
|
|
75
86
|
function runUniversalGovernanceGate(payload) {
|
|
76
87
|
if (!existsSync(GOVERNANCE_GATE_PATH)) return null;
|
|
@@ -84,11 +95,49 @@ function runUniversalGovernanceGate(payload) {
|
|
|
84
95
|
try { result = stdout ? JSON.parse(stdout) : null; } catch {}
|
|
85
96
|
if (child.status !== 0 || result?.ok === false || result?.decision === 'block') {
|
|
86
97
|
const reason = stdout || child.stderr || 'aria-governance-gate blocked this output.';
|
|
87
|
-
throw new Error(
|
|
98
|
+
throw new Error([
|
|
99
|
+
'=== ARIA UNIVERSAL GOVERNANCE GATE BLOCK ===',
|
|
100
|
+
'',
|
|
101
|
+
reason,
|
|
102
|
+
'',
|
|
103
|
+
'Recovery contract:',
|
|
104
|
+
'1. Do not retry the same blocked output unchanged.',
|
|
105
|
+
'2. Load or apply the doctrine/skill named by the governance output.',
|
|
106
|
+
'3. Re-write the output with <applied_cognition> and concrete proof.',
|
|
107
|
+
'4. Re-test by submitting the revised output through this same gate.',
|
|
108
|
+
].join('\n'));
|
|
109
|
+
}
|
|
110
|
+
if (result?.decision === 'warn' || result?.governanceMode === 'recovery-required' || result?.governanceMode === 'architectural-intervention-required') {
|
|
111
|
+
process.stderr.write(`[aria-governance:${result.governanceMode || 'recovery-required'}] ${JSON.stringify(result)}\n`);
|
|
88
112
|
}
|
|
89
113
|
return result;
|
|
90
114
|
}
|
|
91
115
|
|
|
116
|
+
function classifyContinuationHandoff(text) {
|
|
117
|
+
const body = String(text || '');
|
|
118
|
+
const isContinuation = HANDOFF_MODE_RX.test(body);
|
|
119
|
+
const missingFields = HANDOFF_REQUIRED_FIELDS.filter((field) => !field.rx.test(body)).map((field) => field.label);
|
|
120
|
+
return { isContinuation, ok: isContinuation && missingFields.length === 0, missingFields };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function formatHandoffRecovery(missingFields = []) {
|
|
124
|
+
return [
|
|
125
|
+
'=== ARIA LOCAL OUTPUT BLOCK ===',
|
|
126
|
+
'',
|
|
127
|
+
`post-compact continuation handoff malformed: missing fields: ${missingFields.join(', ') || '(none)'}`,
|
|
128
|
+
'',
|
|
129
|
+
'Recovery contract:',
|
|
130
|
+
'1. Do not retry the same blocked text.',
|
|
131
|
+
'2. Rewrite the output using this exact shape:',
|
|
132
|
+
'post_compact_continuation',
|
|
133
|
+
'current objective: <one sentence of the still-active task>',
|
|
134
|
+
'known blockers: <specific blockers, or "none verified" if truly none>',
|
|
135
|
+
'next executable step: <single command/edit/read/action the next agent should run first>',
|
|
136
|
+
'what not to touch: <unrelated dirty files, secrets, protected systems, or deploys to avoid>',
|
|
137
|
+
'verification already run: <commands/probes already run and exact result, or "not run">',
|
|
138
|
+
].join('\n');
|
|
139
|
+
}
|
|
140
|
+
|
|
92
141
|
// SDK loader — bundled at ~/.aria/sdk by `aria connect`, with client-local
|
|
93
142
|
// fallbacks preserved for resilience.
|
|
94
143
|
// All control-plane fetches (validateOutput, gardenTurn) route through the
|
|
@@ -442,6 +491,12 @@ function buildForceReauthorReason({
|
|
|
442
491
|
rewritten ? `\nMIZAN REWRITE SEED:\n${rewritten}` : '',
|
|
443
492
|
recipeAddendum || '',
|
|
444
493
|
'',
|
|
494
|
+
'Recovery contract:',
|
|
495
|
+
'1. Do not retry the same blocked text unchanged.',
|
|
496
|
+
'2. Apply the teaching above to the next draft before re-emitting.',
|
|
497
|
+
'3. Re-test by submitting the revised output through this same gate.',
|
|
498
|
+
'4. If the blocker is stale state, name the stale state and clear or repair it before retrying.',
|
|
499
|
+
'',
|
|
445
500
|
'REQUIRED REDO SHAPE:',
|
|
446
501
|
'1. One sentence: the failed mechanism, not an apology.',
|
|
447
502
|
'2. Evidence checked: file/line, command output, endpoint response, or explicit "unverified".',
|
|
@@ -472,6 +527,50 @@ function buildForceReauthorReason({
|
|
|
472
527
|
].filter(Boolean).join('\n');
|
|
473
528
|
}
|
|
474
529
|
|
|
530
|
+
function recoveryFingerprint(reason, source = 'stop-gate') {
|
|
531
|
+
return createHash('sha256')
|
|
532
|
+
.update([source, String(reason || '').replace(/\s+/g, ' ').trim().slice(0, 1200)].join('\0'))
|
|
533
|
+
.digest('hex');
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
function emitRecoverableStopGate(reason, { source = 'stop-gate', sessionId = gateSessionId } = {}) {
|
|
537
|
+
const fingerprint = recoveryFingerprint(reason, source);
|
|
538
|
+
const recovery = {
|
|
539
|
+
schema: 'aria.governance_recovery_current.v1',
|
|
540
|
+
updatedAt: new Date().toISOString(),
|
|
541
|
+
deliveryRule: 'This file is injected into the next system prompt. Execute recoveryLoop.nextStep before any completion claim.',
|
|
542
|
+
ok: true,
|
|
543
|
+
decision: 'warn',
|
|
544
|
+
source: 'aria-stop-gate',
|
|
545
|
+
governanceMode: 'recovery-required',
|
|
546
|
+
recoveryLoop: {
|
|
547
|
+
fingerprint,
|
|
548
|
+
allowedRecoveryAttempts: 1,
|
|
549
|
+
priorRecoveryAttempts: 0,
|
|
550
|
+
remainingRecoveryAttempts: 1,
|
|
551
|
+
nextStep: 'Re-author the blocked output using the recovery contract, load required skills if named, run a concrete verification probe when tools are available, then emit the corrected output.',
|
|
552
|
+
architectFallback: 'If Aria consult is unavailable or this same fingerprint repeats, use the strongest available client LLM under the architect harness, produce and execute the recovery plan, then verify.',
|
|
553
|
+
},
|
|
554
|
+
recoveryContract: {
|
|
555
|
+
retry: 'One recovery attempt is allowed for this exact output-gate fingerprint; repeat failure enters architect execution mode.',
|
|
556
|
+
architectMode: 'On repeat, load architecture-decision and the named domain skills, define the smallest executable plan, execute the first recovery action, and verify before output.',
|
|
557
|
+
fallbackWhenAriaUnavailable: 'Do not stop or ask the owner to fix it. Bind the strongest available client LLM to the architect harness, give it this JSON contract and failed evidence, execute its recovery plan, then verify.',
|
|
558
|
+
repairRecoveryCycle: ['re-author output according to the gate reason', 'verify the corrected claim or state explicit unverified boundary'],
|
|
559
|
+
retest: 'Submit the revised output through the same stop gate and run the concrete verification probe named by the recovery plan.',
|
|
560
|
+
blockedReason: reason,
|
|
561
|
+
},
|
|
562
|
+
};
|
|
563
|
+
try {
|
|
564
|
+
mkdirSync(dirname(CURRENT_RECOVERY_PATH), { recursive: true, mode: 0o700 });
|
|
565
|
+
writeFileSync(CURRENT_RECOVERY_PATH, `${JSON.stringify(recovery, null, 2)}\n`, { mode: 0o600 });
|
|
566
|
+
} catch (error) {
|
|
567
|
+
audit('recovery-state-write-failed', error instanceof Error ? error.message : String(error));
|
|
568
|
+
}
|
|
569
|
+
audit('recovery-required-output-gate', `${source} ${fingerprint}`);
|
|
570
|
+
console.log(JSON.stringify({ decision: 'allow', recoveryRequired: recovery }));
|
|
571
|
+
process.exit(0);
|
|
572
|
+
}
|
|
573
|
+
|
|
475
574
|
// Lens substance check — same constants as aria-pre-tool-gate.mjs.
|
|
476
575
|
// Hamza directive 2026-04-28: all 8 canonical lenses required, not 4-of-8.
|
|
477
576
|
const REQUIRED_LENSES = 8;
|
|
@@ -517,6 +616,11 @@ try {
|
|
|
517
616
|
audit('allow-parse-error', 'stdin not JSON');
|
|
518
617
|
process.exit(0);
|
|
519
618
|
}
|
|
619
|
+
const emergencyGateOff = emergencyGateOffDecision(event);
|
|
620
|
+
if (emergencyGateOff.off) {
|
|
621
|
+
audit('allow-emergency-gateoff', `reason=${emergencyGateOff.reason}`);
|
|
622
|
+
process.exit(0);
|
|
623
|
+
}
|
|
520
624
|
const gateSessionId = String(event.session_id || 'claude-code').replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
521
625
|
const sessionMizanState = loadMizanReceiptState(event.session_id || 'claude-code');
|
|
522
626
|
|
|
@@ -616,8 +720,7 @@ if (userCorrectionViolation) {
|
|
|
616
720
|
lensCount: 0,
|
|
617
721
|
requiredLenses: REQUIRED_LENSES,
|
|
618
722
|
});
|
|
619
|
-
|
|
620
|
-
process.exit(2);
|
|
723
|
+
emitRecoverableStopGate(reason, { source: 'stop/user-correction', sessionId: gateSessionId });
|
|
621
724
|
}
|
|
622
725
|
|
|
623
726
|
// Triviality check — same as eight-lens-detector.ts
|
|
@@ -640,6 +743,17 @@ if (!triggered) {
|
|
|
640
743
|
process.exit(0);
|
|
641
744
|
}
|
|
642
745
|
|
|
746
|
+
const handoff = classifyContinuationHandoff(assistantText);
|
|
747
|
+
if (handoff.isContinuation) {
|
|
748
|
+
if (handoff.ok) {
|
|
749
|
+
audit('allow-post-compact-continuation', `chars=${assistantText.length}`);
|
|
750
|
+
await fireGardenTurn(event.session_id || 'claude-code', lastUserMessage, assistantText);
|
|
751
|
+
process.exit(0);
|
|
752
|
+
}
|
|
753
|
+
audit('block-post-compact-continuation', `missing=${handoff.missingFields.join(',')}`);
|
|
754
|
+
emitRecoverableStopGate(formatHandoffRecovery(handoff.missingFields), { source: 'stop/post-compact-continuation', sessionId: gateSessionId });
|
|
755
|
+
}
|
|
756
|
+
|
|
643
757
|
const stopSkillGate = evaluateSkillGate({
|
|
644
758
|
sessionId: event.session_id || 'claude-code',
|
|
645
759
|
surface: 'claude-stop-gate',
|
|
@@ -647,7 +761,7 @@ const stopSkillGate = evaluateSkillGate({
|
|
|
647
761
|
isOutputCloseout: true,
|
|
648
762
|
autoLoadAvailable: false,
|
|
649
763
|
});
|
|
650
|
-
if (!stopSkillGate.ok) {
|
|
764
|
+
if (!stopSkillGate.ok && !stopSkillGate.redirectOnly) {
|
|
651
765
|
audit('block-missing-skill-receipt', `missing=${stopSkillGate.missingSkills.join(',')} chars=${assistantText.length}`);
|
|
652
766
|
const reason = withLoopDirective(buildForceReauthorReason({
|
|
653
767
|
source: 'stop/skill-autoload',
|
|
@@ -656,8 +770,7 @@ if (!stopSkillGate.ok) {
|
|
|
656
770
|
lensCount: 0,
|
|
657
771
|
requiredLenses: REQUIRED_LENSES,
|
|
658
772
|
}), `stop:skill-autoload:${stopSkillGate.missingSkills.join(',')}`, gateSessionId);
|
|
659
|
-
|
|
660
|
-
process.exit(2);
|
|
773
|
+
emitRecoverableStopGate(reason, { source: 'stop/skill-autoload', sessionId: gateSessionId });
|
|
661
774
|
}
|
|
662
775
|
try {
|
|
663
776
|
runUniversalGovernanceGate({
|
|
@@ -678,8 +791,7 @@ try {
|
|
|
678
791
|
lensCount: 0,
|
|
679
792
|
requiredLenses: REQUIRED_LENSES,
|
|
680
793
|
}), 'stop:universal-governance', gateSessionId);
|
|
681
|
-
|
|
682
|
-
process.exit(2);
|
|
794
|
+
emitRecoverableStopGate(reason, { source: 'stop/universal-governance', sessionId: gateSessionId });
|
|
683
795
|
}
|
|
684
796
|
|
|
685
797
|
// Non-trivial response — require substantive cognition.
|
|
@@ -712,8 +824,7 @@ if (cog.count < REQUIRED_LENSES) {
|
|
|
712
824
|
codeCount: 0,
|
|
713
825
|
implCouplingCount: 0,
|
|
714
826
|
});
|
|
715
|
-
|
|
716
|
-
process.exit(2);
|
|
827
|
+
emitRecoverableStopGate(reason, { source: 'stop/no-cognition', sessionId: gateSessionId });
|
|
717
828
|
}
|
|
718
829
|
|
|
719
830
|
// Question-emission visibility (Phase 11 promotes to block-mode):
|
|
@@ -1596,8 +1707,7 @@ if (cog.count >= REQUIRED_LENSES) {
|
|
|
1596
1707
|
codeCount: codeQualityHits.length,
|
|
1597
1708
|
implCouplingCount: implCouplingHits.length,
|
|
1598
1709
|
});
|
|
1599
|
-
|
|
1600
|
-
process.exit(2);
|
|
1710
|
+
emitRecoverableStopGate(reason, { source: 'stop/output-quality', sessionId: gateSessionId });
|
|
1601
1711
|
}
|
|
1602
1712
|
|
|
1603
1713
|
audit('allow-output-qc',
|
|
@@ -1752,8 +1862,7 @@ if (hadNonTrivialAction && (!dalioExpectedMatch || !dalioHasMeasurablePredicate)
|
|
|
1752
1862
|
codeCount: 0,
|
|
1753
1863
|
implCouplingCount: 0,
|
|
1754
1864
|
});
|
|
1755
|
-
|
|
1756
|
-
process.exit(2);
|
|
1865
|
+
emitRecoverableStopGate(missingReason, { source: 'stop/dalio-expected', sessionId: gateSessionId });
|
|
1757
1866
|
}
|
|
1758
1867
|
|
|
1759
1868
|
// Dalio ledger write — fire-and-forget HTTP POST + local JSONL mirror.
|
|
@@ -1878,5 +1987,4 @@ emitHarnessFooter({
|
|
|
1878
1987
|
codeCount: 0,
|
|
1879
1988
|
implCouplingCount: 0,
|
|
1880
1989
|
});
|
|
1881
|
-
|
|
1882
|
-
process.exit(2);
|
|
1990
|
+
emitRecoverableStopGate(buildForceReauthorReason({ source: 'stop/lens-missing', reason, lensCount: cog.count, requiredLenses: REQUIRED_LENSES }), { source: 'stop/lens-missing', sessionId: gateSessionId });
|
|
@@ -572,6 +572,17 @@
|
|
|
572
572
|
"teaching": "A service without a K8s manifest is not deployed — it's aspirational code. Every service in the registry must have a canonical k8s/<service>.yaml manifest. Without it, kubectl apply cannot restore the service after cluster restart.",
|
|
573
573
|
"counter_action": "Create the canonical K8s manifest (Deployment + Service + liveness probe) at k8s/<service>.yaml. Register the service in k8s/service-registry.json. Never deploy via ad-hoc kubectl run or docker run — only via a version-controlled manifest.",
|
|
574
574
|
"message": "Service lacks K8s manifest — see feedback_registry_image_drift.md"
|
|
575
|
+
},
|
|
576
|
+
{
|
|
577
|
+
"trigger_id": "containment_only_production_fix",
|
|
578
|
+
"trigger": "\\b(?:containment[- ]?only|only[- ]?contain(?:ed|ment)|just[- ]?contain(?:ed|ment))\\b|\\b(?:surface|cosmetic|appearance[- ]?only|form[- ]?only)\\s+(?:fix|repair|change)\\b|\\b(?:fix|repair|change)\\s+(?:only\\s+)?(?:the\\s+)?(?:surface|cosmetic|appearance|form)\\b|\\b(?:just|only|merely)\\s+(?:silence|satisfy|appease)\\s+(?:the\\s+)?(?:gate|hook|validator)\\b",
|
|
579
|
+
"rx": "\\b(?:containment[- ]?only|only[- ]?contain(?:ed|ment)|just[- ]?contain(?:ed|ment))\\b|\\b(?:surface|cosmetic|appearance[- ]?only|form[- ]?only)\\s+(?:fix|repair|change)\\b|\\b(?:fix|repair|change)\\s+(?:only\\s+)?(?:the\\s+)?(?:surface|cosmetic|appearance|form)\\b|\\b(?:just|only|merely)\\s+(?:silence|satisfy|appease)\\s+(?:the\\s+)?(?:gate|hook|validator)\\b",
|
|
580
|
+
"doctrine": "memory:feedback_gates_enforce_form_not_substance.md",
|
|
581
|
+
"memory": "feedback_gates_enforce_form_not_substance.md",
|
|
582
|
+
"severity": "block",
|
|
583
|
+
"teaching": "Containment-only production fixes are rationalized bypasses when they intentionally leave the broken user-visible mechanism unrepaired. Small source-level fixes are acceptable when they repair the root mechanism and are verified.",
|
|
584
|
+
"counter_action": "Keep the smallest correct change, but tie it to the root mechanism, observable recovery or proof, and user-visible verification; do not only silence gates or change cosmetics.",
|
|
585
|
+
"message": "Containment-only production fix detected. Preserve smallest-correct-change discipline, but replace cosmetic containment with root-mechanism repair plus observable recovery and proof."
|
|
575
586
|
}
|
|
576
587
|
]
|
|
577
588
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
|
|
5
|
+
const GATEOFF_ENV_RX = /^(?:1|true|yes|on)$/i;
|
|
6
|
+
const GATEOFF_PHRASE_RX = /\bGATEOFF\b/;
|
|
7
|
+
|
|
8
|
+
export const gateOffMarkerPath = join(homedir(), '.aria', 'gates-off.manual');
|
|
9
|
+
|
|
10
|
+
function textFromPayload(payload) {
|
|
11
|
+
if (!payload) return '';
|
|
12
|
+
if (typeof payload === 'string') return payload;
|
|
13
|
+
try { return JSON.stringify(payload); } catch { return String(payload); }
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function persistEmergencyGateOff(reason = 'phrase') {
|
|
17
|
+
mkdirSync(dirname(gateOffMarkerPath), { recursive: true, mode: 0o700 });
|
|
18
|
+
writeFileSync(gateOffMarkerPath, JSON.stringify({
|
|
19
|
+
disabled: true,
|
|
20
|
+
reason,
|
|
21
|
+
disabledAt: new Date().toISOString(),
|
|
22
|
+
reenable: 'Manual owner action only: remove this marker and unset ARIA_GATES_OFF/ARIA_HARNESS_GATES_OFF.',
|
|
23
|
+
}, null, 2) + '\n', { mode: 0o600 });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function detectEmergencyGateOff(payload = '') {
|
|
27
|
+
if (GATEOFF_ENV_RX.test(String(process.env.ARIA_GATES_OFF || process.env.ARIA_HARNESS_GATES_OFF || ''))) {
|
|
28
|
+
return { off: true, reason: 'env' };
|
|
29
|
+
}
|
|
30
|
+
if (existsSync(gateOffMarkerPath)) return { off: true, reason: 'marker' };
|
|
31
|
+
if (GATEOFF_PHRASE_RX.test(textFromPayload(payload))) return { off: true, reason: 'phrase' };
|
|
32
|
+
return { off: false, reason: null };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function emergencyGateOffDecision(payload = '') {
|
|
36
|
+
const decision = detectEmergencyGateOff(payload);
|
|
37
|
+
if (decision.off && decision.reason === 'phrase') persistEmergencyGateOff('phrase');
|
|
38
|
+
return decision;
|
|
39
|
+
}
|