mustflow 2.38.0 → 2.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/README.md +3 -0
  2. package/dist/cli/commands/run/executor.js +16 -0
  3. package/dist/cli/commands/run/process-tree.js +6 -3
  4. package/dist/cli/commands/verify.js +3 -1
  5. package/dist/cli/lib/git-changes.js +11 -1
  6. package/dist/cli/lib/i18n.js +1 -1
  7. package/dist/cli/lib/local-index/index.js +8 -4
  8. package/dist/cli/lib/local-index/populate.js +17 -3
  9. package/dist/cli/lib/local-index/search-read-model.js +9 -7
  10. package/dist/cli/lib/local-index/search-text.js +2 -2
  11. package/dist/cli/lib/local-index/workflow-documents.js +17 -2
  12. package/dist/cli/lib/mustflow-read.js +14 -2
  13. package/dist/cli/lib/repo-map.js +16 -3
  14. package/dist/cli/lib/templates.js +8 -7
  15. package/dist/cli/lib/validation/constants.js +1 -1
  16. package/dist/core/active-run-locks.js +78 -20
  17. package/dist/core/change-classification.js +4 -0
  18. package/dist/core/command-contract-rules.js +1 -1
  19. package/dist/core/command-contract-validation.js +1 -1
  20. package/dist/core/command-cwd.js +13 -2
  21. package/dist/core/command-effects.js +22 -4
  22. package/dist/core/command-env.js +8 -6
  23. package/dist/core/command-preconditions.js +28 -2
  24. package/dist/core/completion-verdict.js +1 -1
  25. package/dist/core/line-endings.js +8 -4
  26. package/dist/core/safe-filesystem.js +9 -1
  27. package/dist/core/source-anchor-validation.js +7 -1
  28. package/dist/core/source-anchors.js +8 -2
  29. package/dist/core/verification-scheduler.js +8 -2
  30. package/package.json +1 -1
  31. package/templates/default/common/.mustflow/config/commands.toml +39 -15
  32. package/templates/default/i18n.toml +330 -1
  33. package/templates/default/locales/en/.mustflow/skills/INDEX.md +302 -5
  34. package/templates/default/locales/en/.mustflow/skills/agent-eval-integrity-review/SKILL.md +160 -0
  35. package/templates/default/locales/en/.mustflow/skills/agent-execution-control-review/SKILL.md +163 -0
  36. package/templates/default/locales/en/.mustflow/skills/ai-generated-code-hardening/SKILL.md +49 -13
  37. package/templates/default/locales/en/.mustflow/skills/api-access-control-review/SKILL.md +298 -0
  38. package/templates/default/locales/en/.mustflow/skills/api-misuse-resistance-review/SKILL.md +297 -0
  39. package/templates/default/locales/en/.mustflow/skills/api-request-performance-review/SKILL.md +189 -0
  40. package/templates/default/locales/en/.mustflow/skills/app-startup-performance-review/SKILL.md +309 -0
  41. package/templates/default/locales/en/.mustflow/skills/backend-log-evidence-review/SKILL.md +213 -0
  42. package/templates/default/locales/en/.mustflow/skills/business-rule-leakage-review/SKILL.md +295 -0
  43. package/templates/default/locales/en/.mustflow/skills/cache-integrity-review/SKILL.md +291 -0
  44. package/templates/default/locales/en/.mustflow/skills/change-blast-radius-review/SKILL.md +297 -0
  45. package/templates/default/locales/en/.mustflow/skills/client-bundle-pruning-review/SKILL.md +160 -0
  46. package/templates/default/locales/en/.mustflow/skills/cloud-cost-guardrail-review/SKILL.md +321 -0
  47. package/templates/default/locales/en/.mustflow/skills/concurrency-invariant-review/SKILL.md +193 -0
  48. package/templates/default/locales/en/.mustflow/skills/core-web-vitals-field-review/SKILL.md +161 -0
  49. package/templates/default/locales/en/.mustflow/skills/credit-ledger-integrity-review/SKILL.md +156 -0
  50. package/templates/default/locales/en/.mustflow/skills/database-json-modeling-review/SKILL.md +171 -0
  51. package/templates/default/locales/en/.mustflow/skills/database-lock-contention-review/SKILL.md +192 -0
  52. package/templates/default/locales/en/.mustflow/skills/database-migration-change/SKILL.md +76 -34
  53. package/templates/default/locales/en/.mustflow/skills/database-query-bottleneck-review/SKILL.md +194 -0
  54. package/templates/default/locales/en/.mustflow/skills/deletion-lifecycle-review/SKILL.md +171 -0
  55. package/templates/default/locales/en/.mustflow/skills/deployment-rollout-safety-review/SKILL.md +321 -0
  56. package/templates/default/locales/en/.mustflow/skills/desktop-auto-update-safety-review/SKILL.md +265 -0
  57. package/templates/default/locales/en/.mustflow/skills/desktop-background-process-stability-review/SKILL.md +318 -0
  58. package/templates/default/locales/en/.mustflow/skills/desktop-memory-footprint-review/SKILL.md +318 -0
  59. package/templates/default/locales/en/.mustflow/skills/error-message-integrity-review/SKILL.md +283 -0
  60. package/templates/default/locales/en/.mustflow/skills/failure-integrity-review/SKILL.md +193 -0
  61. package/templates/default/locales/en/.mustflow/skills/file-upload-security-review/SKILL.md +305 -0
  62. package/templates/default/locales/en/.mustflow/skills/frame-render-performance-review/SKILL.md +159 -0
  63. package/templates/default/locales/en/.mustflow/skills/frontend-accessibility-tree-review/SKILL.md +202 -0
  64. package/templates/default/locales/en/.mustflow/skills/frontend-localization-review/SKILL.md +202 -0
  65. package/templates/default/locales/en/.mustflow/skills/frontend-state-ownership-review/SKILL.md +183 -0
  66. package/templates/default/locales/en/.mustflow/skills/frontend-stress-layout-review/SKILL.md +193 -0
  67. package/templates/default/locales/en/.mustflow/skills/hot-path-performance-review/SKILL.md +159 -0
  68. package/templates/default/locales/en/.mustflow/skills/idempotency-integrity-review/SKILL.md +195 -0
  69. package/templates/default/locales/en/.mustflow/skills/image-delivery-performance-review/SKILL.md +161 -0
  70. package/templates/default/locales/en/.mustflow/skills/incident-triage-review/SKILL.md +185 -0
  71. package/templates/default/locales/en/.mustflow/skills/llm-hallucination-control-review/SKILL.md +155 -0
  72. package/templates/default/locales/en/.mustflow/skills/llm-response-latency-review/SKILL.md +155 -0
  73. package/templates/default/locales/en/.mustflow/skills/llm-service-ux-review/SKILL.md +2 -0
  74. package/templates/default/locales/en/.mustflow/skills/llm-token-cost-control-review/SKILL.md +155 -0
  75. package/templates/default/locales/en/.mustflow/skills/low-end-device-support-review/SKILL.md +340 -0
  76. package/templates/default/locales/en/.mustflow/skills/memory-lifetime-review/SKILL.md +169 -0
  77. package/templates/default/locales/en/.mustflow/skills/mobile-energy-efficiency-review/SKILL.md +329 -0
  78. package/templates/default/locales/en/.mustflow/skills/module-boundary-review/SKILL.md +278 -0
  79. package/templates/default/locales/en/.mustflow/skills/multi-agent-work-coordination/SKILL.md +1 -0
  80. package/templates/default/locales/en/.mustflow/skills/observability-debuggability-review/SKILL.md +208 -0
  81. package/templates/default/locales/en/.mustflow/skills/payment-integrity-review/SKILL.md +155 -0
  82. package/templates/default/locales/en/.mustflow/skills/prompt-contract-quality-review/SKILL.md +158 -0
  83. package/templates/default/locales/en/.mustflow/skills/quadratic-scan-review/SKILL.md +155 -0
  84. package/templates/default/locales/en/.mustflow/skills/queue-processing-integrity-review/SKILL.md +193 -0
  85. package/templates/default/locales/en/.mustflow/skills/race-condition-review/SKILL.md +188 -0
  86. package/templates/default/locales/en/.mustflow/skills/rate-limit-integrity-review/SKILL.md +344 -0
  87. package/templates/default/locales/en/.mustflow/skills/retry-policy-integrity-review/SKILL.md +195 -0
  88. package/templates/default/locales/en/.mustflow/skills/routes.toml +330 -0
  89. package/templates/default/locales/en/.mustflow/skills/security-flow-review/SKILL.md +279 -0
  90. package/templates/default/locales/en/.mustflow/skills/testability-boundary-review/SKILL.md +295 -0
  91. package/templates/default/locales/en/.mustflow/skills/transaction-boundary-integrity-review/SKILL.md +196 -0
  92. package/templates/default/locales/en/.mustflow/skills/type-state-modeling-review/SKILL.md +179 -0
  93. package/templates/default/locales/en/.mustflow/skills/web-render-performance-review/SKILL.md +164 -0
  94. package/templates/default/manifest.toml +388 -2
