@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.
Files changed (61) hide show
  1. package/dist/coordination/agents/index.js +4 -4
  2. package/dist/coordination/index.d.ts +1 -0
  3. package/dist/coordination/index.js +113 -15
  4. package/dist/coordination/task-boundary.d.ts +64 -0
  5. package/dist/core/index.js +1 -1
  6. package/dist/defaults/index.js +116 -19
  7. package/dist/execution/index.js +11 -8
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.js +127 -20
  10. package/dist/infrastructure/index.js +1 -1
  11. package/dist/storage/index.js +2 -1
  12. package/dist/tools/index.js +4 -4
  13. package/dist/types/config/ui.d.ts +1 -1
  14. package/dist/types/context-window.d.ts +18 -1
  15. package/dist/types/index.d.ts +1 -1
  16. package/dist/types/index.js +11 -4
  17. package/dist/types/runtime-capability-manifest.d.ts +1 -1
  18. package/instructions/agents/backend.md +3 -0
  19. package/instructions/agents/bug-hunter.md +3 -0
  20. package/instructions/agents/code-reviewer.md +1 -0
  21. package/instructions/agents/frontend.md +2 -0
  22. package/instructions/agents/test.md +2 -0
  23. package/instructions/coordination/director-preamble.md +9 -1
  24. package/instructions/coordination/subagent-baseline.md +4 -0
  25. package/instructions/modes/code-reviewer.md +1 -1
  26. package/instructions/modes/debugger.md +2 -2
  27. package/instructions/modes/refactorer.md +2 -2
  28. package/instructions/modes/tester.md +2 -2
  29. package/instructions/system-lite.md +37 -33
  30. package/instructions/system-pro.md +23 -7
  31. package/instructions/system.md +33 -11
  32. package/package.json +6 -4
  33. package/skills/api-design/SKILL.md +26 -1
  34. package/skills/audit-log/SKILL.md +22 -1
  35. package/skills/auto-review/SKILL.md +21 -1
  36. package/skills/bug-hunter/SKILL.md +8 -0
  37. package/skills/chimera/SKILL.md +9 -0
  38. package/skills/data-governance/SKILL.md +25 -1
  39. package/skills/design-system/SKILL.md +19 -1
  40. package/skills/docker-deploy/SKILL.md +26 -1
  41. package/skills/git-flow/SKILL.md +26 -1
  42. package/skills/mailbox-bridge/SKILL.md +25 -1
  43. package/skills/mnemosyne/SKILL.md +25 -2
  44. package/skills/multi-agent/SKILL.md +12 -0
  45. package/skills/node-modern/SKILL.md +28 -1
  46. package/skills/observability/SKILL.md +25 -1
  47. package/skills/output-standards/SKILL.md +28 -1
  48. package/skills/plugin-author/SKILL.md +31 -1
  49. package/skills/prompt-engineering/SKILL.md +27 -1
  50. package/skills/react-modern/SKILL.md +29 -1
  51. package/skills/refactor-planner/SKILL.md +10 -0
  52. package/skills/research-web/SKILL.md +28 -1
  53. package/skills/sdd/SKILL.md +18 -0
  54. package/skills/security-scanner/SKILL.md +25 -1
  55. package/skills/skill-creator/SKILL.md +25 -1
  56. package/skills/tech-stack/SKILL.md +25 -1
  57. package/skills/testing/SKILL.md +25 -1
  58. package/skills/typescript-strict/SKILL.md +30 -1
  59. package/skills/wrongstack-kanban/SKILL.md +24 -0
  60. package/skills/wrongstack-mailbox/SKILL.md +29 -1
  61. 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 mode = getContextWindowMode(requested) ?? expectDefined(getContextWindowMode(DEFAULT_CONTEXT_WINDOW_MODE_ID));
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 > meta.consolidatedAt);
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 task in natural language \u2014 what you want this subagent to do."
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 isPlaceholder = name === "" || name.toLowerCase() === role.toLowerCase() || name === "subagent" || name === "adhoc" || name === "generic" || /^slot-/.test(name);
39085
- if (!isPlaceholder) return subagent;
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: "What the subagent should do \u2014 natural language, complete sentence(s)."
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 complete instruction. 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.",
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
- let delegatedTask = i.task;
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(i.task, continuation, handoffCount, maxHandoffs);
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,
@@ -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({
@@ -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 > meta.consolidatedAt);
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
@@ -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';
@@ -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 mode = getContextWindowMode(requested) ?? expectDefined(getContextWindowMode(DEFAULT_CONTEXT_WINDOW_MODE_ID));
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 should state:
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 far enough to validate invariants, compatibility, lifecycle, error handling, concurrency, security, data integrity, and material performance.
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