forgedock 1.1.11 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/README.md +9 -3
  2. package/bin/cli-spawn-shared.mjs +25 -0
  3. package/bin/engine/phases.mjs +178 -28
  4. package/bin/engine/state.mjs +39 -7
  5. package/bin/engine-cli.mjs +85 -3
  6. package/bin/engine.mjs +71 -8
  7. package/bin/forgedock.mjs +322 -20
  8. package/bin/hooks/pre-tool-use.mjs +345 -10
  9. package/bin/init-enrich-api.mjs +12 -4
  10. package/bin/init-enrich-cli.mjs +328 -0
  11. package/bin/init-enrich.mjs +137 -0
  12. package/bin/journey.mjs +116 -15
  13. package/bin/runner.mjs +653 -10
  14. package/commands/adopt.md +1 -1
  15. package/commands/analytics.md +10 -7
  16. package/commands/audit-agents.md +29 -6
  17. package/commands/audit.md +9 -20
  18. package/commands/autopilot.md +52 -78
  19. package/commands/changelog.md +1 -1
  20. package/commands/ci-audit.md +19 -10
  21. package/commands/cleanup.md +1 -1
  22. package/commands/compat-audit.md +1 -1
  23. package/commands/deploy-info.md +1 -1
  24. package/commands/deploy-pr.md +1 -1
  25. package/commands/design-bench.md +1 -1
  26. package/commands/design-render-critique-loop.md +1 -1
  27. package/commands/diagnose.md +1 -1
  28. package/commands/forge-stats.md +6 -5
  29. package/commands/forgedock-init.md +1 -1
  30. package/commands/geo-audit.md +9 -6
  31. package/commands/incident-response.md +15 -5
  32. package/commands/issue.md +302 -15
  33. package/commands/milestone.md +45 -18
  34. package/commands/optimize.md +1 -1
  35. package/commands/orchestrate/phase-1-resolve.md +20 -5
  36. package/commands/orchestrate/phase-4-execution.md +8 -1
  37. package/commands/orchestrate/phase-5-cleanup.md +43 -2
  38. package/commands/orchestrate/phase-6-report.md +1 -0
  39. package/commands/orchestrate.md +1 -1
  40. package/commands/pipeline-health/phase-4-proposals.md +40 -10
  41. package/commands/pipeline-health/phase-5-report.md +140 -13
  42. package/commands/pipeline-health.md +1 -1
  43. package/commands/pipeline-resume.md +1 -1
  44. package/commands/pipeline-status.md +1 -1
  45. package/commands/qa-sweep.md +27 -4
  46. package/commands/recover-orphans.md +1 -1
  47. package/commands/replay.md +16 -2
  48. package/commands/review-pr-agents/protocols.md +4 -0
  49. package/commands/review-pr-agents/spec-cli.md +179 -0
  50. package/commands/review-pr-agents.md +7 -4
  51. package/commands/review-pr-staging.md +44 -15
  52. package/commands/review-pr.md +122 -28
  53. package/commands/rollback.md +15 -5
  54. package/commands/security-audit.md +14 -11
  55. package/commands/signal-planner.md +32 -12
  56. package/commands/spec-doctor.md +1 -1
  57. package/commands/sync-ecosystem.md +54 -11
  58. package/commands/test-gate.md +49 -11
  59. package/commands/upgrade-deps.md +518 -0
  60. package/commands/validate.md +16 -5
  61. package/commands/work-on/build/architect.md +1 -1
  62. package/commands/work-on/build/context.md +1 -1
  63. package/commands/work-on/build/implement.md +2 -2
  64. package/commands/work-on/build/validate.md +64 -2
  65. package/commands/work-on/build.md +10 -2
  66. package/commands/work-on/close.md +1 -1
  67. package/commands/work-on/decompose.md +35 -25
  68. package/commands/work-on/investigate.md +2 -2
  69. package/commands/work-on/remediate.md +1 -1
  70. package/commands/work-on/review.md +5 -3
  71. package/commands/work-on-monolithic.md +1 -1
  72. package/commands/work-on.md +28 -7
  73. package/docs/AIDER.md +264 -0
  74. package/docs/AUTOPILOT-CRON.md +130 -0
  75. package/docs/CI.md +18 -0
  76. package/docs/CONFIG.md +41 -2
  77. package/docs/CURSOR.md +135 -0
  78. package/docs/OPENCODE.md +312 -0
  79. package/docs/demo.gif +0 -0
  80. package/docs/eval/README.md +4 -4
  81. package/docs/launch/show-hn.md +3 -3
  82. package/docs/site/annotations-explained.md +2 -2
  83. package/docs/site/architecture.md +180 -0
  84. package/docs/site/command-reference.md +38 -0
  85. package/docs/site/configuration.md +243 -0
  86. package/docs/site/for-companies.md +4 -4
  87. package/docs/site/forge-annotation-protocol.md +1 -1
  88. package/docs/site/github-is-the-memory.md +2 -2
  89. package/docs/site/how-it-works.md +1 -1
  90. package/docs/site/public/llms-full.txt +380 -0
  91. package/docs/site/public/llms.txt +35 -0
  92. package/docs/spec/review-protocol.md +6 -0
  93. package/docs/spec-graph-schema.md +3 -3
  94. package/package.json +2 -2
  95. package/packages/protocol/README.md +75 -0
  96. package/packages/protocol/src/card.js +114 -0
  97. package/packages/protocol/src/cli.js +4 -77
  98. package/packages/protocol/src/emit.js +14 -3
  99. package/packages/protocol/src/index.js +2 -1
  100. package/packages/protocol/src/parse.js +17 -8
  101. package/packages/protocol/src/types.js +1 -1
  102. package/packages/protocol/src/validate.js +11 -0
  103. package/scripts/check-command-side-effects.sh +261 -0
  104. package/scripts/check-spec-markers.sh +273 -0
  105. package/scripts/classify-lane.sh +29 -7
  106. package/scripts/forge-run.sh +322 -0
  107. package/templates/cross-repo-trigger.yml +282 -0
  108. package/templates/cursor/forge.mdc +148 -0
  109. package/templates/github-actions/forgedock-autopilot.yml +113 -0
