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
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Validation agent — quality gate loop, format/verify, proxy check, deploy check
3
- argument-hint: [issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--worktree PATH] [--files FILE1 FILE2...]
3
+ argument-hint: "[issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--worktree PATH] [--files FILE1 FILE2...]"
4
4
  ---
5
5
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
6
6
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -254,6 +254,65 @@ fi
254
254
 
255
255
  ---
256
256
 
257
+ ## Phase V3.6: Browser Signal Check
258
+
259
+ **Skip if**: No TypeScript/TSX files were changed, OR `forge.yaml → services.app_url` is absent or empty.
260
+
261
+ After static proxy checks, run a lightweight live browser check using Playwright MCP tools to surface console errors, failed network requests, and basic performance metrics for any changed UI routes. This check is advisory — findings are surfaced as warnings in the V5 summary but do NOT block the gate unless the browser session is available AND returns ERROR-level console output.
262
+
263
+ ```bash
264
+ cd {WORKTREE_PATH}
265
+ APP_URL=$(yq '.services.app_url // ""' forge.yaml 2>/dev/null || echo '')
266
+ if [ -z "$APP_URL" ]; then
267
+ echo "SKIPPED — services.app_url not configured in forge.yaml (browser signal check requires a running app URL)"
268
+ else
269
+ echo "BROWSER SIGNAL CHECK: navigating $APP_URL"
270
+ fi
271
+ ```
272
+
273
+ **When APP_URL is configured**, perform the following using Playwright MCP tools:
274
+
275
+ **Step 1 — Navigate**
276
+ Use `browser_navigate` to load `{APP_URL}`. If the changed files include a specific page route (e.g., `web/src/app/dashboard/page.tsx`), derive the route path and navigate there instead (e.g., `{APP_URL}/dashboard`).
277
+
278
+ **Step 2 — Capture console messages**
279
+ ```
280
+ browser_console_messages
281
+ ```
282
+ Classify findings:
283
+ - Any message at `error` level → **MEDIUM** finding: `BROWSER-CONSOLE-ERROR | MEDIUM | console | {message}`
284
+ - Any message at `warn` level → **LOW** advisory: `BROWSER-CONSOLE-WARN | LOW | console | {message}`
285
+ - Ignore `info` and `log` levels
286
+
287
+ **Step 3 — Capture network failures**
288
+ ```
289
+ browser_network_requests filter="static:false"
290
+ ```
291
+ Check for HTTP 4xx and 5xx responses on non-static requests. Exclude known third-party analytics/tracking domains.
292
+ - HTTP 4xx or 5xx response → **HIGH** finding: `BROWSER-NETWORK-FAIL | HIGH | network | {url} returned {status}`
293
+
294
+ **Step 4 — Capture performance metrics (LCP-ish)**
295
+ ```
296
+ browser_evaluate function="() => {
297
+ const nav = performance.getEntriesByType('navigation')[0];
298
+ const paint = performance.getEntriesByType('paint');
299
+ const fcp = paint.find(e => e.name === 'first-contentful-paint');
300
+ return {
301
+ domContentLoaded: nav ? Math.round(nav.domContentLoadedEventEnd) : null,
302
+ loadTime: nav ? Math.round(nav.loadEventEnd) : null,
303
+ fcp: fcp ? Math.round(fcp.startTime) : null
304
+ };
305
+ }"
306
+ ```
307
+ Classify:
308
+ - `loadTime > 4000` ms → **HIGH** finding: `BROWSER-PERF | HIGH | performance | page load time {loadTime}ms exceeds 4s threshold`
309
+ - `loadTime > 2500` ms → **MEDIUM** finding: `BROWSER-PERF | MEDIUM | performance | page load time {loadTime}ms exceeds 2.5s threshold`
310
+ - `fcp > 1800` ms → **LOW** advisory: `BROWSER-PERF | LOW | performance | FCP {fcp}ms — consider lazy-loading or code splitting`
311
+
312
+ **Advisory scope**: Browser signal findings are included in the V5 summary under "Browser Signals". They do NOT block the gate (GATE_PASSED stays true) unless a BROWSER-NETWORK-FAIL HIGH finding is present on the primary app URL (indicating the app is completely broken for that route). Console ERROR findings are MEDIUM — surfaced for human review, not blocking.
313
+
314
+ ---
315
+
257
316
  ## Phase V4: Deployment Completeness Check
