forgedock 1.0.0 → 1.0.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.
Files changed (42) hide show
  1. package/README.md +19 -2
  2. package/bin/forgedock.mjs +286 -10
  3. package/commands/analytics.md +129 -52
  4. package/commands/audit-agents.md +29 -5
  5. package/commands/audit.md +55 -17
  6. package/commands/autopilot.md +11 -6
  7. package/commands/cleanup.md +44 -24
  8. package/commands/deploy-info.md +7 -3
  9. package/commands/forge-stats.md +13 -4
  10. package/commands/forgedock-init.md +534 -0
  11. package/commands/geo-audit.md +114 -26
  12. package/commands/incident-response.md +4 -1
  13. package/commands/issue.md +26 -25
  14. package/commands/milestone.md +80 -59
  15. package/commands/orchestrate.md +38 -21
  16. package/commands/pipeline-health.md +26 -15
  17. package/commands/qa-sweep.md +68 -5
  18. package/commands/quality-gate.md +18 -0
  19. package/commands/review-pr-agents.md +58 -90
  20. package/commands/review-pr.md +58 -16
  21. package/commands/rollback.md +8 -5
  22. package/commands/security-audit.md +68 -12
  23. package/commands/sync-ecosystem.md +196 -156
  24. package/commands/validate.md +1 -1
  25. package/commands/work-on/build/architect.md +2 -2
  26. package/commands/work-on/build/context.md +2 -2
  27. package/commands/work-on/build/implement.md +3 -3
  28. package/commands/work-on/build/validate.md +3 -3
  29. package/commands/work-on/build.md +6 -6
  30. package/commands/work-on/close.md +59 -30
  31. package/commands/work-on/decompose.md +6 -6
  32. package/commands/work-on/investigate.md +16 -20
  33. package/commands/work-on/review.md +4 -4
  34. package/commands/work-on-monolithic.md +15 -16
  35. package/commands/work-on.md +45 -33
  36. package/docs/CODEX.md +1 -1
  37. package/docs/CONFIG.md +398 -0
  38. package/docs/WORKFLOW.md +115 -72
  39. package/package.json +2 -2
  40. package/scripts/verify-host-headers.sh +14 -9
  41. package/scripts/verify-route-registration.sh +10 -10
  42. package/commands/failure-recon.md +0 -375
@@ -4,7 +4,7 @@ argument-hint: [PR number, URL, "open", or "staging" for feature→main review]
4
4
  allowed-tools: Task, Bash, Read, Grep, Glob, WebFetch, Skill
5
5
  ---
6
6
 
7
- # AlterLab PR Review — Orchestrator
7
+ # PR Review — Orchestrator
8
8
 
9
9
  **Input**: $ARGUMENTS
10
10
 
@@ -20,8 +20,10 @@ This is the **orchestrator**. It routes to the right review mode, runs automated
20
20
 
21
21
  | File | What | How to invoke |
22
22
  |------|------|---------------|
23
- | `/home/mrdubey/.claude/commands/review-pr-agents.md` | Agent prompt templates (9 agents + protocols) | `Read` tool during Phase 3C |
24
- | `/home/mrdubey/.claude/commands/review-pr-staging.md` | Full staging→main review pipeline | `Skill("review-pr-staging", ...)` during Phase 0 |
23
+ | `$FORGE_HOME/commands/review-pr-agents.md` | Agent prompt templates (9 agents + protocols) | `Read` tool during Phase 3C |
24
+ | `$FORGE_HOME/commands/review-pr-staging.md` | Full staging→main review pipeline | `Skill("review-pr-staging", ...)` during Phase 0 |
25
+
26
+ `$FORGE_HOME` defaults to `~/.claude` (the directory where `npx forgedock` symlinks commands). Override by setting `FORGE_HOME` in your environment.
25
27
 
26
28
  **Invocation flow:**
27
29
  ```
@@ -38,7 +40,7 @@ This is the **orchestrator**. It routes to the right review mode, runs automated
38
40
  If `$ARGUMENTS` contains `--auto-merge`, this review was invoked from `/work-on` and must merge the PR after approval. Parse:
39
41
 
40
42
  ```
