@event4u/agent-config 9.34.0 → 9.36.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 (112) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +64 -77
  3. package/CONTRIBUTING.md +23 -14
  4. package/dist/agent-src/commands/analyze/reference-repo.md +135 -42
  5. package/dist/agent-src/commands/roadmap/next.md +37 -5
  6. package/dist/agent-src/contexts/augment-infrastructure.md +1 -1
  7. package/dist/agent-src/rules/design-review-after-ui-write.md +53 -6
  8. package/dist/agent-src/rules/improve-before-implement.md +1 -1
  9. package/dist/agent-src/rules/ui-audit-gate.md +35 -0
  10. package/dist/agent-src/scripts/roadmap_gates.ts +119 -4
  11. package/dist/agent-src/skills/design-system-capture/SKILL.md +2 -2
  12. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +1 -1
  13. package/dist/agent-src/skills/fe-design/SKILL.md +84 -12
  14. package/dist/agent-src/skills/fe-design/evals/triggers.json +11 -3
  15. package/dist/agent-src/skills/prediction-pool-optimizer/SKILL.md +5 -5
  16. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
  17. package/dist/agent-src/skills/skill-writing/SKILL.md +24 -0
  18. package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +29 -0
  19. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +25 -0
  20. package/dist/agent-src/templates/AGENTS.md +1 -1
  21. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  22. package/dist/agent-src/templates/scripts/memory_lookup.ts +1 -2
  23. package/dist/agent-src/templates/scripts/memory_signal.ts +2 -4
  24. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_gate.ts +35 -5
  25. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/staged_confirmation.ts +252 -0
  26. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/staged_confirmation_store.ts +307 -0
  27. package/dist/cli/registry.js +2 -2
  28. package/dist/cli/registry.js.map +1 -1
  29. package/dist/cli-delegate/{chunk-YPAWXXXR.js → chunk-55RI5UXK.js} +17 -0
  30. package/dist/cli-delegate/{chunk-UVKNIJH2.js → chunk-JP53LNVT.js} +12 -0
  31. package/dist/cli-delegate/{chunk-736JCWLM.js → chunk-M2DPGFZ4.js} +10 -0
  32. package/dist/cli-delegate/{chunk-MA4GFWDY.js → chunk-NR7HSN3P.js} +2 -2
  33. package/dist/cli-delegate/{chunk-REMEZSVP.js → chunk-SFGARMAB.js} +13 -3
  34. package/dist/cli-delegate/{chunk-DS6BLDMG.js → chunk-U7CMAIOC.js} +7 -2
  35. package/dist/cli-delegate/cmd_conformance.js +4 -4
  36. package/dist/cli-delegate/cmd_doctor.js +3 -3
  37. package/dist/cli-delegate/cmd_export.js +3 -3
  38. package/dist/cli-delegate/cmd_handoff.js +1 -1
  39. package/dist/cli-delegate/cmd_migrate.js +1 -1
  40. package/dist/cli-delegate/cmd_prune.js +3 -3
  41. package/dist/cli-delegate/cmd_refresh.js +1 -1
  42. package/dist/cli-delegate/cmd_session_recycle.js +8 -1
  43. package/dist/cli-delegate/cmd_settings_migrate.js +3 -3
  44. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  45. package/dist/cli-delegate/cmd_sync.js +3 -3
  46. package/dist/cli-delegate/cmd_uninstall.js +3 -3
  47. package/dist/cli-delegate/cmd_upgrade.js +1 -1
  48. package/dist/cli-delegate/cmd_validate.js +3 -3
  49. package/dist/discovery/deprecation-report.md +1 -1
  50. package/dist/discovery/discovery-manifest.json +14 -14
  51. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  52. package/dist/discovery/discovery-manifest.summary.md +1 -1
  53. package/dist/discovery/dormancy-report.md +1 -1
  54. package/dist/discovery/orphan-report.md +1 -1
  55. package/dist/discovery/packs.json +2 -2
  56. package/dist/discovery/trust-report.md +1 -1
  57. package/dist/discovery/workspaces.json +2 -2
  58. package/dist/hooks/dispatch.js +789 -401
  59. package/dist/install/install.mjs +21 -4
  60. package/dist/mcp/registry-manifest.json +2 -2
  61. package/dist/mcp/server.json +2 -2
  62. package/dist/mcp/server.mjs +99 -7
  63. package/dist/router.json +1 -1
  64. package/dist/server/schemas/settings.js +6 -0
  65. package/dist/server/schemas/settings.js.map +1 -1
  66. package/docs/contracts/settings-classes.md +5 -2
  67. package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +46 -4
  68. package/package.json +2 -2
  69. package/src/agent-src/scripts/roadmap_gates.ts +119 -4
  70. package/src/agent-src/templates/AGENTS.md +1 -1
  71. package/src/agent-src/templates/scripts/memory_lookup.ts +1 -2
  72. package/src/agent-src/templates/scripts/memory_signal.ts +2 -4
  73. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/decision_gate.ts +35 -5
  74. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/staged_confirmation.ts +252 -0
  75. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/staged_confirmation_store.ts +307 -0
  76. package/src/config/agent-settings.template.yml +43 -2
  77. package/src/config/gate-coverage.yml +12 -0
  78. package/src/config/quorum-attendance-budget.json +10 -2
  79. package/src/scripts/_cli/cmd_doctor.ts +32 -0
  80. package/src/scripts/_cli/cmd_migrate.ts +26 -3
  81. package/src/scripts/_cli/cmd_refresh.ts +29 -0
  82. package/src/scripts/_cli/cmd_session_recycle.ts +40 -2
  83. package/src/scripts/_dispatch.bash +6 -2
  84. package/src/scripts/_lib/hook_settings.ts +79 -0
  85. package/src/scripts/_lib/session_register.ts +67 -1
  86. package/src/scripts/_lib/ui_surface.ts +97 -0
  87. package/src/scripts/ai_council/config.ts +60 -0
  88. package/src/scripts/ai_council/events_log.ts +103 -4
  89. package/src/scripts/ai_council/quorum.ts +83 -6
  90. package/src/scripts/capture_skill_catalogue.ts +483 -0
  91. package/src/scripts/council_cli.ts +36 -1
  92. package/src/scripts/hook_manifest.yaml +18 -3
  93. package/src/scripts/hooks/concern_registry.ts +2 -0
  94. package/src/scripts/hooks/design_slop_hook.ts +1 -1
  95. package/src/scripts/hooks/turn_end_gate_hook.ts +172 -11
  96. package/src/scripts/hooks/ui_route_nudge_hook.ts +250 -0
  97. package/src/scripts/lint_framework_leakage.ts +195 -28
  98. package/src/scripts/lint_framework_leakage_allowlist.json +94 -86
  99. package/src/scripts/lint_roadmap_complexity.ts +60 -0
  100. package/src/scripts/lint_rule_skill_pack_reach.ts +263 -0
  101. package/src/scripts/memory_lookup.ts +1 -2
  102. package/src/scripts/report_consultation_rate.ts +358 -0
  103. package/src/scripts/report_skill_activation.ts +5 -1
  104. package/src/scripts/schemas/command.schema.json +4 -0
  105. package/src/scripts/schemas/skill.schema.json +4 -0
  106. package/src/scripts/session_register_hook.ts +238 -18
  107. package/src/scripts/sessions_cli.ts +377 -12
  108. package/src/server/schemas/settings.ts +12 -0
  109. /package/dist/agent-src/skills/design-system-capture/{reference → references}/design-system-json.md +0 -0
  110. /package/dist/agent-src/skills/prediction-pool-optimizer/{reference → references}/ev-fixtures.md +0 -0
  111. /package/dist/agent-src/skills/prediction-pool-optimizer/{reference → references}/odds-and-bonus.md +0 -0
  112. /package/dist/agent-src/skills/react-shadcn-ui/{reference → references}/registry.md +0 -0