package/commands/adopt.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Bootstrap an existing repo for ForgeDock — triage open issues, apply labels, suggest a starter milestone, and identify first /work-on candidates
3
- argument-hint: [--dry-run | --limit <N> | --milestone | --no-milestone]
3
+ argument-hint: "[--dry-run | --limit <N> | --milestone | --no-milestone]"
4
4
  install: extras
5
5
  ---
6
6
 
@@ -684,13 +684,11 @@ Fill in historical values from the Phase 0 history snapshots. Leave cells blank
684
684
 
685
685
  **Only after user confirms.** If "adjust" — modify list. If they pick specific ones — only create those.
686
686
 
687
- For each approved action:
687
+ For each approved action, route creation through the `/issue` create-hook's programmatic invocation contract (see `commands/issue.md` → Programmatic Invocation Contract) so dedup and mandatory-section validation run on every finding:
688
688
 
689
689
  ```bash
690
- gh issue create \
691
- --title "{type}: {action title}" \
692
- --label "{priority},{category_label}" \
693
- --body "$(cat <<'BODY_EOF'
690
+ ANALYTICS_BODY_FILE=$(mktemp)
691
+ cat > "$ANALYTICS_BODY_FILE" <<'BODY_EOF'
694
692
  ## Problem
695
693
 
696
694
  {1-3 sentences: what the analytics data shows is wrong or suboptimal, with specific numbers.}
@@ -727,10 +725,15 @@ Identified in analytics audit on {DATE}.
727
725
 
728
726
  {Technical steps}
729
727
  BODY_EOF
730
- )"
731
728
  ```
732
729
 
733
- **Label mapping**: SEO → `seo`, UX → `ux,frontend`, Performance → `performance,infra`, Bug → `bug`. Priority: `P0`-`P3`.
730
+ ```
731
+ Skill(skill="issue", args="--title \"{type}: {action title}\" --body-file \"$ANALYTICS_BODY_FILE\" --label \"{priority}\" --label \"{category_label_1}\" --label \"{category_label_2}\"")
732
+ ```
733
+
734
+ `{priority}`, `{category_label_1}`, and `{category_label_2}` are each passed as their own `--label` flag — `/issue`'s programmatic mode does not comma-split a single `--label` value. Resolve `{category_label_1}`/`{category_label_2}` from the label mapping below: split each mapping's comma-separated value into one label per placeholder. When a category maps to only one label, omit the `--label "{category_label_2}"` flag entirely (do not pass an empty string).
735
+
736
+ **Label mapping**: SEO → `seo` (single label), UX → `ux` + `frontend` (two labels), Performance → `performance` + `infra` (two labels), Bug → `bug` (single label). Priority: `P0`-`P3`.
734
737
 
735
738
  If an open milestone fits, offer to assign issues to it.
736
739
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Audit agent outputs from an orchestration run — timeline analysis, stall detection, active vs idle time breakdown
3
- argument-hint: [session-id | latest | <agent-id>]
3
+ argument-hint: "[session-id | latest | <agent-id>]"
4
4
  install: extras
5
5
  ---
6
6
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
@@ -427,6 +427,8 @@ This step posts a structured `<!-- FORGE:AUDIT-AGENTS -->` summary comment to th
427
427
 
428
428
  **Step 4E.1 — Locate or create the tracking issue**:
429
429
 