258
317
 
259
318
  **Skip if**: No new environment variables were introduced in the changed files.
@@ -304,6 +363,8 @@ Where `{SCOPE}` is the command or module scope from the contract (e.g. `work-on`
304
363
 
305
364
  This is the **only** commit for this build cycle. It replaces the old `git commit` that was previously in `implement.md` Phase I4. Do NOT create a separate commit for validation fixes — they are absorbed into this single commit.
306
365
 
366
+ **Attribution**: The commit message is exactly the conventional-commit line above — nothing more. Do NOT append a `Co-Authored-By: Claude` trailer, a `🤖 Generated with Claude Code` line, or any assistant-tool attribution. Pipeline output is ForgeDock-branded; the assistant signature must never enter the repo's commit history. (A PreToolUse guard hard-blocks it as a backstop — see `bin/hooks/pre-tool-use.mjs` Rule 5.)
367
+
307
368
  ### V5 Post-Commit Ancestry Audit (MANDATORY)
308
369
 
309
370
  After committing, run the ancestry audit to detect merge commits from unrelated branches before the branch is pushed:
@@ -396,9 +457,10 @@ This module runs at **Step 3F.5** — after implement, before commit (3J) and PR
396
457
 
397
458
  ```
398
459
  3F → Implement (by implement.md) — code written, staged (not committed)
399
- 3F.5 → [THIS MODULE] Validate — gate loop, format, proxy, deploy checks
460
+ 3F.5 → [THIS MODULE] Validate — gate loop, format, proxy, browser signals, deploy checks
400
461
  3G → (covered by Phase V2 above)
401
462
  3H → (covered by Phase V3 above)
463
+ 3H.5 → (covered by Phase V3.6 above — browser signal check for UI changes)
402
464
  3I → (covered by Phase V4 above)
403
465
  3J → V5 commit happens here after GATE_PASSED=true (single commit for implementation + any fixes)
404
466
  ```
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Build subcommand — create worktree, post contract, sequence context/architect/implement/validate
3
- argument-hint: [issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--base PR_BASE]
3
+ argument-hint: "[issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--base PR_BASE]"
4
4
  ---
5
5
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
6
6
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -154,6 +154,13 @@ gh issue edit {NUMBER} {GH_FLAG} \
154
154
 
155
155
  Post `<!-- FORGE:CONTRACT -->` comment documenting what will be built and why:
156
156
 
157
+ **Before posting, read the attribution config**:
158
+ ```bash
159
+ SHOW_ATTRIBUTION=$(yq '.branding.show_attribution // "true"' forge.yaml 2>/dev/null || echo "true")
160
+ [ "$SHOW_ATTRIBUTION" = "false" ] && ATTRIBUTION_LINE="" || ATTRIBUTION_LINE="
161
+ > Pipeline powered by [ForgeDock](https://github.com/RapierCraftStudios/ForgeDock)"
162
+ ```
163
+
157
164
  ```bash
158
165
  gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:CONTRACT -->
159
166
  ## Builder Contract
@@ -180,7 +187,8 @@ gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:CONTRACT -->
180
187
 
181
188
  ### Out of Scope
182
189
 
183
- {OUT_OF_SCOPE_ITEMS}"
190
+ {OUT_OF_SCOPE_ITEMS}
191
+ ${ATTRIBUTION_LINE}"
184
192
  ```
185
193
 
186
194
  Contract must be grounded in the investigation report. Every deliverable file must appear in the affected files list from the investigator. Adversarially validate the proposed fix against adjacent system layers before posting.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Close subcommand — update project board, final issue body, parent tracker, summary report, trajectory log
3
- argument-hint: [issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--pr PR_NUMBER] [--base PR_BASE] [--branch BRANCH] [--worktree WORKTREE_PATH]
3
+ argument-hint: "[issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--pr PR_NUMBER] [--base PR_BASE] [--branch BRANCH] [--worktree WORKTREE_PATH]"
4
4
  ---
5
5
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
6
6
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Decompose subcommand — break a complex issue into ordered sub-issues, post FORGE:DECOMPOSED, stop
3
- argument-hint: [issue number] [--repo GH_REPO] [--gh-flag GH_FLAG]
3
+ argument-hint: "[issue number] [--repo GH_REPO] [--gh-flag GH_FLAG]"
4
4
  ---
5
5
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
6
6
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -106,30 +106,14 @@ For each sub-issue, prepare:
106
106
 
107
107
  ## Phase D3: Create Sub-Issues
108
108
 
109
- For each sub-issue (in dependency order):
109
+ For each sub-issue (in dependency order), route creation through the `/issue` create-hook's programmatic invocation contract (`commands/issue.md` Programmatic Invocation Contract, added in #2085) instead of calling `gh issue create` directly. `/issue`'s Phase 2D runs the same `scripts/issue-dedup.sh` check this file used to run manually — the standalone pre-check below is removed; dedup is now enforced inside the create-hook on every call, with no bypass path. <!-- Changed: forge#2086 — route through /issue create-hook -->
110
110
 
111
- **Before creating each sub-issue, run the deterministic dedup check:** <!-- Added: forge#1335 -->
111
+ **Compose the sub-issue body to a temp file** (avoids quoting issues when passed as `--body-file`):
112
112
 
113
113
  ```bash
114
114
  SUB_TITLE="{fix|feat|refactor}: {SUB_ISSUE_TITLE}"
115
- DEDUP_RESULT=$(scripts/issue-dedup.sh "$SUB_TITLE" {GH_FLAG} 2>&1)
116
- DEDUP_EXIT=$?
117
- if [ "$DEDUP_EXIT" -eq 1 ]; then
118
- echo "DEDUP: Sub-issue near-duplicate detected — $DEDUP_RESULT"
119
- echo "Skipping creation. Comment on the existing issue instead."
120
- # Do NOT call gh issue create for this sub-issue
121
- elif [ "$DEDUP_EXIT" -eq 2 ]; then
122
- echo "DEDUP: Usage error — $DEDUP_RESULT"
123
- # Do NOT call gh issue create for this sub-issue — fix the invocation and retry
124
- fi
125
- ```
126
-
127
- Only call `gh issue create` when the dedup script exits 0 (no match):
128
-
129
- ```bash
130
- gh issue create {GH_FLAG} \
131
- --title "{fix|feat|refactor}: {SUB_ISSUE_TITLE}" \
132
- --body "$(cat <<'SUB_BODY_EOF'
115
+ SUB_BODY_FILE="$(mktemp)"
116
+ cat > "$SUB_BODY_FILE" <<'SUB_BODY_EOF'
133
117
  ## Problem
134
118
 
135
119
  {1-3 sentences: what this sub-issue specifically addresses. What's wrong or what needs to be built for this sub-task.}
@@ -155,11 +139,30 @@ Files that need changes:
155
139
  **Parent**: #{NUMBER}
156
140
  {If depends on another sub-issue: "**Depends on**: #{SUB_ISSUE_N} — {reason}"}
157
141
  SUB_BODY_EOF
158
- )" \
159
- --label "{PRIORITY_LABEL}" \
160
- --milestone "{MILESTONE_TITLE}"
161
142
  ```
162
143
 
144
+ **Invoke `/issue` in programmatic mode**:
145
+
146
+ ```
147
+ ISSUE_SKILL_OUTPUT=$(Skill(skill="issue", args="--title \"${SUB_TITLE}\" --body-file \"${SUB_BODY_FILE}\" --label \"{PRIORITY_LABEL}\" --milestone \"{MILESTONE_TITLE}\""))
148
+ ```
149
+
150
+ `/issue` runs Phase 2D dedup, Phase 3F body validation, then creates the issue (Phase 4) — no separate pre-check needed on this side.
151
+
152
+ **Extract the created sub-issue number from the Skill output** (see `commands/issue.md` Phase 4C/4E — it echoes `Created: {url}` and reports `**#{NUMBER}**: {title}`):
153
+
154
+ ```bash
155
+ # Match either the "Created: {url}" line (extract trailing /issues/N) or the "**#{NUMBER}**" bold report line.
156
+ SUB_NUMBER=$(echo "$ISSUE_SKILL_OUTPUT" | grep -oE 'issues/[0-9]+' | head -1 | grep -oE '[0-9]+')
157
+ [ -z "$SUB_NUMBER" ] && SUB_NUMBER=$(echo "$ISSUE_SKILL_OUTPUT" | grep -oE '\*\*#[0-9]+\*\*' | head -1 | grep -oE '[0-9]+')
158
+
159
+ if [ -z "$SUB_NUMBER" ]; then
160
+ echo "WARNING: /issue did not report a created issue number for sub-issue '${SUB_TITLE}' — likely a Phase 2D dedup STOP (near-duplicate found) or a usage error. Skipping this sub-issue: do not reference it in the parent tracker or in dependent sub-issue bodies. Review the Skill output above and, if a near-duplicate exists, comment on the existing issue instead."
161
+ fi
162
+ ```
163
+
164
+ If `SUB_NUMBER` is empty, treat this sub-issue as not created — do not add it to the parent tracker checklist (Phase D4) and do not reference it as a dependency in later sub-issues.
165
+
163
166
  **Append Prior Investigation section** (conditional — only if `GIST_URLS` from Phase D1.5 is non-empty):
164
167
 
165
168
  After creating each sub-issue, append the `## Prior Investigation` section containing all parent Gist URLs. This keeps the Gist references machine-readable for downstream agents.
@@ -215,6 +218,13 @@ gh issue edit {NUMBER} {GH_FLAG} --body "${CURRENT_BODY}${TRACKER}"
215
218
 
216
219
  ## Phase D5: Post FORGE:DECOMPOSED Comment
217
220
 
221
+ **Before posting, read the attribution config**:
222
+ ```bash
223
+ SHOW_ATTRIBUTION=$(yq '.branding.show_attribution // "true"' forge.yaml 2>/dev/null || echo "true")
224
+ [ "$SHOW_ATTRIBUTION" = "false" ] && ATTRIBUTION_LINE="" || ATTRIBUTION_LINE="
225
+ > Pipeline powered by [ForgeDock](https://github.com/RapierCraftStudios/ForgeDock)"
226
+ ```
227
+
218
228
  ```bash
219
229
  gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:DECOMPOSED -->
220
230
  ## Decomposition Complete
@@ -229,7 +239,7 @@ This issue has been broken into sub-issues. Each sub-issue runs through its own
229
239
  ### Decomposition Rationale
230
240
 
231
241
  {brief summary of why this issue was decomposed and the dependency ordering chosen}
232
-
242
+ ${ATTRIBUTION_LINE}
233
243
  <!-- FORGE:DECOMPOSED:COMPLETE -->"
234
244
  ```
235
245
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Investigate a GitHub issue — validate it's real, determine root cause, post findings
3
- argument-hint: [issue number] [--repo {owner}/{repo}] [--gh-flag "-R {owner}/{repo}"]
3
+ argument-hint: "[issue number] [--repo {owner}/{repo}] [--gh-flag \"-R {owner}/{repo}\"]"
4
4
  ---
5
5
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
6
6
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -380,7 +380,7 @@ if [ "$ATTRIBUTION_ANNOTATION_LINK" = "true" ]; then
380
380
  ANNOTATION_LINK_FOOTER="
381
381
 
382
382
  ---
383
- *Pipeline powered by [ForgeDock](https://github.com/RapierCraftStudios/ForgeDock)*"
383
+ *⚒️ Pipeline powered by [ForgeDock](https://github.com/RapierCraftStudios/ForgeDock)*"
384
384
  fi
385
385
  ```
386
386
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Remediate subcommand — checkout a needs-human PR, fix review findings, re-review, and re-gate with a FORGE:REMEDIATION paper trail
3
- argument-hint: [PR number] [--issue N] [--repo GH_REPO] [--gh-flag GH_FLAG] [--base PR_BASE]
3
+ argument-hint: "[PR number] [--issue N] [--repo GH_REPO] [--gh-flag GH_FLAG] [--base PR_BASE]"
4
4
  ---
5
5
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
6
6
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Review subcommand — push branch, create PR, invoke /review-pr with --auto-merge
3
- argument-hint: [issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--worktree PATH] [--branch BRANCH] [--base PR_BASE]
3
+ argument-hint: "[issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--worktree PATH] [--branch BRANCH] [--base PR_BASE]"
4
4
  ---
5
5
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
6
6
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -159,7 +159,7 @@ ATTRIBUTION_PR_FOOTER=$(grep -A5 "^attribution:" forge.yaml 2>/dev/null | grep "
159
159
  If `ATTRIBUTION_PR_FOOTER` is `true`, append the following footer to the PR body (once — never duplicate on retries):
160
160
 
161
161
  ```
162
- > Orchestrated with [ForgeDock](https://github.com/RapierCraftStudios/ForgeDock) — state, scheduling, review, and memory on GitHub.
162
+ > ⚒️ Orchestrated with [ForgeDock](https://github.com/RapierCraftStudios/ForgeDock) — state, scheduling, review, and memory on GitHub.
163
163
  ```
164
164
 
165
165
  ### R2C: Create PR
@@ -188,13 +188,15 @@ Closes #{NUMBER}
188
188
  **Implementation branch**: \`{BRANCH}\`
189
189
  **Base**: \`{PR_BASE}\`
190
190
  {IF_ATTRIBUTION_PR_FOOTER_TRUE:
191
- > Orchestrated with [ForgeDock](https://github.com/RapierCraftStudios/ForgeDock) — state, scheduling, review, and memory on GitHub.}"
191
+ > ⚒️ Orchestrated with [ForgeDock](https://github.com/RapierCraftStudios/ForgeDock) — state, scheduling, review, and memory on GitHub.}"
192
192
  ```
193
193
 
194
194
  **Note**: `Closes #{NUMBER}` documents intent but does NOT auto-close for non-default-branch PRs. The close subcommand handles explicit closure after merge.
195
195
 
196
196
  **Attribution guard**: The footer line is appended once at PR creation. If the PR already exists (resume path), do NOT append the footer again — check the existing PR body first.
197
197
 
198
+ **No assistant attribution**: The PR body is exactly the sections above (plus the optional ForgeDock footer). Do NOT add a `🤖 Generated with Claude Code` line, a `Co-Authored-By: Claude` trailer, or any assistant-tool attribution — the pipeline is ForgeDock-branded. A PreToolUse guard hard-blocks it as a backstop (`bin/hooks/pre-tool-use.mjs` Rule 5).
199
+
198
200
  If PR creation fails because a PR already exists for this branch:
199
201
  ```bash
200
202
  gh pr list {GH_FLAG} --head {BRANCH} --json number,url --jq '.[0]'
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: "[BENCHMARK] Monolithic work-on — single-prompt pipeline with no Skill sub-phase boundaries"
3
- argument-hint: [issue number]
3
+ argument-hint: "[issue number]"
4
4
  install: internal
5
5
  ---
6
6
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Pick up a GitHub issue and run the full investigate-build-review-merge pipeline
3
- argument-hint: [issue number or "next" to pick highest priority]
3
+ argument-hint: "[issue number or \"next\" to pick highest priority]"
4
4
  ---
5
5
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
6
6
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -926,10 +926,18 @@ For each sub-issue:
926
926
  - **Milestone**: same as parent
927
927
 
928
928
  ### 2C: Create sub-issues
929
+
930
+ Route through the `/issue` create-hook's programmatic invocation contract (see `commands/issue.md` § "Programmatic Invocation Contract") instead of calling the raw issue-creation command directly — this gets dedup (Phase 2D) and body validation (Phase 3F) for free on every decomposition-spawned sub-issue.
931
+
929
932
  ```bash
930
- gh issue create {GH_FLAG} \
931
- --title "{fix|feat|refactor}: {SUB_ISSUE_TITLE}" \
932
- --body "$(cat <<'SUB_BODY_EOF'
933
+ SUB_ISSUE_TITLE_FULL="{fix|feat|refactor}: {SUB_ISSUE_TITLE}"
934
+ # Defense-in-depth: /issue's arg tokenizer (commands/issue.md, forge#2094) uses
935
+ # an xargs-based tokenizer that never expands backtick/$(...) substitution, so
936
+ # this is no longer required for safety — but strip it anyway so the raw title
937
+ # stays readable if it round-trips through any other eval-based consumer.
938
+ SUB_ISSUE_TITLE_FULL=$(printf '%s' "$SUB_ISSUE_TITLE_FULL" | tr '`' "'" | sed 's/\$(/$ (/g')
939
+ SUB_ISSUE_BODY_FILE=$(mktemp)
940
+ cat <<'SUB_BODY_EOF' > "$SUB_ISSUE_BODY_FILE"
933
941
  ## Problem
934
942
 
935
943
  {1-3 sentences: what this sub-issue specifically addresses. What's wrong or what needs to be built.}
@@ -955,9 +963,22 @@ Files that need changes:
955
963
  **Parent**: #{NUMBER}
956
964
  {If depends on another sub-issue: "**Depends on**: #{SUB_ISSUE_N} — {reason}"}
957
965
  SUB_BODY_EOF
958
- )" \
959
- --label "{PRIORITY_LABEL}" \
960
- --milestone "{MILESTONE_TITLE}"
966
+
967
+ # --milestone is only passed when the parent has one (see Phase 2B — "Milestone: same as parent").
968
+ MILESTONE_ARG=""
969
+ [ -n "{MILESTONE_TITLE}" ] && MILESTONE_ARG="--milestone \"{MILESTONE_TITLE}\""
970
+ Skill(skill="issue", args="--title \"$SUB_ISSUE_TITLE_FULL\" --body-file \"$SUB_ISSUE_BODY_FILE\" --label \"{PRIORITY_LABEL}\" ${MILESTONE_ARG}")
971
+ rm -f "$SUB_ISSUE_BODY_FILE"
972
+
973
+ # /issue has no machine-readable return contract — resolve the created issue's number by
974
+ # exact-title search immediately after the call (used by Phase 2D's tracker checklist).
975
+ # Retry to absorb GitHub Search API indexing lag.
976
+ SUB_ISSUE_NUM=""
977
+ for _resolve_attempt in 1 2 3; do
978
+ SUB_ISSUE_NUM=$(gh issue list {GH_FLAG} --search "in:title \"${SUB_ISSUE_TITLE_FULL}\"" --state open --limit 1 --json number --jq '.[0].number // empty')
979
+ [ -n "$SUB_ISSUE_NUM" ] && break
980
+ sleep 2
981
+ done
961
982
  ```
962
983
 
963
984
  ### 2D: Update parent issue body
package/docs/AIDER.md ADDED
@@ -0,0 +1,264 @@
1
+ # Aider Support
2
+
3
+ ForgeDock has an additive Aider-native install path. The goal is to give Aider
4
+ users access to the ForgeDock pipeline without regressing the existing Claude
5
+ Code or Codex setups.
6
+
7
+ ## Architecture
8
+
9
+ Shared source:
10
+ - `commands/**/*.md` remains the workflow spec for all runtimes
11
+
12
+ Claude Code wrapper:
13
+ - `install.sh` (or `npx forgedock`) symlinks command files into `~/.claude/commands/`
14
+
15
+ Codex wrapper:
16
+ - `install-codex.sh` generates namespaced skills in `~/.codex/skills/`
17
+
18
+ **Aider wrapper** (this document):
19
+ - `install-aider.sh` writes `~/.aider-forge.md` — a conventions file Aider
20
+ loads at session start via `--read`
21
+ - The conventions file provides runtime mapping rules and entry point references
22
+ - Aider reads ForgeDock command specs on demand with `/read $FORGE_HOME/commands/x.md`
23
+
24
+ This is intentionally a conventions-file architecture, not a duplicate command
25
+ tree. The shared `commands/` directory remains the single source of truth.
26
+
27
+ ## Install
28
+
29
+ ### Option A — standalone bash installer
30
+
31
+ ```bash
32
+ cd /path/to/forgedock
33
+ ./install-aider.sh
34
+ ```
35
+
36
+ This writes `~/.aider-forge.md` with ForgeDock conventions and runtime mapping
37
+ rules.
38
+
39
+ ### Option B — via npx forgedock
40
+
41
+ If you already use `npx forgedock` for Claude Code:
42
+
43
+ ```bash
44
+ npx forgedock
45
+ ```
46
+
47
+ When `aider` is detected on your PATH, `npx forgedock` writes `~/.aider-forge.md`
48
+ as an additional install step. No existing Claude Code files are affected.
49
+
50
+ ## Usage
51
+
52
+ ### Per-session (command line)
53
+
54
+ ```bash
55
+ aider --read ~/.aider-forge.md
56
+ ```
57
+
58
+ ### Always-on (`.aider.conf.yml`)
59
+
60
+ Add to your project's `.aider.conf.yml`:
61
+
62
+ ```yaml
63
+ read:
64
+ - ~/.aider-forge.md
65
+ ```
66
+
67
+ Or to `~/.aider.conf.yml` for global application across all projects.
68
+
69
+ ### Loading a pipeline command
70
+
71
+ Once Aider has the conventions file loaded, load a command spec on demand:
72
+
73
+ ```
74
+ /read /path/to/forgedock/commands/work-on.md
75
+ ```
76
+
77
+ Then follow the command spec step by step, using `/run` for all shell
78
+ operations.
79
+
80
+ ## Tool Translation Rules
81
+
82
+ ForgeDock command specs reference Claude Code-specific tools. Translate them
83
+ to Aider equivalents:
84
+
85
+ | Claude Code | Aider equivalent | Notes |
86
+ |-------------|-----------------|-------|
87
+ | `Skill("work-on", args="123")` | `/read $FORGE_HOME/commands/work-on.md` | Load the spec and execute it |
88
+ | `Skill("review-pr", args="456")` | `/read $FORGE_HOME/commands/review-pr.md` | Load the spec and execute it |
89
+ | `Skill("quality-gate")` | `/read $FORGE_HOME/commands/quality-gate.md` | Load the spec and execute it |
90
+ | `Bash("git status")` | `/run git status` | Direct shell execution |
91
+ | `Read("path/to/file")` | Read the file directly | Aider's native file read |
92
+ | `Grep(pattern, path)` | `/run rg 'pattern' path` | Use `rg` (ripgrep) |
93
+ | `Glob("**/*.md")` | `/run find . -name "*.md"` | Shell find |
94
+ | `WebFetch(url)` | `/run curl -s url` | curl or wget |
95
+ | `Agent(...)` / `Task(...)` | Continue the sub-task yourself | No sub-agent support; inline it |
96
+ | `EnterWorktree(path)` | `/run cd path` then use `/run` | Work in worktree directory |
97
+
98
+ ### Nested Skill references
99
+
100
+ When a command spec calls `Skill("x")` or references another command:
101
+
102
+ ```
103
+ # Load the referenced command spec manually:
104
+ /read $FORGE_HOME/commands/x.md
105
+ ```
106
+
107
+ Map command names to file paths:
108
+ - `Skill("work-on")` → `commands/work-on.md`
109
+ - `Skill("review-pr")` → `commands/review-pr.md`
110
+ - `Skill("quality-gate")` → `commands/quality-gate.md`
111
+ - `Skill("orchestrate")` → `commands/orchestrate.md`
112
+
113
+ ## GitHub Operations
114
+
115
+ All FORGE annotations are written to GitHub issue/PR comments via the `gh`
116
+ CLI. Use `/run gh ...` for every GitHub operation.
117
+
118
+ ### Label management
119
+
120
+ ```bash
121
+ /run gh issue edit 123 -R OWNER/REPO --add-label "workflow:investigating"
122
+ /run gh issue edit 123 -R OWNER/REPO --remove-label "workflow:investigating"
123
+ ```
124
+
125
+ ### Reading existing annotations
126
+
127
+ ```bash
128
+ /run gh api repos/OWNER/REPO/issues/123/comments \
129
+ --jq '.[] | select(.body | contains("FORGE:INVESTIGATOR")) | .body'
130
+ ```
131
+
132
+ ### Writing a FORGE annotation comment
133
+
134
+ ```bash
135
+ /run gh issue comment 123 -R OWNER/REPO --body "<!-- FORGE:INVESTIGATOR -->
136
+ ## Investigation Report
137
+
138
+ **Verdict**: CONFIRMED
139
+ ...
140
+ <!-- INVESTIGATION:COMPLETE -->"
141
+ ```
142
+
143
+ For multi-line comment bodies, write the content to a temp file first:
144
+
145
+ ```bash
146
+ cat > /tmp/comment.md << 'EOF'
147
+ <!-- FORGE:INVESTIGATOR -->
148
+ ## Investigation Report
149
+ ...
150
+ <!-- INVESTIGATION:COMPLETE -->
151
+ EOF
152
+ /run gh issue comment 123 -R OWNER/REPO --body "$(cat /tmp/comment.md)"
153
+ ```
154
+
155
+ ### Creating a PR
156
+
157
+ ```bash
158
+ /run gh pr create -R OWNER/REPO \
159
+ --base staging \
160
+ --head feat/my-branch-123 \
161
+ --title "feat: description (#123)" \
162
+ --body "$(cat /tmp/pr_body.md)"
163
+ ```
164
+
165
+ ## Worktrees
166
+
167
+ ForgeDock uses git worktrees to isolate branch work. Create one with:
168
+
169
+ ```bash
170
+ /run git fetch origin
171
+ /run git worktree add .claude/worktrees/feat-my-feature-123 \
172
+ -b feat/my-feature-123 origin/staging
173
+ ```
174
+
175
+ Work inside the worktree for all file edits and commits. Aider's `/run`
176
+ commands execute in the worktree directory if you `cd` to it:
177
+
178
+ ```bash
179
+ /run cd /path/to/repo/.claude/worktrees/feat-my-feature-123
180
+ ```
181
+
182
+ Or pass the path explicitly in each command:
183
+
184
+ ```bash
185
+ /run git -C /path/to/repo/.claude/worktrees/feat-my-feature-123 status
186
+ ```
187
+
188
+ ## FORGE Annotation Protocol
189
+
190
+ Every pipeline stage writes a structured annotation to GitHub. Key rules:
191
+
192
+ 1. **Idempotency**: Check for existing annotations BEFORE starting a phase.
193
+ Do not re-run a completed phase.
194
+ 2. **Compaction resilience**: Write annotations AFTER completing each
195
+ significant step. GitHub is the persistent state layer.
196
+ 3. **Restart partial annotations**: If an annotation exists without its
197
+ `:COMPLETE` sentinel, delete it and restart the phase.
198
+ 4. **Respect label state**: Labels track workflow state. Read and set them
199
+ at each phase boundary.
200
+
201
+ ### Label state machine
202
+
203
+ ```
204
+ workflow:investigating
205
+ → workflow:ready-to-build (investigation complete)
206
+ → workflow:building (build started)
207
+ → workflow:in-review (PR created)
208
+ → workflow:merged (PR merged) [TERMINAL]
209
+
210
+ workflow:invalid [TERMINAL]
211
+ workflow:decomposed [TERMINAL]
212
+ needs-human [TERMINAL]
213
+ ```
214
+
215
+ Stop the pipeline when any terminal label is set.
216
+
217
+ ## Feasibility Analysis
218
+
219
+ Aider is the highest-feasibility non-Claude agent for ForgeDock because:
220
+
221
+ | Capability | Requirement | Aider support |
222
+ |-----------|-------------|---------------|
223
+ | Load instruction files | `--read` flag / `.aider.conf.yml` | Native |
224
+ | Execute shell commands | `gh`, `git`, `rg` via shell | `/run` command |
225
+ | Read/write files | File editing | Native |
226
+ | GitHub API | `gh` CLI | Via `/run gh ...` |
227
+ | Multi-step workflows | Follow sequential instructions | Supported |
228
+ | Compaction resilience | Re-read GitHub state at phase start | Supported (via `/run gh ...`) |
229
+
230
+ **Limitation**: Aider has no native sub-agent/parallel task model (`Agent(...)`,
231
+ `Task(...)`). Phase 3 parallel context gathering (`FORGE:CONTEXT`) and
232
+ multi-agent review (`review-pr-agents.md`) must be executed sequentially.
233
+ For the orchestrate command (`/orchestrate`), run one issue at a time or
234
+ use separate Aider sessions per issue.
235
+
236
+ ## Trust and Configuration
237
+
238
+ Aider does not have a project trust model. Once `~/.aider-forge.md` is loaded,
239
+ all operations in that session have access to shell execution via `/run`.
240
+
241
+ **Security note**: ForgeDock's shell operations are limited to `gh`, `git`,
242
+ `rg`, `find`, and standard POSIX tools. The conventions file does not execute
243
+ arbitrary code at load time — it only provides instruction text.
244
+
245
+ ## Usage Notes
246
+
247
+ - Use `--read ~/.aider-forge.md` on every session, or add it to
248
+ `.aider.conf.yml` for automatic loading.
249
+ - Load command specs on demand with `/read $FORGE_HOME/commands/x.md` —
250
+ do not load all commands at once.
251
+ - Keep `CLAUDE.md` and `AGENTS.md` aligned with ForgeDock conventions;
252
+ Aider and Claude Code can differ at the wrapper layer but not on FORGE
253
+ workflow invariants (annotation format, label state machine, branch
254
+ naming, worktree conventions).
255
+ - For pipeline stages that post FORGE annotations, always write the body
256
+ to a temp file before passing to `gh issue comment` to avoid shell
257
+ quoting issues with multi-line content.
258
+
259
+ ## Reference
260
+
261
+ - [FORGE Protocol spec](FORGE-PROTOCOL.md) — annotation format, label state machine, conformance tests
262
+ - [Codex adapter](CODEX.md) — parallel reference for OpenAI Codex CLI
263
+ - [Pipeline commands](../commands/) — shared workflow specs (authoritative for all runtimes)
264
+ - [`install-aider.sh`](../install-aider.sh) — installer script