41
- Example: "3126 --auto-merge --issue 3124 --base staging --gh-flag -R RapierCraft/AlterLab --worktree /path/to/worktree"
43
+ Example: "3126 --auto-merge --issue 3124 --base staging --gh-flag -R $GH_REPO --worktree /path/to/worktree"
42
44
  ```
43
45
 
44
46
  Extract: `PR_NUMBER`, `AUTO_MERGE=true`, `MERGE_ISSUE`, `MERGE_BASE`, `MERGE_GH_FLAG`, `MERGE_WORKTREE` (optional — the absolute path to the git worktree to clean up after merge)
@@ -292,12 +294,12 @@ Map each changed file to its activation requirements:
292
294
  | `web/src/app/**/*-client.tsx`, `web/src/components/**/*.tsx`, `web/src/lib/*.ts` (Client-side code with `fetch()`/`useSWR()`) | Client requests go through Next.js proxy (`/api/...`), never directly to FastAPI (`/api/v1/...`) | Grep changed `.tsx`/`.ts` files (excluding `route.ts` proxy handlers) for `fetch("/api/v1/` or `` `/api/v1/ `` in template literals or `useSWR.*"/api/v1/`. Any match is a **CONFIRMED BLOCKING** integration bug — direct calls bypass session auth (admin proxy JWT, session-to-bearer conversion) and fail locally (no nginx). |
293
295
  | `.github/workflows/*.yml` (Workflow with test/build jobs) | Sibling workflows with same-named jobs stay in sync | For each job name in the changed workflow, check if the same job name exists in sibling workflows (`ci.yml` ↔ `deploy-production.yml` ↔ `hotfix-deploy.yml`). Compare env vars, PYTHONPATH, working-directory, and run commands for meaningful drift. |
294
296
  | `docker-compose*.yml` changes to `postgres` or `redis` service (`command:`, `image:`, `volumes:`, `environment:`) | Stateful container will NOT be recreated during deploy, OR restart is safe | **Auto-escalate to HIGH risk.** Changing `command:` args, `image:` tag, or `volumes:` forces container recreation on `docker-compose up`. For stateful services (postgres, redis), verify: (1) `stop_grace_period` is set and sufficient (≥30s for PG); (2) `full_page_writes = on` in PG config (protects against partial page writes on crash); (3) `fsync = on` (ensures write durability); (4) No long-running transactions will be interrupted. If container recreation is unavoidable, recommend scheduling during a maintenance window — NOT as a side effect of a routine deploy. **This check prevents the class of incident documented in issue #146**: a PG `command:` arg change triggered container restart under active load, corrupting btree indexes. |
295
- | `docker-compose*.yml` changes `entrypoint:` or `command:` to reference a script (`.sh` file) | Env vars used inside the entrypoint script are available inside the container at runtime | **Run `verify-env-vars.sh`** which detects shell `${VAR}` references in entrypoint scripts and cross-checks against the service's `environment:` section. Docker Compose `${VAR}` in YAML `command:` is parsed at Compose load time (host-side) — the var doesn't need to be in the container. But `${VAR}` inside an entrypoint `.sh` script runs at container runtime — it MUST be injected via `environment:` or `env_file:`. **This check prevents the class of incident documented in RapierCraftStudios/forge#185**: Redis migrated from `command: --requirepass ${REDIS_PASSWORD}` (Compose interpolation) to `entrypoint.sh` (container runtime) without adding `environment: REDIS_PASSWORD`, causing a restart loop on deploy. |
297
+ | `docker-compose*.yml` changes `entrypoint:` or `command:` to reference a script (`.sh` file) | Env vars used inside the entrypoint script are available inside the container at runtime | **Run `verify-env-vars.sh`** which detects shell `${VAR}` references in entrypoint scripts and cross-checks against the service's `environment:` section. Docker Compose `${VAR}` in YAML `command:` is parsed at Compose load time (host-side) — the var doesn't need to be in the container. But `${VAR}` inside an entrypoint `.sh` script runs at container runtime — it MUST be injected via `environment:` or `env_file:`. **This check prevents the class of incident where a service migrates from `command:` args (Compose interpolation) to an entrypoint script (container runtime) without adding the env var to `environment:`, causing a restart loop on deploy.** <!-- Added: forge#185 --> |
296
298
  | **ANY staging→main PR** (regardless of files changed) | `ci.yml` and `deploy-production.yml` test jobs are in sync | **ALWAYS runs for staging→main PRs.** Pre-existing drift is invisible until deploy. Deep-diff shared jobs (test-api, test-web): compare PYTHONPATH values, dependency install steps, and step names. A missing PYTHONPATH or install step in deploy is CONFIRMED BLOCKING — CI passes but deploy fails (PR #11356 incident). |
297
299
 
298
300
  ### Step 2.5B: Run Verification
299
301
 
300
- For each changed file, execute the relevant checks using the standalone verification scripts in `~/projects/forge/scripts/`. These scripts can also be run independently outside the review context (e.g., from `/quality-gate` or `/work-on` builder steps).
302
+ For each changed file, execute the relevant checks using the standalone verification scripts in `$FORGE_HOME/scripts/`. These scripts can also be run independently outside the review context (e.g., from `/quality-gate` or `/work-on` builder steps).
301
303
 
302
304
  ```bash
303
305
  CHANGED_FILES=$(gh pr diff $ARGUMENTS --name-only)
@@ -315,19 +317,29 @@ gh pr diff $ARGUMENTS > "$DIFF_TMP"
315
317
 
316
318
  # 1. Route/router/middleware/shared-module/component registration
317
319
  echo "=== Running: verify-route-registration.sh ==="
318
- ~/projects/forge/scripts/verify-route-registration.sh "$CHANGED_FILES_TMP" "$REPO_ROOT" || true
320
+ $FORGE_HOME/scripts/verify-route-registration.sh "$CHANGED_FILES_TMP" "$REPO_ROOT" || true
319
321
 
320
322
  # 2. Environment variable wiring (checks .env.example, docker-compose, env_validation, SOPS mapping)
321
323
  echo "=== Running: verify-env-vars.sh ==="
322
- ~/projects/forge/scripts/verify-env-vars.sh "$DIFF_TMP" "$REPO_ROOT" || true
324
+ $FORGE_HOME/scripts/verify-env-vars.sh "$DIFF_TMP" "$REPO_ROOT" || true
323
325
 
324
326
  # 3. Host headers in shell scripts + client-side proxy bypass check
327
+ # Read project-specific internal service patterns from forge.yaml (if present)
328
+ FORGE_INTERNAL_PATTERNS=""
329
+ if [ -f "$REPO_ROOT/forge.yaml" ]; then
330
+ FORGE_INTERNAL_PATTERNS=$(grep -A 999 'internal_service_patterns:' "$REPO_ROOT/forge.yaml" \
331
+ | grep -E '^\s*-\s+' \
332
+ | sed 's/^\s*-\s*//' \
333
+ | tr -d '"'"'" \
334
+ | paste -sd '|' -)
335
+ fi
336
+ export FORGE_INTERNAL_PATTERNS
325
337
  echo "=== Running: verify-host-headers.sh ==="
