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
|
@@ -12,9 +12,11 @@ argument-hint: [issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--pr PR_NUMB
|
|
|
12
12
|
**Invoked by**: `work-on.md` Phase 6–7, after `review.md` returns `REVIEW_RESULT: status: COMPLETE`.
|
|
13
13
|
**Output**: Update project board, close issue, update parent tracker, post trajectory log. Return final summary.
|
|
14
14
|
|
|
15
|
-
**Agent model policy**:
|
|
15
|
+
**Agent model policy**: `model: "haiku"`, `effort: low` (mechanical tier — label transitions, annotation posting, board updates). Fallback: `model: "sonnet"` if rate-limited. Feature gate: pass `effort` only on Claude Code >= 2.1.154.
|
|
16
16
|
**NEVER use plan mode (EnterPlanMode).**
|
|
17
17
|
|
|
18
|
+
<!-- FORGE:SPEC_LOADED — work-on/close.md loaded and active. Agent is bound by this spec. -->
|
|
19
|
+
|
|
18
20
|
---
|
|
19
21
|
|
|
20
22
|
## Inputs
|
|
@@ -179,13 +181,15 @@ ISSUE_STATE=$(gh issue view {NUMBER} {GH_FLAG} --json state --jq '.state')
|
|
|
179
181
|
|
|
180
182
|
**If `REMAINING_AFTER > 0`** (multi-phase: uncompleted phases remain):
|
|
181
183
|
```bash
|
|
182
|
-
# Post phase-complete marker —
|
|
184
|
+
# Post phase-complete marker — work-on.md's Universal continuation rule will re-read labels and continue to the next phase
|
|
183
185
|
gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:PHASE:COMPLETE -->
|
|
184
186
|
Phase complete. PR #{PR_NUMBER} merged to \`{PR_BASE}\`. ${REMAINING_AFTER} phase item(s) remain — leaving issue open for next pipeline iteration."
|
|
185
187
|
|
|
186
|
-
# Update labels to reflect phase complete
|
|
188
|
+
# Update labels to reflect phase complete — remove current-phase labels and set next-phase label
|
|
189
|
+
# so the router has a signal for which phase comes next (fixes: issue #1381)
|
|
187
190
|
gh issue edit {NUMBER} {GH_FLAG} \
|
|
188
|
-
--remove-label "workflow:in-review,workflow:building,workflow:investigating"
|
|
191
|
+
--remove-label "workflow:in-review,workflow:building,workflow:investigating" \
|
|
192
|
+
--add-label "workflow:investigating" 2>/dev/null || true
|
|
189
193
|
|
|
190
194
|
# EXIT — do not close, do not post trajectory, do not run C3–C6
|
|
191
195
|
# Return CLOSE_RESULT: status: PHASE_COMPLETE to caller
|
|
@@ -444,6 +448,129 @@ Where:
|
|
|
444
448
|
|
|
445
449
|
---
|
|
446
450
|
|
|
451
|
+
## Phase C5.2: Memory Index Update <!-- Added: forge#1316 -->
|
|
452
|
+
|
|
453
|
+
**Goal**: Append this run's learnings to the per-repo memory index so future `investigate` runs can retrieve relevant priors. This is the write side of the compounding intelligence loop.
|
|
454
|
+
|
|
455
|
+
**This phase is non-blocking** — if Gist creation or update fails, log the reason and continue to Phase C5.5. Never stall close for memory.
|
|
456
|
+
|
|
457
|
+
**Skip if**: Terminal state is `INVALID` (nothing useful to learn from an invalid issue) OR `<!-- FORGE:TRAJECTORY -->` was already posted AND `<!-- FORGE:MEMORY_INDEXED -->` comment exists on the issue (idempotency guard).
|
|
458
|
+
|
|
459
|
+
### Step 1: Compose memory entry
|
|
460
|
+
|
|
461
|
+
Extract key fields from the pipeline:
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
ROOT_CAUSE=$(gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
|
|
465
|
+
--jq '.[] | select(.body | contains("FORGE:INVESTIGATOR")) | .body' \
|
|
466
|
+
| sed -n '/### Root Cause/{n;p;q}' | head -1 | cut -c1-120)
|
|
467
|
+
|
|
468
|
+
AFFECTED_FILES_BRIEF=$(gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
|
|
469
|
+
--jq '.[] | select(.body | contains("FORGE:INVESTIGATOR")) | .body' \
|
|
470
|
+
| sed -n '/### Affected Files/{n;p;q}' | head -1 | cut -c1-120)
|
|
471
|
+
|
|
472
|
+
DOMAIN_TAGS=$(gh issue view {NUMBER} {GH_FLAG} --json labels \
|
|
473
|
+
--jq '[.labels[].name | select(test("^(auth|billing|database|security|payments|gdpr|perf|ui|api|config)"))] | join(",")' 2>/dev/null || echo "")
|
|
474
|
+
|
|
475
|
+
MEMORY_TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
476
|
+
|
|
477
|
+
MEMORY_ENTRY="MEMORY_ENTRY: issue={NUMBER} title=\"{TITLE}\" domain=\"${DOMAIN_TAGS}\" root_cause=\"${ROOT_CAUSE}\" outcome=\"${CARD_STATUS}\" files=\"${AFFECTED_FILES_BRIEF}\" lesson=\"${ROOT_CAUSE}\" timestamp=${MEMORY_TIMESTAMP}"
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### Step 2: Find or create the memory index Gist
|
|
481
|
+
|
|
482
|
+
```bash
|
|
483
|
+
MEMORY_INDEX_ID=$(gh gist list --limit 100 \
|
|
484
|
+
--jq '.[] | select(.description | contains("FORGE:MEMORY_INDEX: {GH_REPO}")) | .id' 2>/dev/null | head -1)
|
|
485
|
+
|
|
486
|
+
if [ -z "$MEMORY_INDEX_ID" ]; then
|
|
487
|
+
# First run — create the index Gist
|
|
488
|
+
TMPFILE=$(mktemp --suffix=.md)
|
|
489
|
+
cat > "$TMPFILE" <<GIST_EOF
|
|
490
|
+
# ForgeDock Memory Index — {GH_REPO}
|
|
491
|
+
<!-- FORGE:MEMORY_INDEX: {GH_REPO} -->
|
|
492
|
+
Generated by ForgeDock close phase. Each line is a prior pipeline run.
|
|
493
|
+
|
|
494
|
+
${MEMORY_ENTRY}
|
|
495
|
+
GIST_EOF
|
|
496
|
+
# Memory gists MUST be secret — never pass --public here (forge#1587).
|
|
497
|
+
# The entry content below embeds real issue titles, root causes, and file
|
|
498
|
+
# paths; for a private consumer repo, --public would publish that content
|
|
499
|
+
# to a world-readable Gist. `gh gist create` is secret by default, so
|
|
500
|
+
# simply omitting --public is sufficient — the read side (investigate.md
|
|
501
|
+
# Phase 0.5, via `gh gist view`/`gh gist list`) works unchanged against
|
|
502
|
+
# secret gists for the authenticated owner.
|
|
503
|
+
MEMORY_INDEX_URL=$(gh gist create "$TMPFILE" \
|
|
504
|
+
--desc "FORGE:MEMORY_INDEX: {GH_REPO} — per-codebase learning index" \
|
|
505
|
+
2>/dev/null | head -1)
|
|
506
|
+
MEMORY_INDEX_ID=$(echo "$MEMORY_INDEX_URL" | sed 's|.*/||')
|
|
507
|
+
rm -f "$TMPFILE"
|
|
508
|
+
echo "[MEMORY] Created memory index Gist: ${MEMORY_INDEX_URL}"
|
|
509
|
+
else
|
|
510
|
+
# Append to existing index
|
|
511
|
+
EXISTING_CONTENT=$(gh gist view "$MEMORY_INDEX_ID" 2>/dev/null)
|
|
512
|
+
UPDATED_CONTENT="${EXISTING_CONTENT}
|
|
513
|
+
${MEMORY_ENTRY}"
|
|
514
|
+
INDEX_FILENAME=$(gh api gists/${MEMORY_INDEX_ID} --jq '.files | keys[0]' 2>/dev/null)
|
|
515
|
+
INDEX_FILENAME="${INDEX_FILENAME:-memory_index.md}"
|
|
516
|
+
TMPFILE=$(mktemp --suffix=.md)
|
|
517
|
+
echo "$UPDATED_CONTENT" > "$TMPFILE"
|
|
518
|
+
gh gist edit "$MEMORY_INDEX_ID" -f "$INDEX_FILENAME" "$TMPFILE" 2>/dev/null
|
|
519
|
+
EDIT_EXIT=$?
|
|
520
|
+
rm -f "$TMPFILE"
|
|
521
|
+
MEMORY_INDEX_URL="https://gist.github.com/${MEMORY_INDEX_ID}"
|
|
522
|
+
if [ $EDIT_EXIT -eq 0 ]; then
|
|
523
|
+
echo "[MEMORY] Appended to memory index: ${MEMORY_INDEX_URL}"
|
|
524
|
+
else
|
|
525
|
+
echo "WARNING: Failed to update memory index — run will not be persisted"
|
|
526
|
+
MEMORY_INDEX_URL=""
|
|
527
|
+
fi
|
|
528
|
+
fi
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### Migration: replacing an existing public memory-index Gist
|
|
532
|
+
|
|
533
|
+
GitHub does not support flipping a Gist's visibility from public to secret in place. If you find an existing `FORGE:MEMORY_INDEX: {GH_REPO}` Gist that is **public** (check with `gh api gists/${MEMORY_INDEX_ID} --jq '.public'`), replace it:
|
|
534
|
+
|
|
535
|
+
```bash
|
|
536
|
+
# The gist ID here is the same one found by the FORGE:MEMORY_INDEX search above.
|
|
537
|
+
OLD_PUBLIC_GIST_ID="$MEMORY_INDEX_ID"
|
|
538
|
+
|
|
539
|
+
# 1. Save the existing content so no learnings are lost — and verify the save
|
|
540
|
+
# succeeded BEFORE deleting anything.
|
|
541
|
+
gh gist view "$OLD_PUBLIC_GIST_ID" > /tmp/memory_index_migrate.md
|
|
542
|
+
if [ ! -s /tmp/memory_index_migrate.md ]; then
|
|
543
|
+
echo "ABORT: failed to save gist content — not deleting the public gist." >&2
|
|
544
|
+
exit 1
|
|
545
|
+
fi
|
|
546
|
+
|
|
547
|
+
# 2. Delete the public gist (removes the world-readable copy)
|
|
548
|
+
gh gist delete "$OLD_PUBLIC_GIST_ID" --yes
|
|
549
|
+
|
|
550
|
+
# 3. Recreate it secret (no --public) with the same description tag so the
|
|
551
|
+
# next close/investigate run finds it via the FORGE:MEMORY_INDEX search
|
|
552
|
+
gh gist create /tmp/memory_index_migrate.md \
|
|
553
|
+
--desc "FORGE:MEMORY_INDEX: {GH_REPO} — per-codebase learning index"
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
This is a one-time manual step per affected repo — Phase C5.2 itself only ever creates the index once (Step 2's `if [ -z "$MEMORY_INDEX_ID" ]` branch) and appends afterward, so a stale public gist is never auto-recreated secret on its own.
|
|
557
|
+
|
|
558
|
+
### Step 3: Post audit annotation on the issue
|
|
559
|
+
|
|
560
|
+
```bash
|
|
561
|
+
if [ -n "$MEMORY_INDEX_URL" ]; then
|
|
562
|
+
gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:MEMORY_INDEXED -->
|
|
563
|
+
This run has been indexed in the per-repo memory: ${MEMORY_INDEX_URL}
|
|
564
|
+
|
|
565
|
+
Future \`investigate\` runs on \`{GH_REPO}\` will retrieve this entry as a prior when working on related issues.
|
|
566
|
+
|
|
567
|
+
<!-- FORGE:MEMORY_INDEXED:COMPLETE -->"
|
|
568
|
+
echo "[MEMORY] Indexed issue #{NUMBER} into memory at: ${MEMORY_INDEX_URL}"
|
|
569
|
+
fi
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
---
|
|
573
|
+
|
|
447
574
|
## Phase C5.5: Graph Decision Record (MANDATORY when PR exists)
|
|
448
575
|
|
|
449
576
|
**Skip if**: `{PR_NUMBER}` is empty OR `<!-- FORGE:DECISION_RECORD -->` already posted on the PR.
|
|
@@ -577,7 +704,7 @@ CLOSE_RESULT:
|
|
|
577
704
|
parent_closed: {true|false}
|
|
578
705
|
```
|
|
579
706
|
|
|
580
|
-
Where `PHASE_COMPLETE` means the current phase was closed but uncompleted phases remain — the issue is left OPEN for
|
|
707
|
+
Where `PHASE_COMPLETE` means the current phase was closed but uncompleted phases remain — the issue is left OPEN for work-on.md to re-evaluate on the next invocation (via Universal continuation rule: re-read labels, check terminal state, continue to next phase).
|
|
581
708
|
|
|
582
709
|
---
|
|
583
710
|
|
|
@@ -12,7 +12,7 @@ argument-hint: [issue number] [--repo GH_REPO] [--gh-flag GH_FLAG]
|
|
|
12
12
|
**Invoked by**: `work-on.md` routing loop, when `INVESTIGATE_RESULT.decompose = YES`.
|
|
13
13
|
**Output**: Create sub-issues, update parent tracker, post `<!-- FORGE:DECOMPOSED -->` comment, set labels. STOP — each sub-issue runs its own /work-on.
|
|
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
18
|
---
|
|
@@ -108,6 +108,24 @@ For each sub-issue, prepare:
|
|
|
108
108
|
|
|
109
109
|
For each sub-issue (in dependency order):
|
|
110
110
|
|
|
111
|
+
**Before creating each sub-issue, run the deterministic dedup check:** <!-- Added: forge#1335 -->
|
|
112
|
+
|
|
113
|
+
```bash
|
|
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
|
+
|
|
111
129
|
```bash
|
|
112
130
|
gh issue create {GH_FLAG} \
|
|
113
131
|
--title "{fix|feat|refactor}: {SUB_ISSUE_TITLE}" \
|
|
@@ -11,9 +11,11 @@ argument-hint: [issue number] [--repo {owner}/{repo}] [--gh-flag "-R {owner}/{re
|
|
|
11
11
|
|
|
12
12
|
Standalone investigation phase for the work-on pipeline. Validates whether an issue is real, determines root cause, posts a structured FORGE:INVESTIGATOR comment to GitHub, and updates workflow labels.
|
|
13
13
|
|
|
14
|
-
**Agent model policy**:
|
|
14
|
+
**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
15
|
**NEVER use plan mode (EnterPlanMode).**
|
|
16
16
|
|
|
17
|
+
<!-- FORGE:SPEC_LOADED — work-on/investigate.md loaded and active. Agent is bound by this spec. -->
|
|
18
|
+
|
|
17
19
|
---
|
|
18
20
|
|
|
19
21
|
## Inputs
|
|
@@ -27,6 +29,67 @@ If called from `work-on`, these are passed through. If invoked standalone, `--re
|
|
|
27
29
|
|
|
28
30
|
---
|
|
29
31
|
|
|
32
|
+
## Phase 0.5: Memory Retrieval — Prior Run Priors <!-- Added: forge#1316 -->
|
|
33
|
+
|
|
34
|
+
**Goal**: Before investigating, retrieve the top-k relevant prior pipeline runs from the per-repo memory index. Inject confirmed priors into the investigation context so the pipeline compounds intelligence across runs.
|
|
35
|
+
|
|
36
|
+
**This phase is non-blocking** — if the memory index is absent or retrieval fails, log the reason and proceed to Phase 1A. Never stall the pipeline for memory.
|
|
37
|
+
|
|
38
|
+
**Note on Gist visibility (forge#1587)**: The memory-index Gist is created **secret** (see `close.md` Phase C5.2 — no `--public` flag). `gh gist list` and `gh gist view` operate against the authenticated user's own Gists by description/id regardless of public/secret status, so the retrieval steps below work unchanged against a secret Gist. No code change is needed here — this note exists only so a future edit doesn't reintroduce a "must be public to be readable" assumption.
|
|
39
|
+
|
|
40
|
+
### Step 1: Locate memory index Gist
|
|
41
|
+
|
|
42
|
+
The memory index is a GitHub Gist tagged `<!-- FORGE:MEMORY_INDEX: {GH_REPO} -->`. Find it:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
MEMORY_INDEX_URL=$(gh gist list --limit 100 \
|
|
46
|
+
--jq '.[] | select(.description | contains("FORGE:MEMORY_INDEX: {GH_REPO}")) | .url' 2>/dev/null | head -1)
|
|
47
|
+
|
|
48
|
+
MEMORY_INDEX_ID=$(gh gist list --limit 100 \
|
|
49
|
+
--jq '.[] | select(.description | contains("FORGE:MEMORY_INDEX: {GH_REPO}")) | .id' 2>/dev/null | head -1)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
If no memory index found: log `[MEMORY] No memory index for {GH_REPO} — starting fresh` and skip to Phase 1A.
|
|
53
|
+
|
|
54
|
+
### Step 2: Retrieve relevant priors (top-k similarity)
|
|
55
|
+
|
|
56
|
+
Read the memory index content:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
MEMORY_CONTENT=$(gh gist view "$MEMORY_INDEX_ID" 2>/dev/null)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The memory index is a newline-delimited list of prior run entries, each formatted as:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
MEMORY_ENTRY: issue={N} title="{TITLE}" domain="{DOMAIN_TAGS}" root_cause="{ROOT_CAUSE_SUMMARY}" outcome="{merged|invalid|blocked}" files="{AFFECTED_FILES}" lesson="{KEY_LESSON_ONE_LINE}" timestamp={ISO}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Retrieve top-3 relevant priors** by matching against the current issue title and body:
|
|
69
|
+
|
|
70
|
+
1. Extract keywords from the current issue title: lowercase, remove stop words, keep noun/verb tokens
|
|
71
|
+
2. Score each memory entry: +2 for a file path overlap, +1 per keyword match in title/root_cause/lesson
|
|
72
|
+
3. Return the top-3 highest-scoring entries (minimum score ≥ 1 to filter noise)
|
|
73
|
+
|
|
74
|
+
If no entries score ≥ 1: log `[MEMORY] No relevant priors found` and skip to Phase 1A.
|
|
75
|
+
|
|
76
|
+
### Step 3: Inject priors into investigation context
|
|
77
|
+
|
|
78
|
+
For each retrieved prior, emit a structured block that Phase 1B can reference:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
[MEMORY PRIOR #{RANK}]
|
|
82
|
+
Issue: #{issue} — {title}
|
|
83
|
+
Root cause: {root_cause}
|
|
84
|
+
Outcome: {outcome}
|
|
85
|
+
Key lesson: {lesson}
|
|
86
|
+
Affected files: {files}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Print these blocks to stdout before Phase 1A begins. During Phase 1B (step 3 — blame analysis and step 5 — pickaxe pass), **explicitly check whether the current issue's suspected symbol or file appears in any prior root cause or affected files**. If a match is found, cite it in the FORGE:INVESTIGATOR comment's History Findings field as a `[MEMORY PRIOR]` hit.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
30
93
|
## Phase 1A: Load Issue & Check Resume State
|
|
31
94
|
|
|
32
95
|
```bash
|
|
@@ -67,10 +130,33 @@ The target repo is `{GH_REPO}` (resolved from `forge.yaml → project`). The wor
|
|
|
67
130
|
|
|
68
131
|
If the issue specifies a **Code branch** (`**Code branch**: \`{branch}\``), check out that branch — the affected files may not be on the default branch.
|
|
69
132
|
|
|
133
|
+
### Code Index Query (run BEFORE any grep exploration)
|
|
134
|
+
|
|
135
|
+
If `scripts/code-index.sh` exists under `{REPO_PATH}`, query the pre-built symbol/import index first. This yields deterministic answers in one tool call and avoids redundant grep exploration across agents.
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Step 0A: Ensure index is current (cache-hit on unchanged HEAD — zero cost if already built)
|
|
139
|
+
bash {REPO_PATH}/scripts/code-index.sh --repo-path {REPO_PATH} 2>/dev/null || true
|
|
140
|
+
|
|
141
|
+
# Step 0B: Look up the symbol or file named in the issue (replace {SYMBOL} with the relevant name)
|
|
142
|
+
bash {REPO_PATH}/scripts/code-index.sh query --symbol {SYMBOL} --repo-path {REPO_PATH} 2>/dev/null || true
|
|
143
|
+
|
|
144
|
+
# Step 0C: Find all callers of that symbol
|
|
145
|
+
bash {REPO_PATH}/scripts/code-index.sh query --callers {SYMBOL} --repo-path {REPO_PATH} 2>/dev/null || true
|
|
146
|
+
|
|
147
|
+
# Step 0D: Find all importers of an affected file
|
|
148
|
+
bash {REPO_PATH}/scripts/code-index.sh query --importers {AFFECTED_FILE} --repo-path {REPO_PATH} 2>/dev/null || true
|
|
149
|
+
|
|
150
|
+
# Step 0E: Get all files in the affected domain (from issue labels/body)
|
|
151
|
+
bash {REPO_PATH}/scripts/code-index.sh query --domain {DOMAIN_LABEL} --repo-path {REPO_PATH} 2>/dev/null || true
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Fallback**: If `scripts/code-index.sh` is absent or returns no results, proceed with standard grep exploration below. The index is an acceleration layer — its absence never blocks investigation.
|
|
155
|
+
|
|
70
156
|
### Investigation steps
|
|
71
157
|
|
|
72
158
|
1. **Check the right branch** — read from the branch specified in the issue body (`**Code branch**: \`{branch}\``) if present
|
|
73
|
-
2. **Read domain files** — start with the key files for the affected domain
|
|
159
|
+
2. **Read domain files** — start with the key files for the affected domain (use index query results from Step 0E as the file list; fall back to directory inspection if index is absent)
|
|
74
160
|
3. **Verify claims** — does the code actually have the problem described?
|
|
75
161
|
4. **Git blame** — trace when/why the relevant code was written. Run bounded, local commands (no network round-trip):
|
|
76
162
|
```bash
|
|
@@ -106,6 +192,19 @@ If the issue specifies a **Code branch** (`**Code branch**: \`{branch}\``), chec
|
|
|
106
192
|
|
|
107
193
|
The comment MUST include `<!-- INVESTIGATION:COMPLETE -->` at the very end, AFTER all required sections are present. This marker signals the investigation finished successfully.
|
|
108
194
|
|
|
195
|
+
Before posting, resolve the attribution annotation link from `forge.yaml`:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
ATTRIBUTION_ANNOTATION_LINK=$(grep -A5 "^attribution:" forge.yaml 2>/dev/null | grep "annotation_link:" | awk '{print $2}' | tr -d '"' || echo "false")
|
|
199
|
+
ANNOTATION_LINK_FOOTER=""
|
|
200
|
+
if [ "$ATTRIBUTION_ANNOTATION_LINK" = "true" ]; then
|
|
201
|
+
ANNOTATION_LINK_FOOTER="
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
*Pipeline powered by [ForgeDock](https://github.com/RapierCraftStudios/ForgeDock)*"
|
|
205
|
+
fi
|
|
206
|
+
```
|
|
207
|
+
|
|
109
208
|
```bash
|
|
110
209
|
gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:INVESTIGATOR -->
|
|
111
210
|
## Investigation Report
|
|
@@ -146,6 +245,22 @@ gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:INVESTIGATOR -->
|
|
|
146
245
|
**{YES|NO}** — {reason}
|
|
147
246
|
{if YES: proposed sub-issues with titles and dependencies}
|
|
148
247
|
|
|
248
|
+
### Acceptance Spec
|
|
249
|
+
{For each item in the issue's ## Acceptance Criteria section, emit one machine-checkable check line using the format below. If the issue has no Acceptance Criteria section, derive checks from the Recommendation above. Each check MUST be specific, observable, and testable — not vague prose. Checks are consumed by build/validate Phase B6.5 as the merge gate.}
|
|
250
|
+
|
|
251
|
+
```
|
|
252
|
+
ACCEPTANCE_CHECK: id={ac-1} type={exists|contains|command|behavior} target={file_path|command|url} matcher={string|exit_0|regex} description={one-line human description}
|
|
253
|
+
ACCEPTANCE_CHECK: id={ac-2} type={exists|contains|command|behavior} target={file_path|command|url} matcher={string|exit_0|regex} description={one-line human description}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Check types**:
|
|
257
|
+
- `exists` — assert a file or directory exists (`target` = path, `matcher` = ignored)
|
|
258
|
+
- `contains` — assert a file contains a string or regex (`target` = file path, `matcher` = string/regex)
|
|
259
|
+
- `command` — run a shell command and assert exit 0 (`target` = shell command, `matcher` = `exit_0`)
|
|
260
|
+
- `behavior` — assert a runtime/observable behavior via shell command (`target` = shell command, `matcher` = expected output string or regex)
|
|
261
|
+
|
|
262
|
+
**Skipping**: if the issue has no verifiable acceptance criteria and none can be derived from the recommendation, emit a single sentinel: `ACCEPTANCE_CHECK: id=ac-skip type=skipped target=none matcher=none description=No machine-checkable criteria available — human review required`
|
|
263
|
+
${ANNOTATION_LINK_FOOTER}
|
|
149
264
|
<!-- INVESTIGATION:COMPLETE -->"
|
|
150
265
|
```
|
|
151
266
|
|
|
@@ -12,9 +12,11 @@ argument-hint: [issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--worktree P
|
|
|
12
12
|
**Invoked by**: `work-on.md` Phase 4–5, after `build/validate.md` returns `GATE_PASSED: true`.
|
|
13
13
|
**Output**: Push branch, create PR, invoke /review-pr --auto-merge, 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/review.md loaded and active. Agent is bound by this spec. -->
|
|
19
|
+
|
|
18
20
|
---
|
|
19
21
|
|
|
20
22
|
## Inputs
|
|
@@ -81,6 +83,30 @@ Do NOT push this branch. Human review required to identify the source of the mer
|
|
|
81
83
|
fi
|
|
82
84
|
```
|
|
83
85
|
|
|
86
|
+
## Phase R1: Non-Empty Commit Guard (MANDATORY — run before push) <!-- Added: forge#1305 -->
|
|
87
|
+
|
|
88
|
+
Before pushing, verify the branch has at least one commit ahead of the PR base. This is the last-line defense against the phantom-commit hazard: a session that resumed from a partial FORGE:BUILDER comment (without `:COMPLETE`) would have skipped the commit step and could otherwise push an empty branch.
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
cd {WORKTREE_PATH}
|
|
92
|
+
# Count commits on this branch that are not reachable from origin/{PR_BASE}
|
|
93
|
+
COMMIT_COUNT=$(git rev-list --count HEAD ^origin/{PR_BASE} 2>/dev/null || echo "0")
|
|
94
|
+
if [ "$COMMIT_COUNT" -eq 0 ]; then
|
|
95
|
+
gh issue comment {NUMBER} {GH_FLAG} --body "## Push Blocked — No Commits Ahead of Base
|
|
96
|
+
|
|
97
|
+
Branch \`{BRANCH}\` has 0 commits ahead of \`origin/{PR_BASE}\`. Pushing this branch would create an empty PR.
|
|
98
|
+
|
|
99
|
+
**Likely cause**: Build was interrupted after the FORGE:BUILDER comment was posted (implement.md Phase I6) but before the commit was created (validate.md Phase V5). The branch was pushed with no implementation on it.
|
|
100
|
+
|
|
101
|
+
**Resolution**: Delete this branch, re-run \`/work-on {NUMBER}\` to restart the build phase. The partial FORGE:BUILDER comment (lacking \`FORGE:BUILDER:COMPLETE\`) will be detected and deleted, and the build will restart cleanly.
|
|
102
|
+
|
|
103
|
+
<!-- FORGE:PUSH_BLOCKED_EMPTY_BRANCH -->"
|
|
104
|
+
gh issue edit {NUMBER} {GH_FLAG} --add-label "needs-human"
|
|
105
|
+
exit 1
|
|
106
|
+
fi
|
|
107
|
+
echo "Commit count ahead of origin/{PR_BASE}: $COMMIT_COUNT — OK to push"
|
|
108
|
+
```
|
|
109
|
+
|
|
84
110
|
## Phase R1: Push Branch
|
|
85
111
|
|
|
86
112
|
```bash
|
|
@@ -122,7 +148,21 @@ Derive from issue title:
|
|
|
122
148
|
- `docs(...):` → `Docs: {description}`
|
|
123
149
|
- fallback: use issue title as-is
|
|
124
150
|
|
|
125
|
-
### R2B:
|
|
151
|
+
### R2B: Resolve attribution footer (optional)
|
|
152
|
+
|
|
153
|
+
Before creating the PR, check `forge.yaml → attribution.pr_footer`:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
ATTRIBUTION_PR_FOOTER=$(grep -A5 "^attribution:" forge.yaml 2>/dev/null | grep "pr_footer:" | awk '{print $2}' | tr -d '"' || echo "false")
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
If `ATTRIBUTION_PR_FOOTER` is `true`, append the following footer to the PR body (once — never duplicate on retries):
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
> Orchestrated with [ForgeDock](https://github.com/RapierCraftStudios/ForgeDock) — state, scheduling, review, and memory on GitHub.
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### R2C: Create PR
|
|
126
166
|
|
|
127
167
|
```bash
|
|
128
168
|
gh pr create {GH_FLAG} \
|
|
@@ -146,18 +186,22 @@ gh pr create {GH_FLAG} \
|
|
|
146
186
|
Closes #{NUMBER}
|
|
147
187
|
|
|
148
188
|
**Implementation branch**: \`{BRANCH}\`
|
|
149
|
-
**Base**: \`{PR_BASE}\`
|
|
189
|
+
**Base**: \`{PR_BASE}\`
|
|
190
|
+
{IF_ATTRIBUTION_PR_FOOTER_TRUE:
|
|
191
|
+
> Orchestrated with [ForgeDock](https://github.com/RapierCraftStudios/ForgeDock) — state, scheduling, review, and memory on GitHub.}"
|
|
150
192
|
```
|
|
151
193
|
|
|
152
194
|
**Note**: `Closes #{NUMBER}` documents intent but does NOT auto-close for non-default-branch PRs. The close subcommand handles explicit closure after merge.
|
|
153
195
|
|
|
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
|
+
|
|
154
198
|
If PR creation fails because a PR already exists for this branch:
|
|
155
199
|
```bash
|
|
156
200
|
gh pr list {GH_FLAG} --head {BRANCH} --json number,url --jq '.[0]'
|
|
157
201
|
```
|
|
158
202
|
Use the existing PR number and continue.
|
|
159
203
|
|
|
160
|
-
###
|
|
204
|
+
### R2D: Update labels
|
|
161
205
|
|
|
162
206
|
```bash
|
|
163
207
|
gh issue edit {NUMBER} {GH_FLAG} \
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: "[BENCHMARK] Monolithic work-on — single-prompt pipeline with no Skill sub-phase boundaries"
|
|
3
3
|
argument-hint: [issue number]
|
|
4
|
+
install: internal
|
|
4
5
|
---
|
|
5
6
|
<!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
|
|
6
7
|
<!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
|
|
@@ -11,9 +12,14 @@ argument-hint: [issue number]
|
|
|
11
12
|
|
|
12
13
|
Orchestrator for the full issue lifecycle: investigate → build → review → merge → close. GitHub issues are the persistent context layer — read existing comments before starting, write structured reports back, use `workflow:*` labels to track state.
|
|
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
|
**NEVER use plan mode (EnterPlanMode).**
|
|
16
17
|
|
|
18
|
+
> **Relationship to `/work-on` (canonical path)**: This file is a `[BENCHMARK]` reference variant. It documents the same inline-execution model that `/work-on` Phase 3 and `work-on/build.md` use as their **default** for STANDARD/fast-lane issues — all build sub-phases (context → architect → implement → validate) run inline in the current context window with no `Skill()` sub-agent spawns. The difference is that this file omits the worktree lifecycle, `FORGE:CONTRACT` posting, and the Spawn-Decision exception path for large builds. Use `/work-on` for production runs; use this file for baseline benchmarking or when comparing single-prompt token cost against the modular path. See `work-on/build.md` (Canonical Build Path section) for the reconciled build topology. <!-- Added: forge#1276 -->
|
|
19
|
+
**NEVER use the Agent tool** — this spec executes all phases inline as a single monolithic prompt. The Agent tool would spawn a subprocess outside this context, breaking the single-prompt contract and losing all accumulated pipeline state.
|
|
20
|
+
|
|
21
|
+
<!-- FORGE:SPEC_LOADED — work-on-monolithic.md loaded and active. Agent is bound by this spec. -->
|
|
22
|
+
|
|
17
23
|
### Compaction Resilience
|
|
18
24
|
|
|
19
25
|
1. Write state to GitHub after EVERY significant step
|
|
@@ -64,7 +70,7 @@ gh api repos/{GH_REPO}/issues/{NUMBER}/comments --jq '.[] | {id: .id, author: .u
|
|
|
64
70
|
|
|
65
71
|
**Check**: state (closed → STOP), terminal labels (`workflow:merged`/`workflow:invalid` → STOP), existing agent comments (`FORGE:INVESTIGATOR`, `FORGE:CONTRACT`, `FORGE:BUILDER`, `FORGE:TRAJECTORY`), parent tracker status.
|
|
66
72
|
|
|
67
|
-
**Determine resume point**: No comments → Phase 1. Investigation exists + ready-to-build → Phase 3. Builder + no PR → Phase 4. Builder + PR open → Phase 5. PR merged + issue open → close issue.
|
|
73
|
+
**Determine resume point**: No comments → Phase 1. Investigation exists + ready-to-build → Phase 3. Builder:COMPLETE + no PR → Phase 4. Builder without :COMPLETE (partial/interrupted build) + no PR → Phase 3 (partial-build cleanup). Builder + PR open → Phase 5. PR merged + issue open → close issue.
|
|
68
74
|
|
|
69
75
|
**Classify lane**: Milestone → feature lane (`milestone/{slug}`). No milestone → fast lane (`staging`).
|
|
70
76
|
|