430
+ Creation (first-use only — the `gh issue list` existence check below still gates whether creation runs at all) is routed through the `/issue` create-hook's programmatic invocation contract (see `commands/issue.md` → Programmatic Invocation Contract):
431
+
430
432
  ```bash
431
433
  # Ensure the label exists before using it (gh issue create fails with GraphQL error if label is absent).
432
434
  # Color and description match the canonical ForgeDock label manifest (bin/labels.json).
@@ -441,11 +443,32 @@ TRACKING_ISSUE=$(gh issue list -R {FORGE_REPO} \
441
443
 
442
444
  if [ -z "$TRACKING_ISSUE" ]; then
443
445
  # Create the tracking issue on first use
444
- TRACKING_ISSUE=$(gh issue create -R {FORGE_REPO} \
445
- --title "Orchestration Metrics — Running Log" \
446
- --label "orchestration-metrics" \
447
- --body "This issue is a running log of persisted \`/audit-agents\` summaries. Each comment contains one session's efficiency metrics. Do not close this issue — \`/pipeline-health\` Phase 2K queries it to aggregate orchestration efficiency trends." \
448
- --json number --jq '.number')
446
+ TRACKING_BODY_FILE=$(mktemp)
447
+ cat > "$TRACKING_BODY_FILE" <<'EOF'
448
+ ## Problem
449
+
450
+ No `orchestration-metrics` tracking issue exists yet — this is the first `/audit-agents --persist` run for this repo.
451
+
452
+ ## Affected Files
453
+
454
+ N/A — this is a running log issue, not a code change.
455
+
456
+ ## Acceptance Criteria
457
+
458
+ - [ ] This issue stays open indefinitely as a running log of persisted `/audit-agents` summaries
459
+
460
+ ## Context
461
+
462
+ This issue is a running log of persisted `/audit-agents` summaries. Each comment contains one session's efficiency metrics. Do not close this issue — `/pipeline-health` Phase 2K queries it to aggregate orchestration efficiency trends.
463
+ EOF
464
+
465
+ Skill(skill="issue", args="--title \"Orchestration Metrics — Running Log\" --body-file \"$TRACKING_BODY_FILE\" --label \"orchestration-metrics\"")
466
+
467
+ # /issue's programmatic mode does not print a structured return value — re-query
468
+ # by label to recover the newly created issue number.
469
+ TRACKING_ISSUE=$(gh issue list -R {FORGE_REPO} \
470
+ --state open --label "orchestration-metrics" --limit 1 \
471
+ --json number --jq '.[0].number' 2>/dev/null)
449
472
  echo "Created orchestration-metrics tracking issue #$TRACKING_ISSUE"
450
473
  fi
451
474
  ```
package/commands/audit.md CHANGED
@@ -287,29 +287,13 @@ Create a detailed, actionable issue in the **Forge repository**.
287
287
 
288
288
  ### 4B: Create the issue
289
289
 
290
- **Before creating, run the deterministic dedup check:** <!-- Added: forge#1335 -->
290
+ Creation is routed through the `/issue` create-hook's programmatic invocation contract (see `commands/issue.md` → Programmatic Invocation Contract). `/issue` runs its own Phase 2D deterministic dedup check (`scripts/issue-dedup.sh`, same script and exit-code semantics this file used to run manually) before creating — a separate manual pre-check here is redundant and has been removed. `/issue`'s dedup STOP is authoritative: on exit 1 (near-duplicate) or exit 2 (usage error) it stops before creation and the audit tool should treat that as "skip creation, comment on the existing issue with new evidence instead" (see `commands/issue.md` Phase 2D).
291
291
 
292
292
  ```bash
293
293
  AUDIT_TITLE="fix(pipeline): {one-line description of what the pipeline missed}"
294
- DEDUP_RESULT=$(scripts/issue-dedup.sh "$AUDIT_TITLE" -R {FORGE_REPO} 2>&1)
295
- DEDUP_EXIT=$?
296
- if [ "$DEDUP_EXIT" -eq 1 ]; then
297
- echo "DEDUP: Audit finding near-duplicate — $DEDUP_RESULT"
298
- echo "Skipping creation. Comment on the existing issue with new evidence instead."
299
- # Do NOT call gh issue create for this audit finding
300
- elif [ "$DEDUP_EXIT" -eq 2 ]; then
301
- echo "DEDUP: Usage error — $DEDUP_RESULT"
302
- # Do NOT call gh issue create for this audit finding — fix the invocation and retry
303
- fi
304
- ```
305
-
306
- Only call `gh issue create` when the dedup script exits 0:
307
294
 
308
- ```bash
309
- gh issue create -R {FORGE_REPO} \
310
- --title "fix(pipeline): {one-line description of what the pipeline missed}" \
311
- --label "{LABELS}" \
312
- --body "$(cat <<'EOF'
295
+ AUDIT_BODY_FILE=$(mktemp)
296
+ cat > "$AUDIT_BODY_FILE" <<'EOF'
313
297
  ## Problem
314
298
 
315
299
  {2-3 sentences: what production issue or implementation failure occurred and what pipeline phase failed to prevent it.}
@@ -397,9 +381,14 @@ gh issue list -R {FORGE_REPO} --state all --limit 30 --json number,title \
397
381
 
398
382
  {Include results here with links}
399
383
  EOF
400
- )"
401
384
  ```
402
385
 
386
+ ```
387
+ Skill(skill="issue", args="--title \"$AUDIT_TITLE\" --body-file \"$AUDIT_BODY_FILE\" --label \"{LABEL_1}\" --label \"{LABEL_2}\" --label \"{LABEL_3}\"")
388
+ ```
389
+
390
+ `{LABELS}` from the table in 4A (e.g. `P1,audit-finding,bug`) is split into one `--label` flag per label (`{LABEL_1}`, `{LABEL_2}`, `{LABEL_3}`) — `/issue`'s programmatic mode does not comma-split a single `--label` value. If `/issue` stops on dedup (near-duplicate or usage error, per the note above), do not fall back to a raw `gh issue create` — comment on the existing issue with the new evidence instead.
391
+
403
392
  ---
404
393
 
