@event4u/agent-config 9.27.0 → 9.28.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 (138) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/AGENTS.md +12 -11
  3. package/CHANGELOG.md +99 -0
  4. package/README.md +1 -1
  5. package/dist/agent-src/commands/analyze/conformance.md +24 -0
  6. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +10 -3
  7. package/dist/agent-src/rules/artifact-engagement-recording.md +4 -1
  8. package/dist/agent-src/rules/autonomous-execution.md +1 -1
  9. package/dist/agent-src/rules/brand-source-of-truth.md +33 -6
  10. package/dist/agent-src/rules/context-hygiene.md +3 -1
  11. package/dist/agent-src/rules/council-availability.md +93 -0
  12. package/dist/agent-src/rules/cross-source-consistency.md +3 -0
  13. package/dist/agent-src/rules/delegation-policy.md +29 -5
  14. package/dist/agent-src/rules/design-fidelity.md +3 -0
  15. package/dist/agent-src/rules/evaluator-independence.md +2 -1
  16. package/dist/agent-src/rules/external-code-graph-interop.md +2 -1
  17. package/dist/agent-src/rules/finance-safety-floor.md +1 -1
  18. package/dist/agent-src/rules/git-history-discipline.md +1 -1
  19. package/dist/agent-src/rules/history-discipline.md +3 -1
  20. package/dist/agent-src/rules/legal-safety-floor.md +1 -1
  21. package/dist/agent-src/rules/no-pr-progress-comments.md +3 -1
  22. package/dist/agent-src/rules/onboarding-gate.md +3 -1
  23. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +4 -1
  24. package/dist/agent-src/rules/role-mode-adherence.md +1 -1
  25. package/dist/agent-src/rules/scale-discipline.md +3 -1
  26. package/dist/agent-src/rules/self-repair-loop.md +103 -0
  27. package/dist/agent-src/rules/session-canary.md +2 -1
  28. package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
  29. package/dist/agent-src/rules/token-budget-discipline.md +3 -1
  30. package/dist/agent-src/rules/tool-safety.md +5 -1
  31. package/dist/agent-src/skills/adversarial-review/SKILL.md +1 -1
  32. package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
  33. package/dist/agent-src/skills/performance-analysis/SKILL.md +1 -1
  34. package/dist/agent-src/skills/persona-improvement/SKILL.md +1 -1
  35. package/dist/agent-src/skills/project-analyzer/SKILL.md +1 -1
  36. package/dist/agent-src/skills/security-audit/SKILL.md +1 -1
  37. package/dist/agent-src/skills/sequential-thinking/SKILL.md +1 -1
  38. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +1 -1
  39. package/dist/agent-src/skills/universal-project-analysis/SKILL.md +1 -1
  40. package/dist/agent-src/templates/AGENTS.md +6 -10
  41. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  42. package/dist/cli/registry.js +7 -0
  43. package/dist/cli/registry.js.map +1 -1
  44. package/dist/cli-delegate/chunk-22GCIJ2O.js +270 -0
  45. package/dist/cli-delegate/{chunk-BCPIOAGV.js → chunk-2BE5I2MN.js} +8 -8
  46. package/dist/cli-delegate/{chunk-AIIUU73N.js → chunk-7OMQCH4V.js} +1 -1
  47. package/dist/cli-delegate/{chunk-HJ6DAJHR.js → chunk-GB2FSUEE.js} +57 -7
  48. package/dist/cli-delegate/{chunk-WR6GTRHJ.js → chunk-JXARCGVN.js} +3 -3
  49. package/dist/cli-delegate/{chunk-3KJIMFTB.js → chunk-PQSAQKHW.js} +466 -304
  50. package/dist/cli-delegate/chunk-REKCMYOU.js +2991 -0
  51. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  52. package/dist/cli-delegate/cmd_brand_status.js +134 -0
  53. package/dist/cli-delegate/cmd_conformance.js +7 -7
  54. package/dist/cli-delegate/cmd_converge.js +3 -3
  55. package/dist/cli-delegate/cmd_doctor.js +4 -4
  56. package/dist/cli-delegate/cmd_explain.js +80 -330
  57. package/dist/cli-delegate/cmd_export.js +5 -5
  58. package/dist/cli-delegate/cmd_fleet.js +3 -3
  59. package/dist/cli-delegate/cmd_handoff.js +2 -2
  60. package/dist/cli-delegate/cmd_mcp_available.js +433 -0
  61. package/dist/cli-delegate/cmd_migrate.js +3 -3
  62. package/dist/cli-delegate/cmd_packs_active.js +153 -0
  63. package/dist/cli-delegate/cmd_preflight.js +1 -1
  64. package/dist/cli-delegate/cmd_prune.js +5 -5
  65. package/dist/cli-delegate/cmd_route_audit.js +8 -8
  66. package/dist/cli-delegate/cmd_route_explain.js +4 -4
  67. package/dist/cli-delegate/cmd_settings_get.js +272 -0
  68. package/dist/cli-delegate/cmd_settings_migrate.js +5 -5
  69. package/dist/cli-delegate/cmd_settings_set.js +7 -2967
  70. package/dist/cli-delegate/cmd_sync.js +5 -5
  71. package/dist/cli-delegate/cmd_uninstall.js +5 -5
  72. package/dist/cli-delegate/cmd_update.js +4 -4
  73. package/dist/cli-delegate/cmd_upgrade.js +4 -4
  74. package/dist/cli-delegate/cmd_validate.js +5 -5
  75. package/dist/cli-delegate/cmd_versions.js +4 -4
  76. package/dist/discovery/deprecation-report.md +1 -1
  77. package/dist/discovery/discovery-manifest.json +100 -40
  78. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  79. package/dist/discovery/discovery-manifest.summary.md +3 -3
  80. package/dist/discovery/orphan-report.md +1 -1
  81. package/dist/discovery/packs.json +7 -5
  82. package/dist/discovery/trust-report.md +11 -11
  83. package/dist/discovery/workspaces.json +6 -4
  84. package/dist/hooks/dispatch.js +9004 -6132
  85. package/dist/install/install.mjs +697 -507
  86. package/dist/mcp/registry-manifest.json +3 -3
  87. package/dist/mcp/server.json +2 -2
  88. package/dist/mcp/server.mjs +127 -20
  89. package/dist/router.json +1 -1
  90. package/dist/scripts/_lib/agent_settings.js +80 -15
  91. package/dist/scripts/_lib/agent_settings.js.map +1 -1
  92. package/docs/contracts/settings-classes.md +29 -8
  93. package/docs/guidelines/agent-infra/memory-access.md +14 -3
  94. package/package.json +1 -1
  95. package/src/agent-src/templates/AGENTS.md +6 -10
  96. package/src/config/budgets.yml +29 -0
  97. package/src/config/evaluator-budgets.json +4 -4
  98. package/src/config/gate-coverage.yml +26 -0
  99. package/src/scripts/_cli/cmd_brand_status.ts +174 -0
  100. package/src/scripts/_cli/cmd_mcp_available.ts +266 -0
  101. package/src/scripts/_cli/cmd_packs_active.ts +225 -0
  102. package/src/scripts/_cli/cmd_settings_get.ts +324 -0
  103. package/src/scripts/_dispatch.bash +57 -0
  104. package/src/scripts/_lib/agent_settings.ts +82 -16
  105. package/src/scripts/_lib/carrier_divergence.ts +135 -0
  106. package/src/scripts/_lib/host_capability.ts +84 -1
  107. package/src/scripts/_lib/prompt_shape.ts +88 -0
  108. package/src/scripts/_lib/review_skipped_record.ts +102 -0
  109. package/src/scripts/_lib/rule_layer_overlap.ts +254 -0
  110. package/src/scripts/_lib/self_repair.ts +342 -0
  111. package/src/scripts/_lib/self_repair_store.ts +100 -0
  112. package/src/scripts/_lib/transcript_entry.ts +80 -0
  113. package/src/scripts/check_branch_freshness.ts +255 -0
  114. package/src/scripts/check_council_config_location.ts +125 -1
  115. package/src/scripts/check_standing_rule_delivery.ts +314 -0
  116. package/src/scripts/config/profiles.ts +13 -3
  117. package/src/scripts/conformance_scan.ts +272 -24
  118. package/src/scripts/council_availability_hook.ts +188 -0
  119. package/src/scripts/council_cli.ts +126 -7
  120. package/src/scripts/hook_manifest.yaml +107 -26
  121. package/src/scripts/hooks/block_no_verify.ts +39 -2
  122. package/src/scripts/hooks/block_unauthorized_git.ts +156 -7
  123. package/src/scripts/hooks/concern_registry.ts +10 -0
  124. package/src/scripts/hooks/delegation_nudge_hook.ts +450 -0
  125. package/src/scripts/hooks/end_review_nudge_hook.ts +726 -0
  126. package/src/scripts/hooks/orchestration_record_hook.ts +342 -0
  127. package/src/scripts/install.ts +151 -0
  128. package/src/scripts/language_mirror_hook.ts +30 -37
  129. package/src/scripts/measure_scope_dedup.ts +19 -13
  130. package/src/scripts/onboarding_gate_hook.ts +40 -1
  131. package/src/scripts/orchestration_record.ts +4 -1
  132. package/src/scripts/preamble_byte_census.ts +9 -20
  133. package/src/scripts/report_carrier_divergence.ts +364 -0
  134. package/src/scripts/report_skill_activation.ts +257 -0
  135. package/src/scripts/report_skill_obligation_violations.ts +579 -0
  136. package/src/scripts/routing_doctor.ts +77 -6
  137. package/src/scripts/self_repair_cli.ts +240 -0
  138. package/src/scripts/self_repair_hook.ts +241 -0
