forgedock 1.0.5 → 1.0.7
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 +7 -1
- package/bin/forgedock.mjs +496 -364
- package/bin/labels.json +152 -0
- package/commands/audit-agents.md +4 -2
- package/commands/autopilot.md +19 -11
- package/commands/cleanup.md +27 -12
- package/commands/deploy-info.md +36 -17
- package/commands/incident-response.md +15 -10
- package/commands/issue.md +8 -6
- package/commands/milestone.md +97 -48
- package/commands/orchestrate.md +109 -65
- package/commands/pipeline-health.md +8 -1
- package/commands/qa-sweep.md +14 -3
- package/commands/review-pr-agents.md +1 -1
- package/commands/review-pr-staging.md +129 -23
- package/commands/review-pr.md +237 -90
- package/commands/rollback.md +26 -7
- package/commands/security-audit.md +27 -25
- package/commands/sync-ecosystem.md +2 -2
- package/commands/work-on/build/architect.md +154 -2
- package/commands/work-on/build/context.md +131 -3
- package/commands/work-on/build/validate.md +32 -13
- package/commands/work-on/decompose.md +2 -0
- package/commands/work-on-monolithic.md +9 -5
- package/commands/work-on.md +67 -23
- package/docs/CONFIG.md +117 -0
- package/package.json +2 -1
- package/scripts/verify-route-registration.sh +36 -15
- package/scripts/verify-sops-chain.sh +18 -0
- package/templates/devdocs/README.md +96 -0
- package/templates/devdocs/agent/using-forgedock.md +245 -0
- package/templates/devdocs/agent/using-github.md +325 -0
- package/templates/devdocs/project/architecture.md +122 -0
- package/templates/devdocs/project/conventions.md +158 -0
- package/templates/devdocs/project/custom-instructions.md +73 -0
- package/templates/devdocs/project/glossary.md +84 -0
- package/templates/devdocs/project/stack.md +80 -0
- package/templates/devdocs/templates/commit-convention.md +147 -0
- package/templates/devdocs/templates/issue.md +141 -0
- package/templates/devdocs/templates/pull-request.md +115 -0
- package/templates/devdocs/templates/review-finding.md +147 -0
- package/bin/github-app-manifest.json +0 -24
|
@@ -7,7 +7,7 @@ argument-hint: [--repo <prefix>] [--phase 1|2|3|4|all] [--dry-run]
|
|
|
7
7
|
|
|
8
8
|
**Input**: $ARGUMENTS
|
|
9
9
|
|
|
10
|
-
You are the security posture auditor. Run a scripted 4-phase checklist against the **current state** of the target repository (not a PR diff). Each check uses bash/grep against repo files. Confirmed findings are posted as GitHub issues in the target repo, labeled `security,audit-finding,P1/P2/P3`.
|
|
10
|
+
You are the security posture auditor. Run a scripted 4-phase checklist against the **current state** of the target repository (not a PR diff). Each check uses bash/grep against repo files. Confirmed findings are posted as GitHub issues in the target repo, labeled `security,audit-finding,priority:P1/priority:P2/priority:P3`.
|
|
11
11
|
|
|
12
12
|
This command is designed to be run:
|
|
13
13
|
- **Manually** after a pen test engagement
|
|
@@ -119,7 +119,7 @@ done
|
|
|
119
119
|
|
|
120
120
|
**Confirm**: For each hit, verify the port is NOT a web-facing port (80, 443, 8080, 3000). Ports like 6432 (PgBouncer), 6379 (Redis), 5432 (Postgres), 27017 (MongoDB) bound to `0.0.0.0` are confirmed findings.
|
|
121
121
|
|
|
122
|
-
**Severity**: P1 if no external firewall documented; P2 otherwise.
|
|
122
|
+
**Severity**: `priority:P1` if no external firewall documented; `priority:P2` otherwise.
|
|
123
123
|
|
|
124
124
|
**Issue title**: `security: {SERVICE} port {PORT} bound to 0.0.0.0 — exposed beyond localhost`
|
|
125
125
|
|
|
@@ -142,7 +142,7 @@ done
|
|
|
142
142
|
|
|
143
143
|
**Confirm**: Check if the Dockerfile is for a long-running service (not a one-shot build image). If service container with no USER → confirmed finding.
|
|
144
144
|
|
|
145
|
-
**Severity**: P2 (standard finding; exploitability depends on runtime isolation).
|
|
145
|
+
**Severity**: `priority:P2` (standard finding; exploitability depends on runtime isolation).
|
|
146
146
|
|
|
147
147
|
**Issue title**: `security: {SERVICE} Dockerfile has no USER directive — runs as root`
|
|
148
148
|
|
|
@@ -167,7 +167,7 @@ done
|
|
|
167
167
|
|
|
168
168
|
**Manual review**: Check for `POSTGRES_PASSWORD` and `requirepass` in compose environment sections. Flag any service using a blank/trivial password as a documented value.
|
|
169
169
|
|
|
170
|
-
**Severity**: P3 for dev compose; P1 if the compose file is used in production.
|
|
170
|
+
**Severity**: `priority:P3` for dev compose; `priority:P1` if the compose file is used in production.
|
|
171
171
|
|
|
172
172
|
**Issue title**: `security: {SERVICE} in {FILE} has no authentication configured`
|
|
173
173
|
|
|
@@ -198,7 +198,7 @@ done
|
|
|
198
198
|
|
|
199
199
|
**Confirm**: Verify the flagged step is indeed a security scanner step (not a notification or deploy step). Confirmed if scanner produces failure exit codes that are being swallowed.
|
|
200
200
|
|
|
201
|
-
**Severity**: P2 (scanner present but findings are silently ignored).
|
|
201
|
+
**Severity**: `priority:P2` (scanner present but findings are silently ignored).
|
|
202
202
|
|
|
203
203
|
**Issue title**: `security: {SCANNER} step in {WORKFLOW} has continue-on-error: true — findings silently ignored`
|
|
204
204
|
|
|
@@ -219,7 +219,7 @@ done
|
|
|
219
219
|
|
|
220
220
|
**Confirm**: Distinguish intentional comments (documentation) from disabled access control rules. Confirmed if the commented line is a functional directive that would restrict access.
|
|
221
221
|
|
|
222
|
-
**Severity**: P1 if the endpoint is publicly accessible; P2 otherwise.
|
|
222
|
+
**Severity**: `priority:P1` if the endpoint is publicly accessible; `priority:P2` otherwise.
|
|
223
223
|
|
|
224
224
|
**Issue title**: `security: commented-out access control in {FILE} — {DIRECTIVE} disabled`
|
|
225
225
|
|
|
@@ -242,7 +242,7 @@ done
|
|
|
242
242
|
|
|
243
243
|
**Confirm**: Verify the CSP header applies to the production site (not just dev/storybook). Check if a nonce-based approach is already in use (nonce + unsafe-inline is still a finding but lower severity).
|
|
244
244
|
|
|
245
|
-
**Severity**: P2 (XSS protection materially weakened).
|
|
245
|
+
**Severity**: `priority:P2` (XSS protection materially weakened).
|
|
246
246
|
|
|
247
247
|
**Issue title**: `security: CSP script-src includes unsafe-inline in {FILE} — XSS protection bypassed`
|
|
248
248
|
|
|
@@ -261,9 +261,9 @@ for f in $HEADER_FILES; do
|
|
|
261
261
|
done
|
|
262
262
|
```
|
|
263
263
|
|
|
264
|
-
**Confirm**: Check if the header is set in a response (not just read). If set in outbound responses → confirmed finding. Internal-only APIs (not publicly routed) are P3
|
|
264
|
+
**Confirm**: Check if the header is set in a response (not just read). If set in outbound responses → confirmed finding. Internal-only APIs (not publicly routed) are `priority:P3`; public APIs are `priority:P2`.
|
|
265
265
|
|
|
266
|
-
**Severity**: P2 for public APIs; P3 for internal.
|
|
266
|
+
**Severity**: `priority:P2` for public APIs; `priority:P3` for internal.
|
|
267
267
|
|
|
268
268
|
**Issue title**: `security: {HEADER} response header leaks deployment/version information`
|
|
269
269
|
|
|
@@ -291,7 +291,7 @@ grep -rn '@router.get\("/health"\|@app.route("/health"\|@router.get\("/metrics"\
|
|
|
291
291
|
|
|
292
292
|
**Confirm**: Manually verify the route has no authentication dependency. Check if it's behind a network-level gate (traefik middleware, nginx ACL). Confirmed if publicly routable and returns system state.
|
|
293
293
|
|
|
294
|
-
**Severity**: P2 (information disclosure enables targeted attacks).
|
|
294
|
+
**Severity**: `priority:P2` (information disclosure enables targeted attacks).
|
|
295
295
|
|
|
296
296
|
**Issue title**: `security: unauthenticated {ROUTE} endpoint exposes system state`
|
|
297
297
|
|
|
@@ -326,7 +326,7 @@ grep -rn "new Map\(\)" "$REPO_PATH/web" --include="*.ts" --include="*.tsx" --inc
|
|
|
326
326
|
|
|
327
327
|
**Confirm**: Verify the rate limiter is not backed by Redis, a database, or a distributed cache. Confirmed if per-process store with no TTL-based external backend.
|
|
328
328
|
|
|
329
|
-
**Severity**: P2 (rate limit bypass possible in scaled deployments).
|
|
329
|
+
**Severity**: `priority:P2` (rate limit bypass possible in scaled deployments).
|
|
330
330
|
|
|
331
331
|
**Issue title**: `security: in-memory rate limiter in {FILE} has no cross-replica enforcement`
|
|
332
332
|
|
|
@@ -363,9 +363,9 @@ grep -rn "document\.cookie\s*=\|res\.cookie(" "$REPO_PATH/web" --include="*.ts"
|
|
|
363
363
|
done
|
|
364
364
|
```
|
|
365
365
|
|
|
366
|
-
**Confirm**: Verify the cookie stores user-controlled data or authentication state. Internal-only cookies (debug flags, feature flags with no sensitive data) are P3
|
|
366
|
+
**Confirm**: Verify the cookie stores user-controlled data or authentication state. Internal-only cookies (debug flags, feature flags with no sensitive data) are `priority:P3`. Auth/session cookies without flags are `priority:P1`.
|
|
367
367
|
|
|
368
|
-
**Severity**: P1 for auth/session tokens; P2 for user-controlled data; P3 for non-sensitive cookies.
|
|
368
|
+
**Severity**: `priority:P1` for auth/session tokens; `priority:P2` for user-controlled data; `priority:P3` for non-sensitive cookies.
|
|
369
369
|
|
|
370
370
|
**Issue title**: `security: {COOKIE_NAME} cookie missing {FLAGS} — vulnerable to XSS/CSRF/MITM`
|
|
371
371
|
|
|
@@ -395,7 +395,7 @@ grep -rn '||\s*["'"'"'][a-zA-Z0-9]\{4,\}["'"'"']\|default.*password\|default.*se
|
|
|
395
395
|
|
|
396
396
|
**Confirm**: Verify the fallback value is a real credential (not a placeholder like `""` or `"REPLACE_ME"` which would fail explicitly). Confirmed if a non-trivial value would silently succeed authentication.
|
|
397
397
|
|
|
398
|
-
**Severity**: P1 if the credential protects a production service; P2 otherwise.
|
|
398
|
+
**Severity**: `priority:P1` if the credential protects a production service; `priority:P2` otherwise.
|
|
399
399
|
|
|
400
400
|
**Issue title**: `security: credential placeholder fallback in {FILE} — {VAR} defaults to hardcoded value`
|
|
401
401
|
|
|
@@ -445,7 +445,7 @@ done
|
|
|
445
445
|
|
|
446
446
|
**Confirm**: Verify the event type appears in a handler dispatch (not just a comment). Confirmed if the event would change user entitlements or financial state but has no handler.
|
|
447
447
|
|
|
448
|
-
**Severity**: P1 for events that affect billing state (subscription.deleted, payment_failed, dispute); P2 for informational events.
|
|
448
|
+
**Severity**: `priority:P1` for events that affect billing state (subscription.deleted, payment_failed, dispute); `priority:P2` for informational events.
|
|
449
449
|
|
|
450
450
|
**Issue title**: `security: Stripe event {EVENT_TYPE} not handled in {FILE} — financial state may diverge`
|
|
451
451
|
|
|
@@ -466,7 +466,7 @@ grep -rn "pre_reserve\|prereserve\|reserve_credits\|MAX_COST\|max_cost\|PRE_RESE
|
|
|
466
466
|
|
|
467
467
|
**Manual review required**: Compare the pre-reserve amount against the maximum operation cost for the highest-tier model. If pre-reserve < max possible cost, users can overdraw.
|
|
468
468
|
|
|
469
|
-
**Severity**: P2 (financial loss; users can consume credits they don't have).
|
|
469
|
+
**Severity**: `priority:P2` (financial loss; users can consume credits they don't have).
|
|
470
470
|
|
|
471
471
|
**Issue title**: `security: pre-reservation credit cap {AMOUNT} is below maximum operation cost {MAX_COST}`
|
|
472
472
|
|
|
@@ -483,8 +483,8 @@ After all phases complete, produce a summary table:
|
|
|
483
483
|
|
|
484
484
|
| # | Phase | Finding | File | Severity | Status |
|
|
485
485
|
|---|-------|---------|------|----------|--------|
|
|
486
|
-
| 1 | 1A | Port binding | docker-compose.prod.yml:12 | P1 | CONFIRMED |
|
|
487
|
-
| 2 | 1B | No USER directive | services/worker/Dockerfile | P2 | CONFIRMED |
|
|
486
|
+
| 1 | 1A | Port binding | docker-compose.prod.yml:12 | priority:P1 | CONFIRMED |
|
|
487
|
+
| 2 | 1B | No USER directive | services/worker/Dockerfile | priority:P2 | CONFIRMED |
|
|
488
488
|
...
|
|
489
489
|
```
|
|
490
490
|
|
|
@@ -492,12 +492,14 @@ If `--dry-run` was passed, print the table and STOP. Do not create issues.
|
|
|
492
492
|
|
|
493
493
|
### 5B: Ensure labels exist in target repo
|
|
494
494
|
|
|
495
|
-
Before creating any issues, ensure all required labels exist
|
|
495
|
+
Before creating any issues, ensure all required labels exist. Colors match the canonical ForgeDock label manifest (`bin/labels.json`). Run `npx forgedock labels setup` to bootstrap all managed labels at once.
|
|
496
496
|
|
|
497
497
|
```bash
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
498
|
+
gh label create "security" --color "B60205" --description "Security vulnerability or hardening. Managed by ForgeDock." --force -R "{GH_REPO}" 2>/dev/null || true
|
|
499
|
+
gh label create "audit-finding" --color "D93F0B" --description "Security or compliance defect found during audit. Managed by ForgeDock." --force -R "{GH_REPO}" 2>/dev/null || true
|
|
500
|
+
gh label create "priority:P1" --color "D93F0B" --description "High priority — major feature broken, no workaround. Managed by ForgeDock." --force -R "{GH_REPO}" 2>/dev/null || true
|
|
501
|
+
gh label create "priority:P2" --color "FBCA04" --description "Medium priority — impaired functionality, workaround exists. Managed by ForgeDock." --force -R "{GH_REPO}" 2>/dev/null || true
|
|
502
|
+
gh label create "priority:P3" --color "C2E0C6" --description "Low priority — minor issue or polish. Managed by ForgeDock." --force -R "{GH_REPO}" 2>/dev/null || true
|
|
501
503
|
```
|
|
502
504
|
|
|
503
505
|
### 5C: Create GitHub issues for CONFIRMED findings
|
|
@@ -559,9 +561,9 @@ gh issue comment "{CALLER_ISSUE}" -R {FORGE_REPO} --body "$(cat <<'COMMENT_EOF'
|
|
|
559
561
|
|
|
560
562
|
| Severity | Count |
|
|
561
563
|
|----------|-------|
|
|
562
|
-
| P1 | {P1_COUNT} |
|
|
563
|
-
| P2 | {P2_COUNT} |
|
|
564
|
-
| P3 | {P3_COUNT} |
|
|
564
|
+
| priority:P1 | {P1_COUNT} |
|
|
565
|
+
| priority:P2 | {P2_COUNT} |
|
|
566
|
+
| priority:P3 | {P3_COUNT} |
|
|
565
567
|
|
|
566
568
|
### Issues Created
|
|
567
569
|
|
|
@@ -217,7 +217,7 @@ Create issues in the affected repos:
|
|
|
217
217
|
# For satellite repos (separate GitHub repos):
|
|
218
218
|
gh issue create -R {TARGET_REPO} \
|
|
219
219
|
--title "feat(sync): {description of what API change needs to be reflected}" \
|
|
220
|
-
--label "feature,P2" \
|
|
220
|
+
--label "feature,priority:P2" \
|
|
221
221
|
--body "$(cat <<'BODY_EOF'
|
|
222
222
|
## Problem
|
|
223
223
|
|
|
@@ -254,7 +254,7 @@ BODY_EOF
|
|
|
254
254
|
# For monorepo issues (SDKs, packages inside a single repo):
|
|
255
255
|
gh issue create \
|
|
256
256
|
--title "feat(sync): {description of what API change needs to be reflected}" \
|
|
257
|
-
--label "feature,P2" \
|
|
257
|
+
--label "feature,priority:P2" \
|
|
258
258
|
--body "$(cat <<'BODY_EOF'
|
|
259
259
|
## Problem
|
|
260
260
|
|
|
@@ -65,6 +65,134 @@ gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
|
|
|
65
65
|
|
|
66
66
|
---
|
|
67
67
|
|
|
68
|
+
## Phase A0: Read Custom Instructions and Project Conventions
|
|
69
|
+
|
|
70
|
+
Read project-resident authoritative docs **before** any code path tracing. `project/custom-instructions.md` has the highest precedence of all knowledge sources — its directives are BINDING and override agent defaults, training knowledge, and all other context. Other applicable `project/*.md` files provide authoritative project conventions the architect must enforce.
|
|
71
|
+
|
|
72
|
+
**Time budget**: 30 seconds. If exceeded, log a skip note and continue to Phase A1.
|
|
73
|
+
|
|
74
|
+
**Skip if**: `{REPO_PATH}` is not set, devdocs path does not exist, or path contains no markdown files.
|
|
75
|
+
|
|
76
|
+
### Step 0: Resolve devdocs path
|
|
77
|
+
|
|
78
|
+
Read `forge.yaml → devdocs.path` from the project root. Default to `devdocs` if the key is absent or unreadable.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
DEVDOCS_PATH=""
|
|
82
|
+
|
|
83
|
+
FORGE_YAML_PATH="{REPO_PATH}/forge.yaml"
|
|
84
|
+
|
|
85
|
+
if [ -f "$FORGE_YAML_PATH" ]; then
|
|
86
|
+
DEVDOCS_REL=$(grep -A5 '^devdocs:' "$FORGE_YAML_PATH" \
|
|
87
|
+
| grep '^\s*path:' \
|
|
88
|
+
| head -1 \
|
|
89
|
+
| sed 's/.*path:\s*//' \
|
|
90
|
+
| tr -d '"'"'"' \
|
|
91
|
+
| tr -d '[:space:]')
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
DEVDOCS_REL="${DEVDOCS_REL:-devdocs}"
|
|
95
|
+
DEVDOCS_PATH="{REPO_PATH}/${DEVDOCS_REL}"
|
|
96
|
+
|
|
97
|
+
if [ ! -d "$DEVDOCS_PATH" ]; then
|
|
98
|
+
echo "Devdocs path '${DEVDOCS_PATH}' does not exist — skipping Phase A0 (no blocking)"
|
|
99
|
+
DEVDOCS_PATH=""
|
|
100
|
+
fi
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
> **Note**: `devdocs/` must be tracked in git for the worktree to contain it. If the project gitignores `devdocs/`, the path will not exist in the worktree and this phase silently skips — this is by design. Run `git check-ignore -v devdocs/` to confirm tracking status.
|
|
104
|
+
|
|
105
|
+
### Step 1: Priority read — custom instructions (HIGHEST PRECEDENCE)
|
|
106
|
+
|
|
107
|
+
Always read `project/custom-instructions.md` first if it exists. Directives in this file are BINDING — they override everything else.
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
CUSTOM_INSTRUCTIONS=""
|
|
111
|
+
|
|
112
|
+
if [ -n "$DEVDOCS_PATH" ]; then
|
|
113
|
+
CUSTOM_INSTRUCTIONS_FILE="${DEVDOCS_PATH}/project/custom-instructions.md"
|
|
114
|
+
if [ -f "$CUSTOM_INSTRUCTIONS_FILE" ]; then
|
|
115
|
+
TOTAL_LINES=$(wc -l < "$CUSTOM_INSTRUCTIONS_FILE" 2>/dev/null || echo 0)
|
|
116
|
+
if [ "$TOTAL_LINES" -gt 200 ]; then
|
|
117
|
+
CUSTOM_INSTRUCTIONS=$(head -200 "$CUSTOM_INSTRUCTIONS_FILE")
|
|
118
|
+
CUSTOM_INSTRUCTIONS="${CUSTOM_INSTRUCTIONS}
|
|
119
|
+
|
|
120
|
+
_[Truncated at 200 lines — ${TOTAL_LINES} total. Read full file for complete directives.]_"
|
|
121
|
+
else
|
|
122
|
+
CUSTOM_INSTRUCTIONS=$(cat "$CUSTOM_INSTRUCTIONS_FILE")
|
|
123
|
+
fi
|
|
124
|
+
fi
|
|
125
|
+
fi
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Step 2: Secondary reads — other applicable project files
|
|
129
|
+
|
|
130
|
+
Read all other `*.md` files under `DEVDOCS_PATH` where `applies_to` contains `work-on`. Skip `project/custom-instructions.md` (already read). Sort by authority (`required` first).
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
PROJECT_CONVENTIONS=""
|
|
134
|
+
|
|
135
|
+
if [ -n "$DEVDOCS_PATH" ]; then
|
|
136
|
+
APPLICABLE_FILES=""
|
|
137
|
+
|
|
138
|
+
while IFS= read -r -d '' mdfile; do
|
|
139
|
+
# Skip custom-instructions — already read as priority
|
|
140
|
+
[ "$mdfile" = "${DEVDOCS_PATH}/project/custom-instructions.md" ] && continue
|
|
141
|
+
|
|
142
|
+
FRONTMATTER=$(awk '/^---/{c++; if(c==1){next} if(c==2){exit}} c==1{print}' "$mdfile" 2>/dev/null)
|
|
143
|
+
|
|
144
|
+
if echo "$FRONTMATTER" | grep -q 'applies_to:.*work-on'; then
|
|
145
|
+
AUTHORITY=$(echo "$FRONTMATTER" | grep 'authority:' | head -1 | sed 's/.*authority:\s*//' | tr -d ' ')
|
|
146
|
+
case "$AUTHORITY" in
|
|
147
|
+
required) SORT_KEY="1" ;;
|
|
148
|
+
recommended) SORT_KEY="2" ;;
|
|
149
|
+
*) SORT_KEY="3" ;;
|
|
150
|
+
esac
|
|
151
|
+
APPLICABLE_FILES="${APPLICABLE_FILES}${SORT_KEY}|${mdfile}\n"
|
|
152
|
+
fi
|
|
153
|
+
done < <(find "$DEVDOCS_PATH" -name "*.md" -print0 2>/dev/null)
|
|
154
|
+
|
|
155
|
+
APPLICABLE_FILES=$(printf "$APPLICABLE_FILES" | sort | cut -d'|' -f2-)
|
|
156
|
+
|
|
157
|
+
while IFS= read -r mdfile; do
|
|
158
|
+
[ -z "$mdfile" ] && continue
|
|
159
|
+
TOTAL_LINES=$(wc -l < "$mdfile" 2>/dev/null || echo 0)
|
|
160
|
+
if [ "$TOTAL_LINES" -gt 200 ]; then
|
|
161
|
+
FILE_CONTENT=$(head -200 "$mdfile")
|
|
162
|
+
TRUNCATION_NOTE="_[Truncated at 200 lines — ${TOTAL_LINES} total.]_"
|
|
163
|
+
else
|
|
164
|
+
FILE_CONTENT=$(cat "$mdfile")
|
|
165
|
+
TRUNCATION_NOTE=""
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
REL_PATH="${mdfile#${DEVDOCS_PATH}/}"
|
|
169
|
+
PROJECT_CONVENTIONS="${PROJECT_CONVENTIONS}
|
|
170
|
+
|
|
171
|
+
#### \`${REL_PATH}\`
|
|
172
|
+
${FILE_CONTENT}
|
|
173
|
+
${TRUNCATION_NOTE}"
|
|
174
|
+
done <<< "$APPLICABLE_FILES"
|
|
175
|
+
fi
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Step 3: Precedence rules to enforce
|
|
179
|
+
|
|
180
|
+
When `CUSTOM_INSTRUCTIONS` or `PROJECT_CONVENTIONS` is non-empty, the architect MUST apply them throughout the plan. The precedence order is:
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
project/custom-instructions.md ← HIGHEST PRIORITY (binding directives)
|
|
184
|
+
↑
|
|
185
|
+
other project/*.md ← Authoritative project conventions
|
|
186
|
+
agent/*.md ← ForgeDock/GitHub usage instructions
|
|
187
|
+
agent memory ← Recalled knowledge
|
|
188
|
+
agent defaults ← Built-in behaviors
|
|
189
|
+
↓ LOWEST PRIORITY
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
`CUSTOM_INSTRUCTIONS` and `PROJECT_CONVENTIONS` are used in the `### Custom Instructions (HIGHEST PRECEDENCE)` and `### Project Conventions` sections of the FORGE:ARCHITECT output. If both are empty (devdocs path absent), these sections are replaced with skip notes.
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
68
196
|
## Phase A1: Read Entry Points
|
|
69
197
|
|
|
70
198
|
Identify every entry point that initiates the affected logic. Start from the files named in the investigation report.
|
|
@@ -226,6 +354,20 @@ Post the following as a GitHub comment on `{NUMBER}`:
|
|
|
226
354
|
gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:ARCHITECT -->
|
|
227
355
|
## Implementation Plan for #{NUMBER}
|
|
228
356
|
|
|
357
|
+
### Custom Instructions (HIGHEST PRECEDENCE)
|
|
358
|
+
<!-- Binding directives from project/custom-instructions.md (Phase A0).
|
|
359
|
+
These override agent defaults, training knowledge, and all other context.
|
|
360
|
+
Builder MUST follow these exactly — violations are elevated to HIGH severity in review.
|
|
361
|
+
If devdocs path was absent or file not found: 'No custom-instructions.md found at
|
|
362
|
+
{DEVDOCS_PATH}/project/custom-instructions.md — skipping. Run `npx forgedock docs init`.' -->
|
|
363
|
+
{CUSTOM_INSTRUCTIONS}
|
|
364
|
+
|
|
365
|
+
### Project Conventions
|
|
366
|
+
<!-- Authoritative project knowledge from project/*.md and agent/*.md files
|
|
367
|
+
with applies_to: work-on (Phase A0). Read these before finalizing the plan.
|
|
368
|
+
If devdocs path was absent or no applicable files found: 'No applicable devdocs found.' -->
|
|
369
|
+
{PROJECT_CONVENTIONS}
|
|
370
|
+
|
|
229
371
|
### Affected Paths (ALL must be updated)
|
|
230
372
|
| # | File | Function/Class | Change Required | Why |
|
|
231
373
|
|---|------|----------------|-----------------|-----|
|
|
@@ -259,9 +401,10 @@ gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:ARCHITECT -->
|
|
|
259
401
|
|
|
260
402
|
## Timing Rules
|
|
261
403
|
|
|
262
|
-
-
|
|
404
|
+
- Phase A0 devdocs read: 30s total budget (path resolution + file enumeration + content reads); skip if exceeded
|
|
405
|
+
- Each file read (A1): skip if the file exceeds 500 lines and only the first 100 lines are needed for structure
|
|
263
406
|
- Each `grep -r` call: timeout after 10s, skip if exceeded
|
|
264
|
-
- Total wall time budget: **3 minutes
|
|
407
|
+
- Total wall time budget: **3 minutes** (A0 through A5 combined). If budget exceeded, post partial results with `<!-- FORGE:ARCHITECT:PARTIAL -->` marker instead of `COMPLETE`.
|
|
265
408
|
|
|
266
409
|
---
|
|
267
410
|
|
|
@@ -285,7 +428,16 @@ This module runs at **Step 3C.6** — after Context Gathering, before Implement:
|
|
|
285
428
|
3C → Builder Contract posted
|
|
286
429
|
3C.5 → Context Gathering (FORGE:CONTEXT comment)
|
|
287
430
|
3C.6 → [THIS MODULE] Architecture Planning (FORGE:ARCHITECT comment)
|
|
431
|
+
Phase A0: Read Custom Instructions and Project Conventions (highest precedence)
|
|
432
|
+
Phase A1: Read Entry Points
|
|
433
|
+
Phase A2: Trace the Data Flow
|
|
434
|
+
Phase A2.5: Pipeline Phase-Dependency Check
|
|
435
|
+
Phase A3: Consistency Rules
|
|
436
|
+
Phase A4: Sequence the Implementation
|
|
437
|
+
Phase A5: Risk Assessment
|
|
288
438
|
3F → Implement (builder reads plan, implements ALL affected paths)
|
|
289
439
|
```
|
|
290
440
|
|
|
291
441
|
The builder agent reads the `<!-- FORGE:ARCHITECT -->` comment as its **primary input** before writing any code. The raw issue body is secondary context. If the architect step was skipped, the builder falls back to investigation report + contract.
|
|
442
|
+
|
|
443
|
+
**Devdocs precedence** (Phase A0): `project/custom-instructions.md` has ABSOLUTE priority over all other context. The architect's plan must reflect any directives in that file — if custom instructions mandate a specific pattern, the implementation order and approach MUST follow it, even if the architect's general reasoning suggests an alternative. <!-- Added: forge#259 -->
|
|
@@ -33,6 +33,117 @@ Parse from `$ARGUMENTS`:
|
|
|
33
33
|
|
|
34
34
|
---
|
|
35
35
|
|
|
36
|
+
## Phase C-1: Authoritative Devdocs
|
|
37
|
+
|
|
38
|
+
Read project-resident authoritative docs **before** any institutional-memory queries. Devdocs contain binding project knowledge (conventions, architecture, custom instructions) that must inform the builder's mental model from the start.
|
|
39
|
+
|
|
40
|
+
**Time budget**: 30 seconds. If exceeded, log a skip note and continue to Phase C0.
|
|
41
|
+
|
|
42
|
+
**Skip if**: `{REPO_PATH}` is not set, devdocs path does not exist, or path contains no markdown files.
|
|
43
|
+
|
|
44
|
+
### Step 0: Resolve devdocs path
|
|
45
|
+
|
|
46
|
+
Read `forge.yaml → devdocs.path` from the project root. Default to `devdocs` if the key is absent or unreadable.
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
DEVDOCS_PATH=""
|
|
50
|
+
|
|
51
|
+
# Read forge.yaml directly from repo root (REPO_PATH points to the project root — no directory walk)
|
|
52
|
+
FORGE_YAML_PATH="{REPO_PATH}/forge.yaml"
|
|
53
|
+
|
|
54
|
+
if [ -f "$FORGE_YAML_PATH" ]; then
|
|
55
|
+
# Extract devdocs.path key (simple grep — value is on the same or next line under "devdocs:")
|
|
56
|
+
DEVDOCS_REL=$(grep -A5 '^devdocs:' "$FORGE_YAML_PATH" \
|
|
57
|
+
| grep '^\s*path:' \
|
|
58
|
+
| head -1 \
|
|
59
|
+
| sed 's/.*path:\s*//' \
|
|
60
|
+
| tr -d '"'"'"' \
|
|
61
|
+
| tr -d '[:space:]')
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
# Default to "devdocs" if not found
|
|
65
|
+
DEVDOCS_REL="${DEVDOCS_REL:-devdocs}"
|
|
66
|
+
DEVDOCS_PATH="{REPO_PATH}/${DEVDOCS_REL}"
|
|
67
|
+
|
|
68
|
+
if [ ! -d "$DEVDOCS_PATH" ]; then
|
|
69
|
+
echo "Devdocs path '${DEVDOCS_PATH}' does not exist — skipping Phase C-1 (no blocking)"
|
|
70
|
+
DEVDOCS_PATH=""
|
|
71
|
+
fi
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
> **Note**: `devdocs/` must be tracked in git for the worktree to contain it. If the project gitignores `devdocs/`, the path will not exist in the worktree and this phase silently skips — this is by design. Run `git check-ignore -v devdocs/` to confirm tracking status.
|
|
75
|
+
|
|
76
|
+
### Step 1: Enumerate and filter applicable files
|
|
77
|
+
|
|
78
|
+
Find all `.md` files under `DEVDOCS_PATH`, parse YAML frontmatter, keep those with `work-on` in `applies_to`. Sort by authority (`required` first, then `recommended`, then `reference`).
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
DEVDOCS_APPLICABLE="" # list of paths that apply
|
|
82
|
+
|
|
83
|
+
if [ -n "$DEVDOCS_PATH" ]; then
|
|
84
|
+
# Find all markdown files recursively
|
|
85
|
+
while IFS= read -r -d '' mdfile; do
|
|
86
|
+
# Extract frontmatter block (between first two --- markers)
|
|
87
|
+
FRONTMATTER=$(awk '/^---/{c++; if(c==1){next} if(c==2){exit}} c==1{print}' "$mdfile" 2>/dev/null)
|
|
88
|
+
|
|
89
|
+
# Check if applies_to contains work-on
|
|
90
|
+
if echo "$FRONTMATTER" | grep -q 'applies_to:.*work-on'; then
|
|
91
|
+
AUTHORITY=$(echo "$FRONTMATTER" | grep 'authority:' | head -1 | sed 's/.*authority:\s*//' | tr -d ' ')
|
|
92
|
+
# Prepend sort key: 1=required, 2=recommended, 3=reference, 4=other
|
|
93
|
+
case "$AUTHORITY" in
|
|
94
|
+
required) SORT_KEY="1" ;;
|
|
95
|
+
recommended) SORT_KEY="2" ;;
|
|
96
|
+
reference) SORT_KEY="3" ;;
|
|
97
|
+
*) SORT_KEY="4" ;;
|
|
98
|
+
esac
|
|
99
|
+
DEVDOCS_APPLICABLE="${DEVDOCS_APPLICABLE}${SORT_KEY}|${mdfile}\n"
|
|
100
|
+
fi
|
|
101
|
+
done < <(find "$DEVDOCS_PATH" -name "*.md" -print0 2>/dev/null)
|
|
102
|
+
|
|
103
|
+
# Sort by authority key and extract paths
|
|
104
|
+
DEVDOCS_APPLICABLE=$(printf "$DEVDOCS_APPLICABLE" | sort | cut -d'|' -f2-)
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
if [ -z "$DEVDOCS_APPLICABLE" ]; then
|
|
108
|
+
echo "No devdocs files with 'applies_to: work-on' found — skipping Phase C-1 content read"
|
|
109
|
+
fi
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Step 2: Read content of applicable files
|
|
113
|
+
|
|
114
|
+
For each applicable file: read its content (max 200 lines; truncate with note if longer). Accumulate for output.
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
DEVDOCS_CONTENT=""
|
|
118
|
+
|
|
119
|
+
while IFS= read -r mdfile; do
|
|
120
|
+
[ -z "$mdfile" ] && continue
|
|
121
|
+
TOTAL_LINES=$(wc -l < "$mdfile" 2>/dev/null || echo 0)
|
|
122
|
+
if [ "$TOTAL_LINES" -gt 200 ]; then
|
|
123
|
+
FILE_CONTENT=$(head -200 "$mdfile")
|
|
124
|
+
TRUNCATION_NOTE="_[Truncated at 200 lines — ${TOTAL_LINES} total. Read full file for complete context.]_"
|
|
125
|
+
else
|
|
126
|
+
FILE_CONTENT=$(cat "$mdfile")
|
|
127
|
+
TRUNCATION_NOTE=""
|
|
128
|
+
fi
|
|
129
|
+
|
|
130
|
+
# Relative path for display
|
|
131
|
+
REL_PATH="${mdfile#${DEVDOCS_PATH}/}"
|
|
132
|
+
|
|
133
|
+
DEVDOCS_CONTENT="${DEVDOCS_CONTENT}
|
|
134
|
+
|
|
135
|
+
#### \`${REL_PATH}\`
|
|
136
|
+
${FILE_CONTENT}
|
|
137
|
+
${TRUNCATION_NOTE}"
|
|
138
|
+
done <<< "$DEVDOCS_APPLICABLE"
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Step 3: Store for output
|
|
142
|
+
|
|
143
|
+
`DEVDOCS_CONTENT` is used in the `### Authoritative Devdocs` section of the FORGE:CONTEXT comment output. If empty (path absent or no applicable files), the section is replaced with a skip note.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
36
147
|
## Phase C0: Prior Investigation Findings (from Gists)
|
|
37
148
|
|
|
38
149
|
Scan the issue body for `<!-- FORGE:PRIOR_GIST: {url} -->` annotations embedded by the decompose or orchestrate phases (GIST-02). Also check for `<!-- FORGE:MILESTONE_INDEX: {url} -->` annotations — these reference a milestone-level index Gist (GIST-04) that aggregates all investigation Gist URLs for a milestone into a single reference. Both annotation types reference Knowledge Gists created during upstream investigation (GIST-01) and contain structured findings — verdict, root cause, recommendation, affected files — that the builder needs before writing code.
|
|
@@ -278,6 +389,14 @@ Post the following as a GitHub comment on `{NUMBER}`:
|
|
|
278
389
|
gh issue comment {NUMBER} -R {GH_REPO} --body "<!-- FORGE:CONTEXT -->
|
|
279
390
|
## Implementation Context for #{NUMBER}
|
|
280
391
|
|
|
392
|
+
### Authoritative Devdocs
|
|
393
|
+
<!-- Project-resident authoritative knowledge read from devdocs/ (Phase C-1).
|
|
394
|
+
These files have the highest precedence — they override agent defaults and memory.
|
|
395
|
+
custom-instructions.md directives are BINDING and MUST be followed exactly.
|
|
396
|
+
If devdocs path was absent or no files matched applies_to: work-on — write:
|
|
397
|
+
'No devdocs found at {DEVDOCS_PATH} — skipping. Run `npx forgedock docs init` to scaffold.' -->
|
|
398
|
+
{DEVDOCS_CONTENT}
|
|
399
|
+
|
|
281
400
|
### Prior Investigation Findings
|
|
282
401
|
<!-- Summarized Knowledge Gist content from upstream investigations (Phase C0).
|
|
283
402
|
If no FORGE:PRIOR_GIST annotations were found in the issue body: omit this section entirely.
|
|
@@ -317,11 +436,12 @@ gh issue comment {NUMBER} -R {GH_REPO} --body "<!-- FORGE:CONTEXT -->
|
|
|
317
436
|
|
|
318
437
|
## Timing Rules
|
|
319
438
|
|
|
439
|
+
- Phase C-1 devdocs read: 30s total budget (file enumeration + content reads combined); skip if exceeded
|
|
320
440
|
- Phase C0 `gh gist view` calls: timeout after 15s each, 30s total budget for all Gist fetches
|
|
321
441
|
- Each `gh issue list` call: timeout after 20s, skip if exceeded
|
|
322
442
|
- Each `gh pr list` call: timeout after 20s, skip if exceeded
|
|
323
443
|
- Each `grep -r` call: timeout after 10s, skip if exceeded
|
|
324
|
-
- Total wall time budget: **2 minutes** (
|
|
444
|
+
- Total wall time budget: **2 minutes** (C-1 through C4 combined). If budget exceeded, post partial results with `<!-- FORGE:CONTEXT:PARTIAL -->` marker instead of `COMPLETE`.
|
|
325
445
|
|
|
326
446
|
---
|
|
327
447
|
|
|
@@ -339,11 +459,19 @@ Skip this entire step (post nothing, return empty briefing) if:
|
|
|
339
459
|
This module runs at **Step 3C.5** — after Builder Contract is posted, before Implement:
|
|
340
460
|
|
|
341
461
|
```
|
|
342
|
-
3C
|
|
462
|
+
3C → Builder Contract posted
|
|
343
463
|
3C.5 → [THIS MODULE] Context gathering (max 2 min)
|
|
344
|
-
|
|
464
|
+
Phase C-1: Authoritative Devdocs (project-resident knowledge — highest precedence)
|
|
465
|
+
Phase C0: Prior Investigation Findings (from Gists)
|
|
466
|
+
Phase C1: Past Review Findings on These Files
|
|
467
|
+
Phase C2: Past Bugs in the Same Module
|
|
468
|
+
Phase C3: Related Code Paths
|
|
469
|
+
Phase C4: Successful Similar Implementations
|
|
470
|
+
3F → Implement (builder now has context briefing)
|
|
345
471
|
```
|
|
346
472
|
|
|
347
473
|
The builder agent reads the `<!-- FORGE:CONTEXT -->` comment before writing any code. If the context step was skipped, the builder proceeds with investigation report + contract only.
|
|
348
474
|
|
|
475
|
+
**Devdocs precedence** (Phase C-1): Content from `project/custom-instructions.md` has the HIGHEST precedence of all context sources. Directives there override agent defaults, training knowledge, and all other devdocs. Other `project/*.md` and `agent/*.md` files with `applies_to: work-on` provide authoritative project conventions and ForgeDock usage guidance. <!-- Added: forge#259 -->
|
|
476
|
+
|
|
349
477
|
When prior investigation Gists are available (Phase C0), the `### Prior Investigation Findings` section gives the builder cross-issue context — root causes, recommendations, and affected files from upstream investigations — without requiring manual Gist lookups. When a milestone-level index Gist exists (GIST-04), Phase C0 can resolve the index to discover all investigation Gists for the milestone from a single URL — providing full milestone-wide context automatically. <!-- Updated: forge#341 -->
|
|
@@ -88,31 +88,50 @@ Needs human review before proceeding to commit.
|
|
|
88
88
|
|
|
89
89
|
## Phase V2: Format and Verify
|
|
90
90
|
|
|
91
|
-
Run after quality gate passes.
|
|
91
|
+
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:
|
|
92
92
|
|
|
93
93
|
**Python**:
|
|
94
94
|
```bash
|
|
95
95
|
cd {WORKTREE_PATH}
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
|
|
97
|
+
PYTHON_FORMAT=$(awk '/^ commands:/{f=1;next} f && /^[^ \t]/{exit} f' forge.yaml 2>/dev/null | awk '/^ python:/{f=1;next} f && /^ [^ \t]/{exit} f' | grep 'format:' | head -1 | sed "s/.*format: *['\"]//;s/['\"].*//")
|
|
98
|
+
if [ -n "$PYTHON_FORMAT" ]; then
|
|
99
|
+
eval "$PYTHON_FORMAT" 2>&1
|
|
100
|
+
else
|
|
101
|
+
echo "SKIPPED — python.format not configured in verification.commands"
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# Compile check always runs for Python files (no config needed — catches syntax errors)
|
|
98
105
|
python -m py_compile {PYTHON_FILES}
|
|
99
106
|
```
|
|
100
107
|
Failures in `py_compile` are BLOCKING — fix before continuing.
|
|
101
108
|
|
|
102
|
-
**TypeScript
|
|
109
|
+
**TypeScript**:
|
|
103
110
|
```bash
|
|
104
111
|
cd {WORKTREE_PATH}
|
|
105
|
-
prettier --write {TS_FILES}
|
|
106
|
-
tsc --noEmit
|
|
107
|
-
```
|
|
108
|
-
`tsc --noEmit` failures are BLOCKING — fix type errors before continuing.
|
|
109
112
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
TS_FORMAT=$(awk '/^ commands:/{f=1;next} f && /^[^ \t]/{exit} f' forge.yaml 2>/dev/null | awk '/^ typescript:/{f=1;next} f && /^ [^ \t]/{exit} f' | grep 'format:' | head -1 | sed "s/.*format: *['\"]//;s/['\"].*//")
|
|
114
|
+
TS_TYPECHECK=$(awk '/^ commands:/{f=1;next} f && /^[^ \t]/{exit} f' forge.yaml 2>/dev/null | awk '/^ typescript:/{f=1;next} f && /^ [^ \t]/{exit} f' | grep 'typecheck:' | head -1 | sed "s/.*typecheck: *['\"]//;s/['\"].*//")
|
|
115
|
+
TS_BUILD=$(awk '/^ commands:/{f=1;next} f && /^[^ \t]/{exit} f' forge.yaml 2>/dev/null | awk '/^ typescript:/{f=1;next} f && /^ [^ \t]/{exit} f' | grep 'build:' | head -1 | sed "s/.*build: *['\"]//;s/['\"].*//")
|
|
116
|
+
|
|
117
|
+
if [ -n "$TS_FORMAT" ]; then
|
|
118
|
+
eval "$TS_FORMAT" 2>&1
|
|
119
|
+
else
|
|
120
|
+
echo "SKIPPED — typescript.format not configured in verification.commands"
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
if [ -n "$TS_TYPECHECK" ]; then
|
|
124
|
+
eval "$TS_TYPECHECK" 2>&1
|
|
125
|
+
TS_EXIT=$?
|
|
126
|
+
elif [ -n "$TS_BUILD" ]; then
|
|
127
|
+
eval "$TS_BUILD" 2>&1 | tail -30
|
|
128
|
+
TS_EXIT=$?
|
|
129
|
+
else
|
|
130
|
+
echo "SKIPPED — typescript.typecheck and typescript.build not configured in verification.commands"
|
|
131
|
+
TS_EXIT=0
|
|
132
|
+
fi
|
|
115
133
|
```
|
|
134
|
+
Typecheck or build failures are BLOCKING — fix type errors before continuing.
|
|
116
135
|
|
|
117
136
|
**Shell scripts**: Verify service interactions — read target middleware files, document what was verified in V4 summary.
|
|
118
137
|
|
|
@@ -40,6 +40,8 @@ gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
|
|
|
40
40
|
- If FORGE:INVESTIGATOR comment is absent → EXIT with `DECOMPOSE_RESULT: status: BLOCKED`, blocker: "No investigation report found — run investigate first"
|
|
41
41
|
- If investigation report has no Decomposition Assessment section, OR the assessment does not list any sub-issues → EXIT with `DECOMPOSE_RESULT: status: BLOCKED`, blocker: "Investigation report has no decomposition plan — re-run investigate with explicit decomposition scope"
|
|
42
42
|
|
|
43
|
+
> **Shared Scoping Convention**: This investigation gate (blocks without a `FORGE:INVESTIGATOR` comment) is the **reference pattern** for investigation-gated issue creation across the pipeline. `milestone.md` Step 4 and `orchestrate.md` MUST apply the same principle: read code and identify all affected call sites BEFORE writing any issue body. Sub-issue bodies created in Phase D3 MUST use the Pipeline Issue Template defined in `issue.md` Phase 3D — that template is the single canonical standard for all automated issue creation. <!-- Added: forge#293 -->
|
|
44
|
+
|
|
43
45
|
Extract from investigation report:
|
|
44
46
|
- Decomposition Assessment section: list of proposed sub-issues with titles and dependencies
|
|
45
47
|
- Milestone (from issue metadata)
|
|
@@ -89,16 +89,20 @@ Mission: Validate whether the issue is real. Assume description is wrong until p
|
|
|
89
89
|
|
|
90
90
|
**Domain file hints** (start search here):
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
|
95
|
-
|
|
92
|
+
Configure domain-to-file mappings for your project in `forge.yaml → review.key_paths`. The table below shows the standard layout — override any entry that doesn't match your codebase:
|
|
93
|
+
|
|
94
|
+
| Domain | Default key files (override via forge.yaml) |
|
|
95
|
+
|--------|---------------------------------------------|
|
|
96
|
+
| BILLING | `routers/billing.py`, `core/pricing.py`, `services/payment_service.py` |
|
|
97
|
+
| WORKER | `worker/main.py`, `worker/queues.py`, `worker/tasks.py` |
|
|
96
98
|
| AUTH | `core/auth.py`, `routers/auth.py`, `dependencies.py` |
|
|
97
99
|
| DATABASE | `infra/migrations/`, `models/`, `db/` |
|
|
98
100
|
| FRONTEND | `web/src/app/`, `web/src/components/`, `web/src/lib/` |
|
|
99
|
-
|
|
|
101
|
+
| AI | `services/ai_client.py`, `routers/ai.py` |
|
|
100
102
|
| INFRA | `.github/workflows/`, `docker-compose.yml`, `infra/traefik/` |
|
|
101
103
|
|
|
104
|
+
If `forge.yaml → review.key_paths` is present, use those mappings instead of the defaults above.
|
|
105
|
+
|
|
102
106
|
**Steps**: Check right branch → read domain files → verify claims → git blame → determine root cause → identify affected files → validate proposed fixes against full system stack.
|
|
103
107
|
|
|
104
108
|
**Fix-Approach Validation**: If issue proposes a fix, don't adopt it as spec. Trace through target system's middleware, auth, routing.
|