405
394
  ## Phase 5: Cross-Reference and Enrich
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Autonomous deploy loop — runs until zero open issues remain. Detects pipeline state and resumes from any position. Fully autonomous after invocation.
3
- argument-hint: [--dry-run | --recon-only]
3
+ argument-hint: "[--dry-run | --recon-only]"
4
4
  install: extras
5
5
  ---
6
6
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
@@ -149,19 +149,25 @@ if [ -z "$OPS_ISSUE_NUMBER" ]; then
149
149
  --description "Autopilot ops issue — rolling FORGE:AUTOPILOT_CYCLE annotations. Managed by /autopilot." \
150
150
  --color "0075CA" \
151
151
  $GH_FLAG 2>/dev/null || true
152
- OPS_ISSUE_NUMBER=$(gh issue create $GH_FLAG \
153
- --title "ops: autopilot cycle log" \
154
- --label "$AUTOPILOT_OPS_LABEL" \
155
- --body "$(cat <<'OPS_EOF'
152
+ OPS_BODY_TMPFILE=$(mktemp)
153
+ trap 'rm -f "$OPS_BODY_TMPFILE"' EXIT
154
+ cat > "$OPS_BODY_TMPFILE" <<'OPS_EOF'
156
155
  ## Autopilot Ops Issue
157
156
 
158
157
  This issue is the rolling log for `/autopilot` cycle annotations. Each cycle appends a `<!-- FORGE:AUTOPILOT_CYCLE -->` comment with its metrics and phase-completion markers. Cycle N+1 reads the latest comment for baseline deltas and resume state.
159
158
 
160
159
  **Do not close this issue manually.** It is managed by `/autopilot`.
161
160
  OPS_EOF
162
- )" \
163
- --json number \
164
- --jq '.number' 2>/dev/null || echo '')
161
+ # Route through the /issue create-hook (canonical dedup + body validation) instead of
162
+ # a raw `gh issue create`. See commands/issue.md Programmatic Invocation Contract.
163
+ Skill(skill="issue", args="--title \"ops: autopilot cycle log\" --body-file \"$OPS_BODY_TMPFILE\" --label \"$AUTOPILOT_OPS_LABEL\"")
164
+ rm -f "$OPS_BODY_TMPFILE"
165
+ trap - EXIT
166
+ OPS_ISSUE_NUMBER=$(gh issue list $GH_FLAG \
167
+ --state open \
168
+ --search "ops: autopilot cycle log" \
169
+ --json number,title \
170
+ --jq '.[] | select(.title == "ops: autopilot cycle log") | .number' 2>/dev/null | head -1)
165
171
  echo "Autopilot: ops issue created: #$OPS_ISSUE_NUMBER"
166
172
  else
167
173
  echo "[DRY-RUN] Would create ops issue with label '$AUTOPILOT_OPS_LABEL'"
@@ -545,36 +551,10 @@ fi
545
551
 
546
552
  ### 1E: Create issues from recon findings
547
553
 
548
- For each finding (recurring CI failures, critical stale issue patterns):
554
+ For each finding (recurring CI failures, critical stale issue patterns), route creation through the `/issue` create-hook — its Phase 2D runs the same deterministic `scripts/issue-dedup.sh` + LLM-fallback dedup this step used to run inline, and its Phase 3F runs the same mandatory-section repair this step used to run inline post-creation. Do not duplicate either check here.
549
555
 
