forgedock 1.0.22 → 1.1.2
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/README.md +255 -211
- package/bin/batch-runner.mjs +339 -0
- package/bin/cinema.mjs +320 -0
- package/bin/demo.mjs +92 -7
- package/bin/engine/phases.mjs +168 -0
- package/bin/engine/projector.mjs +32 -0
- package/bin/engine/reconcile.mjs +11 -0
- package/bin/engine/runlog.mjs +79 -0
- package/bin/engine/state.mjs +32 -0
- package/bin/engine-cli.mjs +222 -0
- package/bin/engine.mjs +138 -0
- package/bin/forgedock.mjs +896 -1540
- package/bin/hooks/interactive-engine.mjs +509 -0
- package/bin/hooks/pre-tool-use.mjs +498 -0
- package/bin/hooks/subagent-stop-enforce.mjs +197 -0
- package/bin/journey.mjs +841 -0
- package/bin/registry.mjs +139 -0
- package/bin/report.mjs +447 -0
- package/bin/runner.mjs +136 -20
- package/bin/settings-hook.mjs +346 -0
- package/bin/tui.mjs +6 -3
- package/commands/adopt.md +4 -1
- package/commands/analytics.md +4 -1
- package/commands/audit-agents.md +110 -27
- package/commands/audit.md +20 -1
- package/commands/autopilot.md +84 -12
- package/commands/changelog.md +2 -1
- package/commands/ci-audit.md +2 -1
- package/commands/cleanup.md +161 -1
- package/commands/compat-audit.md +2 -1
- package/commands/deploy-info.md +63 -4
- package/commands/design-bench.md +6 -1
- package/commands/design-render-critique-loop.md +2 -1
- package/commands/design.md +1 -0
- package/commands/diagnose.md +2 -1
- package/commands/explain.md +2 -1
- package/commands/forge-stats.md +122 -2
- package/commands/forgedock-init.md +1 -1
- package/commands/geo-audit.md +3 -0
- package/commands/incident-response.md +2 -1
- package/commands/issue.md +24 -3
- package/commands/milestone.md +77 -12
- package/commands/optimize.md +2 -1
- package/commands/orchestrate/config.md +67 -0
- package/commands/orchestrate/phase-1-resolve.md +159 -0
- package/commands/orchestrate/phase-2-triage.md +126 -0
- package/commands/orchestrate/phase-2.5-synthesis.md +156 -0
- package/commands/orchestrate/phase-3-dependency.md +591 -0
- package/commands/orchestrate/phase-4-execution.md +962 -0
- package/commands/orchestrate/phase-5-cleanup.md +47 -0
- package/commands/orchestrate/phase-6-report.md +198 -0
- package/commands/orchestrate/safety.md +62 -0
- package/commands/orchestrate.md +25 -2027
- package/commands/pipeline-health/config.md +34 -0
- package/commands/pipeline-health/phase-1-context.md +180 -0
- package/commands/pipeline-health/phase-2-metrics.md +1729 -0
- package/commands/pipeline-health/phase-3-analyze.md +204 -0
- package/commands/pipeline-health/phase-4-proposals.md +117 -0
- package/commands/pipeline-health/phase-5-report.md +284 -0
- package/commands/pipeline-health/phase-6-summary.md +52 -0
- package/commands/pipeline-health.md +25 -2401
- package/commands/pipeline-resume.md +24 -1
- package/commands/pipeline-status.md +65 -0
- package/commands/qa-sweep.md +4 -1
- package/commands/quality-gate.md +326 -42
- package/commands/replay.md +2 -1
- package/commands/review-pr-agents/api.md +135 -0
- package/commands/review-pr-agents/auth.md +137 -0
- package/commands/review-pr-agents/billing.md +101 -0
- package/commands/review-pr-agents/concurrency.md +145 -0
- package/commands/review-pr-agents/database.md +103 -0
- package/commands/review-pr-agents/frontend.md +89 -0
- package/commands/review-pr-agents/infra.md +385 -0
- package/commands/review-pr-agents/protocols.md +185 -0
- package/commands/review-pr-agents/scraper.md +185 -0
- package/commands/review-pr-agents/security.md +406 -0
- package/commands/review-pr-agents.md +45 -1722
- package/commands/review-pr-staging.md +196 -40
- package/commands/review-pr.md +612 -56
- package/commands/rollback.md +2 -1
- package/commands/scope.md +2 -1
- package/commands/security-audit.md +2 -1
- package/commands/signal-planner.md +623 -0
- package/commands/sync-ecosystem.md +1 -0
- package/commands/test-gate.md +17 -1
- package/commands/validate.md +2 -1
- package/commands/work-on/build/architect.md +28 -0
- package/commands/work-on/build/context.md +2 -0
- package/commands/work-on/build/implement.md +19 -5
- package/commands/work-on/build/validate.md +62 -6
- package/commands/work-on/build.md +187 -30
- package/commands/work-on/close.md +132 -5
- package/commands/work-on/decompose.md +19 -1
- package/commands/work-on/investigate.md +117 -2
- package/commands/work-on/review.md +48 -4
- package/commands/work-on-monolithic.md +8 -2
- package/commands/work-on.md +247 -7
- package/docs/BRAND.md +16 -5
- package/docs/CI.md +2 -2
- package/docs/CODEX.md +36 -1
- package/docs/CONFIG.md +44 -42
- package/docs/FORGE-PROTOCOL.md +15 -1064
- package/docs/anthropic-devrel-outreach.md +2 -2
- package/docs/articles/command-decomposition-token-savings.md +214 -0
- package/docs/articles/model-release-playbook.md +131 -0
- package/docs/articles/per-repo-adaptive-scripts-token-savings.md +27 -25
- package/docs/claude-breakpoints.json +75 -5
- package/docs/design/abc-benchmark.md +1 -1
- package/docs/design/design-spec-schema.md +1 -1
- package/docs/design/divergent-generation.md +1 -1
- package/docs/design/eval-gate-runbook.md +178 -0
- package/docs/design/show-hn-draft.md +26 -1
- package/docs/design/token-cost-baseline-1298.md +59 -0
- package/docs/eval/README.md +117 -0
- package/docs/eval/corpus/seed-v1.json +6 -0
- package/docs/eval/published/claude-sonnet-4-6-2026-07-04.json +33 -0
- package/docs/site/annotations-explained.md +24 -0
- package/docs/site/command-learning-path.md +51 -14
- package/docs/site/command-reference.md +339 -113
- package/docs/site/for-companies.md +95 -0
- package/docs/site/forge-annotation-protocol.md +12 -256
- package/docs/site/getting-started.md +58 -12
- package/docs/site/github-is-the-memory.md +113 -0
- package/docs/site/how-it-works.md +3 -13
- package/docs/site/index.md +10 -2
- package/docs/spec/eval-run-result.md +147 -0
- package/docs/spec/forge-protocol-v1.md +441 -18
- package/docs/spec/label-state-machine.md +55 -0
- package/docs/spec/review-protocol.md +158 -0
- package/docs/spec-graph-schema.md +28 -0
- package/docs/superpowers/plans/2026-07-03-cinematic-onboarding-tui.md +2339 -0
- package/docs/superpowers/plans/2026-07-03-durable-execution-engine.md +1223 -0
- package/docs/superpowers/specs/2026-07-03-cinematic-onboarding-tui-design.md +157 -0
- package/docs/superpowers/specs/2026-07-03-durable-execution-engine-design.md +194 -0
- package/docs/superpowers/specs/2026-07-04-economic-self-governance-design.md +181 -0
- package/docs/superpowers/specs/2026-07-04-provenance-trail-design.md +189 -0
- package/examples/forgedock-demo/README.md +41 -22
- package/examples/forgedock-demo/issues/06-bug-tags-type-validation.md +43 -0
- package/examples/forgedock-demo/issues/07-bug-negative-offset-pagination.md +42 -0
- package/examples/forgedock-demo/issues/08-bug-patch-mass-assignment.md +49 -0
- package/examples/forgedock-demo/issues/09-bug-count-injection.md +47 -0
- package/examples/forgedock-demo/issues/10-feature-sort-param.md +39 -0
- package/examples/forgedock-demo/issues/11-feature-patch-tags.md +37 -0
- package/examples/forgedock-demo/issues/12-feature-bulk-create.md +42 -0
- package/examples/forgedock-demo/issues/13-feature-archive-notes.md +46 -0
- package/examples/forgedock-demo/issues/14-refactor-extract-title-validation.md +41 -0
- package/examples/forgedock-demo/issues/15-refactor-protected-route-flag.md +43 -0
- package/examples/forgedock-demo/issues/16-refactor-extract-store.md +45 -0
- package/examples/forgedock-demo/issues/17-perf-tags-dedup-set.md +35 -0
- package/examples/forgedock-demo/issues/18-perf-remove-redundant-sort.md +37 -0
- package/examples/forgedock-demo/issues/19-docs-api-reference-full.md +53 -0
- package/examples/forgedock-demo/issues/20-docs-intentional-flaw-convention.md +46 -0
- package/examples/forgedock-demo/scripts/smoke.js +18 -1
- package/examples/forgedock-demo/src/db.js +36 -11
- package/examples/forgedock-demo/src/routes/notes.js +106 -9
- package/examples/forgedock-demo/src/server.js +4 -1
- package/package.json +12 -4
- package/packages/protocol/LICENSE +21 -0
- package/packages/protocol/src/cli.js +135 -0
- package/packages/protocol/src/emit.js +146 -0
- package/packages/protocol/src/index.js +43 -0
- package/packages/protocol/src/parse.js +229 -0
- package/packages/protocol/src/types.js +171 -0
- package/packages/protocol/src/validate.js +122 -0
- package/scripts/bench-topology-cost.mjs +372 -0
- package/scripts/check-command-docs-drift.sh +198 -0
- package/scripts/check-protocol-restatements.sh +176 -0
- package/scripts/check-registry/README.md +72 -0
- package/scripts/check-registry/manifest.json +6 -0
- package/scripts/code-index.sh +454 -0
- package/scripts/conformance-check.mjs +168 -0
- package/scripts/doctor-pipeline-state.sh +484 -0
- package/scripts/eval-gate-baseline.json +17 -0
- package/scripts/eval-gate-scorecard.mjs +242 -0
- package/scripts/eval-scorecard-aggregator.mjs +252 -0
- package/scripts/flaky-quarantine.sh +241 -0
- package/scripts/forge-annotation.sh +567 -0
- package/scripts/issue-dedup.sh +236 -0
- package/scripts/validate-annotation-node.mjs +233 -0
- package/scripts/verify-env-vars.sh +18 -2
- package/scripts/verify-host-headers.sh +4 -4
- package/scripts/verify-route-registration.sh +2 -2
- package/scripts/worktree-lifecycle.sh +202 -0
- package/templates/devdocs/agent/using-forgedock.md +14 -0
package/commands/test-gate.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
description: Deterministic deploy-gate — verify a staging→main bundle's acceptance criteria against running code before deploy
|
|
3
3
|
argument-hint: [--prs "<N1 N2 ...>"] [--base <branch>]
|
|
4
4
|
allowed-tools: Task, Bash, Read, Grep, Glob
|
|
5
|
+
install: extras
|
|
5
6
|
---
|
|
6
7
|
<!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
|
|
7
8
|
<!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
|
|
@@ -12,7 +13,22 @@ allowed-tools: Task, Bash, Read, Grep, Glob
|
|
|
12
13
|
|
|
13
14
|
Verifies a staging→main bundle's acceptance criteria against running code before deploy. Called by `/review-pr-staging` (Phase 6.5) with the bundle PRs, or run standalone when `--prs` is absent (computes the bundle itself). Returns a machine-readable BLOCK / PASS / SKIP verdict for the caller to consume.
|
|
14
15
|
|
|
15
|
-
**Agent model policy**:
|
|
16
|
+
**Agent model policy**: `model: "sonnet"` (standard tier). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
|
|
17
|
+
**NEVER use plan mode (EnterPlanMode).**
|
|
18
|
+
**NEVER use the Agent tool** — test-gate dispatches test clusters via `Task` only. The Agent tool bypasses the allowed-tools constraint and produces output that cannot be structured into the machine-readable BLOCK / PASS / SKIP verdict.
|
|
19
|
+
|
|
20
|
+
<!-- FORGE:SPEC_LOADED — test-gate.md loaded and active. Agent is bound by this spec. -->
|
|
21
|
+
|
|
22
|
+
## Forbidden Tools Self-Check
|
|
23
|
+
|
|
24
|
+
**Before executing any phase**, verify you are NOT using any of these tools:
|
|
25
|
+
|
|
26
|
+
| Tool | Status | Reason |
|
|
27
|
+
|------|--------|--------|
|
|
28
|
+
| `Agent` | **FORBIDDEN** | Bypasses allowed-tools constraint; produces unstructured output that cannot be parsed into the machine-readable BLOCK / PASS / SKIP verdict |
|
|
29
|
+
| `EnterPlanMode` | **FORBIDDEN** | Breaks execution context; gate phases must execute, not be planned |
|
|
30
|
+
|
|
31
|
+
If you find yourself about to call `Agent(...)`, stop and use `Task(...)` instead.
|
|
16
32
|
|
|
17
33
|
**Posture**: Blocking-with-override at the staging→main boundary (mirrors the Phase 0A open-finding gate in `/review-pr-staging`). Posture is config-driven via `verification.test_gate`.
|
|
18
34
|
|
package/commands/validate.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Independently verify if a reported issue is actually a problem before making code changes.
|
|
3
3
|
argument-hint: [issue description or #number]
|
|
4
|
+
install: extras
|
|
4
5
|
---
|
|
5
6
|
<!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
|
|
6
7
|
<!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
|
|
@@ -11,7 +12,7 @@ argument-hint: [issue description or #number]
|
|
|
11
12
|
|
|
12
13
|
Verify whether a reported issue is real before anyone writes code. This command exists for reports that come from outside the pipeline — user complaints, DevOps alerts, monitoring triggers, gut feelings. It is the checkpoint before creating a GitHub issue.
|
|
13
14
|
|
|
14
|
-
**Agent model policy**:
|
|
15
|
+
**Agent model policy**: `model: "sonnet"` (standard tier). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
|
|
15
16
|
|
|
16
17
|
**Output**: A verdict (CONFIRMED / NOT A PROBLEM / NEEDS MORE DATA) with evidence.
|
|
17
18
|
|
|
@@ -11,6 +11,11 @@ argument-hint: [issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--files AFFE
|
|
|
11
11
|
**Time budget**: Max 3 minutes. Skip any file read that times out.
|
|
12
12
|
**Output**: Post `<!-- FORGE:ARCHITECT -->` comment on the issue, then return structured plan to caller.
|
|
13
13
|
|
|
14
|
+
**Agent model policy**: `model: "sonnet"`, `effort: xhigh` (deep tier — full code-path tracing, multi-file architecture planning). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` only on Claude Code >= 2.1.154.
|
|
15
|
+
**NEVER use plan mode (EnterPlanMode).**
|
|
16
|
+
|
|
17
|
+
<!-- FORGE:SPEC_LOADED — work-on/build/architect.md loaded and active. Agent is bound by this spec. -->
|
|
18
|
+
|
|
14
19
|
---
|
|
15
20
|
|
|
16
21
|
## COMPLEXITY_BAND Guard (check BEFORE all phases)
|
|
@@ -50,6 +55,7 @@ Parse from $ARGUMENTS:
|
|
|
50
55
|
Also read from the calling context (in-memory, passed by parent agent):
|
|
51
56
|
- `{INVESTIGATION_REPORT}` — full text of FORGE:INVESTIGATOR comment
|
|
52
57
|
- `{CONTEXT_BRIEFING}` — full text of FORGE:CONTEXT comment (empty string if context step was skipped)
|
|
58
|
+
- `{MEMORY_PRIORS}` — structured prior run blocks emitted by investigate Phase 0.5 (empty string if no priors found or investigate predates memory). When non-empty, treat each `[MEMORY PRIOR]` block as a high-confidence prior: if any prior's affected files overlap with the current plan's affected files, explicitly note the prior's root cause and key lesson in the FORGE:ARCHITECT comment's **Prior Run Priors** section (add this section after **Context Briefing** when priors exist). <!-- Added: forge#1316 -->
|
|
53
59
|
|
|
54
60
|
If any of these are not passed directly, read them from GitHub (fallback/recovery path):
|
|
55
61
|
|
|
@@ -316,6 +322,28 @@ agent defaults ← Built-in behaviors
|
|
|
316
322
|
|
|
317
323
|
Identify every entry point that initiates the affected logic. Start from the files named in the investigation report.
|
|
318
324
|
|
|
325
|
+
### A1.0: Code Index Query (run FIRST — deterministic, one tool call)
|
|
326
|
+
|
|
327
|
+
If `scripts/code-index.sh` exists under `{REPO_PATH}`, query the pre-built index before any grep. The index provides caller lists and import graphs without re-scanning the repo:
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
# Ensure index is current (cache-hit on unchanged HEAD — instant if already built)
|
|
331
|
+
bash {REPO_PATH}/scripts/code-index.sh --repo-path {REPO_PATH} 2>/dev/null || true
|
|
332
|
+
|
|
333
|
+
# Get callers of the primary function under change
|
|
334
|
+
bash {REPO_PATH}/scripts/code-index.sh query --callers {PRIMARY_FUNCTION} --repo-path {REPO_PATH} 2>/dev/null || true
|
|
335
|
+
|
|
336
|
+
# Get all files that import the affected module
|
|
337
|
+
bash {REPO_PATH}/scripts/code-index.sh query --importers {AFFECTED_FILE} --repo-path {REPO_PATH} 2>/dev/null || true
|
|
338
|
+
|
|
339
|
+
# Get all files in the same domain as affected files (for sibling path detection)
|
|
340
|
+
bash {REPO_PATH}/scripts/code-index.sh query --domain {DOMAIN} --repo-path {REPO_PATH} 2>/dev/null || true
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Use index results to populate the caller list and sibling candidates below. If the index returns results, **skip the grep fallback** — do not re-scan what the index already answered. If the index is absent or returns nothing, fall back to grep.
|
|
344
|
+
|
|
345
|
+
### A1.1: Grep fallback (only when index absent or returned no results)
|
|
346
|
+
|
|
319
347
|
For each affected file, read it and identify:
|
|
320
348
|
1. The primary function/method being changed
|
|
321
349
|
2. All callers of that function (grep for usages)
|
|
@@ -11,6 +11,8 @@ argument-hint: [issue number] [affected_files...] [--functions function_names...
|
|
|
11
11
|
**Time budget**: Max 2 minutes of queries. Skip any query that times out.
|
|
12
12
|
**Output**: Post `<!-- FORGE:CONTEXT -->` comment on the issue, then return structured briefing to caller.
|
|
13
13
|
|
|
14
|
+
<!-- FORGE:SPEC_LOADED — work-on/build/context.md loaded and active. Agent is bound by this spec. -->
|
|
15
|
+
|
|
14
16
|
---
|
|
15
17
|
|
|
16
18
|
## COMPLEXITY_BAND Guard (check BEFORE all phases)
|
|
@@ -12,9 +12,11 @@ argument-hint: [issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--worktree P
|
|
|
12
12
|
**Invoked by**: `work-on.md` Step 3F, after worktree is created and context is gathered.
|
|
13
13
|
**Output**: Write code, commit(s), post `<!-- FORGE:BUILDER -->` comment, return result to caller.
|
|
14
14
|
|
|
15
|
-
**Agent model policy**:
|
|
15
|
+
**Agent model policy**: `model: "sonnet"` (standard tier). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
|
|
16
16
|
**NEVER use plan mode (EnterPlanMode).**
|
|
17
17
|
|
|
18
|
+
<!-- FORGE:SPEC_LOADED — work-on/build/implement.md loaded and active. Agent is bound by this spec. -->
|
|
19
|
+
|
|
18
20
|
---
|
|
19
21
|
|
|
20
22
|
## Inputs
|
|
@@ -53,7 +55,17 @@ gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
|
|
|
53
55
|
--jq '.[] | select(.body | contains("FORGE:CONTEXT")) | .body'
|
|
54
56
|
```
|
|
55
57
|
|
|
56
|
-
**Resume check**:
|
|
58
|
+
**Resume check**:
|
|
59
|
+
- If `<!-- FORGE:BUILDER:COMPLETE -->` is present in a BUILDER comment → implementation is done — EXIT and return `IMPLEMENT_RESULT: status: ALREADY_DONE` to caller.
|
|
60
|
+
- If `<!-- FORGE:BUILDER -->` exists BUT `<!-- FORGE:BUILDER:COMPLETE -->` is ABSENT → implementation was interrupted after the comment was posted but before the commit (validate.md V5). Delete the partial comment and restart from Phase I2:
|
|
61
|
+
```bash
|
|
62
|
+
PARTIAL_ID=$(gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
|
|
63
|
+
--jq '[.[] | select(.body | contains("FORGE:BUILDER") and (contains("FORGE:BUILDER:COMPLETE") | not))] | last | .id // ""')
|
|
64
|
+
if [ -n "$PARTIAL_ID" ]; then
|
|
65
|
+
gh api repos/{GH_REPO}/issues/comments/$PARTIAL_ID -X DELETE
|
|
66
|
+
echo "Deleted partial FORGE:BUILDER comment (no FORGE:BUILDER:COMPLETE) — restarting implementation"
|
|
67
|
+
fi
|
|
68
|
+
```
|
|
57
69
|
|
|
58
70
|
**Primary guide**: If `<!-- FORGE:ARCHITECT -->` is present, it is the **primary implementation input**. Follow its ordered implementation list exactly — it defines which files change, in what order, and what consistency checks must pass. The investigation report and contract are secondary context.
|
|
59
71
|
|
|
@@ -225,6 +237,8 @@ gh issue edit {NUMBER} {GH_FLAG} --body "{UPDATED_BODY}"
|
|
|
225
237
|
|
|
226
238
|
## Phase I6: Post FORGE:BUILDER Comment
|
|
227
239
|
|
|
240
|
+
Post the implementation summary comment. **Do NOT include `<!-- FORGE:BUILDER:COMPLETE -->` here** — that marker is posted by `validate.md` Phase V5 after the commit succeeds. A crash between I6 and V5 would otherwise leave a completion-marked comment with no commit on the branch.
|
|
241
|
+
|
|
228
242
|
```bash
|
|
229
243
|
gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:BUILDER -->
|
|
230
244
|
## Implementation Complete
|
|
@@ -247,11 +261,11 @@ gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:BUILDER -->
|
|
|
247
261
|
- [ ] {Test scenario 2} [type:unit]
|
|
248
262
|
- [ ] {Test scenario 3} [type:e2e]
|
|
249
263
|
|
|
250
|
-
> **Test-type annotation** (optional): Append `[type:api]`, `[type:unit]`, `[type:e2e]`, or `[type:manual]` to each checklist item. The test gate reads this annotation directly and skips regex inference. Omit it to rely on regex classification fallback.
|
|
251
|
-
|
|
252
|
-
<!-- FORGE:BUILDER:COMPLETE -->"
|
|
264
|
+
> **Test-type annotation** (optional): Append `[type:api]`, `[type:unit]`, `[type:e2e]`, or `[type:manual]` to each checklist item. The test gate reads this annotation directly and skips regex inference. Omit it to rely on regex classification fallback."
|
|
253
265
|
```
|
|
254
266
|
|
|
267
|
+
**Note**: `<!-- FORGE:BUILDER:COMPLETE -->` is intentionally absent from this comment. It is appended to this comment by `validate.md` Phase V5 after the git commit completes — see `validate.md § Phase V5`. This ordering ensures the completion marker only exists when a real commit is present on the branch.
|
|
268
|
+
|
|
255
269
|
---
|
|
256
270
|
|
|
257
271
|
## Output
|
|
@@ -12,9 +12,11 @@ argument-hint: [issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--worktree P
|
|
|
12
12
|
**Invoked by**: `work-on.md` Step 3F.5, after `implement.md` has written and staged code (not committed).
|
|
13
13
|
**Output**: Return `GATE_PASSED: true/false` to caller. On failure after max iterations, post comment and set `needs-human`.
|
|
14
14
|
|
|
15
|
-
**Agent model policy**:
|
|
15
|
+
**Agent model policy**: `model: "sonnet"` (standard tier). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
|
|
16
16
|
**NEVER use plan mode (EnterPlanMode).**
|
|
17
17
|
|
|
18
|
+
<!-- FORGE:SPEC_LOADED — work-on/build/validate.md loaded and active. Agent is bound by this spec. -->
|
|
19
|
+
|
|
18
20
|
---
|
|
19
21
|
|
|
20
22
|
## Inputs
|
|
@@ -52,10 +54,22 @@ while iteration < max_iterations:
|
|
|
52
54
|
GATE_PASSED = true
|
|
53
55
|
break
|
|
54
56
|
else:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
# Separate quarantined test findings from real blocker findings.
|
|
58
|
+
# quality-gate Step 2R classifies each failing test as PRE_BROKEN, FLAKY, or REAL.
|
|
59
|
+
# TEST-QUARANTINE findings (LOW) are advisory — do not fix, do not count as gate failures.
|
|
60
|
+
# TEST-REAL findings (HIGH) and all other HIGH/MEDIUM findings must be fixed.
|
|
61
|
+
quarantine_findings = findings where severity == LOW and code starts with "TEST-QUARANTINE"
|
|
62
|
+
blocker_findings = findings where code != "TEST-QUARANTINE"
|
|
63
|
+
|
|
64
|
+
if blocker_findings is empty:
|
|
65
|
+
# All remaining findings are quarantined tests — gate passes from the builder's perspective.
|
|
66
|
+
GATE_PASSED = true
|
|
67
|
+
break
|
|
68
|
+
else:
|
|
69
|
+
Fix each HIGH and MEDIUM finding in blocker_findings at {WORKTREE_PATH}
|
|
70
|
+
(Do NOT commit yet — fixes are staged for the next gate run)
|
|
71
|
+
|
|
72
|
+
if iteration == max_iterations AND result != PASS AND blocker_findings not empty:
|
|
59
73
|
GATE_PASSED = false
|
|
60
74
|
→ post comment (see V1-FAIL below)
|
|
61
75
|
→ add label needs-human
|
|
@@ -71,6 +85,7 @@ Skill("quality-gate", args="{CHANGED_FILES} --worktree {WORKTREE_PATH}")
|
|
|
71
85
|
- Re-run after EVERY fix pass — never trust that fixes resolved findings without verification
|
|
72
86
|
- Each iteration re-scans ALL changed files — fixes can introduce new issues
|
|
73
87
|
- Only HIGH and MEDIUM findings must be fixed; LOW findings are advisory only
|
|
88
|
+
- `TEST-QUARANTINE | LOW` findings (pre-broken or flaky tests classified by Step 2R) do **not** require fixing and do **not** count toward gate failure — include them in the V5 commit comment for reviewer visibility
|
|
74
89
|
|
|
75
90
|
**V1-FAIL comment** (post when gate never passes):
|
|
76
91
|
```bash
|
|
@@ -90,7 +105,12 @@ Needs human review before proceeding to commit.
|
|
|
90
105
|
|
|
91
106
|
## Phase V2: Format and Verify
|
|
92
107
|
|
|
93
|
-
Run after quality gate passes. All tool commands are read from `forge.yaml → verification.commands`; each step logs `SKIPPED — not configured` when the corresponding key is absent rather than silently passing
|
|
108
|
+
Run after quality gate passes. All tool commands are read from `forge.yaml → verification.commands`; each step logs `SKIPPED — not configured` when the corresponding key is absent rather than silently passing.
|
|
109
|
+
|
|
110
|
+
**Track skipped checks** — initialize before any check runs:
|
|
111
|
+
```bash
|
|
112
|
+
SKIPPED_CHECKS=""
|
|
113
|
+
```
|
|
94
114
|
|
|
95
115
|
**Python**:
|
|
96
116
|
```bash
|
|
@@ -101,6 +121,7 @@ if [ -n "$PYTHON_FORMAT" ]; then
|
|
|
101
121
|
eval "$PYTHON_FORMAT" 2>&1
|
|
102
122
|
else
|
|
103
123
|
echo "SKIPPED — python.format not configured in verification.commands"
|
|
124
|
+
SKIPPED_CHECKS="${SKIPPED_CHECKS:+$SKIPPED_CHECKS, }python.format"
|
|
104
125
|
fi
|
|
105
126
|
|
|
106
127
|
# Compile check always runs for Python files (no config needed — catches syntax errors)
|
|
@@ -120,6 +141,7 @@ if [ -n "$TS_FORMAT" ]; then
|
|
|
120
141
|
eval "$TS_FORMAT" 2>&1
|
|
121
142
|
else
|
|
122
143
|
echo "SKIPPED — typescript.format not configured in verification.commands"
|
|
144
|
+
SKIPPED_CHECKS="${SKIPPED_CHECKS:+$SKIPPED_CHECKS, }typescript.format"
|
|
123
145
|
fi
|
|
124
146
|
|
|
125
147
|
if [ -n "$TS_TYPECHECK" ]; then
|
|
@@ -130,6 +152,7 @@ elif [ -n "$TS_BUILD" ]; then
|
|
|
130
152
|
TS_EXIT=$?
|
|
131
153
|
else
|
|
132
154
|
echo "SKIPPED — typescript.typecheck and typescript.build not configured in verification.commands"
|
|
155
|
+
SKIPPED_CHECKS="${SKIPPED_CHECKS:+$SKIPPED_CHECKS, }typescript.typecheck/build"
|
|
133
156
|
TS_EXIT=0
|
|
134
157
|
fi
|
|
135
158
|
```
|
|
@@ -287,6 +310,36 @@ If `origin/{PR_BASE}` does not exist yet (new branch), skip this check — no co
|
|
|
287
310
|
git ls-remote --exit-code origin {PR_BASE} >/dev/null 2>&1 || echo "PR_BASE not on origin — skipping ancestry audit"
|
|
288
311
|
```
|
|
289
312
|
|
|
313
|
+
### V5 Post-Commit: Mark Build Complete (MANDATORY)
|
|
314
|
+
|
|
315
|
+
After the ancestry audit passes (or is skipped), append `<!-- FORGE:BUILDER:COMPLETE -->` to the existing FORGE:BUILDER comment. This is the **only** place this marker is written — it signals that a real commit exists on the branch and the build is safe to resume-skip. <!-- Added: forge#1305 -->
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
# Find the FORGE:BUILDER comment posted by implement.md Phase I6
|
|
319
|
+
BUILDER_COMMENT_ID=$(gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
|
|
320
|
+
--jq '[.[] | select(.body | contains("FORGE:BUILDER") and (contains("FORGE:BUILDER:COMPLETE") | not))] | last | .id // ""')
|
|
321
|
+
|
|
322
|
+
if [ -n "$BUILDER_COMMENT_ID" ]; then
|
|
323
|
+
# Fetch current body and append the completion marker plus best-effort cost signal
|
|
324
|
+
CURRENT_BODY=$(gh api repos/{GH_REPO}/issues/comments/$BUILDER_COMMENT_ID --jq '.body')
|
|
325
|
+
# Best-effort cost append: only include if session telemetry provides a value; never block
|
|
326
|
+
PHASE_COST_LINE=""
|
|
327
|
+
[ -n "${PHASE_COST_USD:-}" ] && PHASE_COST_LINE="
|
|
328
|
+
cost_usd: ${PHASE_COST_USD}"
|
|
329
|
+
UPDATED_BODY="${CURRENT_BODY}${PHASE_COST_LINE}
|
|
330
|
+
|
|
331
|
+
<!-- FORGE:BUILDER:COMPLETE -->"
|
|
332
|
+
gh api repos/{GH_REPO}/issues/comments/$BUILDER_COMMENT_ID \
|
|
333
|
+
-X PATCH \
|
|
334
|
+
--field body="$UPDATED_BODY"
|
|
335
|
+
echo "FORGE:BUILDER:COMPLETE appended to comment $BUILDER_COMMENT_ID"
|
|
336
|
+
else
|
|
337
|
+
echo "WARNING: FORGE:BUILDER comment not found or already marked complete — skipping BUILDER:COMPLETE append"
|
|
338
|
+
fi
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
**Why here and not in implement.md**: The commit (`git commit`) runs in this phase (V5). Appending `:COMPLETE` after the commit ensures that a session crash between implement.md I6 (comment posted) and this step (commit) leaves a partial BUILDER comment without `:COMPLETE`. The next resume will detect the partial comment, delete it, and restart the build. See `implement.md § Phase I1 resume check`.
|
|
342
|
+
|
|
290
343
|
---
|
|
291
344
|
|
|
292
345
|
## Output
|
|
@@ -302,6 +355,9 @@ VALIDATE_RESULT:
|
|
|
302
355
|
deploy_completeness_fixes: [{VAR_NAME: location_added}, ...]
|
|
303
356
|
commits_added: [{SHA}, ...] # from V5 if any
|
|
304
357
|
blocker: {description if gate_passed=false}
|
|
358
|
+
verification_skipped: [] # empty when all configured checks ran; list of skipped check names otherwise
|
|
359
|
+
# e.g. ["python.format", "typescript.typecheck/build"]
|
|
360
|
+
# populated from SKIPPED_CHECKS in Phase V2
|
|
305
361
|
```
|
|
306
362
|
|
|
307
363
|
---
|
|
@@ -9,13 +9,31 @@ argument-hint: [issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--base PR_BA
|
|
|
9
9
|
|
|
10
10
|
**Input**: $ARGUMENTS
|
|
11
11
|
|
|
12
|
-
**Invoked by**: `work-on.md`
|
|
13
|
-
**Output**: Create worktree, post contract,
|
|
12
|
+
**Invoked by**: `work-on.md` Phase 3 — entered when the issue carries label `workflow:ready-to-build` or `workflow:building` (see Universal Phase Dispatcher in work-on.md).
|
|
13
|
+
**Output**: Create worktree, post contract, run build phases, return result to work-on.md.
|
|
14
14
|
|
|
15
|
-
**Agent model policy**:
|
|
15
|
+
**Agent model policy**: `model: "sonnet"` (standard tier). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
|
|
16
16
|
**NEVER use plan mode (EnterPlanMode).**
|
|
17
17
|
|
|
18
|
-
**CRITICAL: You MUST execute ALL phases B0–B6 in order.
|
|
18
|
+
**CRITICAL: You MUST execute ALL phases B0–B6 in order. Phases B3 (context) and B4 (architect) are skipped ONLY when COMPLEXITY_BAND: TRIVIAL (read from FORGE:FAST_PATH comment in Phase B0). For STANDARD and COMPLEX tasks they are NOT optional — skipping them degrades build quality.**
|
|
19
|
+
|
|
20
|
+
### Canonical Build Path (STANDARD/fast-lane) <!-- Added: forge#1276 -->
|
|
21
|
+
|
|
22
|
+
**Default execution model: inline.** For STANDARD and fast-lane issues, phases B3 (context gathering) and B4 (architecture planning) run **inline in the current context window** — not as separate `Skill()` sub-agent spawns. B5 (implement) and B6 (validate) also run inline.
|
|
23
|
+
|
|
24
|
+
`Skill()` invocations for context/architect sub-phases are only permitted when the Spawn-Decision Table (work-on.md `##Spawn-Decision Policy`) explicitly applies — specifically Row (c) (parent context near overflow: ≥20 Skill invocations or ≥10 files already changed before the build sub-phase). For most issues, the Skill() forms shown in B3 and B4 below are **reference documentation** describing the sub-phase contract, not mandatory sub-agent invocations.
|
|
25
|
+
|
|
26
|
+
**Build topology summary**:
|
|
27
|
+
|
|
28
|
+
| Path | When | Phases |
|
|
29
|
+
|------|------|--------|
|
|
30
|
+
| **STANDARD/fast-lane (default)** | All issues not matching exceptions below | B0 → B1 → B2 → B2.5 → [B3] → [B4] → B5 → B6 — all inline |
|
|
31
|
+
| **Spawn exception (Row c)** | ≥20 Skill invocations OR ≥10 files changed before build | Spawn B3/B4 as fresh sub-agents via `Skill()` |
|
|
32
|
+
| **TRIVIAL fast-path** | COMPLEXITY_BAND: TRIVIAL | Skip B3 and B4 entirely |
|
|
33
|
+
|
|
34
|
+
This resolves the three-topology conflict: `work-on.md` Phase 3 (inline 3A–3M), `work-on/build.md` (this file), and `work-on-monolithic.md` ([BENCHMARK]) all describe the **same canonical inline path**. `work-on/build.md` adds worktree lifecycle management (B1) and the FORGE:CONTRACT handoff (B2) that the monolithic variant omits for brevity. The `Skill()` forms in B3/B4 below document the sub-phase contract and serve as the exception path only. <!-- Added: forge#1276 -->
|
|
35
|
+
|
|
36
|
+
<!-- FORGE:SPEC_LOADED — work-on/build.md loaded and active. Agent is bound by this spec. -->
|
|
19
37
|
|
|
20
38
|
---
|
|
21
39
|
|
|
@@ -27,6 +45,8 @@ Parse from $ARGUMENTS:
|
|
|
27
45
|
- `--gh-flag {GH_FLAG}` — gh CLI repo flag (e.g. `-R {owner}/{repo}`)
|
|
28
46
|
- `--base {PR_BASE}` — PR target branch (e.g. `milestone/modular-pipeline-architecture` or `staging`)
|
|
29
47
|
|
|
48
|
+
**Phase notation**: This file uses **B0–B6** for its own phases. The calling orchestrator (`work-on.md`) uses **3A–3M** for its sub-phases. Mapping: work-on.md Phase 3A = B0 (load state), Phase 3B = complexity classification (posts `FORGE:FAST_PATH` before invoking build), Phase 3C onward maps to B1+ in this file. When cross-references mention "Phase 3B", they refer to work-on.md's Phase 3B, not a phase in this file. <!-- Added: forge#1380 -->
|
|
49
|
+
|
|
30
50
|
---
|
|
31
51
|
|
|
32
52
|
## Phase B0: Load State from GitHub (MANDATORY)
|
|
@@ -46,7 +66,16 @@ gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
|
|
|
46
66
|
```
|
|
47
67
|
|
|
48
68
|
**Resume check**:
|
|
49
|
-
- If `<!-- FORGE:BUILDER -->` comment
|
|
69
|
+
- If `<!-- FORGE:BUILDER:COMPLETE -->` is present in a BUILDER comment → build already complete. Return `BUILD_RESULT: status: ALREADY_DONE` to router.
|
|
70
|
+
- If `<!-- FORGE:BUILDER -->` exists BUT `<!-- FORGE:BUILDER:COMPLETE -->` is ABSENT → build was interrupted after the comment was posted but before the commit (validate.md V5). Delete the partial comment and restart from Phase B2 (contract): <!-- Added: forge#1305 -->
|
|
71
|
+
```bash
|
|
72
|
+
PARTIAL_ID=$(gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
|
|
73
|
+
--jq '[.[] | select(.body | contains("FORGE:BUILDER") and (contains("FORGE:BUILDER:COMPLETE") | not))] | last | .id // ""')
|
|
74
|
+
if [ -n "$PARTIAL_ID" ]; then
|
|
75
|
+
gh api repos/{GH_REPO}/issues/comments/$PARTIAL_ID -X DELETE
|
|
76
|
+
echo "Deleted partial FORGE:BUILDER comment (no FORGE:BUILDER:COMPLETE) — restarting build from Phase B2"
|
|
77
|
+
fi
|
|
78
|
+
```
|
|
50
79
|
- If no `<!-- FORGE:INVESTIGATOR -->` comment with `<!-- INVESTIGATION:COMPLETE -->` → EXIT with `BUILD_RESULT: status: BLOCKED`, blocker: "Investigation not complete — run investigate first".
|
|
51
80
|
|
|
52
81
|
Extract from investigation report:
|
|
@@ -55,7 +84,7 @@ Extract from investigation report:
|
|
|
55
84
|
- Recommendation
|
|
56
85
|
- Task type (Bug Fix / Feature / Refactor / Maintenance / UI/UX / Full-Stack)
|
|
57
86
|
|
|
58
|
-
**Read COMPLEXITY_BAND** (from FORGE:FAST_PATH comment posted by Phase 3B):
|
|
87
|
+
**Read COMPLEXITY_BAND** (from `FORGE:FAST_PATH` comment posted by Phase 3B of `work-on.md` — the complexity classification step that runs before invoking this file): <!-- Fixed: forge#1380 -->
|
|
59
88
|
```bash
|
|
60
89
|
COMPLEXITY_BAND=$(gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
|
|
61
90
|
--jq '.[] | select(.body | contains("FORGE:FAST_PATH")) | .body' 2>/dev/null \
|
|
@@ -82,6 +111,14 @@ Append `-{NUMBER}` to ensure uniqueness: e.g. `fix/work-on-build-landing-file-85
|
|
|
82
111
|
|
|
83
112
|
- Review-finding issue → parse `**Code branch**: \`{branch}\`` from issue body; branch from `origin/{branch}`
|
|
84
113
|
- **Milestone review-finding hybrid lane** (ONLY when Code branch matches `milestone/*`): This is a high-risk lane. The worktree will carry the full milestone history. The PR target is `staging` (or the base specified). **DANGER: Agents MUST NOT use `git merge` to resolve any conflicts in this lane.** Merge-based conflict resolution will pull the entire milestone commit tree onto staging, contaminating it with unapproved code. Use `git rebase` or `git cherry-pick` only. If conflicts cannot be resolved without a merge, post a comment on the issue, add `needs-human`, and STOP.
|
|
114
|
+
- **Missing ref fallback**: After parsing, verify the Code branch still exists on remote. If not, fall back to the lane default (`staging` for fast lane, `milestone/{slug}` for feature lane) and note the fallback:
|
|
115
|
+
```bash
|
|
116
|
+
SOURCE_BRANCH="{CODE_BRANCH_FROM_ISSUE_BODY}"
|
|
117
|
+
if ! git ls-remote --exit-code origin "$SOURCE_BRANCH" >/dev/null 2>&1; then
|
|
118
|
+
echo "WARNING: Code branch '$SOURCE_BRANCH' not found on remote — falling back to lane default '$PR_BASE'"
|
|
119
|
+
SOURCE_BRANCH="$PR_BASE"
|
|
120
|
+
fi
|
|
121
|
+
```
|
|
85
122
|
- Feature lane (has milestone) → branch from `origin/{PR_BASE}`
|
|
86
123
|
- Fast lane (no milestone) → branch from `origin/staging`
|
|
87
124
|
|
|
@@ -175,44 +212,46 @@ If `FUNCTION_NAMES` is non-empty, it will be passed via `--functions` to the con
|
|
|
175
212
|
|
|
176
213
|
## Phase B3: Context Gathering (MANDATORY for STANDARD/COMPLEX — skip for TRIVIAL)
|
|
177
214
|
|
|
178
|
-
**Skip if COMPLEXITY_BAND: TRIVIAL** (read from FORGE:FAST_PATH in Phase B0) —
|
|
215
|
+
**Skip if COMPLEXITY_BAND: TRIVIAL** (read from FORGE:FAST_PATH in Phase B0) — skip this phase entirely. Proceed directly to Phase B4.
|
|
179
216
|
|
|
180
|
-
**For STANDARD and COMPLEX tasks**: Always
|
|
217
|
+
**For STANDARD and COMPLEX tasks**: Always run. Do NOT skip without a TRIVIAL COMPLEXITY_BAND.
|
|
181
218
|
|
|
182
|
-
|
|
219
|
+
**Execution model**: Run **inline** (see Canonical Build Path above). Read the `commands/work-on/build/context.md` spec and execute its steps directly in this context window. Only spawn a Skill() sub-agent when the Spawn-Decision Table Row (c) applies (≥20 prior Skill invocations or ≥10 files already changed). <!-- Added: forge#1276 -->
|
|
183
220
|
|
|
184
|
-
|
|
185
|
-
Skill("work-on:build:context", args="{NUMBER} --repo {GH_REPO} --gh-flag {GH_FLAG} --repo-path {WORKTREE_PATH} {AFFECTED_FILES} --functions {FUNCTION_NAMES}")
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
If `FUNCTION_NAMES` is empty, omit the `--functions` flag entirely:
|
|
221
|
+
Surface historical review findings and bug patterns for the affected files. The full step-by-step logic is defined in `commands/work-on/build/context.md`. Key steps: search closed issues with `review-finding` label on the affected files; check git log for past bug patterns; synthesize a `FORGE:CONTEXT` annotation and post it as a GitHub comment.
|
|
189
222
|
|
|
223
|
+
**Spawn exception** (only when Row (c) applies):
|
|
190
224
|
```
|
|
191
|
-
Skill("work-on:build:context", args="{NUMBER} --repo {GH_REPO} --gh-flag {GH_FLAG} --repo-path {WORKTREE_PATH} {AFFECTED_FILES}")
|
|
225
|
+
Skill("work-on:build:context", args="{NUMBER} --repo {GH_REPO} --gh-flag {GH_FLAG} --repo-path {WORKTREE_PATH} {AFFECTED_FILES} --functions {FUNCTION_NAMES}")
|
|
192
226
|
```
|
|
227
|
+
If `FUNCTION_NAMES` is empty, omit `--functions`. The Skill() form above is the exception path — not the default. <!-- Added: forge#1276 -->
|
|
193
228
|
|
|
194
|
-
**After
|
|
195
|
-
-
|
|
196
|
-
-
|
|
229
|
+
**After context gathering**:
|
|
230
|
+
- Structured context briefing produced (or no relevant history found) → continue to B4
|
|
231
|
+
- Context gathering timed out or errored → log warning, continue to B4 with empty context (non-blocking)
|
|
197
232
|
# MUST CONTINUE to Phase B4 — context result is intermediate, NOT terminal.
|
|
198
233
|
|
|
199
234
|
---
|
|
200
235
|
|
|
201
236
|
## Phase B4: Architecture Planning (MANDATORY for STANDARD/COMPLEX — skip for TRIVIAL)
|
|
202
237
|
|
|
203
|
-
**Skip if COMPLEXITY_BAND: TRIVIAL** (read from FORGE:FAST_PATH in Phase B0) —
|
|
238
|
+
**Skip if COMPLEXITY_BAND: TRIVIAL** (read from FORGE:FAST_PATH in Phase B0) — skip this phase entirely. Proceed directly to Phase B5.
|
|
204
239
|
|
|
205
|
-
**For STANDARD and COMPLEX tasks**: Always
|
|
240
|
+
**For STANDARD and COMPLEX tasks**: Always run. Even a 1-file STANDARD fix benefits from cross-path consistency checks. Do NOT skip without a TRIVIAL COMPLEXITY_BAND.
|
|
206
241
|
|
|
207
|
-
|
|
242
|
+
**Execution model**: Run **inline** (see Canonical Build Path above). Read the `commands/work-on/build/architect.md` spec and execute its steps directly in this context window. Only spawn a Skill() sub-agent when the Spawn-Decision Table Row (c) applies. <!-- Added: forge#1276 -->
|
|
208
243
|
|
|
244
|
+
Trace all affected code paths and produce an ordered implementation plan. The full step-by-step logic is defined in `commands/work-on/build/architect.md`. Key steps: map all callers and importers of changed functions; check consistency rules across paths; post a `FORGE:ARCHITECT` annotation with the ordered plan and a risk table.
|
|
245
|
+
|
|
246
|
+
**Spawn exception** (only when Row (c) applies):
|
|
209
247
|
```
|
|
210
248
|
Skill("work-on:build:architect", args="{NUMBER} --repo {GH_REPO} --gh-flag {GH_FLAG} --repo-path {WORKTREE_PATH} --files {AFFECTED_FILES}")
|
|
211
249
|
```
|
|
250
|
+
The Skill() form above is the exception path — not the default. <!-- Added: forge#1276 -->
|
|
212
251
|
|
|
213
|
-
**After
|
|
252
|
+
**After architecture planning**:
|
|
214
253
|
- Returns ordered implementation plan → continue to B5
|
|
215
|
-
-
|
|
254
|
+
- BLOCKED (conflicting constraints that cannot be resolved inline) → post comment, add `needs-human`, return `BUILD_RESULT: status: BLOCKED`
|
|
216
255
|
# MUST CONTINUE to Phase B5 — architect result is intermediate, NOT terminal.
|
|
217
256
|
|
|
218
257
|
---
|
|
@@ -245,9 +284,126 @@ Skill("work-on:build:validate", args="{NUMBER} --repo {GH_REPO} --gh-flag {GH_FL
|
|
|
245
284
|
Where `{CHANGED_FILES}` is the space-separated list of files changed by the implement subcommand (read from `IMPLEMENT_RESULT` or from the `<!-- FORGE:BUILDER -->` comment).
|
|
246
285
|
|
|
247
286
|
**After subcommand returns**:
|
|
248
|
-
- `VALIDATE_RESULT: gate_passed: true` →
|
|
287
|
+
- `VALIDATE_RESULT: gate_passed: true` → continue to Phase B6.5 (acceptance gate)
|
|
249
288
|
- `VALIDATE_RESULT: gate_passed: false` → subcommand has already posted comment and added `needs-human` label; return `BUILD_RESULT: status: BLOCKED`
|
|
250
289
|
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Phase B6.5: Acceptance Gate (MANDATORY — cannot be silently skipped) <!-- Added: forge#1315 -->
|
|
293
|
+
|
|
294
|
+
**Goal**: Execute the machine-checkable acceptance spec emitted by investigate Phase 1C and block merge if any check fails. This is a hard gate — not advisory.
|
|
295
|
+
|
|
296
|
+
**Read acceptance spec from FORGE:INVESTIGATOR comment**:
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
ACCEPTANCE_CHECKS=$(gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
|
|
300
|
+
--jq '.[] | select(.body | contains("FORGE:INVESTIGATOR")) | .body' \
|
|
301
|
+
| grep "^ACCEPTANCE_CHECK:" )
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**If `ACCEPTANCE_CHECKS` is empty** (investigation predates this feature or comment was deleted): post a warning comment and **block** — do not silently pass:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:ACCEPTANCE_GATE -->
|
|
308
|
+
## Acceptance Gate — No Spec Found
|
|
309
|
+
|
|
310
|
+
No \`ACCEPTANCE_CHECK:\` lines found in the FORGE:INVESTIGATOR comment. This may mean:
|
|
311
|
+
- The investigation was run before acceptance spec emission was added (re-run investigate to generate the spec), or
|
|
312
|
+
- The investigator comment was deleted.
|
|
313
|
+
|
|
314
|
+
**Gate result: BLOCKED** — re-run \`/work-on:investigate {NUMBER}\` to regenerate the acceptance spec, then retry the build.
|
|
315
|
+
|
|
316
|
+
<!-- FORGE:ACCEPTANCE_GATE:BLOCKED -->"
|
|
317
|
+
gh issue edit {NUMBER} {GH_FLAG} --add-label "needs-human"
|
|
318
|
+
```
|
|
319
|
+
Return `BUILD_RESULT: status: BLOCKED`, blocker: "No acceptance spec — re-run investigate to emit ACCEPTANCE_CHECK lines".
|
|
320
|
+
|
|
321
|
+
**If all checks are `type=skipped`**: post a pass comment noting human review is required, then continue to the checkpoint (non-blocking — skip was deliberate):
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:ACCEPTANCE_GATE -->
|
|
325
|
+
## Acceptance Gate — Skipped (No Machine-Checkable Criteria)
|
|
326
|
+
|
|
327
|
+
The acceptance spec contains only a skip sentinel (\`type=skipped\`). No automated checks were run. Human review is required before merge.
|
|
328
|
+
|
|
329
|
+
<!-- FORGE:ACCEPTANCE_GATE:PASSED -->"
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
**Otherwise — execute each check**:
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
GATE_PASS=true
|
|
336
|
+
FAILED_CHECKS=""
|
|
337
|
+
|
|
338
|
+
while IFS= read -r check_line; do
|
|
339
|
+
ID=$(echo "$check_line" | sed -n 's/.*id=\([^ ]*\).*/\1/p')
|
|
340
|
+
TYPE=$(echo "$check_line" | sed -n 's/.*type=\([^ ]*\).*/\1/p')
|
|
341
|
+
TARGET=$(echo "$check_line"| sed -n 's/.*target=\([^ ]*\).*/\1/p')
|
|
342
|
+
MATCHER=$(echo "$check_line"| sed -n 's/.*matcher=\([^ ]*\).*/\1/p')
|
|
343
|
+
DESC=$(echo "$check_line" | sed -n 's/.*description=\(.*\)/\1/p')
|
|
344
|
+
|
|
345
|
+
[ "$TYPE" = "skipped" ] && continue
|
|
346
|
+
|
|
347
|
+
RESULT="PASS"
|
|
348
|
+
DETAIL=""
|
|
349
|
+
|
|
350
|
+
case "$TYPE" in
|
|
351
|
+
exists)
|
|
352
|
+
[ -e "$TARGET" ] || { RESULT="FAIL"; DETAIL="path not found: $TARGET"; }
|
|
353
|
+
;;
|
|
354
|
+
contains)
|
|
355
|
+
grep -qE "$MATCHER" "$TARGET" 2>/dev/null || { RESULT="FAIL"; DETAIL="'$MATCHER' not found in $TARGET"; }
|
|
356
|
+
;;
|
|
357
|
+
command|behavior)
|
|
358
|
+
if [ "$MATCHER" = "exit_0" ]; then
|
|
359
|
+
eval "$TARGET" >/dev/null 2>&1 || { RESULT="FAIL"; DETAIL="command exited non-zero: $TARGET"; }
|
|
360
|
+
else
|
|
361
|
+
OUTPUT=$(eval "$TARGET" 2>&1)
|
|
362
|
+
echo "$OUTPUT" | grep -qE "$MATCHER" || { RESULT="FAIL"; DETAIL="output did not match '$MATCHER'. Got: $(echo "$OUTPUT" | head -3)"; }
|
|
363
|
+
fi
|
|
364
|
+
;;
|
|
365
|
+
*)
|
|
366
|
+
RESULT="FAIL"; DETAIL="unknown check type: $TYPE"
|
|
367
|
+
;;
|
|
368
|
+
esac
|
|
369
|
+
|
|
370
|
+
if [ "$RESULT" = "FAIL" ]; then
|
|
371
|
+
GATE_PASS=false
|
|
372
|
+
FAILED_CHECKS="${FAILED_CHECKS}\n- **$ID** ($DESC): $DETAIL"
|
|
373
|
+
fi
|
|
374
|
+
done <<< "$ACCEPTANCE_CHECKS"
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
**Post gate result comment**:
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
if [ "$GATE_PASS" = "true" ]; then
|
|
381
|
+
gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:ACCEPTANCE_GATE -->
|
|
382
|
+
## Acceptance Gate — PASSED
|
|
383
|
+
|
|
384
|
+
All machine-checkable acceptance criteria verified against real behavior.
|
|
385
|
+
|
|
386
|
+
<!-- FORGE:ACCEPTANCE_GATE:PASSED -->"
|
|
387
|
+
else
|
|
388
|
+
gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:ACCEPTANCE_GATE -->
|
|
389
|
+
## Acceptance Gate — FAILED
|
|
390
|
+
|
|
391
|
+
The following acceptance checks did not pass:
|
|
392
|
+
|
|
393
|
+
$(echo -e "$FAILED_CHECKS")
|
|
394
|
+
|
|
395
|
+
Merge is blocked. Fix the failing criteria and re-run the validate phase.
|
|
396
|
+
|
|
397
|
+
<!-- FORGE:ACCEPTANCE_GATE:FAILED -->"
|
|
398
|
+
gh issue edit {NUMBER} {GH_FLAG} --add-label "needs-human"
|
|
399
|
+
# Return BLOCKED — merge gate failed
|
|
400
|
+
fi
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
If `GATE_PASS = false`: return `BUILD_RESULT: status: BLOCKED`, blocker: "Acceptance gate failed — see FORGE:ACCEPTANCE_GATE comment".
|
|
404
|
+
|
|
405
|
+
If `GATE_PASS = true`: continue to write the phase checkpoint below.
|
|
406
|
+
|
|
251
407
|
**When gate_passed is true — write machine-readable phase checkpoint before returning (MANDATORY)**:
|
|
252
408
|
```bash
|
|
253
409
|
CHECKPOINT_TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
@@ -275,13 +431,14 @@ BUILD_RESULT:
|
|
|
275
431
|
|
|
276
432
|
## Integration Point in work-on.md
|
|
277
433
|
|
|
278
|
-
This module runs
|
|
434
|
+
This module runs during **Phase 3** of the work-on.md pipeline (label: `workflow:ready-to-build` or `workflow:building`). The full sequence is defined by the Universal Phase Dispatcher in work-on.md:
|
|
279
435
|
|
|
280
436
|
```
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
437
|
+
Phase 3 (Build) → [THIS MODULE] worktree + contract + context + architect + implement + validate + acceptance-gate
|
|
438
|
+
→ posts FORGE:BUILDER comment + FORGE:ACCEPTANCE_GATE comment, writes FORGE:CHECKPOINT next_phase=REVIEW
|
|
439
|
+
Phase 4 (PR) → work-on:review — push branch, create PR, set workflow:in-review
|
|
440
|
+
Phase 5 (Review) → work-on:review — invoke /review-pr --auto-merge
|
|
441
|
+
Phase 6 (Close) → work-on:close — trajectory + parent tracker + summary + worktree cleanup
|
|
285
442
|
```
|
|
286
443
|
|
|
287
|
-
|
|
444
|
+
After this module posts `FORGE:BUILDER` and returns, work-on.md's Universal continuation rule re-reads the issue labels. Since the label is not yet terminal (`workflow:merged` / `workflow:invalid` / `needs-human`), it proceeds immediately to Phase 4 (PR Creation) and then Phase 5 (Auto-Review).
|