forgedock 1.1.6 → 1.1.8

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 (43) hide show
  1. package/README.md +3 -1
  2. package/bin/engine/invariants.mjs +361 -0
  3. package/bin/hooks/pre-tool-use.mjs +182 -0
  4. package/bin/journey.mjs +77 -7
  5. package/bin/labels.json +10 -0
  6. package/bin/recall.mjs +540 -0
  7. package/commands/autopilot.md +959 -78
  8. package/commands/cleanup.md +52 -3
  9. package/commands/optimize.md +585 -0
  10. package/commands/orchestrate/phase-1-resolve.md +35 -25
  11. package/commands/orchestrate/phase-3-dependency.md +465 -34
  12. package/commands/orchestrate/phase-4-execution.md +448 -29
  13. package/commands/orchestrate/phase-6-report.md +198 -9
  14. package/commands/pipeline-health/phase-2-metrics.md +305 -1
  15. package/commands/pipeline-health/phase-4-proposals.md +127 -0
  16. package/commands/quality-gate.md +417 -0
  17. package/commands/review-pr.md +391 -13
  18. package/commands/spec-doctor.md +429 -0
  19. package/commands/validate.md +52 -0
  20. package/commands/work-on/build/architect.md +77 -0
  21. package/commands/work-on/build/context.md +357 -22
  22. package/commands/work-on/build/implement.md +2 -0
  23. package/commands/work-on/build/validate.md +28 -0
  24. package/commands/work-on/build.md +44 -0
  25. package/commands/work-on/close.md +621 -8
  26. package/commands/work-on/investigate.md +221 -0
  27. package/commands/work-on.md +15 -14
  28. package/docs/FORGE-PROTOCOL.md +101 -0
  29. package/docs/design/awesome-list-submissions.md +105 -0
  30. package/docs/design/f5bot-monitoring-setup.md +43 -0
  31. package/docs/design/growth-strategy-2026.md +579 -0
  32. package/docs/spec/forge-protocol-v1.md +97 -5
  33. package/docs/spec/label-state-machine.md +6 -1
  34. package/package.json +2 -2
  35. package/packages/protocol/src/cli.js +374 -84
  36. package/packages/protocol/src/types.js +75 -1
  37. package/scripts/build-knowledge-index.mjs +1761 -0
  38. package/scripts/calibration.mjs +996 -0
  39. package/scripts/danger-zones.mjs +782 -0
  40. package/scripts/doctor-pipeline-state.sh +88 -2
  41. package/scripts/refresh-bot-token.sh +97 -0
  42. package/scripts/select-fix-targets.sh +234 -0
  43. package/scripts/transition-label.sh +157 -6
@@ -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
- It provides:
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 strings
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
- A conformance suite in `packages/protocol/fixtures/` covers all 13 reserved
1154
- types with valid and invalid examples. The CLI runner can be invoked against any
1155
- fixtures directory:
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` clears `needs-human` (best-effort) on every transition, so moving an issue onto `workflow:awaiting-merge` also clears any stale `needs-human` label.
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.6",
3
+ "version": "1.1.8",
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"
@@ -45,7 +45,7 @@
45
45
  "README.md"
46
46
  ],
47
47
  "scripts": {
48
- "test": "node --test \"bin/tests/**/*.test.mjs\"",
48
+ "test": "node --test \"bin/tests/**/*.test.mjs\" \"packages/protocol/test/**/*.test.mjs\"",
49
49
  "docs:dev": "vitepress dev docs/site",
50
50
  "docs:build": "vitepress build docs/site",
51
51
  "docs:preview": "vitepress preview docs/site"