550
- **Deduplication check first** — deterministic script, then LLM fallback (canonical path from `issue.md §2D`):
551
556
  ```bash
552
- # Authoritative deterministic check — uses token overlap algorithm (see scripts/issue-dedup.sh)
553
- DEDUP_RESULT=$(scripts/issue-dedup.sh "{finding_title}" "$GH_FLAG" 2>&1)
554
- DEDUP_EXIT=$?
555
-
556
- if [ "$DEDUP_EXIT" -eq 1 ]; then
557
- echo "Near-duplicate detected: $DEDUP_RESULT"
558
- echo "Existing issue found — skipping creation for this finding."
559
- # STOP here for this finding — do not fall through to gh issue create
560
- elif [ "$DEDUP_EXIT" -eq 2 ]; then
561
- echo "Dedup check usage error: $DEDUP_RESULT"
562
- echo "Do NOT proceed to issue creation — fix the invocation and retry."
563
- # STOP here — do not fall through to gh issue create
564
- fi
565
-
566
- # If script exits 0 (no match), also run LLM-side semantic search as a secondary pass
567
- if [ "$DEDUP_EXIT" -eq 0 ]; then
568
- gh issue list $GH_FLAG --state open --limit 20 --search "{key_terms_from_finding}" \
569
- --json number,title,labels \
570
- --jq '.[] | "#\(.number) [\(.labels | map(.name) | join(","))] \(.title)"' 2>/dev/null || true
571
- # LLM: if the secondary pass finds a semantic duplicate, treat it as DEDUP_EXIT=1 and skip
572
- fi
573
- ```
574
-
575
- For new findings that have no existing open duplicate (DEDUP_EXIT=0 and no LLM match):
576
- ```bash
577
- if [ "$DRY_RUN" = "false" ] && [ "${DEDUP_EXIT:-0}" -eq 0 ]; then
557
+ if [ "$DRY_RUN" = "false" ]; then
578
558
  # Write body to a temp file to avoid heredoc shell-expansion and injection issues
579
559
  BODY_TMPFILE=$(mktemp /tmp/autopilot-issue-body-XXXXXX.md)
580
560
  trap 'rm -f "$BODY_TMPFILE"' EXIT
@@ -609,47 +589,28 @@ ISSUE_BODY_EOF
609
589
  # Substitute the cycle timestamp (not inside heredoc to avoid expansion-in-template issues)
610
590
  sed -i "s|{CYCLE_TIMESTAMP}|$(date -u +%Y-%m-%dT%H:%M:%SZ)|g" "$BODY_TMPFILE"
611
591
 
612
- NEW_NUMBER=$(gh issue create $GH_FLAG \
613
- --title "fix: {finding_description}" \
614
- --label "P2,bug" \
615
- --body-file "$BODY_TMPFILE" \
616
- --json number --jq '.number' 2>/dev/null)
592
+ FINDING_TITLE="fix: {finding_description}"
593
+
594
+ # Route through the /issue create-hook (canonical dedup + body validation) instead of
595
+ # a raw `gh issue create`. If /issue finds a near-duplicate, it reports it and does not
596
+ # create — NEW_NUMBER will come back empty from the lookup below.
597
+ Skill(skill="issue", args="--title \"$FINDING_TITLE\" --body-file \"$BODY_TMPFILE\" --label P2 --label bug")
617
598
 
618
599
  rm -f "$BODY_TMPFILE"
619
600
  trap - EXIT
620
601
 
621
- # §4C.5: Body validation/repair — ensure mandatory pipeline sections are present
622
- # (canonical pattern from issue.md §4C.5 — never fails/blocks, only repairs)
623
- if [ -n "$NEW_NUMBER" ]; then
624
- CREATED_BODY=$(gh issue view "$NEW_NUMBER" $GH_FLAG --json body --jq '.body' 2>/dev/null || echo '')
625
- MISSING_SECTIONS=""
626
- echo "$CREATED_BODY" | grep -q "^## Problem" || MISSING_SECTIONS="$MISSING_SECTIONS PROBLEM"
627
- echo "$CREATED_BODY" | grep -q "^## Affected Files" || MISSING_SECTIONS="$MISSING_SECTIONS AFFECTED_FILES"
628
- echo "$CREATED_BODY" | grep -q "^## Acceptance Criteria" || MISSING_SECTIONS="$MISSING_SECTIONS ACCEPTANCE_CRITERIA"
629
-
630
- if [ -n "$MISSING_SECTIONS" ]; then
631
- echo "WARNING: Issue #$NEW_NUMBER body is missing sections:$MISSING_SECTIONS — adding placeholders"
632
- APPEND_TEXT=""
633
- echo "$MISSING_SECTIONS" | grep -q "PROBLEM" && APPEND_TEXT="$APPEND_TEXT
634
- ## Problem
635
-
636
- Root cause unknown — investigation needed."
637
- echo "$MISSING_SECTIONS" | grep -q "AFFECTED_FILES" && APPEND_TEXT="$APPEND_TEXT
638
- ## Affected Files
639
-
640
- Files to be identified during investigation."
641
- echo "$MISSING_SECTIONS" | grep -q "ACCEPTANCE_CRITERIA" && APPEND_TEXT="$APPEND_TEXT
642
- ## Acceptance Criteria
602
+ NEW_NUMBER=$(gh issue list $GH_FLAG \
603
+ --state open \
604
+ --search "$FINDING_TITLE" \
605
+ --json number,title \
606
+ --jq --arg t "$FINDING_TITLE" '.[] | select(.title == $t) | .number' 2>/dev/null | head -1)
643
607
 
644
- - [ ] Fix confirmed during investigation."
645
- REPAIRED_BODY="${CREATED_BODY}${APPEND_TEXT}"
646
- gh issue edit "$NEW_NUMBER" $GH_FLAG --body "$REPAIRED_BODY"
647
- echo "Body repaired — added:$MISSING_SECTIONS"
648
- else
649
- echo "Body validation passed for #$NEW_NUMBER — all mandatory sections present"
650
- fi
608
+ if [ -n "$NEW_NUMBER" ]; then
609
+ echo "Created: #$NEW_NUMBER"
610
+ else
611
+ echo "No new issue created for finding (likely deduped by /issue) — skipping"
651
612
  fi
652
- elif [ "$DRY_RUN" = "true" ]; then
613
+ else
653
614
  echo "[DRY-RUN] Would create issue: fix: {finding_description}"
654
615
  fi
655
616
  ```
@@ -1377,10 +1338,10 @@ if [ "${#RECON_ISSUES[@]:-0}" -gt 0 ] && [ -n "$OPS_ISSUE_NUMBER" ] && [ "$OPS_I
1377
1338
  --limit 1 --json number --jq '.[0].number // empty' 2>/dev/null || echo '')
1378
1339
 
1379
1340
  if [ -z "$EXISTING_META" ] && [ "$DRY_RUN" = "false" ]; then
1380
- gh issue create $GH_FLAG \
1381
- --title "meta: recurring autopilot finding — $FINDING_PATTERN" \
1382
- --label "priority:P2" \
1383
- --body "$(cat <<META_EOF
1341
+ META_TITLE="meta: recurring autopilot finding — $FINDING_PATTERN"
1342
+ META_BODY_TMPFILE=$(mktemp /tmp/autopilot-meta-body-XXXXXX.md)
1343
+ trap 'rm -f "$META_BODY_TMPFILE"' EXIT
1344
+ cat > "$META_BODY_TMPFILE" <<META_EOF
1384
1345
  ## Problem
