@codedrifters/configulator 0.0.289 → 0.0.290
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/lib/index.d.mts +146 -2
- package/lib/index.d.ts +147 -3
- package/lib/index.js +254 -15
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +252 -15
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
package/lib/index.mjs
CHANGED
|
@@ -11761,6 +11761,14 @@ var DEFAULT_SOURCES_THRESHOLDS = {
|
|
|
11761
11761
|
smallMax: 2,
|
|
11762
11762
|
mediumMax: 5
|
|
11763
11763
|
};
|
|
11764
|
+
var DEFAULT_BUNDLE_OVERRIDES = {
|
|
11765
|
+
"req:write": {
|
|
11766
|
+
acceptanceCriteria: { smallMax: 3, mediumMax: 20 }
|
|
11767
|
+
},
|
|
11768
|
+
"bcm:scaffold": {
|
|
11769
|
+
acceptanceCriteria: { smallMax: 3, mediumMax: 12 }
|
|
11770
|
+
}
|
|
11771
|
+
};
|
|
11764
11772
|
var DEFAULT_DECOMPOSITION_TEMPLATE = [
|
|
11765
11773
|
"## Scope gate: issue is too large to dispatch",
|
|
11766
11774
|
"",
|
|
@@ -11800,22 +11808,58 @@ function resolveScopeGate(config) {
|
|
|
11800
11808
|
DEFAULT_SOURCES_THRESHOLDS,
|
|
11801
11809
|
"sources"
|
|
11802
11810
|
);
|
|
11811
|
+
const bundleOverrides = resolveBundleOverrides(
|
|
11812
|
+
config?.bundleOverrides,
|
|
11813
|
+
DEFAULT_BUNDLE_OVERRIDES
|
|
11814
|
+
);
|
|
11803
11815
|
return {
|
|
11804
11816
|
enabled: config?.enabled ?? true,
|
|
11805
11817
|
acceptanceCriteria: ac,
|
|
11806
11818
|
sources,
|
|
11807
11819
|
autoFile: config?.autoFile ?? false,
|
|
11808
|
-
decompositionTemplate: config?.decompositionTemplate ?? DEFAULT_DECOMPOSITION_TEMPLATE
|
|
11820
|
+
decompositionTemplate: config?.decompositionTemplate ?? DEFAULT_DECOMPOSITION_TEMPLATE,
|
|
11821
|
+
bundleOverrides
|
|
11822
|
+
};
|
|
11823
|
+
}
|
|
11824
|
+
function resolveOverrideForLabels(gate, labels) {
|
|
11825
|
+
const overrideKeys = Object.keys(gate.bundleOverrides);
|
|
11826
|
+
if (overrideKeys.length === 0 || labels.length === 0) {
|
|
11827
|
+
return {
|
|
11828
|
+
acceptanceCriteria: gate.acceptanceCriteria,
|
|
11829
|
+
sources: gate.sources
|
|
11830
|
+
};
|
|
11831
|
+
}
|
|
11832
|
+
const sortedLabels = [...labels].sort((a, b) => a.localeCompare(b));
|
|
11833
|
+
const matchedLabel = sortedLabels.find(
|
|
11834
|
+
(label) => Object.prototype.hasOwnProperty.call(gate.bundleOverrides, label)
|
|
11835
|
+
);
|
|
11836
|
+
if (matchedLabel === void 0) {
|
|
11837
|
+
return {
|
|
11838
|
+
acceptanceCriteria: gate.acceptanceCriteria,
|
|
11839
|
+
sources: gate.sources
|
|
11840
|
+
};
|
|
11841
|
+
}
|
|
11842
|
+
const override = gate.bundleOverrides[matchedLabel];
|
|
11843
|
+
return {
|
|
11844
|
+
acceptanceCriteria: override.acceptanceCriteria ?? gate.acceptanceCriteria,
|
|
11845
|
+
sources: override.sources ?? gate.sources,
|
|
11846
|
+
matchedLabel
|
|
11809
11847
|
};
|
|
11810
11848
|
}
|
|
11811
11849
|
function validateScopeGateConfig(config) {
|
|
11812
11850
|
return resolveScopeGate(config);
|
|
11813
11851
|
}
|
|
11814
|
-
function classifyIssueScope(body, gate) {
|
|
11852
|
+
function classifyIssueScope(body, gate, labels = []) {
|
|
11815
11853
|
const acCount = countAcceptanceCriteria(body);
|
|
11816
11854
|
const sourcesCount = countSources(body);
|
|
11817
|
-
const
|
|
11818
|
-
|
|
11855
|
+
const effective = resolveOverrideForLabels(gate, labels);
|
|
11856
|
+
const scope = resolveScopeClass(acCount, sourcesCount, effective);
|
|
11857
|
+
return {
|
|
11858
|
+
scope,
|
|
11859
|
+
acCount,
|
|
11860
|
+
sourcesCount,
|
|
11861
|
+
matchedLabel: effective.matchedLabel
|
|
11862
|
+
};
|
|
11819
11863
|
}
|
|
11820
11864
|
function renderScopeGateSection(gate) {
|
|
11821
11865
|
const { acceptanceCriteria: ac, sources } = gate;
|
|
@@ -11891,6 +11935,38 @@ function renderScopeGateSection(gate) {
|
|
|
11891
11935
|
" is in place."
|
|
11892
11936
|
);
|
|
11893
11937
|
}
|
|
11938
|
+
const overrideEntries = Object.entries(gate.bundleOverrides);
|
|
11939
|
+
if (overrideEntries.length > 0) {
|
|
11940
|
+
lines.push(
|
|
11941
|
+
"",
|
|
11942
|
+
"### Per-phase-label thresholds",
|
|
11943
|
+
"",
|
|
11944
|
+
"Issues whose `type:*` or phase label matches an entry below are",
|
|
11945
|
+
"classified against the override's thresholds instead of the",
|
|
11946
|
+
"global `acceptance-criteria` / `sources` defaults. This",
|
|
11947
|
+
"accommodates **content-spec workflows** \u2014 issues whose AC list",
|
|
11948
|
+
"is the per-section content checklist for one cohesive document,",
|
|
11949
|
+
"not a phase-completion checklist that can be decomposed.",
|
|
11950
|
+
"",
|
|
11951
|
+
"| Phase label | AC `mediumMax` | Sources `mediumMax` |",
|
|
11952
|
+
"|-------------|----------------|---------------------|"
|
|
11953
|
+
);
|
|
11954
|
+
const sortedKeys = overrideEntries.map(([k]) => k).sort();
|
|
11955
|
+
for (const label of sortedKeys) {
|
|
11956
|
+
const override = gate.bundleOverrides[label];
|
|
11957
|
+
const acMax = override.acceptanceCriteria?.mediumMax;
|
|
11958
|
+
const sourcesMax = override.sources?.mediumMax;
|
|
11959
|
+
const acCell = acMax === void 0 ? "_(global)_" : `${acMax}`;
|
|
11960
|
+
const sourcesCell = sourcesMax === void 0 ? "_(global)_" : `${sourcesMax}`;
|
|
11961
|
+
lines.push(`| \`${label}\` | ${acCell} | ${sourcesCell} |`);
|
|
11962
|
+
}
|
|
11963
|
+
lines.push(
|
|
11964
|
+
"",
|
|
11965
|
+
"When an issue carries multiple labels that each match an entry",
|
|
11966
|
+
"in this table, the orchestrator picks the **first match in",
|
|
11967
|
+
"alphabetical order on the label name** \u2014 first-wins, deterministic."
|
|
11968
|
+
);
|
|
11969
|
+
}
|
|
11894
11970
|
lines.push(
|
|
11895
11971
|
"",
|
|
11896
11972
|
"### Decomposition-proposal template",
|
|
@@ -11907,12 +11983,21 @@ function renderScopeGateSection(gate) {
|
|
|
11907
11983
|
}
|
|
11908
11984
|
function renderScopeGateShellHelpers(gate) {
|
|
11909
11985
|
const { acceptanceCriteria: ac, sources } = gate;
|
|
11910
|
-
|
|
11986
|
+
const lines = [
|
|
11911
11987
|
"# Classify an issue body against the scope-gate thresholds.",
|
|
11912
11988
|
"# Reads the issue body from stdin. Echoes one of 'small',",
|
|
11913
11989
|
"# 'medium', or 'large' on stdout. Writes the observed counts to",
|
|
11914
11990
|
"# stderr as `ac=<n> sources=<n>` so the caller can embed them in",
|
|
11915
11991
|
"# the decomposition-proposal comment.",
|
|
11992
|
+
"#",
|
|
11993
|
+
"# Effective per-issue thresholds are read from the four",
|
|
11994
|
+
"# `_EFFECTIVE_*` shell variables. The caller is expected to set",
|
|
11995
|
+
"# them via `bundle_override_for()` before invoking scope_of();",
|
|
11996
|
+
"# defaults preserve the global thresholds.",
|
|
11997
|
+
`_EFFECTIVE_AC_SMALL_MAX="\${_EFFECTIVE_AC_SMALL_MAX:-${ac.smallMax}}"`,
|
|
11998
|
+
`_EFFECTIVE_AC_MEDIUM_MAX="\${_EFFECTIVE_AC_MEDIUM_MAX:-${ac.mediumMax}}"`,
|
|
11999
|
+
`_EFFECTIVE_SOURCES_SMALL_MAX="\${_EFFECTIVE_SOURCES_SMALL_MAX:-${sources.smallMax}}"`,
|
|
12000
|
+
`_EFFECTIVE_SOURCES_MEDIUM_MAX="\${_EFFECTIVE_SOURCES_MEDIUM_MAX:-${sources.mediumMax}}"`,
|
|
11916
12001
|
"scope_of() {",
|
|
11917
12002
|
" local body",
|
|
11918
12003
|
" body=$(cat)",
|
|
@@ -11941,15 +12026,79 @@ function renderScopeGateShellHelpers(gate) {
|
|
|
11941
12026
|
" END { print count }",
|
|
11942
12027
|
" ')",
|
|
11943
12028
|
` printf 'ac=%s sources=%s\\n' "$ac_count" "$sources_count" >&2`,
|
|
11944
|
-
|
|
12029
|
+
' if [ "$ac_count" -le "$_EFFECTIVE_AC_SMALL_MAX" ] && [ "$sources_count" -le "$_EFFECTIVE_SOURCES_SMALL_MAX" ]; then',
|
|
11945
12030
|
" echo small",
|
|
11946
|
-
|
|
12031
|
+
' elif [ "$ac_count" -le "$_EFFECTIVE_AC_MEDIUM_MAX" ] && [ "$sources_count" -le "$_EFFECTIVE_SOURCES_MEDIUM_MAX" ]; then',
|
|
11947
12032
|
" echo medium",
|
|
11948
12033
|
" else",
|
|
11949
12034
|
" echo large",
|
|
11950
12035
|
" fi",
|
|
12036
|
+
"}",
|
|
12037
|
+
"",
|
|
12038
|
+
"# Resolve per-phase-label threshold overrides. Reads a newline-",
|
|
12039
|
+
"# separated list of label names on stdin and echoes effective",
|
|
12040
|
+
"# threshold variable assignments (one per line) on stdout. The",
|
|
12041
|
+
"# caller `eval`s the output to set the four `_EFFECTIVE_*`",
|
|
12042
|
+
"# variables before calling `scope_of()`. Also echoes",
|
|
12043
|
+
"# `MATCHED_LABEL=<label>` (or `MATCHED_LABEL=`) so the caller can",
|
|
12044
|
+
"# report which override fired.",
|
|
12045
|
+
"#",
|
|
12046
|
+
"# Tie-breaking: when more than one label matches an override key,",
|
|
12047
|
+
"# the alphabetical first-wins rule applies \u2014 the same rule the",
|
|
12048
|
+
"# TypeScript classifier uses.",
|
|
12049
|
+
"bundle_override_for() {",
|
|
12050
|
+
` local default_ac_small=${ac.smallMax}`,
|
|
12051
|
+
` local default_ac_medium=${ac.mediumMax}`,
|
|
12052
|
+
` local default_sources_small=${sources.smallMax}`,
|
|
12053
|
+
` local default_sources_medium=${sources.mediumMax}`,
|
|
12054
|
+
" # Sort labels alphabetically so the first match is deterministic.",
|
|
12055
|
+
" local sorted_labels",
|
|
12056
|
+
" sorted_labels=$(LC_ALL=C sort)",
|
|
12057
|
+
" local matched_label=''",
|
|
12058
|
+
" local ac_small=$default_ac_small",
|
|
12059
|
+
" local ac_medium=$default_ac_medium",
|
|
12060
|
+
" local sources_small=$default_sources_small",
|
|
12061
|
+
" local sources_medium=$default_sources_medium",
|
|
12062
|
+
" while IFS= read -r label; do",
|
|
12063
|
+
' [ -z "$label" ] && continue',
|
|
12064
|
+
` case "$label" in`
|
|
12065
|
+
];
|
|
12066
|
+
const sortedKeys = Object.keys(gate.bundleOverrides).sort();
|
|
12067
|
+
if (sortedKeys.length === 0) {
|
|
12068
|
+
lines.push(" *) ;;");
|
|
12069
|
+
} else {
|
|
12070
|
+
for (const label of sortedKeys) {
|
|
12071
|
+
const override = gate.bundleOverrides[label];
|
|
12072
|
+
const acThresholds = override.acceptanceCriteria;
|
|
12073
|
+
const sourcesThresholds = override.sources;
|
|
12074
|
+
const branchLines = [` '${label}')`];
|
|
12075
|
+
if (acThresholds !== void 0) {
|
|
12076
|
+
branchLines.push(` ac_small=${acThresholds.smallMax}`);
|
|
12077
|
+
branchLines.push(` ac_medium=${acThresholds.mediumMax}`);
|
|
12078
|
+
}
|
|
12079
|
+
if (sourcesThresholds !== void 0) {
|
|
12080
|
+
branchLines.push(` sources_small=${sourcesThresholds.smallMax}`);
|
|
12081
|
+
branchLines.push(
|
|
12082
|
+
` sources_medium=${sourcesThresholds.mediumMax}`
|
|
12083
|
+
);
|
|
12084
|
+
}
|
|
12085
|
+
branchLines.push(` matched_label='${label}'`);
|
|
12086
|
+
branchLines.push(" break");
|
|
12087
|
+
branchLines.push(" ;;");
|
|
12088
|
+
lines.push(...branchLines);
|
|
12089
|
+
}
|
|
12090
|
+
}
|
|
12091
|
+
lines.push(
|
|
12092
|
+
" esac",
|
|
12093
|
+
` done <<<"$sorted_labels"`,
|
|
12094
|
+
` printf 'MATCHED_LABEL=%s\\n' "$matched_label"`,
|
|
12095
|
+
` printf '_EFFECTIVE_AC_SMALL_MAX=%s\\n' "$ac_small"`,
|
|
12096
|
+
` printf '_EFFECTIVE_AC_MEDIUM_MAX=%s\\n' "$ac_medium"`,
|
|
12097
|
+
` printf '_EFFECTIVE_SOURCES_SMALL_MAX=%s\\n' "$sources_small"`,
|
|
12098
|
+
` printf '_EFFECTIVE_SOURCES_MEDIUM_MAX=%s\\n' "$sources_medium"`,
|
|
11951
12099
|
"}"
|
|
11952
|
-
|
|
12100
|
+
);
|
|
12101
|
+
return lines.join("\n");
|
|
11953
12102
|
}
|
|
11954
12103
|
function resolveThresholds(supplied, defaults, field) {
|
|
11955
12104
|
const merged = {
|
|
@@ -11959,6 +12108,42 @@ function resolveThresholds(supplied, defaults, field) {
|
|
|
11959
12108
|
assertValidThresholds(merged, field);
|
|
11960
12109
|
return merged;
|
|
11961
12110
|
}
|
|
12111
|
+
function resolveBundleOverrides(supplied, defaults) {
|
|
12112
|
+
const out = {};
|
|
12113
|
+
for (const [label, override] of Object.entries(defaults)) {
|
|
12114
|
+
out[label] = override;
|
|
12115
|
+
}
|
|
12116
|
+
if (supplied !== void 0) {
|
|
12117
|
+
for (const label of Object.keys(supplied)) {
|
|
12118
|
+
const value = supplied[label];
|
|
12119
|
+
if (value === void 0) {
|
|
12120
|
+
delete out[label];
|
|
12121
|
+
continue;
|
|
12122
|
+
}
|
|
12123
|
+
const resolved = {};
|
|
12124
|
+
if (value.acceptanceCriteria !== void 0) {
|
|
12125
|
+
resolved.acceptanceCriteria = resolveThresholds(
|
|
12126
|
+
value.acceptanceCriteria,
|
|
12127
|
+
DEFAULT_AC_THRESHOLDS,
|
|
12128
|
+
"acceptanceCriteria"
|
|
12129
|
+
);
|
|
12130
|
+
}
|
|
12131
|
+
if (value.sources !== void 0) {
|
|
12132
|
+
resolved.sources = resolveThresholds(
|
|
12133
|
+
value.sources,
|
|
12134
|
+
DEFAULT_SOURCES_THRESHOLDS,
|
|
12135
|
+
"sources"
|
|
12136
|
+
);
|
|
12137
|
+
}
|
|
12138
|
+
if (resolved.acceptanceCriteria === void 0 && resolved.sources === void 0) {
|
|
12139
|
+
delete out[label];
|
|
12140
|
+
continue;
|
|
12141
|
+
}
|
|
12142
|
+
out[label] = resolved;
|
|
12143
|
+
}
|
|
12144
|
+
}
|
|
12145
|
+
return out;
|
|
12146
|
+
}
|
|
11962
12147
|
function assertValidThresholds(thresholds, field) {
|
|
11963
12148
|
const { smallMax, mediumMax } = thresholds;
|
|
11964
12149
|
for (const [key, value] of [
|
|
@@ -11982,8 +12167,8 @@ function assertValidThresholds(thresholds, field) {
|
|
|
11982
12167
|
);
|
|
11983
12168
|
}
|
|
11984
12169
|
}
|
|
11985
|
-
function resolveScopeClass(acCount, sourcesCount,
|
|
11986
|
-
const { acceptanceCriteria: ac, sources } =
|
|
12170
|
+
function resolveScopeClass(acCount, sourcesCount, thresholds) {
|
|
12171
|
+
const { acceptanceCriteria: ac, sources } = thresholds;
|
|
11987
12172
|
if (acCount <= ac.smallMax && sourcesCount <= sources.smallMax) {
|
|
11988
12173
|
return "small";
|
|
11989
12174
|
}
|
|
@@ -12563,7 +12748,9 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
|
|
|
12563
12748
|
"STALE_BLOCKED_HOURS=168",
|
|
12564
12749
|
`SCOPE_GATE_ENABLED=${scopeGate.enabled ? "1" : "0"}`,
|
|
12565
12750
|
`SCOPE_GATE_AUTO_FILE=${scopeGate.autoFile ? "1" : "0"}`,
|
|
12751
|
+
`SCOPE_AC_SMALL_MAX=${scopeGate.acceptanceCriteria.smallMax}`,
|
|
12566
12752
|
`SCOPE_AC_MEDIUM_MAX=${scopeGate.acceptanceCriteria.mediumMax}`,
|
|
12753
|
+
`SCOPE_SOURCES_SMALL_MAX=${scopeGate.sources.smallMax}`,
|
|
12567
12754
|
`SCOPE_SOURCES_MEDIUM_MAX=${scopeGate.sources.mediumMax}`,
|
|
12568
12755
|
`RUN_RATIO_ENABLED=${runRatio.enabled ? "1" : "0"}`,
|
|
12569
12756
|
`RUN_RATIO_DISPATCH_PER_HOUSEKEEPING=${runRatio.ratio}`,
|
|
@@ -12917,12 +13104,45 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
|
|
|
12917
13104
|
' echo "SCOPE #${issue_num} disabled"',
|
|
12918
13105
|
" return 0",
|
|
12919
13106
|
" fi",
|
|
13107
|
+
" # Fetch the body and labels in a single API call so we resolve",
|
|
13108
|
+
" # any per-phase-label override against the issue's actual labels.",
|
|
13109
|
+
" local issue_json",
|
|
13110
|
+
' issue_json=$(gh issue view "$issue_num" --json body,labels 2>/dev/null || echo "")',
|
|
13111
|
+
' if [[ -z "$issue_json" ]]; then',
|
|
13112
|
+
' echo "SCOPE #${issue_num} unknown \u2014 could not read issue body"',
|
|
13113
|
+
" return 1",
|
|
13114
|
+
" fi",
|
|
12920
13115
|
" local body",
|
|
12921
|
-
` body=$(
|
|
13116
|
+
` body=$(printf '%s' "$issue_json" | jq -r '.body // ""')`,
|
|
12922
13117
|
' if [[ -z "$body" ]]; then',
|
|
12923
13118
|
' echo "SCOPE #${issue_num} unknown \u2014 could not read issue body"',
|
|
12924
13119
|
" return 1",
|
|
12925
13120
|
" fi",
|
|
13121
|
+
" local labels",
|
|
13122
|
+
` labels=$(printf '%s' "$issue_json" | jq -r '.labels[]?.name // empty')`,
|
|
13123
|
+
" # Resolve the effective thresholds. `bundle_override_for` reads",
|
|
13124
|
+
" # labels on stdin and emits `KEY=VALUE` assignments (one per line)",
|
|
13125
|
+
" # for the four `_EFFECTIVE_*` variables plus `MATCHED_LABEL`.",
|
|
13126
|
+
" local override_output",
|
|
13127
|
+
` override_output=$(printf '%s\\n' "$labels" | bundle_override_for)`,
|
|
13128
|
+
" local matched_label=''",
|
|
13129
|
+
" local _EFFECTIVE_AC_SMALL_MAX=$SCOPE_AC_SMALL_MAX",
|
|
13130
|
+
" local _EFFECTIVE_AC_MEDIUM_MAX=$SCOPE_AC_MEDIUM_MAX",
|
|
13131
|
+
" local _EFFECTIVE_SOURCES_SMALL_MAX=$SCOPE_SOURCES_SMALL_MAX",
|
|
13132
|
+
" local _EFFECTIVE_SOURCES_MEDIUM_MAX=$SCOPE_SOURCES_MEDIUM_MAX",
|
|
13133
|
+
" while IFS= read -r assignment; do",
|
|
13134
|
+
' [ -z "$assignment" ] && continue',
|
|
13135
|
+
' case "$assignment" in',
|
|
13136
|
+
" MATCHED_LABEL=*) matched_label=${assignment#MATCHED_LABEL=} ;;",
|
|
13137
|
+
" _EFFECTIVE_AC_SMALL_MAX=*) _EFFECTIVE_AC_SMALL_MAX=${assignment#_EFFECTIVE_AC_SMALL_MAX=} ;;",
|
|
13138
|
+
" _EFFECTIVE_AC_MEDIUM_MAX=*) _EFFECTIVE_AC_MEDIUM_MAX=${assignment#_EFFECTIVE_AC_MEDIUM_MAX=} ;;",
|
|
13139
|
+
" _EFFECTIVE_SOURCES_SMALL_MAX=*) _EFFECTIVE_SOURCES_SMALL_MAX=${assignment#_EFFECTIVE_SOURCES_SMALL_MAX=} ;;",
|
|
13140
|
+
" _EFFECTIVE_SOURCES_MEDIUM_MAX=*) _EFFECTIVE_SOURCES_MEDIUM_MAX=${assignment#_EFFECTIVE_SOURCES_MEDIUM_MAX=} ;;",
|
|
13141
|
+
" esac",
|
|
13142
|
+
' done <<<"$override_output"',
|
|
13143
|
+
" # Export the effective thresholds so scope_of() picks them up.",
|
|
13144
|
+
" export _EFFECTIVE_AC_SMALL_MAX _EFFECTIVE_AC_MEDIUM_MAX",
|
|
13145
|
+
" export _EFFECTIVE_SOURCES_SMALL_MAX _EFFECTIVE_SOURCES_MEDIUM_MAX",
|
|
12926
13146
|
" local scope counts",
|
|
12927
13147
|
" # scope_of writes counts to stderr (ac=N sources=N); capture both.",
|
|
12928
13148
|
` scope=$(printf '%s' "$body" | scope_of 2> >(read -r counts; echo "$counts" >&2))`,
|
|
@@ -12936,9 +13156,17 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
|
|
|
12936
13156
|
` sources_count=$(echo "$stderr_capture" | grep -oE 'sources=[0-9]+' | head -1 | cut -d= -f2)`,
|
|
12937
13157
|
" ac_count=${ac_count:-0}",
|
|
12938
13158
|
" sources_count=${sources_count:-0}",
|
|
12939
|
-
|
|
12940
|
-
|
|
12941
|
-
'
|
|
13159
|
+
' if [ -n "$matched_label" ]; then',
|
|
13160
|
+
" printf 'SCOPE #%s %s ac=%s sources=%s ac_limit=%s sources_limit=%s auto_file=%s matched_label=%s\\n' \\",
|
|
13161
|
+
' "$issue_num" "$scope" "$ac_count" "$sources_count" \\',
|
|
13162
|
+
' "$_EFFECTIVE_AC_MEDIUM_MAX" "$_EFFECTIVE_SOURCES_MEDIUM_MAX" \\',
|
|
13163
|
+
' "$SCOPE_GATE_AUTO_FILE" "$matched_label"',
|
|
13164
|
+
" else",
|
|
13165
|
+
" printf 'SCOPE #%s %s ac=%s sources=%s ac_limit=%s sources_limit=%s auto_file=%s\\n' \\",
|
|
13166
|
+
' "$issue_num" "$scope" "$ac_count" "$sources_count" \\',
|
|
13167
|
+
' "$_EFFECTIVE_AC_MEDIUM_MAX" "$_EFFECTIVE_SOURCES_MEDIUM_MAX" \\',
|
|
13168
|
+
' "$SCOPE_GATE_AUTO_FILE"',
|
|
13169
|
+
" fi",
|
|
12942
13170
|
"}",
|
|
12943
13171
|
"",
|
|
12944
13172
|
"cmd_tick() {",
|
|
@@ -13143,9 +13371,16 @@ var orchestratorSubAgent = {
|
|
|
13143
13371
|
"The output is one line of the form:",
|
|
13144
13372
|
"",
|
|
13145
13373
|
"```",
|
|
13146
|
-
"SCOPE #<n> <small|medium|large> ac=<n> sources=<n> ac_limit=<n> sources_limit=<n> auto_file=<0|1>",
|
|
13374
|
+
"SCOPE #<n> <small|medium|large> ac=<n> sources=<n> ac_limit=<n> sources_limit=<n> auto_file=<0|1> [matched_label=<label>]",
|
|
13147
13375
|
"```",
|
|
13148
13376
|
"",
|
|
13377
|
+
"When `matched_label=<label>` is present, the scope gate applied a",
|
|
13378
|
+
"per-phase-label override (e.g. `req:write` raises the AC ceiling to",
|
|
13379
|
+
"20 for content-spec workflows whose AC list is the per-section",
|
|
13380
|
+
"checklist for one document). The `ac_limit` / `sources_limit`",
|
|
13381
|
+
"values reflect the override; the global thresholds are documented",
|
|
13382
|
+
"in the **Scope gate** section in `CLAUDE.md`.",
|
|
13383
|
+
"",
|
|
13149
13384
|
"If the scope is `small` or `medium`, continue \u2014 the issue is",
|
|
13150
13385
|
"dispatchable. Record the first `PICK` line as the next work item",
|
|
13151
13386
|
"and proceed to Phase G:",
|
|
@@ -32438,6 +32673,7 @@ export {
|
|
|
32438
32673
|
DEFAULT_API_EXTRACTOR_REPORT_FILENAME,
|
|
32439
32674
|
DEFAULT_API_EXTRACTOR_REPORT_FOLDER,
|
|
32440
32675
|
DEFAULT_AUDIT_REPORT_DIR,
|
|
32676
|
+
DEFAULT_BUNDLE_OVERRIDES,
|
|
32441
32677
|
DEFAULT_DECOMPOSITION_TEMPLATE,
|
|
32442
32678
|
DEFAULT_DISPATCH_MODEL,
|
|
32443
32679
|
DEFAULT_DISPATCH_TO_HOUSEKEEPING_RATIO,
|
|
@@ -32623,6 +32859,7 @@ export {
|
|
|
32623
32859
|
resolveModelAlias,
|
|
32624
32860
|
resolveOrchestratorAssets,
|
|
32625
32861
|
resolveOutdirFromPackageName,
|
|
32862
|
+
resolveOverrideForLabels,
|
|
32626
32863
|
resolveProgressFiles,
|
|
32627
32864
|
resolveRunRatio,
|
|
32628
32865
|
resolveScheduledTasks,
|