326
- ~/projects/forge/scripts/verify-host-headers.sh "$CHANGED_FILES_TMP" "$REPO_ROOT" || true
338
+ $FORGE_HOME/scripts/verify-host-headers.sh "$CHANGED_FILES_TMP" "$REPO_ROOT" || true
327
339
 
328
340
  # 4. SOPS deploy chain (ENV_MAPPING consistency, deploy path drift, hotfix sync)
329
341
  echo "=== Running: verify-sops-chain.sh ==="
330
- ~/projects/forge/scripts/verify-sops-chain.sh "$DIFF_TMP" "$CHANGED_FILES_TMP" "$REPO_ROOT" || true
342
+ $FORGE_HOME/scripts/verify-sops-chain.sh "$DIFF_TMP" "$CHANGED_FILES_TMP" "$REPO_ROOT" || true
331
343
 
332
344
  # Cleanup temp files
333
345
  rm -f "$CHANGED_FILES_TMP" "$DIFF_TMP"
@@ -488,14 +500,37 @@ echo "$FILES" | grep -cE "^sdk/|openapi.*\.json$|openapi-versions/" && echo " S
488
500
 
489
501
  **>>> INVOCATION: Read the agent catalog file:**
490
502
  ```
491
- Read the file: /home/mrdubey/.claude/commands/review-pr-agents.md
503
+ Read the file: $FORGE_HOME/commands/review-pr-agents.md
492
504
  ```