1385
1346
 
1386
1347
  The following finding pattern has appeared in **3 or more consecutive /autopilot cycles**, indicating a systemic issue rather than a one-off occurrence.
@@ -1413,9 +1374,22 @@ Files to be identified during investigation.
1413
1374
  **Citing cycles**: ${CITING_CYCLES}
1414
1375
  **Detected by**: /autopilot Phase 4B recurrence detection
1415
1376
  META_EOF
1416
- )" \
1417
- --json number --jq '"Created meta-issue #\(.number) for recurrent pattern: $ENV.FINDING_PATTERN"' \
1418
- 2>/dev/null || echo "WARNING: Failed to create meta-issue for recurrence pattern: $FINDING_PATTERN"
1377
+ # Route through the /issue create-hook (canonical dedup + body validation) instead
1378
+ # of a raw `gh issue create`. The EXISTING_META search above already guards against
1379
+ # re-creating for the same pattern; /issue's own dedup is an additional safety net.
1380
+ Skill(skill="issue", args="--title \"$META_TITLE\" --body-file \"$META_BODY_TMPFILE\" --label priority:P2")
1381
+ rm -f "$META_BODY_TMPFILE"
1382
+ trap - EXIT
1383
+ META_NEW_NUMBER=$(gh issue list $GH_FLAG \
1384
+ --state open \
1385
+ --search "$META_TITLE" \
1386
+ --json number,title \
1387
+ --jq --arg t "$META_TITLE" '.[] | select(.title == $t) | .number' 2>/dev/null | head -1)
1388
+ if [ -n "$META_NEW_NUMBER" ]; then
1389
+ echo "Created meta-issue #$META_NEW_NUMBER for recurrent pattern: $FINDING_PATTERN"
1390
+ else
1391
+ echo "WARNING: Could not confirm meta-issue creation for recurrence pattern: $FINDING_PATTERN"
1392
+ fi
1419
1393
  elif [ -n "$EXISTING_META" ]; then
1420
1394
  echo "Recurrence meta-issue already exists (#$EXISTING_META) for pattern '$FINDING_PATTERN' — skipping"
1421
1395
  elif [ "$DRY_RUN" = "true" ]; then
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Auto-generate release notes from merged PRs and FORGE:TRAJECTORY annotations — grouped by conventional commit type
3
- argument-hint: [v1.0.0..v1.1.0 | since:YYYY-MM-DD | last-N]
3
+ argument-hint: "[v1.0.0..v1.1.0 | since:YYYY-MM-DD | last-N]"
4
4
  install: extras
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Stack-aware CI gap detection — audits a project's GitHub Actions workflows against its declared tech stack and files issues for missing config validation checks
3
- argument-hint: [--repo <prefix>] [--dry-run]
3
+ argument-hint: "[--repo <prefix>] [--dry-run]"
4
4
  install: extras
5
5
  ---
6
6
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
@@ -362,11 +362,15 @@ ${VERSION_NOTE}
362
362
  echo "$ISSUE_BODY"
363
363
  echo "Labels: bug,P2,audit-finding"
364
364
  else
365
- CREATED_ISSUE=$(gh issue create $GH_FLAG \
366
- --title "ci($tool): add structural config validation step to CI pipeline" \
367
- --body "$ISSUE_BODY" \
368
- --label "bug,P2,audit-finding" 2>&1)
369
- echo "Created issue for $tool gap: $CREATED_ISSUE"
365
+ # Route creation through the /issue create-hook's programmatic invocation
366
+ # contract (see commands/issue.md -> Programmatic Invocation Contract) so
367
+ # dedup and mandatory-section validation run on every CI-gap finding.
368
+ # Written to a temp file (rather than passed inline via --body) because
369
+ # $ISSUE_BODY contains backticks and other shell metacharacters that would
370
+ # be unsafe to re-embed into a Skill args string.
371
+ CI_GAP_BODY_FILE=$(mktemp)
372
+ printf '%s' "$ISSUE_BODY" > "$CI_GAP_BODY_FILE"
373
+ Skill(skill="issue", args="--title \"ci($tool): add structural config validation step to CI pipeline\" --body-file \"$CI_GAP_BODY_FILE\" --label \"bug\" --label \"P2\" --label \"audit-finding\"")
370
374
  fi
371
375
  fi
372
376
  done