@@ -41,7 +41,7 @@ export const LONG_RUNNING_COMMAND_TEXT_PATTERNS = [
41
41
  /\bturbo\s+dev\b/iu,
42
42
  /\btsx\s+(?:watch|--watch|-w)\b/iu,
43
43
  /\bcargo\s+(?:watch|tauri\s+dev)\b/iu,
44
- /\bzig\s+build\b(?=.*(?:--watch|-w|\bwatch\b))/iu,
44
+ /\bzig\s+build\b(?=[^\r\n;&|]*?(?:--watch(?:=|\b)|-w\b|\bwatch\b))/iu,
45
45
  /\btauri\s+dev\b/iu,
46
46
  /\bgh\s+(?:run\s+watch|codespace\s+ssh|codespace\s+logs\b.*(?:--follow|-f))\b/iu,
47
47
  /\bdeno\s+(?:serve|task\s+(?:dev|start|serve|watch|preview)|run\b.*(?:--watch|-w))\b/iu,
@@ -546,6 +546,6 @@ export function validateCommandContractStrictDefaults(projectRoot, commandsToml)
546
546
  issues.push(...validateCommandEnvInheritanceWarnings(commandsToml));
547
547
  issues.push(...validateProjectLocalBinWarnings(projectRoot, commandsToml));
548
548
  issues.push(...validateCommandEffects(projectRoot, commandsToml));
549
- issues.push(...validateCommandEffectLockWarnings(commandsToml));
549
+ issues.push(...validateCommandEffectLockWarnings(projectRoot, commandsToml));
550
550
  return issues;
551
551
  }