493
505
 
506
+ (`$FORGE_HOME` defaults to `~/.claude`)
507
+
508
+ **>>> LOAD CONFIG: Read forge.yaml for project context:**
509
+ ```bash
510
+ # Read review config from forge.yaml (if present in project root)
511
+ FORGE_YAML="${REPO_ROOT}/forge.yaml"
512
+ PROJECT_NAME=$(yq '.project.name' "$FORGE_YAML" 2>/dev/null || echo "this project")
513
+ PROJECT_CONTEXT=$(yq '.review.context' "$FORGE_YAML" 2>/dev/null || echo "")
514
+ TECH_STACK=$(yq '.review.tech_stack' "$FORGE_YAML" 2>/dev/null || echo "")
515
+ # Domain-specific context (keyed by agent name)
516
+ DOMAIN_CONTEXT_AUTH=$(yq '.review.domains.auth' "$FORGE_YAML" 2>/dev/null || echo "")
517
+ DOMAIN_CONTEXT_BILLING=$(yq '.review.domains.billing' "$FORGE_YAML" 2>/dev/null || echo "")
518
+ DOMAIN_CONTEXT_INFRA=$(yq '.review.domains.infra' "$FORGE_YAML" 2>/dev/null || echo "")
519
+ DOMAIN_CONTEXT_DATABASE=$(yq '.review.domains.database' "$FORGE_YAML" 2>/dev/null || echo "")
520
+ DOMAIN_CONTEXT_FRONTEND=$(yq '.review.domains.frontend' "$FORGE_YAML" 2>/dev/null || echo "")
521
+ DOMAIN_CONTEXT_SECURITY=$(yq '.review.domains.security' "$FORGE_YAML" 2>/dev/null || echo "")
522
+ DOMAIN_CONTEXT_API=$(yq '.review.domains.api' "$FORGE_YAML" 2>/dev/null || echo "")
523
+ ```
524
+
525
+ If `forge.yaml` is absent or a field is empty/null, agents fall back to generic checks (no project-specific context injected — agents still function correctly, just without project conventions).
526
+
494
527
  This file contains the Evidence-Based Review Protocol, Structured Findings Protocol, and all 9 agent prompt templates. For each selected agent:
495
528
  1. Extract its template from the catalog
496
529
  2. Substitute: `[PR_NUMBER]`, `[REVIEW_SHA]`, `[REVIEW_SHA_SHORT]`, `[TITLE]`, relevant files list
497
- 3. If Phase 2.5 found broken assumptions, append them to the agent's prompt as "Pre-found integration issues to verify"
498
- 4. Launch via `Task` tool with the resolved model (default `"sonnet"`, fallback `"opus"` if rate-limited)
530
+ 3. Substitute: `[PROJECT_NAME]` → `$PROJECT_NAME`, `[PROJECT_CONTEXT]` → `$PROJECT_CONTEXT`, `[TECH_STACK]` → `$TECH_STACK`
531
+ 4. Substitute per-agent domain context: `[DOMAIN_CONTEXT]` → the agent's matching key from `forge.yaml → review.domains` (e.g., `$DOMAIN_CONTEXT_AUTH` for the auth agent, `$DOMAIN_CONTEXT_BILLING` for the billing agent)
532
+ 5. If Phase 2.5 found broken assumptions, append them to the agent's prompt as "Pre-found integration issues to verify"
533
+ 6. Launch via `Task` tool with the resolved model (default `"sonnet"`, fallback `"opus"` if rate-limited)
499
534
 