@@ -402,10 +406,15 @@ The project has a \`$tool\` validation step in CI, but it only runs in the deplo
402
406
  if [ "$DRY_RUN" = "true" ]; then
403
407
  echo "=== DRY RUN: Would create placement issue for $tool ==="
404
408
  else
405
- gh issue create $GH_FLAG \
406
- --title "ci($tool): move config validation to PR-time CI workflow" \
407
- --body "$ISSUE_BODY" \
408
- --label "bug,P3,audit-finding" 2>&1
409
+ # Route creation through the /issue create-hook's programmatic invocation
410
+ # contract (see commands/issue.md -> Programmatic Invocation Contract) so
411
+ # dedup and mandatory-section validation run on every finding. Written to a
412
+ # temp file (rather than passed inline via --body) because $ISSUE_BODY
413
+ # contains backticks and other shell metacharacters that would be unsafe to
414
+ # re-embed into a Skill args string.
415
+ CI_PLACEMENT_BODY_FILE=$(mktemp)
416
+ printf '%s' "$ISSUE_BODY" > "$CI_PLACEMENT_BODY_FILE"
417
+ Skill(skill="issue", args="--title \"ci($tool): move config validation to PR-time CI workflow\" --body-file \"$CI_PLACEMENT_BODY_FILE\" --label \"bug\" --label \"P3\" --label \"audit-finding\"")
409
418
  fi
410
419
  done
411
420
  ```
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Sweep closed issues for stale labels, missing workflow state, and Project board gaps — plus prune worktrees, branches, and milestones
3
- argument-hint: [labels | branches | milestones | board | orphans | all]
3
+ argument-hint: "[labels | branches | milestones | board | orphans | all]"
4
4
  install: extras
5
5
  ---
6
6
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: On-demand Claude Code compatibility and feature parity report — compares installed version against the breakpoints registry and lists affected ForgeDock features
3
- argument-hint: [--refresh]
3
+ argument-hint: "[--refresh]"
4
4
  install: extras
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Show what will deploy next — diff staging vs main with issue/PR summary, risk assessment, and deploy checklist
3
- argument-hint: [staging | milestone/{slug} | compare {branch}]
3
+ argument-hint: "[staging | milestone/{slug} | compare {branch}]"
4
4
  install: extras
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Ship a branch to its deploy target — detect or create PR, fix CI, review, merge. Returns structured result for callers.
3
- argument-hint: [source_branch | "staging" | "milestone/{slug}"] [--target TARGET] [--issue ISSUE_NUMBER] [--repo REPO] [--max-ci-iterations N] [--max-review-iterations N] [--dry-run]
3
+ argument-hint: "[source_branch | \"staging\" | \"milestone/{slug}\"] [--target TARGET] [--issue ISSUE_NUMBER] [--repo REPO] [--max-ci-iterations N] [--max-review-iterations N] [--dry-run]"
4
4
  allowed-tools: Bash, Read, Grep, Glob, Skill
5
5
  ---
6
6
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Run the ABC benchmark — reference URL → design-blind brief → render arms A/B/C → blind judge → scorecard with win-rates over n runs
3
- argument-hint: [<brief-name>|all] [--n <runs>] [--corpus-version <ver>]
3
+ argument-hint: "[<brief-name>|all] [--n <runs>] [--corpus-version <ver>]"
4
4
  install: internal
5
5
  ---
6
6
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Render a design from its FORGE:DESIGN_SPEC, critique the rendered pixels against the perceptual negatives, and iterate until it passes or the budget is spent — the missing reward signal.
3
- argument-hint: [<issue-number>|<spec-path>] [--max-iters <n>] [--viewports desktop,mobile]
3
+ argument-hint: "[<issue-number>|<spec-path>] [--max-iters <n>] [--viewports desktop,mobile]"
4
4
  install: internal
5
5
  ---
6
6
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Trace a failed or stalled pipeline run — identify which FORGE annotation is missing or malformed, diagnose the failure point, and suggest specific remediation steps
3
- argument-hint: [issue number] [--repo prefix]
3
+ argument-hint: "[issue number] [--repo prefix]"
4
4
  install: extras
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Track command sizes, detect bloat, compare against baselines and thresholds
3
- argument-hint: [diff | baseline | full | cost]
3
+ argument-hint: "[diff | baseline | full | cost]"
4
4
  install: internal
5
5
  ---
6
6
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
@@ -34,8 +34,8 @@ Commands are classified by role. Each role has a max line count — beyond this,
34
34
  |------|-----------|-----------|
35
35
  | Orchestrator (work-on, orchestrate, review-pr) | 800 | Delegates to sub-agents; needs full pipeline logic |
36
36
  | Agent catalog (review-pr-agents, review-pr-staging) | 1000 | Reference file read on demand, not fed whole to one agent |
37
- | Specialist (milestone, analytics, validate, etc.) | 400 | Single-purpose; Sonnet attention degrades past this |
38
- | Utility (cleanup, sync-ecosystem, forge-stats) | 250 | Simple tasks; should stay lean |
37
+ | Specialist (milestone, analytics, sync-ecosystem, validate, etc.) | 400 | Single-purpose or multi-subcommand; Sonnet attention degrades past this |
38
+ | Utility (cleanup, forge-stats) | 250 | Simple tasks; should stay lean |
39
39
  | Sub-file (quality-gate, pipeline-health) | 350 | Invoked by parent; shares context budget |
40
40
 
41
41
  **Current overages (v1.1.0 baseline):**
@@ -46,7 +46,8 @@ Commands are classified by role. Each role has a max line count — beyond this,
46
46
  - `review-pr.md`: 796 lines (threshold 800) — OK
47
47
  - `validate.md`: 97 lines (threshold 400) — OK (compressed from 679)
48
48
  - `orchestrate.md`: 654 lines (threshold 800) — OK