@@ -13,10 +13,21 @@ export function resolveSafeProjectCwd(projectRoot, rawCwd) {
13
13
  const cwd = rawCwd ?? '.';
14
14
  const resolved = path.resolve(projectRoot, cwd);
15
15
  const rootRealPath = realpathSync.native(projectRoot);
16
- if (!existsSync(resolved) || !statSync(resolved).isDirectory()) {
16
+ try {
17
+ if (!existsSync(resolved) || !statSync(resolved).isDirectory()) {
18
+ throw new Error();
19
+ }
20
+ }
21
+ catch {
22
+ throw new Error(`Intent cwd must stay inside the current root and resolve to an existing directory: ${cwd}`);
23
+ }
24
+ let cwdRealPath;
25
+ try {
26
+ cwdRealPath = realpathSync.native(resolved);
27
+ }
28
+ catch {
17
29
  throw new Error(`Intent cwd must stay inside the current root and resolve to an existing directory: ${cwd}`);
18
30
  }
19
- const cwdRealPath = realpathSync.native(resolved);
20
31
  if (!isInsideOrEqual(rootRealPath, cwdRealPath)) {
21
32
  throw new Error(`Intent cwd must stay inside the current root and resolve to an existing directory: ${cwd}`);
22
33
  }
@@ -161,11 +161,16 @@ export function validateCommandEffects(projectRoot, commandsToml) {
161
161
  }
162
162
  return issues;
163
163
  }
164
- export function validateCommandEffectLockWarnings(commandsToml) {
164
+ export function validateCommandEffectLockWarnings(projectRoot, commandsToml) {
165
165
  const issues = [];
166
166
  if (!commandsToml || !isRecord(commandsToml.intents)) {
167
167
  return issues;
168
168
  }
169
+ const commandContract = {
170
+ defaults: isRecord(commandsToml.defaults) ? commandsToml.defaults : {},
171
+ intents: commandsToml.intents,
172
+ resources: isRecord(commandsToml.resources) ? commandsToml.resources : {},
173
+ };
169
174
  const lockToIntents = new Map();
170
175
  for (const [intentName, intent] of Object.entries(commandsToml.intents)) {
171
176
  if (!isRecord(intent)) {
@@ -177,9 +182,22 @@ export function validateCommandEffectLockWarnings(commandsToml) {
177
182
  Array.isArray(intent.effects)) {
178
183
  continue;
179
184
  }
180
- for (const rawPath of readStringArray(intent, 'writes') ?? []) {
181
- const lock = pathLockKey(rawPath);
182
- lockToIntents.set(lock, [...(lockToIntents.get(lock) ?? []), intentName]);
185
+ let effects;
186
+ try {
187
+ effects = normalizeCommandEffects(projectRoot, commandContract, intentName).filter((effect) => effect.source === 'writes');
188
+ }
189
+ catch {
190
+ continue;
191
+ }
192
+ for (const effect of effects) {
193
+ const lock = effect.lock;
194
+ const intents = lockToIntents.get(lock);
195
+ if (intents) {
196
+ intents.push(intentName);
197
+ }
198
+ else {
199
+ lockToIntents.set(lock, [intentName]);
200
+ }
183
201
  }
184
202
  }
185
203
  for (const [lock, intents] of lockToIntents) {
@@ -105,14 +105,16 @@ function removeProjectLocalBinFromPath(env, projectRoot) {
105
105
  const pathKey = getPathEnvKey(env);
106
106
  const currentPath = env[pathKey];
107
107
  if (!currentPath) {
108
- return env;
108
+ return { ...env };
109
109
  }
110
110
  const localBinPath = path.join(projectRoot, 'node_modules', '.bin');
111
- env[pathKey] = currentPath
112
- .split(path.delimiter)
113
- .filter((entry) => entry.length > 0 && !sameResolvedPath(entry, localBinPath))
114
- .join(path.delimiter);
115
- return env;
111
+ return {
112
+ ...env,
113
+ [pathKey]: currentPath
114
+ .split(path.delimiter)
115
+ .filter((entry) => entry.length > 0 && !sameResolvedPath(entry, localBinPath))
116
+ .join(path.delimiter),
117
+ };
116
118
  }
117
119
  export function resolveCommandEnv(contract, intent) {
118
120
  const policy = readEnvPolicy(intent) ?? readEnvPolicy(contract.defaults) ?? DEFAULT_COMMAND_ENV_POLICY;
@@ -84,6 +84,10 @@ function globToRegExp(pattern) {
84
84
  expression += '[^/]*';
85
85
  continue;
86
86
  }
87
+ if (character === '?') {
88
+ expression += '[^/]';
89
+ continue;
90
+ }
87
91
  expression += escapeRegExp(character);
88
92
  }
89
93
  return new RegExp(`${expression}$`, 'u');
@@ -219,10 +223,32 @@ function evaluateArtifactFreshness(projectRoot, declaration, satisfyIntent, cont
219
223
  satisfyIntent,
220
224
  };
221
225
  }
222
- const artifactMtime = statSync(artifactPath).mtimeMs;
226
+ let artifactMtime;
227
+ try {
228
+ artifactMtime = statSync(artifactPath).mtimeMs;
229
+ }
230
+ catch {
231
+ return {
232
+ kind: declaration.kind,
233
+ label: declaration.label,
234
+ status: 'missing',
235
+ detail: `artifact "${artifact}" is missing.`,
236
+ path: null,
237
+ artifact,
238
+ sources: declaration.sources,
239
+ newestSource: null,
240
+ satisfyIntent,
241
+ };
242
+ }
223
243
  let newest = null;
224
244
  for (const source of sourceFiles) {
225
- const mtime = statSync(path.join(projectRoot, ...source.split('/'))).mtimeMs;
245
+ let mtime;
246
+ try {
247
+ mtime = statSync(path.join(projectRoot, ...source.split('/'))).mtimeMs;
248
+ }
249
+ catch {
250
+ continue;
251
+ }
226
252
  if (!newest || mtime > newest.mtime) {
227
253
  newest = { source, mtime };
228
254
  }
@@ -219,7 +219,7 @@ export function createVerifyCompletionVerdict(input) {
219
219
  failed_intents: normalizedInput.failedIntents,
220
220
  skipped_intents: normalizedInput.skippedIntents,
221
221
  receipt_count: normalizedInput.receiptCount,
222
- gap_count: normalizedInput.skippedIntents,
222
+ gap_count: normalizedInput.gapCount ?? 0,
223
223
  source_anchor_risk_count: normalizedInput.sourceAnchorRiskCount ?? 0,
224
224
  scope_diff_risk_count: normalizedInput.scopeDiffRiskCount ?? 0,
225
225
  repeated_failure_count: normalizedInput.repeatedFailureCount ?? 0,
@@ -21,6 +21,7 @@ function gitList(projectRoot, args) {
21
21
  encoding: 'buffer',
22
22
  env: createCommandEnv(projectRoot, { policy: 'minimal', allowlist: [] }),
23
23
  stdio: ['ignore', 'pipe', 'pipe'],
24
+ timeout: 30_000,
24
25
  windowsHide: true,
25
26
  });
26
27
  if (result.status !== 0) {
@@ -71,19 +72,22 @@ function detectLineEnding(buffer) {
71
72
  return crlfCount === lfCount ? 'crlf' : 'mixed';
72
73
  }
73
74
  function normalizeLf(buffer) {
74
- const bytes = [];
75
+ const bytes = Buffer.allocUnsafe(buffer.length);
76
+ let writeIndex = 0;
75
77
  for (let index = 0; index < buffer.length; index += 1) {
76
78
  const byte = buffer[index];
77
79
  if (byte === 0x0d) {
78
- bytes.push(0x0a);
80
+ bytes[writeIndex] = 0x0a;
81
+ writeIndex += 1;
79
82
  if (buffer[index + 1] === 0x0a) {
80
83
  index += 1;
81
84
  }
82
85
  continue;
83
86
  }
84
- bytes.push(byte);
87
+ bytes[writeIndex] = byte;
88
+ writeIndex += 1;
85
89
  }
86
- return Buffer.from(bytes);
90
+ return bytes.subarray(0, writeIndex);
87
91
  }
88
92
  export function inspectLineEndings(projectRoot, mode, options = {}) {
89
93
  const root = path.resolve(projectRoot);
@@ -14,7 +14,15 @@ function tempFilePath(targetPath) {
14
14
  return path.join(path.dirname(targetPath), `.${path.basename(targetPath)}.${suffix}.tmp`);
15
15
  }
16
16
  function sleep(milliseconds) {
17
- Atomics.wait(WRITE_SLEEP_BUFFER, 0, 0, milliseconds);
17
+ try {
18
+ Atomics.wait(WRITE_SLEEP_BUFFER, 0, 0, milliseconds);
19
+ }
20
+ catch {
21
+ const end = Date.now() + milliseconds;
22
+ while (Date.now() < end) {
23
+ // Fall back only for short retry delays when Atomics.wait is unavailable on this runtime.
24
+ }
25
+ }
18
26
  }
19
27
  function isRetryableWindowsRenameError(error) {
20
28
  if (process.platform !== 'win32' || !error || typeof error !== 'object' || !('code' in error)) {
@@ -131,7 +131,13 @@ export function validateSourceAnchorsInProject(projectRoot) {
131
131
  const anchorsById = new Map();
132
132
  for (const relativePath of sourceFiles) {
133
133
  const absolutePath = path.join(projectRoot, ...relativePath.split('/'));
134
- const content = readFileSync(absolutePath, 'utf8');
134
+ let content;
135
+ try {
136
+ content = readFileSync(absolutePath, 'utf8');
137
+ }
138
+ catch {
139
+ continue;
140
+ }
135
141
  const anchors = parseSourceAnchorsInContent(relativePath, content);
136
142
  issues.push(...validateSourceAnchorDensity(relativePath, content, anchors));
137
143
  for (const anchor of anchors) {
@@ -321,10 +321,16 @@ export function collectSourceAnchorSummaries(projectRoot) {
321
321
  const anchors = [];
322
322
  for (const relativePath of listSourceAnchorFiles(projectRoot)) {
323
323
  const filePath = path.join(projectRoot, ...relativePath.split('/'));
324
- if (!existsSync(filePath) || !statSync(filePath).isFile()) {
324
+ let content;
325
+ try {
326
+ if (!existsSync(filePath) || !statSync(filePath).isFile()) {
327
+ continue;
328
+ }
329
+ content = readFileSync(filePath, 'utf8');
330
+ }
331
+ catch {
325
332
  continue;
326
333
  }
327
- const content = readFileSync(filePath, 'utf8');
328
334
  for (const anchor of parseSourceAnchorsInContent(relativePath, content)) {
329
335
  if (!anchor.idValid || sourceAnchorTextContainsSecretLike(anchor.rawText)) {
330
336
  continue;
@@ -19,12 +19,18 @@ function toScheduleEffect(effect) {
19
19
  function isObject(value) {
20
20
  return !!value && typeof value === 'object';
21
21
  }
22
+ function isMissingPathError(error) {
23
+ return error instanceof Error && 'code' in error && error.code === 'ENOENT';
24
+ }
22
25
  function readJsonFile(projectRoot, filePath) {
23
26
  try {
24
27
  return JSON.parse(readUtf8FileInsideWithoutSymlinks(projectRoot, filePath, { maxBytes: MUSTFLOW_JSON_MAX_BYTES }));
25
28
  }
26
- catch {
27
- return null;
29
+ catch (error) {
30
+ if (isMissingPathError(error)) {
31
+ return null;
32
+ }
33
+ throw error;
28
34
  }
29
35
  }
30
36
  function getUndeclaredWriteIntent(value) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mustflow",
3
- "version": "2.38.0",
3
+ "version": "2.58.0",
4
4
  "description": "Agent workflow documents and CLI for mustflow repository roots.",
5
5
  "type": "module",
6
6
  "license": "MIT-0",
@@ -25,24 +25,48 @@ description = "Generated mustflow SQLite local index under .mustflow/cache/."
25
25
  concurrency = "exclusive_writer"
26
26
 
27
27
  [intents.test]
28
- status = "unknown"
29
- description = "Run the test suite."
30
- reason = "This repository has not declared its test command yet."
31
- agent_action = "do_not_guess_report_missing"
32
- required_after = ["code_change", "behavior_change"]
28
+ status = "configured"
29
+ lifecycle = "oneshot"
30
+ run_policy = "agent_allowed"
31
+ description = "Run the default Bun test suite."
32
+ argv = ["bun", "test"]
33
+ cwd = "."
34
+ timeout_seconds = 600
35
+ stdin = "closed"
36
+ success_exit_codes = [0]
37
+ writes = []
38
+ network = false
39
+ destructive = false
40
+ required_after = ["release_risk", "cross_cutting_code_change", "full_test_request"]
33
41
 
34
42
  [intents.test_related]
35
- status = "unknown"
36
- description = "Run tests directly related to changed files."
37
- reason = "This repository has not declared its related-test command yet."
38
- agent_action = "do_not_guess_report_missing"
43
+ status = "configured"
44
+ lifecycle = "oneshot"
45
+ run_policy = "agent_allowed"
46
+ description = "Run the default Bun test suite for changed code when no narrower test command exists."
47
+ argv = ["bun", "test"]
48
+ cwd = "."
49
+ timeout_seconds = 600
50
+ stdin = "closed"
51
+ success_exit_codes = [0]
52
+ writes = []
53
+ network = false
54
+ destructive = false
39
55
  required_after = ["code_change", "behavior_change", "test_change"]
40
56
 
41
57
  [intents.test_fast]
42
- status = "unknown"
43
- description = "Run the fast test baseline."
44
- reason = "This repository has not declared its fast-test command yet."
45
- agent_action = "do_not_guess_report_missing"
58
+ status = "configured"
59
+ lifecycle = "oneshot"
60
+ run_policy = "agent_allowed"
61
+ description = "Run the default Bun test suite as the fast baseline until the repository narrows it."
62
+ argv = ["bun", "test"]
63
+ cwd = "."
64
+ timeout_seconds = 600
65
+ stdin = "closed"
66
+ success_exit_codes = [0]
67
+ writes = []
68
+ network = false
69
+ destructive = false
46
70
  required_after = ["low_risk_code_change", "copy_change", "i18n_change", "unknown_change"]
47
71
 
48
72
  [intents.test_coverage]
@@ -57,7 +81,7 @@ status = "unknown"
57
81
  description = "Inspect stale or redundant test candidates."
58
82
  reason = "This repository has not declared its test-audit command yet."
59
83
  agent_action = "do_not_guess_report_missing"
60
- required_after = ["test_change", "behavior_removed", "public_api_change"]
84
+ required_after = []
61
85
 
62
86
  [intents.test_release]
63
87
  status = "unknown"
@@ -85,7 +109,7 @@ status = "unknown"
85
109
  description = "Run linting or static analysis."
86
110
  reason = "This repository has not declared its lint command yet."
87
111
  agent_action = "do_not_guess_report_missing"
88
- required_after = ["code_change", "style_change"]
112
+ required_after = []
89
113
 
90
114
  [intents.line_endings_check]
91
115
  status = "configured"