@@ -38,6 +38,23 @@
38
38
  * Exit codes (dispatcher contract): 0 allow · 2 block (stderr carries the
39
39
  * reason on block-capable events) — the dispatcher's `host_semantics`
40
40
  * translation owns the per-platform mapping.
41
+ *
42
+ * WHAT THIS GUARD DOES NOT SEE — stated because the previous version of this
43
+ * header stated only what it covers, and a coverage claim that omits its
44
+ * residue reads as completeness. The classifier reads the command TEXT; it does
45
+ * not interpret the shell. So an invocation whose command word is assembled at
46
+ * runtime is not classified, measured and still open:
47
+ *
48
+ * P=publish; npm $P — variable indirection
49
+ * echo publish | xargs npm — the command word is composed by xargs
50
+ *
51
+ * Both execute under bash. Closing them needs a different mechanism than a
52
+ * longer pattern, and `Measured, deferred, and why` in the round-6 roadmap
53
+ * draws that line deliberately. Covered, by contrast, and each pinned by a
54
+ * vector whose ground truth came from running bash rather than from reading
55
+ * this file: ANSI-C and locale quoting, unbalanced quotes, command and process
56
+ * substitution in every position tried, `sh -c` and `eval` payloads, env
57
+ * assignment prefixes, and quotes inside the command word.
41
58
  */
