@event4u/agent-config 14.20.0 → 14.21.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 (100) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +243 -0
  5. package/README.md +1 -1
  6. package/agents/templates/.ai-council.yml.example +10 -0
  7. package/dist/agent-src/commands/analyze/inbox.md +1 -1
  8. package/dist/agent-src/commands/analyze/{reference-repo.md → repo.md} +247 -32
  9. package/dist/agent-src/commands/analyze/roadmap-repos.md +129 -0
  10. package/dist/agent-src/commands/analyze.md +12 -7
  11. package/dist/agent-src/commands/feature/plan.md +55 -16
  12. package/dist/agent-src/commands/feature/refactor.md +8 -3
  13. package/dist/agent-src/commands/humanize.md +48 -4
  14. package/dist/agent-src/contexts/execution/contract-decision-sheet.md +22 -1
  15. package/dist/agent-src/contexts/execution/host-capability-manifest.md +4 -1
  16. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +35 -2
  17. package/dist/agent-src/contexts/execution/terminal-states.md +4 -1
  18. package/dist/agent-src/rules/evaluator-independence.md +4 -4
  19. package/dist/agent-src/rules/external-reference-deep-dive.md +2 -2
  20. package/dist/agent-src/skills/competitive-positioning/SKILL.md +2 -2
  21. package/dist/agent-src/skills/humanizer/references/anti-aiisms.md +27 -11
  22. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +1 -1
  23. package/dist/agent-src/skills/markitdown/SKILL.md +1 -1
  24. package/dist/agent-src/skills/repomix-packer/SKILL.md +1 -1
  25. package/dist/agent-src/skills/technical-specification/SKILL.md +4 -0
  26. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  27. package/dist/agent-src/templates/features.md +5 -0
  28. package/dist/agent-src/templates/roadmaps.md +15 -0
  29. package/dist/cli-delegate/{chunk-KPBWFOPZ.js → chunk-2FTMENJL.js} +194 -37
  30. package/dist/cli-delegate/{chunk-PI2GU3DP.js → chunk-2TAQ2K4V.js} +4 -1
  31. package/dist/cli-delegate/{chunk-C6IPZRDA.js → chunk-643Z7FIC.js} +1 -1
  32. package/dist/cli-delegate/{chunk-NUMQHLS5.js → chunk-J3RFNKG4.js} +21 -2
  33. package/dist/cli-delegate/cmd_conformance.js +17 -3
  34. package/dist/cli-delegate/cmd_doctor.js +3 -3
  35. package/dist/cli-delegate/cmd_export.js +2 -2
  36. package/dist/cli-delegate/cmd_handoff.js +1 -1
  37. package/dist/cli-delegate/cmd_prune.js +2 -2
  38. package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
  39. package/dist/cli-delegate/cmd_sync.js +2 -2
  40. package/dist/cli-delegate/cmd_uninstall.js +2 -2
  41. package/dist/cli-delegate/cmd_validate.js +2 -2
  42. package/dist/discovery/deprecation-report.md +1 -1
  43. package/dist/discovery/discovery-manifest.json +56 -25
  44. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  45. package/dist/discovery/discovery-manifest.summary.md +3 -3
  46. package/dist/discovery/dormancy-report.md +1 -1
  47. package/dist/discovery/orphan-report.md +1 -1
  48. package/dist/discovery/packs.json +7 -6
  49. package/dist/discovery/trust-report.md +2 -2
  50. package/dist/discovery/workspaces.json +6 -5
  51. package/dist/hooks/dispatch.js +479 -241
  52. package/dist/install/install.mjs +4 -1
  53. package/dist/mcp/registry-manifest.json +2 -2
  54. package/dist/mcp/server.json +2 -2
  55. package/dist/mcp/server.mjs +313 -63
  56. package/dist/scripts/ai_council/content_ceiling.js +63 -0
  57. package/dist/scripts/ai_council/seat_policy.js +106 -0
  58. package/dist/scripts/ai_council/transport_resolver.js +21 -0
  59. package/llms.txt +14 -14
  60. package/package.json +1 -1
  61. package/src/config/gate-violation-baselines.json +3 -3
  62. package/src/config/release-gate-locality.yml +4 -3
  63. package/src/scripts/_lib/blocked_by_marker.ts +189 -0
  64. package/src/scripts/_lib/host_capability.ts +38 -1
  65. package/src/scripts/_lib/release_highlights.ts +19 -211
  66. package/src/scripts/_lib/release_material.ts +27 -77
  67. package/src/scripts/_lib/structured_ask.ts +117 -0
  68. package/src/scripts/_lib/tty_prompt.ts +76 -0
  69. package/src/scripts/ai_council/api_transport.ts +163 -0
  70. package/src/scripts/ai_council/clients.ts +58 -63
  71. package/src/scripts/ai_council/config.ts +13 -0
  72. package/src/scripts/ai_council/content_ceiling.ts +79 -0
  73. package/src/scripts/ai_council/jury_aggregate.ts +178 -0
  74. package/src/scripts/ai_council/seat_policy.ts +137 -0
  75. package/src/scripts/ai_council/status_surface.ts +79 -0
  76. package/src/scripts/ai_council/transport_resolver.ts +59 -1
  77. package/src/scripts/ai_tells_rules.ts +446 -5
  78. package/src/scripts/ask_block_census.ts +499 -0
  79. package/src/scripts/bench_humanizer_eval.ts +264 -40
  80. package/src/scripts/bench_prose_tells_fp.ts +198 -0
  81. package/src/scripts/check_branch_work_committed.ts +234 -0
  82. package/src/scripts/check_pack_size.ts +1 -1
  83. package/src/scripts/check_release_highlights.ts +0 -157
  84. package/src/scripts/council_cli.ts +18 -27
  85. package/src/scripts/detect_ai_tells.ts +142 -20
  86. package/src/scripts/harvest_reference_tokens.ts +698 -0
  87. package/src/scripts/hook_manifest.json +1 -1
  88. package/src/scripts/hook_manifest.yaml +31 -1
  89. package/src/scripts/hooks/concern_registry.ts +2 -0
  90. package/src/scripts/hooks/delegation_nudge_hook.ts +45 -1
  91. package/src/scripts/hooks/one_question_per_ask_hook.ts +191 -0
  92. package/src/scripts/install-hooks.sh +52 -0
  93. package/src/scripts/lint_roadmap_blockers.ts +51 -1
  94. package/src/scripts/migrate_command_suggestions.ts +1 -1
  95. package/src/scripts/probe_unblocked_ask.ts +135 -2
  96. package/src/scripts/release.ts +26 -71
  97. package/src/scripts/release_drill.ts +6 -10
  98. package/src/scripts/release_env.ts +1 -0
  99. package/src/scripts/release_publication.ts +34 -29
  100. package/src/scripts/self_review_gate.ts +409 -15
