@wrongstack/core 0.308.0 → 0.308.2
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/coordination/agents/index.js +4 -4
- package/dist/coordination/index.d.ts +1 -0
- package/dist/coordination/index.js +113 -15
- package/dist/coordination/task-boundary.d.ts +64 -0
- package/dist/core/index.js +1 -1
- package/dist/defaults/index.js +116 -19
- package/dist/execution/index.js +11 -8
- package/dist/index.d.ts +1 -1
- package/dist/index.js +127 -20
- package/dist/infrastructure/index.js +1 -1
- package/dist/storage/index.js +2 -1
- package/dist/tools/index.js +4 -4
- package/dist/types/config/ui.d.ts +1 -1
- package/dist/types/context-window.d.ts +18 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +11 -4
- package/dist/types/runtime-capability-manifest.d.ts +1 -1
- package/instructions/agents/backend.md +3 -0
- package/instructions/agents/bug-hunter.md +3 -0
- package/instructions/agents/code-reviewer.md +1 -0
- package/instructions/agents/frontend.md +2 -0
- package/instructions/agents/test.md +2 -0
- package/instructions/coordination/director-preamble.md +9 -1
- package/instructions/coordination/subagent-baseline.md +4 -0
- package/instructions/modes/code-reviewer.md +1 -1
- package/instructions/modes/debugger.md +2 -2
- package/instructions/modes/refactorer.md +2 -2
- package/instructions/modes/tester.md +2 -2
- package/instructions/system-lite.md +37 -33
- package/instructions/system-pro.md +23 -7
- package/instructions/system.md +33 -11
- package/package.json +6 -4
- package/skills/api-design/SKILL.md +26 -1
- package/skills/audit-log/SKILL.md +22 -1
- package/skills/auto-review/SKILL.md +21 -1
- package/skills/bug-hunter/SKILL.md +8 -0
- package/skills/chimera/SKILL.md +9 -0
- package/skills/data-governance/SKILL.md +25 -1
- package/skills/design-system/SKILL.md +19 -1
- package/skills/docker-deploy/SKILL.md +26 -1
- package/skills/git-flow/SKILL.md +26 -1
- package/skills/mailbox-bridge/SKILL.md +25 -1
- package/skills/mnemosyne/SKILL.md +25 -2
- package/skills/multi-agent/SKILL.md +12 -0
- package/skills/node-modern/SKILL.md +28 -1
- package/skills/observability/SKILL.md +25 -1
- package/skills/output-standards/SKILL.md +28 -1
- package/skills/plugin-author/SKILL.md +31 -1
- package/skills/prompt-engineering/SKILL.md +27 -1
- package/skills/react-modern/SKILL.md +29 -1
- package/skills/refactor-planner/SKILL.md +10 -0
- package/skills/research-web/SKILL.md +28 -1
- package/skills/sdd/SKILL.md +18 -0
- package/skills/security-scanner/SKILL.md +25 -1
- package/skills/skill-creator/SKILL.md +25 -1
- package/skills/tech-stack/SKILL.md +25 -1
- package/skills/testing/SKILL.md +25 -1
- package/skills/typescript-strict/SKILL.md +30 -1
- package/skills/wrongstack-kanban/SKILL.md +24 -0
- package/skills/wrongstack-mailbox/SKILL.md +29 -1
- package/skills/wrongstack-mailbox-mcp/SKILL.md +30 -3
package/dist/index.js
CHANGED
|
@@ -3042,6 +3042,8 @@ function expectDefined(value, label) {
|
|
|
3042
3042
|
|
|
3043
3043
|
// src/types/context-window.ts
|
|
3044
3044
|
var DEFAULT_CONTEXT_WINDOW_MODE_ID = "balanced";
|
|
3045
|
+
var LARGE_WINDOW_DEEP_MODE_THRESHOLD = 1e6;
|
|
3046
|
+
var CONTEXT_WINDOW_MODE_PINNED_META_KEY = "contextWindowModePinned";
|
|
3045
3047
|
var DEPRECATED_CONTEXT_WINDOW_MODE_ALIASES = Object.freeze({
|
|
3046
3048
|
archival: "balanced"
|
|
3047
3049
|
});
|
|
@@ -3049,7 +3051,7 @@ var CONTEXT_WINDOW_MODES = Object.freeze([
|
|
|
3049
3051
|
{
|
|
3050
3052
|
id: "balanced",
|
|
3051
3053
|
name: "Balanced",
|
|
3052
|
-
description: "Default rolling compaction: recent work stays verbatim, old tool output is trimmed.",
|
|
3054
|
+
description: "Default rolling compaction: recent work stays verbatim, old tool output is trimmed. Windows of 1M+ tokens default to Deep.",
|
|
3053
3055
|
thresholds: { warn: 0.55, soft: 0.7, hard: 0.85 },
|
|
3054
3056
|
aggressiveOn: "soft",
|
|
3055
3057
|
preserveK: 8,
|
|
@@ -3100,9 +3102,11 @@ function getContextWindowMode(id) {
|
|
|
3100
3102
|
function isContextWindowModeId(id) {
|
|
3101
3103
|
return CONTEXT_WINDOW_MODES.some((m) => m.id === id);
|
|
3102
3104
|
}
|
|
3103
|
-
function resolveContextWindowPolicy(config = {}, overrideMode) {
|
|
3105
|
+
function resolveContextWindowPolicy(config = {}, overrideMode, maxContext) {
|
|
3104
3106
|
const requested = overrideMode ?? config.mode ?? DEFAULT_CONTEXT_WINDOW_MODE_ID;
|
|
3105
|
-
const
|
|
3107
|
+
const normalized = normalizeContextWindowModeId(requested) ?? DEFAULT_CONTEXT_WINDOW_MODE_ID;
|
|
3108
|
+
const baseId = normalized === DEFAULT_CONTEXT_WINDOW_MODE_ID && typeof maxContext === "number" && maxContext >= LARGE_WINDOW_DEEP_MODE_THRESHOLD ? "deep" : normalized;
|
|
3109
|
+
const mode = expectDefined(getContextWindowMode(baseId));
|
|
3106
3110
|
return {
|
|
3107
3111
|
...mode,
|
|
3108
3112
|
thresholds: {
|
|
@@ -3532,7 +3536,8 @@ var THEME_PRESET_IDS = [
|
|
|
3532
3536
|
"poimandres",
|
|
3533
3537
|
"vitesse-dark",
|
|
3534
3538
|
"aura",
|
|
3535
|
-
"dark-plus"
|
|
3539
|
+
"dark-plus",
|
|
3540
|
+
"monochrome"
|
|
3536
3541
|
];
|
|
3537
3542
|
|
|
3538
3543
|
// src/types/default-config.ts
|
|
@@ -10269,7 +10274,7 @@ var RUNTIME_CAPABILITY_MANIFEST = [
|
|
|
10269
10274
|
id: "execution.shell",
|
|
10270
10275
|
pack: "development",
|
|
10271
10276
|
exposure: "direct",
|
|
10272
|
-
tools: ["bash", "exec", "language", "language_info", "language_package"]
|
|
10277
|
+
tools: ["bash", "exec", "pwsh", "language", "language_info", "language_package"]
|
|
10273
10278
|
},
|
|
10274
10279
|
{
|
|
10275
10280
|
id: "verification.run",
|
|
@@ -23517,7 +23522,7 @@ ${identity2}`);
|
|
|
23517
23522
|
splitLearnedEntries(rawLearned)
|
|
23518
23523
|
);
|
|
23519
23524
|
const rawBytes = Buffer.byteLength(rawLearned, "utf8");
|
|
23520
|
-
const freshEntries = meta === void 0 ? [] : rawEntries.filter((entry) => entry.capturedAt
|
|
23525
|
+
const freshEntries = meta === void 0 ? [] : rawEntries.filter((entry) => entry.capturedAt >= meta.consolidatedAt);
|
|
23521
23526
|
const stale = meta === void 0 || freshEntries.length > 0 || rawEntries.length > meta.sourceEntryCount || rawBytes > meta.sourceBytes;
|
|
23522
23527
|
if (!stale) {
|
|
23523
23528
|
learnedContent = consolidated;
|
|
@@ -25114,7 +25119,7 @@ var VERIFY_AGENTS = [
|
|
|
25114
25119
|
id: "bug-hunter",
|
|
25115
25120
|
name: "Bug Hunter",
|
|
25116
25121
|
role: "bug-hunter",
|
|
25117
|
-
tools: [...TOOLS.inspect],
|
|
25122
|
+
tools: [...TOOLS.inspect, "dead-code-scan"],
|
|
25118
25123
|
prompt: agentPrompt("bug-hunter")
|
|
25119
25124
|
},
|
|
25120
25125
|
budget: HEAVY_BUDGET,
|
|
@@ -25204,7 +25209,7 @@ var REVIEW_AGENTS = [
|
|
|
25204
25209
|
id: "code-reviewer",
|
|
25205
25210
|
name: "Code Reviewer",
|
|
25206
25211
|
role: "code-reviewer",
|
|
25207
|
-
tools: [...TOOLS.inspect, "git"],
|
|
25212
|
+
tools: [...TOOLS.inspect, "git", "codebase-impact-analysis", "codebase-invariant-check"],
|
|
25208
25213
|
prompt: agentPrompt("code-reviewer")
|
|
25209
25214
|
},
|
|
25210
25215
|
budget: MEDIUM_BUDGET,
|
|
@@ -31215,6 +31220,82 @@ function makeLLMClassifier(complete2) {
|
|
|
31215
31220
|
// src/coordination/director-basic-tools.ts
|
|
31216
31221
|
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
31217
31222
|
init_error();
|
|
31223
|
+
|
|
31224
|
+
// src/coordination/task-boundary.ts
|
|
31225
|
+
var PLACEHOLDER_VALUES = /* @__PURE__ */ new Set([
|
|
31226
|
+
"n/a",
|
|
31227
|
+
"na",
|
|
31228
|
+
"none",
|
|
31229
|
+
"nothing",
|
|
31230
|
+
"tbd",
|
|
31231
|
+
"todo",
|
|
31232
|
+
"unknown",
|
|
31233
|
+
"unspecified",
|
|
31234
|
+
"-",
|
|
31235
|
+
"\u2014",
|
|
31236
|
+
".",
|
|
31237
|
+
"as above",
|
|
31238
|
+
"same as above",
|
|
31239
|
+
"see above",
|
|
31240
|
+
"see task",
|
|
31241
|
+
"same as task"
|
|
31242
|
+
]);
|
|
31243
|
+
var isPlaceholder = (value) => PLACEHOLDER_VALUES.has(value.trim().toLowerCase());
|
|
31244
|
+
var MIN_SCOPE_CHARS = 8;
|
|
31245
|
+
var MIN_NON_GOAL_CHARS = 3;
|
|
31246
|
+
function parseTaskBoundary(raw) {
|
|
31247
|
+
const scope = typeof raw.scope === "string" ? raw.scope.trim() : "";
|
|
31248
|
+
if (scope.length < MIN_SCOPE_CHARS) {
|
|
31249
|
+
return {
|
|
31250
|
+
ok: false,
|
|
31251
|
+
error: `\`scope\` is missing or too vague \u2014 state in one concrete sentence what work this task covers (files, components, or commands in-bounds).`,
|
|
31252
|
+
hint: 'Example \u2014 scope: "Audit packages/core/src/parser/*.ts for unhandled token errors and report findings."'
|
|
31253
|
+
};
|
|
31254
|
+
}
|
|
31255
|
+
if (!Array.isArray(raw.outOfScope) || raw.outOfScope.length === 0) {
|
|
31256
|
+
return {
|
|
31257
|
+
ok: false,
|
|
31258
|
+
error: "`outOfScope` must be an array with at least one explicit non-goal \u2014 things the worker must NOT do.",
|
|
31259
|
+
hint: 'Example \u2014 outOfScope: ["Do not modify files outside packages/core", "Do not fix the bugs you find, only report them"].'
|
|
31260
|
+
};
|
|
31261
|
+
}
|
|
31262
|
+
const concrete = raw.outOfScope.filter((item) => typeof item === "string").map((item) => item.trim()).filter((item) => item.length >= MIN_NON_GOAL_CHARS && !isPlaceholder(item));
|
|
31263
|
+
if (concrete.length === 0) {
|
|
31264
|
+
return {
|
|
31265
|
+
ok: false,
|
|
31266
|
+
error: 'Every `outOfScope` entry was a placeholder ("none", "n/a", \u2026). Name at least one concrete non-goal: files or areas not to touch, changes not to make, features not to add.',
|
|
31267
|
+
hint: 'There is always an edge worth stating \u2014 "read-only, no edits", "no dependency changes", "do not touch other packages". If truly nothing comes to mind, the task is not decomposed enough yet.'
|
|
31268
|
+
};
|
|
31269
|
+
}
|
|
31270
|
+
return { ok: true, boundary: { scope, outOfScope: concrete } };
|
|
31271
|
+
}
|
|
31272
|
+
function renderTaskBoundaryBlock(boundary) {
|
|
31273
|
+
return [
|
|
31274
|
+
"\u2500\u2500 TASK BOUNDARY (hard contract \u2014 these lines define your edges) \u2500\u2500",
|
|
31275
|
+
`Scope (what this task covers):
|
|
31276
|
+
${boundary.scope}`,
|
|
31277
|
+
`Out of scope (explicit non-goals \u2014 do NOT do any of these):
|
|
31278
|
+
${boundary.outOfScope.map((item) => `- ${item}`).join("\n")}`
|
|
31279
|
+
].join("\n");
|
|
31280
|
+
}
|
|
31281
|
+
function composeBoundedTaskDescription(objective, boundary) {
|
|
31282
|
+
return `${objective.trim()}
|
|
31283
|
+
|
|
31284
|
+
${renderTaskBoundaryBlock(boundary)}`;
|
|
31285
|
+
}
|
|
31286
|
+
var taskBoundarySchemaProperties = {
|
|
31287
|
+
scope: {
|
|
31288
|
+
type: "string",
|
|
31289
|
+
description: "REQUIRED. One concrete sentence stating what work this task covers \u2014 the in-bounds. The call is rejected without it."
|
|
31290
|
+
},
|
|
31291
|
+
outOfScope: {
|
|
31292
|
+
type: "array",
|
|
31293
|
+
items: { type: "string", minLength: 1 },
|
|
31294
|
+
description: 'REQUIRED. At least one explicit non-goal the worker must NOT do (files/areas not to touch, changes not to make, features not to add). Placeholders like "none" are rejected.'
|
|
31295
|
+
}
|
|
31296
|
+
};
|
|
31297
|
+
|
|
31298
|
+
// src/coordination/director-basic-tools.ts
|
|
31218
31299
|
function makeAssignTool(director) {
|
|
31219
31300
|
const inputSchema = {
|
|
31220
31301
|
type: "object",
|
|
@@ -31223,8 +31304,9 @@ function makeAssignTool(director) {
|
|
|
31223
31304
|
description: {
|
|
31224
31305
|
type: "string",
|
|
31225
31306
|
minLength: 1,
|
|
31226
|
-
description: "The
|
|
31307
|
+
description: "The objective in natural language \u2014 what you want this subagent to do. Pair it with the required `scope` and `outOfScope` boundary fields."
|
|
31227
31308
|
},
|
|
31309
|
+
...taskBoundarySchemaProperties,
|
|
31228
31310
|
maxToolCalls: {
|
|
31229
31311
|
type: "number",
|
|
31230
31312
|
minimum: 1,
|
|
@@ -31232,20 +31314,28 @@ function makeAssignTool(director) {
|
|
|
31232
31314
|
},
|
|
31233
31315
|
timeoutMs: { type: "number", minimum: 1, description: "Optional per-task timeout in ms." }
|
|
31234
31316
|
},
|
|
31235
|
-
required: ["subagentId", "description"]
|
|
31317
|
+
required: ["subagentId", "description", "scope", "outOfScope"]
|
|
31236
31318
|
};
|
|
31237
31319
|
return {
|
|
31238
31320
|
name: "assign_task",
|
|
31239
|
-
description: "Queue a task on a previously spawned subagent. NON-BLOCKING: returns a `taskId` IMMEDIATELY \u2014 the subagent processes the task on its next iteration with its own LLM budget. The `taskId` is the durable handle for retrieving the result later via `await_tasks`, `roll_up`, or `ask_result`. Many `assign_task` calls can be in flight in parallel against the same or different subagents. This is the primary tool for fan-out work; do NOT use `delegate` to spawn multiple investigations sequentially.",
|
|
31321
|
+
description: "Queue a task on a previously spawned subagent. NON-BLOCKING: returns a `taskId` IMMEDIATELY \u2014 the subagent processes the task on its next iteration with its own LLM budget. The `taskId` is the durable handle for retrieving the result later via `await_tasks`, `roll_up`, or `ask_result`. Every assignment MUST carry an explicit boundary: `scope` (what the work covers) and `outOfScope` (at least one concrete non-goal) \u2014 the call is rejected without them, and the worker treats the rendered boundary block as a hard contract. Many `assign_task` calls can be in flight in parallel against the same or different subagents. This is the primary tool for fan-out work; do NOT use `delegate` to spawn multiple investigations sequentially.",
|
|
31240
31322
|
permission: "auto",
|
|
31241
31323
|
mutating: false,
|
|
31242
31324
|
capabilities: [ToolCapabilities.SUBAGENT_SPAWN],
|
|
31243
31325
|
inputSchema,
|
|
31244
31326
|
async execute(input) {
|
|
31245
31327
|
const i = input;
|
|
31328
|
+
const boundary = parseTaskBoundary(i);
|
|
31329
|
+
if (!boundary.ok) {
|
|
31330
|
+
return {
|
|
31331
|
+
ok: false,
|
|
31332
|
+
error: `assign_task rejected \u2014 task boundary incomplete: ${boundary.error}`,
|
|
31333
|
+
hint: boundary.hint
|
|
31334
|
+
};
|
|
31335
|
+
}
|
|
31246
31336
|
const task = {
|
|
31247
31337
|
id: randomUUID12(),
|
|
31248
|
-
description: i.description,
|
|
31338
|
+
description: composeBoundedTaskDescription(i.description, boundary.boundary),
|
|
31249
31339
|
subagentId: i.subagentId,
|
|
31250
31340
|
maxToolCalls: i.maxToolCalls,
|
|
31251
31341
|
timeoutMs: i.timeoutMs
|
|
@@ -36518,6 +36608,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
36518
36608
|
sessionPath: (sid, ext) => this.sessionPath(sid, ext)
|
|
36519
36609
|
});
|
|
36520
36610
|
this.clearLoadCache(canonical);
|
|
36611
|
+
if (id !== canonical) this.clearLoadCache(id);
|
|
36521
36612
|
}
|
|
36522
36613
|
async summarize(id, mtime) {
|
|
36523
36614
|
return summarizeSessionFile({
|
|
@@ -39081,8 +39172,8 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
39081
39172
|
withNickname(subagent, subagentId) {
|
|
39082
39173
|
const role = subagent.role ?? "subagent";
|
|
39083
39174
|
const name = subagent.name?.trim() ?? "";
|
|
39084
|
-
const
|
|
39085
|
-
if (!
|
|
39175
|
+
const isPlaceholder2 = name === "" || name.toLowerCase() === role.toLowerCase() || name === "subagent" || name === "adhoc" || name === "generic" || /^slot-/.test(name);
|
|
39176
|
+
if (!isPlaceholder2) return subagent;
|
|
39086
39177
|
const { key, display } = assignNickname(role, this.usedNicknames);
|
|
39087
39178
|
this.usedNicknames.add(key);
|
|
39088
39179
|
this.subagentNicknames.set(subagentId, key);
|
|
@@ -43318,8 +43409,9 @@ function createDelegateTool(opts) {
|
|
|
43318
43409
|
properties: {
|
|
43319
43410
|
task: {
|
|
43320
43411
|
type: "string",
|
|
43321
|
-
description: "
|
|
43412
|
+
description: "The objective \u2014 what the subagent should do, natural language, complete sentence(s). Pair it with the required `scope` and `outOfScope` boundary fields."
|
|
43322
43413
|
},
|
|
43414
|
+
...taskBoundarySchemaProperties,
|
|
43323
43415
|
role: {
|
|
43324
43416
|
type: "string",
|
|
43325
43417
|
description: rosterIds.length > 0 ? "Roster role id. Common: bug-hunter, security-scanner, refactor-planner, critic, audit-log, executor, shadow-agent, architect." : "No roster configured \u2014 pass `name` instead."
|
|
@@ -43377,12 +43469,12 @@ function createDelegateTool(opts) {
|
|
|
43377
43469
|
description: "Max fresh-worker continuations after budget exhaustion. Default 1. Each gets the prior partial report."
|
|
43378
43470
|
}
|
|
43379
43471
|
},
|
|
43380
|
-
required: ["task"]
|
|
43472
|
+
required: ["task", "scope", "outOfScope"]
|
|
43381
43473
|
};
|
|
43382
43474
|
return {
|
|
43383
43475
|
name: "delegate",
|
|
43384
43476
|
description: "Hand a piece of work to a subagent and block until it returns. This call is synchronous: the leader's iteration pauses for the full duration of the subagent's run. (Multiple `delegate` calls fired in the same assistant turn still parallelize through the provider's parallel-tool-call surface, but each one eats wall-clock time \u2014 so for fan-out you actually control, reach for the async path below.) Use `delegate` when your next step genuinely needs the subagent's verdict \u2014 a review, a fact-check, a sign-off. Has own context, own LLM call, auto-extending budget, and a partial-completion handoff path (maxHandoffs, default 1). Workers cannot recursively spawn.\n\n**Do NOT use `delegate` for long-running work.** While `delegate` is in flight, the leader is fully blocked \u2014 it cannot act on other tools, read mail, or react to the user. If the work might run for tens of minutes or hours (multi-file refactor, monorepo audit, long-running build/test, sweeping migration), the blocking call wastes the leader's time. Use the async tool family instead: `spawn_subagent` to create each worker (returns a `subagentId` immediately), `assign_task` to queue work on it (returns a `taskId` immediately), then `await_tasks` to retrieve results later. The leader keeps doing other work while the worker churns, and a worker that realizes its task will run long can mail the leader (type `steer` or `ask` via `mail_send`) saying *\"my task is going to run long, please spawn a subagent instead\"* so the leader re-dispatches asynchronously instead of waiting.\n\n**Do NOT use `delegate` for fan-out you control.** Multiple sequential `delegate` calls each block the leader, wasting wall-clock time. For independent investigations you want to run in parallel \u2014 security scan + bug hunt + perf review on the same PR \u2014 use the async tool family: `spawn_subagent` to create each worker (returns a `subagentId` immediately), `assign_task` to queue work on it (returns a `taskId` immediately), then the `await_tasks` tool with `{mode: 'any'}` to fold the first useful result into the next decision while the rest keep churning. Reach for `delegate` only when the result gates your next move AND the work is short enough that blocking the leader is acceptable.",
|
|
43385
|
-
usageHint: "Set `task` to a
|
|
43477
|
+
usageHint: "Set `task` to the objective, then make the edges explicit: `scope` (what the work covers) and `outOfScope` (at least one concrete non-goal) are REQUIRED \u2014 the call is rejected without them, and the worker treats the rendered boundary block as a hard contract. Pick `role` from roster or pass `name` for free-form. Reach for `delegate` only when the result gates your next move AND the work is short enough that blocking the leader is acceptable (minutes, not hours). For long-running work or fan-out you control, use `spawn_subagent` + `assign_task` + `await_tasks` instead. Raise `maxHandoffs` (default 1, cap 8) for multi-day or multi-refactor tasks; pass larger `timeoutMs`/`maxIterations`/`maxToolCalls` only when needed.",
|
|
43386
43478
|
permission: "auto",
|
|
43387
43479
|
mutating: false,
|
|
43388
43480
|
managesOwnTimeout: true,
|
|
@@ -43402,6 +43494,14 @@ function createDelegateTool(opts) {
|
|
|
43402
43494
|
error: "Delegation cancelled before spawn \u2014 the run was interrupted."
|
|
43403
43495
|
};
|
|
43404
43496
|
}
|
|
43497
|
+
const boundary = parseTaskBoundary(i);
|
|
43498
|
+
if (!boundary.ok) {
|
|
43499
|
+
return {
|
|
43500
|
+
ok: false,
|
|
43501
|
+
error: `delegate rejected \u2014 task boundary incomplete: ${boundary.error}`,
|
|
43502
|
+
hint: boundary.hint
|
|
43503
|
+
};
|
|
43504
|
+
}
|
|
43405
43505
|
const target = i.role ?? i.name ?? "subagent";
|
|
43406
43506
|
const launchModePreface = [
|
|
43407
43507
|
"Launch-mode guidance (delegate): you were launched via the synchronous `delegate` tool, so the leader is blocked on this call for the full duration of your run.",
|
|
@@ -43472,7 +43572,8 @@ function createDelegateTool(opts) {
|
|
|
43472
43572
|
const dir = director;
|
|
43473
43573
|
const maxHandoffs = Math.min(8, Math.max(0, Math.floor(i.maxHandoffs ?? 1)));
|
|
43474
43574
|
const handoffs = [];
|
|
43475
|
-
|
|
43575
|
+
const baseBrief = composeBoundedTaskDescription(i.task, boundary.boundary);
|
|
43576
|
+
let delegatedTask = baseBrief;
|
|
43476
43577
|
let handoffCount = 0;
|
|
43477
43578
|
for (; ; ) {
|
|
43478
43579
|
const attemptConfig = (() => {
|
|
@@ -43612,7 +43713,7 @@ function createDelegateTool(opts) {
|
|
|
43612
43713
|
remainingWork: continuation.remainingWork
|
|
43613
43714
|
});
|
|
43614
43715
|
handoffCount += 1;
|
|
43615
|
-
delegatedTask = buildHandoffTask(
|
|
43716
|
+
delegatedTask = buildHandoffTask(baseBrief, continuation, handoffCount, maxHandoffs);
|
|
43616
43717
|
continue;
|
|
43617
43718
|
}
|
|
43618
43719
|
const incomplete = result.report?.completion === "partial";
|
|
@@ -58283,7 +58384,7 @@ function readContextWindowPolicy(ctx) {
|
|
|
58283
58384
|
function installSubagentAutoCompaction(pipelines, ctx, contextConfig, events) {
|
|
58284
58385
|
const maxContext = ctx.provider?.capabilities?.maxContext ?? 0;
|
|
58285
58386
|
if (!(maxContext > 0)) return void 0;
|
|
58286
|
-
const policy = resolveContextWindowPolicy(contextConfig ?? {});
|
|
58387
|
+
const policy = resolveContextWindowPolicy(contextConfig ?? {}, void 0, maxContext);
|
|
58287
58388
|
ctx.meta ??= {};
|
|
58288
58389
|
ctx.meta["contextWindowPolicy"] = policy;
|
|
58289
58390
|
const compactor = new HybridCompactor({
|
|
@@ -97077,6 +97178,7 @@ export {
|
|
|
97077
97178
|
COMPLETED_WORK_LEDGER_MARKER,
|
|
97078
97179
|
CONFIG_BEHAVIOR_DEFAULTS,
|
|
97079
97180
|
CONTEXT_WINDOW_MODES,
|
|
97181
|
+
CONTEXT_WINDOW_MODE_PINNED_META_KEY,
|
|
97080
97182
|
CORE_RECONSTRUCT_EVENTS,
|
|
97081
97183
|
COUNCIL_JUDGE_PROMPT_PATH,
|
|
97082
97184
|
COUNCIL_REFUSAL_OPTION_ID,
|
|
@@ -97268,6 +97370,7 @@ export {
|
|
|
97268
97370
|
KNOWN_TOKEN_GROUPS,
|
|
97269
97371
|
KNOWN_TOKEN_NAMES,
|
|
97270
97372
|
KnowledgeGraph,
|
|
97373
|
+
LARGE_WINDOW_DEEP_MODE_THRESHOLD,
|
|
97271
97374
|
LAYER_1_IDENTITY,
|
|
97272
97375
|
LEADER_MODEL_SET_TOOL_NAME,
|
|
97273
97376
|
LEARNED_HARD_LIMIT,
|
|
@@ -97544,6 +97647,7 @@ export {
|
|
|
97544
97647
|
compileUserRegex,
|
|
97545
97648
|
completeBrainLlm,
|
|
97546
97649
|
completePartialObject,
|
|
97650
|
+
composeBoundedTaskDescription,
|
|
97547
97651
|
composeDirectorPrompt,
|
|
97548
97652
|
composeSubagentPrompt,
|
|
97549
97653
|
computeMessageTokens,
|
|
@@ -97961,6 +98065,7 @@ export {
|
|
|
97961
98065
|
parseReviewSeverity,
|
|
97962
98066
|
parseSkillFrontmatter,
|
|
97963
98067
|
parseSkillRef,
|
|
98068
|
+
parseTaskBoundary,
|
|
97964
98069
|
peekQueuedMessages,
|
|
97965
98070
|
pendingBtwCount,
|
|
97966
98071
|
persistReviewReport,
|
|
@@ -98019,6 +98124,7 @@ export {
|
|
|
98019
98124
|
renderPrometheus,
|
|
98020
98125
|
renderPrompt,
|
|
98021
98126
|
renderSkillAugmentation,
|
|
98127
|
+
renderTaskBoundaryBlock,
|
|
98022
98128
|
repairConfigDefaults,
|
|
98023
98129
|
repairToolUseAdjacency,
|
|
98024
98130
|
repeatedReadPressure,
|
|
@@ -98183,6 +98289,7 @@ export {
|
|
|
98183
98289
|
syncReportCompletion,
|
|
98184
98290
|
syncReportReopen,
|
|
98185
98291
|
takeHeapSample,
|
|
98292
|
+
taskBoundarySchemaProperties,
|
|
98186
98293
|
terminalPolicyDecision,
|
|
98187
98294
|
tightenHqRedactionPolicy,
|
|
98188
98295
|
toAlertMessage,
|
|
@@ -2895,7 +2895,7 @@ var CONTEXT_WINDOW_MODES = Object.freeze([
|
|
|
2895
2895
|
{
|
|
2896
2896
|
id: "balanced",
|
|
2897
2897
|
name: "Balanced",
|
|
2898
|
-
description: "Default rolling compaction: recent work stays verbatim, old tool output is trimmed.",
|
|
2898
|
+
description: "Default rolling compaction: recent work stays verbatim, old tool output is trimmed. Windows of 1M+ tokens default to Deep.",
|
|
2899
2899
|
thresholds: { warn: 0.55, soft: 0.7, hard: 0.85 },
|
|
2900
2900
|
aggressiveOn: "soft",
|
|
2901
2901
|
preserveK: 8,
|
package/dist/storage/index.js
CHANGED
|
@@ -4656,7 +4656,7 @@ var CONTEXT_WINDOW_MODES = Object.freeze([
|
|
|
4656
4656
|
{
|
|
4657
4657
|
id: "balanced",
|
|
4658
4658
|
name: "Balanced",
|
|
4659
|
-
description: "Default rolling compaction: recent work stays verbatim, old tool output is trimmed.",
|
|
4659
|
+
description: "Default rolling compaction: recent work stays verbatim, old tool output is trimmed. Windows of 1M+ tokens default to Deep.",
|
|
4660
4660
|
thresholds: { warn: 0.55, soft: 0.7, hard: 0.85 },
|
|
4661
4661
|
aggressiveOn: "soft",
|
|
4662
4662
|
preserveK: 8,
|
|
@@ -15085,6 +15085,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
15085
15085
|
sessionPath: (sid, ext) => this.sessionPath(sid, ext)
|
|
15086
15086
|
});
|
|
15087
15087
|
this.clearLoadCache(canonical);
|
|
15088
|
+
if (id !== canonical) this.clearLoadCache(id);
|
|
15088
15089
|
}
|
|
15089
15090
|
async summarize(id, mtime) {
|
|
15090
15091
|
return summarizeSessionFile({
|
package/dist/tools/index.js
CHANGED
|
@@ -3280,7 +3280,7 @@ var RUNTIME_CAPABILITY_MANIFEST = [
|
|
|
3280
3280
|
id: "execution.shell",
|
|
3281
3281
|
pack: "development",
|
|
3282
3282
|
exposure: "direct",
|
|
3283
|
-
tools: ["bash", "exec", "language", "language_info", "language_package"]
|
|
3283
|
+
tools: ["bash", "exec", "pwsh", "language", "language_info", "language_package"]
|
|
3284
3284
|
},
|
|
3285
3285
|
{
|
|
3286
3286
|
id: "verification.run",
|
|
@@ -3945,7 +3945,7 @@ ${identity}`);
|
|
|
3945
3945
|
splitLearnedEntries(rawLearned)
|
|
3946
3946
|
);
|
|
3947
3947
|
const rawBytes = Buffer.byteLength(rawLearned, "utf8");
|
|
3948
|
-
const freshEntries = meta === void 0 ? [] : rawEntries.filter((entry) => entry.capturedAt
|
|
3948
|
+
const freshEntries = meta === void 0 ? [] : rawEntries.filter((entry) => entry.capturedAt >= meta.consolidatedAt);
|
|
3949
3949
|
const stale = meta === void 0 || freshEntries.length > 0 || rawEntries.length > meta.sourceEntryCount || rawBytes > meta.sourceBytes;
|
|
3950
3950
|
if (!stale) {
|
|
3951
3951
|
learnedContent = consolidated;
|
|
@@ -5542,7 +5542,7 @@ var VERIFY_AGENTS = [
|
|
|
5542
5542
|
id: "bug-hunter",
|
|
5543
5543
|
name: "Bug Hunter",
|
|
5544
5544
|
role: "bug-hunter",
|
|
5545
|
-
tools: [...TOOLS.inspect],
|
|
5545
|
+
tools: [...TOOLS.inspect, "dead-code-scan"],
|
|
5546
5546
|
prompt: agentPrompt("bug-hunter")
|
|
5547
5547
|
},
|
|
5548
5548
|
budget: HEAVY_BUDGET,
|
|
@@ -5632,7 +5632,7 @@ var REVIEW_AGENTS = [
|
|
|
5632
5632
|
id: "code-reviewer",
|
|
5633
5633
|
name: "Code Reviewer",
|
|
5634
5634
|
role: "code-reviewer",
|
|
5635
|
-
tools: [...TOOLS.inspect, "git"],
|
|
5635
|
+
tools: [...TOOLS.inspect, "git", "codebase-impact-analysis", "codebase-invariant-check"],
|
|
5636
5636
|
prompt: agentPrompt("code-reviewer")
|
|
5637
5637
|
},
|
|
5638
5638
|
budget: MEDIUM_BUDGET,
|
|
@@ -12,6 +12,6 @@
|
|
|
12
12
|
* is typed `Record<ThemePresetId, Theme>` (no cast) and the CLI's `THEME_META`
|
|
13
13
|
* is a total record — so a missing preset fails `tsc`, not the runtime.
|
|
14
14
|
*/
|
|
15
|
-
export declare const THEME_PRESET_IDS: readonly ['catppuccin', 'tokyo-night', 'nord', 'cyberpunk', 'dracula', 'gruvbox-dark', 'solarized-dark', 'one-dark', 'monokai', 'rose-pine', 'kanagawa', 'ayu-dark', 'everforest', 'night-owl', 'synthwave', 'github-dark', 'material-ocean', 'nightfox', 'oxocarbon', 'catppuccin-macchiato', 'catppuccin-frappe', 'gruvbox-material', 'tokyo-night-storm', 'rose-pine-moon', 'zenburn', 'palenight', 'horizon', 'sonokai', 'edge-dark', 'moonfly', 'melange', 'poimandres', 'vitesse-dark', 'aura', 'dark-plus'];
|
|
15
|
+
export declare const THEME_PRESET_IDS: readonly ['catppuccin', 'tokyo-night', 'nord', 'cyberpunk', 'dracula', 'gruvbox-dark', 'solarized-dark', 'one-dark', 'monokai', 'rose-pine', 'kanagawa', 'ayu-dark', 'everforest', 'night-owl', 'synthwave', 'github-dark', 'material-ocean', 'nightfox', 'oxocarbon', 'catppuccin-macchiato', 'catppuccin-frappe', 'gruvbox-material', 'tokyo-night-storm', 'rose-pine-moon', 'zenburn', 'palenight', 'horizon', 'sonokai', 'edge-dark', 'moonfly', 'melange', 'poimandres', 'vitesse-dark', 'aura', 'dark-plus', 'monochrome'];
|
|
16
16
|
export type ThemePresetId = (typeof THEME_PRESET_IDS)[number];
|
|
17
17
|
//# sourceMappingURL=ui.d.ts.map
|
|
@@ -45,6 +45,23 @@ export interface ContextWindowConfigLike {
|
|
|
45
45
|
targetLoad?: number | undefined;
|
|
46
46
|
}
|
|
47
47
|
export declare const DEFAULT_CONTEXT_WINDOW_MODE_ID: ContextWindowModeId;
|
|
48
|
+
/**
|
|
49
|
+
* Windows at or above this size default to the `deep` policy instead of
|
|
50
|
+
* `balanced`: 1M-class windows exist to be filled, and balanced's hard line
|
|
51
|
+
* (0.85) would compact at ~890K of a 1.05M window, stranding the tail. Deep
|
|
52
|
+
* holds compaction until 0.96 and keeps a wider verbatim tail. An explicit
|
|
53
|
+
* `frugal`/`deep` choice, custom modes, and per-field threshold overrides are
|
|
54
|
+
* always respected as-is; only the balanced default is swapped.
|
|
55
|
+
*/
|
|
56
|
+
export declare const LARGE_WINDOW_DEEP_MODE_THRESHOLD = 1000000;
|
|
57
|
+
/**
|
|
58
|
+
* Meta key the mode-switch surfaces (`/context mode`, WebUI `context.mode.switch`,
|
|
59
|
+
* `/context thresholds`) set after the user deliberately picks a policy for the
|
|
60
|
+
* session. Window-change flows re-resolve the default policy against the new
|
|
61
|
+
* window (so a 1M↔200K model switch keeps the policy scaled to the window) but
|
|
62
|
+
* must leave a user-pinned choice alone.
|
|
63
|
+
*/
|
|
64
|
+
export declare const CONTEXT_WINDOW_MODE_PINNED_META_KEY = "contextWindowModePinned";
|
|
48
65
|
export declare const DEPRECATED_CONTEXT_WINDOW_MODE_ALIASES: Readonly<Record<DeprecatedContextWindowModeId, ContextWindowModeId>>;
|
|
49
66
|
export declare const CONTEXT_WINDOW_MODES: readonly ContextWindowMode[];
|
|
50
67
|
export declare function listContextWindowModes(): ContextWindowMode[];
|
|
@@ -53,6 +70,6 @@ export declare function isDeprecatedContextWindowModeId(id: string): id is Depre
|
|
|
53
70
|
export declare function isContextWindowModeSelectionId(id: string): id is ContextWindowModeSelectionId;
|
|
54
71
|
export declare function getContextWindowMode(id: string | null | undefined): ContextWindowMode | null;
|
|
55
72
|
export declare function isContextWindowModeId(id: string): id is ContextWindowModeId;
|
|
56
|
-
export declare function resolveContextWindowPolicy(config?: ContextWindowConfigLike, overrideMode?: string | null | undefined): ContextWindowPolicy;
|
|
73
|
+
export declare function resolveContextWindowPolicy(config?: ContextWindowConfigLike, overrideMode?: string | null | undefined, maxContext?: number | undefined): ContextWindowPolicy;
|
|
57
74
|
export declare function formatContextWindowModeList(activeId?: string | null): string;
|
|
58
75
|
//# sourceMappingURL=context-window.d.ts.map
|
package/dist/types/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export type { AdaptiveConcurrencyConfig, AgentLearningConfig, AutonomyConfig, Br
|
|
|
7
7
|
export { DEFAULT_TUI_THINKING_WORD, FLEET_CHAT_VERBOSITY_VALUES, MAX_TUI_THINKING_WORD_LENGTH, normalizeTokenSavingTier, normalizeTuiThinkingWord, resolveFleetChatVerbosity, resolveTokenSavingTier, THEME_PRESET_IDS, } from './config.js';
|
|
8
8
|
export type { CompletedWorkEvidence, CompletedWorkSource, ContextEvidenceState, ContextFileEvidence, ContextIntentEvidence, ContextRepeatedReadEvidence, ToolEvidenceStatus, ToolOutputMetadata, } from './context-evidence.js';
|
|
9
9
|
export type { ContextSnapshot, ContextWindowAggressiveOn, ContextWindowConfigLike, ContextWindowMode, ContextWindowModeId, ContextWindowModeSelectionId, ContextWindowPolicy, ContextWindowThresholds, DeprecatedContextWindowModeId, } from './context-window.js';
|
|
10
|
-
export { CONTEXT_WINDOW_MODES, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEPRECATED_CONTEXT_WINDOW_MODE_ALIASES, formatContextWindowModeList, getContextWindowMode, isContextWindowModeId, isContextWindowModeSelectionId, isDeprecatedContextWindowModeId, listContextWindowModes, normalizeContextWindowModeId, resolveContextWindowPolicy, } from './context-window.js';
|
|
10
|
+
export { CONTEXT_WINDOW_MODES, CONTEXT_WINDOW_MODE_PINNED_META_KEY, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEPRECATED_CONTEXT_WINDOW_MODE_ALIASES, LARGE_WINDOW_DEEP_MODE_THRESHOLD, formatContextWindowModeList, getContextWindowMode, isContextWindowModeId, isContextWindowModeSelectionId, isDeprecatedContextWindowModeId, listContextWindowModes, normalizeContextWindowModeId, resolveContextWindowPolicy, } from './context-window.js';
|
|
11
11
|
export type { CouncilDistinctness, CouncilLLMCaller, CouncilModelTarget, CouncilOption, CouncilPersona, CouncilProfileConfig, CouncilQuestion, CouncilResolutionMethod, CouncilResult, CouncilSeatConfig, CouncilUsage, CouncilVoteResult, CouncilVoteStatus, ResolvedCouncilProfile, ResolvedCouncilSeat, } from './council.js';
|
|
12
12
|
export { DEFAULT_AUTONOMY_CONFIG, DEFAULT_CIRCUIT_BREAKER_CONFIG, DEFAULT_CONTEXT_CONFIG, DEFAULT_SESSION_LOGGING_CONFIG, DEFAULT_SESSION_PRUNE_DAYS, DEFAULT_TOOLS_CONFIG, } from './default-config.js';
|
|
13
13
|
export type { DesignKitEntry, DesignKitLoader, DesignKitManifest, DesignKitTokens, DesignStack, DesignStudioState, DesignTokenSet, TokenValueKind, } from './design-kit.js';
|
package/dist/types/index.js
CHANGED
|
@@ -95,7 +95,8 @@ var THEME_PRESET_IDS = [
|
|
|
95
95
|
"poimandres",
|
|
96
96
|
"vitesse-dark",
|
|
97
97
|
"aura",
|
|
98
|
-
"dark-plus"
|
|
98
|
+
"dark-plus",
|
|
99
|
+
"monochrome"
|
|
99
100
|
];
|
|
100
101
|
|
|
101
102
|
// src/utils/expect-defined.ts
|
|
@@ -110,6 +111,8 @@ function expectDefined(value, label) {
|
|
|
110
111
|
|
|
111
112
|
// src/types/context-window.ts
|
|
112
113
|
var DEFAULT_CONTEXT_WINDOW_MODE_ID = "balanced";
|
|
114
|
+
var LARGE_WINDOW_DEEP_MODE_THRESHOLD = 1e6;
|
|
115
|
+
var CONTEXT_WINDOW_MODE_PINNED_META_KEY = "contextWindowModePinned";
|
|
113
116
|
var DEPRECATED_CONTEXT_WINDOW_MODE_ALIASES = Object.freeze({
|
|
114
117
|
archival: "balanced"
|
|
115
118
|
});
|
|
@@ -117,7 +120,7 @@ var CONTEXT_WINDOW_MODES = Object.freeze([
|
|
|
117
120
|
{
|
|
118
121
|
id: "balanced",
|
|
119
122
|
name: "Balanced",
|
|
120
|
-
description: "Default rolling compaction: recent work stays verbatim, old tool output is trimmed.",
|
|
123
|
+
description: "Default rolling compaction: recent work stays verbatim, old tool output is trimmed. Windows of 1M+ tokens default to Deep.",
|
|
121
124
|
thresholds: { warn: 0.55, soft: 0.7, hard: 0.85 },
|
|
122
125
|
aggressiveOn: "soft",
|
|
123
126
|
preserveK: 8,
|
|
@@ -168,9 +171,11 @@ function getContextWindowMode(id) {
|
|
|
168
171
|
function isContextWindowModeId(id) {
|
|
169
172
|
return CONTEXT_WINDOW_MODES.some((m) => m.id === id);
|
|
170
173
|
}
|
|
171
|
-
function resolveContextWindowPolicy(config = {}, overrideMode) {
|
|
174
|
+
function resolveContextWindowPolicy(config = {}, overrideMode, maxContext) {
|
|
172
175
|
const requested = overrideMode ?? config.mode ?? DEFAULT_CONTEXT_WINDOW_MODE_ID;
|
|
173
|
-
const
|
|
176
|
+
const normalized = normalizeContextWindowModeId(requested) ?? DEFAULT_CONTEXT_WINDOW_MODE_ID;
|
|
177
|
+
const baseId = normalized === DEFAULT_CONTEXT_WINDOW_MODE_ID && typeof maxContext === "number" && maxContext >= LARGE_WINDOW_DEEP_MODE_THRESHOLD ? "deep" : normalized;
|
|
178
|
+
const mode = expectDefined(getContextWindowMode(baseId));
|
|
174
179
|
return {
|
|
175
180
|
...mode,
|
|
176
181
|
thresholds: {
|
|
@@ -1312,6 +1317,7 @@ export {
|
|
|
1312
1317
|
BUILTIN_PROMPT_CATEGORIES,
|
|
1313
1318
|
CHAT_MARKER_SOURCES,
|
|
1314
1319
|
CONTEXT_WINDOW_MODES,
|
|
1320
|
+
CONTEXT_WINDOW_MODE_PINNED_META_KEY,
|
|
1315
1321
|
ConfigError,
|
|
1316
1322
|
DEFAULT_AUTONOMY_CONFIG,
|
|
1317
1323
|
DEFAULT_CIRCUIT_BREAKER_CONFIG,
|
|
@@ -1332,6 +1338,7 @@ export {
|
|
|
1332
1338
|
GOVERNED_TOOL_EXECUTOR_META_KEY,
|
|
1333
1339
|
KNOWN_TOKEN_GROUPS,
|
|
1334
1340
|
KNOWN_TOKEN_NAMES,
|
|
1341
|
+
LARGE_WINDOW_DEEP_MODE_THRESHOLD,
|
|
1335
1342
|
MALFORMED_ARG_MARKERS,
|
|
1336
1343
|
MAX_TUI_THINKING_WORD_LENGTH,
|
|
1337
1344
|
MEMORY_TYPE_LABELS,
|
|
@@ -34,7 +34,7 @@ export declare const RUNTIME_CAPABILITY_MANIFEST: readonly [{
|
|
|
34
34
|
readonly id: 'execution.shell';
|
|
35
35
|
readonly pack: 'development';
|
|
36
36
|
readonly exposure: 'direct';
|
|
37
|
-
readonly tools: readonly ["bash", "exec", "language", "language_info", "language_package"];
|
|
37
|
+
readonly tools: readonly ["bash", "exec", "pwsh", "language", "language_info", "language_package"];
|
|
38
38
|
}, {
|
|
39
39
|
readonly id: 'verification.run';
|
|
40
40
|
readonly pack: 'development';
|
|
@@ -21,3 +21,6 @@ Working rules:
|
|
|
21
21
|
- Make write paths idempotent or transactional where correctness demands it
|
|
22
22
|
- Don't swallow errors — handle, propagate, or log with context
|
|
23
23
|
- Follow the codebase's existing service patterns and dependency direction
|
|
24
|
+
- Prefer index-first discovery: use `codebase-search` and `codebase-skeleton` before `grep`/`read`
|
|
25
|
+
- Before modifying service signatures or models, run `codebase-impact-analysis` and `codebase-incoming-calls`
|
|
26
|
+
- Verify changes with `codebase-targeted-test` and `codebase-invariant-check` before wider testing
|
|
@@ -17,6 +17,9 @@ Each entry: **[TYPE]** `file:line` — description + suggested fix
|
|
|
17
17
|
|
|
18
18
|
Working rules:
|
|
19
19
|
- Never scan node_modules — it's noise
|
|
20
|
+
- Use `codebase-search` to target suspect symbols, and `codebase-skeleton` to read signatures without bloating context
|
|
21
|
+
- Trace call graphs with `codebase-incoming-calls` and `codebase-outgoing-calls` to detect broken caller assumptions
|
|
22
|
+
- Use `dead-code-scan` to find unreferenced exports and dead execution paths
|
|
20
23
|
- Always include file:line for every finding
|
|
21
24
|
- If >30% of findings are false positives, note the confidence level
|
|
22
25
|
- Ask director for clarification if paths are ambiguous
|
|
@@ -23,6 +23,7 @@ Output: Markdown review:
|
|
|
23
23
|
Working rules:
|
|
24
24
|
- Read-only — review and recommend, never edit
|
|
25
25
|
- Prefer `codebase-search` / `codebase-incoming-calls` to confirm call sites and duplicates before calling a change isolated
|
|
26
|
+
- Run `codebase-impact-analysis` and `codebase-invariant-check` to verify architectural boundaries and blast radius
|
|
26
27
|
- Lead with correctness; don't bury a real bug under style nits
|
|
27
28
|
- Every finding needs file:line and a concrete suggestion
|
|
28
29
|
- Cite the project convention you're invoking, don't assert taste
|
|
@@ -18,6 +18,8 @@ Output: Markdown frontend report:
|
|
|
18
18
|
|
|
19
19
|
Working rules:
|
|
20
20
|
- Reuse existing components/tokens; don't duplicate the design system
|
|
21
|
+
- Discover existing components, hooks, and types with `codebase-search` and `codebase-skeleton` before building new ones
|
|
22
|
+
- Check dependent views and callers with `codebase-incoming-calls` and `codebase-impact-analysis` before changing shared UI components
|
|
21
23
|
- Handle loading, empty, and error states — not just the happy path
|
|
22
24
|
- Keep components accessible by default (labels, roles, focus)
|
|
23
25
|
- Run the build/typecheck; don't leave the UI broken
|
|
@@ -19,6 +19,8 @@ Output: Markdown test report:
|
|
|
19
19
|
|
|
20
20
|
Working rules:
|
|
21
21
|
- Test behavior, not implementation details
|
|
22
|
+
- Inspect signatures and types with `codebase-skeleton` before writing tests; search existing fixtures with `codebase-search`
|
|
23
|
+
- Prefer `codebase-targeted-test` for fast, laser-focused test verification of touched components
|
|
22
24
|
- Prefer real dependencies over mocks for integration tests unless told otherwise
|
|
23
25
|
- Every test must be able to actually fail — no tautologies
|
|
24
26
|
- Run the tests you write; never report tests you didn't execute
|
|
@@ -48,7 +48,7 @@ For controlled fan-out, use `spawn_subagent` → `assign_task` →
|
|
|
48
48
|
|
|
49
49
|
## Dispatch contract
|
|
50
50
|
|
|
51
|
-
Every assigned task
|
|
51
|
+
Every assigned task must state:
|
|
52
52
|
|
|
53
53
|
- the objective and why it matters;
|
|
54
54
|
- exact scope and non-goals;
|
|
@@ -58,6 +58,14 @@ Every assigned task should state:
|
|
|
58
58
|
- the narrowest required verification;
|
|
59
59
|
- known dependencies, risks, and assumptions.
|
|
60
60
|
|
|
61
|
+
The assignment tools enforce the boundary: `delegate` and `assign_task` reject
|
|
62
|
+
any call without an explicit `scope` (what the work covers) and at least one
|
|
63
|
+
concrete `outOfScope` non-goal (what the worker must not do). Treat a
|
|
64
|
+
rejection as a design checkpoint, not paperwork — if you cannot name what is
|
|
65
|
+
out of scope, the task is not decomposed enough yet. The boundary is rendered
|
|
66
|
+
into the worker's brief as a hard contract and survives into handoff
|
|
67
|
+
continuations, so write it once, precisely.
|
|
68
|
+
|
|
61
69
|
Match role and model to the work: use economical workers for bounded discovery
|
|
62
70
|
and capable workers for ambiguous implementation or synthesis. Provider
|
|
63
71
|
diversity is useful for independent review, not an end in itself.
|
|
@@ -7,6 +7,10 @@ self-contained handoff; do not take over fleet orchestration.
|
|
|
7
7
|
- Treat the assigned objective, scope, write authority, non-goals, and
|
|
8
8
|
completion criteria as your boundary. Later role, task, and per-spawn
|
|
9
9
|
instructions may narrow this baseline.
|
|
10
|
+
- Your brief carries an explicit "TASK BOUNDARY" block (scope plus
|
|
11
|
+
out-of-scope non-goals). It is a hard contract, not a suggestion: stay
|
|
12
|
+
inside it even when an out-of-scope change looks quick or obviously right —
|
|
13
|
+
report it back instead of doing it.
|
|
10
14
|
- Inspect before editing. Resolve discoverable context yourself and use the
|
|
11
15
|
project's existing conventions, tests, and tooling.
|
|
12
16
|
- Make only task-relevant changes. Preserve unrelated work and avoid broad
|
|
@@ -5,7 +5,7 @@ Act as the quality gate for the requested change. Report actionable defects that
|
|
|
5
5
|
### Review loop
|
|
6
6
|
|
|
7
7
|
1. Establish the review base, intended behavior, and changed surface. Inspect the diff before whole files.
|
|
8
|
-
2. Follow affected contracts and call sites
|
|
8
|
+
2. Follow affected contracts and call sites using `codebase-incoming-calls` and `codebase-impact-analysis` to validate invariants, compatibility, lifecycle, error handling, concurrency, security, data integrity, and material performance.
|
|
9
9
|
3. Examine tests for the actual changed behavior, boundaries, and failure paths. Coverage alone is not proof.
|
|
10
10
|
4. Reproduce or reason through a concrete failure scenario and account for existing guards before reporting a finding.
|
|
11
11
|
5. Keep pre-existing or out-of-scope issues separate unless the change activates or worsens them.
|
|
@@ -5,11 +5,11 @@ Own the incident from reproducible symptom to demonstrated root cause and, when
|
|
|
5
5
|
### Investigation loop
|
|
6
6
|
|
|
7
7
|
1. Record the exact symptom, expected behavior, environment, frequency, and smallest reliable reproduction. Preserve baseline evidence before editing.
|
|
8
|
-
2. Trace the failure through time and data flow using logs, stack traces, configuration, state transitions, and recent changes as evidence.
|
|
8
|
+
2. Trace the failure through time and data flow using logs, stack traces, configuration, state transitions, and recent changes as evidence. Prefer `codebase-search`, `codebase-incoming-calls`, and `codebase-outgoing-calls` over broad grepping.
|
|
9
9
|
3. Maintain a short ranked hypothesis set. Run the narrowest experiment that can falsify the leader; update the ranking after each result.
|
|
10
10
|
4. Use binary isolation, targeted instrumentation, state capture, or concurrency analysis when normal traces are insufficient. Remove temporary diagnostics afterward.
|
|
11
11
|
5. Identify the initiating defect, explain secondary failures, and rule out existing guards or environmental causes.
|
|
12
|
-
6. If fixing is authorized, change the smallest responsible surface, add regression coverage where durable, and rerun both the original reproduction and adjacent checks
|
|
12
|
+
6. If fixing is authorized, change the smallest responsible surface, add regression coverage where durable, and rerun both the original reproduction and adjacent checks via `codebase-targeted-test`.
|
|
13
13
|
|
|
14
14
|
### Deliverable
|
|
15
15
|
|