42
59
  import fs from "node:fs";
43
60
  import path from "node:path";
@@ -153,20 +170,42 @@ export function extractCommand(envelope: JsonObject): string | null {
153
170
  *
154
171
  * Deliberately NOT a full tokeniser. `shlexSplit` in `block_no_verify` throws on
155
172
  * an unbalanced quote, which is the right behaviour for a guard that fail-closes;
156
- * this guard must classify every command it sees, including a malformed one. So
157
- * an unterminated quote here degrades to "the rest of the string is quoted",
158
- * which yields one segment starting at the real command word — the conservative
159
- * outcome, since the command word is what `commandOp` matches on.
173
+ * this guard must classify every command it sees, including a malformed one.
174
+ *
175
+ * THE UNTERMINATED-QUOTE POSTURE IS FAIL-CLOSED, AND THE ARGUMENT FOR THE
176
+ * PREVIOUS ONE WAS INVERTED. Round 5 shipped this docstring: "an unterminated
177
+ * quote here degrades to 'the rest of the string is quoted', which yields one
178
+ * segment starting at the real command word — the conservative outcome". It is
179
+ * the opposite. In `echo 'oops && npm publish` the surviving segment's command
180
+ * word is `echo`, so everything after `&&` is swallowed and the publish is never
181
+ * seen. Measured, not reasoned: that command was blocked before #1208 and
182
+ * allowed after it. So an unbalanced quote now re-splits the trailing segment
183
+ * WITHOUT quote awareness and classifies every piece. A false positive on input
184
+ * bash would itself refuse to run is acceptable; a false negative on input bash
185
+ * does run is the failure this guard exists for.
186
+ *
187
+ * ANSI-C quoting (`$'…'`) is a distinct opener, and treating its `$` as ordinary
188
+ * text was the second half of the same regress. In `$'don\'t'` the `\'` does NOT
189
+ * close the quote — C escape semantics apply inside — so a plain single-quote
190
+ * reading closes early, re-opens on the trailing `'`, and swallows the tail.
191
+ * `$"…"` is locale translation and behaves as `"…"`.
160
192
  */
161
193
  export function splitOutsideQuotes(command: string): string[] {
162
194
  const parts: string[] = [];
163
195
  let cur = "";
164
- let quote: '"' | "'" | null = null;
196
+ // `$'` is tracked distinctly from `'` because only it honours `\` escapes.
197
+ let quote: '"' | "'" | "$'" | null = null;
165
198
  for (let i = 0; i < command.length; i += 1) {
166
199
  const ch = command[i] as string;
167
200
  if (quote !== null) {
201
+ if (quote === "$'" && ch === "\\" && i + 1 < command.length) {
202
+ // C-style escape: `\'` is a literal quote, not a terminator.
203
+ cur += ch + (command[i + 1] as string);
204
+ i += 1;
205
+ continue;
206
+ }
168
207
  cur += ch;
169
- if (ch === quote) {
208
+ if (ch === (quote === "$'" ? "'" : quote)) {
170
209
  quote = null;
171
210
  } else if (ch === "\\" && quote === '"' && i + 1 < command.length) {
172
211
  cur += command[i + 1] as string;
@@ -174,6 +213,13 @@ export function splitOutsideQuotes(command: string): string[] {
174
213
  }
175
214
  continue;
176
215
  }
216
+ // `$'…'` / `$"…"` — the `$` belongs to the opener, not to the payload.
217
+ if (ch === "$" && (command[i + 1] === "'" || command[i + 1] === '"')) {
218
+ quote = command[i + 1] === "'" ? "$'" : '"';
219
+ cur += ch + (command[i + 1] as string);
220
+ i += 1;
221
+ continue;
222
+ }
177
223
  if (ch === '"' || ch === "'") {
178
224
  quote = ch;
179
225
  cur += ch;
@@ -195,10 +241,93 @@ export function splitOutsideQuotes(command: string): string[] {
195
241
  }
196
242
  cur += ch;
197
243
  }
244
+ if (quote !== null) {
245
+ // Unbalanced: the trailing segment carries an opener that never closed, so
246
+ // its separators were read as data. Re-read them as separators. Segments
247
+ // completed BEFORE the opener keep their quote-aware split — the round-5
248
+ // false positive (a `grep -E` alternation) balances its quotes and never
249
+ // reaches this branch.
250
+ parts.push(...splitIgnoringQuotes(cur));
251
+ return parts;
252
+ }
198
253
  parts.push(cur);
199
254
  return parts;
200
255
  }
201
256
 
257
+ /**
258
+ * Separator split with no quote awareness at all — the fail-closed fallback for
259
+ * a command whose quotes do not balance. Backslash still escapes, because a
260
+ * `\|` is a literal pipe under every reading.
261
+ */
262
+ function splitIgnoringQuotes(fragment: string): string[] {
263
+ const parts: string[] = [];
264
+ let cur = "";
265
+ for (let i = 0; i < fragment.length; i += 1) {
266
+ const ch = fragment[i] as string;
267
+ if (ch === "\\" && i + 1 < fragment.length) {
268
+ cur += ch + (fragment[i + 1] as string);
269
+ i += 1;
270
+ continue;
271
+ }
272
+ if (ch === "\n" || ch === ";" || ch === "|" || ch === "&") {
273
+ if ((ch === "|" || ch === "&") && fragment[i + 1] === ch) {
274
+ i += 1;
275
+ }
276
+ parts.push(cur);
277
+ cur = "";
278
+ continue;
279
+ }
280
+ cur += ch;
281
+ }
282
+ parts.push(cur);
283
+ return parts;
284
+ }
285
+
286
+ /**
287
+ * Extract the payload of every command substitution in a segment — `$(…)` with
288
+ * balanced parentheses, and backtick form.
289
+ *
290
+ * An unterminated substitution yields everything to the end of the segment
291
+ * rather than nothing: the same fail-closed direction the quote posture takes.
292
+ */
293
+ export function substitutionPayloads(segment: string): string[] {
294
+ const out: string[] = [];
295
+ for (let i = 0; i < segment.length; i += 1) {
296
+ const ch = segment[i];
297
+ if (ch === "\\") {
298
+ i += 1;
299
+ continue;
300
+ }
301
+ // `$(…)` command substitution and `<(…)` / `>(…)` process substitution:
302
+ // different syntax, same fact — the parenthesised payload is a command that
303
+ // runs. Measured: `cat <(npm publish)` executes the publish.
304
+ if ((ch === "$" || ch === "<" || ch === ">") && segment[i + 1] === "(") {
305
+ let open = 1;
306
+ let j = i + 2;
307
+ const start = j;
308
+ for (; j < segment.length && open > 0; j += 1) {
309
+ const c = segment[j];
310
+ if (c === "\\") {
311
+ j += 1;
312
+ } else if (c === "(") {
313
+ open += 1;
314
+ } else if (c === ")") {
315
+ open -= 1;
316
+ }
317
+ }
318
+ out.push(segment.slice(start, open === 0 ? j - 1 : segment.length));
319
+ i = j - 1;
320
+ continue;
321
+ }
322
+ if (ch === "`") {
323
+ const end = segment.indexOf("`", i + 1);
324
+ out.push(segment.slice(i + 1, end === -1 ? segment.length : end));
325
+ i = end === -1 ? segment.length : end;
326
+ }
327
+ }
328
+ return out;
329
+ }
330
+
202
331
  /**
203
332
  * Split a shell command into the segments that are actually INVOKED.
204
333
  *
@@ -245,13 +374,33 @@ export function invokedSegments(command: string, depth = 0): string[] {
245
374
  }
246
375
  // Drop leading env assignments: `FOO=bar BAZ=1 npm publish`.
247
376
  seg = seg.replace(/^(?:[A-Za-z_][A-Za-z0-9_]*=(?:"[^"]*"|'[^']*'|\S*)\s+)+/, "");
377
+ // A command substitution is an invocation in its own right, and it runs
378
+ // whether or not the enclosing segment's command word is harmless:
379
+ // `echo "$(npm publish)"` publishes. Classify INSIDE the substitution by
380
+ // command position, so the substitution that *invokes* a blocked op is
381
+ // refused and the one that merely *mentions* it in an argument
382
+ // (`echo "$(grep -c 'npm publish' f)"`) is not — the same rule `commandOp`
383
+ // already applies one level up, applied one level deeper.
384
+ for (const payload of substitutionPayloads(seg)) {
385
+ out.push(...invokedSegments(payload, depth + 1));
386
+ }
248
387
  // Unwrap `sh -c '<payload>'` / `bash -c "<payload>"` and recurse.
249
388
  const wrapped = /^(?:\S*\/)?(?:ba|z|k)?sh\s+-[a-z]*c\s+(?:"([^"]*)"|'([^']*)'|(\S+))/.exec(seg);
250
389
  if (wrapped) {
251
390
  out.push(...invokedSegments(wrapped[1] ?? wrapped[2] ?? wrapped[3] ?? "", depth + 1));
252
391
  continue;
253
392
  }
254
- out.push(seg);
393
+ // `eval` is the same shape as `sh -c`: its argument is command context, and
394
+ // it takes the rest of the segment rather than one word.
395
+ const evaled = /^eval\s+(?:"([^"]*)"|'([^']*)'|(.+))$/.exec(seg);
396
+ if (evaled) {
397
+ out.push(...invokedSegments(evaled[1] ?? evaled[2] ?? evaled[3] ?? "", depth + 1));
398
+ continue;
399
+ }
400
+ // Quotes inside the command WORD are removed by the shell before it looks
401
+ // the command up, so `np''m publish` invokes npm. Strip them from the head
402
+ // only — an argument's quotes are data and stay.
403
+ out.push(seg.replace(/^(\S+)/, (w) => w.replace(/['"]/g, "")));
255
404
  }
256
405
  return out;
257
406
  }
@@ -41,6 +41,8 @@ import { main as surfaceProbeMain } from '../surface_probe_hook.js';
41
41
  import { main as teamReviewGateMain } from '../team_review_gate_hook.js';
42
42
  import { main as prUrlReminderMain } from '../pr_url_reminder_hook.js';
43
43
  import { main as sessionCanaryMain } from '../session_canary_hook.js';
44
+ import { main as councilAvailabilityMain } from '../council_availability_hook.js';
45
+ import { main as selfRepairMain } from '../self_repair_hook.js';
44
46
  import { main as sessionRegisterMain } from '../session_register_hook.js';
45
47
  import { main as languageMirrorMain } from '../language_mirror_hook.js';
46
48
  import { main as gitAuthorizationMain } from '../git_authorization_hook.js';
@@ -52,6 +54,9 @@ import { main as blockConfigWeakeningMain } from './block_config_weakening.js';
52
54
  import { main as rtkWrapMain } from './rtk_wrap_hook.js';
53
55
  import { main as designSlopMain } from './design_slop_hook.js';
54
56
  import { main as codeGraphNudgeMain } from './code_graph_nudge_hook.js';
57
+ import { main as orchestrationRecordMain } from './orchestration_record_hook.js';
58
+ import { main as delegationNudgeMain } from './delegation_nudge_hook.js';
59
+ import { main as endReviewNudgeMain } from './end_review_nudge_hook.js';
55
60
 
56
61
  /** A concern `main` — argv-taking or not; both shapes exist. */
57
62
  export type ConcernMain = (argv?: string[]) => number | undefined | void;
@@ -75,6 +80,8 @@ export const CONCERN_REGISTRY: Readonly<Record<string, ConcernMain>> = {
75
80
  'src/scripts/team_review_gate_hook.ts': teamReviewGateMain as ConcernMain,
76
81
  'src/scripts/pr_url_reminder_hook.ts': prUrlReminderMain as ConcernMain,
77
82
  'src/scripts/session_canary_hook.ts': sessionCanaryMain as ConcernMain,
83
+ 'src/scripts/council_availability_hook.ts': councilAvailabilityMain as ConcernMain,
84
+ 'src/scripts/self_repair_hook.ts': selfRepairMain as ConcernMain,
78
85
  'src/scripts/session_register_hook.ts': sessionRegisterMain as ConcernMain,
79
86
  'src/scripts/language_mirror_hook.ts': languageMirrorMain as ConcernMain,
80
87
  'src/scripts/git_authorization_hook.ts': gitAuthorizationMain as ConcernMain,
@@ -86,4 +93,7 @@ export const CONCERN_REGISTRY: Readonly<Record<string, ConcernMain>> = {
86
93
  'src/scripts/hooks/rtk_wrap_hook.ts': rtkWrapMain as ConcernMain,
87
94
  'src/scripts/hooks/design_slop_hook.ts': designSlopMain as ConcernMain,
88
95
  'src/scripts/hooks/code_graph_nudge_hook.ts': codeGraphNudgeMain as ConcernMain,
96
+ 'src/scripts/hooks/orchestration_record_hook.ts': orchestrationRecordMain as ConcernMain,
97
+ 'src/scripts/hooks/delegation_nudge_hook.ts': delegationNudgeMain as ConcernMain,
98
+ 'src/scripts/hooks/end_review_nudge_hook.ts': endReviewNudgeMain as ConcernMain,
89
99
  };