@@ -81,7 +81,7 @@ __export(clients_exports, {
81
81
  record_cli_call: () => record_cli_call,
82
82
  reset_cli_call_counts: () => reset_cli_call_counts
83
83
  });
84
- import { spawnSync } from "node:child_process";
84
+ import { spawnSync as spawnSync2 } from "node:child_process";
85
85
  import * as fs3 from "node:fs";
86
86
  import * as os from "node:os";
87
87
  import * as path3 from "node:path";
@@ -205,6 +205,88 @@ function boundFor(member) {
205
205
  return AGENCY_BOUNDS.find((b) => b.member === member)?.bound ?? [];
206
206
  }
207
207
 
208
+ // src/scripts/ai_council/api_transport.ts
209
+ import { spawnSync } from "node:child_process";
210
+ var GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta";
211
+ function curlJsonPost(url, extraHeaders, body) {
212
+ const args = ["-sS", "-X", "POST", url, "-H", "content-type: application/json"];
213
+ for (const h of extraHeaders) {
214
+ args.push("-H", h);
215
+ }
216
+ args.push("--connect-timeout", "30", "--max-time", "290");
217
+ args.push("-w", "\n%{http_code}", "--data-binary", "@-");
218
+ const r = spawnSync("curl", args, {
219
+ input: JSON.stringify(body),
220
+ encoding: "utf8",
221
+ maxBuffer: 64 * 1024 * 1024,
222
+ timeout: 3e5
223
+ });
224
+ if (r.error) {
225
+ throw new Error(`curl spawn failed: ${r.error.message}`);
226
+ }
227
+ if (r.status !== 0) {
228
+ throw new Error(
229
+ `curl exited ${r.status ?? "null"}: ${(r.stderr ?? "").toString().slice(0, 500)}`
230
+ );
231
+ }
232
+ const out = (r.stdout ?? "").toString();
233
+ const nl = out.lastIndexOf("\n");
234
+ const httpCode = (nl >= 0 ? out.slice(nl + 1) : out).trim();
235
+ const bodyText = nl >= 0 ? out.slice(0, nl) : out;
236
+ if (!/^2\d\d$/.test(httpCode)) {
237
+ throw new Error(`HTTP ${httpCode}: ${bodyText.slice(0, 500)}`);
238
+ }
239
+ return JSON.parse(bodyText);
240
+ }
241
+ function openAiCompatibleClient(baseUrl, apiKey, post = curlJsonPost) {
242
+ const url = `${baseUrl.replace(/\/+$/, "")}/chat/completions`;
243
+ return {
244
+ chat: {
245
+ completions: {
246
+ create: (kwargs) => post(url, [`authorization: Bearer ${apiKey}`], kwargs)
247
+ }
248
+ }
249
+ };
250
+ }
251
+ function geminiRestClient(apiKey, post = curlJsonPost, baseUrl = GEMINI_BASE_URL) {
252
+ return {
253
+ models: {
254
+ generate_content: (kwargs) => {
255
+ const model = String(kwargs["model"] ?? "");
256
+ const cfg = kwargs["config"] ?? {};
257
+ const url = `${baseUrl.replace(/\/+$/, "")}/models/${model}:generateContent`;
258
+ const raw = post(
259
+ url,
260
+ [`x-goog-api-key: ${apiKey}`],
261
+ {
262
+ contents: [{ role: "user", parts: [{ text: String(kwargs["contents"] ?? "") }] }],
263
+ generationConfig: { maxOutputTokens: cfg["max_output_tokens"] ?? null }
264
+ }
265
+ );
266
+ return normaliseGeminiRest(raw);
267
+ }
268
+ }
269
+ };
270
+ }
271
+ function normaliseGeminiRest(raw) {
272
+ const env = raw ?? {};
273
+ const candidates = Array.isArray(env["candidates"]) ? env["candidates"] : [];
274
+ const first = candidates[0] ?? {};
275
+ const content = first["content"] ?? {};
276
+ const parts = Array.isArray(content["parts"]) ? content["parts"] : [];
277
+ const text = parts.map((p) => String((p ?? {})["text"] ?? "")).join("");
278
+ const usage = env["usageMetadata"] ?? {};
279
+ const num = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
280
+ return {
281
+ text,
282
+ model_version: String(env["modelVersion"] ?? ""),
283
+ usage_metadata: {
284
+ prompt_token_count: num(usage["promptTokenCount"]),
285
+ candidates_token_count: num(usage["candidatesTokenCount"])
286
+ }
287
+ };
288
+ }
289
+
208
290
  // src/scripts/_lib/session_role.ts
