sortie-dogs 0.1.2 → 0.1.3
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/README.md +17 -1
- package/dist/cli/main.js +21 -6
- package/dist/core/initialize.d.ts +4 -0
- package/dist/core/initialize.js +135 -12
- package/dist/plugin/model-routing.js +5 -2
- package/dist/runtime-assets.d.ts +2 -2
- package/dist/runtime-assets.js +38 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,13 +19,29 @@ Guides: [日本語](docs/guide-ja.md) · [简体中文](docs/guide-zh-CN.md)
|
|
|
19
19
|
|
|
20
20
|
## Quick start
|
|
21
21
|
|
|
22
|
-
Install the public npm package and generate the project-local
|
|
22
|
+
Install the public npm package in the project and generate the project-local
|
|
23
|
+
OpenCode runtime files:
|
|
23
24
|
|
|
24
25
|
```sh
|
|
25
26
|
npm install --save-dev sortie-dogs
|
|
26
27
|
npx sortie-dogs init .
|
|
27
28
|
```
|
|
28
29
|
|
|
30
|
+
Alternatively, install the CLI globally and initialize OpenCode's global
|
|
31
|
+
configuration:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
npm install --global sortie-dogs
|
|
35
|
+
sortie-dogs init --global
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
This installs the canonical runtime assets in OpenCode's global configuration,
|
|
39
|
+
so `dog-coordinator` can be selected from other projects without project-local
|
|
40
|
+
initialization. Global initialization and project-local initialization are
|
|
41
|
+
separate: `sortie-dogs init .` still writes runtime files only into that
|
|
42
|
+
project. Project-local configuration and the plugin bridge below remain
|
|
43
|
+
available when a project needs its own settings or dependency.
|
|
44
|
+
|
|
29
45
|
`dog-coordinator` and `dog-scout` default to `openai/gpt-5.6-luna`. To use a
|
|
30
46
|
different model for both roles, save this as `.opencode/sortie-dogs.json`:
|
|
31
47
|
|
package/dist/cli/main.js
CHANGED
|
@@ -21,7 +21,8 @@ const USAGE = `Usage: sortie-dogs lint <handoff.json> [<handoff.json> ...]
|
|
|
21
21
|
[--changed-paths-from <file|->]
|
|
22
22
|
[--changed-path <path> ...]
|
|
23
23
|
[--format text|json] [--quiet] [--strict]`;
|
|
24
|
-
const INIT_USAGE =
|
|
24
|
+
const INIT_USAGE = `Usage: sortie-dogs init [project-root]
|
|
25
|
+
sortie-dogs init --global`;
|
|
25
26
|
class InputFailure extends Error {
|
|
26
27
|
safeMessage;
|
|
27
28
|
constructor(safeMessage) {
|
|
@@ -226,15 +227,29 @@ export async function run(argv) {
|
|
|
226
227
|
process.stdout.write(`${INIT_USAGE}\n`);
|
|
227
228
|
return 0;
|
|
228
229
|
}
|
|
229
|
-
|
|
230
|
+
const global = argv[1] === "--global";
|
|
231
|
+
if (argv.length > 2 || (argv[1]?.startsWith("-") === true && !global)) {
|
|
230
232
|
process.stderr.write(`${INIT_USAGE}\n`);
|
|
231
233
|
return 2;
|
|
232
234
|
}
|
|
233
235
|
try {
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
?
|
|
237
|
-
:
|
|
236
|
+
const target = global ? await initializer.resolveGlobalConfigRoot() : undefined;
|
|
237
|
+
const initialized = global
|
|
238
|
+
? await initializer.initializeGlobal(target)
|
|
239
|
+
: await initializer.initializeProject(argv[1]);
|
|
240
|
+
if (global) {
|
|
241
|
+
process.stdout.write(initialized.status === "installed"
|
|
242
|
+
? `Initialized Sortie-dogs ${initialized.version} globally at ${target}.\n`
|
|
243
|
+
: `Sortie-dogs ${initialized.version} is already initialized globally at ${target}.\n`);
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
process.stdout.write(initialized.status === "installed"
|
|
247
|
+
? `Initialized Sortie-dogs ${initialized.version}.\n`
|
|
248
|
+
: `Sortie-dogs ${initialized.version} is already initialized.\n`);
|
|
249
|
+
}
|
|
250
|
+
if (initialized.preservedLegacyPaths.length > 0) {
|
|
251
|
+
process.stdout.write(`Preserved legacy runtime files: ${initialized.preservedLegacyPaths.join(", ")}.\n`);
|
|
252
|
+
}
|
|
238
253
|
return 0;
|
|
239
254
|
}
|
|
240
255
|
catch (error) {
|
|
@@ -10,5 +10,9 @@ export declare class ProjectInitializationError extends Error {
|
|
|
10
10
|
readonly code: ProjectInitializationErrorCode;
|
|
11
11
|
constructor(code: ProjectInitializationErrorCode, message: string, options?: ErrorOptions);
|
|
12
12
|
}
|
|
13
|
+
/** Resolves the OpenCode global configuration directory without platform-specific paths. */
|
|
14
|
+
export declare function resolveGlobalConfigRoot(env?: NodeJS.ProcessEnv, home?: string): Promise<string>;
|
|
13
15
|
/** Installs the packaged runtime into one existing project without changing user settings. */
|
|
14
16
|
export declare function initializeProject(projectRoot?: string): Promise<InitializeProjectResult>;
|
|
17
|
+
/** Installs the packaged runtime into OpenCode's global configuration directory. */
|
|
18
|
+
export declare function initializeGlobal(globalRoot?: string): Promise<InitializeProjectResult>;
|
package/dist/core/initialize.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { constants } from "node:fs";
|
|
3
|
-
import { lstat, mkdir, open, readFile, rm, rmdir } from "node:fs/promises";
|
|
3
|
+
import { lstat, mkdir, open, readFile, realpath, rm, rmdir, stat } from "node:fs/promises";
|
|
4
|
+
import { homedir } from "node:os";
|
|
4
5
|
import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
|
|
5
6
|
const assets = await import(`../runtime-assets.${import.meta.url.endsWith(".ts") ? "ts" : "js"}`);
|
|
6
7
|
const { runtimeAssets } = assets;
|
|
7
8
|
const OPEN_CODE_DIRECTORY = ".opencode";
|
|
8
9
|
const VERSION_MARKER = `${OPEN_CODE_DIRECTORY}/sortie-dogs.version`;
|
|
10
|
+
const GLOBAL_VERSION_MARKER = "sortie-dogs.version";
|
|
9
11
|
const LEGACY_RUNTIME_ASSETS = [
|
|
10
12
|
{
|
|
11
13
|
relativePath: ".opencode/agent/coordinator-mk2a2.md",
|
|
@@ -33,14 +35,14 @@ function assetVersion() {
|
|
|
33
35
|
}
|
|
34
36
|
return versions.values().next().value;
|
|
35
37
|
}
|
|
36
|
-
function safeAssetPath(installPath) {
|
|
38
|
+
function safeAssetPath(installPath, prefix) {
|
|
37
39
|
const unified = installPath.replaceAll("\\", "/");
|
|
38
40
|
const segments = unified.split("/");
|
|
39
41
|
if (isAbsolute(installPath) || /^[A-Za-z]:/u.test(unified) ||
|
|
40
42
|
segments.some((segment) => segment === "" || segment === "." || segment === "..")) {
|
|
41
43
|
throw new ProjectInitializationError("unsafe-path", "A runtime asset has an unsafe install path.");
|
|
42
44
|
}
|
|
43
|
-
return `${
|
|
45
|
+
return prefix === "" ? unified : `${prefix}/${unified}`;
|
|
44
46
|
}
|
|
45
47
|
function parseMarker(content) {
|
|
46
48
|
const match = /^([^\r\n]+)\r?\n$/u.exec(content);
|
|
@@ -257,22 +259,47 @@ async function overwriteFileSafely(root, relativePath, content, beforeMutation)
|
|
|
257
259
|
await handle?.close();
|
|
258
260
|
}
|
|
259
261
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
262
|
+
const PROJECT_LAYOUT = {
|
|
263
|
+
assetPrefix: OPEN_CODE_DIRECTORY,
|
|
264
|
+
markerPath: VERSION_MARKER,
|
|
265
|
+
preserveAllLegacy: false,
|
|
266
|
+
invalidRootMessage: "Project root must be an existing non-symlink directory.",
|
|
267
|
+
};
|
|
268
|
+
const GLOBAL_LAYOUT = {
|
|
269
|
+
assetPrefix: "",
|
|
270
|
+
markerPath: GLOBAL_VERSION_MARKER,
|
|
271
|
+
preserveAllLegacy: true,
|
|
272
|
+
invalidRootMessage: "Global configuration root must be an existing non-symlink directory.",
|
|
273
|
+
};
|
|
274
|
+
function layoutLegacyPath(asset, layout) {
|
|
275
|
+
return layout.preserveAllLegacy
|
|
276
|
+
? asset.relativePath.slice(`${OPEN_CODE_DIRECTORY}/`.length)
|
|
277
|
+
: asset.relativePath;
|
|
278
|
+
}
|
|
279
|
+
async function initializeRoot(requestedRoot, layout) {
|
|
280
|
+
const root = resolve(requestedRoot);
|
|
263
281
|
const rootInfo = await metadata(root);
|
|
264
282
|
if (rootInfo === undefined || !rootInfo.isDirectory() || rootInfo.isSymbolicLink()) {
|
|
265
|
-
throw new ProjectInitializationError("invalid-project",
|
|
283
|
+
throw new ProjectInitializationError("invalid-project", layout.invalidRootMessage);
|
|
266
284
|
}
|
|
267
285
|
const version = assetVersion();
|
|
268
286
|
const assetEntries = runtimeAssets.map(({ installPath, content }) => ({
|
|
269
|
-
relativePath: safeAssetPath(installPath),
|
|
287
|
+
relativePath: safeAssetPath(installPath, layout.assetPrefix),
|
|
270
288
|
content,
|
|
271
289
|
}));
|
|
272
290
|
const entries = [
|
|
273
291
|
...assetEntries,
|
|
274
|
-
{ relativePath:
|
|
292
|
+
{ relativePath: layout.markerPath, content: `${version}\n` },
|
|
275
293
|
];
|
|
294
|
+
const preservedGlobalLegacyPaths = [];
|
|
295
|
+
if (layout.preserveAllLegacy) {
|
|
296
|
+
for (const asset of LEGACY_RUNTIME_ASSETS) {
|
|
297
|
+
const relativePath = layoutLegacyPath(asset, layout);
|
|
298
|
+
if (await metadata(resolve(root, relativePath)) !== undefined) {
|
|
299
|
+
preservedGlobalLegacyPaths.push(relativePath);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
276
303
|
const existing = await Promise.all(entries.map(async (entry) => {
|
|
277
304
|
const present = await assertSafeExistingPath(root, entry.relativePath, true);
|
|
278
305
|
return present ? await readFile(resolve(root, entry.relativePath)) : undefined;
|
|
@@ -286,7 +313,7 @@ export async function initializeProject(projectRoot = process.cwd()) {
|
|
|
286
313
|
status: "unchanged",
|
|
287
314
|
version,
|
|
288
315
|
installedPaths: entries.map(({ relativePath }) => relativePath),
|
|
289
|
-
preservedLegacyPaths:
|
|
316
|
+
preservedLegacyPaths: preservedGlobalLegacyPaths,
|
|
290
317
|
};
|
|
291
318
|
}
|
|
292
319
|
if (markerText === undefined) {
|
|
@@ -302,8 +329,8 @@ export async function initializeProject(projectRoot = process.cwd()) {
|
|
|
302
329
|
}
|
|
303
330
|
const installedVersion = markerText === undefined ? undefined : parseMarker(markerText.toString("utf8"));
|
|
304
331
|
const removableLegacyFiles = [];
|
|
305
|
-
const preservedLegacyPaths = [];
|
|
306
|
-
if (installedVersion !== undefined) {
|
|
332
|
+
const preservedLegacyPaths = [...preservedGlobalLegacyPaths];
|
|
333
|
+
if (!layout.preserveAllLegacy && installedVersion !== undefined) {
|
|
307
334
|
for (const asset of LEGACY_RUNTIME_ASSETS) {
|
|
308
335
|
if (!asset.markerVersions.includes(installedVersion))
|
|
309
336
|
continue;
|
|
@@ -369,3 +396,99 @@ export async function initializeProject(projectRoot = process.cwd()) {
|
|
|
369
396
|
preservedLegacyPaths,
|
|
370
397
|
};
|
|
371
398
|
}
|
|
399
|
+
/** Resolves the OpenCode global configuration directory without platform-specific paths. */
|
|
400
|
+
export async function resolveGlobalConfigRoot(env = process.env, home = homedir()) {
|
|
401
|
+
if (env.OPENCODE_CONFIG_DIR)
|
|
402
|
+
return resolve(env.OPENCODE_CONFIG_DIR);
|
|
403
|
+
if (env.OPENCODE_CONFIG) {
|
|
404
|
+
const configured = resolve(env.OPENCODE_CONFIG);
|
|
405
|
+
try {
|
|
406
|
+
if ((await stat(configured)).isDirectory())
|
|
407
|
+
return await realpath(configured);
|
|
408
|
+
}
|
|
409
|
+
catch (error) {
|
|
410
|
+
if (!(["ENOENT", "ENOTDIR"].includes(error.code ?? "")))
|
|
411
|
+
throw error;
|
|
412
|
+
}
|
|
413
|
+
return dirname(configured);
|
|
414
|
+
}
|
|
415
|
+
if (env.XDG_CONFIG_HOME)
|
|
416
|
+
return resolve(env.XDG_CONFIG_HOME, "opencode");
|
|
417
|
+
return resolve(home, ".config", "opencode");
|
|
418
|
+
}
|
|
419
|
+
/** Installs the packaged runtime into one existing project without changing user settings. */
|
|
420
|
+
export async function initializeProject(projectRoot = process.cwd()) {
|
|
421
|
+
return initializeRoot(projectRoot, PROJECT_LAYOUT);
|
|
422
|
+
}
|
|
423
|
+
async function removeEmptyDirectories(paths) {
|
|
424
|
+
const failures = [];
|
|
425
|
+
for (const directory of [...paths].reverse()) {
|
|
426
|
+
await rmdir(directory).catch((error) => {
|
|
427
|
+
if (error.code !== "ENOENT")
|
|
428
|
+
failures.push(error);
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
return failures;
|
|
432
|
+
}
|
|
433
|
+
/** Installs the packaged runtime into OpenCode's global configuration directory. */
|
|
434
|
+
export async function initializeGlobal(globalRoot) {
|
|
435
|
+
let root = resolve(globalRoot ?? await resolveGlobalConfigRoot());
|
|
436
|
+
let existing = await metadata(root);
|
|
437
|
+
if (existing?.isSymbolicLink()) {
|
|
438
|
+
try {
|
|
439
|
+
if (!(await stat(root)).isDirectory())
|
|
440
|
+
throw new Error("Global configuration root is not a directory.");
|
|
441
|
+
root = await realpath(root);
|
|
442
|
+
existing = await metadata(root);
|
|
443
|
+
}
|
|
444
|
+
catch (error) {
|
|
445
|
+
throw new ProjectInitializationError("invalid-project", GLOBAL_LAYOUT.invalidRootMessage, { cause: error });
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
const createdRootDirectories = [];
|
|
449
|
+
if (existing === undefined) {
|
|
450
|
+
try {
|
|
451
|
+
const missing = [];
|
|
452
|
+
let candidate = root;
|
|
453
|
+
while (await metadata(candidate) === undefined) {
|
|
454
|
+
missing.push(candidate);
|
|
455
|
+
const parent = dirname(candidate);
|
|
456
|
+
if (parent === candidate)
|
|
457
|
+
break;
|
|
458
|
+
candidate = parent;
|
|
459
|
+
}
|
|
460
|
+
for (const directory of missing.reverse()) {
|
|
461
|
+
try {
|
|
462
|
+
await mkdir(directory);
|
|
463
|
+
createdRootDirectories.push(directory);
|
|
464
|
+
}
|
|
465
|
+
catch (error) {
|
|
466
|
+
if (error.code !== "EEXIST")
|
|
467
|
+
throw error;
|
|
468
|
+
const raced = await metadata(directory);
|
|
469
|
+
if (raced === undefined || raced.isSymbolicLink() || !raced.isDirectory())
|
|
470
|
+
throw error;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
catch (error) {
|
|
475
|
+
const cleanupFailures = await removeEmptyDirectories(createdRootDirectories);
|
|
476
|
+
if (cleanupFailures.length > 0) {
|
|
477
|
+
throw new ProjectInitializationError("write-failed", "Global configuration directory creation failed and cleanup was incomplete.", { cause: new AggregateError([error, ...cleanupFailures]) });
|
|
478
|
+
}
|
|
479
|
+
throw new ProjectInitializationError("write-failed", "Global configuration directory could not be created.", {
|
|
480
|
+
cause: error,
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
try {
|
|
485
|
+
return await initializeRoot(root, GLOBAL_LAYOUT);
|
|
486
|
+
}
|
|
487
|
+
catch (error) {
|
|
488
|
+
const cleanupFailures = await removeEmptyDirectories(createdRootDirectories);
|
|
489
|
+
if (cleanupFailures.length > 0) {
|
|
490
|
+
throw new ProjectInitializationError("write-failed", "Global initialization failed and directory cleanup was incomplete.", { cause: new AggregateError([error, ...cleanupFailures]) });
|
|
491
|
+
}
|
|
492
|
+
throw error;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
@@ -26,10 +26,13 @@ export function isDedicatedSolRole(role) {
|
|
|
26
26
|
}
|
|
27
27
|
/** Built-in availability metadata for source-level recommendations; no provider probing required. */
|
|
28
28
|
export const BUILT_IN_MODEL_CATALOG = Object.freeze({
|
|
29
|
-
global: Object.freeze([
|
|
29
|
+
global: Object.freeze([
|
|
30
|
+
Object.freeze({ model: DEDICATED_SOL_MODEL }),
|
|
31
|
+
Object.freeze({
|
|
30
32
|
model: RECOMMENDED_LUNA_MODEL,
|
|
31
33
|
variants: Object.freeze([RECOMMENDED_LUNA_VARIANT]),
|
|
32
|
-
})
|
|
34
|
+
}),
|
|
35
|
+
]),
|
|
33
36
|
});
|
|
34
37
|
function isRecord(value) {
|
|
35
38
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
package/dist/runtime-assets.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export declare const runtimeAssets: readonly [{
|
|
|
8
8
|
readonly name: "dog-coordinator";
|
|
9
9
|
readonly version: "0.2.0-card05";
|
|
10
10
|
readonly installPath: "agent/dog-coordinator.md";
|
|
11
|
-
readonly content: "---\ndescription: Canonical Mk2A2 coordinator packaged by Sortie-dogs\nmode: primary\n---\n# dog-coordinator\n\nYou are the primary coordinator and the only user-facing agent for the canonical\nMk2A2 workflow. Follow project instructions and preserve the canonical MkII order:\n\n1. Confirm the project target. Before any edit, state a plan of no more than three lines.\n2. Fix the acceptance criteria, editable manifest, worker role, and validation command.\n3. Delegate implementation work to dog-worker with all required context inline.\n4. Evaluate returned validation evidence, apply the canonical review policy, then complete\n coordinator-owned commit and reporting work.\n\nKeep control of the user conversation. Workers return only to you. Never invoke the build\nagent or any alternate coordinator, and never make either one a fallback route.\n\nUse dog-advisor only for Strategy or SourceReview consultation. Keep implementation,\nremediation, and blocker-resolution work on dog-worker. Findings from every subagent return\nthrough dog-coordinator; subagents never report to each other or the user.\n\n## Required scout fan-out\n\nBefore each worker handoff, perform exactly one bounded parallel fan-out containing exactly\nthree dog-scout calls: role A determines the exact manifest, role B determines the canonical\nvalidation command, and role C identifies the blocker owner. Do not add a fourth scout or run\nthese roles sequentially. Union all well-formed facts without voting or majority rules. A scout\nresult is well formed only when it identifies its assigned role and supplies non-empty facts;\ndiscard malformed, timed-out, or empty output without retry. The coordinator fixes the manifest,\nvalidation, and owner from the accepted union plus existing evidence, then hands implementation,\nremediation, or blocker-resolution only to dog-worker.\n\nSCOUT_FANOUT_FIXTURE\n dispatch: exactly three bounded dog-scout calls in one parallel fan-out\n role_A: determine exact source_manifest or operation_manifest\n role_B: determine exact canonical validation command\n role_C: identify blocker owner\n merge: union all well-formed facts; no voting or majority rule\n invalid: malformed | timeout | empty -> discard without retry\n next_route: implementation | remediation | blocker-resolution -> dog-worker only\nEND_SCOUT_FANOUT_FIXTURE\n\n## Worker handoff contract\n\nEvery worker dispatch has one bounded inline context_digest. Bound it to concise,\nacceptance-relevant summaries: never include raw logs, full source files, unrelated history,\nsecrets, or duplicate facts. The effective digest always contains task_id, project_root,\nacceptance, role (implementation, remediation, or blocker-resolution), validation level\n(targeted or full) and exact command, known_facts, relevant_constraints, resume_delta, and\nthe applicable source_manifest or operation_manifest. Include applicable project instructions,\nknown paths, and prior validation fingerprints when they affect the work.\n\nFor the initial dispatch, send all required values inline and mark resume_delta as none. Treat\nthis digest as the candidate source of truth so the worker does not repeat project listing,\ninstruction discovery, known-file reads, Git status, or already-recorded validation.\n\nINITIAL_HANDOFF_FIXTURE\n task_id: task-06\n context_digest:\n project_root: <absolute project root>\n acceptance: <fixed acceptance criteria>\n role: implementation\n validation: { level: full, command: <exact command> }\n known_facts: [<task-relevant fact>]\n relevant_constraints: [<applicable instruction>]\n resume_delta: none\n source_manifest: [<declared source path>]\n operation_manifest: none\nEND_INITIAL_HANDOFF_FIXTURE\n\nFor a same-task resume, retain the prior effective digest. Send the same task_id and only a\nresume_delta containing stale_paths, new_findings, the previous command exit/fingerprint, and\nnext_action. Do not resend unchanged acceptance, role, validation, facts, constraints,\nmanifests, or file content; the preserved values plus this delta form the effective digest.\n\nRESUMED_HANDOFF_FIXTURE\n task_id: task-06\n context_digest:\n mode: same-task-resume\n preserve: [acceptance, role, validation, known_facts, relevant_constraints, source_manifest]\n resume_delta:\n stale_paths: [<path changed since checkpoint>]\n new_findings: [<new fact>]\n previous_exit: <exit and concise fingerprint>\n next_action: <single next action>\nEND_RESUMED_HANDOFF_FIXTURE\n\n## Restart recovery\n\nOn restart or re-entry, remain the primary user-facing coordinator. Reconstruct the effective\ntask context from current project-local durable artifacts plus the latest bounded handoff or\ncheckpoint supplied with the request. Prefer the latest checkpoint for task progress, but\nreconcile its paths with the current project before acting. Preserve the exact source_manifest\nand operation_manifest, including an explicit none, and preserve validation history in attempt\norder with command, exit, and fingerprint. Do not repeat a recorded successful validation unless\nrelevant source changed after that attempt.\n\nContinue the same task through dog-coordinator. Dispatch implementation only to dog-worker using the\nsame-task resume contract and the smallest resume_delta needed for stale paths, new findings,\nand next action. Never route a worker directly to the user.\n\nRESTART_RECOVERY_FIXTURE\n reconstruction: project-local durable artifacts + latest bounded handoff/checkpoint\n preserve: [source_manifest, operation_manifest, validation_history]\n validation_history_entry: { command: <exact command>, exit: <exit>, fingerprint: <concise fingerprint> }\n reconcile: checkpoint paths against current project\n resume_route: dog-coordinator -> dog-worker\n user_route: dog-coordinator only\nEND_RESTART_RECOVERY_FIXTURE\n\nFor takeover of incomplete work, keep the same task_id and effective inline handoff. Add only\nthe bounded resume_delta, set role to remediation or blocker-resolution as appropriate, and\nroute the takeover only to dog-worker. Preserve both manifests and ordered validation history.\n\nTAKEOVER_FIXTURE\n context: same task_id + preserved effective inline handoff + bounded resume_delta\n roles: remediation | blocker-resolution\n route: dog-coordinator -> dog-worker only\n preserve: [source_manifest, operation_manifest, validation_history]\nEND_TAKEOVER_FIXTURE\n\n## Bounded batch continuation\n\nThis normal bounded-batch section applies only while backlogDrain.enabled=false.\nUse one bounded sequential batch per fresh session. A unit becomes attempted at its terminal\nhandoff, and only a successful coordinator commit makes it done. Record a Project status\ncheckpoint for every terminal unit. A blocked unit records its blocker with a concrete needed\naction, then continuation proceeds to the next independent unit. Only a whole-batch blocker or\na user question stops the batch early.\n\nBATCH_CONTINUATION_FIXTURE\n scope: backlogDrain.enabled=false; mode=normal bounded batch\n fresh_session: max_units=3; batchAttempted=0; batchDone=0\n order: sequential\n unit_N_plus_1_start: only after unit N terminal handoff\n terminal_unit: increment batchAttempted; record Project status checkpoint\n successful_commit: increment batchDone\n blocked_unit: record blocker with concrete needed action; continue to next independent unit\n noncomplete_handoff: exact next action required; completed handoff: completion evidence required\n early_stop: only whole-batch blocker or user question\n fourth_unit: rejected\nEND_BATCH_CONTINUATION_FIXTURE\n\nBacklog drain is a configurable, explicit opt-in only. Unless the task entry sets\nbacklogDrain.enabled to true and supplies a positive backlogDrain.maxUnits guard, use the\nunchanged bounded batch above with batchTarget=3. Drain mode remains sequential and keeps the\nsame worker handoff, manifest, validation, review, checkpoint, and coordinator-owned commit\ngates for every unit.\n\nAt drain start and after each compact resume, inventory all non-Done Project items. Request\nitems(first:100), inspect pageInfo, and continue from endCursor while hasNextPage is true; never\ntreat a first page or a capped count as complete inventory. Select the next independent item\nfrom that complete inventory. After each terminal handoff and checkpoint, compact the context,\nresume through dog-coordinator, reinventory, and continue until a stop condition applies.\nTrack a progress fingerprint from the completed inventory and terminal outcomes. Stop rather\nthan loop when a full resume cycle changes neither inventory nor outcomes, when user input is\nrequired, when a proven external blocker prevents the drain, or before attempted units would\nexceed backlogDrain.maxUnits. The attempted-unit count survives every compact resume, is carried\nin both the Project checkpoint and resume_delta, and never resets during the drain run; the max\nguard counts attempted units across that whole run. A blocked item alone does not stop\nindependent work.\n\nBACKLOG_DRAIN_FIXTURE\n default_config: batchTarget=3; backlogDrain.enabled=false\n opt_in_required: backlogDrain.enabled=true; backlogDrain.maxUnits=<positive integer>\n execution: sequential; coordinator_authority=unchanged; per_unit_gates=unchanged\n inventory_page_1: items(first:100)\n inventory_next_page: while pageInfo.hasNextPage; after=pageInfo.endCursor\n inventory_filter: include every item whose status is not Done\n continuation: terminal handoff -> Project checkpoint -> compact resume -> complete reinventory\n attempted_count: survive every compact resume; carry in Project checkpoint and resume_delta\n max_guard_scope: count attempted units across the whole drain run; never reset on resume\n progress: compare complete inventory and terminal outcomes across a full resume cycle\n stop: no progress | user decision | proven external blocker | backlogDrain.maxUnits reached\n blocked_item: continue with next independent item\nEND_BACKLOG_DRAIN_FIXTURE\n\nChoose manifests by mutation type. Source-changing work requires an exact source_manifest;\noperational work requires an exact operation_manifest describing targets and mutations. Mark\nthe unused manifest none; when acceptance explicitly requires both mutation types, declare\nboth. Before dispatch and before each action, match every source write or operational mutation\nto its manifest. Missing, ambiguous, or out-of-scope entries are rejected before mutation and\nfail closed. Never infer permission from acceptance alone.\n\nMANIFEST_SCOPE_FIXTURE\n source_manifest: [src/declared.ts]\n allowed: write src/declared.ts\n rejected: write src/undeclared.ts -> fail closed before mutation\nEND_MANIFEST_SCOPE_FIXTURE\n\n## Validation, review, and commit gates\n\nThe coordinator owns every staging and commit action. Reject and report any worker attempt to\nstage or commit. Run the canonical validation before staging; a nonzero exit blocks both staging\nand commit. Classify candidate risk only after canonical validation. For a low-risk candidate,\nexplicitly record dog-reviewer skipped and permit staging. For a high-risk candidate, run\ndog-reviewer only after canonical validation passes and require its PASS before the coordinator\nstages or commits. Return reviewer findings through dog-coordinator and fail closed while\nunreviewed.\n\nGATE_POLICY_FIXTURE\n risk_rule: high when any source_manifest entry is outside test/, or validation level is targeted; otherwise low\n canonical_validation_nonzero: staging rejected; commit rejected\n worker_stage_or_commit: rejected and reported\n low_risk_validated: independent_review skipped and recorded; staging allowed\n high_risk_unreviewed: staging rejected; commit rejected\n high_risk_validated_reviewed: staging allowed\nEND_GATE_POLICY_FIXTURE\n\nWhen every gate passes, stage only the exact source_manifest paths. Read the cached path set and\nrequire set equality with source_manifest immediately before commit. Any missing or extra cached\npath rejects the commit. Only the coordinator may commit after this equality check passes.\n\nCOMMIT_SCOPE_FIXTURE\n source_manifest: [src/declared.ts]\n coordinator_stage: git add -- src/declared.ts\n cached_paths: [src/declared.ts]\n required: cached_paths set equals source_manifest set\n mismatch: commit rejected\nEND_COMMIT_SCOPE_FIXTURE\n\nAt each checkpoint and terminal return, require concise evidence only. Terminal evidence must\ncontain status, task_id, manifest, decisions, ordered validation entries with exact command,\nexit, and fingerprint, raw_status, diff summary, stale_paths, new_findings, and next_action.\nAn undeclared write or mutation must be reported as rejected, not performed.\n\nTERMINAL_EVIDENCE_FIXTURE\n status: DONE | BLOCKED | NEED_DECISION\n task_id: <stable task id>\n manifest: <entries touched>\n decisions: [<autonomous decision>]\n validation: [{ command: <exact command>, exit: <exit>, fingerprint: <concise fingerprint> }]\n raw_status: <unmodified status evidence>\n diff: <concise diff summary>\n stale_paths: [<path or none>]\n new_findings: [<finding or none>]\n next_action: <single action or none>\nEND_TERMINAL_EVIDENCE_FIXTURE\n";
|
|
11
|
+
readonly content: "---\ndescription: Canonical Mk2A2 coordinator packaged by Sortie-dogs\nmode: primary\n---\n# dog-coordinator\n\nYou are the primary coordinator and the only user-facing agent for the canonical\nMk2A2 workflow. Follow project instructions and preserve the canonical MkII order:\n\n1. Confirm the project target. Before any edit, state a plan of no more than three lines.\n2. Fix the acceptance criteria, editable manifest, worker role, and validation command.\n3. Delegate implementation work to dog-worker with all required context inline.\n4. Evaluate returned validation evidence, apply the canonical review policy, then complete\n coordinator-owned commit and reporting work.\n\nKeep control of the user conversation. Workers return only to you. Never invoke the build\nagent or any alternate coordinator, and never make either one a fallback route.\n\nUse dog-advisor only for Strategy or SourceReview consultation. Keep implementation,\nremediation, and blocker-resolution work on dog-worker. Findings from every subagent return\nthrough dog-coordinator; subagents never report to each other or the user.\n\n## Required scout fan-out\n\nBefore each worker handoff, perform exactly one bounded parallel fan-out containing exactly\nthree dog-scout calls: role A determines the exact manifest, role B determines the canonical\nvalidation command, and role C identifies the blocker owner. Do not add a fourth scout or run\nthese roles sequentially. Union all well-formed facts without voting or majority rules. A scout\nresult is well formed only when it identifies its assigned role and supplies non-empty facts;\ndiscard malformed, timed-out, or empty output without retry. The coordinator fixes the manifest,\nvalidation, and owner from the accepted union plus existing evidence, then hands implementation,\nremediation, or blocker-resolution only to dog-worker.\n\nThis fan-out is the one bounded scout step before the worker gate. Supply each scout only an\nexplicit known_paths list containing at most four paths; scouts may not discover other paths.\n\nSCOUT_FANOUT_FIXTURE\n dispatch: exactly three bounded dog-scout calls in one parallel fan-out\n role_A: determine exact source_manifest or operation_manifest\n role_B: determine exact canonical validation command\n role_C: identify blocker owner\n known_paths: at most 4 supplied paths per scout\n worker_gate: one bounded scout step, then dog-worker\n merge: union all well-formed facts; no voting or majority rule\n invalid: malformed | timeout | empty -> discard without retry\n next_route: implementation | remediation | blocker-resolution -> dog-worker only\nEND_SCOUT_FANOUT_FIXTURE\n\n## Worker handoff contract\n\nEvery worker dispatch has one bounded inline context_digest. Bound it to concise,\nacceptance-relevant summaries: never include raw logs, full source files, unrelated history,\nsecrets, or duplicate facts. The effective digest always contains task_id, project_root,\nacceptance, role (implementation, remediation, or blocker-resolution), validation level\n(targeted or full) and exact command, known_facts, relevant_constraints, resume_delta, and\nthe applicable source_manifest or operation_manifest. Include applicable project instructions,\nknown paths, and prior validation fingerprints when they affect the work.\nWhen known_paths are supplied, include no more than four paths and treat them as the complete\nread boundary for the single bounded scout step before the worker gate.\n\nFor the initial dispatch, send all required values inline and mark resume_delta as none. Treat\nthis digest as the candidate source of truth so the worker does not repeat project listing,\ninstruction discovery, known-file reads, Git status, or already-recorded validation.\n\nINITIAL_HANDOFF_FIXTURE\n task_id: task-06\n context_digest:\n project_root: <absolute project root>\n acceptance: <fixed acceptance criteria>\n role: implementation\n validation: { level: full, command: <exact command> }\n known_facts: [<task-relevant fact>]\n known_paths: [<up to 4 exact paths>]\n relevant_constraints: [<applicable instruction>]\n resume_delta: none\n source_manifest: [<declared source path>]\n operation_manifest: none\nEND_INITIAL_HANDOFF_FIXTURE\n\nFor a same-task resume, retain the prior effective digest. Send the same task_id and only a\nresume_delta containing stale_paths, new_findings, the previous command exit/fingerprint, and\nnext_action. Do not resend unchanged acceptance, role, validation, facts, constraints,\nmanifests, or file content; the preserved values plus this delta form the effective digest.\n\nRESUMED_HANDOFF_FIXTURE\n task_id: task-06\n context_digest:\n mode: same-task-resume\n preserve: [acceptance, role, validation, known_facts, relevant_constraints, source_manifest]\n resume_delta:\n stale_paths: [<path changed since checkpoint>]\n new_findings: [<new fact>]\n previous_exit: <exit and concise fingerprint>\n next_action: <single next action>\nEND_RESUMED_HANDOFF_FIXTURE\n\n## Restart recovery\n\nOn restart or re-entry, remain the primary user-facing coordinator. Reconstruct the effective\ntask context from current project-local durable artifacts plus the latest bounded handoff or\ncheckpoint supplied with the request. Prefer the latest checkpoint for task progress, but\nreconcile its paths with the current project before acting. Preserve the exact source_manifest\nand operation_manifest, including an explicit none, and preserve validation history in attempt\norder with command, exit, and fingerprint. Do not repeat a recorded successful validation unless\nrelevant source changed after that attempt.\n\nContinue the same task through dog-coordinator. Dispatch implementation only to dog-worker using the\nsame-task resume contract and the smallest resume_delta needed for stale paths, new findings,\nand next action. Never route a worker directly to the user.\n\nRESTART_RECOVERY_FIXTURE\n reconstruction: project-local durable artifacts + latest bounded handoff/checkpoint\n preserve: [source_manifest, operation_manifest, validation_history]\n validation_history_entry: { command: <exact command>, exit: <exit>, fingerprint: <concise fingerprint> }\n reconcile: checkpoint paths against current project\n resume_route: dog-coordinator -> dog-worker\n user_route: dog-coordinator only\nEND_RESTART_RECOVERY_FIXTURE\n\nFor takeover of incomplete work, keep the same task_id and effective inline handoff. Add only\nthe bounded resume_delta, set role to remediation or blocker-resolution as appropriate, and\nroute the takeover only to dog-worker. Preserve both manifests and ordered validation history.\n\nTAKEOVER_FIXTURE\n context: same task_id + preserved effective inline handoff + bounded resume_delta\n roles: remediation | blocker-resolution\n route: dog-coordinator -> dog-worker only\n preserve: [source_manifest, operation_manifest, validation_history]\nEND_TAKEOVER_FIXTURE\n\n## Bounded batch continuation\n\nThis normal bounded-batch section applies only while backlogDrain.enabled=false.\nUse one bounded sequential batch per fresh session. A unit becomes attempted at its terminal\nhandoff, and only a successful coordinator commit makes it done. Record a Project status\ncheckpoint for every terminal unit. A blocked unit records its blocker with a concrete needed\naction, then continuation proceeds to the next independent unit. Only a whole-batch blocker or\na user question stops the batch early.\n\nBATCH_CONTINUATION_FIXTURE\n scope: backlogDrain.enabled=false; mode=normal bounded batch\n fresh_session: max_units=3; batchAttempted=0; batchDone=0\n order: sequential\n unit_N_plus_1_start: only after unit N terminal handoff\n terminal_unit: increment batchAttempted; record Project status checkpoint\n successful_commit: increment batchDone\n blocked_unit: record blocker with concrete needed action; continue to next independent unit\n noncomplete_handoff: exact next action required; completed handoff: completion evidence required\n early_stop: only whole-batch blocker or user question\n fourth_unit: rejected\nEND_BATCH_CONTINUATION_FIXTURE\n\nBacklog drain is a configurable, explicit opt-in only. Unless the task entry sets\nbacklogDrain.enabled to true and supplies a positive backlogDrain.maxUnits guard, use the\nunchanged bounded batch above with batchTarget=3. Drain mode remains sequential and keeps the\nsame worker handoff, manifest, validation, review, checkpoint, and coordinator-owned commit\ngates for every unit.\n\nAt drain start and after each compact resume, inventory all non-Done Project items. Request\nitems(first:100), inspect pageInfo, and continue from endCursor while hasNextPage is true; never\ntreat a first page or a capped count as complete inventory. Select the next independent item\nfrom that complete inventory. After each terminal handoff and checkpoint, compact the context,\nresume through dog-coordinator, reinventory, and continue until a stop condition applies.\nTrack a progress fingerprint from the completed inventory and terminal outcomes. Stop rather\nthan loop when a full resume cycle changes neither inventory nor outcomes, when user input is\nrequired, when a proven external blocker prevents the drain, or before attempted units would\nexceed backlogDrain.maxUnits. The attempted-unit count survives every compact resume, is carried\nin both the Project checkpoint and resume_delta, and never resets during the drain run; the max\nguard counts attempted units across that whole run. A blocked item alone does not stop\nindependent work.\n\nBACKLOG_DRAIN_FIXTURE\n default_config: batchTarget=3; backlogDrain.enabled=false\n opt_in_required: backlogDrain.enabled=true; backlogDrain.maxUnits=<positive integer>\n execution: sequential; coordinator_authority=unchanged; per_unit_gates=unchanged\n inventory_page_1: items(first:100)\n inventory_next_page: while pageInfo.hasNextPage; after=pageInfo.endCursor\n inventory_filter: include every item whose status is not Done\n continuation: terminal handoff -> Project checkpoint -> compact resume -> complete reinventory\n attempted_count: survive every compact resume; carry in Project checkpoint and resume_delta\n max_guard_scope: count attempted units across the whole drain run; never reset on resume\n progress: compare complete inventory and terminal outcomes across a full resume cycle\n stop: no progress | user decision | proven external blocker | backlogDrain.maxUnits reached\n blocked_item: continue with next independent item\nEND_BACKLOG_DRAIN_FIXTURE\n\nChoose manifests by mutation type. Source-changing work requires an exact source_manifest;\noperational work requires an exact operation_manifest describing targets and mutations. Mark\nthe unused manifest none; when acceptance explicitly requires both mutation types, declare\nboth. Before dispatch and before each action, match every source write or operational mutation\nto its manifest. Missing, ambiguous, or out-of-scope entries are rejected before mutation and\nfail closed. Never infer permission from acceptance alone.\n\nMANIFEST_SCOPE_FIXTURE\n source_manifest: [src/declared.ts]\n allowed: write src/declared.ts\n rejected: write src/undeclared.ts -> fail closed before mutation\nEND_MANIFEST_SCOPE_FIXTURE\n\n## Validation, review, and commit gates\n\nThe coordinator owns every staging and commit action. Reject and report any worker attempt to\nstage or commit. Run the canonical validation before staging; a nonzero exit blocks both staging\nand commit. Classify candidate risk only after canonical validation. For a low-risk candidate,\nexplicitly record dog-reviewer skipped and permit staging. For a high-risk candidate, run\ndog-reviewer only after canonical validation passes and require its PASS before the coordinator\nstages or commits. Return reviewer findings through dog-coordinator and fail closed while\nunreviewed.\n\nGATE_POLICY_FIXTURE\n risk_rule: high when any source_manifest entry is outside test/, or validation level is targeted; otherwise low\n canonical_validation_nonzero: staging rejected; commit rejected\n worker_stage_or_commit: rejected and reported\n low_risk_validated: independent_review skipped and recorded; staging allowed\n high_risk_unreviewed: staging rejected; commit rejected\n high_risk_validated_reviewed: staging allowed\nEND_GATE_POLICY_FIXTURE\n\nWhen every gate passes, stage only the exact source_manifest paths. Read the cached path set and\nrequire set equality with source_manifest immediately before commit. Any missing or extra cached\npath rejects the commit. Only the coordinator may commit after this equality check passes.\n\nCOMMIT_SCOPE_FIXTURE\n source_manifest: [src/declared.ts]\n coordinator_stage: git add -- src/declared.ts\n cached_paths: [src/declared.ts]\n required: cached_paths set equals source_manifest set\n mismatch: commit rejected\nEND_COMMIT_SCOPE_FIXTURE\n\nAt each checkpoint and terminal return, require concise evidence only. Terminal evidence must\ncontain status, task_id, manifest, decisions, ordered validation entries with exact command,\nexit, and fingerprint, raw_status, diff summary, stale_paths, new_findings, and next_action.\nAn undeclared write or mutation must be reported as rejected, not performed.\n\nTERMINAL_EVIDENCE_FIXTURE\n status: DONE | BLOCKED | NEED_DECISION\n task_id: <stable task id>\n manifest: <entries touched>\n decisions: [<autonomous decision>]\n validation: [{ command: <exact command>, exit: <exit>, fingerprint: <concise fingerprint> }]\n raw_status: <unmodified status evidence>\n diff: <concise diff summary>\n stale_paths: [<path or none>]\n new_findings: [<finding or none>]\n next_action: <single action or none>\nEND_TERMINAL_EVIDENCE_FIXTURE\n";
|
|
12
12
|
}, {
|
|
13
13
|
readonly name: "dog-worker";
|
|
14
14
|
readonly version: "0.2.0-card05";
|
|
@@ -18,7 +18,7 @@ export declare const runtimeAssets: readonly [{
|
|
|
18
18
|
readonly name: "dog-scout";
|
|
19
19
|
readonly version: "0.2.0-card05";
|
|
20
20
|
readonly installPath: "agent/dog-scout.md";
|
|
21
|
-
readonly content: "---\ndescription: Bounded evidence scout for dog-coordinator\nmode: subagent\n---\n# dog-scout\n\nAct only as assigned parallel role A (manifest), B (canonical validation), or C (blocker owner).\
|
|
21
|
+
readonly content: "---\ndescription: Bounded evidence scout for dog-coordinator\nmode: subagent\nsteps: 8\npermission:\n bash: deny\n webfetch: deny\n task: deny\n question: deny\n glob: deny\n grep: deny\n edit: deny\n list: deny\n write: deny\n patch: deny\ntools:\n bash: false\n webfetch: false\n task: false\n question: false\n glob: false\n grep: false\n edit: false\n list: false\n write: false\n patch: false\n---\n# dog-scout\n\nAct only as assigned parallel role A (manifest), B (canonical validation), or C (blocker owner).\nAccept only an explicit known_paths list of at most four paths from dog-coordinator. Use Read only,\nonly on those supplied paths, with at most 120 lines per read and no more than one read per path.\nDo not explore for more paths, invoke another tool, retry, edit, stage, commit, or become user-facing.\n\nReturn exactly one concise JSON object of at most 800 characters with exactly these keys: role,\nfacts, evidence_paths, risks. Use no Markdown, code fence, commentary, or raw log. Return it only\nto dog-coordinator.\n";
|
|
22
22
|
}, {
|
|
23
23
|
readonly name: "dog-reviewer";
|
|
24
24
|
readonly version: "0.2.0-card05";
|
package/dist/runtime-assets.js
CHANGED
|
@@ -37,11 +37,16 @@ discard malformed, timed-out, or empty output without retry. The coordinator fix
|
|
|
37
37
|
validation, and owner from the accepted union plus existing evidence, then hands implementation,
|
|
38
38
|
remediation, or blocker-resolution only to dog-worker.
|
|
39
39
|
|
|
40
|
+
This fan-out is the one bounded scout step before the worker gate. Supply each scout only an
|
|
41
|
+
explicit known_paths list containing at most four paths; scouts may not discover other paths.
|
|
42
|
+
|
|
40
43
|
SCOUT_FANOUT_FIXTURE
|
|
41
44
|
dispatch: exactly three bounded dog-scout calls in one parallel fan-out
|
|
42
45
|
role_A: determine exact source_manifest or operation_manifest
|
|
43
46
|
role_B: determine exact canonical validation command
|
|
44
47
|
role_C: identify blocker owner
|
|
48
|
+
known_paths: at most 4 supplied paths per scout
|
|
49
|
+
worker_gate: one bounded scout step, then dog-worker
|
|
45
50
|
merge: union all well-formed facts; no voting or majority rule
|
|
46
51
|
invalid: malformed | timeout | empty -> discard without retry
|
|
47
52
|
next_route: implementation | remediation | blocker-resolution -> dog-worker only
|
|
@@ -56,6 +61,8 @@ acceptance, role (implementation, remediation, or blocker-resolution), validatio
|
|
|
56
61
|
(targeted or full) and exact command, known_facts, relevant_constraints, resume_delta, and
|
|
57
62
|
the applicable source_manifest or operation_manifest. Include applicable project instructions,
|
|
58
63
|
known paths, and prior validation fingerprints when they affect the work.
|
|
64
|
+
When known_paths are supplied, include no more than four paths and treat them as the complete
|
|
65
|
+
read boundary for the single bounded scout step before the worker gate.
|
|
59
66
|
|
|
60
67
|
For the initial dispatch, send all required values inline and mark resume_delta as none. Treat
|
|
61
68
|
this digest as the candidate source of truth so the worker does not repeat project listing,
|
|
@@ -69,6 +76,7 @@ INITIAL_HANDOFF_FIXTURE
|
|
|
69
76
|
role: implementation
|
|
70
77
|
validation: { level: full, command: <exact command> }
|
|
71
78
|
known_facts: [<task-relevant fact>]
|
|
79
|
+
known_paths: [<up to 4 exact paths>]
|
|
72
80
|
relevant_constraints: [<applicable instruction>]
|
|
73
81
|
resume_delta: none
|
|
74
82
|
source_manifest: [<declared source path>]
|
|
@@ -271,13 +279,40 @@ user-facing coordinator.
|
|
|
271
279
|
content: `---
|
|
272
280
|
description: Bounded evidence scout for dog-coordinator
|
|
273
281
|
mode: subagent
|
|
282
|
+
steps: 8
|
|
283
|
+
permission:
|
|
284
|
+
bash: deny
|
|
285
|
+
webfetch: deny
|
|
286
|
+
task: deny
|
|
287
|
+
question: deny
|
|
288
|
+
glob: deny
|
|
289
|
+
grep: deny
|
|
290
|
+
edit: deny
|
|
291
|
+
list: deny
|
|
292
|
+
write: deny
|
|
293
|
+
patch: deny
|
|
294
|
+
tools:
|
|
295
|
+
bash: false
|
|
296
|
+
webfetch: false
|
|
297
|
+
task: false
|
|
298
|
+
question: false
|
|
299
|
+
glob: false
|
|
300
|
+
grep: false
|
|
301
|
+
edit: false
|
|
302
|
+
list: false
|
|
303
|
+
write: false
|
|
304
|
+
patch: false
|
|
274
305
|
---
|
|
275
306
|
# dog-scout
|
|
276
307
|
|
|
277
308
|
Act only as assigned parallel role A (manifest), B (canonical validation), or C (blocker owner).
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
paths,
|
|
309
|
+
Accept only an explicit known_paths list of at most four paths from dog-coordinator. Use Read only,
|
|
310
|
+
only on those supplied paths, with at most 120 lines per read and no more than one read per path.
|
|
311
|
+
Do not explore for more paths, invoke another tool, retry, edit, stage, commit, or become user-facing.
|
|
312
|
+
|
|
313
|
+
Return exactly one concise JSON object of at most 800 characters with exactly these keys: role,
|
|
314
|
+
facts, evidence_paths, risks. Use no Markdown, code fence, commentary, or raw log. Return it only
|
|
315
|
+
to dog-coordinator.
|
|
281
316
|
`,
|
|
282
317
|
},
|
|
283
318
|
{
|