forgedock 1.1.7 → 1.1.9
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 +10 -33
- package/bin/cinema.mjs +23 -5
- package/bin/engine/invariants.mjs +361 -0
- package/bin/engine-cli.mjs +137 -11
- package/bin/env-detect.mjs +249 -0
- package/bin/forge-utils.mjs +364 -4
- package/bin/forgedock.mjs +1064 -135
- package/bin/hooks/pre-tool-use.mjs +182 -0
- package/bin/hooks/session-start.mjs +68 -3
- package/bin/init-detect.mjs +101 -12
- package/bin/journey.mjs +917 -16
- package/bin/labels.json +10 -0
- package/bin/recall.mjs +557 -0
- package/bin/registry.mjs +91 -3
- package/bin/runner.mjs +38 -2
- package/bin/tui.mjs +49 -3
- package/commands/adopt.md +1 -1
- package/commands/analytics.md +8 -8
- package/commands/audit.md +1 -1
- package/commands/autopilot.md +958 -77
- package/commands/ci-audit.md +1 -1
- package/commands/cleanup.md +139 -55
- package/commands/compat-audit.md +1 -1
- package/commands/deploy-info.md +1 -1
- package/commands/deploy-pr.md +1 -1
- package/commands/diagnose.md +1 -1
- package/commands/explain.md +1 -1
- package/commands/fix-ci.md +1 -1
- package/commands/forgedock-init.md +1 -1
- package/commands/incident-response.md +3 -3
- package/commands/issue.md +1 -1
- package/commands/optimize.md +586 -1
- package/commands/orchestrate/config.md +13 -3
- package/commands/orchestrate/phase-1-resolve.md +36 -26
- package/commands/orchestrate/phase-2-triage.md +1 -1
- package/commands/orchestrate/phase-2.5-synthesis.md +1 -1
- package/commands/orchestrate/phase-3-dependency.md +587 -48
- package/commands/orchestrate/phase-4-execution.md +1031 -57
- package/commands/orchestrate/phase-5-cleanup.md +1 -1
- package/commands/orchestrate/phase-6-report.md +248 -11
- package/commands/orchestrate/safety.md +2 -2
- package/commands/pipeline-health/phase-2-metrics.md +305 -1
- package/commands/pipeline-health/phase-4-proposals.md +127 -0
- package/commands/qa-sweep.md +1 -1
- package/commands/quality-gate.md +418 -1
- package/commands/recover-orphans.md +5 -5
- package/commands/replay.md +1 -1
- package/commands/review-pr-agents/api.md +2 -2
- package/commands/review-pr-agents/auth.md +2 -2
- package/commands/review-pr-agents/billing.md +2 -2
- package/commands/review-pr-agents/concurrency.md +2 -2
- package/commands/review-pr-agents/database.md +2 -2
- package/commands/review-pr-agents/frontend.md +2 -2
- package/commands/review-pr-agents/infra.md +2 -2
- package/commands/review-pr-agents/protocols.md +1 -1
- package/commands/review-pr-agents/scraper.md +2 -2
- package/commands/review-pr-agents/security.md +2 -2
- package/commands/review-pr-staging.md +41 -3
- package/commands/review-pr.md +462 -19
- package/commands/rollback.md +1 -1
- package/commands/scope.md +1 -1
- package/commands/security-audit.md +1 -1
- package/commands/spec-doctor.md +429 -0
- package/commands/test-gate.md +1 -1
- package/commands/validate.md +53 -1
- package/commands/work-on/build/architect.md +78 -1
- package/commands/work-on/build/context.md +360 -22
- package/commands/work-on/build/implement.md +3 -1
- package/commands/work-on/build/validate.md +29 -1
- package/commands/work-on/build.md +75 -6
- package/commands/work-on/close.md +624 -10
- package/commands/work-on/decompose.md +1 -1
- package/commands/work-on/investigate.md +235 -5
- package/commands/work-on/remediate.md +331 -0
- package/commands/work-on/review.md +1 -1
- package/commands/work-on-monolithic.md +1 -1
- package/commands/work-on.md +205 -66
- package/docs/CI.md +2 -2
- package/docs/CODEX.md +1 -1
- package/docs/CONFIG.md +186 -0
- package/docs/FORGE-PROTOCOL.md +101 -0
- package/docs/site/command-reference.md +31 -1
- package/docs/site/getting-started.md +9 -34
- package/docs/site/index.md +1 -1
- package/docs/spec/forge-protocol-v1.md +97 -5
- package/docs/spec/label-state-machine.md +6 -1
- package/package.json +3 -2
- package/packages/protocol/src/cli.js +374 -84
- package/packages/protocol/src/types.js +75 -1
- package/scripts/build-knowledge-index.mjs +1761 -0
- package/scripts/calibration.mjs +996 -0
- package/scripts/check-command-docs-drift.sh +4 -2
- package/scripts/danger-zones.mjs +789 -0
- package/scripts/doctor-pipeline-state.sh +88 -2
- package/scripts/select-fix-targets.sh +234 -0
- package/scripts/transition-label.sh +245 -6
- package/scripts/refresh-bot-token.sh +0 -97
package/docs/CONFIG.md
CHANGED
|
@@ -42,6 +42,7 @@ The default (no flags) is the annotated review screen: detection runs, AI enrich
|
|
|
42
42
|
| [`project`](#project-required) | **Yes** | GitHub identity (owner, repo, name) |
|
|
43
43
|
| [`paths`](#paths-required) | **Yes** | Local filesystem locations |
|
|
44
44
|
| [`branches`](#branches-required) | **Yes** | Branch naming conventions |
|
|
45
|
+
| [`agents`](#agents-optional) | No | Default model for pipeline agents |
|
|
45
46
|
| [`repos`](#repos-optional) | No | Multi-repository routing |
|
|
46
47
|
| [`project_board`](#project_board-optional) | No | GitHub Projects v2 integration |
|
|
47
48
|
| [`services`](#services-optional) | No | External service URLs and IDs |
|
|
@@ -125,6 +126,40 @@ branches:
|
|
|
125
126
|
|
|
126
127
|
---
|
|
127
128
|
|
|
129
|
+
## `agents` (OPTIONAL)
|
|
130
|
+
|
|
131
|
+
Model configuration for pipeline agents. `default_model` governs the main agent — the one you invoke directly (`work-on`, `orchestrate`, `review-pr`, etc.), referenced by every command spec's "Agent model policy" line. `subagent_model` governs the **child** sub-agents that a top-level command spawns internally — e.g. `/orchestrate`'s per-issue `/work-on` agents, `/review-pr`'s domain persona reviewers, `/analytics`'s parallel data-collection agents, `/incident-response`'s validation/root-cause agents.
|
|
132
|
+
|
|
133
|
+
```yaml
|
|
134
|
+
agents:
|
|
135
|
+
default_model: "sonnet"
|
|
136
|
+
subagent_model: "sonnet"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
| Field | Type | Required | Default | Description |
|
|
140
|
+
|-------|------|----------|---------|-------------|
|
|
141
|
+
| `default_model` | string | No | `"sonnet"` | Short alias — `"sonnet"`, `"opus"`, or `"haiku"` — the same values the Agent/Task tool's `model` parameter accepts. This is the only form that works for interactive command-spec sub-agent spawning. |
|
|
142
|
+
| `subagent_model` | string | No | `default_model`, else `"sonnet"` | Short alias, same accepted values as `default_model`. Overrides the model used for child agents spawned internally by a top-level command (see above). Omit to inherit `default_model`. |
|
|
143
|
+
|
|
144
|
+
**Resolution order** (highest precedence first):
|
|
145
|
+
1. `--model <id>` — CLI flag, `npx forgedock run` only (headless; main agent only).
|
|
146
|
+
2. `FORGEDOCK_MODEL` env var — headless runner only (main agent only).
|
|
147
|
+
3. `agents.default_model` — this field. Governs the main agent.
|
|
148
|
+
4. Hardcoded default — `"sonnet"` for interactive agents, `"claude-sonnet-5"` for the headless runner (`bin/runner.mjs`'s `DEFAULT_MODEL`).
|
|
149
|
+
|
|
150
|
+
**Sub-agent resolution order** (highest precedence first):
|
|
151
|
+
1. `agents.subagent_model` — this field. Governs child agents spawned by a top-level command.
|
|
152
|
+
2. `agents.default_model` — falls back here when `subagent_model` is unset.
|
|
153
|
+
3. Hardcoded default — `"sonnet"`.
|
|
154
|
+
|
|
155
|
+
**Headless runner note**: `bin/runner.mjs` (`npx forgedock run`, used for CI/headless invocations) calls the Anthropic SDK directly and also accepts a full Anthropic model ID here as a pass-through escape hatch (e.g. `"claude-opus-4-6"`). A full model ID does **not** work for interactive Agent/Task tool calls in command specs — those only accept the short-alias enum (`sonnet`/`opus`/`haiku`/`fable`). Prefer the short alias unless you specifically need a headless-only override. `subagent_model` is interactive-only — it has no headless-runner equivalent, since the headless runner does not spawn child sub-agents.
|
|
156
|
+
|
|
157
|
+
Projects without this section see no behavior change — everything defaults exactly as it did before these fields existed.
|
|
158
|
+
|
|
159
|
+
**Commands that use this section**: all commands with an "Agent model policy" line (`default_model`, nearly every command spec) and all commands that spawn internal sub-agents — `orchestrate`, `review-pr`, `analytics`, `incident-response` (`subagent_model`).
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
128
163
|
## `repos` (OPTIONAL)
|
|
129
164
|
|
|
130
165
|
Multi-repository routing. Use this when your project spans multiple GitHub repositories and you want to route issues to satellite repos by prefix.
|
|
@@ -571,6 +606,26 @@ Colors are grouped by semantic meaning:
|
|
|
571
606
|
|
|
572
607
|
---
|
|
573
608
|
|
|
609
|
+
## GitHub App Install
|
|
610
|
+
|
|
611
|
+
During `npx forgedock`, the installer prompts you to install the ForgeDock GitHub App (`rapiercraft-forgedock`) on your account or org.
|
|
612
|
+
|
|
613
|
+
**What installing it does today**: registers the app against the account/org you choose. That's it.
|
|
614
|
+
|
|
615
|
+
**What it does NOT do (yet)**:
|
|
616
|
+
- It does **not** create a bot token. GitHub App *installation* tokens can only be minted with the app's private key, and that key is held solely by RapierCraft Studios (the app's owner) — your installation grants *your* installation ID against *RapierCraft's* app, not a key you can use yourself.
|
|
617
|
+
- It does **not** auto-refresh anything, and there is no background process managing token expiry.
|
|
618
|
+
- It does **not** change which `gh` auth context pipeline commands (`/work-on`, `/orchestrate`, etc.) use. Every pipeline `gh` call always uses whatever auth is currently active in your shell — your personal token unless you've manually configured something else.
|
|
619
|
+
- It does **not** wire up webhook-driven "automatic pipeline triggers" — no webhook receiver exists yet.
|
|
620
|
+
|
|
621
|
+
**Why this matters**: GitHub App installation tokens get materially higher API rate limits than a personal access token, and actions taken with them are attributed to the bot (`rapiercraft-forgedock[bot]`) rather than your personal account. Those benefits are real, but delivering them to arbitrary installers requires a hosted token-minting backend service that doesn't exist yet (tracked as forge#1890). Installing the app today is safe and free, but on its own changes nothing about how the pipeline authenticates.
|
|
622
|
+
|
|
623
|
+
`npx forgedock doctor` reports this status explicitly (Check 12: "GitHub App / bot token") so you aren't left guessing whether a bot token is active.
|
|
624
|
+
|
|
625
|
+
**If you want bot-token behavior today**: you'd need to register your own GitHub App (with your own private key), and drive your own token-refresh loop (mint an installation token via the app's `/app/installations/{id}/access_tokens` API, then `gh auth login --with-token`, repeating before the ~1-hour expiry). This is an advanced, self-hosted setup — ForgeDock does not package a generic version of this for you.
|
|
626
|
+
|
|
627
|
+
---
|
|
628
|
+
|
|
574
629
|
## `marketing` (OPTIONAL)
|
|
575
630
|
|
|
576
631
|
Controls opt-in growth features such as 'Powered by ForgeDock' footers on PR descriptions created by the pipeline.
|
|
@@ -730,6 +785,53 @@ See [Per-Directory State Registry](#per-directory-state-registry) below for how
|
|
|
730
785
|
|
|
731
786
|
---
|
|
732
787
|
|
|
788
|
+
## Persisted Toolset Home (`~/.forge/`)
|
|
789
|
+
|
|
790
|
+
`npx`/`npm` never installs `forgedock` to a stable location on your machine — it resolves to wherever `npx`'s cache (or a global npm install, or a git clone) happens to physically live. Historically, `~/.claude/commands/` and the SessionStart hook's script path were symlinked **directly** from that ephemeral location. When npm/npx (or the OS) later evicted its cache, those symlinks silently dangled — Claude Code sessions stopped getting ForgeDock context with no error shown.
|
|
791
|
+
|
|
792
|
+
As of this feature, every `npx forgedock` (or `npx forgedock update`) run copies ForgeDock's own installable payload into a stable, version-independent home:
|
|
793
|
+
|
|
794
|
+
```
|
|
795
|
+
~/.forge/
|
|
796
|
+
bin/ — the same bin/ tree bundled with the resolved package (hooks, CLI entry points)
|
|
797
|
+
commands/ — the slash-command specs (.md)
|
|
798
|
+
scripts/ — the universal pipeline-agent scripts (classify-lane.sh, etc.)
|
|
799
|
+
templates/ — scaffold templates (e.g. the demo repo)
|
|
800
|
+
version — plain-text file containing the source package's version (e.g. "1.7.2")
|
|
801
|
+
```
|
|
802
|
+
|
|
803
|
+
`~/.claude/commands/` symlinks and the SessionStart hook's baked-in script path are then built from **this** copy, not the original ephemeral source — so they keep working even after the npm/npx cache that originally served them is cleared.
|
|
804
|
+
|
|
805
|
+
### When It Runs
|
|
806
|
+
|
|
807
|
+
| Command | Behavior |
|
|
808
|
+
|---------|----------|
|
|
809
|
+
| `npx forgedock` / `npx forgedock install` | Copies the resolved package's payload into `~/.forge/` (content-compared — unchanged files are never rewritten) before linking commands, then links from `~/.forge/`, not the original source |
|
|
810
|
+
| `npx forgedock init` | Does not touch `~/.forge/` — `init` only writes `forge.yaml`, it never installs commands |
|
|
811
|
+
| `npx forgedock update` (npm/npx install) | Refreshes `~/.forge/` from whatever the currently-resolved package looks like, then relinks |
|
|
812
|
+
| `npx forgedock update` (git-clone install) | **Does not** touch `~/.forge/` at all — see the exemption below |
|
|
813
|
+
| `npx forgedock doctor` | Reports `~/.forge/version` and confirms `~/.forge/{bin,commands,scripts,templates}` exist |
|
|
814
|
+
|
|
815
|
+
The copy is idempotent: files whose content is already byte-identical are never rewritten, so steady-state re-runs are fast and don't generate false "updated" noise.
|
|
816
|
+
|
|
817
|
+
### The Git-Clone Exemption
|
|
818
|
+
|
|
819
|
+
If you run ForgeDock from a git clone (or a git worktree) of the repo itself — the development/self-hosted install mode — nothing is copied into `~/.forge/`. A git clone is already a stable, user-owned location; copying it into `~/.forge/` and linking commands from the copy instead of the clone would silently disconnect `git pull` (or `npx forgedock update`'s git branch) from what's actually linked into `~/.claude/commands/`. So:
|
|
820
|
+
|
|
821
|
+
- `~/.claude/commands/` continues to symlink directly from the clone, exactly as before this feature.
|
|
822
|
+
- `~/.forge/{bin,commands,scripts,templates}` correctly does **not** exist for this install mode — `npx forgedock doctor` treats that absence as healthy, not a warning.
|
|
823
|
+
|
|
824
|
+
### Not the Same as `~/.forge/{runs,index}`
|
|
825
|
+
|
|
826
|
+
`~/.forge/` also hosts two **unrelated, pre-existing** directories used by other parts of ForgeDock:
|
|
827
|
+
|
|
828
|
+
- `~/.forge/runs/` — durable engine run state for `npx forgedock run-issue` / `resume-stalled` (see `bin/engine.mjs`).
|
|
829
|
+
- `~/.forge/index/` — the `recall` knowledge index (see `bin/recall.mjs`, `docs/FORGE-PROTOCOL.md`).
|
|
830
|
+
|
|
831
|
+
These are **engine data**, not the toolset itself, and this feature does not read, write, or otherwise change them. `~/.forge/{bin,commands,scripts,templates,version}` (this section) and `~/.forge/{runs,index}` (engine data) are unrelated siblings that merely happen to live under the same `~/.forge/` root — don't conflate the two when reading `~/.forge/`'s contents.
|
|
832
|
+
|
|
833
|
+
---
|
|
834
|
+
|
|
733
835
|
## Per-Directory State Registry
|
|
734
836
|
|
|
735
837
|
ForgeDock tracks per-directory opt-out state in a central registry file on the local machine.
|
|
@@ -810,6 +912,90 @@ npx forgedock status [dir] # Show a directory's resolved state (default: cwd)
|
|
|
810
912
|
|
|
811
913
|
---
|
|
812
914
|
|
|
915
|
+
## Install Receipt
|
|
916
|
+
|
|
917
|
+
ForgeDock writes a machine-readable receipt of what the last install or update actually did, so debugging drift (wrong commands installed, wrong tier, stale hooks) can start from a recorded fact instead of re-deriving state from scratch.
|
|
918
|
+
|
|
919
|
+
### Receipt File Location
|
|
920
|
+
|
|
921
|
+
```
|
|
922
|
+
~/.forge/install-receipt.json
|
|
923
|
+
```
|
|
924
|
+
|
|
925
|
+
The directory (`~/.forge/`) is created automatically on first write with `mkdir(..., { recursive: true })`. The file is never committed to version control — it is per-user, per-machine state.
|
|
926
|
+
|
|
927
|
+
### When It's Written
|
|
928
|
+
|
|
929
|
+
- After every successful `npx forgedock install` (end of the onboarding journey, right after the "Forged." celebration screen).
|
|
930
|
+
- After every `npx forgedock update` — both the git-clone branch (fast-forward pull) and the npm branch (version-check advisory) route through the same repair step (`relinkAndHint()`), so the receipt is refreshed either way.
|
|
931
|
+
|
|
932
|
+
The write is best-effort and never blocks or fails the install/update it records: any error (permission denied, disk full, unusual `FORGE_HOME` layout) degrades silently to a no-op, matching the fail-open contract already used by the command-manifest and hook-registration steps.
|
|
933
|
+
|
|
934
|
+
### Receipt Schema
|
|
935
|
+
|
|
936
|
+
```json
|
|
937
|
+
{
|
|
938
|
+
"schemaVersion": 1,
|
|
939
|
+
"timestamp": "2026-07-10T12:00:00.000Z",
|
|
940
|
+
"forgedockVersion": "1.1.6",
|
|
941
|
+
"installMode": "npm",
|
|
942
|
+
"forgeHome": "/home/user/.npm/_npx/abc123/node_modules/forgedock",
|
|
943
|
+
"cwd": "/home/user/projects/my-repo",
|
|
944
|
+
"platform": {
|
|
945
|
+
"platform": "linux",
|
|
946
|
+
"platformLabel": "Linux",
|
|
947
|
+
"isWSL": false,
|
|
948
|
+
"wslDistro": null,
|
|
949
|
+
"shell": "bash"
|
|
950
|
+
},
|
|
951
|
+
"tier": "core",
|
|
952
|
+
"commands": {
|
|
953
|
+
"count": 42,
|
|
954
|
+
"list": ["work-on", "review-pr", "quality-gate", "orchestrate/phase-1-resolve"]
|
|
955
|
+
},
|
|
956
|
+
"hooks": {
|
|
957
|
+
"sessionStart": "registered",
|
|
958
|
+
"preToolUse": "registered",
|
|
959
|
+
"subagentStopEnforce": null
|
|
960
|
+
},
|
|
961
|
+
"forgeYaml": {
|
|
962
|
+
"present": true,
|
|
963
|
+
"validShape": true
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
```
|
|
967
|
+
|
|
968
|
+
| Field | Type | Description |
|
|
969
|
+
|-------|------|--------------|
|
|
970
|
+
| `schemaVersion` | number | Schema version — currently `1` |
|
|
971
|
+
| `timestamp` | string | ISO-8601 timestamp of this install/update |
|
|
972
|
+
| `forgedockVersion` | string | `version` field from `{forgeHome}/package.json` (empty string if unreadable) |
|
|
973
|
+
| `installMode` | `"npm"` \| `"git-clone"` | Detected from whether `{forgeHome}/.git` exists — same predicate `update()` already uses to choose its update strategy |
|
|
974
|
+
| `forgeHome` | string | Absolute path to the ForgeDock package install (`FORGE_HOME`) |
|
|
975
|
+
| `cwd` | string | Absolute path to the project directory the command was run in |
|
|
976
|
+
| `platform` | object | `detectEnvironment()`'s output — platform, human label, WSL status/distro, detected shell |
|
|
977
|
+
| `tier` | `"core"` \| `"extras"` | Whether `--extras` was passed (opt-in command tier, see `install: extras` frontmatter) |
|
|
978
|
+
| `commands` | object | `count` and `list` (relative slash-command names) of everything installed for the resolved tier, sourced from `findMarkdownFiles()` — never a separately maintained list |
|
|
979
|
+
| `hooks.sessionStart` | string \| null | SessionStart hook registration status (`"registered"`, `"already"`, `"skipped-malformed"`) |
|
|
980
|
+
| `hooks.preToolUse` | string \| null | PreToolUse enforcement hook status, or `null` when the installed Claude Code version doesn't support it |
|
|
981
|
+
| `hooks.subagentStopEnforce` | string \| null | Cleanup status of the (retired) SubagentStop enforce hook |
|
|
982
|
+
| `forgeYaml.present` | boolean | Whether `forge.yaml` exists in `cwd` at receipt-write time |
|
|
983
|
+
| `forgeYaml.validShape` | boolean | Whether `forge.yaml` contains the 3 required top-level sections (`project:`, `paths:`, `branches:`) — a lightweight regex check, not a full YAML parse |
|
|
984
|
+
|
|
985
|
+
### No PII or Secrets
|
|
986
|
+
|
|
987
|
+
The receipt never contains `process.env` values, GitHub tokens, API keys, or the contents of `forge.yaml` — only the `present`/`validShape` booleans above. Absolute filesystem paths (`forgeHome`, `cwd`) are included for drift debugging; they typically contain the OS username but nothing more sensitive, consistent with other per-machine ForgeDock state (e.g. `registry.json`'s path-keyed entries, see above).
|
|
988
|
+
|
|
989
|
+
### Reading the Receipt
|
|
990
|
+
|
|
991
|
+
```bash
|
|
992
|
+
cat ~/.forge/install-receipt.json
|
|
993
|
+
```
|
|
994
|
+
|
|
995
|
+
There is no CLI subcommand to read it yet — `doctor()` reading the receipt to detect drift is a deliberately deferred stretch goal, not part of this feature.
|
|
996
|
+
|
|
997
|
+
---
|
|
998
|
+
|
|
813
999
|
## Complete Example
|
|
814
1000
|
|
|
815
1001
|
See [`forge.yaml.example`](../forge.yaml.example) at the repository root for a fully annotated example covering all sections.
|
package/docs/FORGE-PROTOCOL.md
CHANGED
|
@@ -13,3 +13,104 @@
|
|
|
13
13
|
> and usable in any product with attribution. This older draft was mistakenly
|
|
14
14
|
> marked AGPL-3.0; the protocol description itself has always been intended for
|
|
15
15
|
> open, license-compatible adoption.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Forge Ledger — Derived Artifact of the Protocol
|
|
20
|
+
|
|
21
|
+
The **Forge Ledger** is the persistent, file/symbol-keyed knowledge index built from FORGE
|
|
22
|
+
annotations. It is a _derived artifact_ of the protocol: the ledger is rebuilt by re-parsing
|
|
23
|
+
the annotation corpus on GitHub (source of truth), not by maintaining separate authoritative
|
|
24
|
+
state.
|
|
25
|
+
|
|
26
|
+
### Architecture
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
GitHub Issues/PRs (annotation corpus, source of truth)
|
|
30
|
+
│
|
|
31
|
+
▼
|
|
32
|
+
scripts/build-knowledge-index.mjs ← incremental indexer (watermarked by issue.updated_at)
|
|
33
|
+
│ uses packages/protocol/src/parse.js (FORGE annotation parser)
|
|
34
|
+
▼
|
|
35
|
+
~/.forge/index/
|
|
36
|
+
knowledge.jsonl ← card records (one JSON per line, keyed by issue/kind/seq)
|
|
37
|
+
postings.json ← BM25-lite inverted index (term → card IDs with per-field tf)
|
|
38
|
+
manifest.json ← issue → content-hash map + watermark + card count
|
|
39
|
+
renames.jsonl ← git rename log (old path → new path for query-time resolution)
|
|
40
|
+
│
|
|
41
|
+
▼ (mirrored to orphan branch)
|
|
42
|
+
forge-knowledge branch ← versioned, diffable, hydratable by any clone or CI
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Card Schema
|
|
46
|
+
|
|
47
|
+
Cards are keyed by provenance (`{issue}/{kind}/{seq}`), never by file path. Paths are
|
|
48
|
+
attributes maintained by the indexer; renames are metadata updates, not re-keys.
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"schemaVersion": 1,
|
|
53
|
+
"id": "1370/pattern/0",
|
|
54
|
+
"kind": "pattern",
|
|
55
|
+
"issue": 1370,
|
|
56
|
+
"pattern": "...",
|
|
57
|
+
"rootCause": "...",
|
|
58
|
+
"prevention": "...",
|
|
59
|
+
"paths": ["bin/runner.mjs"],
|
|
60
|
+
"symbols": ["scrubEnv"],
|
|
61
|
+
"anchor": { "path": "bin/runner.mjs", "symbol": "scrubEnv" },
|
|
62
|
+
"status": "fresh",
|
|
63
|
+
"createdAt": "2026-07-04"
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### CLI
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
# Query by file path (exact lookup):
|
|
71
|
+
forge recall --file bin/runner.mjs --json
|
|
72
|
+
|
|
73
|
+
# Query by symbol:
|
|
74
|
+
forge recall --symbol scrubEnv --json
|
|
75
|
+
|
|
76
|
+
# Free-text BM25 search:
|
|
77
|
+
forge recall "env scrub proc environ" --k 5
|
|
78
|
+
|
|
79
|
+
# Index health:
|
|
80
|
+
forge recall --doctor
|
|
81
|
+
|
|
82
|
+
# Rebuild index from scratch:
|
|
83
|
+
node scripts/build-knowledge-index.mjs --full-rebuild
|
|
84
|
+
|
|
85
|
+
# Incremental update (used by close phase):
|
|
86
|
+
node scripts/build-knowledge-index.mjs --issue {NUMBER}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Invariants
|
|
90
|
+
|
|
91
|
+
- **Full rebuild = incremental parity**: running a full rebuild produces byte-identical
|
|
92
|
+
card content to a sequence of incremental runs over the same issue range.
|
|
93
|
+
- **Idempotency**: re-indexing the same issue twice produces the same card content (card IDs
|
|
94
|
+
are deterministic; content is a pure function of current annotation state).
|
|
95
|
+
- **GitHub wins**: the index is always rebuildable from the annotation corpus alone. Deleting
|
|
96
|
+
`~/.forge/index/` loses nothing — a rebuild restores the same state.
|
|
97
|
+
- **Non-blocking**: ledger indexing at close time never stalls the pipeline. Failure is logged
|
|
98
|
+
and the close phase continues.
|
|
99
|
+
|
|
100
|
+
### Staleness Detection (tiered, cheapest first)
|
|
101
|
+
|
|
102
|
+
1. Current blob sha of `anchor.path` matches stored blob sha → **FRESH**
|
|
103
|
+
2. `anchor.symbol` is still defined in the current file → **FRESH**
|
|
104
|
+
3. Rolling-hash scan finds `snippetHash` elsewhere in file → **MOVED** (re-anchor)
|
|
105
|
+
4. `snippetHash` found in a file touched by rename log → **MOVED** (re-anchor path)
|
|
106
|
+
5. Otherwise → **STALE** (excluded from binding injection; recallable with `--include-stale`)
|
|
107
|
+
|
|
108
|
+
### Integration Points
|
|
109
|
+
|
|
110
|
+
- **`commands/work-on/build/context.md` Phase C1**: uses `forge recall --file` for exact
|
|
111
|
+
file-path lookup; falls back to live `gh issue list --search` when index is absent.
|
|
112
|
+
- **`commands/work-on/close.md` Phase C5.3**: calls `build-knowledge-index.mjs --issue`
|
|
113
|
+
after merge to index the just-closed issue; advances watermark.
|
|
114
|
+
|
|
115
|
+
See issue [#1732](https://github.com/RapierCraftStudios/ForgeDock/issues/1732) for the
|
|
116
|
+
implementation history and design decisions.
|
|
@@ -592,7 +592,37 @@ These are invoked automatically by `/work-on` but can also be run standalone.
|
|
|
592
592
|
| `/work-on/review` | Phase 5 | Review only |
|
|
593
593
|
| `/work-on/close` | Phase 6 | Close & cleanup only |
|
|
594
594
|
| `/work-on/decompose` | Phase 2 | Decompose into sub-issues |
|
|
595
|
-
| `/
|
|
595
|
+
| `/work-on/remediate` | Phase 0A.1 | Remediate a `needs-human` PR: fix findings, re-review, re-gate (`/work-on <pr> --remediate`) |
|
|
596
|
+
| `/review-pr-agents` | PR review | Agent catalog router read by `/review-pr` during dispatch (not user-invokable directly) |
|
|
597
|
+
|
|
598
|
+
`/review-pr` (core) reads the following per-persona and shared-protocol templates from `commands/review-pr-agents/` at runtime during Phase 3C dispatch. They ship as part of every install alongside `/review-pr` — not user-invokable directly.
|
|
599
|
+
|
|
600
|
+
| Command | Phase | Purpose |
|
|
601
|
+
|---------|-------|---------|
|
|
602
|
+
| `/review-pr-agents/protocols` | Phase 3C | Shared Evidence-Based/Structured-Findings/Input-Scoping protocols read before every persona template |
|
|
603
|
+
| `/review-pr-agents/security` | Phase 3C | General security & quality scan (always runs) |
|
|
604
|
+
| `/review-pr-agents/auth` | Phase 3C | Auth conventions auditor (AUTH domain) |
|
|
605
|
+
| `/review-pr-agents/billing` | Phase 3C | Billing/payments auditor (BILLING domain) |
|
|
606
|
+
| `/review-pr-agents/concurrency` | Phase 3C | Concurrency/locking auditor (CONCURRENCY domain) |
|
|
607
|
+
| `/review-pr-agents/database` | Phase 3C | Database/migration auditor (DATABASE domain) |
|
|
608
|
+
| `/review-pr-agents/frontend` | Phase 3C | Frontend conventions auditor (FRONTEND domain) |
|
|
609
|
+
| `/review-pr-agents/infra` | Phase 3C | Infra/deploy auditor (INFRA domain) |
|
|
610
|
+
| `/review-pr-agents/api` | Phase 3C | API/SDK contract auditor (API domain) |
|
|
611
|
+
| `/review-pr-agents/scraper` | Phase 3C | Scraping/anti-bot auditor (SCRAPING domain) |
|
|
612
|
+
|
|
613
|
+
`/orchestrate` (core) reads the following phase files from `commands/orchestrate/` at runtime. They ship as part of every install alongside `/orchestrate` — not user-invokable directly.
|
|
614
|
+
|
|
615
|
+
| Command | Phase | Purpose |
|
|
616
|
+
|---------|-------|---------|
|
|
617
|
+
| `/orchestrate/config` | Phase 0 | Hard rules, config resolution, multi-repo support — read first |
|
|
618
|
+
| `/orchestrate/phase-1-resolve` | Phase 1 | Resolve the issue set from input |
|
|
619
|
+
| `/orchestrate/phase-2-triage` | Phase 2 | Investigation-first triage, Wave 0 |
|
|
620
|
+
| `/orchestrate/phase-2.5-synthesis` | Phase 2.5 | Investigation synthesis and deconfliction |
|
|
621
|
+
| `/orchestrate/phase-3-dependency` | Phase 3 | Dependency analysis, DAG construction, execution plan |
|
|
622
|
+
| `/orchestrate/phase-4-execution` | Phase 4 | Streaming DAG execution, agent dispatch, stall detection |
|
|
623
|
+
| `/orchestrate/phase-5-cleanup` | Phase 5 | Post-batch cleanup sweep and agent audit |
|
|
624
|
+
| `/orchestrate/phase-6-report` | Phase 6 | Consolidated report and pipeline summary |
|
|
625
|
+
| `/orchestrate/safety` | Reference | Safety rules and examples |
|
|
596
626
|
|
|
597
627
|
---
|
|
598
628
|
|
|
@@ -49,9 +49,9 @@ Run the installer with `npx` from your project directory:
|
|
|
49
49
|
npx forgedock
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
This installs all 25+ ForgeDock command specs into
|
|
52
|
+
This installs all 25+ ForgeDock command specs into `~/.claude/commands/` — making them available as slash commands in every Claude Code session on this machine, not just this repo.
|
|
53
53
|
|
|
54
|
-
>
|
|
54
|
+
> Install is always global. `--global` is still accepted on the command line for backward compatibility, but it's a no-op — `npx forgedock` and `npx forgedock --global` do exactly the same thing.
|
|
55
55
|
|
|
56
56
|
**Verify the install:**
|
|
57
57
|
|
|
@@ -75,7 +75,7 @@ ForgeDock Doctor — Installation Health Check
|
|
|
75
75
|
|
|
76
76
|
It exits `0` when everything passes and `1` if any check fails, so you can also use it in CI.
|
|
77
77
|
|
|
78
|
-
> Prefer a quick spot-check? `ls
|
|
78
|
+
> Prefer a quick spot-check? `ls ~/.claude/commands/ | grep -E "work-on|review-pr|quality-gate"` should list `work-on.md`, `review-pr.md`, and `quality-gate.md`.
|
|
79
79
|
|
|
80
80
|
---
|
|
81
81
|
|
|
@@ -205,7 +205,7 @@ The quick fixes below cover the most common first-run issues. For the full list
|
|
|
205
205
|
|
|
206
206
|
**`/work-on` not found in Claude Code**
|
|
207
207
|
|
|
208
|
-
The symlink wasn't created. Re-run `npx forgedock` and check `ls
|
|
208
|
+
The symlink wasn't created. Re-run `npx forgedock` and check `ls ~/.claude/commands/`.
|
|
209
209
|
|
|
210
210
|
**`forge.yaml` not found**
|
|
211
211
|
|
|
@@ -221,37 +221,12 @@ The issue may have been marked `workflow:invalid`. Check the issue comments for
|
|
|
221
221
|
|
|
222
222
|
---
|
|
223
223
|
|
|
224
|
-
##
|
|
224
|
+
## A note on install location
|
|
225
225
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
**Option A: Keep the global install (no action required)**
|
|
229
|
-
|
|
230
|
-
Add `--global` to all future `npx forgedock install/update/uninstall/doctor` calls. Your existing setup is unchanged.
|
|
231
|
-
|
|
232
|
-
```bash
|
|
233
|
-
npx forgedock update --global # re-link after a version bump
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
**Option B: Switch to project-scoped (recommended for per-repo version control)**
|
|
237
|
-
|
|
238
|
-
1. Remove the global install:
|
|
239
|
-
```bash
|
|
240
|
-
npx forgedock uninstall --global
|
|
241
|
-
```
|
|
242
|
-
2. In each repo you want ForgeDock in, run a fresh project-scoped install:
|
|
243
|
-
```bash
|
|
244
|
-
cd /path/to/your-repo
|
|
245
|
-
npx forgedock install
|
|
246
|
-
```
|
|
247
|
-
3. Verify:
|
|
248
|
-
```bash
|
|
249
|
-
npx forgedock doctor # auto-detects project-scoped install
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
**Detect your current mode:**
|
|
226
|
+
ForgeDock briefly shipped a project-scoped-by-default install mode. It was backed out after causing a "split-brain" bug (`doctor`/`status` assumed project-scoped while the installer still wrote globally — [#1589](https://github.com/RapierCraftStudios/ForgeDock/issues/1589)), so install has always been global (`~/.claude/commands/`) since. If you have scripts or CI that still pass `--global`, there's nothing to change — it's accepted for backward compatibility and does exactly what a plain `npx forgedock` does.
|
|
253
227
|
|
|
254
228
|
```bash
|
|
255
|
-
npx forgedock
|
|
256
|
-
npx forgedock
|
|
229
|
+
npx forgedock update # re-link after a version bump
|
|
230
|
+
npx forgedock doctor # confirm the install is healthy
|
|
231
|
+
npx forgedock status # shows the install path (~/.claude/commands/)
|
|
257
232
|
```
|
package/docs/site/index.md
CHANGED
|
@@ -56,7 +56,7 @@ No more coordinating between agent sessions. No more lost context. No more start
|
|
|
56
56
|
npx forgedock
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
Installs commands into
|
|
59
|
+
Installs commands into `~/.claude/commands/`, available in every Claude Code session on this machine. `--global` is still accepted as a flag for backward compatibility, but install is always global — there's nothing to opt into.
|
|
60
60
|
|
|
61
61
|
**Requirements**: Claude Code, Node.js 18+, `gh` CLI authenticated with GitHub.
|
|
62
62
|
|
|
@@ -449,6 +449,43 @@ artifact so a sub-issue builder can fetch upstream context directly.
|
|
|
449
449
|
<!-- FORGE:PRIOR_GIST: {https://example.com/artifact} -->
|
|
450
450
|
```
|
|
451
451
|
|
|
452
|
+
#### Security: Gist Visibility — Normative Requirement <!-- Added: forge#1729 -->
|
|
453
|
+
|
|
454
|
+
**All FORGE gist types (`FORGE:KNOWLEDGE_GIST`, `FORGE:MILESTONE_INDEX`, `FORGE:PRIOR_GIST`,
|
|
455
|
+
and the memory-index Gist referenced by `FORGE:MEMORY_INDEX` in `close.md`) MUST be created
|
|
456
|
+
secret. Publishing them as public Gists is a protocol violation.**
|
|
457
|
+
|
|
458
|
+
Rationale: these artifacts embed investigation findings — root causes, file paths, affected
|
|
459
|
+
service names, and security details. A public Gist exposes this content to a world-readable
|
|
460
|
+
URL with no access control. `gh gist create` is secret by default; the requirement is that
|
|
461
|
+
no pipeline spec or operator script must pass `--public` when creating any of these artifacts.
|
|
462
|
+
|
|
463
|
+
**Enforcement**: The `pre-tool-use.mjs` hook (Rule 3) hard-blocks `gh gist create --public`
|
|
464
|
+
in pipeline sessions. The `doctor-pipeline-state.sh` check I8 audits existing annotation-referenced
|
|
465
|
+
gists and reports a CRITICAL finding if any are public.
|
|
466
|
+
|
|
467
|
+
**Migration** (if a public gist is found): GitHub does not support changing a Gist's visibility
|
|
468
|
+
in place. To replace a public pipeline gist with a secret one:
|
|
469
|
+
|
|
470
|
+
```bash
|
|
471
|
+
# 1. Save current content
|
|
472
|
+
gh gist view {GIST_ID} > /tmp/gist_migrate.md
|
|
473
|
+
[ -s /tmp/gist_migrate.md ] || { echo "ABORT: empty save"; exit 1; }
|
|
474
|
+
|
|
475
|
+
# 2. Delete the public gist
|
|
476
|
+
gh gist delete {GIST_ID} --yes
|
|
477
|
+
|
|
478
|
+
# 3. Recreate secret (no --public) with same description
|
|
479
|
+
gh gist create /tmp/gist_migrate.md --desc "{ORIGINAL_DESCRIPTION}"
|
|
480
|
+
# gh gist create without --public creates a secret gist.
|
|
481
|
+
|
|
482
|
+
# 4. Update the FORGE annotation on the issue to point to the new URL
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
**Override**: set `FORGE_ALLOW_PUBLIC_GIST=1` in the operator's shell environment before
|
|
486
|
+
starting Claude Code only if a public gist is genuinely required (e.g., sharing a demo
|
|
487
|
+
artifact). This must not be used for pipeline memory gists.
|
|
488
|
+
|
|
452
489
|
### 4.3 Control and error markers
|
|
453
490
|
|
|
454
491
|
These markers carry no Markdown body; their presence is the signal.
|
|
@@ -1143,16 +1180,71 @@ separate, MIT-licensed npm package:
|
|
|
1143
1180
|
**`@forgedock/protocol`** — available at `packages/protocol/` in the ForgeDock
|
|
1144
1181
|
repository.
|
|
1145
1182
|
|
|
1146
|
-
|
|
1183
|
+
### 13.1 Normative codec path
|
|
1184
|
+
|
|
1185
|
+
**`packages/protocol/` is the normative write and read path for all FORGE
|
|
1186
|
+
annotations.** Hand-rolled annotation construction (embedding raw
|
|
1187
|
+
`<!-- FORGE:TYPE -->` strings in inline heredocs or `--body` blocks) is
|
|
1188
|
+
**non-conformant** because it bypasses the codec's escaping and round-trip
|
|
1189
|
+
guarantees. Every producer MUST route annotation construction through one of:
|
|
1190
|
+
|
|
1191
|
+
1. **`forge-annotation.sh write <TYPE> --field KEY=VALUE ...`** (AGPL-licensed,
|
|
1192
|
+
ships with the npm package at `scripts/forge-annotation.sh`), or
|
|
1193
|
+
2. **`node packages/protocol/src/cli.js emit <TYPE> --field KEY=VALUE ...`**
|
|
1194
|
+
(MIT-licensed, part of the `@forgedock/protocol` package)
|
|
1195
|
+
|
|
1196
|
+
Both paths delegate to `emit()` from `packages/protocol/src/emit.js`, which
|
|
1197
|
+
applies the complete escaping and sanitization policy (§3.5 injection hardening).
|
|
1198
|
+
|
|
1199
|
+
### 13.2 JavaScript API
|
|
1200
|
+
|
|
1201
|
+
```js
|
|
1202
|
+
import { parse, validate, emit, emitPartial } from '@forgedock/protocol';
|
|
1203
|
+
```
|
|
1147
1204
|
|
|
1148
1205
|
- `parse(commentBody)` — extracts all annotations from a comment body string
|
|
1149
1206
|
- `validate(annotation)` — checks conformance per §3–4; returns `{ valid, errors, warnings }`
|
|
1150
|
-
- `emit(type, fields)` — produces well-formed annotation
|
|
1207
|
+
- `emit(type, fields)` — produces a well-formed annotation string; applies all §3.5 escaping
|
|
1151
1208
|
- `emitPartial(type)` — produces the partial sentinel for a type (§3.3)
|
|
1152
1209
|
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1210
|
+
### 13.3 CLI subcommands
|
|
1211
|
+
|
|
1212
|
+
The CLI at `packages/protocol/src/cli.js` exposes three modes:
|
|
1213
|
+
|
|
1214
|
+
```bash
|
|
1215
|
+
# Emit — print a well-formed annotation body to stdout
|
|
1216
|
+
node packages/protocol/src/cli.js emit INVESTIGATOR \
|
|
1217
|
+
--field Verdict=CONFIRMED --field Confidence=HIGH \
|
|
1218
|
+
--field Severity=MEDIUM --field "Task Type=Bug Fix" \
|
|
1219
|
+
--field "Decomposition Assessment=NO — single fix."
|
|
1220
|
+
|
|
1221
|
+
# Parse — read a comment body from stdin, extract a field value
|
|
1222
|
+
echo '<!-- FORGE:INVESTIGATOR -->...' | \
|
|
1223
|
+
node packages/protocol/src/cli.js parse --type INVESTIGATOR --field Verdict
|
|
1224
|
+
# → CONFIRMED
|
|
1225
|
+
|
|
1226
|
+
# Conformance runner (legacy — no subcommand keyword)
|
|
1227
|
+
node packages/protocol/src/cli.js fixtures/
|
|
1228
|
+
```
|
|
1229
|
+
|
|
1230
|
+
The `emit` subcommand also supports the Base64url machine-surface form for
|
|
1231
|
+
`FORGE:CARD` annotations (design decision 2026-07-08: encoding beats escaping):
|
|
1232
|
+
|
|
1233
|
+
```bash
|
|
1234
|
+
node packages/protocol/src/cli.js emit CARD \
|
|
1235
|
+
--field issue=1370 --field status=merged --b64
|
|
1236
|
+
# → <!-- FORGE:CARD: v1 sha:7234c2d8 b64:eyJ... -->
|
|
1237
|
+
```
|
|
1238
|
+
|
|
1239
|
+
The Base64url alphabet `[A-Za-z0-9_-]` cannot contain `>`, `<`, or `!`, making
|
|
1240
|
+
`-->`, `--!>`, and `<!--` structurally unrepresentable in the machine surface.
|
|
1241
|
+
|
|
1242
|
+
### 13.4 Conformance suite
|
|
1243
|
+
|
|
1244
|
+
A conformance suite in `packages/protocol/fixtures/` covers all reserved types
|
|
1245
|
+
with valid and invalid examples, including adversarial payloads that reproduce
|
|
1246
|
+
historical escaping vulnerabilities. The suite can be run against any fixtures
|
|
1247
|
+
directory:
|
|
1156
1248
|
|
|
1157
1249
|
```bash
|
|
1158
1250
|
npx @forgedock/protocol fixtures/
|
|
@@ -14,11 +14,14 @@ See also: [FORGE Annotation Protocol §6](forge-protocol-v1.md#6-label-state-mac
|
|
|
14
14
|
| `workflow:ready-to-build` | Investigation complete, build not started | Investigator agent |
|
|
15
15
|
| `workflow:building` | Build phase active | Builder agent |
|
|
16
16
|
| `workflow:in-review` | PR created, review active | Orchestrator agent |
|
|
17
|
+
| `workflow:awaiting-merge` | Remediated + re-reviewed, awaiting a human merge decision | Review-pr Phase 8 (auto-merge guard) |
|
|
17
18
|
| `workflow:merged` | PR merged, issue closed | Close phase agent |
|
|
18
19
|
| `workflow:invalid` | Issue closed as invalid | Investigator agent |
|
|
19
20
|
| `workflow:decomposed` | Issue decomposed into sub-issues | Decomposer agent |
|
|
20
21
|
| `needs-human` | Pipeline blocked, human intervention required | Any agent on error |
|
|
21
22
|
|
|
23
|
+
`workflow:awaiting-merge` vs `needs-human`: both are terminal (the pipeline stops advancing the issue automatically), but they mean different things. `needs-human` means the pipeline hit a condition it cannot resolve on its own (genuinely blocked — conflicting PR, failed verdict, calibration/trust escalation, etc.) and a human must diagnose and act. `workflow:awaiting-merge` means the opposite: the PR was previously escalated to `needs-human`, has since been remediated and re-reviewed to a clean `APPROVED` verdict with no mergeability blockers, but does not yet meet the automated auto-land bar (see forge#1809 Q1) — a human only needs to click merge, not diagnose a problem. `scripts/transition-label.sh` only clears `needs-human` (best-effort) when the target state is `workflow:awaiting-merge` — every other forward transition leaves a pre-existing `needs-human` label untouched, preserving its sticky/terminal semantics.
|
|
24
|
+
|
|
22
25
|
## Transitions
|
|
23
26
|
|
|
24
27
|
```
|
|
@@ -27,6 +30,7 @@ See also: [FORGE Annotation Protocol §6](forge-protocol-v1.md#6-label-state-mac
|
|
|
27
30
|
→ workflow:ready-to-build [Phase 2: Investigation complete]
|
|
28
31
|
→ workflow:building [Phase 3: Build started]
|
|
29
32
|
→ workflow:in-review [Phase 4: PR created]
|
|
33
|
+
→ workflow:awaiting-merge [TERMINAL] [Phase 5/review-pr: re-reviewed after needs-human, awaiting human merge]
|
|
30
34
|
→ workflow:merged [TERMINAL] [Phase 5: PR merged]
|
|
31
35
|
→ workflow:invalid [TERMINAL] [Any phase: closed as invalid]
|
|
32
36
|
→ workflow:decomposed [TERMINAL] [Phase 2: split into sub-issues]
|
|
@@ -40,6 +44,7 @@ Processing stops when any of these labels is set:
|
|
|
40
44
|
- `workflow:merged`
|
|
41
45
|
- `workflow:invalid`
|
|
42
46
|
- `workflow:decomposed`
|
|
47
|
+
- `workflow:awaiting-merge`
|
|
43
48
|
- `needs-human`
|
|
44
49
|
|
|
45
50
|
## Label Exclusivity
|
|
@@ -49,7 +54,7 @@ At most one `workflow:*` label should be active on an issue at any time. When tr
|
|
|
49
54
|
```bash
|
|
50
55
|
gh issue edit {NUMBER} -R {REPO} \
|
|
51
56
|
--add-label "workflow:building" \
|
|
52
|
-
--remove-label "workflow:investigating,workflow:ready-to-build,workflow:in-review,workflow:merged,workflow:invalid,workflow:decomposed"
|
|
57
|
+
--remove-label "workflow:investigating,workflow:ready-to-build,workflow:in-review,workflow:awaiting-merge,workflow:merged,workflow:invalid,workflow:decomposed"
|
|
53
58
|
```
|
|
54
59
|
|
|
55
60
|
This is enforced by `scripts/transition-label.sh` — use `resolve_script 'transition-label'` rather than calling `gh issue edit` directly when possible.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "forgedock",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.9",
|
|
4
4
|
"description": "Autonomous dev pipeline for Claude Code. GitHub as institutional memory — every issue, PR, and annotation survives context resets and makes the next agent smarter.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"forgedock": "bin/forgedock.mjs"
|
|
@@ -40,12 +40,13 @@
|
|
|
40
40
|
"examples/",
|
|
41
41
|
"packages/protocol/src/",
|
|
42
42
|
"scripts/",
|
|
43
|
+
"!scripts/refresh-bot-token.sh",
|
|
43
44
|
"templates/",
|
|
44
45
|
"LICENSE",
|
|
45
46
|
"README.md"
|
|
46
47
|
],
|
|
47
48
|
"scripts": {
|
|
48
|
-
"test": "node --test \"bin/tests/**/*.test.mjs\"",
|
|
49
|
+
"test": "node --test \"bin/tests/**/*.test.mjs\" \"packages/protocol/test/**/*.test.mjs\"",
|
|
49
50
|
"docs:dev": "vitepress dev docs/site",
|
|
50
51
|
"docs:build": "vitepress build docs/site",
|
|
51
52
|
"docs:preview": "vitepress preview docs/site"
|