@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
|
@@ -109,7 +109,27 @@ const HARNESS_URL =
|
|
|
109
109
|
process.env.ARIA_HARNESS_BASE_URL ||
|
|
110
110
|
process.env.ARIA_HARNESS_URL ||
|
|
111
111
|
'https://harness.ariasos.com';
|
|
112
|
-
|
|
112
|
+
function resolveHarnessToken() {
|
|
113
|
+
if (process.env.ARIA_HARNESS_TOKEN) return process.env.ARIA_HARNESS_TOKEN;
|
|
114
|
+
if (process.env.ARIA_API_KEY) return process.env.ARIA_API_KEY;
|
|
115
|
+
if (process.env.ARIA_MASTER_TOKEN) return process.env.ARIA_MASTER_TOKEN;
|
|
116
|
+
try {
|
|
117
|
+
if (existsSync(OWNER_TOKEN_PATH)) {
|
|
118
|
+
const token = readFileSync(OWNER_TOKEN_PATH, 'utf8').trim();
|
|
119
|
+
if (token) return token;
|
|
120
|
+
}
|
|
121
|
+
} catch {}
|
|
122
|
+
try {
|
|
123
|
+
const licensePath = `${HOME}/.aria/license.json`;
|
|
124
|
+
if (existsSync(licensePath)) {
|
|
125
|
+
const license = JSON.parse(readFileSync(licensePath, 'utf8'));
|
|
126
|
+
if (license.harnessToken) return String(license.harnessToken).trim();
|
|
127
|
+
if (license.token) return String(license.token).trim();
|
|
128
|
+
}
|
|
129
|
+
} catch {}
|
|
130
|
+
return '';
|
|
131
|
+
}
|
|
132
|
+
const HARNESS_TOKEN = resolveHarnessToken();
|
|
113
133
|
const MIN_PROMPT_CHARS = 40; // skip auto-consult on trivial prompts
|
|
114
134
|
const MAX_DIRECTION_CHARS = 4000; // cap injected chunk size
|
|
115
135
|
|
|
@@ -248,6 +268,8 @@ Respond with EXACTLY this JSON shape:
|
|
|
248
268
|
"successCriterion": "<observable signal of completion>",
|
|
249
269
|
"abortCriterion": "<observable signal of failure>",
|
|
250
270
|
"doctrineRefs": ["<memory_filename.md>", ...],
|
|
271
|
+
"cognitionUse": "<how Aria cognition should change the executor's tool/input/output shape for this phase>",
|
|
272
|
+
"evidenceRequired": ["<observable proof the executor must collect before reporting complete>"],
|
|
251
273
|
"allowedActions": ["read", "edit:<path-pattern>", "kubectl_get", "consult", "bash_safe", "..."],
|
|
252
274
|
"forbiddenActions": ["kubectl_apply", "edit:<path-pattern>", "..."]
|
|
253
275
|
}
|
|
@@ -259,7 +281,9 @@ Respond with EXACTLY this JSON shape:
|
|
|
259
281
|
}
|
|
260
282
|
}
|
|
261
283
|
|
|
262
|
-
Apply your 8 lenses + substrate. Phases are ordered + small (one logical step each). Doctrine refs cite memory files in /home/hamzaibrahim1/.claude/projects/-home-hamzaibrahim1/memory/. Be specific in allowedActions / forbiddenActions — Claude can ONLY do what's allowed for the current phase
|
|
284
|
+
Apply your 8 lenses + substrate. Phases are ordered + small (one logical step each). Doctrine refs cite memory files in /home/hamzaibrahim1/.claude/projects/-home-hamzaibrahim1/memory/. Be specific in allowedActions / forbiddenActions — Claude can ONLY do what's allowed for the current phase.
|
|
285
|
+
|
|
286
|
+
Every phase must include cognitionUse and evidenceRequired. cognitionUse tells Claude how Aria's cognition should improve the actual tool input, edit shape, review scope, or final output. evidenceRequired tells Claude what observation must be collected before reporting the phase complete.` : `Pre-prompt direction request from Claude orchestrator.
|
|
263
287
|
|
|
264
288
|
The user just submitted this prompt:
|
|
265
289
|
|
|
@@ -280,6 +304,8 @@ thinking from training reflex. Be concrete:
|
|
|
280
304
|
(NOT a reflexive "want me to" deferral).
|
|
281
305
|
4. Mizan check: any risk patterns in this prompt — over-scope creep,
|
|
282
306
|
over-replacement temptation, tier-substitution temptation, etc.
|
|
307
|
+
5. How should Aria cognition improve Claude's actual input/output shape —
|
|
308
|
+
what should be more specific, safer, more evidence-bound, or differently scoped?
|
|
283
309
|
|
|
284
310
|
Keep direction under 1500 chars. This is the pre-load context for Claude's
|
|
285
311
|
turn — not the final response. Claude will still emit cognition + action;
|
|
@@ -56,6 +56,30 @@ function auditLog(decision, summary, sessionId) {
|
|
|
56
56
|
appendFileSync(GATE_LOG, `${new Date().toISOString()} [${sessionId}] ${decision} ${summary}\n`);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
function buildForceRedoActionReason({ source, reason, missingSignals = [], incidents = [] }) {
|
|
60
|
+
return [
|
|
61
|
+
'=== ARIA FORCE_REDO_ACTION ===',
|
|
62
|
+
`source: ${source}`,
|
|
63
|
+
`reason: ${reason}`,
|
|
64
|
+
'',
|
|
65
|
+
'This is not a terminal error. It is a forced redo instruction before action execution.',
|
|
66
|
+
'Do not proceed with tools from unloaded context. Load/repair substrate first, then retry the action.',
|
|
67
|
+
'',
|
|
68
|
+
'TEACHING:',
|
|
69
|
+
'- Every action turn must begin from Aria substrate, not improvised memory.',
|
|
70
|
+
'- Blocking incidents are Dalio failure deltas; they must be fixed and marked resolved before new action.',
|
|
71
|
+
'- Missing harness/direction/memory signals mean the context-loader path must run before retry.',
|
|
72
|
+
missingSignals.length ? `\nMISSING SIGNALS:\n${missingSignals.map((signal) => `- ${signal}`).join('\n')}` : '',
|
|
73
|
+
incidents.length ? `\nINCIDENTS TO RESOLVE:\n${incidents.map((incident) => `- ${incident}`).join('\n')}` : '',
|
|
74
|
+
'',
|
|
75
|
+
'REQUIRED REDO SHAPE:',
|
|
76
|
+
'1. Run the structured recovery action in hookSpecificOutput.recovery.',
|
|
77
|
+
'2. Verify harness_packet, aria_direction/binding_plan, and memory references are loaded.',
|
|
78
|
+
'3. Retry the original action only after the missing context or incidents are resolved.',
|
|
79
|
+
'=== END FORCE_REDO_ACTION ===',
|
|
80
|
+
].filter(Boolean).join('\n');
|
|
81
|
+
}
|
|
82
|
+
|
|
59
83
|
// ── Turn-state deduplication ──────────────────────────────────────────
|
|
60
84
|
const TURN_DEDUP_WINDOW_MS = 60_000; // 60s
|
|
61
85
|
|
|
@@ -105,6 +129,37 @@ function readAnyJsonArtifact(filePath) {
|
|
|
105
129
|
};
|
|
106
130
|
}
|
|
107
131
|
|
|
132
|
+
function unwrapHarnessPacketEnvelope(value) {
|
|
133
|
+
let current = value;
|
|
134
|
+
for (let depth = 0; depth < 3; depth++) {
|
|
135
|
+
if (!current || typeof current !== 'object' || Array.isArray(current)) break;
|
|
136
|
+
const nested = current.packet;
|
|
137
|
+
if (!nested || typeof nested !== 'object' || Array.isArray(nested)) break;
|
|
138
|
+
if (typeof current.timestamp !== 'string' && typeof current.version !== 'string') break;
|
|
139
|
+
current = nested;
|
|
140
|
+
}
|
|
141
|
+
return current && typeof current === 'object' && !Array.isArray(current) ? current : {};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function extractHarnessPromptText(packetArtifact) {
|
|
145
|
+
const packet = unwrapHarnessPacketEnvelope(packetArtifact);
|
|
146
|
+
const directHarness = typeof packet.harness === 'string' ? packet.harness : '';
|
|
147
|
+
if (directHarness.trim()) return directHarness;
|
|
148
|
+
|
|
149
|
+
const promptFullText = typeof packet?.prompt?.fullText === 'string' ? packet.prompt.fullText : '';
|
|
150
|
+
if (promptFullText.trim()) return promptFullText;
|
|
151
|
+
|
|
152
|
+
const promptPreview = typeof packet?.prompt?.preview === 'string' ? packet.prompt.preview : '';
|
|
153
|
+
if (promptPreview.trim()) return promptPreview;
|
|
154
|
+
|
|
155
|
+
const doctrine = Array.isArray(packet.doctrine) ? packet.doctrine.filter((x) => typeof x === 'string').join('\n') : '';
|
|
156
|
+
const memory = Array.isArray(packet.memory) ? packet.memory.filter((x) => typeof x === 'string').join('\n') : '';
|
|
157
|
+
const runtimeMode = typeof packet.runtimeOfflineBundle?.source === 'string'
|
|
158
|
+
? `runtime_offline_bundle_source=${packet.runtimeOfflineBundle.source}`
|
|
159
|
+
: '';
|
|
160
|
+
return [doctrine, memory, runtimeMode].filter(Boolean).join('\n');
|
|
161
|
+
}
|
|
162
|
+
|
|
108
163
|
function detectArtifactSignals(sessionId) {
|
|
109
164
|
let harnessArtifact = null;
|
|
110
165
|
for (const packetPath of PACKET_CACHE_PATHS) {
|
|
@@ -160,36 +215,34 @@ function detectArtifactSignals(sessionId) {
|
|
|
160
215
|
staleSubstrateArtifact = null;
|
|
161
216
|
}
|
|
162
217
|
|
|
163
|
-
const harnessText =
|
|
164
|
-
harnessArtifact?.data?.harness ??
|
|
165
|
-
harnessArtifact?.data?.packet?.prompt?.fullText ??
|
|
166
|
-
'',
|
|
167
|
-
);
|
|
218
|
+
const harnessText = extractHarnessPromptText(harnessArtifact?.data);
|
|
168
219
|
const substrateMemories = Array.isArray(substrateArtifact?.data?.memories)
|
|
169
220
|
? substrateArtifact.data.memories
|
|
170
221
|
: [];
|
|
171
|
-
const staleHarnessText =
|
|
172
|
-
staleHarnessArtifact?.data?.harness ??
|
|
173
|
-
staleHarnessArtifact?.data?.packet?.prompt?.fullText ??
|
|
174
|
-
'',
|
|
175
|
-
);
|
|
222
|
+
const staleHarnessText = extractHarnessPromptText(staleHarnessArtifact?.data);
|
|
176
223
|
const staleSubstrateMemories = Array.isArray(staleSubstrateArtifact?.data?.memories)
|
|
177
224
|
? staleSubstrateArtifact.data.memories
|
|
178
225
|
: [];
|
|
179
226
|
const packetMentionsMemory = MEMORY_REF_RX.test(harnessText);
|
|
180
227
|
const stalePacketMentionsMemory = MEMORY_REF_RX.test(staleHarnessText);
|
|
228
|
+
const persistedDirectionUsable = Boolean(directionArtifact?.data?.usable === true);
|
|
229
|
+
const persistedOwnerBootstrap = Boolean(directionArtifact?.data?.ownerBootstrap === true);
|
|
230
|
+
const activePlanPresent = Boolean(
|
|
231
|
+
activePlanArtifact?.data?.phases &&
|
|
232
|
+
Array.isArray(activePlanArtifact.data.phases) &&
|
|
233
|
+
activePlanArtifact.data.phases.length > 0,
|
|
234
|
+
);
|
|
181
235
|
|
|
182
236
|
return {
|
|
183
237
|
hasHarnessPacket: Boolean(harnessText.trim()),
|
|
184
238
|
hasAriaDirection: Boolean(
|
|
185
|
-
|
|
186
|
-
(activePlanArtifact?.data?.phases && Array.isArray(activePlanArtifact.data.phases) && activePlanArtifact.data.phases.length > 0),
|
|
239
|
+
persistedDirectionUsable || activePlanPresent,
|
|
187
240
|
),
|
|
188
241
|
hasMemoryRef: Boolean(packetMentionsMemory || substrateMemories.length > 0),
|
|
189
242
|
ownerBootstrap: {
|
|
190
|
-
hasHarnessPacket: Boolean(staleHarnessText.trim()),
|
|
243
|
+
hasHarnessPacket: Boolean(staleHarnessText.trim() || staleHarnessArtifact?.path),
|
|
191
244
|
hasMemoryRef: Boolean(stalePacketMentionsMemory || staleSubstrateMemories.length > 0),
|
|
192
|
-
directionBootstrap:
|
|
245
|
+
directionBootstrap: persistedOwnerBootstrap || persistedDirectionUsable || activePlanPresent,
|
|
193
246
|
},
|
|
194
247
|
detail: {
|
|
195
248
|
packetPath: harnessArtifact?.path || null,
|
|
@@ -204,6 +257,9 @@ function detectArtifactSignals(sessionId) {
|
|
|
204
257
|
ownerBootstrapSubstrateAgeMs: staleSubstrateArtifact?.ageMs ?? null,
|
|
205
258
|
ownerBootstrapSubstrateMemoryCount: staleSubstrateMemories.length,
|
|
206
259
|
ownerBootstrapPacketMentionsMemory: stalePacketMentionsMemory,
|
|
260
|
+
ownerBootstrapPersistedDirectionUsable: persistedDirectionUsable,
|
|
261
|
+
ownerBootstrapPersistedDirectionSource: directionArtifact?.data?.source ?? null,
|
|
262
|
+
ownerBootstrapActivePlanPresent: activePlanPresent,
|
|
207
263
|
},
|
|
208
264
|
};
|
|
209
265
|
}
|
|
@@ -429,7 +485,11 @@ Per Dalio Loop Layer 2 doctrine: failure deltas are not optional to address. The
|
|
|
429
485
|
|
|
430
486
|
console.log(JSON.stringify({
|
|
431
487
|
decision: 'block',
|
|
432
|
-
reason:
|
|
488
|
+
reason: buildForceRedoActionReason({
|
|
489
|
+
source: 'preturn-memory/blocking-incidents',
|
|
490
|
+
reason: blockReason,
|
|
491
|
+
incidents: blockingIncidents.map((inc) => `${inc.incident_id || '(no incident_id)'} ${inc.title || '(no title)'}`),
|
|
492
|
+
}),
|
|
433
493
|
hookSpecificOutput: {
|
|
434
494
|
hookEventName: 'PreToolUse',
|
|
435
495
|
blocking_incidents: blockingIncidents.map((inc) => ({
|
|
@@ -497,6 +557,13 @@ const ownerBootstrapSessionPresent =
|
|
|
497
557
|
artifactSignals.ownerBootstrap.hasHarnessPacket &&
|
|
498
558
|
artifactSignals.ownerBootstrap.hasMemoryRef;
|
|
499
559
|
|
|
560
|
+
const ownerCompactionRecoveryPresent =
|
|
561
|
+
existsSync(OWNER_TOKEN_PATH) &&
|
|
562
|
+
!transcriptWindow.trim() &&
|
|
563
|
+
artifactSignals.ownerBootstrap.hasHarnessPacket &&
|
|
564
|
+
artifactSignals.ownerBootstrap.hasMemoryRef &&
|
|
565
|
+
(artifactSignals.ownerBootstrap.directionBootstrap || artifactSignals.detail.ownerBootstrapPersistedDirectionUsable);
|
|
566
|
+
|
|
500
567
|
if (allSignalsPresent) {
|
|
501
568
|
// Context was loaded — allow and record the fire timestamp for dedup.
|
|
502
569
|
writeTurnState(sessionId, { lastTurnGateFiredAt: now, lastDecision: 'allow', signals, transcriptSignals, artifactSignals: artifactSignals.detail });
|
|
@@ -528,6 +595,16 @@ if (ownerBootstrapSessionPresent) {
|
|
|
528
595
|
process.exit(0);
|
|
529
596
|
}
|
|
530
597
|
|
|
598
|
+
if (ownerCompactionRecoveryPresent) {
|
|
599
|
+
writeTurnState(sessionId, { lastTurnGateFiredAt: now, lastDecision: 'allow-owner-compaction-recovery', signals, transcriptSignals, artifactSignals: artifactSignals.detail });
|
|
600
|
+
auditLog(
|
|
601
|
+
'allow-owner-compaction-recovery',
|
|
602
|
+
`transcript compacted/empty; recovering from persisted owner artifacts. transcript=${JSON.stringify(transcriptSignals)} artifacts=${JSON.stringify(artifactSignals.detail)}`,
|
|
603
|
+
sessionId,
|
|
604
|
+
);
|
|
605
|
+
process.exit(0);
|
|
606
|
+
}
|
|
607
|
+
|
|
531
608
|
// ── Block with structured recovery signal ────────────────────────────
|
|
532
609
|
// Per Aria's refined spec (consult 2026-04-27): soft-gate + structured
|
|
533
610
|
// recovery. The orchestrator catches this and runs the context-loader.
|
|
@@ -556,7 +633,7 @@ auditLog(
|
|
|
556
633
|
|
|
557
634
|
console.log(JSON.stringify({
|
|
558
635
|
decision: 'block',
|
|
559
|
-
reason,
|
|
636
|
+
reason: buildForceRedoActionReason({ source: 'preturn-memory/context-not-loaded', reason, missingSignals }),
|
|
560
637
|
hookSpecificOutput: {
|
|
561
638
|
hookEventName: 'PreToolUse',
|
|
562
639
|
recovery: {
|
|
@@ -87,6 +87,29 @@ function audit(event, data = {}) {
|
|
|
87
87
|
} catch {}
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
function buildForceRedoActionReason({ source, reason, violations = [] }) {
|
|
91
|
+
return [
|
|
92
|
+
'=== ARIA FORCE_REDO_ACTION ===',
|
|
93
|
+
`source: ${source}`,
|
|
94
|
+
`reason: ${reason}`,
|
|
95
|
+
'',
|
|
96
|
+
'This is not a terminal error. It is a forced redo instruction for the attempted repository edit/action.',
|
|
97
|
+
'Do not retry the same edit. Redo the action so doctrine-bound source remains real, reviewable, and production-safe.',
|
|
98
|
+
'',
|
|
99
|
+
'TEACHING:',
|
|
100
|
+
'- Production paths cannot gain stub, mock, fake, placeholder, pending, or direct-provider bypass semantics.',
|
|
101
|
+
'- If an exception is intentional, isolate it in tests/specs/fixtures/examples/demos/mocks or add the explicit allow marker in the file.',
|
|
102
|
+
'- External provider calls must use an approved runtime/SDK path or carry the explicit external-call allow marker.',
|
|
103
|
+
violations.length ? `\nVIOLATIONS TO FIX:\n${violations.map((v) => `- ${v}`).join('\n')}` : '',
|
|
104
|
+
'',
|
|
105
|
+
'REQUIRED REDO SHAPE:',
|
|
106
|
+
'1. Preserve the intended behavior without stub/mock/pending semantics.',
|
|
107
|
+
'2. Use real implementation wiring or an explicit reviewed allow marker.',
|
|
108
|
+
'3. Re-run the action after removing the violating lines from the diff.',
|
|
109
|
+
'=== END FORCE_REDO_ACTION ===',
|
|
110
|
+
].filter(Boolean).join('\n');
|
|
111
|
+
}
|
|
112
|
+
|
|
90
113
|
function parseArgs(argv) {
|
|
91
114
|
const parsed = {
|
|
92
115
|
mode: 'working-tree',
|
|
@@ -219,6 +242,8 @@ function isPolicyOrRuleDefinitionLine(line) {
|
|
|
219
242
|
if (/\bno stubs?\b/.test(lower)) return true;
|
|
220
243
|
if (/\bno placeholders?\b/.test(lower)) return true;
|
|
221
244
|
if (/\bno fake implementations?\b/.test(lower)) return true;
|
|
245
|
+
if (lower.includes('no mock content is injected')) return true;
|
|
246
|
+
if (/\bplaceholder\s*=/.test(lower)) return true;
|
|
222
247
|
return false;
|
|
223
248
|
}
|
|
224
249
|
|
|
@@ -382,7 +407,14 @@ async function main() {
|
|
|
382
407
|
audit('repo_doctrine_gate_block', { repoRoot, mode, violations });
|
|
383
408
|
|
|
384
409
|
if (event) {
|
|
385
|
-
console.log(JSON.stringify({
|
|
410
|
+
console.log(JSON.stringify({
|
|
411
|
+
decision: 'block',
|
|
412
|
+
reason: buildForceRedoActionReason({
|
|
413
|
+
source: 'repo-doctrine',
|
|
414
|
+
reason,
|
|
415
|
+
violations: violations.slice(0, 20).map((violation) => `${violation.path}:${violation.line} [${violation.rule}] ${violation.excerpt}`),
|
|
416
|
+
}),
|
|
417
|
+
}));
|
|
386
418
|
process.exit(2);
|
|
387
419
|
}
|
|
388
420
|
|