@codedrifters/configulator 0.0.408 → 0.0.410
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 +36 -1
- package/lib/index.d.ts +36 -1
- package/lib/index.js +631 -40
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +629 -40
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -373,6 +373,7 @@ __export(index_exports, {
|
|
|
373
373
|
buildUnblockDependentsProcedure: () => buildUnblockDependentsProcedure,
|
|
374
374
|
bundleNameForWorkflowRule: () => bundleNameForWorkflowRule,
|
|
375
375
|
businessModelsBundle: () => businessModelsBundle,
|
|
376
|
+
checkClosingKeywordsProcedure: () => checkClosingKeywordsProcedure,
|
|
376
377
|
checkDocSamplesProcedure: () => checkDocSamplesProcedure,
|
|
377
378
|
checkLinksProcedure: () => checkLinksProcedure,
|
|
378
379
|
classifyIssueScope: () => classifyIssueScope,
|
|
@@ -447,6 +448,7 @@ __export(index_exports, {
|
|
|
447
448
|
renderCdkRollback: () => renderCdkRollback,
|
|
448
449
|
renderCdkSynth: () => renderCdkSynth,
|
|
449
450
|
renderCdkWatch: () => renderCdkWatch,
|
|
451
|
+
renderCheckClosingKeywordsScript: () => renderCheckClosingKeywordsScript,
|
|
450
452
|
renderCheckDocSamplesProcedure: () => renderCheckDocSamplesProcedure,
|
|
451
453
|
renderCheckLinksProcedure: () => renderCheckLinksProcedure,
|
|
452
454
|
renderCustomDocSectionBlock: () => renderCustomDocSectionBlock,
|
|
@@ -1256,6 +1258,53 @@ function buildTitlePrefixTypeMap() {
|
|
|
1256
1258
|
return map;
|
|
1257
1259
|
}
|
|
1258
1260
|
|
|
1261
|
+
// src/agent/bundles/origin-label.ts
|
|
1262
|
+
var ORIGIN_ISSUE_WORKER_LABEL = "origin:issue-worker";
|
|
1263
|
+
var ORIGIN_AGENT_LABEL = "origin:agent";
|
|
1264
|
+
var DELEGATION_ELIGIBLE_ORIGIN_PHRASE = `an origin label (\`${ORIGIN_ISSUE_WORKER_LABEL}\` or \`${ORIGIN_AGENT_LABEL}\`)`;
|
|
1265
|
+
var DELEGATION_ELIGIBLE_ORIGIN_LIST = `\`${ORIGIN_ISSUE_WORKER_LABEL}\` or \`${ORIGIN_AGENT_LABEL}\``;
|
|
1266
|
+
function renderOriginStampSection() {
|
|
1267
|
+
return [
|
|
1268
|
+
"## Origin label",
|
|
1269
|
+
"",
|
|
1270
|
+
`Every PR you open must carry the \`${ORIGIN_AGENT_LABEL}\` label. It is`,
|
|
1271
|
+
"the umbrella origin label for **agent-opened** PRs: the `pr-reviewer`",
|
|
1272
|
+
"reads it to decide whether it may autonomously delegate in-scope",
|
|
1273
|
+
"review fixes back to the `issue-worker`. A PR that reaches the",
|
|
1274
|
+
"reviewer with no origin label looks human-authored, so the reviewer",
|
|
1275
|
+
"skips the delegation hand-off and the PR sits waiting for a human",
|
|
1276
|
+
"instead of being self-healed by the pipeline.",
|
|
1277
|
+
"",
|
|
1278
|
+
"Pass the label on the `gh pr create` invocation:",
|
|
1279
|
+
"",
|
|
1280
|
+
"```bash",
|
|
1281
|
+
'gh pr create --title "<type>(<scope>): <description>" \\',
|
|
1282
|
+
` --label '${ORIGIN_AGENT_LABEL}' \\`,
|
|
1283
|
+
' --body "<summary>',
|
|
1284
|
+
"",
|
|
1285
|
+
'Closes #<issue-number>"',
|
|
1286
|
+
"```",
|
|
1287
|
+
"",
|
|
1288
|
+
"If your project's PR workflow opens the PR for you and the label is",
|
|
1289
|
+
"missing afterwards, add it immediately \u2014 before handing the PR to",
|
|
1290
|
+
"review:",
|
|
1291
|
+
"",
|
|
1292
|
+
"```bash",
|
|
1293
|
+
`gh pr edit <pr-number> --add-label '${ORIGIN_AGENT_LABEL}'`,
|
|
1294
|
+
"```",
|
|
1295
|
+
"",
|
|
1296
|
+
`Stamp \`${ORIGIN_AGENT_LABEL}\`, never \`${ORIGIN_ISSUE_WORKER_LABEL}\` \u2014`,
|
|
1297
|
+
`\`${ORIGIN_ISSUE_WORKER_LABEL}\` means the PR was opened by the`,
|
|
1298
|
+
"`issue-worker` agent specifically, and claiming it on an analyst PR",
|
|
1299
|
+
"would be false. Both labels are delegation-eligible, so the umbrella",
|
|
1300
|
+
"label buys the same autonomous fix hand-off without the false claim.",
|
|
1301
|
+
"",
|
|
1302
|
+
`The \`${ORIGIN_AGENT_LABEL}\` label ships with the \`pr-review\` bundle's`,
|
|
1303
|
+
"label set, so it is already present in the repository's label",
|
|
1304
|
+
"registry \u2014 you never need to create it."
|
|
1305
|
+
];
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1259
1308
|
// src/agent/bundles/project-context.ts
|
|
1260
1309
|
var PROJECT_CONTEXT_PATH = "docs/src/content/docs/project-context.md";
|
|
1261
1310
|
var SUBPROJECT_ROLE_GUIDANCE = [
|
|
@@ -1529,6 +1578,8 @@ var agendaAnalystSubAgent = {
|
|
|
1529
1578
|
" label.",
|
|
1530
1579
|
"4. Commit, push, open a PR, and transition the issue to",
|
|
1531
1580
|
" `status:ready-for-review` per your project's PR workflow.",
|
|
1581
|
+
" Stamp every PR you open with the `origin:agent` label \u2014 see the",
|
|
1582
|
+
" **Origin label** section below.",
|
|
1532
1583
|
"",
|
|
1533
1584
|
"---",
|
|
1534
1585
|
"",
|
|
@@ -1536,6 +1587,10 @@ var agendaAnalystSubAgent = {
|
|
|
1536
1587
|
"",
|
|
1537
1588
|
"---",
|
|
1538
1589
|
"",
|
|
1590
|
+
...renderOriginStampSection(),
|
|
1591
|
+
"",
|
|
1592
|
+
"---",
|
|
1593
|
+
"",
|
|
1539
1594
|
"## Phase 1: Draft (`agenda:draft`)",
|
|
1540
1595
|
"",
|
|
1541
1596
|
"**Goal:** Produce a well-structured `agenda.md` in the meeting's",
|
|
@@ -6352,6 +6407,8 @@ function buildBcmWriterSubAgent(paths, issueDefaults) {
|
|
|
6352
6407
|
"3. Execute the phase handler that matches the issue's `bcm:*` label.",
|
|
6353
6408
|
"4. Commit, push, open a PR (if applicable), and close the issue per",
|
|
6354
6409
|
" your project's PR workflow.",
|
|
6410
|
+
" Stamp every PR you open with the `origin:agent` label \u2014 see the",
|
|
6411
|
+
" **Origin label** section below.",
|
|
6355
6412
|
"",
|
|
6356
6413
|
"---",
|
|
6357
6414
|
"",
|
|
@@ -6359,6 +6416,10 @@ function buildBcmWriterSubAgent(paths, issueDefaults) {
|
|
|
6359
6416
|
"",
|
|
6360
6417
|
"---",
|
|
6361
6418
|
"",
|
|
6419
|
+
...renderOriginStampSection(),
|
|
6420
|
+
"",
|
|
6421
|
+
"---",
|
|
6422
|
+
"",
|
|
6362
6423
|
"## Phase 1: Outline (`bcm:outline`)",
|
|
6363
6424
|
"",
|
|
6364
6425
|
"**Goal:** Identify the capability (name-as-noun, business object, tier)",
|
|
@@ -7650,6 +7711,8 @@ function buildBusinessModelsAnalystSubAgent(paths) {
|
|
|
7650
7711
|
" `business-models:*` label.",
|
|
7651
7712
|
"4. Commit, push, open a PR (if applicable), and close the issue per",
|
|
7652
7713
|
" your project's PR workflow.",
|
|
7714
|
+
" Stamp every PR you open with the `origin:agent` label \u2014 see the",
|
|
7715
|
+
" **Origin label** section below.",
|
|
7653
7716
|
"",
|
|
7654
7717
|
"---",
|
|
7655
7718
|
"",
|
|
@@ -7657,6 +7720,10 @@ function buildBusinessModelsAnalystSubAgent(paths) {
|
|
|
7657
7720
|
"",
|
|
7658
7721
|
"---",
|
|
7659
7722
|
"",
|
|
7723
|
+
...renderOriginStampSection(),
|
|
7724
|
+
"",
|
|
7725
|
+
"---",
|
|
7726
|
+
"",
|
|
7660
7727
|
"## Phase 1: Scan (`business-models:scan`)",
|
|
7661
7728
|
"",
|
|
7662
7729
|
"**Goal:** Read upstream industry and profile artifacts to identify",
|
|
@@ -8553,6 +8620,8 @@ function buildCompanyProfileAnalystSubAgent(paths, issueDefaults, tier) {
|
|
|
8553
8620
|
" label.",
|
|
8554
8621
|
"4. Commit, push, open a PR (if applicable), and close the issue per",
|
|
8555
8622
|
" your project's PR workflow.",
|
|
8623
|
+
" Stamp every PR you open with the `origin:agent` label \u2014 see the",
|
|
8624
|
+
" **Origin label** section below.",
|
|
8556
8625
|
"",
|
|
8557
8626
|
"---",
|
|
8558
8627
|
"",
|
|
@@ -8560,6 +8629,10 @@ function buildCompanyProfileAnalystSubAgent(paths, issueDefaults, tier) {
|
|
|
8560
8629
|
"",
|
|
8561
8630
|
"---",
|
|
8562
8631
|
"",
|
|
8632
|
+
...renderOriginStampSection(),
|
|
8633
|
+
"",
|
|
8634
|
+
"---",
|
|
8635
|
+
"",
|
|
8563
8636
|
"## Phase 1: Research (`company:research`)",
|
|
8564
8637
|
"",
|
|
8565
8638
|
"**Goal:** Gather public sources into a bounded research-notes file.",
|
|
@@ -9998,6 +10071,8 @@ function buildCustomerProfileAnalystSubAgent(paths, issueDefaults, tier) {
|
|
|
9998
10071
|
" label.",
|
|
9999
10072
|
"4. Commit, push, open a PR (if applicable), and close the issue per",
|
|
10000
10073
|
" your project's PR workflow.",
|
|
10074
|
+
" Stamp every PR you open with the `origin:agent` label \u2014 see the",
|
|
10075
|
+
" **Origin label** section below.",
|
|
10001
10076
|
"",
|
|
10002
10077
|
"---",
|
|
10003
10078
|
"",
|
|
@@ -10005,6 +10080,10 @@ function buildCustomerProfileAnalystSubAgent(paths, issueDefaults, tier) {
|
|
|
10005
10080
|
"",
|
|
10006
10081
|
"---",
|
|
10007
10082
|
"",
|
|
10083
|
+
...renderOriginStampSection(),
|
|
10084
|
+
"",
|
|
10085
|
+
"---",
|
|
10086
|
+
"",
|
|
10008
10087
|
"## Phase 1: Discover (`customer:discover`)",
|
|
10009
10088
|
"",
|
|
10010
10089
|
"**Goal:** Identify and segment the customer archetypes relevant to",
|
|
@@ -11757,6 +11836,278 @@ var docsSyncBundle = buildDocsSyncBundle();
|
|
|
11757
11836
|
|
|
11758
11837
|
// src/agent/bundles/github-workflow.ts
|
|
11759
11838
|
var import_github = require("projen/lib/github");
|
|
11839
|
+
|
|
11840
|
+
// src/agent/bundles/closing-keywords.ts
|
|
11841
|
+
function renderCheckClosingKeywordsScript() {
|
|
11842
|
+
return [
|
|
11843
|
+
"#!/usr/bin/env bash",
|
|
11844
|
+
"# check-closing-keywords.sh \u2014 Detect PR bodies that strand issues.",
|
|
11845
|
+
"#",
|
|
11846
|
+
"# GitHub honours exactly ONE issue reference per closing keyword. A",
|
|
11847
|
+
"# body that writes `Closes #593, #594, #595` closes #593 and leaves",
|
|
11848
|
+
"# #594 and #595 open forever. The only correct form is one keyword",
|
|
11849
|
+
"# per issue, each on its own line:",
|
|
11850
|
+
"#",
|
|
11851
|
+
"# Closes #593",
|
|
11852
|
+
"# Closes #594",
|
|
11853
|
+
"#",
|
|
11854
|
+
"# Usage:",
|
|
11855
|
+
"# .claude/procedures/check-closing-keywords.sh <pr-number>",
|
|
11856
|
+
"# .claude/procedures/check-closing-keywords.sh --body-file <path>",
|
|
11857
|
+
"#",
|
|
11858
|
+
"# Output (one stable line per reference, then a summary line):",
|
|
11859
|
+
"# CLOSES #<n> line=<L>",
|
|
11860
|
+
"# A reference GitHub WILL honour (the first one after a keyword).",
|
|
11861
|
+
"# STRANDED #<n> line=<L> keyword=<kw> first=#<n>",
|
|
11862
|
+
"# A reference chained onto an earlier one. GitHub will NOT",
|
|
11863
|
+
"# close it \u2014 the issue is stranded.",
|
|
11864
|
+
"# CLOSING_KEYWORDS_OK closes=<K>",
|
|
11865
|
+
"# CLOSING_KEYWORDS_MALFORMED closes=<K> stranded=<S>",
|
|
11866
|
+
"# NO_CLOSING_KEYWORD",
|
|
11867
|
+
"#",
|
|
11868
|
+
"# Exit codes:",
|
|
11869
|
+
"# 0 \u2014 at least one closing keyword, every one well-formed",
|
|
11870
|
+
"# 1 \u2014 at least one stranded reference (malformed body)",
|
|
11871
|
+
"# 2 \u2014 argument error",
|
|
11872
|
+
"# 3 \u2014 required command not on PATH",
|
|
11873
|
+
"# 4 \u2014 could not read the PR body",
|
|
11874
|
+
"# 5 \u2014 no closing keyword found at all",
|
|
11875
|
+
"",
|
|
11876
|
+
"set -uo pipefail",
|
|
11877
|
+
"",
|
|
11878
|
+
"# \u2500\u2500 helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
11879
|
+
"",
|
|
11880
|
+
"err() {",
|
|
11881
|
+
' printf "check-closing-keywords.sh: %s\\n" "$*" >&2',
|
|
11882
|
+
"}",
|
|
11883
|
+
"",
|
|
11884
|
+
"usage() {",
|
|
11885
|
+
" cat >&2 <<'USAGE'",
|
|
11886
|
+
"Usage: check-closing-keywords.sh <pr-number>",
|
|
11887
|
+
" check-closing-keywords.sh --body-file <path>",
|
|
11888
|
+
"",
|
|
11889
|
+
" <pr-number> Positive integer PR number; the body is read",
|
|
11890
|
+
" via `gh pr view <n> --json body`.",
|
|
11891
|
+
" --body-file <path> Read the body from a file instead. Use this to",
|
|
11892
|
+
" check a drafted body BEFORE `gh pr create`.",
|
|
11893
|
+
"",
|
|
11894
|
+
"Emits one CLOSES / STRANDED line per issue reference, then a summary.",
|
|
11895
|
+
"Exits 1 when any reference is stranded by a multi-issue keyword.",
|
|
11896
|
+
"USAGE",
|
|
11897
|
+
"}",
|
|
11898
|
+
"",
|
|
11899
|
+
"# \u2500\u2500 argument parsing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
11900
|
+
"",
|
|
11901
|
+
'mode=""',
|
|
11902
|
+
'arg=""',
|
|
11903
|
+
"",
|
|
11904
|
+
"while [[ $# -gt 0 ]]; do",
|
|
11905
|
+
' case "$1" in',
|
|
11906
|
+
" --body-file)",
|
|
11907
|
+
' if [[ $# -lt 2 || -z "${2:-}" ]]; then',
|
|
11908
|
+
' err "--body-file requires a value"',
|
|
11909
|
+
" usage",
|
|
11910
|
+
" exit 2",
|
|
11911
|
+
" fi",
|
|
11912
|
+
' if [[ -n "$mode" ]]; then',
|
|
11913
|
+
' err "specify either a PR number or --body-file, not both"',
|
|
11914
|
+
" exit 2",
|
|
11915
|
+
" fi",
|
|
11916
|
+
' mode="file"',
|
|
11917
|
+
' arg="$2"',
|
|
11918
|
+
" shift 2",
|
|
11919
|
+
" ;;",
|
|
11920
|
+
" -h|--help)",
|
|
11921
|
+
" usage",
|
|
11922
|
+
" exit 0",
|
|
11923
|
+
" ;;",
|
|
11924
|
+
" -*)",
|
|
11925
|
+
' err "unknown option: $1"',
|
|
11926
|
+
" usage",
|
|
11927
|
+
" exit 2",
|
|
11928
|
+
" ;;",
|
|
11929
|
+
" *)",
|
|
11930
|
+
' if [[ -n "$mode" ]]; then',
|
|
11931
|
+
' err "unexpected extra argument: $1"',
|
|
11932
|
+
" usage",
|
|
11933
|
+
" exit 2",
|
|
11934
|
+
" fi",
|
|
11935
|
+
' mode="pr"',
|
|
11936
|
+
' arg="$1"',
|
|
11937
|
+
" shift",
|
|
11938
|
+
" ;;",
|
|
11939
|
+
" esac",
|
|
11940
|
+
"done",
|
|
11941
|
+
"",
|
|
11942
|
+
'if [[ -z "$mode" ]]; then',
|
|
11943
|
+
' err "expected a PR number or --body-file <path>"',
|
|
11944
|
+
" usage",
|
|
11945
|
+
" exit 2",
|
|
11946
|
+
"fi",
|
|
11947
|
+
"",
|
|
11948
|
+
"# \u2500\u2500 read the body \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
11949
|
+
"",
|
|
11950
|
+
'body=""',
|
|
11951
|
+
"",
|
|
11952
|
+
'if [[ "$mode" == "file" ]]; then',
|
|
11953
|
+
' if [[ ! -r "$arg" ]]; then',
|
|
11954
|
+
' err "body file not readable: $arg"',
|
|
11955
|
+
" exit 4",
|
|
11956
|
+
" fi",
|
|
11957
|
+
' body=$(cat "$arg")',
|
|
11958
|
+
"else",
|
|
11959
|
+
' if ! [[ "$arg" =~ ^[1-9][0-9]*$ ]]; then',
|
|
11960
|
+
` err "PR number must be a positive integer (got: '$arg')"`,
|
|
11961
|
+
" exit 2",
|
|
11962
|
+
" fi",
|
|
11963
|
+
" if ! command -v gh >/dev/null 2>&1; then",
|
|
11964
|
+
' err "required command not found on PATH: gh"',
|
|
11965
|
+
" exit 3",
|
|
11966
|
+
" fi",
|
|
11967
|
+
` if ! body=$(gh pr view "$arg" --json body -q '.body' 2>/dev/null); then`,
|
|
11968
|
+
' err "could not read the body of PR #${arg} via gh"',
|
|
11969
|
+
" exit 4",
|
|
11970
|
+
" fi",
|
|
11971
|
+
"fi",
|
|
11972
|
+
"",
|
|
11973
|
+
"# \u2500\u2500 parsing contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
11974
|
+
"#",
|
|
11975
|
+
"# Regexes live in single-quoted variables so backticks and other shell",
|
|
11976
|
+
"# metacharacters inside them are never expanded by [[ ]].",
|
|
11977
|
+
"#",
|
|
11978
|
+
"# kw_re matches a closing keyword plus its FIRST issue reference. The",
|
|
11979
|
+
"# leading (^|[^[:alnum:]_]) is a word boundary so `prefixes #1` is not",
|
|
11980
|
+
"# read as `fixes #1`.",
|
|
11981
|
+
"#",
|
|
11982
|
+
"# sep_re / ws_re walk the tail AFTER that first reference, matching",
|
|
11983
|
+
"# only references CHAINED directly onto it by a separator a human",
|
|
11984
|
+
"# would mistake for a list: `,` `/` `&` `+` `and` `, and`, or",
|
|
11985
|
+
"# bare whitespace. Anything else \u2014 a period, a dash, a word, an",
|
|
11986
|
+
"# opening paren \u2014 terminates the chain. That is what keeps prose like",
|
|
11987
|
+
"# `Closes #893. See #607 and #860 for context.` from false-positiving:",
|
|
11988
|
+
"# the `.` after #893 ends the chain before `#607` is ever considered.",
|
|
11989
|
+
"",
|
|
11990
|
+
"fence_re='^[[:space:]]{0,3}(```+|~~~+)'",
|
|
11991
|
+
"quote_re='^[[:space:]]*>'",
|
|
11992
|
+
"kw_re='(^|[^[:alnum:]_])(closes|closed|close|fixes|fixed|fix|resolves|resolved|resolve)[[:space:]]*:?[[:space:]]*#([0-9]+)(.*)$'",
|
|
11993
|
+
"sep_re='^[[:space:]]*(,[[:space:]]*and|,|/|&|[+]|and)[[:space:]]*#([0-9]+)(.*)$'",
|
|
11994
|
+
"ws_re='^[[:space:]]+#([0-9]+)(.*)$'",
|
|
11995
|
+
"",
|
|
11996
|
+
"# Keywords are case-insensitive on GitHub, so the scan is too.",
|
|
11997
|
+
"shopt -s nocasematch",
|
|
11998
|
+
"",
|
|
11999
|
+
"# A single backtick, held in a variable so the code-span stripper",
|
|
12000
|
+
"# never has to quote one inline.",
|
|
12001
|
+
"bt='`'",
|
|
12002
|
+
"",
|
|
12003
|
+
"# Remove inline code spans (`...`) from a line. A PR body that",
|
|
12004
|
+
"# DISCUSSES the malformed form \u2014 writing `Closes #593, #594` inside",
|
|
12005
|
+
"# backticks \u2014 must not trip the detector.",
|
|
12006
|
+
"strip_code_spans() {",
|
|
12007
|
+
' local s="$1"',
|
|
12008
|
+
' local out=""',
|
|
12009
|
+
' while [[ "$s" == *"$bt"*"$bt"* ]]; do',
|
|
12010
|
+
' out="$out${s%%$bt*}"',
|
|
12011
|
+
' s="${s#*$bt}"',
|
|
12012
|
+
' s="${s#*$bt}"',
|
|
12013
|
+
" done",
|
|
12014
|
+
` printf '%s%s' "$out" "$s"`,
|
|
12015
|
+
"}",
|
|
12016
|
+
"",
|
|
12017
|
+
"# \u2500\u2500 scan \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
12018
|
+
"",
|
|
12019
|
+
"line_no=0",
|
|
12020
|
+
"in_fence=0",
|
|
12021
|
+
'fence_marker=""',
|
|
12022
|
+
"closes_count=0",
|
|
12023
|
+
"stranded_count=0",
|
|
12024
|
+
"",
|
|
12025
|
+
'while IFS= read -r raw || [[ -n "$raw" ]]; do',
|
|
12026
|
+
" line_no=$((line_no + 1))",
|
|
12027
|
+
" # gh returns CRLF bodies; strip the CR so end-of-line matching works.",
|
|
12028
|
+
` raw="\${raw//$'\\r'/}"`,
|
|
12029
|
+
"",
|
|
12030
|
+
" # Fenced code blocks are quoted content, never the PR's own intent.",
|
|
12031
|
+
' if [[ "$raw" =~ $fence_re ]]; then',
|
|
12032
|
+
' marker="${BASH_REMATCH[1]:0:1}"',
|
|
12033
|
+
" if [[ $in_fence -eq 0 ]]; then",
|
|
12034
|
+
" in_fence=1",
|
|
12035
|
+
' fence_marker="$marker"',
|
|
12036
|
+
' elif [[ "$marker" == "$fence_marker" ]]; then',
|
|
12037
|
+
" in_fence=0",
|
|
12038
|
+
' fence_marker=""',
|
|
12039
|
+
" fi",
|
|
12040
|
+
" continue",
|
|
12041
|
+
" fi",
|
|
12042
|
+
" if [[ $in_fence -eq 1 ]]; then",
|
|
12043
|
+
" continue",
|
|
12044
|
+
" fi",
|
|
12045
|
+
"",
|
|
12046
|
+
" # Blockquoted text is someone else's words being cited.",
|
|
12047
|
+
' if [[ "$raw" =~ $quote_re ]]; then',
|
|
12048
|
+
" continue",
|
|
12049
|
+
" fi",
|
|
12050
|
+
"",
|
|
12051
|
+
' line=$(strip_code_spans "$raw")',
|
|
12052
|
+
"",
|
|
12053
|
+
' rest="$line"',
|
|
12054
|
+
' while [[ "$rest" =~ $kw_re ]]; do',
|
|
12055
|
+
' kw="${BASH_REMATCH[2]}"',
|
|
12056
|
+
' first="${BASH_REMATCH[3]}"',
|
|
12057
|
+
' tail="${BASH_REMATCH[4]}"',
|
|
12058
|
+
"",
|
|
12059
|
+
` printf 'CLOSES #%s line=%s\\n' "$first" "$line_no"`,
|
|
12060
|
+
" closes_count=$((closes_count + 1))",
|
|
12061
|
+
"",
|
|
12062
|
+
" # Walk every reference chained onto this keyword's first one.",
|
|
12063
|
+
' t="$tail"',
|
|
12064
|
+
" while :; do",
|
|
12065
|
+
' if [[ "$t" =~ $sep_re ]]; then',
|
|
12066
|
+
' extra="${BASH_REMATCH[2]}"',
|
|
12067
|
+
' t="${BASH_REMATCH[3]}"',
|
|
12068
|
+
' elif [[ "$t" =~ $ws_re ]]; then',
|
|
12069
|
+
' extra="${BASH_REMATCH[1]}"',
|
|
12070
|
+
' t="${BASH_REMATCH[2]}"',
|
|
12071
|
+
" else",
|
|
12072
|
+
" break",
|
|
12073
|
+
" fi",
|
|
12074
|
+
" printf 'STRANDED #%s line=%s keyword=%s first=#%s\\n' \\",
|
|
12075
|
+
' "$extra" "$line_no" "$kw" "$first"',
|
|
12076
|
+
" stranded_count=$((stranded_count + 1))",
|
|
12077
|
+
" done",
|
|
12078
|
+
"",
|
|
12079
|
+
' rest="$t"',
|
|
12080
|
+
" done",
|
|
12081
|
+
'done <<< "$body"',
|
|
12082
|
+
"",
|
|
12083
|
+
"# \u2500\u2500 summary \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
12084
|
+
"",
|
|
12085
|
+
"if [[ $closes_count -eq 0 ]]; then",
|
|
12086
|
+
' echo "NO_CLOSING_KEYWORD"',
|
|
12087
|
+
" exit 5",
|
|
12088
|
+
"fi",
|
|
12089
|
+
"",
|
|
12090
|
+
"if [[ $stranded_count -gt 0 ]]; then",
|
|
12091
|
+
" printf 'CLOSING_KEYWORDS_MALFORMED closes=%s stranded=%s\\n' \\",
|
|
12092
|
+
' "$closes_count" "$stranded_count"',
|
|
12093
|
+
' err "GitHub honours only ONE issue reference per closing keyword."',
|
|
12094
|
+
' err "Give every issue its own keyword, one per line:"',
|
|
12095
|
+
' err " Closes #123"',
|
|
12096
|
+
' err " Closes #456"',
|
|
12097
|
+
" exit 1",
|
|
12098
|
+
"fi",
|
|
12099
|
+
"",
|
|
12100
|
+
`printf 'CLOSING_KEYWORDS_OK closes=%s\\n' "$closes_count"`,
|
|
12101
|
+
"exit 0"
|
|
12102
|
+
].join("\n");
|
|
12103
|
+
}
|
|
12104
|
+
var checkClosingKeywordsProcedure = {
|
|
12105
|
+
name: "check-closing-keywords.sh",
|
|
12106
|
+
description: "Parse a PR body (by PR number or --body-file) and report every closing-keyword issue reference as CLOSES (GitHub will honour it) or STRANDED (chained onto an earlier reference and silently ignored). Exits 1 when any reference is stranded. Skips fenced code blocks, blockquotes, and inline code spans.",
|
|
12107
|
+
content: renderCheckClosingKeywordsScript()
|
|
12108
|
+
};
|
|
12109
|
+
|
|
12110
|
+
// src/agent/bundles/github-workflow.ts
|
|
11760
12111
|
var setIssueTypeProcedure = {
|
|
11761
12112
|
name: "set-issue-type.sh",
|
|
11762
12113
|
description: "Assign a GitHub issue type (Feature / Task / Epic / Bug / etc.) via the updateIssueIssueType GraphQL mutation in a single step",
|
|
@@ -12431,8 +12782,24 @@ function buildGithubWorkflowBundle(buildPolicy = DEFAULT_BUILD_POLICY) {
|
|
|
12431
12782
|
"5. **Push the branch** to origin: `git push -u origin <branch>`",
|
|
12432
12783
|
"6. **Create the PR** using `gh pr create`:",
|
|
12433
12784
|
" - **Title**: use a conventional commit style title (e.g., `feat(scope): short description`)",
|
|
12434
|
-
" - **Body**: include `Closes #<issue-number>` (derived from the branch name) and a brief summary of changes",
|
|
12435
|
-
"7. **
|
|
12785
|
+
" - **Body**: include one `Closes #<issue-number>` line per issue the PR closes (derived from the branch name and any additional issues in scope) and a brief summary of changes. See **Closing Keywords** below \u2014 never list several issues after a single keyword.",
|
|
12786
|
+
"7. **Verify the closing keywords** with `.claude/procedures/check-closing-keywords.sh --body-file <path>` on the body you are about to post, then `.claude/procedures/check-closing-keywords.sh <pr-number>` on the body that landed. Exit `0` means every referenced issue will auto-close; exit `1` prints a `STRANDED #<n>` line per issue GitHub would silently leave open \u2014 fix the body with `gh pr edit <pr-number> --body-file <path>` and re-run until it exits `0`.",
|
|
12787
|
+
"8. **Delegate review and merge to the `pr-reviewer` sub-agent.** After the PR is created, invoke the `/review-pr <pr-number>` skill (or otherwise hand the new PR number to the `pr-reviewer` sub-agent). The reviewer verifies the diff against the linked issue's acceptance criteria and enables squash auto-merge when all checks pass. Do **not** run `gh pr merge --auto` yourself \u2014 review/merge policy lives solely in the `pr-reviewer` agent.",
|
|
12788
|
+
"",
|
|
12789
|
+
"### Closing Keywords",
|
|
12790
|
+
"",
|
|
12791
|
+
"**GitHub honours exactly ONE issue reference per closing keyword.** `Closes #593, #594, #595` closes **#593 only** \u2014 #594 and #595 stay open forever with no warning anywhere. `Closes #821 / #837` and `Closes #821 and #837` strand the second issue the same way. Give every issue its own keyword, one per line:",
|
|
12792
|
+
"",
|
|
12793
|
+
"```markdown",
|
|
12794
|
+
"Closes #593 <- correct: repeat the keyword, one issue each",
|
|
12795
|
+
"Closes #594",
|
|
12796
|
+
"",
|
|
12797
|
+
"Closes #593, #594 <- WRONG: closes #593, strands #594",
|
|
12798
|
+
"Closes #821 / #837 <- WRONG: closes #821, strands #837",
|
|
12799
|
+
"Closes #821 and #837 <- WRONG: closes #821, strands #837",
|
|
12800
|
+
"```",
|
|
12801
|
+
"",
|
|
12802
|
+
"`Fixes` and `Resolves` behave identically \u2014 the rule is the keyword-to-issue ratio, not the verb. Non-closing references (`Refs #849`, `Related to #607`) are unaffected. `.claude/procedures/check-closing-keywords.sh` is the mechanical check; it skips fenced code blocks, blockquotes, and inline code spans, so a body that *discusses* the malformed form does not trip it.",
|
|
12436
12803
|
"",
|
|
12437
12804
|
"### PR Body Template",
|
|
12438
12805
|
"",
|
|
@@ -12449,10 +12816,18 @@ function buildGithubWorkflowBundle(buildPolicy = DEFAULT_BUILD_POLICY) {
|
|
|
12449
12816
|
"- [ ] Relevant changes have been reviewed",
|
|
12450
12817
|
"```",
|
|
12451
12818
|
"",
|
|
12819
|
+
"When the PR closes more than one issue, the closing block expands to one keyword per issue \u2014 it never becomes a list:",
|
|
12820
|
+
"",
|
|
12821
|
+
"```markdown",
|
|
12822
|
+
"Closes #<first-issue-number>",
|
|
12823
|
+
"Closes #<second-issue-number>",
|
|
12824
|
+
"```",
|
|
12825
|
+
"",
|
|
12452
12826
|
"### Important",
|
|
12453
12827
|
"",
|
|
12454
12828
|
"- Always derive the issue number from the branch name (e.g., `feat/42-add-login` \u2192 `#42`)",
|
|
12455
12829
|
"- Use conventional commit format for the PR title",
|
|
12830
|
+
"- **One closing keyword per issue, each on its own line.** Never `Closes #A, #B` \u2014 GitHub closes only `#A`. Run `.claude/procedures/check-closing-keywords.sh` before and after `gh pr create`; a non-zero exit means the PR would strand an issue",
|
|
12456
12831
|
"- Delegate merge to the `pr-reviewer` sub-agent \u2014 do not merge manually and do not enable auto-merge directly"
|
|
12457
12832
|
].join("\n"),
|
|
12458
12833
|
tags: ["workflow"]
|
|
@@ -12485,7 +12860,11 @@ function buildGithubWorkflowBundle(buildPolicy = DEFAULT_BUILD_POLICY) {
|
|
|
12485
12860
|
}
|
|
12486
12861
|
],
|
|
12487
12862
|
skills: [cleanMergedBranchesSkill],
|
|
12488
|
-
procedures: [
|
|
12863
|
+
procedures: [
|
|
12864
|
+
setIssueTypeProcedure,
|
|
12865
|
+
cleanMergedBranchesProcedure,
|
|
12866
|
+
checkClosingKeywordsProcedure
|
|
12867
|
+
]
|
|
12489
12868
|
};
|
|
12490
12869
|
}
|
|
12491
12870
|
var githubWorkflowBundle = buildGithubWorkflowBundle();
|
|
@@ -12650,6 +13029,8 @@ function buildIndustryDiscoveryAnalystSubAgent(paths, issueDefaults) {
|
|
|
12650
13029
|
" label.",
|
|
12651
13030
|
"4. Commit, push, open a PR (if applicable), and close the issue per",
|
|
12652
13031
|
" your project's PR workflow.",
|
|
13032
|
+
" Stamp every PR you open with the `origin:agent` label \u2014 see the",
|
|
13033
|
+
" **Origin label** section below.",
|
|
12653
13034
|
"",
|
|
12654
13035
|
"---",
|
|
12655
13036
|
"",
|
|
@@ -12657,6 +13038,10 @@ function buildIndustryDiscoveryAnalystSubAgent(paths, issueDefaults) {
|
|
|
12657
13038
|
"",
|
|
12658
13039
|
"---",
|
|
12659
13040
|
"",
|
|
13041
|
+
...renderOriginStampSection(),
|
|
13042
|
+
"",
|
|
13043
|
+
"---",
|
|
13044
|
+
"",
|
|
12660
13045
|
"## Phase 1: Discover (`industry:discover`)",
|
|
12661
13046
|
"",
|
|
12662
13047
|
"**Goal:** Enumerate candidate industry verticals into a bounded",
|
|
@@ -13209,6 +13594,8 @@ function buildMaintenanceAuditSubAgent(paths, tier) {
|
|
|
13209
13594
|
" label.",
|
|
13210
13595
|
"4. Commit, push, open a PR (if applicable), and close the issue per",
|
|
13211
13596
|
" your project's PR workflow.",
|
|
13597
|
+
" Stamp every PR you open with the `origin:agent` label \u2014 see the",
|
|
13598
|
+
" **Origin label** section below.",
|
|
13212
13599
|
"",
|
|
13213
13600
|
...renderIssueTypeAssignmentBlanket(),
|
|
13214
13601
|
"",
|
|
@@ -13218,6 +13605,10 @@ function buildMaintenanceAuditSubAgent(paths, tier) {
|
|
|
13218
13605
|
"",
|
|
13219
13606
|
"---",
|
|
13220
13607
|
"",
|
|
13608
|
+
...renderOriginStampSection(),
|
|
13609
|
+
"",
|
|
13610
|
+
"---",
|
|
13611
|
+
"",
|
|
13221
13612
|
"## Phase 1: Scan (`maint:scan`)",
|
|
13222
13613
|
"",
|
|
13223
13614
|
"**Goal:** Walk the configured doc tree, check every cross-reference",
|
|
@@ -14110,6 +14501,10 @@ function buildMeetingAnalystSubAgent(tier) {
|
|
|
14110
14501
|
"",
|
|
14111
14502
|
"---",
|
|
14112
14503
|
"",
|
|
14504
|
+
...renderOriginStampSection(),
|
|
14505
|
+
"",
|
|
14506
|
+
"---",
|
|
14507
|
+
"",
|
|
14113
14508
|
"## Phase 1: Extract (`meeting:extract`)",
|
|
14114
14509
|
"",
|
|
14115
14510
|
"**Goal:** Read the available meeting inputs (notes, transcript, or both)",
|
|
@@ -19573,6 +19968,27 @@ var issueWorkerSubAgent = {
|
|
|
19573
19968
|
'Closes #<issue-number>"',
|
|
19574
19969
|
"```",
|
|
19575
19970
|
"",
|
|
19971
|
+
"**One closing keyword per issue, each on its own line.** GitHub honours",
|
|
19972
|
+
"only one issue reference per keyword, so `Closes #A, #B` closes `#A` and",
|
|
19973
|
+
"leaves `#B` open forever \u2014 the same is true of `Closes #A / #B` and",
|
|
19974
|
+
"`Closes #A and #B`. A PR that closes several issues repeats the keyword:",
|
|
19975
|
+
"",
|
|
19976
|
+
"```",
|
|
19977
|
+
"Closes #<first-issue-number>",
|
|
19978
|
+
"Closes #<second-issue-number>",
|
|
19979
|
+
"```",
|
|
19980
|
+
"",
|
|
19981
|
+
"Verify it mechanically before moving on \u2014 this exits non-zero and names",
|
|
19982
|
+
"every issue the body would strand:",
|
|
19983
|
+
"",
|
|
19984
|
+
"```bash",
|
|
19985
|
+
".claude/procedures/check-closing-keywords.sh <pr-number>",
|
|
19986
|
+
"```",
|
|
19987
|
+
"",
|
|
19988
|
+
"If it reports `CLOSING_KEYWORDS_MALFORMED`, fix the body with",
|
|
19989
|
+
"`gh pr edit <pr-number> --body-file <path>` and re-run until it exits",
|
|
19990
|
+
"`0`. See the **Closing Keywords** section of the `pr-workflow` rule.",
|
|
19991
|
+
"",
|
|
19576
19992
|
"Do **not** enable auto-merge yourself. The `pr-reviewer` sub-agent owns",
|
|
19577
19993
|
"review and merge for every PR \u2014 it verifies the diff against the issue's",
|
|
19578
19994
|
"acceptance criteria and enables squash auto-merge only when all checks",
|
|
@@ -20123,6 +20539,8 @@ function buildPeopleProfileAnalystSubAgent(paths, issueDefaults, tier) {
|
|
|
20123
20539
|
" label.",
|
|
20124
20540
|
"4. Commit, push, open a PR (if applicable), and close the issue per",
|
|
20125
20541
|
" your project's PR workflow.",
|
|
20542
|
+
" Stamp every PR you open with the `origin:agent` label \u2014 see the",
|
|
20543
|
+
" **Origin label** section below.",
|
|
20126
20544
|
"",
|
|
20127
20545
|
"---",
|
|
20128
20546
|
"",
|
|
@@ -20130,6 +20548,10 @@ function buildPeopleProfileAnalystSubAgent(paths, issueDefaults, tier) {
|
|
|
20130
20548
|
"",
|
|
20131
20549
|
"---",
|
|
20132
20550
|
"",
|
|
20551
|
+
...renderOriginStampSection(),
|
|
20552
|
+
"",
|
|
20553
|
+
"---",
|
|
20554
|
+
"",
|
|
20133
20555
|
"## Phase 1: Research (`people:research`)",
|
|
20134
20556
|
"",
|
|
20135
20557
|
"**Goal:** Gather public sources into a bounded research-notes file.",
|
|
@@ -21092,14 +21514,14 @@ var prReviewerSubAgent = {
|
|
|
21092
21514
|
"",
|
|
21093
21515
|
"- **`--allow-human-author`** \u2014 opt-in flag that allows the reviewer to",
|
|
21094
21516
|
" process PRs authored by humans in addition to bot-authored PRs",
|
|
21095
|
-
|
|
21517
|
+
` (those carrying ${DELEGATION_ELIGIBLE_ORIGIN_LIST}). When absent, the`,
|
|
21096
21518
|
" reviewer only processes bot-authored PRs; when present, human-authored",
|
|
21097
21519
|
" PRs are also eligible for this invocation only. The flag does **not**",
|
|
21098
21520
|
" persist across invocations.",
|
|
21099
21521
|
"",
|
|
21100
21522
|
"Phase 4's invocation guard enforces the bot-only default and the",
|
|
21101
|
-
"`--allow-human-author` opt-out. PRs
|
|
21102
|
-
"
|
|
21523
|
+
"`--allow-human-author` opt-out. PRs carrying **no** origin label are",
|
|
21524
|
+
"still classified, commented on, reacted to, and (in",
|
|
21103
21525
|
"`auto-merge` mode) auto-merged when the AC/CI checks pass \u2014 only the",
|
|
21104
21526
|
"delegation hand-off to `issue-worker` is gated.",
|
|
21105
21527
|
"",
|
|
@@ -21252,8 +21674,32 @@ var prReviewerSubAgent = {
|
|
|
21252
21674
|
" resolve CI via the **CI Verification** section's Actions-runs",
|
|
21253
21675
|
" fallback before deciding eligibility \u2014 do **not** treat the 403 as",
|
|
21254
21676
|
" either a pass or an automatic disqualification.",
|
|
21255
|
-
"3. The PR body contains
|
|
21256
|
-
" `Closes #N`, `Fixes #N`,
|
|
21677
|
+
"3. The PR body contains at least one linked issue via a closing",
|
|
21678
|
+
" keyword (`Closes #N`, `Fixes #N`, `Resolves #N`, case-insensitive).",
|
|
21679
|
+
" Resolve this mechanically \u2014 do **not** eyeball the body:",
|
|
21680
|
+
"",
|
|
21681
|
+
"```bash",
|
|
21682
|
+
".claude/procedures/check-closing-keywords.sh <pr-number>",
|
|
21683
|
+
"```",
|
|
21684
|
+
"",
|
|
21685
|
+
" The procedure is the single source of truth for closing-keyword",
|
|
21686
|
+
" parsing in this pipeline. It emits one `CLOSES #<n> line=<L>` line",
|
|
21687
|
+
" per reference GitHub will honour, one",
|
|
21688
|
+
" `STRANDED #<n> line=<L> keyword=<kw> first=#<n>` line per reference",
|
|
21689
|
+
" GitHub will silently ignore, then a summary line. It skips fenced",
|
|
21690
|
+
" code blocks, blockquotes, and inline code spans, so a body that",
|
|
21691
|
+
" merely discusses closing keywords does not confuse it.",
|
|
21692
|
+
"",
|
|
21693
|
+
" - Exit `5` / `NO_CLOSING_KEYWORD` \u2014 check (3) **fails**; the PR has",
|
|
21694
|
+
" no linked issue.",
|
|
21695
|
+
" - Exit `0` / `CLOSING_KEYWORDS_OK` \u2014 check (3) passes. Record the",
|
|
21696
|
+
" `CLOSES` set as the **linked-issue set** for the rest of the pass.",
|
|
21697
|
+
" - Exit `1` / `CLOSING_KEYWORDS_MALFORMED` \u2014 check (3) **passes**",
|
|
21698
|
+
" (there is a linked issue), but the body would strand every",
|
|
21699
|
+
" `STRANDED` issue. This is **not** an eligibility rejection \u2014 the",
|
|
21700
|
+
" code is not at fault. Record both the `CLOSES` and `STRANDED`",
|
|
21701
|
+
" sets as the linked-issue set and carry the malformed finding into",
|
|
21702
|
+
" Phase 4 and Phase 5.",
|
|
21257
21703
|
"",
|
|
21258
21704
|
"If the **CI** check (2) or the **linked-issue** check (3) fails, post",
|
|
21259
21705
|
"a short comment explaining the reason and stop. Do not proceed to",
|
|
@@ -21321,16 +21767,29 @@ var prReviewerSubAgent = {
|
|
|
21321
21767
|
"gh pr checks <pr-number>",
|
|
21322
21768
|
"```",
|
|
21323
21769
|
"",
|
|
21324
|
-
"
|
|
21325
|
-
"
|
|
21770
|
+
"Use the **linked-issue set** already computed in Phase 1.5 \u2014 the union",
|
|
21771
|
+
"of the `CLOSES` and `STRANDED` issue numbers the",
|
|
21772
|
+
"`check-closing-keywords.sh` run reported. Do not re-derive it by",
|
|
21773
|
+
"reading the body yourself.",
|
|
21774
|
+
"",
|
|
21775
|
+
"Most PRs link exactly one issue, and every phase below reads naturally",
|
|
21776
|
+
"in the singular. When the set has more than one member, treat **every**",
|
|
21777
|
+
"member as a linked issue: fetch each one, union their acceptance",
|
|
21778
|
+
"criteria in Phase 3, and close each one in Phase 5. The **primary**",
|
|
21779
|
+
"linked issue \u2014 the one cited in the sticky summary and the structured",
|
|
21780
|
+
"report \u2014 is the first `CLOSES` entry.",
|
|
21326
21781
|
"",
|
|
21327
|
-
"Then fetch
|
|
21328
|
-
"evaluate the issue-type portion of the review policy:",
|
|
21782
|
+
"Then fetch each linked issue, including its `issueType` so Phase 2.75",
|
|
21783
|
+
"can evaluate the issue-type portion of the review policy:",
|
|
21329
21784
|
"",
|
|
21330
21785
|
"```bash",
|
|
21331
21786
|
"gh issue view <issue-number> --json number,title,body,labels,state,issueType",
|
|
21332
21787
|
"```",
|
|
21333
21788
|
"",
|
|
21789
|
+
"When several issues are linked, Phase 2.75's issue-type rule matches if",
|
|
21790
|
+
"**any** linked issue's type is in `human-required.issue-types` \u2014 the",
|
|
21791
|
+
"conservative reading, consistent with the policy's mixed-signal rule.",
|
|
21792
|
+
"",
|
|
21334
21793
|
"## Phase 2.5: Gather Comments",
|
|
21335
21794
|
"",
|
|
21336
21795
|
"Before deciding review mode, collect every human comment on the PR so",
|
|
@@ -21628,6 +22087,14 @@ var prReviewerSubAgent = {
|
|
|
21628
22087
|
"",
|
|
21629
22088
|
"- **Convention compliance** \u2014 PR title uses a conventional commit prefix,",
|
|
21630
22089
|
" body includes a closing keyword, branch name follows project conventions",
|
|
22090
|
+
"- **Closing-keyword integrity** \u2014 the Phase 1.5",
|
|
22091
|
+
" `check-closing-keywords.sh` run exited `0`. A",
|
|
22092
|
+
" `CLOSING_KEYWORDS_MALFORMED` result is a **Suggested** finding (not",
|
|
22093
|
+
" blocking): the diff is unaffected, and Phase 5 closes the stranded",
|
|
22094
|
+
" issues deterministically, so gating the merge on it would wedge a",
|
|
22095
|
+
" correct PR over a body typo. Record every `STRANDED #<n>` in the",
|
|
22096
|
+
" findings and in the sticky summary so the malformed body is visible",
|
|
22097
|
+
" rather than silent.",
|
|
21631
22098
|
"- **Test coverage** \u2014 new or changed behavior has tests",
|
|
21632
22099
|
"- **CI status** \u2014 resolve CI via the **CI Verification** section",
|
|
21633
22100
|
" (primary check-runs read, with the Actions-runs fallback on a",
|
|
@@ -21785,12 +22252,17 @@ var prReviewerSubAgent = {
|
|
|
21785
22252
|
"Before delegating any in-scope fix to `issue-worker`, verify the",
|
|
21786
22253
|
"delegation is permitted by author identity:",
|
|
21787
22254
|
"",
|
|
21788
|
-
|
|
21789
|
-
|
|
22255
|
+
`- If the PR carries the \`${ORIGIN_ISSUE_WORKER_LABEL}\` label **or** the`,
|
|
22256
|
+
` \`${ORIGIN_AGENT_LABEL}\` label, delegation is permitted. Both are`,
|
|
22257
|
+
" agent-origin labels and both are delegation-eligible:",
|
|
22258
|
+
` \`${ORIGIN_ISSUE_WORKER_LABEL}\` marks a PR opened by the \`issue-worker\``,
|
|
22259
|
+
` agent specifically; \`${ORIGIN_AGENT_LABEL}\` is the umbrella label the`,
|
|
22260
|
+
" phased analyst/writer family stamps on the PRs it opens. Treat them",
|
|
22261
|
+
" identically for this guard \u2014 neither requires `--allow-human-author`.",
|
|
21790
22262
|
"- If the invocation prompt contains the literal flag",
|
|
21791
22263
|
" `--allow-human-author`, delegation is permitted for this invocation",
|
|
21792
22264
|
" only.",
|
|
21793
|
-
"- Otherwise (
|
|
22265
|
+
"- Otherwise (no agent-origin label and no opt-in flag) the reviewer",
|
|
21794
22266
|
" **must not delegate**. It still classifies comments (Phase 3.5),",
|
|
21795
22267
|
" posts replies, applies reactions, updates the sticky summary, and",
|
|
21796
22268
|
" (when in `auto-merge` mode and the AC/CI checks pass) enables",
|
|
@@ -21990,7 +22462,38 @@ var prReviewerSubAgent = {
|
|
|
21990
22462
|
"",
|
|
21991
22463
|
"### If all acceptance criteria are met and CI is green",
|
|
21992
22464
|
"",
|
|
21993
|
-
"
|
|
22465
|
+
"#### Pre-merge closing-keyword check",
|
|
22466
|
+
"",
|
|
22467
|
+
"Run this **before** branching on the review mode \u2014 it applies in both",
|
|
22468
|
+
"modes and is the last cheap moment to catch a body that would strand",
|
|
22469
|
+
"issues on merge:",
|
|
22470
|
+
"",
|
|
22471
|
+
"```bash",
|
|
22472
|
+
".claude/procedures/check-closing-keywords.sh <pr-number>",
|
|
22473
|
+
"```",
|
|
22474
|
+
"",
|
|
22475
|
+
"Re-run it here rather than reusing the Phase 1.5 result: the body may",
|
|
22476
|
+
"have been edited since, and the merge is about to make the answer",
|
|
22477
|
+
"permanent.",
|
|
22478
|
+
"",
|
|
22479
|
+
"- **Exit `0`** \u2014 nothing to do; every linked issue will auto-close.",
|
|
22480
|
+
"- **Exit `1`** \u2014 the body strands at least one issue. Do **not** block",
|
|
22481
|
+
" the merge; post one comment naming the stranded issues and the",
|
|
22482
|
+
" corrected block, then continue. Phase 5 closes the survivors",
|
|
22483
|
+
" explicitly, so the malformed body costs a comment, not a wedged PR.",
|
|
22484
|
+
"",
|
|
22485
|
+
"```bash",
|
|
22486
|
+
"gh pr comment <pr-number> --body 'GitHub honours only one issue reference per closing keyword, so this body would close #<first> and silently leave #<stranded\u2026> open. Give each issue its own keyword, one per line:",
|
|
22487
|
+
"",
|
|
22488
|
+
"Closes #<first>",
|
|
22489
|
+
"Closes #<stranded>",
|
|
22490
|
+
"",
|
|
22491
|
+
"Merging anyway \u2014 Phase 5 will close the stranded issues explicitly.'",
|
|
22492
|
+
"```",
|
|
22493
|
+
"",
|
|
22494
|
+
"Carry the full stranded set into Phase 5 verbatim.",
|
|
22495
|
+
"",
|
|
22496
|
+
"Then branch on the **review mode** decided in Phase 2.75:",
|
|
21994
22497
|
"",
|
|
21995
22498
|
"#### Mode `auto-merge`",
|
|
21996
22499
|
"",
|
|
@@ -22178,6 +22681,7 @@ var prReviewerSubAgent = {
|
|
|
22178
22681
|
"**Outstanding:** <list of comments still open with their classification and author>",
|
|
22179
22682
|
"**Pushbacks:** <list of disputes with reasons>",
|
|
22180
22683
|
"**Label reconciliation:** <consistent | corrections applied this pass>",
|
|
22684
|
+
"**Closing keywords:** ok | malformed \u2014 strands #<n>[, #<n>\u2026]",
|
|
22181
22685
|
"**Last pass:** <ISO timestamp>",
|
|
22182
22686
|
"```",
|
|
22183
22687
|
"",
|
|
@@ -22202,6 +22706,11 @@ var prReviewerSubAgent = {
|
|
|
22202
22706
|
" the corrections applied this pass (the detected violation combo,",
|
|
22203
22707
|
" the label(s) removed, and the resulting self-consistent set).",
|
|
22204
22708
|
" Every reconciliation correction is recorded here for auditability.",
|
|
22709
|
+
"- **Closing keywords** \u2014 the",
|
|
22710
|
+
" `.claude/procedures/check-closing-keywords.sh` verdict: `ok`, or",
|
|
22711
|
+
" `malformed` plus every `STRANDED #<n>` the body would leave open.",
|
|
22712
|
+
" Recorded on every pass so a body that strands issues is visible to a",
|
|
22713
|
+
" human before the merge, not only after Phase 5 repairs it.",
|
|
22205
22714
|
"- **Last pass** \u2014 the ISO 8601 timestamp of this run.",
|
|
22206
22715
|
"",
|
|
22207
22716
|
"### Step 3: Create or edit in place",
|
|
@@ -22285,9 +22794,11 @@ var prReviewerSubAgent = {
|
|
|
22285
22794
|
" reviewed diff than the clean merge-commit `gh pr update-branch`",
|
|
22286
22795
|
" performs on a no-conflict branch.)",
|
|
22287
22796
|
"2. **Delegation invocation guard permits the hand-off** \u2014 the PR",
|
|
22288
|
-
|
|
22797
|
+
` carries the \`${ORIGIN_ISSUE_WORKER_LABEL}\` label or the`,
|
|
22798
|
+
` \`${ORIGIN_AGENT_LABEL}\` label, **or** the reviewer was`,
|
|
22289
22799
|
" invoked with `--allow-human-author`. The same guard used for the",
|
|
22290
|
-
" in-scope-fix delegation flow applies here unchanged
|
|
22800
|
+
" in-scope-fix delegation flow applies here unchanged \u2014 both",
|
|
22801
|
+
" agent-origin labels are delegation-eligible.",
|
|
22291
22802
|
"3. **The `review:fixing` lease is currently free.** If",
|
|
22292
22803
|
" `review:fixing` is already on the PR, another delegation is",
|
|
22293
22804
|
" in-flight; skip conflict-resolution delegation, log the contention",
|
|
@@ -22586,42 +23097,64 @@ var prReviewerSubAgent = {
|
|
|
22586
23097
|
"gh pr view <pr-number> --json state --jq '.state'",
|
|
22587
23098
|
"```",
|
|
22588
23099
|
"",
|
|
22589
|
-
"- **`MERGED`** \u2014 clean up locally **and** verify
|
|
23100
|
+
"- **`MERGED`** \u2014 clean up locally **and** verify **every** linked issue",
|
|
23101
|
+
" closed:",
|
|
22590
23102
|
" ```bash",
|
|
22591
23103
|
" git checkout {{repository.defaultBranch}}",
|
|
22592
23104
|
" git pull origin {{repository.defaultBranch}}",
|
|
22593
23105
|
" git fetch --prune origin",
|
|
22594
23106
|
" git branch -d <branch-name> 2>/dev/null || git branch -D <branch-name> 2>/dev/null || true",
|
|
22595
23107
|
" ```",
|
|
22596
|
-
"
|
|
22597
|
-
"
|
|
23108
|
+
"",
|
|
23109
|
+
" **Post-merge closure verification.** Iterate the **full linked-issue",
|
|
23110
|
+
" set** from Phase 1.5 \u2014 the union of the `CLOSES` and `STRANDED`",
|
|
23111
|
+
" numbers `check-closing-keywords.sh` reported \u2014 not just the primary",
|
|
23112
|
+
" issue. This loop is the structural guard against the stranded-issue",
|
|
23113
|
+
" defect class: GitHub honours only one issue reference per closing",
|
|
23114
|
+
" keyword, so a body written as `Closes #A, #B` closes `#A` and leaves",
|
|
23115
|
+
" `#B` open forever with no signal anywhere. Because the reviewer",
|
|
23116
|
+
" already knows the full set, every survivor is closed here",
|
|
23117
|
+
" deterministically instead of being discovered months later by an",
|
|
23118
|
+
" audit.",
|
|
23119
|
+
"",
|
|
23120
|
+
" For **each** issue in the set, in order:",
|
|
23121
|
+
"",
|
|
23122
|
+
" 1. Transition it to `status:done` (replaces whichever of",
|
|
23123
|
+
" `status:ready-for-review` or `status:in-progress` it was carrying):",
|
|
22598
23124
|
" ```bash",
|
|
22599
23125
|
" gh issue edit <issue-number> \\",
|
|
22600
23126
|
' --remove-label "status:ready-for-review" \\',
|
|
22601
23127
|
' --remove-label "status:in-progress" \\',
|
|
22602
23128
|
' --add-label "status:done"',
|
|
22603
23129
|
" ```",
|
|
22604
|
-
"
|
|
23130
|
+
" 2. Check its state:",
|
|
22605
23131
|
" ```bash",
|
|
22606
23132
|
" gh issue view <issue-number> --json state --jq '.state'",
|
|
22607
23133
|
" ```",
|
|
22608
|
-
" If the issue is **not** `CLOSED`, close it explicitly (this covers",
|
|
22609
|
-
"
|
|
23134
|
+
" 3. If the issue is **not** `CLOSED`, close it explicitly (this covers",
|
|
23135
|
+
" both a missing closing keyword and an issue stranded by a",
|
|
23136
|
+
" multi-issue keyword):",
|
|
22610
23137
|
" ```bash",
|
|
22611
23138
|
" gh issue close <issue-number> --reason completed",
|
|
22612
23139
|
" gh issue comment <issue-number> --body 'PR #<pr-number> merged. Closing issue.'",
|
|
22613
23140
|
" ```",
|
|
22614
|
-
" Once `status:done` is applied (either via the edit above or the",
|
|
22615
|
-
"
|
|
22616
|
-
"
|
|
22617
|
-
"
|
|
23141
|
+
" 4. Once `status:done` is applied (either via the edit above or the",
|
|
23142
|
+
" explicit close path), run the targeted unblock sweep so any",
|
|
23143
|
+
" dependents waiting on this issue flip from `status:blocked` to",
|
|
23144
|
+
" `status:ready` immediately:",
|
|
22618
23145
|
" ```bash",
|
|
22619
23146
|
" .claude/procedures/unblock-dependents.sh <issue-number>",
|
|
22620
23147
|
" ```",
|
|
23148
|
+
"",
|
|
22621
23149
|
" Log the sweep's output (one line per processed dependent:",
|
|
22622
23150
|
" `UNBLOCKED #<n>` / `STILL_BLOCKED #<n>` / `NO_DEPENDENTS #<m>`)",
|
|
22623
23151
|
" in the PR review summary. See the **Agent-driven unblocking**",
|
|
22624
23152
|
" section in `CLAUDE.md` for the full contract.",
|
|
23153
|
+
"",
|
|
23154
|
+
" Report one `Issue #<n>: <closed-by-github | closed-explicitly>` line",
|
|
23155
|
+
" per member of the set. Any issue that needed the explicit close was",
|
|
23156
|
+
" stranded by the PR body \u2014 say so in the summary so the authoring",
|
|
23157
|
+
" defect is visible, not just repaired.",
|
|
22625
23158
|
"- **`CLOSED` (not merged)** \u2014 leave the branch in place; report the closure.",
|
|
22626
23159
|
"- **Still `OPEN`** \u2014 auto-merge is pending; report and stop without deleting.",
|
|
22627
23160
|
"",
|
|
@@ -22634,6 +23167,8 @@ var prReviewerSubAgent = {
|
|
|
22634
23167
|
"```",
|
|
22635
23168
|
"PR #<number> \u2014 <title>",
|
|
22636
23169
|
"Linked issue: #<issue-number>",
|
|
23170
|
+
"Linked issue set: #<n> [, #<n>\u2026] (from check-closing-keywords.sh)",
|
|
23171
|
+
"Closing keywords: <ok | malformed: strands #<n>[, #<n>\u2026]>",
|
|
22637
23172
|
"Review mode: <auto-merge | human-required>",
|
|
22638
23173
|
"Reason: <short explanation from Phase 2.75>",
|
|
22639
23174
|
"Verdict: AUTO_MERGE_ENABLED | AWAITING_HUMAN | DELEGATED_TO_WORKER | NEEDS_CHANGES | INELIGIBLE | BLOCKED",
|
|
@@ -22674,6 +23209,14 @@ var prReviewerSubAgent = {
|
|
|
22674
23209
|
" PR in turn.",
|
|
22675
23210
|
"2. **Never merge without a linked issue.** If the PR body has no",
|
|
22676
23211
|
" `Closes #N` / `Fixes #N` / `Resolves #N`, comment and stop.",
|
|
23212
|
+
"2a. **Never merge without verifying every linked issue closes.** Resolve",
|
|
23213
|
+
" the linked-issue set with",
|
|
23214
|
+
" `.claude/procedures/check-closing-keywords.sh <pr-number>`, never by",
|
|
23215
|
+
" eyeballing the body. GitHub honours only one issue reference per",
|
|
23216
|
+
" closing keyword, so a `STRANDED` line means that issue will stay",
|
|
23217
|
+
" open after the merge unless Phase 5 closes it. Phase 5 must iterate",
|
|
23218
|
+
" the **whole** set \u2014 `CLOSES` plus `STRANDED` \u2014 and explicitly close",
|
|
23219
|
+
" every issue GitHub left open.",
|
|
22677
23220
|
"3. **Never merge with failing CI.** Even if every criterion is met,",
|
|
22678
23221
|
" block on red checks. Resolve CI status via the **CI",
|
|
22679
23222
|
" Verification** section: read check-runs first, and only on a",
|
|
@@ -22686,7 +23229,7 @@ var prReviewerSubAgent = {
|
|
|
22686
23229
|
" to `human-required`, Phase 4 applies `review:awaiting-human` and",
|
|
22687
23230
|
" exits. Even if every acceptance criterion is met and CI is green,",
|
|
22688
23231
|
" `gh pr merge --auto` is forbidden in that mode.",
|
|
22689
|
-
|
|
23232
|
+
`6. **Never push commits to the PR's branch yourself.** The reviewer is a decision-maker and orchestrator, not an implementer. When in-scope review comments require code changes **and** the PR carries ${DELEGATION_ELIGIBLE_ORIGIN_PHRASE} (or the invocation prompt explicitly allows human-authored PRs via \`--allow-human-author\`), delegate the fix **by marker, not by spawn**: post a fix-list comment on the PR, apply the \`review:needs-worker\` label, hold the \`review:fixing\` lease, and exit returning \`delegated\`. Do **not** invoke \`issue-worker\` via the \`Agent\` tool \u2014 the reviewer often runs at depth-1 where nested sub-agent spawning is forbidden, so an in-session dispatch would silently abort. A top-level \`issue-worker\` session pulls the marker and applies the fix; a later reviewer confirm pass releases the lease. You must never call \`git commit\`, \`git push\`, \`git rebase\`, or \`gh pr edit\` against the head branch from this agent \u2014 all branch mutations belong to \`issue-worker\`.`,
|
|
22690
23233
|
"7. **Do not implement code.** You review, decide, and orchestrate. If",
|
|
22691
23234
|
" the PR needs code changes and delegation is not permitted by Rule",
|
|
22692
23235
|
" #6, comment and stop \u2014 do not attempt to fix it yourself.",
|
|
@@ -22786,8 +23329,8 @@ var reviewPrSkill = {
|
|
|
22786
23329
|
"",
|
|
22787
23330
|
"- **`--allow-human-author`** \u2014 opt the reviewer into processing",
|
|
22788
23331
|
" human-authored PRs for **this invocation only**. By default, the",
|
|
22789
|
-
" reviewer only processes bot-authored PRs (those carrying
|
|
22790
|
-
|
|
23332
|
+
" reviewer only processes bot-authored PRs (those carrying",
|
|
23333
|
+
` ${DELEGATION_ELIGIBLE_ORIGIN_LIST}); pass this flag to review a`,
|
|
22791
23334
|
" human-authored PR. The flag does not persist \u2014 subsequent",
|
|
22792
23335
|
" invocations return to the bot-only default.",
|
|
22793
23336
|
"",
|
|
@@ -22806,7 +23349,7 @@ var reviewPrSkill = {
|
|
|
22806
23349
|
"",
|
|
22807
23350
|
"Passing `--allow-human-author` opts the reviewer into processing",
|
|
22808
23351
|
"human-authored PRs for this invocation only (the default scope is",
|
|
22809
|
-
|
|
23352
|
+
`bot-authored PRs carrying ${DELEGATION_ELIGIBLE_ORIGIN_LIST}).`,
|
|
22810
23353
|
"",
|
|
22811
23354
|
"## Input",
|
|
22812
23355
|
"",
|
|
@@ -22848,8 +23391,8 @@ var reviewPrsSkill = {
|
|
|
22848
23391
|
"",
|
|
22849
23392
|
"- **`--allow-human-author`** \u2014 opt the reviewer into processing",
|
|
22850
23393
|
" human-authored PRs for **this invocation only**. By default, the",
|
|
22851
|
-
" loop only processes bot-authored PRs (those carrying
|
|
22852
|
-
|
|
23394
|
+
" loop only processes bot-authored PRs (those carrying",
|
|
23395
|
+
` ${DELEGATION_ELIGIBLE_ORIGIN_LIST}); pass this flag to include`,
|
|
22853
23396
|
" human-authored PRs in the queue. The flag does not persist \u2014",
|
|
22854
23397
|
" subsequent invocations return to the bot-only default.",
|
|
22855
23398
|
"",
|
|
@@ -22901,7 +23444,7 @@ var reviewPrsSkill = {
|
|
|
22901
23444
|
"",
|
|
22902
23445
|
"Passing `--allow-human-author` opts the reviewer into including",
|
|
22903
23446
|
"human-authored PRs in the queue for this invocation only (the default",
|
|
22904
|
-
|
|
23447
|
+
`scope is bot-authored PRs carrying ${DELEGATION_ELIGIBLE_ORIGIN_LIST}).`,
|
|
22905
23448
|
"",
|
|
22906
23449
|
"## Output",
|
|
22907
23450
|
"",
|
|
@@ -23547,7 +24090,7 @@ function buildPrReviewBundle(policy = resolvePrReviewPolicy()) {
|
|
|
23547
24090
|
"",
|
|
23548
24091
|
"### Label Glossary",
|
|
23549
24092
|
"",
|
|
23550
|
-
"
|
|
24093
|
+
"Seven review-workflow labels drive the feedback loop. They are",
|
|
23551
24094
|
"**contributed by the pr-review bundle's label set** and auto-sync",
|
|
23552
24095
|
"into every consumer's label registry \u2014 the same way the",
|
|
23553
24096
|
"`type:*` / `priority:*` / `status:*` taxonomy ships. Consumers do",
|
|
@@ -23557,7 +24100,8 @@ function buildPrReviewBundle(policy = resolvePrReviewPolicy()) {
|
|
|
23557
24100
|
"",
|
|
23558
24101
|
"| Label | Purpose |",
|
|
23559
24102
|
"|-------|---------|",
|
|
23560
|
-
|
|
24103
|
+
`| \`${ORIGIN_ISSUE_WORKER_LABEL}\` | PR was opened by the \`issue-worker\` agent specifically. Eligible for auto-delegation of in-scope fixes. |`,
|
|
24104
|
+
`| \`${ORIGIN_AGENT_LABEL}\` | **Umbrella origin label for agent-opened PRs.** Stamped by every phased analyst/writer agent (people-profile, company-profile, software-profile, customer-profile, bcm-writer, industry-discovery, business-models, standards-research, regulatory-research, maintenance-audit, meeting-analysis, agenda, research-pipeline, requirements-analyst, requirements-reviewer, requirements-writer) on the PRs it opens. Delegation-eligible on exactly the same terms as \`${ORIGIN_ISSUE_WORKER_LABEL}\` \u2014 the analyst family stamps this instead of \`${ORIGIN_ISSUE_WORKER_LABEL}\` because claiming the latter on a non-worker PR would be false. Human-authored PRs carry neither origin label and will not trigger delegation unless the reviewer is invoked with \`--allow-human-author\`. This label gates fix-**delegation** only; sweep and auto-merge eligibility have never been origin-gated. |`,
|
|
23561
24105
|
"| `review:human-required` | Force human review regardless of what the policy would otherwise decide. The reviewer never enables auto-merge on a PR carrying this label. |",
|
|
23562
24106
|
"| `review:auto-ok` | Force auto-merge regardless of what the policy would otherwise decide. **Also resolves outstanding `thinking_face` pushbacks** as an explicit maintainer override; the reviewer logs the override in the sticky summary. |",
|
|
23563
24107
|
"| `review:awaiting-human` | Set by the reviewer when it completes its work on a `human-required` PR and is handing off the final merge decision. Cleared by a human (or by `review:auto-ok` flipping the PR back to `auto-merge` mode). |",
|
|
@@ -23567,8 +24111,8 @@ function buildPrReviewBundle(policy = resolvePrReviewPolicy()) {
|
|
|
23567
24111
|
"### Reviewing Human-Authored PRs: the `--allow-human-author` Flag",
|
|
23568
24112
|
"",
|
|
23569
24113
|
"By default the reviewer only **delegates** in-scope fixes on",
|
|
23570
|
-
|
|
23571
|
-
"
|
|
24114
|
+
`bot-authored PRs \u2014 those carrying ${DELEGATION_ELIGIBLE_ORIGIN_PHRASE}.`,
|
|
24115
|
+
"Running `/review-pr <n>` or `/review-prs` on a",
|
|
23572
24116
|
"human-authored PR still produces a full review (reactions,",
|
|
23573
24117
|
"replies, sticky summary, and auto-merge when the policy allows",
|
|
23574
24118
|
"it) but skips the delegation hand-off to `issue-worker` \u2014 the",
|
|
@@ -23602,10 +24146,15 @@ function buildPrReviewBundle(policy = resolvePrReviewPolicy()) {
|
|
|
23602
24146
|
description: "PR review tasks"
|
|
23603
24147
|
},
|
|
23604
24148
|
{
|
|
23605
|
-
name:
|
|
24149
|
+
name: ORIGIN_ISSUE_WORKER_LABEL,
|
|
23606
24150
|
color: "5319E7",
|
|
23607
24151
|
description: "PR opened by the issue-worker agent"
|
|
23608
24152
|
},
|
|
24153
|
+
{
|
|
24154
|
+
name: ORIGIN_AGENT_LABEL,
|
|
24155
|
+
color: "5319E7",
|
|
24156
|
+
description: "PR opened by an agent in this project's pipeline; eligible for autonomous fix delegation"
|
|
24157
|
+
},
|
|
23609
24158
|
{
|
|
23610
24159
|
name: "review:auto-ok",
|
|
23611
24160
|
color: "0E8A16",
|
|
@@ -24257,6 +24806,8 @@ function buildRegulatoryResearchAnalystSubAgent(paths, issueDefaults) {
|
|
|
24257
24806
|
" label.",
|
|
24258
24807
|
"4. Commit, push, open a PR (if applicable), and close the issue per",
|
|
24259
24808
|
" your project's PR workflow.",
|
|
24809
|
+
" Stamp every PR you open with the `origin:agent` label \u2014 see the",
|
|
24810
|
+
" **Origin label** section below.",
|
|
24260
24811
|
"",
|
|
24261
24812
|
"---",
|
|
24262
24813
|
"",
|
|
@@ -24264,6 +24815,10 @@ function buildRegulatoryResearchAnalystSubAgent(paths, issueDefaults) {
|
|
|
24264
24815
|
"",
|
|
24265
24816
|
"---",
|
|
24266
24817
|
"",
|
|
24818
|
+
...renderOriginStampSection(),
|
|
24819
|
+
"",
|
|
24820
|
+
"---",
|
|
24821
|
+
"",
|
|
24267
24822
|
"## Phase 1: Scan (`regulatory:scan`)",
|
|
24268
24823
|
"",
|
|
24269
24824
|
"**Goal:** Enumerate regulations applicable to a given scope \u2014",
|
|
@@ -27464,6 +28019,8 @@ function buildRequirementsWriterSubAgent(paths) {
|
|
|
27464
28019
|
"4. Commit, push, open a PR, and close the issue per your project's",
|
|
27465
28020
|
" PR workflow. Closing the PR transitions the issue to",
|
|
27466
28021
|
" `status:done` per the standard label conventions.",
|
|
28022
|
+
" Stamp every PR you open with the `origin:agent` label \u2014 see the",
|
|
28023
|
+
" **Origin label** section below.",
|
|
27467
28024
|
"",
|
|
27468
28025
|
"---",
|
|
27469
28026
|
"",
|
|
@@ -27471,6 +28028,10 @@ function buildRequirementsWriterSubAgent(paths) {
|
|
|
27471
28028
|
"",
|
|
27472
28029
|
"---",
|
|
27473
28030
|
"",
|
|
28031
|
+
...renderOriginStampSection(),
|
|
28032
|
+
"",
|
|
28033
|
+
"---",
|
|
28034
|
+
"",
|
|
27474
28035
|
"## The `req:write` Issue Schema",
|
|
27475
28036
|
"",
|
|
27476
28037
|
"This section is the **authoritative schema** for `req:write` issue",
|
|
@@ -28106,6 +28667,8 @@ function buildRequirementsAnalystSubAgent(paths, issueDefaults) {
|
|
|
28106
28667
|
"3. Execute the phase handler that matches the issue's `req:*` label.",
|
|
28107
28668
|
"4. Commit, push, open a PR (if applicable), and close the issue per your",
|
|
28108
28669
|
" project's PR workflow.",
|
|
28670
|
+
" Stamp every PR you open with the `origin:agent` label \u2014 see the",
|
|
28671
|
+
" **Origin label** section below.",
|
|
28109
28672
|
"",
|
|
28110
28673
|
"---",
|
|
28111
28674
|
"",
|
|
@@ -28113,6 +28676,10 @@ function buildRequirementsAnalystSubAgent(paths, issueDefaults) {
|
|
|
28113
28676
|
"",
|
|
28114
28677
|
"---",
|
|
28115
28678
|
"",
|
|
28679
|
+
...renderOriginStampSection(),
|
|
28680
|
+
"",
|
|
28681
|
+
"---",
|
|
28682
|
+
"",
|
|
28116
28683
|
"## Phase 1: Scan (`req:scan`)",
|
|
28117
28684
|
"",
|
|
28118
28685
|
"**Goal:** Read source documents, identify where requirements are missing,",
|
|
@@ -28709,6 +29276,10 @@ function buildRequirementsReviewerSubAgent(paths, issueDefaults) {
|
|
|
28709
29276
|
"",
|
|
28710
29277
|
"---",
|
|
28711
29278
|
"",
|
|
29279
|
+
...renderOriginStampSection(),
|
|
29280
|
+
"",
|
|
29281
|
+
"---",
|
|
29282
|
+
"",
|
|
28712
29283
|
"## Phase Router",
|
|
28713
29284
|
"",
|
|
28714
29285
|
"Before reading any documents, classify the session by reading the",
|
|
@@ -30088,6 +30659,8 @@ function buildResearchAnalystSubAgent(paths) {
|
|
|
30088
30659
|
" label.",
|
|
30089
30660
|
"4. Commit, push, open a PR (if applicable), and close the issue per",
|
|
30090
30661
|
" your project's PR workflow.",
|
|
30662
|
+
" Stamp every PR you open with the `origin:agent` label \u2014 see the",
|
|
30663
|
+
" **Origin label** section below.",
|
|
30091
30664
|
"",
|
|
30092
30665
|
"---",
|
|
30093
30666
|
"",
|
|
@@ -30095,6 +30668,10 @@ function buildResearchAnalystSubAgent(paths) {
|
|
|
30095
30668
|
"",
|
|
30096
30669
|
"---",
|
|
30097
30670
|
"",
|
|
30671
|
+
...renderOriginStampSection(),
|
|
30672
|
+
"",
|
|
30673
|
+
"---",
|
|
30674
|
+
"",
|
|
30098
30675
|
"## Phase 1: Scope (`research:scope`)",
|
|
30099
30676
|
"",
|
|
30100
30677
|
"**Goal:** Turn a natural-language research question into a bounded",
|
|
@@ -30833,6 +31410,8 @@ function buildSoftwareProfileAnalystSubAgent(paths, issueDefaults, tier) {
|
|
|
30833
31410
|
" label.",
|
|
30834
31411
|
"4. Commit, push, open a PR (if applicable), and close the issue per",
|
|
30835
31412
|
" your project's PR workflow.",
|
|
31413
|
+
" Stamp every PR you open with the `origin:agent` label \u2014 see the",
|
|
31414
|
+
" **Origin label** section below.",
|
|
30836
31415
|
"",
|
|
30837
31416
|
"---",
|
|
30838
31417
|
"",
|
|
@@ -30840,6 +31419,10 @@ function buildSoftwareProfileAnalystSubAgent(paths, issueDefaults, tier) {
|
|
|
30840
31419
|
"",
|
|
30841
31420
|
"---",
|
|
30842
31421
|
"",
|
|
31422
|
+
...renderOriginStampSection(),
|
|
31423
|
+
"",
|
|
31424
|
+
"---",
|
|
31425
|
+
"",
|
|
30843
31426
|
"## Phase 1: Research (`software:research`)",
|
|
30844
31427
|
"",
|
|
30845
31428
|
"**Goal:** Gather public sources into a bounded research-notes file.",
|
|
@@ -31971,6 +32554,8 @@ function buildStandardsResearchAnalystSubAgent(paths, issueDefaults) {
|
|
|
31971
32554
|
" label.",
|
|
31972
32555
|
"4. Commit, push, open a PR (if applicable), and close the issue per",
|
|
31973
32556
|
" your project's PR workflow.",
|
|
32557
|
+
" Stamp every PR you open with the `origin:agent` label \u2014 see the",
|
|
32558
|
+
" **Origin label** section below.",
|
|
31974
32559
|
"",
|
|
31975
32560
|
"---",
|
|
31976
32561
|
"",
|
|
@@ -31978,6 +32563,10 @@ function buildStandardsResearchAnalystSubAgent(paths, issueDefaults) {
|
|
|
31978
32563
|
"",
|
|
31979
32564
|
"---",
|
|
31980
32565
|
"",
|
|
32566
|
+
...renderOriginStampSection(),
|
|
32567
|
+
"",
|
|
32568
|
+
"---",
|
|
32569
|
+
"",
|
|
31981
32570
|
"## Phase 1: Scope (`standards:scope`)",
|
|
31982
32571
|
"",
|
|
31983
32572
|
"**Goal:** Plan the research campaign for a standard \u2014 identify which",
|
|
@@ -42332,6 +42921,7 @@ export const collections = {
|
|
|
42332
42921
|
buildUnblockDependentsProcedure,
|
|
42333
42922
|
bundleNameForWorkflowRule,
|
|
42334
42923
|
businessModelsBundle,
|
|
42924
|
+
checkClosingKeywordsProcedure,
|
|
42335
42925
|
checkDocSamplesProcedure,
|
|
42336
42926
|
checkLinksProcedure,
|
|
42337
42927
|
classifyIssueScope,
|
|
@@ -42406,6 +42996,7 @@ export const collections = {
|
|
|
42406
42996
|
renderCdkRollback,
|
|
42407
42997
|
renderCdkSynth,
|
|
42408
42998
|
renderCdkWatch,
|
|
42999
|
+
renderCheckClosingKeywordsScript,
|
|
42409
43000
|
renderCheckDocSamplesProcedure,
|
|
42410
43001
|
renderCheckLinksProcedure,
|
|
42411
43002
|
renderCustomDocSectionBlock,
|