@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.js
CHANGED
|
@@ -205,6 +205,7 @@ __export(index_exports, {
|
|
|
205
205
|
DEFAULT_API_EXTRACTOR_REPORT_FILENAME: () => DEFAULT_API_EXTRACTOR_REPORT_FILENAME,
|
|
206
206
|
DEFAULT_API_EXTRACTOR_REPORT_FOLDER: () => DEFAULT_API_EXTRACTOR_REPORT_FOLDER,
|
|
207
207
|
DEFAULT_AUDIT_REPORT_DIR: () => DEFAULT_AUDIT_REPORT_DIR,
|
|
208
|
+
DEFAULT_BUNDLE_OVERRIDES: () => DEFAULT_BUNDLE_OVERRIDES,
|
|
208
209
|
DEFAULT_DECOMPOSITION_TEMPLATE: () => DEFAULT_DECOMPOSITION_TEMPLATE,
|
|
209
210
|
DEFAULT_DISPATCH_MODEL: () => DEFAULT_DISPATCH_MODEL,
|
|
210
211
|
DEFAULT_DISPATCH_TO_HOUSEKEEPING_RATIO: () => DEFAULT_DISPATCH_TO_HOUSEKEEPING_RATIO,
|
|
@@ -390,6 +391,7 @@ __export(index_exports, {
|
|
|
390
391
|
resolveModelAlias: () => resolveModelAlias,
|
|
391
392
|
resolveOrchestratorAssets: () => resolveOrchestratorAssets,
|
|
392
393
|
resolveOutdirFromPackageName: () => resolveOutdirFromPackageName,
|
|
394
|
+
resolveOverrideForLabels: () => resolveOverrideForLabels,
|
|
393
395
|
resolveProgressFiles: () => resolveProgressFiles,
|
|
394
396
|
resolveRunRatio: () => resolveRunRatio,
|
|
395
397
|
resolveScheduledTasks: () => resolveScheduledTasks,
|
|
@@ -12011,6 +12013,14 @@ var DEFAULT_SOURCES_THRESHOLDS = {
|
|
|
12011
12013
|
smallMax: 2,
|
|
12012
12014
|
mediumMax: 5
|
|
12013
12015
|
};
|
|
12016
|
+
var DEFAULT_BUNDLE_OVERRIDES = {
|
|
12017
|
+
"req:write": {
|
|
12018
|
+
acceptanceCriteria: { smallMax: 3, mediumMax: 20 }
|
|
12019
|
+
},
|
|
12020
|
+
"bcm:scaffold": {
|
|
12021
|
+
acceptanceCriteria: { smallMax: 3, mediumMax: 12 }
|
|
12022
|
+
}
|
|
12023
|
+
};
|
|
12014
12024
|
var DEFAULT_DECOMPOSITION_TEMPLATE = [
|
|
12015
12025
|
"## Scope gate: issue is too large to dispatch",
|
|
12016
12026
|
"",
|
|
@@ -12050,22 +12060,58 @@ function resolveScopeGate(config) {
|
|
|
12050
12060
|
DEFAULT_SOURCES_THRESHOLDS,
|
|
12051
12061
|
"sources"
|
|
12052
12062
|
);
|
|
12063
|
+
const bundleOverrides = resolveBundleOverrides(
|
|
12064
|
+
config?.bundleOverrides,
|
|
12065
|
+
DEFAULT_BUNDLE_OVERRIDES
|
|
12066
|
+
);
|
|
12053
12067
|
return {
|
|
12054
12068
|
enabled: config?.enabled ?? true,
|
|
12055
12069
|
acceptanceCriteria: ac,
|
|
12056
12070
|
sources,
|
|
12057
12071
|
autoFile: config?.autoFile ?? false,
|
|
12058
|
-
decompositionTemplate: config?.decompositionTemplate ?? DEFAULT_DECOMPOSITION_TEMPLATE
|
|
12072
|
+
decompositionTemplate: config?.decompositionTemplate ?? DEFAULT_DECOMPOSITION_TEMPLATE,
|
|
12073
|
+
bundleOverrides
|
|
12074
|
+
};
|
|
12075
|
+
}
|
|
12076
|
+
function resolveOverrideForLabels(gate, labels) {
|
|
12077
|
+
const overrideKeys = Object.keys(gate.bundleOverrides);
|
|
12078
|
+
if (overrideKeys.length === 0 || labels.length === 0) {
|
|
12079
|
+
return {
|
|
12080
|
+
acceptanceCriteria: gate.acceptanceCriteria,
|
|
12081
|
+
sources: gate.sources
|
|
12082
|
+
};
|
|
12083
|
+
}
|
|
12084
|
+
const sortedLabels = [...labels].sort((a, b) => a.localeCompare(b));
|
|
12085
|
+
const matchedLabel = sortedLabels.find(
|
|
12086
|
+
(label) => Object.prototype.hasOwnProperty.call(gate.bundleOverrides, label)
|
|
12087
|
+
);
|
|
12088
|
+
if (matchedLabel === void 0) {
|
|
12089
|
+
return {
|
|
12090
|
+
acceptanceCriteria: gate.acceptanceCriteria,
|
|
12091
|
+
sources: gate.sources
|
|
12092
|
+
};
|
|
12093
|
+
}
|
|
12094
|
+
const override = gate.bundleOverrides[matchedLabel];
|
|
12095
|
+
return {
|
|
12096
|
+
acceptanceCriteria: override.acceptanceCriteria ?? gate.acceptanceCriteria,
|
|
12097
|
+
sources: override.sources ?? gate.sources,
|
|
12098
|
+
matchedLabel
|
|
12059
12099
|
};
|
|
12060
12100
|
}
|
|
12061
12101
|
function validateScopeGateConfig(config) {
|
|
12062
12102
|
return resolveScopeGate(config);
|
|
12063
12103
|
}
|
|
12064
|
-
function classifyIssueScope(body, gate) {
|
|
12104
|
+
function classifyIssueScope(body, gate, labels = []) {
|
|
12065
12105
|
const acCount = countAcceptanceCriteria(body);
|
|
12066
12106
|
const sourcesCount = countSources(body);
|
|
12067
|
-
const
|
|
12068
|
-
|
|
12107
|
+
const effective = resolveOverrideForLabels(gate, labels);
|
|
12108
|
+
const scope = resolveScopeClass(acCount, sourcesCount, effective);
|
|
12109
|
+
return {
|
|
12110
|
+
scope,
|
|
12111
|
+
acCount,
|
|
12112
|
+
sourcesCount,
|
|
12113
|
+
matchedLabel: effective.matchedLabel
|
|
12114
|
+
};
|
|
12069
12115
|
}
|
|
12070
12116
|
function renderScopeGateSection(gate) {
|
|
12071
12117
|
const { acceptanceCriteria: ac, sources } = gate;
|
|
@@ -12141,6 +12187,38 @@ function renderScopeGateSection(gate) {
|
|
|
12141
12187
|
" is in place."
|
|
12142
12188
|
);
|
|
12143
12189
|
}
|
|
12190
|
+
const overrideEntries = Object.entries(gate.bundleOverrides);
|
|
12191
|
+
if (overrideEntries.length > 0) {
|
|
12192
|
+
lines.push(
|
|
12193
|
+
"",
|
|
12194
|
+
"### Per-phase-label thresholds",
|
|
12195
|
+
"",
|
|
12196
|
+
"Issues whose `type:*` or phase label matches an entry below are",
|
|
12197
|
+
"classified against the override's thresholds instead of the",
|
|
12198
|
+
"global `acceptance-criteria` / `sources` defaults. This",
|
|
12199
|
+
"accommodates **content-spec workflows** \u2014 issues whose AC list",
|
|
12200
|
+
"is the per-section content checklist for one cohesive document,",
|
|
12201
|
+
"not a phase-completion checklist that can be decomposed.",
|
|
12202
|
+
"",
|
|
12203
|
+
"| Phase label | AC `mediumMax` | Sources `mediumMax` |",
|
|
12204
|
+
"|-------------|----------------|---------------------|"
|
|
12205
|
+
);
|
|
12206
|
+
const sortedKeys = overrideEntries.map(([k]) => k).sort();
|
|
12207
|
+
for (const label of sortedKeys) {
|
|
12208
|
+
const override = gate.bundleOverrides[label];
|
|
12209
|
+
const acMax = override.acceptanceCriteria?.mediumMax;
|
|
12210
|
+
const sourcesMax = override.sources?.mediumMax;
|
|
12211
|
+
const acCell = acMax === void 0 ? "_(global)_" : `${acMax}`;
|
|
12212
|
+
const sourcesCell = sourcesMax === void 0 ? "_(global)_" : `${sourcesMax}`;
|
|
12213
|
+
lines.push(`| \`${label}\` | ${acCell} | ${sourcesCell} |`);
|
|
12214
|
+
}
|
|
12215
|
+
lines.push(
|
|
12216
|
+
"",
|
|
12217
|
+
"When an issue carries multiple labels that each match an entry",
|
|
12218
|
+
"in this table, the orchestrator picks the **first match in",
|
|
12219
|
+
"alphabetical order on the label name** \u2014 first-wins, deterministic."
|
|
12220
|
+
);
|
|
12221
|
+
}
|
|
12144
12222
|
lines.push(
|
|
12145
12223
|
"",
|
|
12146
12224
|
"### Decomposition-proposal template",
|
|
@@ -12157,12 +12235,21 @@ function renderScopeGateSection(gate) {
|
|
|
12157
12235
|
}
|
|
12158
12236
|
function renderScopeGateShellHelpers(gate) {
|
|
12159
12237
|
const { acceptanceCriteria: ac, sources } = gate;
|
|
12160
|
-
|
|
12238
|
+
const lines = [
|
|
12161
12239
|
"# Classify an issue body against the scope-gate thresholds.",
|
|
12162
12240
|
"# Reads the issue body from stdin. Echoes one of 'small',",
|
|
12163
12241
|
"# 'medium', or 'large' on stdout. Writes the observed counts to",
|
|
12164
12242
|
"# stderr as `ac=<n> sources=<n>` so the caller can embed them in",
|
|
12165
12243
|
"# the decomposition-proposal comment.",
|
|
12244
|
+
"#",
|
|
12245
|
+
"# Effective per-issue thresholds are read from the four",
|
|
12246
|
+
"# `_EFFECTIVE_*` shell variables. The caller is expected to set",
|
|
12247
|
+
"# them via `bundle_override_for()` before invoking scope_of();",
|
|
12248
|
+
"# defaults preserve the global thresholds.",
|
|
12249
|
+
`_EFFECTIVE_AC_SMALL_MAX="\${_EFFECTIVE_AC_SMALL_MAX:-${ac.smallMax}}"`,
|
|
12250
|
+
`_EFFECTIVE_AC_MEDIUM_MAX="\${_EFFECTIVE_AC_MEDIUM_MAX:-${ac.mediumMax}}"`,
|
|
12251
|
+
`_EFFECTIVE_SOURCES_SMALL_MAX="\${_EFFECTIVE_SOURCES_SMALL_MAX:-${sources.smallMax}}"`,
|
|
12252
|
+
`_EFFECTIVE_SOURCES_MEDIUM_MAX="\${_EFFECTIVE_SOURCES_MEDIUM_MAX:-${sources.mediumMax}}"`,
|
|
12166
12253
|
"scope_of() {",
|
|
12167
12254
|
" local body",
|
|
12168
12255
|
" body=$(cat)",
|
|
@@ -12191,15 +12278,79 @@ function renderScopeGateShellHelpers(gate) {
|
|
|
12191
12278
|
" END { print count }",
|
|
12192
12279
|
" ')",
|
|
12193
12280
|
` printf 'ac=%s sources=%s\\n' "$ac_count" "$sources_count" >&2`,
|
|
12194
|
-
|
|
12281
|
+
' if [ "$ac_count" -le "$_EFFECTIVE_AC_SMALL_MAX" ] && [ "$sources_count" -le "$_EFFECTIVE_SOURCES_SMALL_MAX" ]; then',
|
|
12195
12282
|
" echo small",
|
|
12196
|
-
|
|
12283
|
+
' elif [ "$ac_count" -le "$_EFFECTIVE_AC_MEDIUM_MAX" ] && [ "$sources_count" -le "$_EFFECTIVE_SOURCES_MEDIUM_MAX" ]; then',
|
|
12197
12284
|
" echo medium",
|
|
12198
12285
|
" else",
|
|
12199
12286
|
" echo large",
|
|
12200
12287
|
" fi",
|
|
12288
|
+
"}",
|
|
12289
|
+
"",
|
|
12290
|
+
"# Resolve per-phase-label threshold overrides. Reads a newline-",
|
|
12291
|
+
"# separated list of label names on stdin and echoes effective",
|
|
12292
|
+
"# threshold variable assignments (one per line) on stdout. The",
|
|
12293
|
+
"# caller `eval`s the output to set the four `_EFFECTIVE_*`",
|
|
12294
|
+
"# variables before calling `scope_of()`. Also echoes",
|
|
12295
|
+
"# `MATCHED_LABEL=<label>` (or `MATCHED_LABEL=`) so the caller can",
|
|
12296
|
+
"# report which override fired.",
|
|
12297
|
+
"#",
|
|
12298
|
+
"# Tie-breaking: when more than one label matches an override key,",
|
|
12299
|
+
"# the alphabetical first-wins rule applies \u2014 the same rule the",
|
|
12300
|
+
"# TypeScript classifier uses.",
|
|
12301
|
+
"bundle_override_for() {",
|
|
12302
|
+
` local default_ac_small=${ac.smallMax}`,
|
|
12303
|
+
` local default_ac_medium=${ac.mediumMax}`,
|
|
12304
|
+
` local default_sources_small=${sources.smallMax}`,
|
|
12305
|
+
` local default_sources_medium=${sources.mediumMax}`,
|
|
12306
|
+
" # Sort labels alphabetically so the first match is deterministic.",
|
|
12307
|
+
" local sorted_labels",
|
|
12308
|
+
" sorted_labels=$(LC_ALL=C sort)",
|
|
12309
|
+
" local matched_label=''",
|
|
12310
|
+
" local ac_small=$default_ac_small",
|
|
12311
|
+
" local ac_medium=$default_ac_medium",
|
|
12312
|
+
" local sources_small=$default_sources_small",
|
|
12313
|
+
" local sources_medium=$default_sources_medium",
|
|
12314
|
+
" while IFS= read -r label; do",
|
|
12315
|
+
' [ -z "$label" ] && continue',
|
|
12316
|
+
` case "$label" in`
|
|
12317
|
+
];
|
|
12318
|
+
const sortedKeys = Object.keys(gate.bundleOverrides).sort();
|
|
12319
|
+
if (sortedKeys.length === 0) {
|
|
12320
|
+
lines.push(" *) ;;");
|
|
12321
|
+
} else {
|
|
12322
|
+
for (const label of sortedKeys) {
|
|
12323
|
+
const override = gate.bundleOverrides[label];
|
|
12324
|
+
const acThresholds = override.acceptanceCriteria;
|
|
12325
|
+
const sourcesThresholds = override.sources;
|
|
12326
|
+
const branchLines = [` '${label}')`];
|
|
12327
|
+
if (acThresholds !== void 0) {
|
|
12328
|
+
branchLines.push(` ac_small=${acThresholds.smallMax}`);
|
|
12329
|
+
branchLines.push(` ac_medium=${acThresholds.mediumMax}`);
|
|
12330
|
+
}
|
|
12331
|
+
if (sourcesThresholds !== void 0) {
|
|
12332
|
+
branchLines.push(` sources_small=${sourcesThresholds.smallMax}`);
|
|
12333
|
+
branchLines.push(
|
|
12334
|
+
` sources_medium=${sourcesThresholds.mediumMax}`
|
|
12335
|
+
);
|
|
12336
|
+
}
|
|
12337
|
+
branchLines.push(` matched_label='${label}'`);
|
|
12338
|
+
branchLines.push(" break");
|
|
12339
|
+
branchLines.push(" ;;");
|
|
12340
|
+
lines.push(...branchLines);
|
|
12341
|
+
}
|
|
12342
|
+
}
|
|
12343
|
+
lines.push(
|
|
12344
|
+
" esac",
|
|
12345
|
+
` done <<<"$sorted_labels"`,
|
|
12346
|
+
` printf 'MATCHED_LABEL=%s\\n' "$matched_label"`,
|
|
12347
|
+
` printf '_EFFECTIVE_AC_SMALL_MAX=%s\\n' "$ac_small"`,
|
|
12348
|
+
` printf '_EFFECTIVE_AC_MEDIUM_MAX=%s\\n' "$ac_medium"`,
|
|
12349
|
+
` printf '_EFFECTIVE_SOURCES_SMALL_MAX=%s\\n' "$sources_small"`,
|
|
12350
|
+
` printf '_EFFECTIVE_SOURCES_MEDIUM_MAX=%s\\n' "$sources_medium"`,
|
|
12201
12351
|
"}"
|
|
12202
|
-
|
|
12352
|
+
);
|
|
12353
|
+
return lines.join("\n");
|
|
12203
12354
|
}
|
|
12204
12355
|
function resolveThresholds(supplied, defaults, field) {
|
|
12205
12356
|
const merged = {
|
|
@@ -12209,6 +12360,42 @@ function resolveThresholds(supplied, defaults, field) {
|
|
|
12209
12360
|
assertValidThresholds(merged, field);
|
|
12210
12361
|
return merged;
|
|
12211
12362
|
}
|
|
12363
|
+
function resolveBundleOverrides(supplied, defaults) {
|
|
12364
|
+
const out = {};
|
|
12365
|
+
for (const [label, override] of Object.entries(defaults)) {
|
|
12366
|
+
out[label] = override;
|
|
12367
|
+
}
|
|
12368
|
+
if (supplied !== void 0) {
|
|
12369
|
+
for (const label of Object.keys(supplied)) {
|
|
12370
|
+
const value = supplied[label];
|
|
12371
|
+
if (value === void 0) {
|
|
12372
|
+
delete out[label];
|
|
12373
|
+
continue;
|
|
12374
|
+
}
|
|
12375
|
+
const resolved = {};
|
|
12376
|
+
if (value.acceptanceCriteria !== void 0) {
|
|
12377
|
+
resolved.acceptanceCriteria = resolveThresholds(
|
|
12378
|
+
value.acceptanceCriteria,
|
|
12379
|
+
DEFAULT_AC_THRESHOLDS,
|
|
12380
|
+
"acceptanceCriteria"
|
|
12381
|
+
);
|
|
12382
|
+
}
|
|
12383
|
+
if (value.sources !== void 0) {
|
|
12384
|
+
resolved.sources = resolveThresholds(
|
|
12385
|
+
value.sources,
|
|
12386
|
+
DEFAULT_SOURCES_THRESHOLDS,
|
|
12387
|
+
"sources"
|
|
12388
|
+
);
|
|
12389
|
+
}
|
|
12390
|
+
if (resolved.acceptanceCriteria === void 0 && resolved.sources === void 0) {
|
|
12391
|
+
delete out[label];
|
|
12392
|
+
continue;
|
|
12393
|
+
}
|
|
12394
|
+
out[label] = resolved;
|
|
12395
|
+
}
|
|
12396
|
+
}
|
|
12397
|
+
return out;
|
|
12398
|
+
}
|
|
12212
12399
|
function assertValidThresholds(thresholds, field) {
|
|
12213
12400
|
const { smallMax, mediumMax } = thresholds;
|
|
12214
12401
|
for (const [key, value] of [
|
|
@@ -12232,8 +12419,8 @@ function assertValidThresholds(thresholds, field) {
|
|
|
12232
12419
|
);
|
|
12233
12420
|
}
|
|
12234
12421
|
}
|
|
12235
|
-
function resolveScopeClass(acCount, sourcesCount,
|
|
12236
|
-
const { acceptanceCriteria: ac, sources } =
|
|
12422
|
+
function resolveScopeClass(acCount, sourcesCount, thresholds) {
|
|
12423
|
+
const { acceptanceCriteria: ac, sources } = thresholds;
|
|
12237
12424
|
if (acCount <= ac.smallMax && sourcesCount <= sources.smallMax) {
|
|
12238
12425
|
return "small";
|
|
12239
12426
|
}
|
|
@@ -12813,7 +13000,9 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
|
|
|
12813
13000
|
"STALE_BLOCKED_HOURS=168",
|
|
12814
13001
|
`SCOPE_GATE_ENABLED=${scopeGate.enabled ? "1" : "0"}`,
|
|
12815
13002
|
`SCOPE_GATE_AUTO_FILE=${scopeGate.autoFile ? "1" : "0"}`,
|
|
13003
|
+
`SCOPE_AC_SMALL_MAX=${scopeGate.acceptanceCriteria.smallMax}`,
|
|
12816
13004
|
`SCOPE_AC_MEDIUM_MAX=${scopeGate.acceptanceCriteria.mediumMax}`,
|
|
13005
|
+
`SCOPE_SOURCES_SMALL_MAX=${scopeGate.sources.smallMax}`,
|
|
12817
13006
|
`SCOPE_SOURCES_MEDIUM_MAX=${scopeGate.sources.mediumMax}`,
|
|
12818
13007
|
`RUN_RATIO_ENABLED=${runRatio.enabled ? "1" : "0"}`,
|
|
12819
13008
|
`RUN_RATIO_DISPATCH_PER_HOUSEKEEPING=${runRatio.ratio}`,
|
|
@@ -13167,12 +13356,45 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
|
|
|
13167
13356
|
' echo "SCOPE #${issue_num} disabled"',
|
|
13168
13357
|
" return 0",
|
|
13169
13358
|
" fi",
|
|
13359
|
+
" # Fetch the body and labels in a single API call so we resolve",
|
|
13360
|
+
" # any per-phase-label override against the issue's actual labels.",
|
|
13361
|
+
" local issue_json",
|
|
13362
|
+
' issue_json=$(gh issue view "$issue_num" --json body,labels 2>/dev/null || echo "")',
|
|
13363
|
+
' if [[ -z "$issue_json" ]]; then',
|
|
13364
|
+
' echo "SCOPE #${issue_num} unknown \u2014 could not read issue body"',
|
|
13365
|
+
" return 1",
|
|
13366
|
+
" fi",
|
|
13170
13367
|
" local body",
|
|
13171
|
-
` body=$(
|
|
13368
|
+
` body=$(printf '%s' "$issue_json" | jq -r '.body // ""')`,
|
|
13172
13369
|
' if [[ -z "$body" ]]; then',
|
|
13173
13370
|
' echo "SCOPE #${issue_num} unknown \u2014 could not read issue body"',
|
|
13174
13371
|
" return 1",
|
|
13175
13372
|
" fi",
|
|
13373
|
+
" local labels",
|
|
13374
|
+
` labels=$(printf '%s' "$issue_json" | jq -r '.labels[]?.name // empty')`,
|
|
13375
|
+
" # Resolve the effective thresholds. `bundle_override_for` reads",
|
|
13376
|
+
" # labels on stdin and emits `KEY=VALUE` assignments (one per line)",
|
|
13377
|
+
" # for the four `_EFFECTIVE_*` variables plus `MATCHED_LABEL`.",
|
|
13378
|
+
" local override_output",
|
|
13379
|
+
` override_output=$(printf '%s\\n' "$labels" | bundle_override_for)`,
|
|
13380
|
+
" local matched_label=''",
|
|
13381
|
+
" local _EFFECTIVE_AC_SMALL_MAX=$SCOPE_AC_SMALL_MAX",
|
|
13382
|
+
" local _EFFECTIVE_AC_MEDIUM_MAX=$SCOPE_AC_MEDIUM_MAX",
|
|
13383
|
+
" local _EFFECTIVE_SOURCES_SMALL_MAX=$SCOPE_SOURCES_SMALL_MAX",
|
|
13384
|
+
" local _EFFECTIVE_SOURCES_MEDIUM_MAX=$SCOPE_SOURCES_MEDIUM_MAX",
|
|
13385
|
+
" while IFS= read -r assignment; do",
|
|
13386
|
+
' [ -z "$assignment" ] && continue',
|
|
13387
|
+
' case "$assignment" in',
|
|
13388
|
+
" MATCHED_LABEL=*) matched_label=${assignment#MATCHED_LABEL=} ;;",
|
|
13389
|
+
" _EFFECTIVE_AC_SMALL_MAX=*) _EFFECTIVE_AC_SMALL_MAX=${assignment#_EFFECTIVE_AC_SMALL_MAX=} ;;",
|
|
13390
|
+
" _EFFECTIVE_AC_MEDIUM_MAX=*) _EFFECTIVE_AC_MEDIUM_MAX=${assignment#_EFFECTIVE_AC_MEDIUM_MAX=} ;;",
|
|
13391
|
+
" _EFFECTIVE_SOURCES_SMALL_MAX=*) _EFFECTIVE_SOURCES_SMALL_MAX=${assignment#_EFFECTIVE_SOURCES_SMALL_MAX=} ;;",
|
|
13392
|
+
" _EFFECTIVE_SOURCES_MEDIUM_MAX=*) _EFFECTIVE_SOURCES_MEDIUM_MAX=${assignment#_EFFECTIVE_SOURCES_MEDIUM_MAX=} ;;",
|
|
13393
|
+
" esac",
|
|
13394
|
+
' done <<<"$override_output"',
|
|
13395
|
+
" # Export the effective thresholds so scope_of() picks them up.",
|
|
13396
|
+
" export _EFFECTIVE_AC_SMALL_MAX _EFFECTIVE_AC_MEDIUM_MAX",
|
|
13397
|
+
" export _EFFECTIVE_SOURCES_SMALL_MAX _EFFECTIVE_SOURCES_MEDIUM_MAX",
|
|
13176
13398
|
" local scope counts",
|
|
13177
13399
|
" # scope_of writes counts to stderr (ac=N sources=N); capture both.",
|
|
13178
13400
|
` scope=$(printf '%s' "$body" | scope_of 2> >(read -r counts; echo "$counts" >&2))`,
|
|
@@ -13186,9 +13408,17 @@ function buildCheckBlockedScript(tiers, scopeGate, runRatio) {
|
|
|
13186
13408
|
` sources_count=$(echo "$stderr_capture" | grep -oE 'sources=[0-9]+' | head -1 | cut -d= -f2)`,
|
|
13187
13409
|
" ac_count=${ac_count:-0}",
|
|
13188
13410
|
" sources_count=${sources_count:-0}",
|
|
13189
|
-
|
|
13190
|
-
|
|
13191
|
-
'
|
|
13411
|
+
' if [ -n "$matched_label" ]; then',
|
|
13412
|
+
" printf 'SCOPE #%s %s ac=%s sources=%s ac_limit=%s sources_limit=%s auto_file=%s matched_label=%s\\n' \\",
|
|
13413
|
+
' "$issue_num" "$scope" "$ac_count" "$sources_count" \\',
|
|
13414
|
+
' "$_EFFECTIVE_AC_MEDIUM_MAX" "$_EFFECTIVE_SOURCES_MEDIUM_MAX" \\',
|
|
13415
|
+
' "$SCOPE_GATE_AUTO_FILE" "$matched_label"',
|
|
13416
|
+
" else",
|
|
13417
|
+
" printf 'SCOPE #%s %s ac=%s sources=%s ac_limit=%s sources_limit=%s auto_file=%s\\n' \\",
|
|
13418
|
+
' "$issue_num" "$scope" "$ac_count" "$sources_count" \\',
|
|
13419
|
+
' "$_EFFECTIVE_AC_MEDIUM_MAX" "$_EFFECTIVE_SOURCES_MEDIUM_MAX" \\',
|
|
13420
|
+
' "$SCOPE_GATE_AUTO_FILE"',
|
|
13421
|
+
" fi",
|
|
13192
13422
|
"}",
|
|
13193
13423
|
"",
|
|
13194
13424
|
"cmd_tick() {",
|
|
@@ -13393,9 +13623,16 @@ var orchestratorSubAgent = {
|
|
|
13393
13623
|
"The output is one line of the form:",
|
|
13394
13624
|
"",
|
|
13395
13625
|
"```",
|
|
13396
|
-
"SCOPE #<n> <small|medium|large> ac=<n> sources=<n> ac_limit=<n> sources_limit=<n> auto_file=<0|1>",
|
|
13626
|
+
"SCOPE #<n> <small|medium|large> ac=<n> sources=<n> ac_limit=<n> sources_limit=<n> auto_file=<0|1> [matched_label=<label>]",
|
|
13397
13627
|
"```",
|
|
13398
13628
|
"",
|
|
13629
|
+
"When `matched_label=<label>` is present, the scope gate applied a",
|
|
13630
|
+
"per-phase-label override (e.g. `req:write` raises the AC ceiling to",
|
|
13631
|
+
"20 for content-spec workflows whose AC list is the per-section",
|
|
13632
|
+
"checklist for one document). The `ac_limit` / `sources_limit`",
|
|
13633
|
+
"values reflect the override; the global thresholds are documented",
|
|
13634
|
+
"in the **Scope gate** section in `CLAUDE.md`.",
|
|
13635
|
+
"",
|
|
13399
13636
|
"If the scope is `small` or `medium`, continue \u2014 the issue is",
|
|
13400
13637
|
"dispatchable. Record the first `PICK` line as the next work item",
|
|
13401
13638
|
"and proceed to Phase G:",
|
|
@@ -32676,6 +32913,7 @@ var TypeScriptConfig = class extends import_projen23.Component {
|
|
|
32676
32913
|
DEFAULT_API_EXTRACTOR_REPORT_FILENAME,
|
|
32677
32914
|
DEFAULT_API_EXTRACTOR_REPORT_FOLDER,
|
|
32678
32915
|
DEFAULT_AUDIT_REPORT_DIR,
|
|
32916
|
+
DEFAULT_BUNDLE_OVERRIDES,
|
|
32679
32917
|
DEFAULT_DECOMPOSITION_TEMPLATE,
|
|
32680
32918
|
DEFAULT_DISPATCH_MODEL,
|
|
32681
32919
|
DEFAULT_DISPATCH_TO_HOUSEKEEPING_RATIO,
|
|
@@ -32861,6 +33099,7 @@ var TypeScriptConfig = class extends import_projen23.Component {
|
|
|
32861
33099
|
resolveModelAlias,
|
|
32862
33100
|
resolveOrchestratorAssets,
|
|
32863
33101
|
resolveOutdirFromPackageName,
|
|
33102
|
+
resolveOverrideForLabels,
|
|
32864
33103
|
resolveProgressFiles,
|
|
32865
33104
|
resolveRunRatio,
|
|
32866
33105
|
resolveScheduledTasks,
|