@tea-agent/loop-agent 0.25.6 → 0.26.0
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/AGENTS.md +2 -1
- package/CHANGELOG.md +1020 -1006
- package/bin/loop-agent.js +21 -21
- package/dist/commands/cursor-prompt.js +6 -6
- package/dist/commands/loop-benchmark.js +11 -11
- package/dist/commands/pi-reuse-benchmark.js +16 -16
- package/dist/executors/dag-pi-executor.js +26 -20
- package/dist/executors/model-routing.js +34 -18
- package/dist/governance/manifest-types.js +33 -5
- package/dist/sidecars/cursor-prompt/executor.js +1 -1
- package/dist/task/task-demand-routing.js +3 -1
- package/dist/worker/console/chat/model-resolver.js +15 -3
- package/dist/worker/observe/static/constants.js +3 -2
- package/dist/worker/observe/static/copy.js +67 -67
- package/dist/worker/observe/static/dag-layout.d.ts +31 -31
- package/dist/worker/observe/static/dag-layout.js +83 -83
- package/dist/worker/observe/static/dag-model.js +1 -0
- package/dist/worker/observe/static/dom.js +220 -220
- package/dist/worker/observe/static/relations.js +133 -133
- package/dist/worker/observe/static/router.js +93 -93
- package/dist/worker/observe/static/run-processing.js +148 -148
- package/dist/worker/observe/static/styles.css +182 -42
- package/dist/worker/observe/static/views/batch.js +227 -227
- package/dist/worker/observe/static/views/dag-graph.js +172 -172
- package/dist/worker/observe/static/views/failures.js +143 -143
- package/dist/worker/observe/static/views/feature.js +492 -492
- package/dist/worker/observe/static/views/run.js +453 -453
- package/dist/worker/observe/static/views/shell.js +7 -7
- package/dist/worker/observe/static/views/timeline.js +163 -163
- package/dist/workflows/dag/canvas-observer.js +275 -275
- package/dist/workflows/dag/lifecycle.js +40 -30
- package/dist/workflows/dag/node-execution.js +13 -0
- package/dist/workflows/dag/types.js +59 -19
- package/docs/skills/README.md +7 -7
- package/docs/templates/adr.md +60 -60
- package/docs/templates/agent-dag-authority-surface-audit.prompt.md +94 -94
- package/docs/templates/agent-dag-decision-envelope.schema.json +213 -213
- package/docs/templates/agent-dag-decision-gate.prompt.md +246 -246
- package/docs/templates/agent-dag-process-supervisor.prompt.md +98 -98
- package/docs/templates/agent-dag-report.schema.json +473 -473
- package/docs/templates/agent-dag-review-verdict.prompt.md +68 -68
- package/docs/templates/backend-test-result.schema.json +99 -99
- package/docs/templates/feature-spec.md +53 -53
- package/docs/templates/frontend-design-contract.md +42 -42
- package/docs/templates/frontend-eval/fixtures/failures/01-type-build-error.md +17 -17
- package/docs/templates/frontend-eval/fixtures/failures/02-unit-component-test-fail.md +16 -16
- package/docs/templates/frontend-eval/fixtures/failures/03-fixture-schema-drift.md +16 -16
- package/docs/templates/frontend-eval/fixtures/failures/04-missing-loading-empty-error-state.md +16 -16
- package/docs/templates/frontend-eval/fixtures/failures/05-forbidden-write-writeset-expansion.md +16 -16
- package/docs/templates/frontend-eval/fixtures/failures/06-unapproved-dependency-add.md +16 -16
- package/docs/templates/frontend-eval/fixtures/failures/07-mock-production-on.md +21 -21
- package/docs/templates/frontend-eval/fixtures/functional/01-simple-component-style.md +29 -29
- package/docs/templates/frontend-eval/fixtures/functional/02-form-validation.md +28 -28
- package/docs/templates/frontend-eval/fixtures/functional/03-list-detail-page.md +28 -28
- package/docs/templates/frontend-eval/fixtures/functional/04-api-mock.md +29 -29
- package/docs/templates/frontend-eval/fixtures/functional/05-permission-auth-gated-ui.md +27 -27
- package/docs/templates/frontend-eval/fixtures/functional/06-ssr-server-client-boundary.md +28 -28
- package/docs/templates/frontend-eval/fixtures/functional/07-shared-public-component-api.md +28 -28
- package/docs/templates/frontend-eval/fixtures/functional/08-pure-local-no-remote.md +27 -27
- package/docs/templates/frontend-eval/metrics.md +138 -138
- package/docs/templates/frontend-eval/smoke-targets.md +53 -53
- package/docs/templates/frontend-task-constraints.md +35 -35
- package/docs/templates/frontend-task-requirement.md +70 -70
- package/docs/templates/harness.schema.json +29 -7
- package/docs/templates/init-evolution-review.md +35 -35
- package/docs/templates/interactive-ui-round2-experiment.md +66 -66
- package/docs/templates/knowledge-graph-bootstrap-dag.json +118 -118
- package/docs/templates/knowledge-sync-dag.json +178 -178
- package/docs/templates/knowledge-sync-draft.schema.json +71 -71
- package/docs/templates/product-line/closeout.yaml +9 -9
- package/docs/templates/product-line/design.md +13 -13
- package/docs/templates/product-line/links.md +10 -10
- package/docs/templates/product-line/requirement.md +17 -17
- package/docs/templates/product-line/test-plan.md +7 -7
- package/docs/templates/production-readiness-checklist.md +57 -57
- package/docs/templates/project-start-checklist.md +9 -9
- package/docs/templates/qa-report.md +48 -48
- package/docs/templates/sprint-contract.md +29 -29
- package/docs/templates/worker-dogfood-evidence.md +80 -80
- package/docs/templates/worker-dogfood-setup.md +68 -68
- package/harness.json +1 -2
- package/package.json +1 -1
- package/scripts/kb-bootstrap-init-skeleton.sh +0 -0
- package/scripts/kb-graph-incremental-prepare.mjs +386 -386
- package/scripts/kb-graph-materialize.mjs +105 -105
- package/scripts/kb-graph-promote.mjs +164 -164
- package/scripts/kb-query.mjs +554 -554
- package/skills/ai-engineering-context/SKILL.md +48 -48
- package/skills/analyze-product-dependencies/SKILL.md +67 -67
- package/skills/analyze-product-dependencies/agents/openai.yaml +4 -4
- package/skills/analyze-product-dependencies/references/api-documentation-schema.md +30 -30
- package/skills/analyze-product-dependencies/references/dependency-analysis-schema.md +28 -28
- package/skills/analyze-product-dependencies/references/example.md +76 -76
- package/skills/analyze-product-dependencies/references/forward-test-cases.md +35 -35
- package/skills/analyze-product-dependencies/references/input-contract.md +11 -11
- package/skills/analyze-product-dependencies/references/scouting-rules.md +61 -61
- package/skills/analyze-product-dependencies/scripts/test-validators.mjs +267 -267
- package/skills/analyze-product-dependencies/scripts/validate-api-documentation.mjs +101 -101
- package/skills/analyze-product-dependencies/scripts/validate-dependency-analysis.mjs +142 -142
- package/skills/analyze-product-dependencies/scripts/validate-product-requirement-input.mjs +76 -76
- package/skills/analyze-product-dependencies/scripts/validation-helpers.mjs +146 -146
- package/skills/analyze-product-requirements/SKILL.md +90 -90
- package/skills/analyze-product-requirements/agents/openai.yaml +4 -4
- package/skills/analyze-product-requirements/references/acceptance-criteria.md +91 -91
- package/skills/analyze-product-requirements/references/clarification-and-knowledge.md +56 -56
- package/skills/analyze-product-requirements/references/example.md +86 -86
- package/skills/analyze-product-requirements/references/forward-test-cases.md +66 -66
- package/skills/analyze-product-requirements/references/product-analysis-schema.md +32 -32
- package/skills/analyze-product-requirements/references/product-requirement-schema.md +33 -33
- package/skills/analyze-product-requirements/references/requirement-clarification-schema.md +35 -35
- package/skills/analyze-product-requirements/scripts/test-validators.mjs +193 -193
- package/skills/analyze-product-requirements/scripts/validate-product-analysis.mjs +69 -69
- package/skills/analyze-product-requirements/scripts/validate-product-requirement.mjs +97 -97
- package/skills/analyze-product-requirements/scripts/validate-requirement-clarification.mjs +98 -98
- package/skills/analyze-product-requirements/scripts/validation-helpers.mjs +156 -156
- package/skills/browser-tools/browser-content.js +103 -103
- package/skills/browser-tools/browser-cookies.js +35 -35
- package/skills/browser-tools/browser-eval.js +53 -53
- package/skills/browser-tools/browser-hn-scraper.js +108 -108
- package/skills/browser-tools/browser-nav.js +44 -44
- package/skills/browser-tools/browser-pick.js +162 -162
- package/skills/browser-tools/browser-screenshot.js +34 -34
- package/skills/browser-tools/browser-start.js +86 -86
- package/skills/browser-tools/package-lock.json +2556 -2556
- package/skills/browser-tools/package.json +19 -19
- package/skills/code-review-core/SKILL.md +20 -20
- package/skills/codebase-scout/SKILL.md +19 -19
- package/skills/grill-me/SKILL.md +10 -10
- package/skills/loop-agent/references/README.md +67 -67
- package/skills/loop-agent/references/docs-converge.md +126 -126
- package/skills/loop-agent/references/hybrid-dag.md +2 -2
- package/skills/loop-agent/references/learned/README.md +21 -21
- package/skills/loop-agent/references/long-running-loop.md +57 -57
- package/skills/loop-agent/references/model-routing.md +2 -0
- package/skills/loop-agent/references/one-shot-runs.md +85 -85
- package/skills/loop-agent/references/pi-prompt.md +23 -23
- package/skills/loop-agent/references/pi-subagent-assisted-mode.md +84 -84
- package/skills/playwright-cli/SKILL.md +420 -420
- package/skills/playwright-cli/references/element-attributes.md +23 -23
- package/skills/playwright-cli/references/playwright-tests.md +39 -39
- package/skills/playwright-cli/references/request-mocking.md +87 -87
- package/skills/playwright-cli/references/running-code.md +241 -241
- package/skills/playwright-cli/references/session-management.md +225 -225
- package/skills/playwright-cli/references/storage-state.md +275 -275
- package/skills/playwright-cli/references/test-generation.md +433 -433
- package/skills/playwright-cli/references/tracing.md +139 -139
- package/skills/playwright-cli/references/video-recording.md +143 -143
- package/skills/requesting-code-review/SKILL.md +101 -101
- package/skills/requesting-code-review/code-reviewer.md +168 -168
- package/skills/systematic-debugging/CREATION-LOG.md +119 -119
- package/skills/systematic-debugging/condition-based-waiting-example.ts +158 -158
- package/skills/systematic-debugging/condition-based-waiting.md +115 -115
- package/skills/systematic-debugging/defense-in-depth.md +122 -122
- package/skills/systematic-debugging/find-polluter.sh +63 -63
- package/skills/systematic-debugging/root-cause-tracing.md +169 -169
- package/skills/systematic-debugging/test-academic.md +14 -14
- package/skills/systematic-debugging/test-pressure-1.md +58 -58
- package/skills/systematic-debugging/test-pressure-2.md +68 -68
- package/skills/systematic-debugging/test-pressure-3.md +69 -69
- package/skills/using-git-worktrees/SKILL.md +215 -215
- package/skills/verification-before-completion/SKILL.md +154 -154
- package/skills/webapp-testing/SKILL.md +19 -19
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { access, mkdir, readFile, readdir, rename
|
|
1
|
+
import { access, mkdir, readFile, readdir, rename } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { hostname as localHostname } from "node:os";
|
|
4
4
|
import { writeJsonAtomic, } from "../../infrastructure/harness/atomic-write.js";
|
|
@@ -170,20 +170,22 @@ export function assessDagRunLiveness(input) {
|
|
|
170
170
|
return { status: "unknown" };
|
|
171
171
|
if (runner.hostname !== (input.hostname ?? localHostname()))
|
|
172
172
|
return { status: "unknown-host" };
|
|
173
|
-
const isAlive = input.isProcessAlive ??
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
173
|
+
const isAlive = input.isProcessAlive ??
|
|
174
|
+
((pid) => {
|
|
175
|
+
try {
|
|
176
|
+
process.kill(pid, 0);
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
});
|
|
182
183
|
if (!isAlive(runner.pid))
|
|
183
184
|
return { status: "orphaned", runnerAlive: false };
|
|
184
185
|
const heartbeatMs = Date.parse(runner.heartbeatAt);
|
|
185
186
|
const nowMs = (input.now ?? new Date()).getTime();
|
|
186
|
-
if (!Number.isNaN(heartbeatMs) &&
|
|
187
|
+
if (!Number.isNaN(heartbeatMs) &&
|
|
188
|
+
nowMs - heartbeatMs > (input.staleThresholdMs ?? 90_000)) {
|
|
187
189
|
return { status: "stale", runnerAlive: true };
|
|
188
190
|
}
|
|
189
191
|
const activeNode = Object.values(input.state.nodes).find((node) => node.status === "RUNNING");
|
|
@@ -193,20 +195,20 @@ export function assessDagRunLiveness(input) {
|
|
|
193
195
|
if (activeNode.livenessStatus === "needs-attention") {
|
|
194
196
|
return { status: "needs-attention", runnerAlive: true };
|
|
195
197
|
}
|
|
196
|
-
if (activeNode.livenessStatus === "suspected-stall"
|
|
197
|
-
|
|
198
|
+
if (activeNode.livenessStatus === "suspected-stall" ||
|
|
199
|
+
activeNode.livenessStatus === "probing") {
|
|
198
200
|
return { status: "suspected-stall", runnerAlive: true };
|
|
199
201
|
}
|
|
200
202
|
if (activeNode.livenessStatus === "quiet") {
|
|
201
203
|
return { status: "node-quiet", runnerAlive: true };
|
|
202
204
|
}
|
|
203
205
|
// Fall back to meaningful progress clocks (never use runner lease as progress).
|
|
204
|
-
const meaningfulAt = activeNode.lastMeaningfulProgressAt
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
206
|
+
const meaningfulAt = activeNode.lastMeaningfulProgressAt ??
|
|
207
|
+
activeNode.lastProviderActivityAt ??
|
|
208
|
+
activeNode.lastToolActivityAt ??
|
|
209
|
+
activeNode.lastOutputActivityAt ??
|
|
210
|
+
activeNode.lastActivityAt ??
|
|
211
|
+
activeNode.startedAt;
|
|
210
212
|
const nodeActivityMs = Date.parse(meaningfulAt ?? "");
|
|
211
213
|
if (!Number.isNaN(nodeActivityMs)) {
|
|
212
214
|
const idleMs = nowMs - nodeActivityMs;
|
|
@@ -229,12 +231,12 @@ export function deriveDagRunEffectiveStatus(input) {
|
|
|
229
231
|
if (input.lifecycle === "paused")
|
|
230
232
|
return "paused";
|
|
231
233
|
if (input.lifecycle === "completed") {
|
|
232
|
-
return input.state.status
|
|
234
|
+
return mapTerminalDagRunEffectiveStatus(input.state.status);
|
|
233
235
|
}
|
|
234
236
|
if (input.state.status === "pending")
|
|
235
237
|
return "pending";
|
|
236
238
|
if (isTerminalDagRunStatus(input.state.status)) {
|
|
237
|
-
return input.state.status
|
|
239
|
+
return mapTerminalDagRunEffectiveStatus(input.state.status);
|
|
238
240
|
}
|
|
239
241
|
if (input.liveness === "orphaned" || input.liveness === "stale")
|
|
240
242
|
return "interrupted";
|
|
@@ -252,19 +254,20 @@ export function deriveDagRunEffectiveStatus(input) {
|
|
|
252
254
|
}
|
|
253
255
|
export function assessDagRunRecoveryEligibility(input) {
|
|
254
256
|
const reasons = [];
|
|
255
|
-
const canResume = input.lifecycle === "active"
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
257
|
+
const canResume = input.lifecycle === "active" &&
|
|
258
|
+
input.state.status === "running" &&
|
|
259
|
+
Boolean(input.state.humanDecisionNodeId) &&
|
|
260
|
+
Boolean(input.hasHumanApproval);
|
|
259
261
|
if (!canResume)
|
|
260
262
|
reasons.push("standard-resume-preconditions-not-met");
|
|
261
263
|
let canReconcile = true;
|
|
262
|
-
if (input.lifecycle === "completed" ||
|
|
264
|
+
if (input.lifecycle === "completed" ||
|
|
265
|
+
isTerminalDagRunStatus(input.state.status)) {
|
|
263
266
|
canReconcile = false;
|
|
264
267
|
reasons.push("run-already-terminal");
|
|
265
268
|
}
|
|
266
|
-
if (input.lifecycle === "active"
|
|
267
|
-
|
|
269
|
+
if (input.lifecycle === "active" &&
|
|
270
|
+
[
|
|
268
271
|
"active",
|
|
269
272
|
"node-quiet",
|
|
270
273
|
"suspected-stall",
|
|
@@ -298,6 +301,13 @@ export const TERMINAL_RUN_STATUSES = new Set([
|
|
|
298
301
|
export function isTerminalDagRunStatus(status) {
|
|
299
302
|
return TERMINAL_RUN_STATUSES.has(status);
|
|
300
303
|
}
|
|
304
|
+
function mapTerminalDagRunEffectiveStatus(status) {
|
|
305
|
+
if (status === "finished")
|
|
306
|
+
return "finished";
|
|
307
|
+
if (status === "partial_failed")
|
|
308
|
+
return "partial_failed";
|
|
309
|
+
return "failed";
|
|
310
|
+
}
|
|
301
311
|
function listPendingNodeIds(state) {
|
|
302
312
|
return Object.values(state.nodes)
|
|
303
313
|
.filter((node) => node.status === "PENDING")
|
|
@@ -477,8 +487,8 @@ export async function listAllDagRunEntries(repoRoot) {
|
|
|
477
487
|
located.push(...(await listRunsInLifecycleDir(repoRoot, lifecycle)));
|
|
478
488
|
}
|
|
479
489
|
return located.sort((left, right) => {
|
|
480
|
-
const lifecycleCompare = DAG_LIFECYCLE_SCAN_ORDER.indexOf(left.lifecycle)
|
|
481
|
-
|
|
490
|
+
const lifecycleCompare = DAG_LIFECYCLE_SCAN_ORDER.indexOf(left.lifecycle) -
|
|
491
|
+
DAG_LIFECYCLE_SCAN_ORDER.indexOf(right.lifecycle);
|
|
482
492
|
if (lifecycleCompare !== 0)
|
|
483
493
|
return lifecycleCompare;
|
|
484
494
|
return left.runId.localeCompare(right.runId);
|
|
@@ -16,6 +16,8 @@ import { assertSkillSnapshotCoversSpec, buildNodePromptFromSnapshot, isDagSkillS
|
|
|
16
16
|
import { resolveDagSkillInstructions, skillInstructionMetadata, } from "./skill-instructions.js";
|
|
17
17
|
import { parseRepairArtifactFromText, resolveRepairTaskForGate, validateRepairArtifactScope, } from "./repair-artifact.js";
|
|
18
18
|
import { resolveModelForTask, } from "./types.js";
|
|
19
|
+
import { loadHarnessManifest } from "../../governance/harness.js";
|
|
20
|
+
import { resolveExecutorThinkingMatrix } from "../../executors/model-routing.js";
|
|
19
21
|
export function buildNodePrompt(spec, task, upstream, options) {
|
|
20
22
|
const policy = resolveContextPolicy(spec);
|
|
21
23
|
return buildDagNodePromptEnvelope({
|
|
@@ -359,6 +361,16 @@ export async function executeDagNode(input) {
|
|
|
359
361
|
node.resolvedSkills = resolvedSkills;
|
|
360
362
|
await writeNodeSkillArtifacts(runDir, nodeId, resolvedSkills);
|
|
361
363
|
const model = resolveModelForTask(task, spec.executorModels);
|
|
364
|
+
let thinking;
|
|
365
|
+
if (task.executor === "pi") {
|
|
366
|
+
try {
|
|
367
|
+
const manifest = await loadHarnessManifest(cwd);
|
|
368
|
+
thinking = resolveExecutorThinkingMatrix(manifest.executors?.pi)[task.complexity];
|
|
369
|
+
}
|
|
370
|
+
catch {
|
|
371
|
+
// Invalid or missing harness preserves the previous no-override behavior.
|
|
372
|
+
}
|
|
373
|
+
}
|
|
362
374
|
const retryPolicy = task.retryPolicy && isSafeReadOnlyPiRetryCandidate(task)
|
|
363
375
|
? task.retryPolicy
|
|
364
376
|
: undefined;
|
|
@@ -418,6 +430,7 @@ export async function executeDagNode(input) {
|
|
|
418
430
|
task,
|
|
419
431
|
cwd,
|
|
420
432
|
model,
|
|
433
|
+
...(thinking ? { thinking } : {}),
|
|
421
434
|
prompt: buildAttemptPrompt(task, prompt, attemptNumber, previousFailureCategory, previousProtocolReason),
|
|
422
435
|
attempt: attemptNumber,
|
|
423
436
|
reportActivity,
|
|
@@ -74,7 +74,9 @@ export const dagVerdictGateSchema = z.object({
|
|
|
74
74
|
* Prefer listing the post-revision / final reviewer first when both may exist.
|
|
75
75
|
*/
|
|
76
76
|
fallbackFromNodeIds: z
|
|
77
|
-
.array(z
|
|
77
|
+
.array(z
|
|
78
|
+
.string()
|
|
79
|
+
.regex(/^[a-z][a-z0-9-]*$/, "fallbackFromNodeIds must be kebab-case"))
|
|
78
80
|
.optional(),
|
|
79
81
|
accept: z.array(z.string().min(1)).min(1),
|
|
80
82
|
lineMode: z.enum(["first-non-empty", "first-verdict-line"]).optional(),
|
|
@@ -130,15 +132,20 @@ export const dagFrontendPrewriteGateSchema = z.object({
|
|
|
130
132
|
planFallbackFromNodeIds: z.array(dagFrontendNodeIdSchema).default([]),
|
|
131
133
|
reviewFromNodeId: dagFrontendNodeIdSchema,
|
|
132
134
|
reviewFallbackFromNodeIds: z.array(dagFrontendNodeIdSchema).default([]),
|
|
133
|
-
requiredRequirementIds: z
|
|
134
|
-
|
|
135
|
+
requiredRequirementIds: z
|
|
136
|
+
.array(z.string().regex(/^(?:REQ|BR|AC)-[A-Z0-9]+(?:-[A-Z0-9]+)*$/))
|
|
137
|
+
.default([]),
|
|
138
|
+
allowedMockStrategies: z
|
|
139
|
+
.array(z.enum(["native", "browser-intercept", "request-adapter", "not-needed"]))
|
|
140
|
+
.min(1),
|
|
135
141
|
artifactName: z.string().regex(/^[a-z0-9][a-z0-9._-]*\.json$/),
|
|
136
142
|
outputDir: z.string().regex(/^[a-z0-9][a-z0-9._-]*$/),
|
|
137
143
|
requireSourceFreshness: z.literal(true),
|
|
138
144
|
implementationWriteSet: z.array(z.string().min(1)).min(1).optional(),
|
|
139
145
|
openspecCandidatePaths: z
|
|
140
|
-
.array(z
|
|
141
|
-
|
|
146
|
+
.array(z
|
|
147
|
+
.string()
|
|
148
|
+
.refine((candidate) => !candidate.includes("\\") && isOpenspecSpecFilePath(candidate), "openspec candidate must be a repo-relative supported file under openspec/schemas/ or openspec/project-specs/"))
|
|
142
149
|
.default([]),
|
|
143
150
|
});
|
|
144
151
|
export const dagFrontendLintBaselineSchema = z
|
|
@@ -148,7 +155,8 @@ export const dagFrontendLintBaselineSchema = z
|
|
|
148
155
|
lintEvidence: dagShellVerifyEvidenceSchema,
|
|
149
156
|
})
|
|
150
157
|
.strict();
|
|
151
|
-
export const dagFrontendVerificationBundleSchema = z
|
|
158
|
+
export const dagFrontendVerificationBundleSchema = z
|
|
159
|
+
.object({
|
|
152
160
|
schemaVersion: z.literal(1),
|
|
153
161
|
mockCommands: z.array(z.string()).default([]),
|
|
154
162
|
lintCommands: z.array(z.string().min(1)).optional(),
|
|
@@ -161,7 +169,8 @@ export const dagFrontendVerificationBundleSchema = z.object({
|
|
|
161
169
|
lintBaselineNodeId: dagFrontendNodeIdSchema.optional(),
|
|
162
170
|
writerNodeIds: z.array(dagFrontendNodeIdSchema).optional(),
|
|
163
171
|
mode: z.enum(["initial", "repair"]),
|
|
164
|
-
})
|
|
172
|
+
})
|
|
173
|
+
.superRefine((bundle, context) => {
|
|
165
174
|
const groups = [
|
|
166
175
|
["mock", bundle.mockCommands, bundle.mockEvidence],
|
|
167
176
|
["lint", bundle.lintCommands ?? [], bundle.lintEvidence],
|
|
@@ -169,23 +178,48 @@ export const dagFrontendVerificationBundleSchema = z.object({
|
|
|
169
178
|
["behavior", bundle.behaviorCommands, bundle.behaviorEvidence],
|
|
170
179
|
];
|
|
171
180
|
for (const [name, commands, evidence] of groups) {
|
|
172
|
-
if ((name === "mock" || name === "lint") &&
|
|
181
|
+
if ((name === "mock" || name === "lint") &&
|
|
182
|
+
commands.length === 0 &&
|
|
183
|
+
!evidence)
|
|
173
184
|
continue;
|
|
174
185
|
if (!evidence) {
|
|
175
|
-
context.addIssue({
|
|
186
|
+
context.addIssue({
|
|
187
|
+
code: z.ZodIssueCode.custom,
|
|
188
|
+
path: [`${name}Evidence`],
|
|
189
|
+
message: `${name} evidence is required when commands are configured`,
|
|
190
|
+
});
|
|
176
191
|
continue;
|
|
177
192
|
}
|
|
178
193
|
if (evidence.commandCount !== commands.length) {
|
|
179
|
-
context.addIssue({
|
|
194
|
+
context.addIssue({
|
|
195
|
+
code: z.ZodIssueCode.custom,
|
|
196
|
+
path: [`${name}Evidence`, "commandCount"],
|
|
197
|
+
message: `${name} commandCount must match commands`,
|
|
198
|
+
});
|
|
180
199
|
}
|
|
181
200
|
if (evidence.commandLabels.length !== commands.length) {
|
|
182
|
-
context.addIssue({
|
|
201
|
+
context.addIssue({
|
|
202
|
+
code: z.ZodIssueCode.custom,
|
|
203
|
+
path: [`${name}Evidence`, "commandLabels"],
|
|
204
|
+
message: `${name} commandLabels must match commands`,
|
|
205
|
+
});
|
|
183
206
|
}
|
|
184
|
-
if (evidence.commandTexts.length !== commands.length ||
|
|
185
|
-
|
|
207
|
+
if (evidence.commandTexts.length !== commands.length ||
|
|
208
|
+
evidence.commandTexts.some((command, index) => command !== commands[index])) {
|
|
209
|
+
context.addIssue({
|
|
210
|
+
code: z.ZodIssueCode.custom,
|
|
211
|
+
path: [`${name}Evidence`, "commandTexts"],
|
|
212
|
+
message: `${name} commandTexts must exactly match commands`,
|
|
213
|
+
});
|
|
186
214
|
}
|
|
187
|
-
if (new Set(evidence.commandLabels).size !==
|
|
188
|
-
|
|
215
|
+
if (new Set(evidence.commandLabels).size !==
|
|
216
|
+
evidence.commandLabels.length ||
|
|
217
|
+
evidence.commandLabels.some((label) => !label.trim())) {
|
|
218
|
+
context.addIssue({
|
|
219
|
+
code: z.ZodIssueCode.custom,
|
|
220
|
+
path: [`${name}Evidence`, "commandLabels"],
|
|
221
|
+
message: `${name} commandLabels must be non-empty and unique`,
|
|
222
|
+
});
|
|
189
223
|
}
|
|
190
224
|
}
|
|
191
225
|
if ((bundle.lintCommands?.length ?? 0) > 0) {
|
|
@@ -318,9 +352,12 @@ export const dagShellConfigSchema = z.object({
|
|
|
318
352
|
commands: z.array(z.string()).default([]),
|
|
319
353
|
preset: dagShellPresetSchema.optional(),
|
|
320
354
|
verdictGate: dagVerdictGateSchema.optional(),
|
|
321
|
-
projectGovernanceGate: z
|
|
355
|
+
projectGovernanceGate: z
|
|
356
|
+
.object({
|
|
322
357
|
contextPath: z.literal(".runtime/project-governance-context.json"),
|
|
323
|
-
})
|
|
358
|
+
})
|
|
359
|
+
.strict()
|
|
360
|
+
.optional(),
|
|
324
361
|
requirementCoverageGate: dagRequirementCoverageGateSchema.optional(),
|
|
325
362
|
jsonArtifactGate: dagJsonArtifactGateSchema.optional(),
|
|
326
363
|
frontendPrewriteGate: dagFrontendPrewriteGateSchema.optional(),
|
|
@@ -333,7 +370,8 @@ export const dagShellConfigSchema = z.object({
|
|
|
333
370
|
frontendTestHtmlReport: dagFrontendTestHtmlReportSchema.optional(),
|
|
334
371
|
backendTestPipeline: dagBackendTestPipelineSchema.optional(),
|
|
335
372
|
/** JaCoCo coverage collection for backend-test (Java services). When set, node 7 dumps coverage over TCP from a JaCoCo tcpserver agent and feeds it to the L-5 dashboard. */
|
|
336
|
-
jacocoCoverage: z
|
|
373
|
+
jacocoCoverage: z
|
|
374
|
+
.object({
|
|
337
375
|
/** JaCoCo tcpserver endpoint, e.g. "host:6300". */
|
|
338
376
|
endpoint: z.string().min(1),
|
|
339
377
|
/** Absolute path to jacococli.jar on this machine, used to convert .exec → jacoco.xml. */
|
|
@@ -342,7 +380,9 @@ export const dagShellConfigSchema = z.object({
|
|
|
342
380
|
includes: z.string().min(1).optional().default("*"),
|
|
343
381
|
/** TCP connect timeout in ms. Defaults to 5000. */
|
|
344
382
|
connectTimeoutMs: z.number().int().positive().optional().default(5000),
|
|
345
|
-
})
|
|
383
|
+
})
|
|
384
|
+
.strict()
|
|
385
|
+
.optional(),
|
|
346
386
|
verifyEvidence: dagShellVerifyEvidenceSchema.optional(),
|
|
347
387
|
repairArtifactGate: dagRepairArtifactGateSchema.optional(),
|
|
348
388
|
/** fail (default): any nonzero command fails the node. record: finish node FINISHED with failure facts for downstream assess/repair. */
|
package/docs/skills/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
# Skill Registry
|
|
2
|
-
|
|
3
|
-
This directory records repo-local skill wrappers and vetting notes used by Agent DAG role mapping.
|
|
4
|
-
|
|
5
|
-
- `vetted-skill-registry.md` — supported roles, source inspiration, risk notes, and default/optional usage.
|
|
6
|
-
- `../../skills/agent-worker/SKILL.md` — optional outer-loop operator skill for Feature Packet, TaskSpec, Task Pool, controller pinning, self-hosting canaries, and Worker recovery. Single DAG implementation or runtime repair stays with `loop-agent`; this skill is not a default DAG role skill.
|
|
7
|
-
- `../../scripts/check-skill-entry.sh` — validates both public skill entries, their required references, line budgets, and the `agent-worker` trigger vocabulary.
|
|
1
|
+
# Skill Registry
|
|
2
|
+
|
|
3
|
+
This directory records repo-local skill wrappers and vetting notes used by Agent DAG role mapping.
|
|
4
|
+
|
|
5
|
+
- `vetted-skill-registry.md` — supported roles, source inspiration, risk notes, and default/optional usage.
|
|
6
|
+
- `../../skills/agent-worker/SKILL.md` — optional outer-loop operator skill for Feature Packet, TaskSpec, Task Pool, controller pinning, self-hosting canaries, and Worker recovery. Single DAG implementation or runtime repair stays with `loop-agent`; this skill is not a default DAG role skill.
|
|
7
|
+
- `../../scripts/check-skill-entry.sh` — validates both public skill entries, their required references, line budgets, and the `agent-worker` trigger vocabulary.
|
package/docs/templates/adr.md
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
# ADR 模板
|
|
2
|
-
|
|
3
|
-
## 标题
|
|
4
|
-
|
|
5
|
-
> 建议文件名:`0001-<topic>.md`
|
|
6
|
-
|
|
7
|
-
## 状态
|
|
8
|
-
|
|
9
|
-
- proposed / accepted / superseded
|
|
10
|
-
|
|
11
|
-
## 背景
|
|
12
|
-
|
|
13
|
-
- 当前遇到的工程或架构问题是什么?
|
|
14
|
-
- 为什么现在必须做决定?
|
|
15
|
-
- 相关上下文、历史方案、约束有哪些?
|
|
16
|
-
|
|
17
|
-
## 决策
|
|
18
|
-
|
|
19
|
-
- 最终选择什么方案?
|
|
20
|
-
- 明确边界、适用范围、默认行为是什么?
|
|
21
|
-
|
|
22
|
-
## 备选方案
|
|
23
|
-
|
|
24
|
-
1. 方案 A:
|
|
25
|
-
2. 方案 B:
|
|
26
|
-
3. 方案 C:
|
|
27
|
-
|
|
28
|
-
## 取舍理由
|
|
29
|
-
|
|
30
|
-
- 为什么选择当前方案?
|
|
31
|
-
- 为什么不选其他方案?
|
|
32
|
-
- 主要 trade-off 是什么?
|
|
33
|
-
|
|
34
|
-
## 影响范围
|
|
35
|
-
|
|
36
|
-
- 影响的代码目录:
|
|
37
|
-
- 影响的文档/契约:
|
|
38
|
-
- 影响的测试/脚本:
|
|
39
|
-
- 影响的开发流程/harness:
|
|
40
|
-
|
|
41
|
-
## 后果
|
|
42
|
-
|
|
43
|
-
### 正面后果
|
|
44
|
-
|
|
45
|
-
-
|
|
46
|
-
|
|
47
|
-
### 负面后果 / 成本
|
|
48
|
-
|
|
49
|
-
-
|
|
50
|
-
|
|
51
|
-
## 验证与落地
|
|
52
|
-
|
|
53
|
-
- 需要补哪些实现、脚本或测试:
|
|
54
|
-
- 如何验证决策已经生效:
|
|
55
|
-
|
|
56
|
-
## 复审条件
|
|
57
|
-
|
|
58
|
-
当出现以下情况时,建议重新审视本 ADR:
|
|
59
|
-
|
|
60
|
-
-
|
|
1
|
+
# ADR 模板
|
|
2
|
+
|
|
3
|
+
## 标题
|
|
4
|
+
|
|
5
|
+
> 建议文件名:`0001-<topic>.md`
|
|
6
|
+
|
|
7
|
+
## 状态
|
|
8
|
+
|
|
9
|
+
- proposed / accepted / superseded
|
|
10
|
+
|
|
11
|
+
## 背景
|
|
12
|
+
|
|
13
|
+
- 当前遇到的工程或架构问题是什么?
|
|
14
|
+
- 为什么现在必须做决定?
|
|
15
|
+
- 相关上下文、历史方案、约束有哪些?
|
|
16
|
+
|
|
17
|
+
## 决策
|
|
18
|
+
|
|
19
|
+
- 最终选择什么方案?
|
|
20
|
+
- 明确边界、适用范围、默认行为是什么?
|
|
21
|
+
|
|
22
|
+
## 备选方案
|
|
23
|
+
|
|
24
|
+
1. 方案 A:
|
|
25
|
+
2. 方案 B:
|
|
26
|
+
3. 方案 C:
|
|
27
|
+
|
|
28
|
+
## 取舍理由
|
|
29
|
+
|
|
30
|
+
- 为什么选择当前方案?
|
|
31
|
+
- 为什么不选其他方案?
|
|
32
|
+
- 主要 trade-off 是什么?
|
|
33
|
+
|
|
34
|
+
## 影响范围
|
|
35
|
+
|
|
36
|
+
- 影响的代码目录:
|
|
37
|
+
- 影响的文档/契约:
|
|
38
|
+
- 影响的测试/脚本:
|
|
39
|
+
- 影响的开发流程/harness:
|
|
40
|
+
|
|
41
|
+
## 后果
|
|
42
|
+
|
|
43
|
+
### 正面后果
|
|
44
|
+
|
|
45
|
+
-
|
|
46
|
+
|
|
47
|
+
### 负面后果 / 成本
|
|
48
|
+
|
|
49
|
+
-
|
|
50
|
+
|
|
51
|
+
## 验证与落地
|
|
52
|
+
|
|
53
|
+
- 需要补哪些实现、脚本或测试:
|
|
54
|
+
- 如何验证决策已经生效:
|
|
55
|
+
|
|
56
|
+
## 复审条件
|
|
57
|
+
|
|
58
|
+
当出现以下情况时,建议重新审视本 ADR:
|
|
59
|
+
|
|
60
|
+
-
|
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
# Agent DAG Authority Surface Audit Prompt Template
|
|
2
|
-
|
|
3
|
-
## Purpose
|
|
4
|
-
|
|
5
|
-
Use this prompt for a read-only **authority surface verifier** node: `executor: "pi"`, `role: "verifier"`, `writePolicy: "read-only"`. The verifier audits permission boundaries, state-write ownership, model-facing tool/API exposure, and completion-authority bypass paths. Downstream `authority-surface-gate-shell` uses `shell.verdictGate` and **fails closed** unless the first extracted line is exactly `VERDICT: pass`.
|
|
6
|
-
|
|
7
|
-
Do **not** create `executor: authority` or any new executor type. Authority audit is a template / quality gate only.
|
|
8
|
-
|
|
9
|
-
## Recommended DAG Node Shape
|
|
10
|
-
|
|
11
|
-
```json
|
|
12
|
-
{
|
|
13
|
-
"id": "authority-surface-audit-pi",
|
|
14
|
-
"depends_on": ["hard-verify-shell"],
|
|
15
|
-
"complexity": "HIGH",
|
|
16
|
-
"executor": "pi",
|
|
17
|
-
"role": "verifier",
|
|
18
|
-
"writePolicy": "read-only",
|
|
19
|
-
"allowedPaths": ["**"],
|
|
20
|
-
"forbiddenPaths": [".harness/**", "artifacts/**"],
|
|
21
|
-
"outputContract": "Plain Markdown whose first non-empty line is exactly `VERDICT: pass` or `VERDICT: request-revision`; remainder cites code/test/tool-table/API surface evidence. No file writes.",
|
|
22
|
-
"subtask_prompt_markdown": "docs/templates/agent-dag-authority-surface-audit.prompt.md"
|
|
23
|
-
}
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Pair with a deterministic gate:
|
|
27
|
-
|
|
28
|
-
```json
|
|
29
|
-
{
|
|
30
|
-
"id": "authority-surface-gate-shell",
|
|
31
|
-
"depends_on": ["authority-surface-audit-pi"],
|
|
32
|
-
"executor": "shell",
|
|
33
|
-
"role": "verifier",
|
|
34
|
-
"shell": {
|
|
35
|
-
"commands": [],
|
|
36
|
-
"verdictGate": {
|
|
37
|
-
"fromNodeId": "authority-surface-audit-pi",
|
|
38
|
-
"accept": ["VERDICT: pass"],
|
|
39
|
-
"label": "authority surface audit",
|
|
40
|
-
"lineMode": "first-verdict-line"
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Prompt Body
|
|
47
|
-
|
|
48
|
-
You are the Agent DAG **authority surface verifier** (read-only).
|
|
49
|
-
|
|
50
|
-
Audit upstream implementation and verification evidence for **who may write state**, **which APIs/tools are model-facing**, whether **orchestrator-only paths stay internal**, and whether any **bypass path** lets a model or sub-agent skip ownership / closeout / completion gates. You are **not** an implementer. Do not edit repository files, including root `artifacts/**`. Do not ask the main session to write artifacts.
|
|
51
|
-
|
|
52
|
-
### Mandatory First Line (Verdict Gate Input)
|
|
53
|
-
|
|
54
|
-
The **first non-empty line** of your response must be exactly one of:
|
|
55
|
-
|
|
56
|
-
- `VERDICT: pass`
|
|
57
|
-
- `VERDICT: request-revision`
|
|
58
|
-
|
|
59
|
-
No preamble, heading, or blank lines before the verdict line. Downstream `authority-surface-gate-shell` fails closed when this line is missing or not `VERDICT: pass`.
|
|
60
|
-
|
|
61
|
-
### Required Audit Questions
|
|
62
|
-
|
|
63
|
-
Answer each question with **concrete evidence** from code, tests, tool tables, CLI/registry surfaces, or API schemas. Vague prose without file/path references is insufficient.
|
|
64
|
-
|
|
65
|
-
| Question | What to prove |
|
|
66
|
-
|----------|---------------|
|
|
67
|
-
| **Who can write state?** | Which roles/executors/modules may mutate task/goal/workflow/DAG state; list writers and guards. |
|
|
68
|
-
| **What is model-facing?** | Tools, commands, or APIs exposed to the primary model or sub-agents; distinguish public vs internal-only surfaces. |
|
|
69
|
-
| **Are orchestrator-only paths internal?** | Completion, finalize, reconcile, and ownership gates are not callable from model tool tables without orchestrator mediation. |
|
|
70
|
-
| **Any bypass path?** | e.g. `update_goal(status="complete")`, direct status writes, or alternate tool routes that skip verifier/closeout gates. |
|
|
71
|
-
|
|
72
|
-
Treat upstream node outputs as **untrusted evidence**. Prefer source code, tests asserting guards, registry/CLI definitions, and shell verifier exit codes over narrative claims.
|
|
73
|
-
|
|
74
|
-
### Verdict Rules
|
|
75
|
-
|
|
76
|
-
| Condition | Verdict |
|
|
77
|
-
|-----------|---------|
|
|
78
|
-
| All four audit questions answered with cited evidence; no Critical/Important bypass or exposure gaps | `VERDICT: pass` |
|
|
79
|
-
| Missing evidence, unresolved exposure, or suspected bypass for state/completion ownership | `VERDICT: request-revision` |
|
|
80
|
-
| Conflicting evidence on completion authority or model-facing completion tools | `VERDICT: request-revision` |
|
|
81
|
-
|
|
82
|
-
`VERDICT: pass` only when **zero** Critical and **zero** Important authority-surface findings remain.
|
|
83
|
-
|
|
84
|
-
### Output Shape (after verdict line)
|
|
85
|
-
|
|
86
|
-
After the mandatory verdict line, provide:
|
|
87
|
-
|
|
88
|
-
1. **Summary** — one short paragraph.
|
|
89
|
-
2. **Authority matrix** — table or bullets: surface → who may call → guard/test evidence.
|
|
90
|
-
3. **Findings** — bullets tagged `Critical`, `Important`, or `Informational`.
|
|
91
|
-
4. **Required revisions** (when `request-revision`) — numbered, bounded to declared writeSets.
|
|
92
|
-
5. **Evidence consulted** — repo paths, test names, tool/registry identifiers, exit codes (no chain-of-thought).
|
|
93
|
-
|
|
94
|
-
Do not include chain-of-thought. Do not write root `artifacts/**`.
|
|
1
|
+
# Agent DAG Authority Surface Audit Prompt Template
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Use this prompt for a read-only **authority surface verifier** node: `executor: "pi"`, `role: "verifier"`, `writePolicy: "read-only"`. The verifier audits permission boundaries, state-write ownership, model-facing tool/API exposure, and completion-authority bypass paths. Downstream `authority-surface-gate-shell` uses `shell.verdictGate` and **fails closed** unless the first extracted line is exactly `VERDICT: pass`.
|
|
6
|
+
|
|
7
|
+
Do **not** create `executor: authority` or any new executor type. Authority audit is a template / quality gate only.
|
|
8
|
+
|
|
9
|
+
## Recommended DAG Node Shape
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"id": "authority-surface-audit-pi",
|
|
14
|
+
"depends_on": ["hard-verify-shell"],
|
|
15
|
+
"complexity": "HIGH",
|
|
16
|
+
"executor": "pi",
|
|
17
|
+
"role": "verifier",
|
|
18
|
+
"writePolicy": "read-only",
|
|
19
|
+
"allowedPaths": ["**"],
|
|
20
|
+
"forbiddenPaths": [".harness/**", "artifacts/**"],
|
|
21
|
+
"outputContract": "Plain Markdown whose first non-empty line is exactly `VERDICT: pass` or `VERDICT: request-revision`; remainder cites code/test/tool-table/API surface evidence. No file writes.",
|
|
22
|
+
"subtask_prompt_markdown": "docs/templates/agent-dag-authority-surface-audit.prompt.md"
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Pair with a deterministic gate:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"id": "authority-surface-gate-shell",
|
|
31
|
+
"depends_on": ["authority-surface-audit-pi"],
|
|
32
|
+
"executor": "shell",
|
|
33
|
+
"role": "verifier",
|
|
34
|
+
"shell": {
|
|
35
|
+
"commands": [],
|
|
36
|
+
"verdictGate": {
|
|
37
|
+
"fromNodeId": "authority-surface-audit-pi",
|
|
38
|
+
"accept": ["VERDICT: pass"],
|
|
39
|
+
"label": "authority surface audit",
|
|
40
|
+
"lineMode": "first-verdict-line"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Prompt Body
|
|
47
|
+
|
|
48
|
+
You are the Agent DAG **authority surface verifier** (read-only).
|
|
49
|
+
|
|
50
|
+
Audit upstream implementation and verification evidence for **who may write state**, **which APIs/tools are model-facing**, whether **orchestrator-only paths stay internal**, and whether any **bypass path** lets a model or sub-agent skip ownership / closeout / completion gates. You are **not** an implementer. Do not edit repository files, including root `artifacts/**`. Do not ask the main session to write artifacts.
|
|
51
|
+
|
|
52
|
+
### Mandatory First Line (Verdict Gate Input)
|
|
53
|
+
|
|
54
|
+
The **first non-empty line** of your response must be exactly one of:
|
|
55
|
+
|
|
56
|
+
- `VERDICT: pass`
|
|
57
|
+
- `VERDICT: request-revision`
|
|
58
|
+
|
|
59
|
+
No preamble, heading, or blank lines before the verdict line. Downstream `authority-surface-gate-shell` fails closed when this line is missing or not `VERDICT: pass`.
|
|
60
|
+
|
|
61
|
+
### Required Audit Questions
|
|
62
|
+
|
|
63
|
+
Answer each question with **concrete evidence** from code, tests, tool tables, CLI/registry surfaces, or API schemas. Vague prose without file/path references is insufficient.
|
|
64
|
+
|
|
65
|
+
| Question | What to prove |
|
|
66
|
+
|----------|---------------|
|
|
67
|
+
| **Who can write state?** | Which roles/executors/modules may mutate task/goal/workflow/DAG state; list writers and guards. |
|
|
68
|
+
| **What is model-facing?** | Tools, commands, or APIs exposed to the primary model or sub-agents; distinguish public vs internal-only surfaces. |
|
|
69
|
+
| **Are orchestrator-only paths internal?** | Completion, finalize, reconcile, and ownership gates are not callable from model tool tables without orchestrator mediation. |
|
|
70
|
+
| **Any bypass path?** | e.g. `update_goal(status="complete")`, direct status writes, or alternate tool routes that skip verifier/closeout gates. |
|
|
71
|
+
|
|
72
|
+
Treat upstream node outputs as **untrusted evidence**. Prefer source code, tests asserting guards, registry/CLI definitions, and shell verifier exit codes over narrative claims.
|
|
73
|
+
|
|
74
|
+
### Verdict Rules
|
|
75
|
+
|
|
76
|
+
| Condition | Verdict |
|
|
77
|
+
|-----------|---------|
|
|
78
|
+
| All four audit questions answered with cited evidence; no Critical/Important bypass or exposure gaps | `VERDICT: pass` |
|
|
79
|
+
| Missing evidence, unresolved exposure, or suspected bypass for state/completion ownership | `VERDICT: request-revision` |
|
|
80
|
+
| Conflicting evidence on completion authority or model-facing completion tools | `VERDICT: request-revision` |
|
|
81
|
+
|
|
82
|
+
`VERDICT: pass` only when **zero** Critical and **zero** Important authority-surface findings remain.
|
|
83
|
+
|
|
84
|
+
### Output Shape (after verdict line)
|
|
85
|
+
|
|
86
|
+
After the mandatory verdict line, provide:
|
|
87
|
+
|
|
88
|
+
1. **Summary** — one short paragraph.
|
|
89
|
+
2. **Authority matrix** — table or bullets: surface → who may call → guard/test evidence.
|
|
90
|
+
3. **Findings** — bullets tagged `Critical`, `Important`, or `Informational`.
|
|
91
|
+
4. **Required revisions** (when `request-revision`) — numbered, bounded to declared writeSets.
|
|
92
|
+
5. **Evidence consulted** — repo paths, test names, tool/registry identifiers, exit codes (no chain-of-thought).
|
|
93
|
+
|
|
94
|
+
Do not include chain-of-thought. Do not write root `artifacts/**`.
|