49
- - `analytics.md`: 590 lines (threshold 400) — **48% over**
49
+ - `analytics.md`: 856 lines (threshold 400) — **114% over**
50
+ - `sync-ecosystem.md`: 799 lines (threshold 400) — **99% over**
50
51
 
51
52
  ---
52
53
 
@@ -75,7 +76,7 @@ for cmd in commands/*.md; do
75
76
  case "$name" in
76
77
  work-on.md|orchestrate.md|review-pr.md) threshold=800 ;;
77
78
  review-pr-agents.md|review-pr-staging.md) threshold=1000 ;;
78
- cleanup.md|sync-ecosystem.md|forge-stats.md) threshold=250 ;;
79
+ cleanup.md|forge-stats.md) threshold=250 ;;
79
80
  quality-gate.md|pipeline-health.md) threshold=350 ;;
80
81
  *) threshold=400 ;;
81
82
  esac
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: AI-powered forge.yaml config generator — scans codebase, queries GitHub, auto-fills all optional sections from detection
3
- argument-hint: [--preserve | --interactive | --section <name>]
3
+ argument-hint: "[--preserve | --interactive | --section <name>]"
4
4
  ---
5
5
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
6
6
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -320,12 +320,10 @@ Show the user a structured report BEFORE creating issues:
320
320
 
321
321
  **Only after user confirms.** If "adjust" — modify. If specific ones — only create those.
322
322
 
323
- For each approved issue:
323
+ For each approved issue, route creation through the `/issue` create-hook's programmatic invocation contract (see `commands/issue.md` → Programmatic Invocation Contract) so dedup and mandatory-section validation run on every finding:
324
324
  ```bash
325
- gh issue create \
326
- --title "{fix|feat}: {concise description}" \
327
- --label "{priority},{labels}" \
328
- --body "$(cat <<'BODY_EOF'
325
+ GEO_BODY_FILE=$(mktemp)
326
+ cat > "$GEO_BODY_FILE" <<'BODY_EOF'
329
327
  ## Problem
330
328
 
331
329
  {1-3 sentences: what the GEO audit found is wrong or missing. Current state with specific numbers.}
@@ -359,9 +357,14 @@ Identified in GEO audit on {DATE}.
359
357
 
360
358
  {Concrete technical steps}
361
359
  BODY_EOF
362
- )"
363
360
  ```
364
361
 
362
+ ```
363
+ Skill(skill="issue", args="--title \"{fix|feat}: {concise description}\" --body-file \"$GEO_BODY_FILE\" --label \"{priority}\" --label \"seo\" --label \"geo\"")
364
+ ```
365
+
366
+ `{priority}`, `seo`, and `geo` are each passed as their own `--label` flag — `/issue`'s programmatic mode does not comma-split a single `--label` value. Every row in the Phase 3 table maps to the `seo,geo` label pair, so both are passed as separate literal `--label` flags rather than a single `{labels}` placeholder.
367
+
365
368
  If a `geo-ai-discoverability` milestone exists, assign issues to it:
366
369
  ```bash
367
370
  gh issue edit {NUMBER} --milestone "geo-ai-discoverability"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Coordinate P0 incident response — hotfix validation, timeline reconstruction, and post-incident analysis
3
- argument-hint: [issue number | "active" | "postmortem {issue}"]
3
+ argument-hint: "[issue number | \"active\" | \"postmortem {issue}\"]"
4
4
  install: extras
5
5
  ---
6
6
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
@@ -330,9 +330,10 @@ POSTMORTEM_EOF
330
330
  For each action item identified in the postmortem:
331
331
 
332
332
  ```bash
333
- gh issue create --title "{fix|feat|refactor}: {action item title}" \
334
- --label "{type_label},P{priority}" \
335
- --body "$(cat <<'BODY_EOF'
333
+ ACTION_ITEM_TITLE="{fix|feat|refactor}: {action item title}"
334
+ ACTION_ITEM_BODY_TMPFILE=$(mktemp)
335
+ trap 'rm -f "$ACTION_ITEM_BODY_TMPFILE"' EXIT
336
+ cat > "$ACTION_ITEM_BODY_TMPFILE" <<'BODY_EOF'
336
337
  ## Problem
337
338
 
338
339
  {What gap or vulnerability this action item addresses. What failure mode it prevents.}
@@ -361,7 +362,16 @@ See postmortem: #{INCIDENT_NUMBER} (comment)
361
362
 
362
363
  {Concrete next step}
363
364
  BODY_EOF
364
- )"
365
+ # Route through the /issue create-hook (canonical dedup + body validation) instead of a raw
366
+ # `gh issue create`.
367
+ Skill(skill="issue", args="--title \"$ACTION_ITEM_TITLE\" --body-file \"$ACTION_ITEM_BODY_TMPFILE\" --label \"{type_label}\" --label \"P{priority}\"")
368
+ rm -f "$ACTION_ITEM_BODY_TMPFILE"
369
+ trap - EXIT
370
+ ACTION_ITEM_NUMBER=$(gh issue list \
371
+ --state open \
372
+ --search "$ACTION_ITEM_TITLE" \
373
+ --json number,title \
374
+ --jq --arg t "$ACTION_ITEM_TITLE" '.[] | select(.title == $t) | .number' 2>/dev/null | head -1)
365
375
  ```
366
376
 
367
377
  ---