@@ -10446,8 +10446,8 @@ function ruleFileArrives(sourcePath, scope) {
10446
10446
  if (!sourcePath.endsWith(".md")) {
10447
10447
  return true;
10448
10448
  }
10449
- const basename5 = path12.basename(sourcePath);
10450
- if (COMPAT_ALWAYS_EXCLUDED.includes(basename5)) {
10449
+ const basename6 = path12.basename(sourcePath);
10450
+ if (COMPAT_ALWAYS_EXCLUDED.includes(basename6)) {
10451
10451
  return false;
10452
10452
  }
10453
10453
  return rule_in_scope(sourcePath, scope.workspaces, scope.packs, scope.roles ?? null);
@@ -14591,6 +14591,7 @@ var modelAutoSwitch = external_exports.enum(["auto", "suggest", "off"]);
14591
14591
  var leanProjectionMode = external_exports.enum(["eager-all", "thin"]);
14592
14592
  var projectionMode = external_exports.enum(["legacy-all", "scoped"]);
14593
14593
  var memoryCadence = external_exports.enum(["auto", "always", "never"]);
14594
+ var projectAudience = external_exports.enum(["self", "internal", "client", "public"]);
14594
14595
  var settingsSchema = external_exports.object({
14595
14596
  agent_config_version: external_exports.string().default("").describe(
14596
14597
  'Pin the package to an exact semver (e.g. "1.4.2") so all teammates load the same skill / rule set. Leave empty to track whatever is installed locally \u2014 useful for the maintainers of this package, risky for production projects.'
@@ -14695,6 +14696,9 @@ var settingsSchema = external_exports.object({
14695
14696
  ),
14696
14697
  improvement_pr_branch_prefix: external_exports.string().default("improve/agent-").describe(
14697
14698
  'Branch-name prefix for improvement PRs the agent opens against project.upstream_repo (e.g. "improve/agent-add-react-skill"). Pick a prefix your repo conventions allow.'
14699
+ ),
14700
+ audience: projectAudience.default("public").describe(
14701
+ 'Who this project is built for \u2014 read by the demand gate (\xA7 8-pre of docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md), whose L0-L4 ladder measures MARKET demand and is meaningless where no market is intended. self = a tool its maintainer builds for themselves; the gate is inert and work is classified L-self (build) instead of being deferred for lack of a user population nobody wants. internal = a team tool; only "what breaks without it?" survives. client = built for a named client, who is the requester rather than a market segment. public (default) = a product with an intended market; full three-question gate, behaviour unchanged from before this key existed.'
14698
14702
  )
14699
14703
  }),
14700
14704
  github: external_exports.object({
@@ -15062,6 +15066,11 @@ var settingsSchema = external_exports.object({
15062
15066
  "PreToolUse anti-slop nudge (road-to-anti-slop-detector Phase 3). Default off. When on, runs the lint_design_slop registry against about-to-be-written UI content and WARNS (never blocks) on P0/P1 aesthetic tells (side-stripe, gradient-text, magic z-index, \u2026). Flags are rebuttable via DESIGN.md / design-slop-disable. Anti-loop: a file::rule signature surfaced 3x goes silent. Host-limited convenience layer; the universal gate is the lint_design_slop linter/CI."
15063
15067
  )
15064
15068
  }).default({}),
15069
+ ui_route_nudge: external_exports.object({
15070
+ enabled: external_exports.boolean().default(false).describe(
15071
+ "PreToolUse UI-route nudge (road-to-frontend-skill-application Phase 4). Default off. When on, a Write/Edit to a UI surface with no design consultation latched this session WARNS (never blocks) naming the route \u2014 run existing-ui-audit, then the fe-design loop. A read or search touching fe-design / existing-ui-audit / design-review / design-intelligence latches consultation and silences it for the session. Anti-loop: at most 2 nudges per session. It does not read the rules: the UI-surface decision comes from _lib/ui_surface.ts and no code parses rule frontmatter, so this runs parallel to the two UI rules rather than consuming their triggers, and a test keeps the sets from drifting. It is a nudge, so their enforced_by: none stays accurate."
15072
+ )
15073
+ }).default({}),
15065
15074
  code_graph: external_exports.object({
15066
15075
  enabled: external_exports.boolean().default(false).describe(
15067
15076
  "PreToolUse code-graph nudge (ADR-124 Phase 4). Default off. When on AND a native code-graph cache or a consumer-shipped graph.json/SCIP index is present, warns once per session (never blocks) as the agent is about to Grep/Glob or Read a source file \u2014 query the graph first for who-calls/where-used/impact questions (or rebuild if stale, build if absent). Source G\u2019s strict block-first-read mode is deliberately un-ported."
@@ -15076,6 +15085,9 @@ var settingsSchema = external_exports.object({
15076
15085
  ),
15077
15086
  language: external_exports.boolean().default(true).describe(
15078
15087
  "Detector B of the turn-end gate: refuse a turn whose reply is not in the pinned language (19 measured occurrences). Fenced code, inline code, quoted tool output, tables, URLs and paths are stripped first, and the remainder is then scored LEAD-FIRST by the same classifier that sets the pin \u2014 so the verdict usually comes from the reply opening, not from all of it. Sharing that classifier is deliberate: it stops the pin and the detector disagreeing about a turn. Accepted opt-in spellings for the switches below include YAML true/false and yes/no/on/off. Inert while hooks.turn_end_gate.enabled is false."
15088
+ ),
15089
+ verification: external_exports.boolean().default(true).describe(
15090
+ "Detector C of the turn-end gate: refuse a turn that changed a file and then ran nothing that could have checked it \u2014 no test, type-check, lint or build call follows the LAST edit. Ordering is the point: a run before the final edit did not exercise it, which is the freshness clause verify-before-complete states. Read off the turn tool calls, not the prose, because a reply cannot say whether an edit was verified. Deliberately narrow on what counts as verification \u2014 a missed detection costs one unguarded turn, a false refusal teaches you to switch the gate off. No fire rate is quoted: none has been measured yet. Inert while hooks.turn_end_gate.enabled is false."
15079
15091
  )
15080
15092
  }).default({})
15081
15093
  }),
@@ -17242,12 +17254,17 @@ function main(argv = null, options = {}) {
17242
17254
  }
17243
17255
  return _apply(project, out, err);
17244
17256
  }
17245
- var _bundled = true;
17257
+ var _inForeignBundle = !(typeof __AGENT_CONFIG_CLI_DELEGATE__ !== "undefined" && __AGENT_CONFIG_CLI_DELEGATE__);
17246
17258
  var _HERE = fileURLToPath4(import.meta.url);
17247
17259
  function _isCliEntry() {
17248
17260
  if (process2.argv[1] === void 0) {
17249
17261
  return false;
17250
17262
  }
17263
+ if (typeof __AGENT_CONFIG_CLI_DELEGATE__ !== "undefined" && __AGENT_CONFIG_CLI_DELEGATE__) {
17264
+ if (path15.basename(process2.argv[1], ".js") === "cmd_migrate") {
17265
+ return true;
17266
+ }
17267
+ }
17251
17268
  const argvUrl = pathToFileURL(path15.resolve(process2.argv[1])).href;
17252
17269
  if (import.meta.url === argvUrl) {
17253
17270
  return true;
@@ -17260,7 +17277,7 @@ function _isCliEntry() {
17260
17277
  return false;
17261
17278
  }
17262
17279
  }
17263
- if (!_bundled && (_isCliEntry() || process2.argv[1] === _HERE)) {
17280
+ if (!_inForeignBundle && (_isCliEntry() || process2.argv[1] === _HERE)) {
17264
17281
  try {
17265
17282
  process2.exitCode = main(process2.argv.slice(2));
17266
17283
  } catch (exc) {
@@ -3,13 +3,13 @@
3
3
  "artefact_count": 603,
4
4
  "scanner_version": "1eaf68b6e9c9"
5
5
  },
6
- "generated_at": "2026-08-11",
6
+ "generated_at": "2026-08-12",
7
7
  "package": {
8
8
  "description": "Governed skills, rules and commands for AI coding tools (Claude Code, Cursor, Windsurf, Copilot) \u2014 every claim machine-checked, including \"zero runtime daemon\".",
9
9
  "homepage": "https://event4u-app.github.io/agent-config",
10
10
  "name": "@event4u/agent-config",
11
11
  "repository": "https://github.com/event4u-app/agent-config",
12
- "version": "9.34.0"
12
+ "version": "9.36.0"
13
13
  },
14
14
  "registries": [
15
15
  {
@@ -9,12 +9,12 @@
9
9
  "transport": {
10
10
  "type": "stdio"
11
11
  },
12
- "version": "9.34.0"
12
+ "version": "9.36.0"
13
13
  }
14
14
  ],
15
15
  "repository": {
16
16
  "source": "github",
17
17
  "url": "https://github.com/event4u-app/agent-config"
18
18
  },
19
- "version": "9.34.0"
19
+ "version": "9.36.0"
20
20
  }
@@ -21543,9 +21543,19 @@ function main14(argv = null, options = {}) {
21543
21543
  return rc;
21544
21544
  }
21545
21545
  function _isCliEntry14() {
21546
+ const bundled = true;
21547
+ const cliDelegate = typeof __AGENT_CONFIG_CLI_DELEGATE__ !== "undefined" && __AGENT_CONFIG_CLI_DELEGATE__;
21548
+ if (bundled && !cliDelegate) {
21549
+ return false;
21550
+ }
21546
21551
  if (process14.argv[1] === void 0) {
21547
21552
  return false;
21548
21553
  }
21554
+ if (cliDelegate) {
21555
+ if (path29.basename(process14.argv[1], ".js") === "cmd_refresh") {
21556
+ return true;
21557
+ }
21558
+ }
21549
21559
  const argvUrl = pathToFileURL14(path29.resolve(process14.argv[1])).href;
21550
21560
  if (import.meta.url === argvUrl) {
21551
21561
  return true;
@@ -25418,9 +25428,19 @@ function evaluateQuorum(total, present, setting = "majority") {
25418
25428
  function isSoloConcluded(result) {
25419
25429
  return result.status === "concluded" && result.present === 1;
25420
25430
  }
25431
+ function wouldSoloFloorHold(result, minPresent = SOLO_FLOOR_MIN_PRESENT, configuredTotal) {
25432
+ if (result.status !== "concluded") {
25433
+ return false;
25434
+ }
25435
+ const ceiling = Math.max(result.total, configuredTotal ?? result.total);
25436
+ const floor = Math.min(Math.max(Math.trunc(minPresent), 1), ceiling);
25437
+ return result.present < floor;
25438
+ }
25439
+ var SOLO_FLOOR_MIN_PRESENT;
25421
25440
  var init_quorum = __esm({
25422
25441
  "src/scripts/ai_council/quorum.ts"() {
25423
25442
  "use strict";
25443
+ SOLO_FLOOR_MIN_PRESENT = 2;
25424
25444
  }
25425
25445
  });
25426
25446
 
@@ -25529,6 +25549,7 @@ function appendEvent(event, opts = {}) {
25529
25549
  }
25530
25550
  function appendQuorumEvent(input, opts = {}) {
25531
25551
  try {
25552
+ const minPresent = input.minPresent ?? SOLO_FLOOR_MIN_PRESENT;
25532
25553
  return appendEvent(
25533
25554
  {
25534
25555
  lens: input.lens,
@@ -25547,6 +25568,38 @@ function appendQuorumEvent(input, opts = {}) {
25547
25568
  // in `quorum.ts`, so a change to it cannot leave a consumer's
25548
25569
  // copy silently stale.
25549
25570
  solo: isSoloConcluded(input.result),
25571
+ // Declared class, never inferred — see `QuorumEventInput`.
25572
+ gate_class: input.gateClass ?? false,
25573
+ // The counterfactual, written on every line: would a
25574
+ // `min_present` floor have held this pass? Recorded as a FIELD
25575
+ // on `quorum_result` rather than as a new action, deliberately:
25576
+ // a new action is invisible to every consumer filtering
25577
+ // `action === 'quorum_result'`, which would split the
25578
+ // attendance population in two and silently move the
25579
+ // denominator of all four registered metrics. An additive
25580
+ // boolean moves no existing bucket.
25581
+ //
25582
+ // Mutually exclusive with `verdict: 'inconclusive'` by
25583
+ // construction (`wouldSoloFloorHold` returns false unless the
25584
+ // pass concluded), which is what makes "held by the floor" and
25585
+ // "threshold not met" readable apart from this line alone.
25586
+ // `configuredTotal` is passed, not omitted: post_run `total`
25587
+ // is the roster that CONSTRUCTED, so without it a pass that
25588
+ // lost a member at construction time reads total=1/present=1
25589
+ // and the floor cannot fire on it — the construction-degraded
25590
+ // solo case ADR-224 was actually decided on.
25591
+ //
25592
+ // `min_present` records the floor the counterfactual was
25593
+ // computed against, resolved ONCE below and used for both the
25594
+ // record and the predicate so the line can never disagree with
25595
+ // the boolean it explains — the one-definition discipline
25596
+ // `solo` follows by deferring to `isSoloConcluded`.
25597
+ min_present: minPresent,
25598
+ floor_would_hold: wouldSoloFloorHold(
25599
+ input.result,
25600
+ minPresent,
25601
+ input.configuredTotal
25602
+ ),
25550
25603
  absent: input.absent.map((a) => ({ member: a.member, reason: a.reason }))
25551
25604
  },
25552
25605
  opts
@@ -25644,7 +25697,7 @@ var init_events_log = __esm({
25644
25697
  "use strict";
25645
25698
  init_env_kill_switch();
25646
25699
  init_quorum();
25647
- SCHEMA_VERSION6 = 2;
25700
+ SCHEMA_VERSION6 = 4;
25648
25701
  _VALID_ACTIONS = /* @__PURE__ */ new Set([
25649
25702
  "proceed",
25650
25703
  "skip_necessity",
@@ -27835,6 +27888,9 @@ function _build_config(raw, source_path) {
27835
27888
  _asDict(_getOr(raw, "cli_call_budget", {}))
27836
27889
  );
27837
27890
  const quorum = _build_quorum(_get(raw, "quorum", "majority"));
27891
+ const quorum_min_present = _build_quorum_min_present(
27892
+ _get(raw, "quorum_min_present", SOLO_FLOOR_MIN_PRESENT)
27893
+ );
27838
27894
  const necessity_classifier = _build_necessity_classifier(
27839
27895
  _asDict(_getOr(raw, "necessity_classifier", {}))
27840
27896
  );
@@ -27883,6 +27939,7 @@ function _build_config(raw, source_path) {
27883
27939
  consensus_scoring: consensus,
27884
27940
  cli_call_budget,
27885
27941
  quorum,
27942
+ quorum_min_present,
27886
27943
  necessity_classifier,
27887
27944
  model_downgrade,
27888
27945
  debate,
@@ -28683,6 +28740,14 @@ function _build_quorum(raw) {
28683
28740
  `\`quorum\`=${_pyRepr6(raw)} must be 'majority' or an integer >= 1 (got ${_pyTypeName(raw)}).`
28684
28741
  );
28685
28742
  }
28743
+ function _build_quorum_min_present(raw) {
28744
+ if (_isInt(raw) && raw >= 1) {
28745
+ return raw;
28746
+ }
28747
+ throw new CouncilConfigError(
28748
+ `\`quorum_min_present\`=${_pyRepr6(raw)} must be an integer >= 1 (got ${_pyTypeName(raw)}).`
28749
+ );
28750
+ }
28686
28751
  function _build_advisor(name, cfg) {
28687
28752
  if (!_isDict(cfg)) {
28688
28753
  throw new CouncilConfigError(`advisors.${name}: must be a mapping.`);
@@ -28809,6 +28874,7 @@ var init_config = __esm({
28809
28874
  "use strict";
28810
28875
  import_yaml5 = __toESM(require_dist(), 1);
28811
28876
  init_user_global_paths();
28877
+ init_quorum();
28812
28878
  _VALID_PROVIDERS = /* @__PURE__ */ new Set([
28813
28879
  "anthropic",
28814
28880
  "openai",
@@ -29306,11 +29372,11 @@ function cliBinary(report2, provider) {
29306
29372
  if (meta === void 0) return null;
29307
29373
  const binaryName = meta[0];
29308
29374
  const host = report2.hosts.find(
29309
- (h) => h.binary !== null && stripExeSuffix(basename12(h.binary)) === binaryName
29375
+ (h) => h.binary !== null && stripExeSuffix(basename13(h.binary)) === binaryName
29310
29376
  );
29311
29377
  return host?.binary ?? null;
29312
29378
  }
29313
- function basename12(p) {
29379
+ function basename13(p) {
29314
29380
  const parts = p.split(/[/\\]/);
29315
29381
  return parts[parts.length - 1] ?? p;
29316
29382
  }
@@ -30207,8 +30273,8 @@ function ruleFileArrives(sourcePath, scope) {
30207
30273
  if (!sourcePath.endsWith(".md")) {
30208
30274
  return true;
30209
30275
  }
30210
- const basename20 = path52.basename(sourcePath);
30211
- if (COMPAT_ALWAYS_EXCLUDED.includes(basename20)) {
30276
+ const basename21 = path52.basename(sourcePath);
30277
+ if (COMPAT_ALWAYS_EXCLUDED.includes(basename21)) {
30212
30278
  return false;
30213
30279
  }
30214
30280
  return rule_in_scope(sourcePath, scope.workspaces, scope.packs, scope.roles ?? null);
@@ -32836,9 +32902,19 @@ function main18(argv = null) {
32836
32902
  return drift_present ? 1 : 0;
32837
32903
  }
32838
32904
  function _isCliEntry16() {
32905
+ const bundled = true;
32906
+ const cliDelegate = typeof __AGENT_CONFIG_CLI_DELEGATE__ !== "undefined" && __AGENT_CONFIG_CLI_DELEGATE__;
32907
+ if (bundled && !cliDelegate) {
32908
+ return false;
32909
+ }
32839
32910
  if (process15.argv[1] === void 0) {
32840
32911
  return false;
32841
32912
  }
32913
+ if (cliDelegate) {
32914
+ if (path53.basename(process15.argv[1], ".js") === "cmd_doctor") {
32915
+ return true;
32916
+ }
32917
+ }
32842
32918
  const argvUrl = pathToFileURL18(path53.resolve(process15.argv[1])).href;
32843
32919
  if (import.meta.url === argvUrl) {
32844
32920
  return true;
@@ -35323,7 +35399,7 @@ function censusSkills(root) {
35323
35399
  return out;
35324
35400
  }
35325
35401
  function defaultStore2(cwd) {
35326
- return path61.join(os14.homedir(), ".claude", "projects", cwd.replace(/\//g, "-"));
35402
+ return path61.join(os14.homedir(), ".claude", "projects", cwd.replace(/[/.]/g, "-"));
35327
35403
  }
35328
35404
  function measureUsage(store, limit) {
35329
35405
  const rep = { store, sessions: 0, assistantTurns: 0, invocations: 0, bySkill: {} };
@@ -44015,6 +44091,12 @@ function _synthesize_ai_council_block(cfg) {
44015
44091
  // configured `quorum: <k>`. Additive key — callers that never read
44016
44092
  // it observe no change.
44017
44093
  quorum: cfg.quorum,
44094
+ // Forwarded for the same reason `quorum` above had to be: a key that
44095
+ // `_build_config` validates and this block drops is a key the loader
44096
+ // enforces and the runtime never sees. That defect shipped once here
44097
+ // already; repeating it for the shadow floor would silently pin every
44098
+ // `floor_would_hold` to the default no matter what the operator set.
44099
+ quorum_min_present: cfg.quorum_min_present,
44018
44100
  necessity_classifier: {
44019
44101
  enabled: cfg.necessity_classifier.enabled,
44020
44102
  mode: cfg.necessity_classifier.mode,
@@ -44075,6 +44157,13 @@ function _quorum_setting_from(ai) {
44075
44157
  }
44076
44158
  return "majority";
44077
44159
  }
44160
+ function _quorum_min_present_from(ai) {
44161
+ const raw = ai["quorum_min_present"];
44162
+ if (typeof raw === "number" && Number.isInteger(raw) && raw >= 1) {
44163
+ return raw;
44164
+ }
44165
+ return SOLO_FLOOR_MIN_PRESENT;
44166
+ }
44078
44167
  function _emitQuorumEvent(phase, quorum, absent, ctx) {
44079
44168
  appendQuorumEvent({
44080
44169
  lens: ctx.lens ?? "",
@@ -44084,6 +44173,7 @@ function _emitQuorumEvent(phase, quorum, absent, ctx) {
44084
44173
  dispatch: ctx.dispatch ?? "full",
44085
44174
  configuredTotal: ctx.configuredTotal ?? quorum.total,
44086
44175
  result: quorum,
44176
+ ...ctx.minPresent !== void 0 ? { minPresent: ctx.minPresent } : {},
44087
44177
  absent: absent.map(
44088
44178
  (a) => ({
44089
44179
  member: String(a["member"] ?? ""),
@@ -44287,7 +44377,8 @@ function build_members(settings, opts = {}) {
44287
44377
  const present = total_enabled - absent_count;
44288
44378
  quorum_out.result = evaluateQuorum(total_enabled, present, _quorum_setting_from(ai));
44289
44379
  _emitQuorumEvent("pre_run", quorum_out.result, absent_entries, {
44290
- command: opts.command ?? "run"
44380
+ command: opts.command ?? "run",
44381
+ minPresent: _quorum_min_present_from(ai)
44291
44382
  });
44292
44383
  }
44293
44384
  if (members.length === 0) {
@@ -45530,6 +45621,7 @@ function cmd_run(args, opts = {}) {
45530
45621
  // and the solo-conclusion rate cannot make the one distinction it
45531
45622
  // exists for.
45532
45623
  dispatch: dispatch_shape,
45624
+ minPresent: _quorum_min_present_from(ai_cfg),
45533
45625
  ...configured_total !== null ? { configuredTotal: configured_total } : {},
45534
45626
  lens: question.mode,
45535
45627
  invocation: String(_getattr3(args, "invocation", "agent"))