209
291
  var SESSION_ROLE_ENV = "AGENT_CONFIG_SESSION_ROLE";
210
292
  var KNOWN_ROLES = /* @__PURE__ */ new Set(["orchestrator", "worker", "reviewer"]);
@@ -899,34 +981,6 @@ var ExternalAIClient = class {
899
981
  return this.ask(system_prompt, user_prompt, max_tokens);
900
982
  }
901
983
  };
902
- function _curlJsonPost(url, extraHeaders, body) {
903
- const args = ["-sS", "-X", "POST", url, "-H", "content-type: application/json"];
904
- for (const h of extraHeaders) {
905
- args.push("-H", h);
906
- }
907
- args.push("--connect-timeout", "30", "--max-time", "290");
908
- args.push("-w", "\n%{http_code}", "--data-binary", "@-");
909
- const r = spawnSync("curl", args, {
910
- input: JSON.stringify(body),
911
- encoding: "utf8",
912
- maxBuffer: 64 * 1024 * 1024,
913
- timeout: 3e5
914
- });
915
- if (r.error) {
916
- throw new Error(`curl spawn failed: ${r.error.message}`);
917
- }
918
- if (r.status !== 0) {
919
- throw new Error(`curl exited ${r.status ?? "null"}: ${(r.stderr ?? "").toString().slice(0, 500)}`);
920
- }
921
- const out = (r.stdout ?? "").toString();
922
- const nl = out.lastIndexOf("\n");
923
- const httpCode = (nl >= 0 ? out.slice(nl + 1) : out).trim();
924
- const bodyText = nl >= 0 ? out.slice(0, nl) : out;
925
- if (!/^2\d\d$/.test(httpCode)) {
926
- throw new Error(`HTTP ${httpCode}: ${bodyText.slice(0, 500)}`);
927
- }
928
- return JSON.parse(bodyText);
929
- }
930
984
  var AnthropicClient = class extends ExternalAIClient {
931
985
  name = "anthropic";
932
986
  billable = true;
@@ -957,7 +1011,7 @@ var AnthropicClient = class extends ExternalAIClient {
957
1011
  }
958
1012
  this._client = {
959
1013
  messages: {
960
- create: (kwargs) => _curlJsonPost(
1014
+ create: (kwargs) => curlJsonPost(
961
1015
  "https://api.anthropic.com/v1/messages",
962
1016
  [`x-api-key: ${api_key}`, "anthropic-version: 2023-06-01"],
963
1017
  kwargs
@@ -1081,7 +1135,7 @@ var OpenAIClient = class extends ExternalAIClient {
1081
1135
  this._client = {
1082
1136
  chat: {
1083
1137
  completions: {
1084
- create: (kwargs) => _curlJsonPost(
1138
+ create: (kwargs) => curlJsonPost(
1085
1139
  "https://api.openai.com/v1/chat/completions",
1086
1140
  [`authorization: Bearer ${api_key}`],
1087
1141
  kwargs
@@ -1164,7 +1218,7 @@ var GeminiClient = class extends ExternalAIClient {
1164
1218
  "GeminiClient requires explicit api_key or injected client. Use `api_key_ref: env:GEMINI_API_KEY` in ~/.event4u/agent-config/settings/.ai-council.yml."
1165
1219
  );
1166
1220
  }
1167
- throw new Error("google-genai package not installed. `pip install google-genai`.");
1221
+ this._client = geminiRestClient(api_key, opts.transport ?? curlJsonPost);
1168
1222
  }
1169
1223
  ask(system_prompt, user_prompt, max_tokens = DEFAULT_MAX_TOKENS) {
1170
1224
  const t0 = _nowMs();
@@ -1226,7 +1280,11 @@ var _OpenAICompatibleClient = class extends ExternalAIClient {
1226
1280
  `${this.constructor.name} requires explicit api_key or injected client.`
1227
1281
  );
1228
1282
  }
1229
- throw new Error("openai package not installed. `pip install openai`.");
1283
+ this._client = openAiCompatibleClient(
1284
+ opts.base_url,
1285
+ api_key,
1286
+ opts.transport ?? curlJsonPost
1287
+ );
1230
1288
  }
1231
1289
  ask(system_prompt, user_prompt, max_tokens = DEFAULT_MAX_TOKENS) {
1232
1290
  const t0 = _nowMs();
@@ -1279,7 +1337,13 @@ var XAIClient = class extends _OpenAICompatibleClient {
1279
1337
  name = "xai";
1280
1338
  base_url = XAI_BASE_URL;
1281
1339
  constructor(opts = {}) {
1282
- super({ model: opts.model ?? DEFAULT_XAI_MODEL, client: opts.client, api_key: opts.api_key });
1340
+ super({
1341
+ model: opts.model ?? DEFAULT_XAI_MODEL,
1342
+ client: opts.client,
1343
+ api_key: opts.api_key,
1344
+ transport: opts.transport,
1345
+ base_url: XAI_BASE_URL
1346
+ });
1283
1347
  }
1284
1348
  };
1285
1349
  var PerplexityClient = class extends _OpenAICompatibleClient {
@@ -1289,7 +1353,9 @@ var PerplexityClient = class extends _OpenAICompatibleClient {
1289
1353
  super({
1290
1354
  model: opts.model ?? DEFAULT_PERPLEXITY_MODEL,
1291
1355
  client: opts.client,
1292
- api_key: opts.api_key
1356
+ api_key: opts.api_key,
1357
+ transport: opts.transport,
1358
+ base_url: PERPLEXITY_BASE_URL
1293
1359
  });
1294
1360
  }
1295
1361
  };
@@ -1546,7 +1612,7 @@ var CliClient = class extends ExternalAIClient {
1546
1612
  if (stdinPayload !== null) {
1547
1613
  spawnOpts.input = stdinPayload;
1548
1614
  }
1549
- const r = spawnSync(argv0, cmd.slice(1), spawnOpts);
1615
+ const r = spawnSync2(argv0, cmd.slice(1), spawnOpts);
1550
1616
  if (r.error) {
1551
1617
  const err = r.error;
1552
1618
  if (r.signal === "SIGTERM" || err.code === "ETIMEDOUT") {
@@ -2636,6 +2702,89 @@ import * as fs4 from "node:fs";
2636
2702
  import * as os2 from "node:os";
2637
2703
  import * as path4 from "node:path";
2638
2704
 
2705
+ // src/scripts/ai_council/content_ceiling.ts
2706
+ var CONTENT_CLASSES = ["public-artifact", "project-content"];
2707
+ var DEFAULT_CONTENT_CLASS = "project-content";
2708
+ var DEFAULT_SEAT_CEILING = "project-content";
2709
+ var _SET = new Set(CONTENT_CLASSES);
2710
+ function classifyContentClass(raw, fallback = DEFAULT_CONTENT_CLASS) {
2711
+ if (typeof raw === "string" && _SET.has(raw)) {
2712
+ return raw;
2713
+ }
2714
+ return fallback;
2715
+ }
2716
+ function admitsContent(seatCeiling, contentClass) {
2717
+ if (seatCeiling === "public-artifact" && contentClass === "project-content") {
2718
+ return {
2719
+ admitted: false,
2720
+ reason: "seat ceiling is 'public-artifact'; the payload is classified 'project-content' (consumer-supplied)"
2721
+ };
2722
+ }
2723
+ return { admitted: true, reason: null };
2724
+ }
2725
+
2726
+ // src/scripts/ai_council/seat_policy.ts
2727
+ var POLICY_EXCLUSIONS = [
2728
+ /** The provider's terms forbid this use of the route. */
2729
+ "policy_terms",
2730
+ /** A privacy constraint forbids sending to this route. */
2731
+ "policy_privacy",
2732
+ /** The route's cost property is asserted rather than proven. */
2733
+ "policy_unproven_cost",
2734
+ /** The route serves a model other than the one requested. */
2735
+ "policy_model_mismatch",
2736
+ /** 2.2 — the payload's content class exceeds the seat's ceiling. */
2737
+ "policy_content_ceiling",
2738
+ /** The config named an exclusion this build does not understand. */
2739
+ "policy_unknown"
2740
+ ];
2741
+ var _SET2 = new Set(POLICY_EXCLUSIONS);
2742
+ function isPolicyExclusion(v) {
2743
+ return typeof v === "string" && _SET2.has(v);
2744
+ }
2745
+ function classifyPolicyExclusion(raw) {
2746
+ if (raw === void 0 || raw === null) {
2747
+ return null;
2748
+ }
2749
+ return isPolicyExclusion(raw) ? raw : "policy_unknown";
2750
+ }
2751
+ function policyExclusionReason(p, provider) {
2752
+ const who = provider === void 0 ? "this seat" : provider;
2753
+ switch (p) {
2754
+ case "policy_terms":
2755
+ return `${who} is excluded by policy: the route's terms forbid this use`;
2756
+ case "policy_privacy":
2757
+ return `${who} is excluded by policy: a privacy constraint forbids this route`;
2758
+ case "policy_unproven_cost":
2759
+ return `${who} is excluded by policy: the route's cost property is asserted, not proven`;
2760
+ case "policy_model_mismatch":
2761
+ return `${who} is excluded by policy: the route serves a model other than the one requested`;
2762
+ case "policy_content_ceiling":
2763
+ return `${who} is excluded by policy: the payload exceeds the seat's content ceiling`;
2764
+ case "policy_unknown":
2765
+ return `${who} is excluded by policy: an exclusion this build does not understand (failing closed)`;
2766
+ }
2767
+ }
2768
+ function parseSeatFields(name, raw) {
2769
+ const dr = raw["disabled_reason"];
2770
+ let disabled_reason = null;
2771
+ if (dr !== void 0 && dr !== null) {
2772
+ if (typeof dr !== "string" || dr.trim() === "") {
2773
+ return {
2774
+ error: `members.${name}.disabled_reason must be a non-empty string when set (got ${JSON.stringify(dr)}).`
2775
+ };
2776
+ }
2777
+ disabled_reason = dr.trim();
2778
+ }
2779
+ return {
2780
+ fields: {
2781
+ disabled_reason,
2782
+ policy_exclusion: classifyPolicyExclusion(raw["policy_exclusion"]),
2783
+ content_ceiling: classifyContentClass(raw["content_ceiling"], DEFAULT_SEAT_CEILING)
2784
+ }
2785
+ };
2786
+ }
2787
+
2639
2788
  // src/scripts/ai_council/fallback_config.ts
2640
2789
  var SECOND_MODEL_PROVIDERS = /* @__PURE__ */ new Set([
2641
2790
  "anthropic",
@@ -3830,6 +3979,10 @@ function _build_member(name, cfg, default_mode = "auto", ignored = []) {
3830
3979
  }
3831
3980
  verified_at = coerced;
3832
3981
  }
3982
+ const seat = parseSeatFields(name, cfg);
3983
+ if ("error" in seat) {
3984
+ throw new CouncilConfigError(seat.error);
3985
+ }
3833
3986
  const prompt_cache_raw = _get(cfg, "prompt_cache", null);
3834
3987
  let prompt_cache_ttl = "5m";
3835
3988
  if (prompt_cache_raw !== null && prompt_cache_raw !== void 0 && !_isBool(prompt_cache_raw)) {
@@ -3857,7 +4010,8 @@ function _build_member(name, cfg, default_mode = "auto", ignored = []) {
3857
4010
  participate_low_impact: participate_raw,
3858
4011
  tier,
3859
4012
  prompt_cache_ttl,
3860
- verified_at
4013
+ verified_at,
4014
+ ...seat.fields
3861
4015
  };
3862
4016
  }
3863
4017
  var DEFAULT_CLI_CALLS_PER_DAY2 = DEFAULT_CLI_CALLS_PER_DAY;
@@ -4210,6 +4364,9 @@ export {
4210
4364
  hardenedSpawnEnv,
4211
4365
  load_cli_call_counts,
4212
4366
  clients_exports,
4367
+ DEFAULT_SEAT_CEILING,
4368
+ admitsContent,
4369
+ policyExclusionReason,
4213
4370
  _RAW_KEY_PREFIXES,
4214
4371
  config_exports
4215
4372
  };
@@ -978,6 +978,7 @@ var SAFE_DEFAULT = {
978
978
  separate_quota_pool: false,
979
979
  agent_teams: false,
980
980
  worker_respawn: false,
981
+ structured_ask: false,
981
982
  reads_project_mcp_config: false,
982
983
  // `true` because the safe answer here is "there is still a step", not
983
984
  // "there is nothing to do" — see the field's own note.
@@ -999,6 +1000,7 @@ function normalizeHostManifest(input) {
999
1000
  separate_quota_pool: asBool(src.separate_quota_pool),
1000
1001
  agent_teams: asBool(src.agent_teams),
1001
1002
  worker_respawn: asBool(src.worker_respawn),
1003
+ structured_ask: asBool(src.structured_ask),
1002
1004
  reads_project_mcp_config: asBool(src.reads_project_mcp_config),
1003
1005
  // Inverted coercion, matching the inverted default: only an explicit
1004
1006
  // `false` clears the residual, so an absent or malformed value keeps
@@ -1007,7 +1009,7 @@ function normalizeHostManifest(input) {
1007
1009
  };
1008
1010
  }
1009
1011
  var HOST_CAPABILITY_REGISTRY = {
1010
- claude: { subagent_spawn: true, parallel_spawn: true }
1012
+ claude: { subagent_spawn: true, parallel_spawn: true, structured_ask: false }
1011
1013
  };
1012
1014
  function resolveHostCapabilities(hostId, override) {
1013
1015
  if (override !== void 0 && override !== null && typeof override === "object" && !Array.isArray(override)) {
@@ -1032,6 +1034,7 @@ var CAPABILITY_FIELDS = [
1032
1034
  "separate_quota_pool",
1033
1035
  "agent_teams",
1034
1036
  "worker_respawn",
1037
+ "structured_ask",
1035
1038
  "reads_project_mcp_config",
1036
1039
  "mcp_needs_manual_activation"
1037
1040
  ];
@@ -30,7 +30,7 @@ import {
30
30
  save_inventory,
31
31
  upsert_tool,
32
32
  write_manifest
33
- } from "./chunk-PI2GU3DP.js";
33
+ } from "./chunk-2TAQ2K4V.js";
34
34
  import {
35
35
  check_version,
36
36
  classify_mismatch,
@@ -17,16 +17,19 @@ import {
17
17
  } from "./chunk-M2DPGFZ4.js";
18
18
  import {
19
19
  DEFAULT_PROJECTS_ROOT,
20
+ DEFAULT_SEAT_CEILING,
21
+ admitsContent,
20
22
  aggregateByBucket,
21
23
  billableInputTokens,
22
24
  clients_exports,
23
25
  config_exports,
24
26
  hardenedSpawnEnv,
25
27
  load_cli_call_counts,
28
+ policyExclusionReason,
26
29
  projectStoreSlug,
27
30
  scanTranscripts,
28
31
  weightedInputUnits
29
- } from "./chunk-KPBWFOPZ.js";
32
+ } from "./chunk-2FTMENJL.js";
30
33
  import {
31
34
  git_common_dir
32
35
  } from "./chunk-E4XIZDIB.js";
@@ -40,7 +43,7 @@ import {
40
43
  manifest_path,
41
44
  read_manifest,
42
45
  residualReport
43
- } from "./chunk-PI2GU3DP.js";
46
+ } from "./chunk-2TAQ2K4V.js";
44
47
  import {
45
48
  read_lockfile
46
49
  } from "./chunk-T7L2QK3K.js";
@@ -3168,6 +3171,22 @@ function resolveTransport(opts) {
3168
3171
  const auth = strongestAuth(report, provider);
3169
3172
  const authSource = auth?.source ?? null;
3170
3173
  const billing = classifyBilling(provider, authSource);
3174
+ const exclusion = opts.policyExclusion ?? null;
3175
+ if (exclusion !== null) {
3176
+ return unavailable(provider, billing, policyExclusionReason(exclusion, provider), exclusion);
3177
+ }
3178
+ const contentClass = opts.contentClass ?? null;
3179
+ if (contentClass !== null) {
3180
+ const verdict = admitsContent(opts.seatCeiling ?? DEFAULT_SEAT_CEILING, contentClass);
3181
+ if (!verdict.admitted) {
3182
+ return unavailable(
3183
+ provider,
3184
+ billing,
3185
+ `${provider}: ${verdict.reason ?? "content ceiling refused the payload"}`,
3186
+ "policy_content_ceiling"
3187
+ );
3188
+ }
3189
+ }
3171
3190
  if (mode === "manual") {
3172
3191
  return {
3173
3192
  available: true,
@@ -34,14 +34,14 @@ import {
34
34
  frontmatterPaths,
35
35
  proseEqual,
36
36
  splitFrontmatter
37
- } from "./chunk-NUMQHLS5.js";
37
+ } from "./chunk-J3RFNKG4.js";
38
38
  import "./chunk-FTAISGDQ.js";
39
39
  import "./chunk-M2DPGFZ4.js";
40
40
  import "./chunk-BTWUYDGN.js";
41
41
  import {
42
42
  projectStoreSlug,
43
43
  resolveSessionRole
44
- } from "./chunk-KPBWFOPZ.js";
44
+ } from "./chunk-2FTMENJL.js";
45
45
  import {
46
46
  atomic_write_json,
47
47
  atomic_write_text,
@@ -60,7 +60,7 @@ import {
60
60
  manifest_path,
61
61
  probeHostCapabilities,
62
62
  read_manifest
63
- } from "./chunk-PI2GU3DP.js";
63
+ } from "./chunk-2TAQ2K4V.js";
64
64
  import "./chunk-MWRD5YOH.js";
65
65
  import "./chunk-T7L2QK3K.js";
66
66
  import "./chunk-DMSZHXZS.js";
@@ -3853,6 +3853,12 @@ function buildNudgeLine(rung, classification, sliceCount, tier) {
3853
3853
  if (rung === 0.5) {
3854
3854
  return `<delegation-nudge>rung-0.5: ask, est. <1k tokens. This is a single bounded question \u2014 answer it via ONE completion (\`./scripts-run src/scripts/ask_transport "<question>"\`) instead of a subagent spawn (measured spawn floor: ~251k tokens) \u2014 ${classification.reason}.</delegation-nudge>`;
3855
3855
  }
3856
+ if (rung === 4) {
3857
+ return `<delegation-nudge>rung-4: council. This is contested judgment, not a slice to dispatch \u2014 route it to the council yourself via \`./scripts-run src/scripts/council_cli run --input <file>\` (check reachability first with \`agent-config council:status\`; the file path is the input, never an inline question). Not a spawn, and not run for you \u2014 ${classification.reason}.</delegation-nudge>`;
3858
+ }
3859
+ if (rung === 3) {
3860
+ return `<delegation-nudge>rung-3: team. These slices must see each other's state during the run, so a set of independent subagent spawns cannot express it \u2014 use the host teams primitive, or fall back to \`./scripts-run src/scripts/ask_transport "<question>"\` for a bounded sub-question. Not a spawn, and not run for you \u2014 ${classification.reason}.</delegation-nudge>`;
3861
+ }
3856
3862
  const modeLabel = classification.mode ?? "single-slice";
3857
3863
  return `<delegation-nudge>${rungLabel}: dispatch ${modeLabel} (${sliceCount} ${unit}, ${tier} tier recommended). Consider dispatching via subagent-orchestration instead of doing every slice in-session \u2014 ${classification.reason}.</delegation-nudge>`;
3858
3864
  }
@@ -3871,6 +3877,14 @@ function classifyPrompt(prompt, workspace_root, hostId) {
3871
3877
  agentTeams,
3872
3878
  insideSubagentSession: sessionRole !== "orchestrator"
3873
3879
  });
3880
+ if (ladder.verdict === "team" || ladder.verdict === "council") {
3881
+ return {
3882
+ classification: { delegable: false, action: "ask", mode: null, reason: ladder.reason },
3883
+ sliceCount: 0,
3884
+ tier: recommendSliceTier(downshift, separate_quota_pool),
3885
+ rung: ladder.rung
3886
+ };
3887
+ }
3874
3888
  if (ladder.verdict !== "subagent") {
3875
3889
  return null;
3876
3890
  }
@@ -66,13 +66,13 @@ import {
66
66
  _wizard_state_path,
67
67
  main,
68
68
  shutilWhich
69
- } from "./chunk-NUMQHLS5.js";
69
+ } from "./chunk-J3RFNKG4.js";
70
70
  import "./chunk-FTAISGDQ.js";
71
71
  import "./chunk-M2DPGFZ4.js";
72
72
  import "./chunk-BTWUYDGN.js";
73
- import "./chunk-KPBWFOPZ.js";
73
+ import "./chunk-2FTMENJL.js";
74
74
  import "./chunk-E4XIZDIB.js";
75
- import "./chunk-PI2GU3DP.js";
75
+ import "./chunk-2TAQ2K4V.js";
76
76
  import "./chunk-MWRD5YOH.js";
77
77
  import "./chunk-T7L2QK3K.js";
78
78
  import "./chunk-DMSZHXZS.js";
@@ -9,13 +9,13 @@ import {
9
9
  KIRO_MARKER,
10
10
  ROOCODE_MARKER,
11
11
  ZED_MARKER
12
- } from "./chunk-C6IPZRDA.js";
12
+ } from "./chunk-643Z7FIC.js";
13
13
  import "./chunk-4FS4WRXP.js";
14
14
  import "./chunk-6RJA2F5A.js";
15
15
  import "./chunk-WOKWX5PL.js";
16
16
  import "./chunk-523HCFYO.js";
17
17
  import "./chunk-A4QJ6ENT.js";
18
- import "./chunk-PI2GU3DP.js";
18
+ import "./chunk-2TAQ2K4V.js";
19
19
  import "./chunk-MWRD5YOH.js";
20
20
  import "./chunk-T7L2QK3K.js";
21
21
  import "./chunk-DMSZHXZS.js";
@@ -29,7 +29,7 @@ import {
29
29
  _RAW_KEY_PREFIXES,
30
30
  hardenedSpawnEnv,
31
31
  projectStoreSlug
32
- } from "./chunk-KPBWFOPZ.js";
32
+ } from "./chunk-2FTMENJL.js";
33
33
  import "./chunk-E4XIZDIB.js";
34
34
  import "./chunk-MWRD5YOH.js";
35
35
  import "./chunk-T7L2QK3K.js";
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
2
2
  import {
3
3
  PROJECT_BRIDGE_MARKERS
4
- } from "./chunk-C6IPZRDA.js";
4
+ } from "./chunk-643Z7FIC.js";
5
5
  import "./chunk-4FS4WRXP.js";
6
6
  import "./chunk-6RJA2F5A.js";
7
7
  import "./chunk-WOKWX5PL.js";
@@ -10,7 +10,7 @@ import "./chunk-A4QJ6ENT.js";
10
10
  import {
11
11
  manifest_path,
12
12
  read_manifest
13
- } from "./chunk-PI2GU3DP.js";
13
+ } from "./chunk-2TAQ2K4V.js";
14
14
  import "./chunk-MWRD5YOH.js";
15
15
  import "./chunk-T7L2QK3K.js";
16
16
  import "./chunk-DMSZHXZS.js";
@@ -3,13 +3,13 @@ import {
3
3
  GLOBAL_AGENT_SETTINGS_PATH,
4
4
  GLOBAL_USER_SETTINGS_PATH,
5
5
  SETTINGS_FILE
6
- } from "./chunk-C6IPZRDA.js";
6
+ } from "./chunk-643Z7FIC.js";
7
7
  import "./chunk-4FS4WRXP.js";
8
8
  import "./chunk-6RJA2F5A.js";
9
9
  import "./chunk-WOKWX5PL.js";
10
10
  import "./chunk-523HCFYO.js";
11
11
  import "./chunk-A4QJ6ENT.js";
12
- import "./chunk-PI2GU3DP.js";
12
+ import "./chunk-2TAQ2K4V.js";
13
13
  import "./chunk-MWRD5YOH.js";
14
14
  import "./chunk-T7L2QK3K.js";
15
15
  import "./chunk-DMSZHXZS.js";
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
2
2
  import {
3
3
  main
4
- } from "./chunk-C6IPZRDA.js";
4
+ } from "./chunk-643Z7FIC.js";
5
5
  import "./chunk-4FS4WRXP.js";
6
6
  import "./chunk-6RJA2F5A.js";
7
7
  import "./chunk-WOKWX5PL.js";
@@ -10,7 +10,7 @@ import "./chunk-A4QJ6ENT.js";
10
10
  import {
11
11
  manifest_path,
12
12
  read_manifest
13
- } from "./chunk-PI2GU3DP.js";
13
+ } from "./chunk-2TAQ2K4V.js";
14
14
  import "./chunk-MWRD5YOH.js";
15
15
  import "./chunk-T7L2QK3K.js";
16
16
  import "./chunk-DMSZHXZS.js";
@@ -3,7 +3,7 @@ import {
3
3
  PROJECT_BRIDGE_MARKERS,
4
4
  USER_SCOPE_PATHS,
5
5
  subtract_pointers
6
- } from "./chunk-C6IPZRDA.js";
6
+ } from "./chunk-643Z7FIC.js";
7
7
  import "./chunk-4FS4WRXP.js";
8
8
  import "./chunk-6RJA2F5A.js";
9
9
  import "./chunk-WOKWX5PL.js";
@@ -14,7 +14,7 @@ import {
14
14
  read_manifest,
15
15
  remove_managed_hooks,
16
16
  write_manifest
17
- } from "./chunk-PI2GU3DP.js";
17
+ } from "./chunk-2TAQ2K4V.js";
18
18
  import {
19
19
  write_atomic
20
20
  } from "./chunk-MWRD5YOH.js";
@@ -3,7 +3,7 @@ import { createRequire as __acCreateRequire } from 'node:module'; const require
3
3
  import {
4
4
  PROJECT_BRIDGE_MARKERS,
5
5
  USER_SCOPE_PATHS
6
- } from "./chunk-C6IPZRDA.js";
6
+ } from "./chunk-643Z7FIC.js";
7
7
  import "./chunk-4FS4WRXP.js";
8
8
  import "./chunk-6RJA2F5A.js";
9
9
  import "./chunk-WOKWX5PL.js";
@@ -12,7 +12,7 @@ import "./chunk-A4QJ6ENT.js";
12
12
  import {
13
13
  manifest_path,
14
14
  read_manifest
15
- } from "./chunk-PI2GU3DP.js";
15
+ } from "./chunk-2TAQ2K4V.js";
16
16
  import "./chunk-MWRD5YOH.js";
17
17
  import {
18
18
  current_package_version
@@ -1,6 +1,6 @@
1
1
  # Discovery — Deprecation Report
2
2
 
3
- - Generated: `2026-09-07T07:10:13Z`
3
+ - Generated: `2026-09-07T14:13:52Z`
4
4
  - Deprecated artefacts: **0**
5
5
 
6
6
  _None. Tree is clean._