500
535
  **CRITICAL**: Launch ALL selected agents in a SINGLE message using multiple Task tool calls. Each agent posts findings directly to the PR via `gh pr comment`.
501
536
 
@@ -711,10 +746,17 @@ Labels: `review-finding` + `needs-validation` + priority (`P1` CONFIRMED, `P2` L
711
746
  **Add to project board:**
712
747
  ```bash
713
748
  for FINDING_NUM in {numbers}; do
714
- ITEM_ID=$(gh project item-add 1 --owner RapierCraft --url "https://github.com/RapierCraft/AlterLab/issues/${FINDING_NUM}" --format json --jq '.id' 2>/dev/null)
749
+ # GH_REPO and board IDs are read from forge.yaml → project_board section
750
+ # OWNER = forge.yaml → project_board.owner (or project.owner)
751
+ # PROJECT_NUMBER = forge.yaml → project_board.project_number
752
+ # PROJECT_ID = forge.yaml → project_board.project_id
753
+ # STATUS_FIELD_ID = forge.yaml → project_board.field_ids.status
754
+ # LANE_FIELD_ID = forge.yaml → project_board.field_ids.lane
755
+ # REVIEW_FINDING_OPTION_ID = forge.yaml → project_board.option_ids.status.in_review
756
+ ITEM_ID=$(gh project item-add ${PROJECT_NUMBER} --owner ${OWNER} --url "https://github.com/${GH_REPO}/issues/${FINDING_NUM}" --format json --jq '.id' 2>/dev/null)
715
757
  [ -n "$ITEM_ID" ] && {
716
- gh project item-edit --project-id PVT_kwHOCx3gR84BSK2L --id "$ITEM_ID" --field-id PVTSSF_lAHOCx3gR84BSK2Lzg_yF6E --single-select-option-id f75ad846 2>/dev/null || true
717
- gh project item-edit --project-id PVT_kwHOCx3gR84BSK2L --id "$ITEM_ID" --field-id PVTSSF_lAHOCx3gR84BSK2Lzg_yF98 --single-select-option-id 62864af4 2>/dev/null || true
758
+ [ -n "$STATUS_FIELD_ID" ] && gh project item-edit --project-id ${PROJECT_ID} --id "$ITEM_ID" --field-id ${STATUS_FIELD_ID} --single-select-option-id ${REVIEW_FINDING_OPTION_ID} 2>/dev/null || true
759
+ [ -n "$LANE_FIELD_ID" ] && gh project item-edit --project-id ${PROJECT_ID} --id "$ITEM_ID" --field-id ${LANE_FIELD_ID} --single-select-option-id ${LANE_OPTION_ID} 2>/dev/null || true
718
760
  }
719
761
  done
720
762
  ```
@@ -7,6 +7,9 @@ argument-hint: [PR number to revert, or "last" for most recent deploy]
7
7
 
8
8
  **Input**: $ARGUMENTS
9
9
 
10
+ **Config variables used by this command** (set in `forge.yaml`):
11
+ - `{REPO_PATH}` ← `paths.root` — project repository root
12
+
10
13
  You are the pipeline's emergency rollback system. When a shipped feature or fix causes production issues, this command creates a revert PR and fast-tracks it through the pipeline.
11
14
 
12
15
  **Agent model policy**: Default `model: "sonnet"`. If Sonnet is rate-limited, fall back to `model: "opus"`. User can override with `--model <name>`.
@@ -75,11 +78,11 @@ Which approach? (Reply or press enter for option 1)
75
78
  ### Step 2A: Create a revert branch
76
79
 
77
80
  ```bash
78
- cd /home/mrdubey/projects/ScraperAPI/alterlab
81
+ cd {REPO_PATH}
79
82
  git fetch origin main
80
- git worktree add ../alterlab-revert-pr-{PR_NUMBER} -b revert/pr-{PR_NUMBER} origin/main
83
+ git worktree add ../revert-pr-{PR_NUMBER} -b revert/pr-{PR_NUMBER} origin/main
81
84
 
82
- cd ../alterlab-revert-pr-{PR_NUMBER}
85
+ cd ../revert-pr-{PR_NUMBER}
83
86
  ```
84
87
 
85
88
  ### Step 2B: Execute the revert
@@ -230,8 +233,8 @@ BODY_EOF
230
233
  ### Step 4C: Clean up worktree
231
234
 
232
235
  ```bash
233
- cd /home/mrdubey/projects/ScraperAPI/alterlab
234
- git worktree remove ../alterlab-revert-pr-{PR_NUMBER}
236
+ cd {REPO_PATH}
237
+ git worktree remove ../revert-pr-{PR_NUMBER}
235
238
  git branch -D revert/pr-{PR_NUMBER} 2>/dev/null || true
236
239
  ```
237
240
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Periodic security posture audit — runs a scripted 4-phase checklist against repo files (not diffs), creates GitHub issues for confirmed findings
3
- argument-hint: [--repo alterlab|mcp|n8n] [--phase 1|2|3|4|all] [--dry-run]
3
+ argument-hint: [--repo <prefix>] [--phase 1|2|3|4|all] [--dry-run]
4
4
  ---
5
5
 
6
6
  # /security-audit — Periodic Security Posture Audit
@@ -21,22 +21,70 @@ This is NOT a PR review — it does not approve or block. It creates issues for
21
21
 
22
22
  ---
23
23
 
24
+ ## Config Preamble
25
+
26
+ Before executing any phase, read `forge.yaml` to resolve project references:
27
+
28
+ ```bash
29
+ CONFIG_FILE="${FORGE_CONFIG:-forge.yaml}"
30
+ if [ -f "$CONFIG_FILE" ]; then
31
+ GH_OWNER=$(yq '.project.owner' "$CONFIG_FILE")
32
+ GH_REPO_NAME=$(yq '.project.repo' "$CONFIG_FILE")
33
+ GH_REPO="${GH_OWNER}/${GH_REPO_NAME}"
34
+ GH_FLAG="-R $GH_REPO"
35
+ REPO_PATH=$(yq '.paths.root' "$CONFIG_FILE")
36
+ # FORGE_REPO: the self-pipeline repo where security audit summary comments are posted.
37
+ # Set project.forge_repo in forge.yaml if your pipeline repo differs from GH_REPO.
38
+ FORGE_REPO=$(yq '.project.forge_repo // ""' "$CONFIG_FILE")
39
+ [ -z "$FORGE_REPO" ] && FORGE_REPO="$GH_REPO"
40
+ # BILLING_ENABLED: controls whether Phase 4 (Financial Integrity) runs.
41
+ # Set billing.enabled: true in forge.yaml if your project uses Stripe billing.
42
+ BILLING_ENABLED=$(yq '.billing.enabled // "false"' "$CONFIG_FILE")
43
+ else
44
+ echo "WARNING: forge.yaml not found — commands will use placeholder values"
45
+ echo "Run: cp forge.yaml.example forge.yaml and fill in your project details"
46
+ GH_REPO="your-org/your-repo"
47
+ GH_FLAG="-R $GH_REPO"
48
+ REPO_PATH="./"
49
+ FORGE_REPO="$GH_REPO"
50
+ BILLING_ENABLED="false"
51
+ fi
52
+ ```
53
+
54
+ ---
55
+
24
56
  ## Multi-Repo Support
25
57
 
26
- | Input Pattern | Target Repo | GH_REPO | REPO_PATH |
27
- |---------------|-------------|---------|-----------|
28
- | `--repo alterlab` or default | AlterLab | `RapierCraft/AlterLab` | `/home/user/projects/alterlab` |
29
- | `--repo mcp` | MCP Server | `RapierCraft/alterlab-mcp-server` | `/home/user/projects/alterlab-mcp-server` |
30
- | `--repo n8n` | n8n Node | `RapierCraft/n8n-nodes-alterlab` | `/home/user/projects/n8n-nodes-alterlab` |
58
+ If your project spans multiple repositories, define them in the `repos.satellites` section of `forge.yaml`. The `--repo <prefix>` argument selects a satellite by its `prefix` field.
31
59
 
32
60
  Parse `$ARGUMENTS` for:
33
- - **`--repo <name>`**: target repo (default: `alterlab`)
61
+ - **`--repo <prefix>`**: target repo prefix (default: primary repo from `project.owner/project.repo`)
34
62
  - **`--phase <N|all>`**: run only a specific phase, or all (default: `all`)
35
63
  - **`--dry-run`**: print findings but do NOT create GitHub issues
36
64
 
37
- Set context variables from the table above. If `REPO_PATH` is not found locally, clone from GitHub:
65
+ Set context variables from config:
66
+
38
67
  ```bash
39
- gh repo clone {GH_REPO} {REPO_PATH} -- --depth=1 2>/dev/null || true
68
+ REPO_PREFIX=$(echo "$ARGUMENTS" | grep -oP '(?<=--repo )\S+' || true)
69
+
70
+ if [ -n "$REPO_PREFIX" ]; then
71
+ # Look up satellite repo by prefix in forge.yaml
72
+ SATELLITE_REPO=$(yq ".repos.satellites[] | select(.prefix == \"$REPO_PREFIX\") | .repo" "$CONFIG_FILE" 2>/dev/null)
73
+ if [ -n "$SATELLITE_REPO" ] && [ "$SATELLITE_REPO" != "null" ]; then
74
+ GH_REPO="$SATELLITE_REPO"
75
+ GH_FLAG="-R $GH_REPO"
76
+ REPO_PATH=$(yq ".repos.satellites[] | select(.prefix == \"$REPO_PREFIX\") | .local_path" "$CONFIG_FILE" 2>/dev/null || echo "$REPO_PATH")
77
+ # Also read billing flag for satellite if set
78
+ BILLING_ENABLED=$(yq ".repos.satellites[] | select(.prefix == \"$REPO_PREFIX\") | .billing_enabled // \"false\"" "$CONFIG_FILE" 2>/dev/null || echo "false")
79
+ else
80
+ echo "WARNING: --repo prefix '$REPO_PREFIX' not found in forge.yaml repos.satellites — using default repo"
81
+ fi
82
+ fi
83
+
84
+ # If REPO_PATH is not found locally, clone from GitHub
85
+ if [ ! -d "$REPO_PATH" ]; then
86
+ gh repo clone {GH_REPO} {REPO_PATH} -- --depth=1 2>/dev/null || true
87
+ fi
40
88
  ```
41
89
 
42
90
  ---
@@ -353,9 +401,17 @@ grep -rn '||\s*["'"'"'][a-zA-Z0-9]\{4,\}["'"'"']\|default.*password\|default.*se
353
401
 
354
402
  ---
355
403
 
356
- ## Phase 4: Financial Integrity (AlterLab-specific)
404
+ ## Phase 4: Financial Integrity
357
405
 
358
- *Skip this phase for non-AlterLab repos (MCP, n8n). These checks are specific to AlterLab's billing architecture.*
406
+ *Skip this phase if `billing.enabled` is not set to `true` in `forge.yaml`. These checks require Stripe webhook integration and a billing architecture in your project.*
407
+
408
+ ```bash
409
+ if [ "$BILLING_ENABLED" != "true" ]; then
410
+ echo "Phase 4 skipped — billing.enabled is not true in forge.yaml"
411
+ echo "To enable: add 'billing:\n enabled: true' to forge.yaml"
412
+ # Skip to Phase 5
413
+ fi
414
+ ```
359
415
 
360
416
  ### 4A: Stripe Webhook Handler Coverage
361
417
 
@@ -491,7 +547,7 @@ ISSUE_EOF
491
547
  If this command was invoked from within a `/work-on` context or with an issue reference:
492
548
 
493
549
  ```bash
494
- gh issue comment "{CALLER_ISSUE}" -R RapierCraftStudios/forge --body "$(cat <<'COMMENT_EOF'
550
+ gh issue comment "{CALLER_ISSUE}" -R {FORGE_REPO} --body "$(cat <<'COMMENT_EOF'
495
551
  <!-- FORGE:SECURITY_AUDIT -->
496
552
  ## Security Audit Complete
497
553