@codedrifters/configulator 0.0.401 → 0.0.403
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 +11 -0
- package/lib/index.d.ts +11 -0
- package/lib/index.js +121 -18
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +121 -18
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
package/lib/index.d.mts
CHANGED
|
@@ -5219,6 +5219,17 @@ declare const DEFAULT_SOURCES_THRESHOLDS: ScopeGateThresholds;
|
|
|
5219
5219
|
* issue scored `ac=7 / src=9`). Both axes are raised to
|
|
5220
5220
|
* `mediumMax: 12` — this is why `req:scan` carries a `sources`
|
|
5221
5221
|
* override the AC-only siblings do not.
|
|
5222
|
+
* - `bcm:outline` — the `bcm-writer` Phase-1 outline phase authors a
|
|
5223
|
+
* single capability outline document whose AC list is the content
|
|
5224
|
+
* checklist for that one indivisible deliverable (identify the L1
|
|
5225
|
+
* parent, draft the L2 definition, document sub-facets, draw the
|
|
5226
|
+
* capability boundary, write the outline file, update the
|
|
5227
|
+
* capability map), not a decomposable plan — the criteria cannot be
|
|
5228
|
+
* split into independently-mergeable sub-issues because every one
|
|
5229
|
+
* of them edits the same outline file. Sibling of `bcm:scaffold` /
|
|
5230
|
+
* `bcm:context` / `bcm:connect`; mirrors their `mediumMax: 12` AC
|
|
5231
|
+
* cap. Observed ac=7 (`codedrifters/openhi-planning`#11216). AC
|
|
5232
|
+
* axis only; sources fall through to the global band.
|
|
5222
5233
|
*
|
|
5223
5234
|
* Consumer overrides deep-merge with these defaults with
|
|
5224
5235
|
* consumer-wins-per-key (see `resolveScopeGate` for the merge
|
package/lib/index.d.ts
CHANGED
|
@@ -5268,6 +5268,17 @@ declare const DEFAULT_SOURCES_THRESHOLDS: ScopeGateThresholds;
|
|
|
5268
5268
|
* issue scored `ac=7 / src=9`). Both axes are raised to
|
|
5269
5269
|
* `mediumMax: 12` — this is why `req:scan` carries a `sources`
|
|
5270
5270
|
* override the AC-only siblings do not.
|
|
5271
|
+
* - `bcm:outline` — the `bcm-writer` Phase-1 outline phase authors a
|
|
5272
|
+
* single capability outline document whose AC list is the content
|
|
5273
|
+
* checklist for that one indivisible deliverable (identify the L1
|
|
5274
|
+
* parent, draft the L2 definition, document sub-facets, draw the
|
|
5275
|
+
* capability boundary, write the outline file, update the
|
|
5276
|
+
* capability map), not a decomposable plan — the criteria cannot be
|
|
5277
|
+
* split into independently-mergeable sub-issues because every one
|
|
5278
|
+
* of them edits the same outline file. Sibling of `bcm:scaffold` /
|
|
5279
|
+
* `bcm:context` / `bcm:connect`; mirrors their `mediumMax: 12` AC
|
|
5280
|
+
* cap. Observed ac=7 (`codedrifters/openhi-planning`#11216). AC
|
|
5281
|
+
* axis only; sources fall through to the global band.
|
|
5271
5282
|
*
|
|
5272
5283
|
* Consumer overrides deep-merge with these defaults with
|
|
5273
5284
|
* consumer-wins-per-key (see `resolveScopeGate` for the merge
|
package/lib/index.js
CHANGED
|
@@ -4674,6 +4674,35 @@ function buildBaseBundle(paths = DEFAULT_AGENT_PATHS) {
|
|
|
4674
4674
|
"schema and consumer example. `status:deferred` is a valid",
|
|
4675
4675
|
"override value reserved for this exact use case.",
|
|
4676
4676
|
"",
|
|
4677
|
+
"### The `status:deferred` invariant",
|
|
4678
|
+
"",
|
|
4679
|
+
"**No agent, procedure, or sweep ever removes `status:deferred`.",
|
|
4680
|
+
"Only a human promotes a deferred issue.**",
|
|
4681
|
+
"",
|
|
4682
|
+
"`status:deferred` records a deliberate human decision to park",
|
|
4683
|
+
"work. Automation may read it, count it, and log it \u2014 but the",
|
|
4684
|
+
"label is cleared exclusively by a human (or by a scheduled task",
|
|
4685
|
+
"a human configured for that purpose). Concretely:",
|
|
4686
|
+
"",
|
|
4687
|
+
"- **Unblock sweeps skip it.** Both `check-blocked.sh unblock`",
|
|
4688
|
+
" and `unblock-dependents.sh` leave a `status:deferred` +",
|
|
4689
|
+
" `status:blocked` issue blocked when its dependencies close,",
|
|
4690
|
+
" emitting a `SKIP_DEFERRED #<n>` line instead of flipping to",
|
|
4691
|
+
" `status:ready`. Dependency resolution is not a promotion",
|
|
4692
|
+
" signal for parked work.",
|
|
4693
|
+
"- **Dispatch scans exclude it.** `check-blocked.sh eligible`",
|
|
4694
|
+
" drops any issue carrying `status:deferred`, so a stray",
|
|
4695
|
+
" `status:ready` + `status:deferred` pairing never reaches a",
|
|
4696
|
+
" worker.",
|
|
4697
|
+
"- **No sweep writes it either.** Automation adds",
|
|
4698
|
+
" `status:deferred` only at filing time via the configured",
|
|
4699
|
+
" `issueDefaults` \u2014 never as a runtime triage decision.",
|
|
4700
|
+
"",
|
|
4701
|
+
"An issue that legitimately needs to leave the parked backlog is",
|
|
4702
|
+
"promoted by a human removing `status:deferred` and setting the",
|
|
4703
|
+
"appropriate base status. Any automation that removes the label",
|
|
4704
|
+
"is a bug.",
|
|
4705
|
+
"",
|
|
4677
4706
|
"### Blocking Rules",
|
|
4678
4707
|
"",
|
|
4679
4708
|
"Two rules force `status:blocked` \u2014 both are non-negotiable:",
|
|
@@ -14392,6 +14421,9 @@ var DEFAULT_BUNDLE_OVERRIDES = {
|
|
|
14392
14421
|
"req:scan": {
|
|
14393
14422
|
acceptanceCriteria: { smallMax: 3, mediumMax: 12 },
|
|
14394
14423
|
sources: { smallMax: 2, mediumMax: 12 }
|
|
14424
|
+
},
|
|
14425
|
+
"bcm:outline": {
|
|
14426
|
+
acceptanceCriteria: { smallMax: 3, mediumMax: 12 }
|
|
14395
14427
|
}
|
|
14396
14428
|
};
|
|
14397
14429
|
var DEFAULT_DECOMPOSITION_TEMPLATE = [
|
|
@@ -15163,13 +15195,16 @@ function renderUnblockDependentsSection(ud) {
|
|
|
15163
15195
|
"",
|
|
15164
15196
|
"1. Searches open issues for `Depends on: #<closed>` references in",
|
|
15165
15197
|
" their body.",
|
|
15166
|
-
"2.
|
|
15198
|
+
"2. Skips any match carrying `status:deferred`, emitting a",
|
|
15199
|
+
" `SKIP_DEFERRED` line. A human-parked issue is never promoted by",
|
|
15200
|
+
" a sweep, no matter how its dependencies resolve.",
|
|
15201
|
+
"3. For each remaining match, re-reads every dependency listed across",
|
|
15167
15202
|
" **all** `Depends on:` lines in the body (bodies routinely list",
|
|
15168
15203
|
" one dependency per line) and checks whether they are all closed.",
|
|
15169
|
-
"
|
|
15204
|
+
"4. If **all** dependencies are closed, flips the dependent from",
|
|
15170
15205
|
" `status:blocked` to `status:ready` and posts a one-line comment",
|
|
15171
15206
|
" citing the resolving issue.",
|
|
15172
|
-
"
|
|
15207
|
+
"5. If **some** dependencies are still open, leaves the dependent",
|
|
15173
15208
|
" as `status:blocked` and optionally posts a partial-unblock",
|
|
15174
15209
|
" comment (see the **Partial unblock behaviour** subsection",
|
|
15175
15210
|
" below).",
|
|
@@ -15203,6 +15238,7 @@ function renderUnblockDependentsSection(ud) {
|
|
|
15203
15238
|
'UNBLOCKED #<dep> \u2014 all deps closed (<closed-list>) \u2014 "<title>"',
|
|
15204
15239
|
'UNBLOCK_FAILED #<dep> \u2014 label flip failed (all deps closed: <closed-list>) \u2014 "<title>"',
|
|
15205
15240
|
'STILL_BLOCKED #<dep> \u2014 waiting on <open-list> \u2014 "<title>"',
|
|
15241
|
+
'SKIP_DEFERRED #<dep> \u2014 status:deferred; human-parked, not promoting \u2014 "<title>"',
|
|
15206
15242
|
"NO_DEPENDENTS #<closed>",
|
|
15207
15243
|
"```",
|
|
15208
15244
|
"",
|
|
@@ -15212,7 +15248,10 @@ function renderUnblockDependentsSection(ud) {
|
|
|
15212
15248
|
"error, permissions, or the dependent went stale between the",
|
|
15213
15249
|
"search and the edit) \u2014 a human needs to retry or flip the label",
|
|
15214
15250
|
"manually. `STILL_BLOCKED` lines mean the dependent stays blocked",
|
|
15215
|
-
"pending other open deps. `
|
|
15251
|
+
"pending other open deps. `SKIP_DEFERRED` lines mean the dependent",
|
|
15252
|
+
"carries `status:deferred` and was deliberately left blocked even",
|
|
15253
|
+
"though its dependencies resolved \u2014 the sweep never promotes a",
|
|
15254
|
+
"human-parked issue. `NO_DEPENDENTS` means no open issue",
|
|
15216
15255
|
"references the just-closed issue in a `Depends on:` line.",
|
|
15217
15256
|
"",
|
|
15218
15257
|
"### Partial unblock behaviour",
|
|
@@ -15363,7 +15402,7 @@ function renderUnblockDependentsScript(ud) {
|
|
|
15363
15402
|
"# `status:blocked` \u2192 `status:ready` directly on the overflow.",
|
|
15364
15403
|
'dependents=$(gh issue list --label "status:blocked" --state open \\',
|
|
15365
15404
|
' --search "in:body \\"Depends on:\\"" \\',
|
|
15366
|
-
' --json number,title,body --limit 100 2>/dev/null || echo "[]")',
|
|
15405
|
+
' --json number,title,body,labels --limit 100 2>/dev/null || echo "[]")',
|
|
15367
15406
|
"",
|
|
15368
15407
|
`count=$(echo "$dependents" | jq 'length')`,
|
|
15369
15408
|
'if [[ "$count" -eq 0 ]]; then',
|
|
@@ -15371,6 +15410,18 @@ function renderUnblockDependentsScript(ud) {
|
|
|
15371
15410
|
" exit 0",
|
|
15372
15411
|
"fi",
|
|
15373
15412
|
"",
|
|
15413
|
+
"# Human-parked candidates (`status:deferred`). Collected jq-side into a",
|
|
15414
|
+
"# space-delimited lookup string rather than threaded through the",
|
|
15415
|
+
"# tab-separated records below: an extra TSV field would either sit after",
|
|
15416
|
+
"# dep_line (displacing the mandatory-last optional field) or before it",
|
|
15417
|
+
"# (reintroducing the #884 IFS tab-collapse bug). The skip itself happens",
|
|
15418
|
+
"# inside the loop, after the closed-issue reference test, so an unrelated",
|
|
15419
|
+
"# deferred issue in the search window never emits a line. No agent or",
|
|
15420
|
+
"# sweep ever removes `status:deferred` \u2014 only a human promotes it.",
|
|
15421
|
+
`deferred_set=" $(echo "$dependents" | jq -r '`,
|
|
15422
|
+
' .[] | select(.labels | map(.name) | index("status:deferred")) | .number',
|
|
15423
|
+
`' | tr '\\n' ' ')"`,
|
|
15424
|
+
"",
|
|
15374
15425
|
"# Union every `Depends on:` line per candidate (a body may list one",
|
|
15375
15426
|
"# dependency per line) into a single space-joined dep string and stream",
|
|
15376
15427
|
"# as tab-separated number / title / dep-line tuples.",
|
|
@@ -15406,6 +15457,14 @@ function renderUnblockDependentsScript(ud) {
|
|
|
15406
15457
|
"",
|
|
15407
15458
|
" found_any=true",
|
|
15408
15459
|
"",
|
|
15460
|
+
" # Deliberately-parked dependents never get promoted by a sweep, even",
|
|
15461
|
+
" # when every dependency has closed. Only a human clears",
|
|
15462
|
+
" # `status:deferred`.",
|
|
15463
|
+
' if [[ "$deferred_set" == *" ${num} "* ]]; then',
|
|
15464
|
+
' echo "SKIP_DEFERRED #${num} \u2014 status:deferred; human-parked, not promoting \u2014 \\"${title}\\""',
|
|
15465
|
+
" continue",
|
|
15466
|
+
" fi",
|
|
15467
|
+
"",
|
|
15409
15468
|
" # Re-check every dep in the list. Fully-closed \u2192 unblock.",
|
|
15410
15469
|
" all_closed=true",
|
|
15411
15470
|
' open_deps=""',
|
|
@@ -15595,15 +15654,26 @@ function buildCheckBlockedScript(tiers, scopeGate, _runRatio) {
|
|
|
15595
15654
|
" # position.",
|
|
15596
15655
|
" local issues",
|
|
15597
15656
|
' issues=$(gh issue list --label "status:blocked" --state open \\',
|
|
15598
|
-
' --json number,body --limit 1000 2>/dev/null || echo "[]")',
|
|
15657
|
+
' --json number,body,labels --limit 1000 2>/dev/null || echo "[]")',
|
|
15599
15658
|
"",
|
|
15600
15659
|
" local count",
|
|
15601
15660
|
` count=$(echo "$issues" | jq 'length')`,
|
|
15602
15661
|
' if [[ "$count" -eq 0 ]]; then',
|
|
15603
|
-
' echo "TRIAGE_DONE unblocked=0 still_blocked=0"',
|
|
15662
|
+
' echo "TRIAGE_DONE unblocked=0 still_blocked=0 deferred_skipped=0"',
|
|
15604
15663
|
" return 0",
|
|
15605
15664
|
" fi",
|
|
15606
15665
|
"",
|
|
15666
|
+
" # Human-parked candidates (`status:deferred`). Collected jq-side into",
|
|
15667
|
+
" # a space-delimited lookup string rather than threaded through the",
|
|
15668
|
+
" # tab-separated records below: an extra TSV field would either sit",
|
|
15669
|
+
" # after dep_line (displacing the mandatory-last optional field) or",
|
|
15670
|
+
" # before it (reintroducing the #884 IFS tab-collapse bug). No agent",
|
|
15671
|
+
" # or sweep ever removes `status:deferred` \u2014 only a human promotes it.",
|
|
15672
|
+
" local deferred_set",
|
|
15673
|
+
` deferred_set=" $(echo "$issues" | jq -r '`,
|
|
15674
|
+
' .[] | select(.labels | map(.name) | index("status:deferred")) | .number',
|
|
15675
|
+
` ' | tr '\\n' ' ')"`,
|
|
15676
|
+
"",
|
|
15607
15677
|
" local issue_data",
|
|
15608
15678
|
` issue_data=$(echo "$issues" | jq -r '`,
|
|
15609
15679
|
" .[] |",
|
|
@@ -15616,10 +15686,20 @@ function buildCheckBlockedScript(tiers, scopeGate, _runRatio) {
|
|
|
15616
15686
|
" # mirroring unblock-dependents.sh.",
|
|
15617
15687
|
" local unblocked_count=0",
|
|
15618
15688
|
" local still_blocked_count=0",
|
|
15689
|
+
" local deferred_skipped_count=0",
|
|
15619
15690
|
"",
|
|
15620
15691
|
" while IFS=$'\\t' read -r num dep_line; do",
|
|
15621
15692
|
' [[ -z "$num" ]] && continue',
|
|
15622
15693
|
"",
|
|
15694
|
+
" # Deliberately-parked issues never get promoted by a sweep, even",
|
|
15695
|
+
" # when every dependency has closed. Only a human clears",
|
|
15696
|
+
" # `status:deferred`.",
|
|
15697
|
+
' if [[ "$deferred_set" == *" ${num} "* ]]; then',
|
|
15698
|
+
' echo "SKIP_DEFERRED #${num} \u2014 status:deferred; human-parked, not promoting"',
|
|
15699
|
+
" deferred_skipped_count=$((deferred_skipped_count + 1))",
|
|
15700
|
+
" continue",
|
|
15701
|
+
" fi",
|
|
15702
|
+
"",
|
|
15623
15703
|
' if [[ -z "$dep_line" ]]; then',
|
|
15624
15704
|
' echo "BLOCKED #${num} \u2014 no Depends on field found"',
|
|
15625
15705
|
" still_blocked_count=$((still_blocked_count + 1))",
|
|
@@ -15680,7 +15760,7 @@ function buildCheckBlockedScript(tiers, scopeGate, _runRatio) {
|
|
|
15680
15760
|
' done <<< "$issue_data"',
|
|
15681
15761
|
"",
|
|
15682
15762
|
" # Single summary line consumed by the orchestrator.",
|
|
15683
|
-
' echo "TRIAGE_DONE unblocked=${unblocked_count} still_blocked=${still_blocked_count}"',
|
|
15763
|
+
' echo "TRIAGE_DONE unblocked=${unblocked_count} still_blocked=${still_blocked_count} deferred_skipped=${deferred_skipped_count}"',
|
|
15684
15764
|
"}",
|
|
15685
15765
|
"",
|
|
15686
15766
|
"cmd_eligible() {",
|
|
@@ -15704,11 +15784,26 @@ function buildCheckBlockedScript(tiers, scopeGate, _runRatio) {
|
|
|
15704
15784
|
" continue",
|
|
15705
15785
|
" fi",
|
|
15706
15786
|
"",
|
|
15787
|
+
" # Dispatch exclusions. `gh issue list` has no negative-label filter",
|
|
15788
|
+
" # for a label-filtered (non-search) listing, so both exclusions run",
|
|
15789
|
+
" # jq-side over the labels already fetched above \u2014 no new TSV field",
|
|
15790
|
+
" # is needed, and the mandatory-last dep_line ordering is untouched.",
|
|
15791
|
+
" # - `status:needs-attention` is additive (it no longer replaces the",
|
|
15792
|
+
" # base status), so a scope-gate-flagged issue keeps `status:ready`",
|
|
15793
|
+
" # and would re-surface in every scan until a human clears the flag",
|
|
15794
|
+
" # (#901). It is never dispatchable, so drop it from the scan.",
|
|
15795
|
+
" # - `status:deferred` is human-parked: captured for provenance and",
|
|
15796
|
+
" # never auto-dispatched. `status:ready` + `status:deferred` is",
|
|
15797
|
+
" # reachable (e.g. after an unblock or a manual edit), so exclude",
|
|
15798
|
+
" # it here as the dispatch-side half of the #887 guard.",
|
|
15707
15799
|
" local issue_data",
|
|
15708
15800
|
` issue_data=$(echo "$issues" | jq -r '`,
|
|
15709
15801
|
" .[] |",
|
|
15802
|
+
" (.labels | map(.name)) as $names |",
|
|
15803
|
+
' select($names | index("status:needs-attention") | not) |',
|
|
15804
|
+
' select($names | index("status:deferred") | not) |',
|
|
15710
15805
|
' (.body | split("\\n") | map(select(test("Depends on:"; "i"))) | join(" ")) as $dep_line |',
|
|
15711
|
-
' (
|
|
15806
|
+
' ($names | map(select(startswith("type:"))) | .[0] // "") as $type_label |',
|
|
15712
15807
|
' "\\(.number)\\t\\(.title)\\t\\($type_label)\\t\\($dep_line)"',
|
|
15713
15808
|
" ')",
|
|
15714
15809
|
"",
|
|
@@ -16352,7 +16447,7 @@ function buildCheckBlockedScript(tiers, scopeGate, _runRatio) {
|
|
|
16352
16447
|
function buildCheckBlockedProcedure(tiers, scopeGate = resolveScopeGate(), runRatio = resolveRunRatio()) {
|
|
16353
16448
|
return {
|
|
16354
16449
|
name: "check-blocked.sh",
|
|
16355
|
-
description: "Token-efficient issue triage script with subcommands: eligible, unblock, stale, orphaned, lease-reconcile, maintenance, prs, scope. Sorts eligible issues by priority desc \u2192 funnel tier asc \u2192 issue number asc
|
|
16450
|
+
description: "Token-efficient issue triage script with subcommands: eligible, unblock, stale, orphaned, lease-reconcile, maintenance, prs, scope. Sorts eligible issues by priority desc \u2192 funnel tier asc \u2192 issue number asc, excluding issues carrying `status:needs-attention` or `status:deferred`; the scope subcommand classifies a single issue against the scope-gate thresholds; the unblock subcommand applies the `status:blocked` \u2192 `status:ready` label flip itself, posts the canned unblock comment, skips human-parked `status:deferred` candidates with a `SKIP_DEFERRED` line, and emits a single `TRIAGE_DONE unblocked=N still_blocked=M deferred_skipped=K` summary line; the lease-reconcile subcommand auto-reconciles stuck `review:fixing` PR leases \u2014 re-applying `review:needs-worker` on an orphaned lease (fix-list stale, no worker report) so the Phase B1 drain retries, and removing `review:needs-worker` on a consumed-but-uncleared wedge (branch HEAD advanced past the fix-list, marker still set, no worker report) so the reviewer confirm pass can merge, always posting an audit-trail note comment and emitting a single `LEASE_RECONCILE orphaned=N consumed_uncleared=M` summary line; the maintenance subcommand flags stale issues with `status:needs-attention` (never auto-resets to `status:ready`), counts orphan branches/PRs, folds in the lease-reconcile sweep, and emits a `MAINTENANCE_DONE flagged_stale=N flagged_blocked=M orphan_branches=A orphan_prs=B needs_attention_total=T` summary line followed by the `LEASE_RECONCILE` line.",
|
|
16356
16451
|
content: buildCheckBlockedScript(tiers, scopeGate, runRatio)
|
|
16357
16452
|
};
|
|
16358
16453
|
}
|
|
@@ -17034,14 +17129,20 @@ var orchestratorSubAgent = {
|
|
|
17034
17129
|
"The script emits one summary line in this shape:",
|
|
17035
17130
|
"",
|
|
17036
17131
|
"```",
|
|
17037
|
-
"TRIAGE_DONE unblocked=<N> still_blocked=<M>",
|
|
17132
|
+
"TRIAGE_DONE unblocked=<N> still_blocked=<M> deferred_skipped=<K>",
|
|
17038
17133
|
"```",
|
|
17039
17134
|
"",
|
|
17040
17135
|
"Per-issue informational lines (`UNBLOCKED #N`, `UNBLOCK_FAILED #N`,",
|
|
17041
|
-
"`STILL_BLOCKED #N`, `BLOCKED #N \u2014 no Depends on
|
|
17042
|
-
"emitted for log visibility but are **not**
|
|
17043
|
-
"orchestrator \u2014 partial failures (one bad `gh`
|
|
17044
|
-
"the sweep, they are simply counted toward
|
|
17136
|
+
"`STILL_BLOCKED #N`, `SKIP_DEFERRED #N`, `BLOCKED #N \u2014 no Depends on",
|
|
17137
|
+
"field found`) are emitted for log visibility but are **not**",
|
|
17138
|
+
"load-bearing for the orchestrator \u2014 partial failures (one bad `gh`",
|
|
17139
|
+
"call) do not abort the sweep, they are simply counted toward",
|
|
17140
|
+
"`still_blocked`.",
|
|
17141
|
+
"",
|
|
17142
|
+
"`deferred_skipped` counts candidates the sweep deliberately left",
|
|
17143
|
+
"blocked because they carry `status:deferred`. Those issues are",
|
|
17144
|
+
"human-parked: no agent or sweep ever removes `status:deferred`, so",
|
|
17145
|
+
"a non-zero count is expected steady-state noise, not a failure.",
|
|
17045
17146
|
"",
|
|
17046
17147
|
"This phase is the **fallback safety net** for agent-driven",
|
|
17047
17148
|
"unblocking. Every agent that applies `status:done` already runs",
|
|
@@ -18221,9 +18322,11 @@ var checkBlockedCommand = {
|
|
|
18221
18322
|
"reference, applies the `status:blocked` \u2192 `status:ready` label flip",
|
|
18222
18323
|
"itself, posts the canned `Dependencies resolved \u2014 unblocking.`",
|
|
18223
18324
|
"comment, and emits a single",
|
|
18224
|
-
"`TRIAGE_DONE unblocked=<N> still_blocked=<M>`
|
|
18225
|
-
"
|
|
18226
|
-
"
|
|
18325
|
+
"`TRIAGE_DONE unblocked=<N> still_blocked=<M> deferred_skipped=<K>`",
|
|
18326
|
+
"summary line. Candidates carrying `status:deferred` are skipped",
|
|
18327
|
+
"rather than promoted \u2014 only a human clears that label. Per-issue",
|
|
18328
|
+
"informational lines (`UNBLOCKED`, `UNBLOCK_FAILED`, `STILL_BLOCKED`,",
|
|
18329
|
+
"`SKIP_DEFERRED`) are also emitted for log visibility.",
|
|
18227
18330
|
"",
|
|
18228
18331
|
"Summarise the output (the `TRIAGE_DONE` counts and the first few",
|
|
18229
18332
|
"per-issue lines) \u2014 do **not** apply additional label flips yourself;",
|