@event4u/agent-config 9.28.0 → 9.29.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/AGENTS.md +6 -6
- package/CHANGELOG.md +66 -0
- package/README.md +1 -1
- package/agents/templates/.ai-council.yml.example +55 -24
- package/dist/agent-src/commands/cost/report.md +2 -2
- package/dist/agent-src/commands/team/adversarial.md +8 -7
- package/dist/agent-src/commands/team/delegate.md +13 -12
- package/dist/agent-src/commands/team/review.md +9 -8
- package/dist/agent-src/commands/team/status.md +9 -8
- package/dist/agent-src/commands/team.md +29 -19
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +88 -2
- package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +29 -21
- package/dist/agent-src/contexts/execution/host-capability-manifest.md +26 -15
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +18 -0
- package/dist/agent-src/contexts/execution/subagent-response-contract.md +54 -0
- package/dist/agent-src/contexts/execution/subagent-routing.md +13 -11
- package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +25 -0
- package/dist/agent-src/contexts/execution/subagent-steering.md +6 -3
- package/dist/agent-src/rules/delegation-policy.md +11 -7
- package/dist/agent-src/rules/settings-ask-protocol.md +8 -7
- package/dist/agent-src/rules/token-budget-discipline.md +1 -1
- package/dist/agent-src/skills/forensics-report/SKILL.md +114 -0
- package/dist/agent-src/skills/forensics-report/evals/triggers.json +17 -0
- package/dist/agent-src/skills/premortem/SKILL.md +30 -1
- package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +2 -1
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +7 -5
- package/dist/agent-src/skills/subagent-orchestration/schemas/subagent-status.json +61 -3
- package/dist/agent-src/skills/test-case-discovery/SKILL.md +1 -1
- package/dist/agent-src/templates/AGENTS.md +4 -4
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +23 -0
- package/dist/cli-delegate/{chunk-22GCIJ2O.js → chunk-66OVWGB5.js} +1 -1
- package/dist/cli-delegate/{chunk-GB2FSUEE.js → chunk-LCFJIQ4J.js} +32 -0
- package/dist/cli-delegate/{chunk-VSYT7OHO.js → chunk-LVRYBKTI.js} +31 -2
- package/dist/cli-delegate/{chunk-DVRS2KVR.js → chunk-MMXA5GY7.js} +10 -17
- package/dist/cli-delegate/{chunk-JXARCGVN.js → chunk-MP3JT3IU.js} +1 -1
- package/dist/cli-delegate/{chunk-PQSAQKHW.js → chunk-NZ5N2XQL.js} +3 -3
- package/dist/cli-delegate/{chunk-7OMQCH4V.js → chunk-OJM3MBJM.js} +1 -1
- package/dist/cli-delegate/{chunk-2BE5I2MN.js → chunk-RCIA67XN.js} +111 -90
- package/dist/cli-delegate/cmd_analyze_session.js +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +1 -1
- package/dist/cli-delegate/cmd_conformance.js +6 -43
- package/dist/cli-delegate/cmd_doctor.js +9 -5
- package/dist/cli-delegate/cmd_explain.js +2 -2
- package/dist/cli-delegate/cmd_export.js +4 -4
- package/dist/cli-delegate/cmd_handoff.js +3 -3
- package/dist/cli-delegate/cmd_mcp_available.js +1 -1
- package/dist/cli-delegate/cmd_migrate.js +2 -2
- package/dist/cli-delegate/cmd_packs_active.js +2 -2
- package/dist/cli-delegate/cmd_prune.js +4 -4
- package/dist/cli-delegate/cmd_route_audit.js +2 -2
- package/dist/cli-delegate/cmd_route_explain.js +1 -1
- package/dist/cli-delegate/cmd_settings_get.js +1 -7
- package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +4 -4
- package/dist/cli-delegate/cmd_uninstall.js +4 -4
- package/dist/cli-delegate/cmd_update.js +1 -1
- package/dist/cli-delegate/cmd_upgrade.js +1 -1
- package/dist/cli-delegate/cmd_validate.js +4 -4
- package/dist/cli-delegate/cmd_versions.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +69 -20
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -2
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +39 -2
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +12 -4
- package/dist/hooks/dispatch.js +373 -35
- package/dist/install/install.mjs +42 -17
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +651 -262
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_settings.js +54 -0
- package/dist/scripts/_lib/agent_settings.js.map +1 -1
- package/dist/scripts/condense.js +147 -2
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/schemas/settings.js +6 -7
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/shared/settingsCarveOut.js +0 -9
- package/dist/shared/settingsCarveOut.js.map +1 -1
- package/dist/shared/settingsClasses.js +11 -9
- package/dist/shared/settingsClasses.js.map +1 -1
- package/dist/ui/assets/{index-DmR0mbk4.js → index-JDAF00bC.js} +2 -2
- package/dist/ui/assets/{index-DmR0mbk4.js.map → index-JDAF00bC.js.map} +1 -1
- package/dist/ui/index.html +1 -1
- package/docs/contracts/settings-classes.md +39 -9
- package/package.json +1 -1
- package/src/agent-src/templates/AGENTS.md +4 -4
- package/src/config/agent-settings.template.yml +52 -66
- package/src/config/discovery/packs.yml +11 -0
- package/src/config/discovery/workspaces.yml +1 -1
- package/src/config/gate-violation-baselines.json +3 -3
- package/src/scripts/_cli/cmd_conformance.ts +14 -42
- package/src/scripts/_cli/cmd_doctor.ts +65 -48
- package/src/scripts/_lib/agent_settings.ts +58 -0
- package/src/scripts/_lib/auto_dispatch.corpus.test.ts +1 -1
- package/src/scripts/_lib/auto_dispatch.ts +23 -18
- package/src/scripts/_lib/capsule_trigger.ts +124 -0
- package/src/scripts/_lib/host_capability.ts +63 -6
- package/src/scripts/_lib/judgment_ladder.ts +382 -0
- package/src/scripts/_lib/orchestration_gate.ts +8 -0
- package/src/scripts/_lib/orchestration_record.ts +37 -0
- package/src/scripts/_lib/orchestration_savings.ts +1 -1
- package/src/scripts/_lib/self_repair.ts +160 -13
- package/src/scripts/_lib/self_repair_store.ts +28 -0
- package/src/scripts/_lib/subagent_capsule.ts +182 -0
- package/src/scripts/_lib/subagent_response.ts +19 -0
- package/src/scripts/_lib/subagent_spawn.ts +13 -0
- package/src/scripts/_lib/subagent_steering.ts +9 -4
- package/src/scripts/_lib/tier_budget_routing.ts +6 -1
- package/src/scripts/_lib/worker_budget.ts +37 -2
- package/src/scripts/ai_council/clients.ts +76 -54
- package/src/scripts/ai_council/config.ts +94 -6
- package/src/scripts/ai_council/handoff.ts +113 -0
- package/src/scripts/ai_council/modes.ts +19 -4
- package/src/scripts/ai_council/orchestrator.ts +105 -0
- package/src/scripts/ai_council/quorum.ts +84 -0
- package/src/scripts/ai_council/session.ts +44 -0
- package/src/scripts/ai_council/transport_resolver.ts +127 -1
- package/src/scripts/ai_team/availability.ts +110 -0
- package/src/scripts/ai_team/config.ts +34 -14
- package/src/scripts/ai_team/team_dispatch.ts +71 -29
- package/src/scripts/bench_critic_protocol.ts +396 -0
- package/src/scripts/check_detector_corpus.ts +202 -0
- package/src/scripts/check_hook_bundle_freshness.ts +4 -1
- package/src/scripts/condense.ts +162 -2
- package/src/scripts/council_cli.ts +401 -25
- package/src/scripts/forensics_report.ts +333 -0
- package/src/scripts/hooks/delegation_nudge_hook.ts +69 -35
- package/src/scripts/lint_discovery_vocabulary.ts +2 -0
- package/src/scripts/lint_never_silent.ts +276 -0
- package/src/scripts/lint_no_activation_gates.ts +271 -0
- package/src/scripts/orchestration_record.ts +8 -0
- package/src/scripts/rebuild_hook_bundle.ts +177 -0
- package/src/scripts/release.ts +74 -2
- package/src/scripts/routing_doctor.ts +21 -36
- package/src/scripts/score_skill_selection.ts +19 -5
- package/src/scripts/self_repair_cli.ts +287 -57
- package/src/scripts/team_events_spike.ts +271 -0
- package/src/scripts/team_review_gate_hook.ts +31 -9
- package/src/server/schemas/settings.ts +10 -17
- package/src/shared/settingsCarveOut.ts +0 -10
- package/src/shared/settingsClasses.ts +11 -9
package/dist/hooks/dispatch.js
CHANGED
|
@@ -11744,8 +11744,40 @@ function load_agent_settings(options = {}) {
|
|
|
11744
11744
|
_deep_merge(merged, layer);
|
|
11745
11745
|
}
|
|
11746
11746
|
}
|
|
11747
|
+
_warn_removed_always_on_keys(merged);
|
|
11747
11748
|
return merged;
|
|
11748
11749
|
}
|
|
11750
|
+
var REMOVED_ALWAYS_ON_KEYS = [
|
|
11751
|
+
"subagents.enabled",
|
|
11752
|
+
"subagents.auto",
|
|
11753
|
+
"subagents.host_capabilities",
|
|
11754
|
+
"subagents.budget_routing",
|
|
11755
|
+
"ai_team.enabled"
|
|
11756
|
+
];
|
|
11757
|
+
var _warnedRemovedAlwaysOnKeys = /* @__PURE__ */ new Set();
|
|
11758
|
+
function _readDottedSettingsPath(root, dotted) {
|
|
11759
|
+
let node = root;
|
|
11760
|
+
for (const part of dotted.split(".")) {
|
|
11761
|
+
if (typeof node !== "object" || node === null || Array.isArray(node)) {
|
|
11762
|
+
return void 0;
|
|
11763
|
+
}
|
|
11764
|
+
node = node[part];
|
|
11765
|
+
}
|
|
11766
|
+
return node;
|
|
11767
|
+
}
|
|
11768
|
+
function _warn_removed_always_on_keys(merged) {
|
|
11769
|
+
for (const key of REMOVED_ALWAYS_ON_KEYS) {
|
|
11770
|
+
if (_warnedRemovedAlwaysOnKeys.has(key)) {
|
|
11771
|
+
continue;
|
|
11772
|
+
}
|
|
11773
|
+
if (_readDottedSettingsPath(merged, key) === void 0) {
|
|
11774
|
+
continue;
|
|
11775
|
+
}
|
|
11776
|
+
_warnedRemovedAlwaysOnKeys.add(key);
|
|
11777
|
+
process.stderr.write(`${key} was removed (always-on orchestration); ignored.
|
|
11778
|
+
`);
|
|
11779
|
+
}
|
|
11780
|
+
}
|
|
11749
11781
|
function _read_yaml(p) {
|
|
11750
11782
|
if (!_is_file(p)) {
|
|
11751
11783
|
return null;
|
|
@@ -14196,6 +14228,7 @@ function _build_config(raw, source_path) {
|
|
|
14196
14228
|
const cli_call_budget = _build_cli_call_budget(
|
|
14197
14229
|
_asDict(_getOr(raw, "cli_call_budget", {}))
|
|
14198
14230
|
);
|
|
14231
|
+
const quorum = _build_quorum(_get(raw, "quorum", "majority"));
|
|
14199
14232
|
const necessity_classifier = _build_necessity_classifier(
|
|
14200
14233
|
_asDict(_getOr(raw, "necessity_classifier", {}))
|
|
14201
14234
|
);
|
|
@@ -14221,6 +14254,7 @@ function _build_config(raw, source_path) {
|
|
|
14221
14254
|
"debate_gates"
|
|
14222
14255
|
);
|
|
14223
14256
|
const restate = _build_restate(_asDict(_getOr(raw, "restate", {})), "restate");
|
|
14257
|
+
const critic_protocol = _build_critic_protocol(_getOr(raw, "critic_protocol", "legacy"));
|
|
14224
14258
|
const decision_resolution = _build_decision_resolution(
|
|
14225
14259
|
_asDict(_getOr(raw, "decision_resolution", {}))
|
|
14226
14260
|
);
|
|
@@ -14242,6 +14276,7 @@ function _build_config(raw, source_path) {
|
|
|
14242
14276
|
advisors,
|
|
14243
14277
|
consensus_scoring: consensus,
|
|
14244
14278
|
cli_call_budget,
|
|
14279
|
+
quorum,
|
|
14245
14280
|
necessity_classifier,
|
|
14246
14281
|
model_downgrade,
|
|
14247
14282
|
debate,
|
|
@@ -14250,6 +14285,7 @@ function _build_config(raw, source_path) {
|
|
|
14250
14285
|
chairman,
|
|
14251
14286
|
debate_gates,
|
|
14252
14287
|
restate,
|
|
14288
|
+
critic_protocol,
|
|
14253
14289
|
decision_resolution,
|
|
14254
14290
|
routing,
|
|
14255
14291
|
low_impact,
|
|
@@ -14451,6 +14487,16 @@ function _build_restate(d, scope) {
|
|
|
14451
14487
|
}
|
|
14452
14488
|
return { enabled: Boolean(enabled4) };
|
|
14453
14489
|
}
|
|
14490
|
+
var _VALID_CRITIC_PROTOCOLS = /* @__PURE__ */ new Set(["legacy", "load_bearing"]);
|
|
14491
|
+
function _build_critic_protocol(v) {
|
|
14492
|
+
if (v === void 0 || v === null) return "legacy";
|
|
14493
|
+
if (!(_isStr(v) && _VALID_CRITIC_PROTOCOLS.has(v))) {
|
|
14494
|
+
throw new CouncilConfigError(
|
|
14495
|
+
`\`critic_protocol\`=${_pyRepr3(v)} not in ${_sortedListRepr(_VALID_CRITIC_PROTOCOLS)}.`
|
|
14496
|
+
);
|
|
14497
|
+
}
|
|
14498
|
+
return v;
|
|
14499
|
+
}
|
|
14454
14500
|
var _VALID_RESOLUTION_MODES = /* @__PURE__ */ new Set([
|
|
14455
14501
|
"agent",
|
|
14456
14502
|
"council",
|
|
@@ -14726,7 +14772,7 @@ function _build_defaults(d) {
|
|
|
14726
14772
|
if (!_isDict(d)) {
|
|
14727
14773
|
throw new CouncilConfigError("`defaults` must be a mapping.");
|
|
14728
14774
|
}
|
|
14729
|
-
const mode = _get(d, "mode", "
|
|
14775
|
+
const mode = _get(d, "mode", "auto");
|
|
14730
14776
|
if (!(_isStr(mode) && _VALID_MODES.has(mode))) {
|
|
14731
14777
|
throw new CouncilConfigError(
|
|
14732
14778
|
`defaults.mode=${_pyRepr3(mode)} not in ${_sortedListRepr(_VALID_MODES)}.`
|
|
@@ -14888,7 +14934,7 @@ function _build_cost_budget(d) {
|
|
|
14888
14934
|
}
|
|
14889
14935
|
return cb;
|
|
14890
14936
|
}
|
|
14891
|
-
function _build_member(name, cfg, default_mode = "
|
|
14937
|
+
function _build_member(name, cfg, default_mode = "auto") {
|
|
14892
14938
|
if (!_VALID_PROVIDERS.has(name)) {
|
|
14893
14939
|
throw new CouncilConfigError(
|
|
14894
14940
|
`members.${name}: unknown provider; valid: ${_sortedListRepr(_VALID_PROVIDERS)}.`
|
|
@@ -15005,6 +15051,7 @@ function _build_member(name, cfg, default_mode = "api") {
|
|
|
15005
15051
|
prompt_cache_ttl
|
|
15006
15052
|
};
|
|
15007
15053
|
}
|
|
15054
|
+
var _DEFAULT_CLI_CALLS_PER_DAY = 50;
|
|
15008
15055
|
function _build_cli_call_budget(d) {
|
|
15009
15056
|
if (!_isDict(d)) {
|
|
15010
15057
|
throw new CouncilConfigError("`cli_call_budget` must be a mapping.");
|
|
@@ -15016,6 +15063,9 @@ function _build_cli_call_budget(d) {
|
|
|
15016
15063
|
);
|
|
15017
15064
|
}
|
|
15018
15065
|
const caps = /* @__PURE__ */ new Map();
|
|
15066
|
+
for (const provider of _VALID_PROVIDERS) {
|
|
15067
|
+
caps.set(provider, _DEFAULT_CLI_CALLS_PER_DAY);
|
|
15068
|
+
}
|
|
15019
15069
|
for (const [provider, value] of Object.entries(raw_caps)) {
|
|
15020
15070
|
if (!_VALID_PROVIDERS.has(provider)) {
|
|
15021
15071
|
throw new CouncilConfigError(
|
|
@@ -15043,6 +15093,17 @@ function _build_cli_call_budget(d) {
|
|
|
15043
15093
|
}
|
|
15044
15094
|
return { max_calls_per_day: caps, warn_at };
|
|
15045
15095
|
}
|
|
15096
|
+
function _build_quorum(raw) {
|
|
15097
|
+
if (raw === "majority") {
|
|
15098
|
+
return "majority";
|
|
15099
|
+
}
|
|
15100
|
+
if (_isInt(raw) && !_isBool(raw) && raw >= 1) {
|
|
15101
|
+
return raw;
|
|
15102
|
+
}
|
|
15103
|
+
throw new CouncilConfigError(
|
|
15104
|
+
`\`quorum\`=${_pyRepr3(raw)} must be 'majority' or an integer >= 1 (got ${_pyTypeName(raw)}).`
|
|
15105
|
+
);
|
|
15106
|
+
}
|
|
15046
15107
|
function _build_advisor(name, cfg) {
|
|
15047
15108
|
if (!_isDict(cfg)) {
|
|
15048
15109
|
throw new CouncilConfigError(`advisors.${name}: must be a mapping.`);
|
|
@@ -17998,7 +18059,6 @@ var AI_TEAM_REVIEW_GATE_DEFAULTS = Object.freeze({
|
|
|
17998
18059
|
max_consecutive_blocks: 3
|
|
17999
18060
|
});
|
|
18000
18061
|
var AI_TEAM_DEFAULTS = Object.freeze({
|
|
18001
|
-
enabled: false,
|
|
18002
18062
|
model: "auto",
|
|
18003
18063
|
allow_delegate: false,
|
|
18004
18064
|
max_calls_per_day: 50,
|
|
@@ -18006,13 +18066,13 @@ var AI_TEAM_DEFAULTS = Object.freeze({
|
|
|
18006
18066
|
review_gate: AI_TEAM_REVIEW_GATE_DEFAULTS
|
|
18007
18067
|
});
|
|
18008
18068
|
var _KNOWN_KEYS = /* @__PURE__ */ new Set([
|
|
18009
|
-
"enabled",
|
|
18010
18069
|
"model",
|
|
18011
18070
|
"allow_delegate",
|
|
18012
18071
|
"max_calls_per_day",
|
|
18013
18072
|
"suppress_setup_hint",
|
|
18014
18073
|
"review_gate"
|
|
18015
18074
|
]);
|
|
18075
|
+
var _DELETED_KEYS = /* @__PURE__ */ new Set(["enabled"]);
|
|
18016
18076
|
var _KNOWN_REVIEW_GATE_KEYS = /* @__PURE__ */ new Set([
|
|
18017
18077
|
"managed",
|
|
18018
18078
|
"max_consecutive_blocks"
|
|
@@ -18079,13 +18139,15 @@ function build_ai_team_config(raw) {
|
|
|
18079
18139
|
throw new TeamConfigError("`ai_team` must be a mapping.");
|
|
18080
18140
|
}
|
|
18081
18141
|
for (const key of Object.keys(raw)) {
|
|
18142
|
+
if (_DELETED_KEYS.has(key)) {
|
|
18143
|
+
continue;
|
|
18144
|
+
}
|
|
18082
18145
|
if (!_KNOWN_KEYS.has(key)) {
|
|
18083
18146
|
throw new TeamConfigError(
|
|
18084
18147
|
`ai_team.${key}: unknown key; valid: [${[..._KNOWN_KEYS].map((k) => `'${k}'`).join(", ")}].`
|
|
18085
18148
|
);
|
|
18086
18149
|
}
|
|
18087
18150
|
}
|
|
18088
|
-
const enabled4 = _requireBool(raw, "enabled", AI_TEAM_DEFAULTS.enabled);
|
|
18089
18151
|
const allow_delegate = _requireBool(raw, "allow_delegate", AI_TEAM_DEFAULTS.allow_delegate);
|
|
18090
18152
|
const suppress_setup_hint = _requireBool(
|
|
18091
18153
|
raw,
|
|
@@ -18113,7 +18175,7 @@ function build_ai_team_config(raw) {
|
|
|
18113
18175
|
max_calls_per_day = value;
|
|
18114
18176
|
}
|
|
18115
18177
|
const review_gate = _build_review_gate("review_gate" in raw ? raw["review_gate"] : void 0);
|
|
18116
|
-
return {
|
|
18178
|
+
return { model, allow_delegate, max_calls_per_day, suppress_setup_hint, review_gate };
|
|
18117
18179
|
}
|
|
18118
18180
|
function load_ai_team_config(opts = {}) {
|
|
18119
18181
|
const settings = opts.settings ?? load_agent_settings({ cwd: opts.cwd ?? process.cwd() });
|
|
@@ -18449,7 +18511,7 @@ function main20() {
|
|
|
18449
18511
|
} catch {
|
|
18450
18512
|
config = AI_TEAM_DEFAULTS;
|
|
18451
18513
|
}
|
|
18452
|
-
if (!config.
|
|
18514
|
+
if (!config.review_gate.managed) {
|
|
18453
18515
|
return 0;
|
|
18454
18516
|
}
|
|
18455
18517
|
let notice = null;
|
|
@@ -18919,7 +18981,10 @@ function sanitizeEvidence(raw) {
|
|
|
18919
18981
|
return flat.length <= MAX_EVIDENCE ? flat : `${flat.slice(0, MAX_EVIDENCE - 1)}\u2026`;
|
|
18920
18982
|
}
|
|
18921
18983
|
var COMPLAINT_PATTERNS = [
|
|
18922
|
-
|
|
18984
|
+
// No \b before the alternation: JS \b is ASCII-only, so a leading umlaut
|
|
18985
|
+
// ("übersehen") never sits on a word boundary — the corpus gate's
|
|
18986
|
+
// near-miss class caught that as a dead alternation branch.
|
|
18987
|
+
/\bdu hast\b[^.!?]{0,60}(nicht|falsch|vergessen|ignoriert|übersehen)\b/i,
|
|
18923
18988
|
/\bdu (ignorierst|übersiehst)\b/i,
|
|
18924
18989
|
/\b(das|es) (war|ist) (aber )?falsch\b/i,
|
|
18925
18990
|
/\bhat nicht (richtig|korrekt) (gearbeitet|funktioniert)\b/i,
|
|
@@ -18928,10 +18993,43 @@ var COMPLAINT_PATTERNS = [
|
|
|
18928
18993
|
/\bthat'?s (wrong|not right|incorrect)\b/i,
|
|
18929
18994
|
/\byou (worked|did (it|that)) (wrong|incorrectly)\b/i
|
|
18930
18995
|
];
|
|
18996
|
+
var COMPLAINT_EXONERATIONS = [
|
|
18997
|
+
/\bdu hast nicht zufällig\b/i,
|
|
18998
|
+
/\bhast du nicht zufällig\b/i,
|
|
18999
|
+
/\byou didn'?t (need|have) to\b/i,
|
|
19000
|
+
/\bit'?s fine\b/i,
|
|
19001
|
+
/\b(kein problem|passt schon|alles gut)\b/i,
|
|
19002
|
+
// Explicit absolution INSIDE the complaint span, which is why it has to be
|
|
19003
|
+
// its own entry rather than relying on a neighbouring pleasantry: in
|
|
19004
|
+
// "das ist fine, du hast nichts falsch gemacht" the matched span is
|
|
19005
|
+
// `du hast nichts falsch`, and the `it's fine` above sits outside the
|
|
19006
|
+
// ± EXONERATION_MARGIN window — correctly, since that margin exists to stop
|
|
19007
|
+
// a pleasantry in one clause muting a complaint in another. `nichts falsch`
|
|
19008
|
+
// is not a neighbouring pleasantry: it is the negation of the complaint
|
|
19009
|
+
// itself. Caught by the detector-corpus gate, which flagged this exact
|
|
19010
|
+
// string as a must-not-fire fixture that fired (PR #1231).
|
|
19011
|
+
/\bnichts falsch\b/i,
|
|
19012
|
+
/\bkein fehler\b/i
|
|
19013
|
+
];
|
|
19014
|
+
var EXONERATION_MARGIN = 12;
|
|
19015
|
+
function spanExonerated(prompt, start, end) {
|
|
19016
|
+
for (const ex of COMPLAINT_EXONERATIONS) {
|
|
19017
|
+
const g = new RegExp(ex.source, ex.flags.includes("g") ? ex.flags : `${ex.flags}g`);
|
|
19018
|
+
let m;
|
|
19019
|
+
while ((m = g.exec(prompt)) !== null) {
|
|
19020
|
+
const s = m.index;
|
|
19021
|
+
const e = m.index + m[0].length;
|
|
19022
|
+
if (e >= start - EXONERATION_MARGIN && s <= end + EXONERATION_MARGIN) {
|
|
19023
|
+
return true;
|
|
19024
|
+
}
|
|
19025
|
+
}
|
|
19026
|
+
}
|
|
19027
|
+
return false;
|
|
19028
|
+
}
|
|
18931
19029
|
function detectUserReport(prompt) {
|
|
18932
19030
|
for (const re of COMPLAINT_PATTERNS) {
|
|
18933
19031
|
const m = re.exec(prompt);
|
|
18934
|
-
if (m !== null) {
|
|
19032
|
+
if (m !== null && !spanExonerated(prompt, m.index, m.index + m[0].length)) {
|
|
18935
19033
|
return {
|
|
18936
19034
|
defect_class: "user-reported",
|
|
18937
19035
|
source: "user-reported",
|
|
@@ -18991,10 +19089,22 @@ function detectLanguageMirror(turn) {
|
|
|
18991
19089
|
suggested_surface: `Reply opened in the language the turn was not pinned to (pinned: ${pinned}) \u2014 report which surface carried the pin and why it did not bind.`
|
|
18992
19090
|
};
|
|
18993
19091
|
}
|
|
19092
|
+
var DETECTOR_REGISTRY = [
|
|
19093
|
+
{
|
|
19094
|
+
defect_class: "user-reported",
|
|
19095
|
+
source: "user-reported",
|
|
19096
|
+
detect: (turn) => detectUserReport(turn.prompt)
|
|
19097
|
+
},
|
|
19098
|
+
{ defect_class: "council-availability-claim", source: "self-detected", detect: detectCouncilClaim },
|
|
19099
|
+
{ defect_class: "language-mirror", source: "self-detected", detect: detectLanguageMirror }
|
|
19100
|
+
];
|
|
18994
19101
|
function runDetectors(turn) {
|
|
18995
19102
|
const out = [];
|
|
18996
|
-
for (const d of
|
|
18997
|
-
|
|
19103
|
+
for (const d of DETECTOR_REGISTRY) {
|
|
19104
|
+
if (d.source !== "self-detected") {
|
|
19105
|
+
continue;
|
|
19106
|
+
}
|
|
19107
|
+
const f = d.detect(turn);
|
|
18998
19108
|
if (f !== null) {
|
|
18999
19109
|
out.push(f);
|
|
19000
19110
|
}
|
|
@@ -22824,6 +22934,7 @@ var BANDS = ["low", "medium", "high"];
|
|
|
22824
22934
|
var PHASES = ["refine", "memory", "analyze", "plan", "implement", "test", "verify", "report"];
|
|
22825
22935
|
var LOOKUP_CLASSES = ["definition", "references", "string-existence", "report-run"];
|
|
22826
22936
|
var ROUTES_TAKEN = ["primitive", "subagent"];
|
|
22937
|
+
var TRIGGER_ARMS = ["watermark", "saturation", "tie"];
|
|
22827
22938
|
var PAYLOAD_HASH_RE = /^[a-f0-9]{8,64}$/i;
|
|
22828
22939
|
var ORIGIN_RE = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
22829
22940
|
function envelopeOutcome(d) {
|
|
@@ -22906,6 +23017,19 @@ function buildOrchestrationLine(input) {
|
|
|
22906
23017
|
if (input.rules_carried != null && input.rules_used != null && input.rules_used > input.rules_carried) {
|
|
22907
23018
|
errors.push("rules_used cannot exceed rules_carried (a worker cannot apply a rule it was not given)");
|
|
22908
23019
|
}
|
|
23020
|
+
if (input.capsule_emitted !== void 0 && typeof input.capsule_emitted !== "boolean") {
|
|
23021
|
+
errors.push("capsule_emitted must be a boolean or omitted");
|
|
23022
|
+
}
|
|
23023
|
+
for (const [key, v] of [
|
|
23024
|
+
["capsule_entries", input.capsule_entries],
|
|
23025
|
+
["watermark_step", input.watermark_step],
|
|
23026
|
+
["saturation_step", input.saturation_step]
|
|
23027
|
+
]) {
|
|
23028
|
+
if (v != null && (!isInt(v) || v < 0)) errors.push(`${key} must be a non-negative integer count`);
|
|
23029
|
+
}
|
|
23030
|
+
if (input.trigger_arm_earlier != null && !TRIGGER_ARMS.includes(input.trigger_arm_earlier)) {
|
|
23031
|
+
errors.push(`trigger_arm_earlier must be one of ${TRIGGER_ARMS.join(" | ")} (or omitted / null when neither arm fired)`);
|
|
23032
|
+
}
|
|
22909
23033
|
if (!input.ts) errors.push("ts (ISO-8601 UTC) is required");
|
|
22910
23034
|
if (!input.id) errors.push("id (ULID or content hash) is required");
|
|
22911
23035
|
if (errors.length) return { line: null, errors };
|
|
@@ -22937,7 +23061,13 @@ function buildOrchestrationLine(input) {
|
|
|
22937
23061
|
cache_hit: input.cache_hit ?? null,
|
|
22938
23062
|
origin: input.origin ?? null,
|
|
22939
23063
|
rules_carried: input.rules_carried ?? null,
|
|
22940
|
-
rules_used: input.rules_used ?? null
|
|
23064
|
+
rules_used: input.rules_used ?? null,
|
|
23065
|
+
// capsule shadow-measurement — readers ignore unknowns per audit-log-v1
|
|
23066
|
+
capsule_emitted: input.capsule_emitted ?? null,
|
|
23067
|
+
capsule_entries: input.capsule_entries ?? null,
|
|
23068
|
+
watermark_step: input.watermark_step ?? null,
|
|
23069
|
+
saturation_step: input.saturation_step ?? null,
|
|
23070
|
+
trigger_arm_earlier: input.trigger_arm_earlier ?? null
|
|
22941
23071
|
};
|
|
22942
23072
|
const line = {
|
|
22943
23073
|
schema_version: 1,
|
|
@@ -23046,6 +23176,11 @@ function main37(argv = process.argv.slice(2)) {
|
|
|
23046
23176
|
origin: str2(flags, "origin"),
|
|
23047
23177
|
rules_carried: int(flags, "rules-carried"),
|
|
23048
23178
|
rules_used: int(flags, "rules-used"),
|
|
23179
|
+
capsule_emitted: bool(flags, "capsule-emitted"),
|
|
23180
|
+
capsule_entries: int(flags, "capsule-entries"),
|
|
23181
|
+
watermark_step: int(flags, "watermark-step"),
|
|
23182
|
+
saturation_step: int(flags, "saturation-step"),
|
|
23183
|
+
trigger_arm_earlier: str2(flags, "trigger-arm-earlier"),
|
|
23049
23184
|
phase: str2(flags, "phase"),
|
|
23050
23185
|
outcome: str2(flags, "outcome"),
|
|
23051
23186
|
confidence_band: str2(flags, "confidence-band"),
|
|
@@ -23228,12 +23363,15 @@ import path55 from "node:path";
|
|
|
23228
23363
|
import { fileURLToPath as fileURLToPath39, pathToFileURL as pathToFileURL34 } from "node:url";
|
|
23229
23364
|
|
|
23230
23365
|
// src/scripts/_lib/host_capability.ts
|
|
23366
|
+
import process10 from "node:process";
|
|
23231
23367
|
var SAFE_DEFAULT = {
|
|
23232
23368
|
schema_version: 1,
|
|
23233
23369
|
subagent_spawn: false,
|
|
23234
23370
|
parallel_spawn: false,
|
|
23235
23371
|
status_polling: false,
|
|
23236
|
-
separate_quota_pool: false
|
|
23372
|
+
separate_quota_pool: false,
|
|
23373
|
+
agent_teams: false,
|
|
23374
|
+
worker_respawn: false
|
|
23237
23375
|
};
|
|
23238
23376
|
function asBool(value) {
|
|
23239
23377
|
return value === true;
|
|
@@ -23248,7 +23386,9 @@ function normalizeHostManifest(input) {
|
|
|
23248
23386
|
subagent_spawn: asBool(src.subagent_spawn),
|
|
23249
23387
|
parallel_spawn: asBool(src.parallel_spawn),
|
|
23250
23388
|
status_polling: asBool(src.status_polling),
|
|
23251
|
-
separate_quota_pool: asBool(src.separate_quota_pool)
|
|
23389
|
+
separate_quota_pool: asBool(src.separate_quota_pool),
|
|
23390
|
+
agent_teams: asBool(src.agent_teams),
|
|
23391
|
+
worker_respawn: asBool(src.worker_respawn)
|
|
23252
23392
|
};
|
|
23253
23393
|
}
|
|
23254
23394
|
var HOST_CAPABILITY_REGISTRY = {
|
|
@@ -23264,6 +23404,12 @@ function resolveHostCapabilities(hostId, override) {
|
|
|
23264
23404
|
}
|
|
23265
23405
|
return { ...SAFE_DEFAULT, ...row, schema_version: 1 };
|
|
23266
23406
|
}
|
|
23407
|
+
function probeHostCapabilities(hostId) {
|
|
23408
|
+
const base = resolveHostCapabilities(hostId);
|
|
23409
|
+
const flag = process10.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS;
|
|
23410
|
+
const probedAgentTeams = typeof flag === "string" && flag !== "";
|
|
23411
|
+
return { ...base, agent_teams: base.agent_teams || probedAgentTeams };
|
|
23412
|
+
}
|
|
23267
23413
|
|
|
23268
23414
|
// src/scripts/_lib/auto_dispatch.ts
|
|
23269
23415
|
var SIZE_FLOOR = 1;
|
|
@@ -23271,8 +23417,7 @@ function inSession(reason) {
|
|
|
23271
23417
|
return { delegable: false, action: "in-session", mode: null, reason };
|
|
23272
23418
|
}
|
|
23273
23419
|
function classifyTask(signals, activation) {
|
|
23274
|
-
if (
|
|
23275
|
-
if (activation.auto === "off") return inSession("subagents.auto is off");
|
|
23420
|
+
if (activation.halted) return inSession("emergency.orchestration_halt is set");
|
|
23276
23421
|
if (!activation.subagent_spawn) return inSession("host has no subagent_spawn primitive");
|
|
23277
23422
|
if (!(signals.size_estimate > SIZE_FLOOR)) {
|
|
23278
23423
|
return inSession(`task below size floor (${signals.size_estimate} <= ${SIZE_FLOOR})`);
|
|
@@ -23288,13 +23433,197 @@ function classifyTask(signals, activation) {
|
|
|
23288
23433
|
reason = signals.parallelizable ? `declared parallelizable: ${signals.parallelizable}` : `independent slices (${slices})`;
|
|
23289
23434
|
}
|
|
23290
23435
|
if (mode === null) {
|
|
23291
|
-
|
|
23292
|
-
|
|
23436
|
+
return { delegable: false, action: "ask", mode: null, reason: "no delegable signal \u2014 borderline, ask" };
|
|
23437
|
+
}
|
|
23438
|
+
return { delegable: true, action: "dispatch", mode, reason };
|
|
23439
|
+
}
|
|
23440
|
+
var LOOKUP_PATTERNS = [
|
|
23441
|
+
{
|
|
23442
|
+
cls: "definition",
|
|
23443
|
+
primitive: "code-graph-query",
|
|
23444
|
+
re: /\b(where\s+is\s+\S+\s+defined|definition\s+(location|of|site)|find\s+the\s+definition|locate\s+the\s+(class|enum|function|type|interface|symbol)|confirm\w*\s+\S+\s+definition)\b/i
|
|
23445
|
+
},
|
|
23446
|
+
{
|
|
23447
|
+
cls: "references",
|
|
23448
|
+
primitive: "code-graph-query",
|
|
23449
|
+
re: /\b(who\s+(calls|imports|uses|references)|call\s*sites?|import\s+(call\s*)?sites?|reverse\s+references|where\s+is\s+\S+\s+(used|imported|referenced|called)|all\s+(callers|usages|references)\s+of)\b/i
|
|
23450
|
+
},
|
|
23451
|
+
{
|
|
23452
|
+
cls: "string-existence",
|
|
23453
|
+
primitive: "fts-or-capped-grep",
|
|
23454
|
+
re: /\b(does\s+(the\s+)?string\s+.*\bexist|is\s+(the\s+)?string\s+.*\b(present|used)\b|prob\w+\s+(candidate\s+)?strings?|search\s+for\s+the\s+(exact\s+)?string|(grep|check)\s+(for\s+)?(the\s+)?(literal|string)\b|does\s+\S+\s+appear\s+anywhere)/i
|
|
23455
|
+
},
|
|
23456
|
+
{
|
|
23457
|
+
cls: "report-run",
|
|
23458
|
+
primitive: "script-run-rtk",
|
|
23459
|
+
re: /\b(run(ning)?\s+(the\s+)?\S*(report|check|lint\w*|coverage)\b|run(ning)?\s+(check|lint|report)_\w+|regenerate\s+the\s+\S+\s+report)/i
|
|
23460
|
+
}
|
|
23461
|
+
];
|
|
23462
|
+
function classifyLookup(taskText) {
|
|
23463
|
+
for (const p of LOOKUP_PATTERNS) {
|
|
23464
|
+
if (p.re.test(taskText)) {
|
|
23465
|
+
return {
|
|
23466
|
+
lookup_class: p.cls,
|
|
23467
|
+
route: "primitive",
|
|
23468
|
+
primitive: p.primitive,
|
|
23469
|
+
reason: `lookup-class ${p.cls} \u2014 deterministic primitive, no spawn`
|
|
23470
|
+
};
|
|
23293
23471
|
}
|
|
23294
|
-
return inSession("no enumerated delegable signal matched");
|
|
23295
23472
|
}
|
|
23296
|
-
|
|
23297
|
-
|
|
23473
|
+
return {
|
|
23474
|
+
lookup_class: null,
|
|
23475
|
+
route: "escalate",
|
|
23476
|
+
primitive: null,
|
|
23477
|
+
reason: "not lookup-shaped \u2014 regular classification path (never down-guessed)"
|
|
23478
|
+
};
|
|
23479
|
+
}
|
|
23480
|
+
|
|
23481
|
+
// src/scripts/_lib/judgment_ladder.ts
|
|
23482
|
+
var RENAME_RE = /\brename\s+\S+\s+to\s+\S+\b/i;
|
|
23483
|
+
var CODEMOD_RE = /\bcodemod\b/i;
|
|
23484
|
+
var FORMATTER_RUN_RE = /\bauto-?format(?:ting)?\b|\breformat(?:ting)?\b|\brun(?:ning)?\s+prettier\b|\brun(?:ning)?\s+eslint\s*--fix\b|\bapply\s+eslint\s*--fix\b/i;
|
|
23485
|
+
var SEARCH_REPLACE_RE = /\bsearch-and-replace\b|\bfind-and-replace\b|\bbulk\s+rename\b/i;
|
|
23486
|
+
function detectMechanicalTransform(text) {
|
|
23487
|
+
const rename = RENAME_RE.exec(text);
|
|
23488
|
+
if (rename) {
|
|
23489
|
+
return { matched: true, reason: `rename signal ("${rename[0]}") \u2014 deterministic script, no spawn` };
|
|
23490
|
+
}
|
|
23491
|
+
const codemod = CODEMOD_RE.exec(text);
|
|
23492
|
+
if (codemod) {
|
|
23493
|
+
return { matched: true, reason: `codemod signal ("${codemod[0]}") \u2014 deterministic script, no spawn` };
|
|
23494
|
+
}
|
|
23495
|
+
const formatter = FORMATTER_RUN_RE.exec(text);
|
|
23496
|
+
if (formatter) {
|
|
23497
|
+
return { matched: true, reason: `formatter-run signal ("${formatter[0]}") \u2014 deterministic script, no spawn` };
|
|
23498
|
+
}
|
|
23499
|
+
const searchReplace = SEARCH_REPLACE_RE.exec(text);
|
|
23500
|
+
if (searchReplace) {
|
|
23501
|
+
return {
|
|
23502
|
+
matched: true,
|
|
23503
|
+
reason: `search-and-replace/bulk-rename signal ("${searchReplace[0]}") \u2014 deterministic script, no spawn`
|
|
23504
|
+
};
|
|
23505
|
+
}
|
|
23506
|
+
return { matched: false, reason: "no mechanical-transform signal" };
|
|
23507
|
+
}
|
|
23508
|
+
var SINGLE_SLICE_READHEAVY_RE = /\b(?:read|review|summarize|summarise|inventory|audit|investigate|research|inspect|dig into|look into)\b[^.!?\n]{0,80}\b(?:this file|the file|this codebase|the codebase|this transcript|the transcript|this log|the log|this document|the document|this diff|the diff)\b/i;
|
|
23509
|
+
function detectBoundedReadHeavySlice(text) {
|
|
23510
|
+
const m = SINGLE_SLICE_READHEAVY_RE.exec(text);
|
|
23511
|
+
return m ? {
|
|
23512
|
+
matched: true,
|
|
23513
|
+
reason: `single bounded read-heavy slice ("${m[0]}") \u2014 one lite-tier subagent instead of session-context burn`
|
|
23514
|
+
} : { matched: false, reason: "no single-slice read-heavy signal" };
|
|
23515
|
+
}
|
|
23516
|
+
var CROSS_LAYER_RE = /\bcross[- ]layer\b|\bcross[- ]cutting\b|\bback[- ]?end\s+and\s+front[- ]?end\b|\bfront[- ]?end\s+and\s+back[- ]?end\b/i;
|
|
23517
|
+
var REVIEW_WITH_CHALLENGE_RE = /\breview[- ]with[- ]challenge\b|\bchallenge[- ]and[- ]implement\b|\bimplementer\s+and\s+(?:a\s+)?(?:judge|reviewer)\s+(?:working\s+)?together\b|\bsecond\s+opinion\s+while\s+(?:building|implementing)\b/i;
|
|
23518
|
+
var SHARED_TASK_LIST_RE = /\bshared\s+(?:task\s+list|todo\s+list|backlog)\b|\bcoordinat(?:e|ed|ing)\s+(?:with|between|across)\s+(?:multiple\s+|several\s+)?(?:agents|workers|subagents|teammates)\b/i;
|
|
23519
|
+
function detectCommunicationNeed(text) {
|
|
23520
|
+
const crossLayer = CROSS_LAYER_RE.exec(text);
|
|
23521
|
+
if (crossLayer) {
|
|
23522
|
+
return { matched: true, reason: `cross-layer communication signal ("${crossLayer[0]}")` };
|
|
23523
|
+
}
|
|
23524
|
+
const reviewChallenge = REVIEW_WITH_CHALLENGE_RE.exec(text);
|
|
23525
|
+
if (reviewChallenge) {
|
|
23526
|
+
return { matched: true, reason: `review-with-challenge signal ("${reviewChallenge[0]}")` };
|
|
23527
|
+
}
|
|
23528
|
+
const sharedList = SHARED_TASK_LIST_RE.exec(text);
|
|
23529
|
+
if (sharedList) {
|
|
23530
|
+
return { matched: true, reason: `shared-task-list signal ("${sharedList[0]}")` };
|
|
23531
|
+
}
|
|
23532
|
+
return { matched: false, reason: "no communication-need signal" };
|
|
23533
|
+
}
|
|
23534
|
+
var DESIGN_DECISION_RE = /\bdesign\s+decision\b|\barchitectur(?:e|al)\s+decision\b|\b(?:record(?:ing)?|decide|deciding|decision|accept(?:ed|ing)?|approv(?:e|ed|ing|al)|challeng(?:e|ed|ing)|choos(?:e|ing)|reject(?:ed|ing)?)\b[^.!?\n]{0,40}\bADR\b|\bADR\b[^.!?\n]{0,40}\b(?:record(?:ing)?|decide|deciding|decision|accept(?:ed|ing)?|approv(?:e|ed|ing|al)|challeng(?:e|ed|ing)|choos(?:e|ing)|reject(?:ed|ing)?)\b/i;
|
|
23535
|
+
var SECURITY_DOWNGRADE_RE = /\bsecurity\s+downgrade\b|\bdowngrade\s+(?:the\s+)?security\b|\bsecurity\s+exception\b/i;
|
|
23536
|
+
var RELEASE_GATE_ESCALATION_RE = /\bgate\s+escalation\b|\bescalat(?:e|ion)\s+to\s+(?:the\s+)?council\b|\b(?:escalat(?:e|ing|ion)|contest(?:ed|ing)?|dispute|disputing|override|overriding|waiv(?:e|ing)|bypass(?:ed|ing)?|challeng(?:e|ed|ing))\b[^.!?\n]{0,40}\brelease[- ]gate\b|\brelease[- ]gate\b[^.!?\n]{0,40}\b(?:escalat(?:e|ing|ion)|contest(?:ed|ing)?|dispute|disputing|override|overriding|waiv(?:e|ing)|bypass(?:ed|ing)?|challeng(?:e|ed|ing))\b/i;
|
|
23537
|
+
function detectContestedJudgment(text) {
|
|
23538
|
+
const design = DESIGN_DECISION_RE.exec(text);
|
|
23539
|
+
if (design) {
|
|
23540
|
+
return { matched: true, reason: `design-decision signal ("${design[0]}")` };
|
|
23541
|
+
}
|
|
23542
|
+
const security = SECURITY_DOWNGRADE_RE.exec(text);
|
|
23543
|
+
if (security) {
|
|
23544
|
+
return { matched: true, reason: `security-downgrade signal ("${security[0]}")` };
|
|
23545
|
+
}
|
|
23546
|
+
const releaseGate = RELEASE_GATE_ESCALATION_RE.exec(text);
|
|
23547
|
+
if (releaseGate) {
|
|
23548
|
+
return { matched: true, reason: `release-gate-escalation signal ("${releaseGate[0]}")` };
|
|
23549
|
+
}
|
|
23550
|
+
return { matched: false, reason: "no contested-judgment signal" };
|
|
23551
|
+
}
|
|
23552
|
+
function classifyLadder(inp) {
|
|
23553
|
+
if (inp.interactiveApprovalRequired === true) {
|
|
23554
|
+
return {
|
|
23555
|
+
rung: null,
|
|
23556
|
+
verdict: "in-session",
|
|
23557
|
+
reason: "interactive-approval-required \u2014 caller-stated, needs a human decision before anything may run"
|
|
23558
|
+
};
|
|
23559
|
+
}
|
|
23560
|
+
const lookup = classifyLookup(inp.taskText);
|
|
23561
|
+
if (lookup.route === "primitive") {
|
|
23562
|
+
return { rung: 0, verdict: "script", reason: `lookup-class ${lookup.lookup_class} \u2014 ${lookup.reason}` };
|
|
23563
|
+
}
|
|
23564
|
+
const mechanical = detectMechanicalTransform(inp.taskText);
|
|
23565
|
+
if (mechanical.matched) {
|
|
23566
|
+
return { rung: 0, verdict: "script", reason: mechanical.reason };
|
|
23567
|
+
}
|
|
23568
|
+
if (inp.insideSubagentSession === true) {
|
|
23569
|
+
return {
|
|
23570
|
+
rung: null,
|
|
23571
|
+
verdict: "in-session",
|
|
23572
|
+
reason: "recursive-dispatch guard: this classification runs inside a subagent/teammate session \u2014 rungs 1-4 resolve in-session"
|
|
23573
|
+
};
|
|
23574
|
+
}
|
|
23575
|
+
if (inp.activation.halted) {
|
|
23576
|
+
return { rung: null, verdict: "in-session", reason: "emergency.orchestration_halt is set" };
|
|
23577
|
+
}
|
|
23578
|
+
if (!inp.activation.subagent_spawn) {
|
|
23579
|
+
return { rung: null, verdict: "in-session", reason: "host has no subagent_spawn primitive" };
|
|
23580
|
+
}
|
|
23581
|
+
const contested = detectContestedJudgment(inp.taskText);
|
|
23582
|
+
if (contested.matched) {
|
|
23583
|
+
return { rung: 4, verdict: "council", reason: contested.reason };
|
|
23584
|
+
}
|
|
23585
|
+
const communication = detectCommunicationNeed(inp.taskText);
|
|
23586
|
+
if (communication.matched) {
|
|
23587
|
+
if (inp.agentTeams) {
|
|
23588
|
+
return { rung: 3, verdict: "team", reason: communication.reason };
|
|
23589
|
+
}
|
|
23590
|
+
const fallback = classifyTask(inp.signals, inp.activation);
|
|
23591
|
+
if (fallback.action === "dispatch" && fallback.mode !== null) {
|
|
23592
|
+
return {
|
|
23593
|
+
rung: 2,
|
|
23594
|
+
verdict: "subagent",
|
|
23595
|
+
mode: fallback.mode,
|
|
23596
|
+
degraded_from: 3,
|
|
23597
|
+
reason: `${communication.reason} \u2014 no agent_teams host capability, degraded to rung 2 (${fallback.reason})`
|
|
23598
|
+
};
|
|
23599
|
+
}
|
|
23600
|
+
return {
|
|
23601
|
+
rung: null,
|
|
23602
|
+
verdict: fallback.action === "ask" ? "ask" : "in-session",
|
|
23603
|
+
degraded_from: 3,
|
|
23604
|
+
reason: `${communication.reason} \u2014 no agent_teams host capability, degraded below rung 2 (${fallback.reason})`
|
|
23605
|
+
};
|
|
23606
|
+
}
|
|
23607
|
+
const classification = classifyTask(inp.signals, inp.activation);
|
|
23608
|
+
if (classification.action === "dispatch" && classification.mode !== null) {
|
|
23609
|
+
return { rung: 2, verdict: "subagent", mode: classification.mode, reason: classification.reason };
|
|
23610
|
+
}
|
|
23611
|
+
if (inp.signals.size_estimate <= SIZE_FLOOR) {
|
|
23612
|
+
return {
|
|
23613
|
+
rung: null,
|
|
23614
|
+
verdict: classification.action === "ask" ? "ask" : "in-session",
|
|
23615
|
+
reason: classification.reason
|
|
23616
|
+
};
|
|
23617
|
+
}
|
|
23618
|
+
const single = detectBoundedReadHeavySlice(inp.taskText);
|
|
23619
|
+
if (single.matched) {
|
|
23620
|
+
return { rung: 1, verdict: "subagent", mode: null, reason: single.reason };
|
|
23621
|
+
}
|
|
23622
|
+
return {
|
|
23623
|
+
rung: null,
|
|
23624
|
+
verdict: classification.action === "ask" ? "ask" : "in-session",
|
|
23625
|
+
reason: classification.reason
|
|
23626
|
+
};
|
|
23298
23627
|
}
|
|
23299
23628
|
|
|
23300
23629
|
// src/scripts/_lib/subagent_routing.ts
|
|
@@ -23403,16 +23732,16 @@ function extractTaskSignals(text) {
|
|
|
23403
23732
|
}
|
|
23404
23733
|
function resolveActivation(workspace_root, hostId) {
|
|
23405
23734
|
const settings = load_agent_settings({ cwd: workspace_root });
|
|
23735
|
+
const emergency = settings["emergency"] ?? {};
|
|
23736
|
+
const halted = emergency["orchestration_halt"] === true;
|
|
23737
|
+
const host_manifest = probeHostCapabilities(hostId);
|
|
23406
23738
|
const sub = settings["subagents"] ?? {};
|
|
23407
|
-
const enabled4 = sub["enabled"] !== false;
|
|
23408
|
-
const rawAuto = sub["auto"];
|
|
23409
|
-
const auto = rawAuto === "on" || rawAuto === "off" ? rawAuto : "ask";
|
|
23410
|
-
const host_manifest = resolveHostCapabilities(hostId, sub["host_capabilities"]);
|
|
23411
23739
|
const downshift = sub["downshift"] !== false;
|
|
23412
23740
|
return {
|
|
23413
|
-
activation: {
|
|
23741
|
+
activation: { halted, subagent_spawn: host_manifest.subagent_spawn },
|
|
23414
23742
|
downshift,
|
|
23415
|
-
separate_quota_pool: host_manifest.separate_quota_pool
|
|
23743
|
+
separate_quota_pool: host_manifest.separate_quota_pool,
|
|
23744
|
+
agentTeams: host_manifest.agent_teams
|
|
23416
23745
|
};
|
|
23417
23746
|
}
|
|
23418
23747
|
function recommendSliceTier(downshift, separate_quota_pool) {
|
|
@@ -23426,23 +23755,32 @@ function recommendSliceTier(downshift, separate_quota_pool) {
|
|
|
23426
23755
|
});
|
|
23427
23756
|
return decision.tier;
|
|
23428
23757
|
}
|
|
23429
|
-
function buildNudgeLine(classification, sliceCount, tier) {
|
|
23758
|
+
function buildNudgeLine(rung, classification, sliceCount, tier) {
|
|
23430
23759
|
const unit = sliceCount === 1 ? "slice" : "slices";
|
|
23431
|
-
|
|
23760
|
+
const rungLabel = rung === null ? "rung-?" : `rung-${rung}`;
|
|
23761
|
+
const modeLabel = classification.mode ?? "single-slice";
|
|
23762
|
+
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>`;
|
|
23432
23763
|
}
|
|
23433
23764
|
function classifyPrompt(prompt, workspace_root, hostId) {
|
|
23434
23765
|
try {
|
|
23435
23766
|
const { signals, sliceCountForLine } = extractTaskSignals(prompt);
|
|
23436
|
-
const { activation, downshift, separate_quota_pool } = resolveActivation(
|
|
23767
|
+
const { activation, downshift, separate_quota_pool, agentTeams } = resolveActivation(
|
|
23437
23768
|
workspace_root,
|
|
23438
23769
|
hostId
|
|
23439
23770
|
);
|
|
23440
|
-
const
|
|
23441
|
-
if (
|
|
23771
|
+
const ladder = classifyLadder({ taskText: prompt, signals, activation, agentTeams });
|
|
23772
|
+
if (ladder.verdict !== "subagent") {
|
|
23442
23773
|
return null;
|
|
23443
23774
|
}
|
|
23444
23775
|
const tier = recommendSliceTier(downshift, separate_quota_pool);
|
|
23445
|
-
|
|
23776
|
+
const sliceCount = ladder.rung === 1 ? 1 : sliceCountForLine;
|
|
23777
|
+
const classification = {
|
|
23778
|
+
delegable: true,
|
|
23779
|
+
action: "dispatch",
|
|
23780
|
+
mode: ladder.mode ?? null,
|
|
23781
|
+
reason: ladder.reason
|
|
23782
|
+
};
|
|
23783
|
+
return { classification, sliceCount, tier, rung: ladder.rung };
|
|
23446
23784
|
} catch {
|
|
23447
23785
|
return null;
|
|
23448
23786
|
}
|
|
@@ -23495,8 +23833,8 @@ function main39() {
|
|
|
23495
23833
|
process.stdout.write(
|
|
23496
23834
|
`${JSON.stringify({
|
|
23497
23835
|
decision: "warn",
|
|
23498
|
-
reason: `delegation-nudge:
|
|
23499
|
-
additional_context: buildNudgeLine(result.classification, result.sliceCount, result.tier)
|
|
23836
|
+
reason: `delegation-nudge: rung-${result.rung} verdict (${result.sliceCount} slices, ${result.tier} tier)`,
|
|
23837
|
+
additional_context: buildNudgeLine(result.rung, result.classification, result.sliceCount, result.tier)
|
|
23500
23838
|
})}
|
|
23501
23839
|
`
|
|
23502
23840
|
);
|