forge-workflow 0.1.0-beta.3 → 0.1.0-beta.4

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 (122) hide show
  1. package/AGENTS.md +1 -1
  2. package/bin/forge-cmd.js +1 -1
  3. package/bin/forge.js +5 -0
  4. package/docs/reference/COMMANDS.md +3 -1
  5. package/docs/reference/shepherd.md +72 -1
  6. package/lib/adapters/greptile-review-adapter.js +1 -1
  7. package/lib/adapters/pr-state-adapter.js +103 -8
  8. package/lib/agents-config.js +5 -0
  9. package/lib/commands/_issue.js +31 -46
  10. package/lib/commands/_manifest.js +1 -1
  11. package/lib/commands/_resolve-command-opts.js +36 -29
  12. package/lib/commands/claim.js +2 -4
  13. package/lib/commands/hooks.js +155 -8
  14. package/lib/commands/plan.js +23 -115
  15. package/lib/commands/prime.js +8 -1
  16. package/lib/commands/release.js +1 -2
  17. package/lib/commands/serve.js +5 -2
  18. package/lib/commands/setup.js +0 -1
  19. package/lib/commands/shepherd.js +36 -3
  20. package/lib/commands/skill.js +275 -0
  21. package/lib/commands/status.js +37 -32
  22. package/lib/commands/test.js +32 -0
  23. package/lib/commands/worktree.js +27 -1
  24. package/lib/core/runtime-graph.js +88 -14
  25. package/lib/forge-issues.js +13 -464
  26. package/lib/harness-capability-matrix.js +2 -2
  27. package/lib/hook-renderer.js +54 -12
  28. package/lib/issue-backend.js +42 -3
  29. package/lib/kernel/broker.js +28 -0
  30. package/lib/kernel/migrations.js +30 -2
  31. package/lib/kernel/schema.js +35 -0
  32. package/lib/kernel/sqlite-driver.js +150 -0
  33. package/lib/memory-recall.js +151 -0
  34. package/lib/orientation.js +303 -6
  35. package/lib/pr-bundle.js +6 -2
  36. package/lib/pr-monitor/reconcile-executor.js +659 -0
  37. package/lib/pr-monitor/reconcile-tick.js +138 -0
  38. package/lib/pr-monitor/reconcile.js +0 -0
  39. package/lib/pr-monitor/render-sticky.js +14 -0
  40. package/lib/pr-monitor/shepherd-lease.js +243 -0
  41. package/lib/pr-monitor/upsert-sticky.js +1 -1
  42. package/lib/pr-monitor/watch-lifecycle.js +1 -1
  43. package/lib/pr-pull.js +70 -15
  44. package/lib/project-memory.js +8 -0
  45. package/lib/rules-sync.js +4 -0
  46. package/lib/runtime-health.js +15 -46
  47. package/lib/skill-eval.js +750 -0
  48. package/lib/status/identity.js +46 -0
  49. package/lib/status/presenter.js +0 -35
  50. package/lib/status/snapshot.js +11 -16
  51. package/lib/upgrade-safety.js +8 -9
  52. package/lib/using-forge.js +315 -0
  53. package/lib/workflow/enforce-stage.js +5 -5
  54. package/lib/workflow/state-manager.js +23 -23
  55. package/package.json +1 -1
  56. package/rules/using-forge.md +24 -0
  57. package/scripts/forge-team/index.sh +0 -5
  58. package/scripts/forge-team/tests/dispatcher.test.sh +1 -1
  59. package/scripts/forge-team/tests/workflow-integration.test.sh +0 -1
  60. package/scripts/test.js +8 -1
  61. package/skills/claim-safety/SKILL.md +4 -0
  62. package/skills/claim-safety/evals/scorecard.json +41 -0
  63. package/skills/coverage.json +83 -0
  64. package/skills/dev/SKILL.md +4 -0
  65. package/skills/dev/evals/scorecard.json +41 -0
  66. package/skills/gates/SKILL.md +80 -0
  67. package/skills/gates/evals/evals.json +38 -0
  68. package/skills/gates/evals/scorecard.json +41 -0
  69. package/skills/hermes-forge/SKILL.md +1 -0
  70. package/skills/hermes-forge/evals/scorecard.json +41 -0
  71. package/skills/issue-basics/SKILL.md +1 -0
  72. package/skills/issue-basics/evals/scorecard.json +41 -0
  73. package/skills/kernel/SKILL.md +38 -0
  74. package/skills/kernel/evals/scorecard.json +41 -0
  75. package/skills/memory/SKILL.md +16 -1
  76. package/skills/memory/evals/scorecard.json +41 -0
  77. package/skills/parallel-deep-research/SKILL.md +1 -0
  78. package/skills/parallel-deep-research/evals/scorecard.json +41 -0
  79. package/skills/plan/SKILL.md +6 -0
  80. package/skills/plan/evals/scorecard.json +41 -0
  81. package/skills/portability/SKILL.md +47 -0
  82. package/skills/portability/evals/evals.json +34 -0
  83. package/skills/portability/evals/scorecard.json +41 -0
  84. package/skills/research/SKILL.md +1 -0
  85. package/skills/research/evals/scorecard.json +41 -0
  86. package/skills/review/SKILL.md +6 -0
  87. package/skills/review/evals/scorecard.json +41 -0
  88. package/skills/rollback/SKILL.md +1 -0
  89. package/skills/rollback/evals/scorecard.json +41 -0
  90. package/skills/setup/SKILL.md +91 -0
  91. package/skills/setup/evals/evals.json +42 -0
  92. package/skills/setup/evals/scorecard.json +41 -0
  93. package/skills/shepherd/SKILL.md +76 -36
  94. package/skills/shepherd/evals/evals.json +21 -9
  95. package/skills/shepherd/evals/scorecard.json +41 -0
  96. package/skills/ship/SKILL.md +6 -0
  97. package/skills/ship/evals/scorecard.json +41 -0
  98. package/skills/smith/SKILL.md +8 -0
  99. package/skills/smith/evals/scorecard.json +41 -0
  100. package/skills/sonarcloud/SKILL.md +1 -0
  101. package/skills/sonarcloud/evals/scorecard.json +41 -0
  102. package/skills/sonarcloud-analysis/SKILL.md +1 -0
  103. package/skills/sonarcloud-analysis/evals/scorecard.json +41 -0
  104. package/skills/status/SKILL.md +3 -0
  105. package/skills/status/evals/scorecard.json +41 -0
  106. package/skills/triage-ready/SKILL.md +2 -0
  107. package/skills/triage-ready/evals/scorecard.json +41 -0
  108. package/skills/using-forge/SKILL.md +104 -0
  109. package/skills/using-forge/evals/scorecard.json +41 -0
  110. package/skills/validate/SKILL.md +4 -0
  111. package/skills/validate/evals/scorecard.json +41 -0
  112. package/skills/verify/SKILL.md +4 -0
  113. package/skills/verify/evals/scorecard.json +41 -0
  114. package/skills/worktree/SKILL.md +87 -0
  115. package/skills/worktree/evals/evals.json +38 -0
  116. package/skills/worktree/evals/scorecard.json +41 -0
  117. package/lib/adapters/beads-issue-adapter.js +0 -127
  118. package/lib/beads-nudge.js +0 -91
  119. package/lib/commands/board.js +0 -64
  120. package/lib/status/beads-snapshot.js +0 -145
  121. package/scripts/forge-team/lib/dashboard.sh +0 -316
  122. package/scripts/forge-team/tests/dashboard.test.sh +0 -155
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forge-workflow",
3
- "version": "0.1.0-beta.3",
3
+ "version": "0.1.0-beta.4",
4
4
  "description": "Local runtime control plane for AI-assisted engineering workflows, gates, evidence, and all AI agents",
5
5
  "bin": {
6
6
  "forge": "bin/forge.js",
@@ -0,0 +1,24 @@
1
+ ---
2
+ description: "Always: before any response, if a Forge skill could apply, invoke it (or run forge skill for)"
3
+ alwaysApply: true
4
+ globs: []
5
+ ---
6
+
7
+ # Using Forge (skill dispatch — auto-trigger)
8
+
9
+ **Before ANY response or action** — including clarifying questions, exploring the
10
+ codebase, or checking files — if there is even a **1% chance** a Forge skill
11
+ applies to what you are doing, invoke that skill first. Then announce
12
+ `Using [skill] to [purpose]` and follow it.
13
+
14
+ - Not sure which skill fits? Run `forge skill for "<what you are about to do>"`
15
+ for the deterministic best-fit, or read the routing table in the dispatch skill.
16
+ - Common routes: build/scope a feature -> plan; implement a task -> dev; fix a
17
+ failing test -> dev (debug first); run checks/lint/tests -> validate; open a PR
18
+ -> ship; address review feedback -> review; where am I -> status.
19
+
20
+ This rule is a **thin pointer**. The full 1%-rule, red-flags table, subagent
21
+ escape hatch, and routing table live in the **`using-forge` dispatch skill**,
22
+ installed into your agent's own skill surface by `forge setup` (for Cursor:
23
+ `.cursor/skills/using-forge/SKILL.md`) — invoke it by name, or run
24
+ `forge skill for "<situation>"`. Do not duplicate that policy here.
@@ -4,7 +4,6 @@
4
4
  # Subcommands:
5
5
  # workload Show team workload by developer
6
6
  # epic Epic progress rollup
7
- # dashboard Team health dashboard
8
7
  # add Add developer to team map
9
8
  # verify Check 1:1 Beads<>GitHub enforcement
10
9
  # sync Manual GitHub<>Beads sync
@@ -22,7 +21,6 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
22
21
  [[ -f "$SCRIPT_DIR/lib/identity.sh" ]] && source "$SCRIPT_DIR/lib/identity.sh"
23
22
  [[ -f "$SCRIPT_DIR/lib/workload.sh" ]] && source "$SCRIPT_DIR/lib/workload.sh"
24
23
  [[ -f "$SCRIPT_DIR/lib/epic.sh" ]] && source "$SCRIPT_DIR/lib/epic.sh"
25
- [[ -f "$SCRIPT_DIR/lib/dashboard.sh" ]] && source "$SCRIPT_DIR/lib/dashboard.sh"
26
24
  [[ -f "$SCRIPT_DIR/lib/hooks.sh" ]] && source "$SCRIPT_DIR/lib/hooks.sh"
27
25
  [[ -f "$SCRIPT_DIR/lib/verify.sh" ]] && source "$SCRIPT_DIR/lib/verify.sh"
28
26
  [[ -f "$SCRIPT_DIR/lib/claim.sh" ]] && source "$SCRIPT_DIR/lib/claim.sh"
@@ -34,7 +32,6 @@ FORGE_SCRIPTS="$(cd "$SCRIPT_DIR/.." && pwd)"
34
32
  # ── Stub implementations ──
35
33
  # cmd_workload provided by lib/workload.sh
36
34
  # cmd_epic provided by lib/epic.sh
37
- # cmd_dashboard provided by lib/dashboard.sh
38
35
  cmd_add() { auto_detect_identity "$@"; }
39
36
  # cmd_verify provided by lib/verify.sh
40
37
  cmd_sync() { forge_team_sync "$@"; }
@@ -47,7 +44,6 @@ Usage: forge team <subcommand> [args...]
47
44
  Subcommands:
48
45
  workload [--developer=<user>] [--me] Show team workload
49
46
  epic <issue-id> Epic progress rollup
50
- dashboard Team health dashboard
51
47
  add [--github=<user>] Add developer to team map
52
48
  verify Check 1:1 Beads<>GitHub sync
53
49
  sync Manual GitHub<>Beads sync
@@ -69,7 +65,6 @@ main() {
69
65
  case "$subcommand" in
70
66
  workload) cmd_workload "$@" ;;
71
67
  epic) cmd_epic "$@" ;;
72
- dashboard) cmd_dashboard "$@" ;;
73
68
  add) cmd_add "$@" ;;
74
69
  verify) cmd_verify "$@" ;;
75
70
  sync) cmd_sync "$@" ;;
@@ -60,7 +60,7 @@ assert_output_contains "unknown subcommand shows error" "unknown subcommand" bas
60
60
  # Test 4: Each stub subcommand is reachable (exits 0)
61
61
  echo ""
62
62
  echo "-- stub subcommands reachable --"
63
- for cmd in workload epic dashboard add verify sync claim; do
63
+ for cmd in workload epic add verify sync claim; do
64
64
  assert_exit "$cmd exits 0" 0 bash "$DISPATCHER" "$cmd"
65
65
  assert_output_contains "$cmd outputs stub message" "not implemented" bash "$DISPATCHER" "$cmd"
66
66
  done
@@ -17,7 +17,6 @@ assert_contains_file() {
17
17
  echo "── /status integration ──"
18
18
  STATUS="$SCRIPT_DIR/.claude/commands/status.md"
19
19
  assert_contains_file "status calls workload --me" "forge-team.*workload.*--me" "$STATUS"
20
- assert_contains_file "status calls dashboard" "forge-team.*dashboard" "$STATUS"
21
20
 
22
21
  echo ""
23
22
  echo "── /plan integration ──"
package/scripts/test.js CHANGED
@@ -156,6 +156,8 @@ function isKnownTargetablePath(file) {
156
156
 
157
157
  if (file === 'README.md'
158
158
  || file === 'bin/forge.js'
159
+ || file === 'bin/forge-cmd.js'
160
+ || file === 'bin/forge-preflight.js'
159
161
  || file === 'QUICKSTART.md'
160
162
  || file === 'CHANGELOG.md'
161
163
  || file === 'AGENTS.md'
@@ -166,7 +168,12 @@ function isKnownTargetablePath(file) {
166
168
  || file.startsWith('docs/guides/')
167
169
  || file.startsWith('docs/plans/')
168
170
  || file.startsWith('docs/reference/')
169
- || file.startsWith('docs/work/')) {
171
+ || file.startsWith('docs/work/')
172
+ // Skill sources + their committed mirror map to the skill suite (see
173
+ // SKILL_TEST_TARGETS in lib/commands/test.js); a skills-only PR stays on the
174
+ // targeted lane instead of the full suite.
175
+ || file.startsWith('skills/')
176
+ || file.startsWith('.agents/skills/')) {
170
177
  return true;
171
178
  }
172
179
 
@@ -14,10 +14,14 @@ description: >
14
14
  and NOT for read-only selecting or ranking the next ready issue without claiming (that is
15
15
  triage-ready).
16
16
  allowed-tools: Read, Bash(forge:*)
17
+ next: dev
18
+ terminal: false
17
19
  ---
18
20
 
19
21
  # Claim safety — claim, then prove you own the lease
20
22
 
23
+ > **Chain:** once you have PROVEN the lease (`forge issue owns <id>` exits 0), continue to `dev` to work the issue (`smith` proceeds into plan/dev after this proof). Usable standalone whenever ownership is in question.
24
+
21
25
  Claiming is not owning. The Forge kernel keys a claim's idempotency on
22
26
  `claim.create:<issue_id>:<actor>`, so a **same-key duplicate replay returns
23
27
  `ok:true`** echoing the *current* call's `claim_id`. A genuine cross-actor
@@ -0,0 +1,41 @@
1
+ {
2
+ "skill": "claim-safety",
3
+ "fixtures": "present",
4
+ "static": {
5
+ "token_cost": {
6
+ "desc_chars": 995,
7
+ "body_lines": 88,
8
+ "score": 43
9
+ },
10
+ "caps": {
11
+ "desc_within": true,
12
+ "body_within": true,
13
+ "score": 100
14
+ },
15
+ "description_quality": {
16
+ "has_trigger_cues": true,
17
+ "has_disambiguation_cues": true,
18
+ "adequate_length": true,
19
+ "score": 100
20
+ }
21
+ },
22
+ "router_reachability": {
23
+ "has_curated_rule": true,
24
+ "router_exempt": false,
25
+ "fixtures": "present",
26
+ "fixtures_total": 6,
27
+ "fixtures_best_hit": 2,
28
+ "reachable": true,
29
+ "keyword_alignment": 0.33
30
+ },
31
+ "behavioral": {
32
+ "trigger_recall": null,
33
+ "trigger_precision": null,
34
+ "disambiguation": null,
35
+ "chain_correctness": null,
36
+ "outcome_quality": null,
37
+ "variance": null,
38
+ "note": "behavioral — W5 (LLM judge): semantic recall/precision/chain/outcome/variance, not deterministic"
39
+ },
40
+ "composite": 83
41
+ }
@@ -0,0 +1,83 @@
1
+ {
2
+ "version": 1,
3
+ "description": "Command -> owning-skill coverage map (plan 2026-07-20-next-phase-plan.md §3.3). Every registered user-facing command MUST map to an existing skill OR carry an explicit { exempt: <reason> }. Enforced by the coverage gate (lib/skill-eval.js evaluateCoverage, surfaced by `forge skill coverage`/`forge skill scores`, gated in test/skill-eval.test.js). Exempts reference the pending skill from plan §3.2 and are tightened as those skills land.",
4
+ "commands": {
5
+ "plan": "plan",
6
+ "dev": "dev",
7
+ "validate": "validate",
8
+ "ship": "ship",
9
+ "shepherd": "shepherd",
10
+ "status": "status",
11
+ "prime": "status",
12
+ "orient": "hermes-forge",
13
+ "recap": "hermes-forge",
14
+ "remember": "memory",
15
+ "recall": "memory",
16
+ "memory": "memory",
17
+ "ready": "triage-ready",
18
+ "blocked": "triage-ready",
19
+ "claim": "claim-safety",
20
+ "claims": "claim-safety",
21
+ "issue": "issue-basics",
22
+ "issues": "issue-basics",
23
+ "create": "issue-basics",
24
+ "close": "issue-basics",
25
+ "comment": "issue-basics",
26
+ "show": "issue-basics",
27
+ "update": "issue-basics",
28
+ "list": "issue-basics",
29
+ "skill": "using-forge",
30
+
31
+ "worktree": "worktree",
32
+ "clean": "worktree",
33
+ "orphans": { "exempt": "full ownership (command-name routing + `forge issue orphans` guidance in the issue-basics body) pending — issue e1e33cf8; issue-basics does not yet document it, so mapping now would be a hollow claim" },
34
+ "rollback": "rollback",
35
+ "review": "review",
36
+ "verify": "verify",
37
+ "check": { "exempt": "legacy alias for `validate` (renamed in PR #50) — bin/forge-cmd.js VALID_COMMANDS only; owned by the `validate` skill" },
38
+ "docs": { "exempt": "bin/forge.js-direct; AGENTS.md/docs management — owning skill pending (coverage pass, plan §3.2)" },
39
+ "reset": "setup",
40
+ "reinstall": "setup",
41
+
42
+ "gate": "gates",
43
+ "control": "gates",
44
+ "doc-gate": "gates",
45
+
46
+ "adapter": { "exempt": "extensions skill pending (plan §3.2 B: new `extensions` skill)" },
47
+ "add": { "exempt": "extensions skill pending (plan §3.2 B: new `extensions` skill)" },
48
+ "new": { "exempt": "extensions skill pending (plan §3.2 B: new `extensions` skill)" },
49
+ "audit": { "exempt": "extensions skill pending (plan §3.2 B: new `extensions` skill)" },
50
+ "role": { "exempt": "extensions skill pending — role/skill binding (plan §3.2 B)" },
51
+
52
+ "export": "portability",
53
+ "migrate": "portability",
54
+ "sync": { "exempt": "cloud-native external-platform sync (ADR-0004); a local no-op with no value until a server backend is configured — skill deferred (issue 666f4b4c)" },
55
+
56
+ "inbox": { "exempt": "team skill pending (plan §3.2 B: new `team` skill)" },
57
+ "serve": { "exempt": "team skill pending (plan §3.2 B: new `team` skill)" },
58
+ "team": { "exempt": "team skill pending (plan §3.2 B: new `team` skill)" },
59
+
60
+ "setup": "setup",
61
+ "init": "setup",
62
+ "upgrade": "setup",
63
+ "doctor": "setup",
64
+ "hooks": "setup",
65
+ "recommend": "setup",
66
+
67
+ "push": { "exempt": "ship skill push/preflight extension pending (plan §3.2 B)" },
68
+ "preflight": { "exempt": "ship skill push/preflight extension pending (plan §3.2 B)" },
69
+ "pr": { "exempt": "ship/shepherd PR-lifecycle extension pending (plan §3.2)" },
70
+ "merge": { "exempt": "ship/shepherd PR-lifecycle extension pending (plan §3.2)" },
71
+
72
+ "patch": { "exempt": "kernel skill fold pending (plan §3.2 C: fold into `kernel`)" },
73
+ "stage": { "exempt": "kernel skill fold pending (plan §3.2 C: fold into `kernel`)" },
74
+ "explain": { "exempt": "kernel skill fold pending (plan §3.2 C: fold into `kernel`)" },
75
+ "options": { "exempt": "kernel skill fold pending (plan §3.2 C: fold into `kernel`)" },
76
+ "insights": { "exempt": "kernel skill fold pending — kernel evidence inspection (plan §3.2 C)" },
77
+
78
+ "lint": { "exempt": "internal quality plumbing; skill assignment pending (coverage pass)" },
79
+ "release": { "exempt": "internal release plumbing; skill assignment pending (coverage pass)" },
80
+ "test": { "exempt": "internal test-runner plumbing; skill assignment pending (coverage pass)" },
81
+ "stale": { "exempt": "internal stale-detection plumbing; skill assignment pending (coverage pass)" }
82
+ }
83
+ }
@@ -13,12 +13,16 @@ description: >
13
13
  opening the PR (ship), for addressing PR review feedback (review), or for orchestrating
14
14
  several stages / taking an issue end-to-end to a merged PR (smith).
15
15
  allowed-tools: Bash, Read, Write, Edit, Grep, Glob
16
+ next: validate
17
+ terminal: false
16
18
  ---
17
19
 
18
20
  Implement each task from the /plan task list using a subagent-driven loop: implementer → spec compliance reviewer → code quality reviewer per task.
19
21
 
20
22
  # Dev
21
23
 
24
+ > **Chain (HARD-GATE):** the ONLY skill you invoke after `dev` is `validate`. Never open a PR straight from `dev`.
25
+
22
26
  This skill reads the task list created by `/plan` and implements each task using a three-stage subagent loop. TDD is enforced inside each implementer subagent.
23
27
 
24
28
  ## Usage
@@ -0,0 +1,41 @@
1
+ {
2
+ "skill": "dev",
3
+ "fixtures": "present",
4
+ "static": {
5
+ "token_cost": {
6
+ "desc_chars": 962,
7
+ "body_lines": 328,
8
+ "score": 20
9
+ },
10
+ "caps": {
11
+ "desc_within": true,
12
+ "body_within": true,
13
+ "score": 100
14
+ },
15
+ "description_quality": {
16
+ "has_trigger_cues": true,
17
+ "has_disambiguation_cues": true,
18
+ "adequate_length": true,
19
+ "score": 100
20
+ }
21
+ },
22
+ "router_reachability": {
23
+ "has_curated_rule": true,
24
+ "router_exempt": false,
25
+ "fixtures": "present",
26
+ "fixtures_total": 6,
27
+ "fixtures_best_hit": 2,
28
+ "reachable": true,
29
+ "keyword_alignment": 0.33
30
+ },
31
+ "behavioral": {
32
+ "trigger_recall": null,
33
+ "trigger_precision": null,
34
+ "disambiguation": null,
35
+ "chain_correctness": null,
36
+ "outcome_quality": null,
37
+ "variance": null,
38
+ "note": "behavioral — W5 (LLM judge): semantic recall/precision/chain/outcome/variance, not deterministic"
39
+ },
40
+ "composite": 76
41
+ }
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: gates
3
+ description: >
4
+ Toggle Forge's workflow gates and rails — strong-but-toggleable enforcement. `forge gate
5
+ enable|disable <gate-id>` flips `workflow.gates.<id>.enabled` in `.forge/config.yaml`; the
6
+ installed git hooks read resolved config at run time, so disabling a rail makes them
7
+ genuinely inert. `forge gate approve|reject <issue> <gate>` records durable human-gate
8
+ approval events; `forge gate status`/`check` query them; `forge control <id>
9
+ <mandatory|optional|permission>` sets tri-state DECLARED intent (writes the same `enabled`
10
+ field — no independent runtime enforcement). Use when the user says "disable the gate",
11
+ "turn off TDD enforcement", "the tdd intent rail is blocking me", "toggle or enable a
12
+ gate", "loosen enforcement", or "approve a human gate". Common default-ON toggleable rails:
13
+ `rail.tdd_intent`, `rail.kernel_tracking`, `rail.auto_shepherd` — e.g. `forge gate disable
14
+ rail.tdd_intent`. NOT for addressing PR review feedback (review), NOT the status snapshot
15
+ of work in flight (status).
16
+ allowed-tools: Bash, Read, Grep, Glob
17
+ terminal: true
18
+ ---
19
+
20
+ Forge's gates and rails are **default-strong but toggleable**. The `gates` skill is how you flip one off (or back on), record a human-gate approval, and see enforcement state. The stored truth is one field — `workflow.gates.<id>.enabled` — and the installed hooks read the resolved config at run time, so a disabled rail is genuinely inert, not cosmetically off.
21
+
22
+ # Toggling gates and rails
23
+
24
+ ## When to use
25
+
26
+ - "Disable the gate", "turn off TDD enforcement", "the tdd intent rail is blocking me".
27
+ - "Toggle / enable a gate", "loosen enforcement for this repo".
28
+ - "Approve a human gate" (record a durable approval event on an issue).
29
+
30
+ ## Toggle a gate or rail (the enforcement switch)
31
+
32
+ ```bash
33
+ forge gate disable <gate-id> # set workflow.gates.<id>.enabled = false in .forge/config.yaml
34
+ forge gate enable <gate-id> # set it back to true
35
+ ```
36
+
37
+ An unknown gate id — or disabling a **locked** gate — errors **before** anything is written, never mid-run. Because the hooks resolve config at run time, the flip takes effect immediately with no reinstall.
38
+
39
+ ### Common rails (default-ON, toggleable)
40
+
41
+ | Rail | What it enforces | Turn off with |
42
+ | --- | --- | --- |
43
+ | `rail.tdd_intent` | Pre-commit TDD gate (source changed ⇒ tests changed). The `minimal` adoption profile ships it off. | `forge gate disable rail.tdd_intent` |
44
+ | `rail.kernel_tracking` | "File every issue" — nothing discussed goes missing. | `forge gate disable rail.kernel_tracking` |
45
+ | `rail.auto_shepherd` | The autonomous PR-shepherd daemon fire. | `forge gate disable rail.auto_shepherd` |
46
+
47
+ The `gate.*` and `rail.*` id namespaces are disjoint, so `forge gate enable|disable` governs both through one flat surface.
48
+
49
+ ## Human-gate approval events
50
+
51
+ ```bash
52
+ forge gate approve <issue-id> <gate-id> # record a durable gate.approved event
53
+ forge gate reject <issue-id> <gate-id> # record gate.rejected
54
+ forge gate status <issue-id> # list recorded events for that issue (resume-safe)
55
+ forge gate check <issue-id> <gate-id> # exit 0 iff gate DISABLED or an approval exists on that issue
56
+ ```
57
+
58
+ `check` is the reusable enforcement primitive a stage skill calls: it passes when the gate is disabled or an approval event has been recorded for that specific issue id (approvals are issue-scoped, so pass the same `<issue-id>` you approved against). Events are durable on the issue, so they survive a compaction or crash.
59
+
60
+ ## Tri-state control (declared intent)
61
+
62
+ ```bash
63
+ forge control <gate-id|rail-id> <mandatory|optional|permission>
64
+ forge control status [--json]
65
+ ```
66
+
67
+ `forge control` sets the **declared intent** vocabulary and writes the **same** `enabled` field that `forge gate` writes — there is deliberately no parallel key. It is a view/intent layer: today no runtime consumer denies purely on a control flag (MCP/rules/skills are presence-only and refused). For actually turning enforcement off, use `forge gate disable`.
68
+
69
+ ## The doc-update gate
70
+
71
+ ```bash
72
+ forge gate doc <detect|check|init|...> # = forge doc-gate (run `forge doc-gate --help`)
73
+ ```
74
+
75
+ The doc-update gate folds under this noun as `forge gate doc`; bare `forge doc-gate` stays as a back-compat alias.
76
+
77
+ ## Adjacent skills
78
+
79
+ - Addressing PR review feedback / resolving threads → `review`.
80
+ - The snapshot of where the project stands and what's in flight → `status`.
@@ -0,0 +1,38 @@
1
+ [
2
+ {
3
+ "query": "Disable the tdd gate for this repo.",
4
+ "should_trigger": true
5
+ },
6
+ {
7
+ "query": "Turn off TDD enforcement — the tdd intent rail is blocking my commit.",
8
+ "should_trigger": true
9
+ },
10
+ {
11
+ "query": "Toggle the kernel tracking rail off for now.",
12
+ "should_trigger": true
13
+ },
14
+ {
15
+ "query": "Enable a gate that I disabled earlier and loosen enforcement.",
16
+ "should_trigger": true
17
+ },
18
+ {
19
+ "query": "Approve the human gate on this issue so the stage can proceed.",
20
+ "should_trigger": true
21
+ },
22
+ {
23
+ "query": "Disable the auto shepherd rail so no PR daemon fires.",
24
+ "should_trigger": true
25
+ },
26
+ {
27
+ "query": "Address the CodeRabbit review feedback and resolve the threads.",
28
+ "should_trigger": false
29
+ },
30
+ {
31
+ "query": "Where am I in the workflow and what work is in flight right now?",
32
+ "should_trigger": false
33
+ },
34
+ {
35
+ "query": "Run the tests and lint before I push.",
36
+ "should_trigger": false
37
+ }
38
+ ]
@@ -0,0 +1,41 @@
1
+ {
2
+ "skill": "gates",
3
+ "fixtures": "present",
4
+ "static": {
5
+ "token_cost": {
6
+ "desc_chars": 994,
7
+ "body_lines": 63,
8
+ "score": 45
9
+ },
10
+ "caps": {
11
+ "desc_within": true,
12
+ "body_within": true,
13
+ "score": 100
14
+ },
15
+ "description_quality": {
16
+ "has_trigger_cues": true,
17
+ "has_disambiguation_cues": true,
18
+ "adequate_length": true,
19
+ "score": 100
20
+ }
21
+ },
22
+ "router_reachability": {
23
+ "has_curated_rule": true,
24
+ "router_exempt": false,
25
+ "fixtures": "present",
26
+ "fixtures_total": 6,
27
+ "fixtures_best_hit": 6,
28
+ "reachable": true,
29
+ "keyword_alignment": 1
30
+ },
31
+ "behavioral": {
32
+ "trigger_recall": null,
33
+ "trigger_precision": null,
34
+ "disambiguation": null,
35
+ "chain_correctness": null,
36
+ "outcome_quality": null,
37
+ "variance": null,
38
+ "note": "behavioral — W5 (LLM judge): semantic recall/precision/chain/outcome/variance, not deterministic"
39
+ },
40
+ "composite": 84
41
+ }
@@ -26,6 +26,7 @@ metadata:
26
26
  author: forge
27
27
  version: "1.0.0"
28
28
  roadmap: forge-2agy.9.7.x
29
+ chainExempt: true
29
30
  ---
30
31
 
31
32
  # Hermes ⇄ Forge consumption contract
@@ -0,0 +1,41 @@
1
+ {
2
+ "skill": "hermes-forge",
3
+ "fixtures": "present",
4
+ "static": {
5
+ "token_cost": {
6
+ "desc_chars": 993,
7
+ "body_lines": 157,
8
+ "score": 36
9
+ },
10
+ "caps": {
11
+ "desc_within": true,
12
+ "body_within": true,
13
+ "score": 100
14
+ },
15
+ "description_quality": {
16
+ "has_trigger_cues": true,
17
+ "has_disambiguation_cues": true,
18
+ "adequate_length": true,
19
+ "score": 100
20
+ }
21
+ },
22
+ "router_reachability": {
23
+ "has_curated_rule": true,
24
+ "router_exempt": false,
25
+ "fixtures": "present",
26
+ "fixtures_total": 6,
27
+ "fixtures_best_hit": 2,
28
+ "reachable": true,
29
+ "keyword_alignment": 0.33
30
+ },
31
+ "behavioral": {
32
+ "trigger_recall": null,
33
+ "trigger_precision": null,
34
+ "disambiguation": null,
35
+ "chain_correctness": null,
36
+ "outcome_quality": null,
37
+ "variance": null,
38
+ "note": "behavioral — W5 (LLM judge): semantic recall/precision/chain/outcome/variance, not deterministic"
39
+ },
40
+ "composite": 81
41
+ }
@@ -14,6 +14,7 @@ description: >
14
14
  the plan->dev->validate->ship pipeline or open a PR (use smith or stage skills); does NOT
15
15
  report the current stage or what's in flight (use status).
16
16
  allowed-tools: Read, Bash(forge:*)
17
+ terminal: true
17
18
  ---
18
19
 
19
20
  # Issue basics — the CRUD floor
@@ -0,0 +1,41 @@
1
+ {
2
+ "skill": "issue-basics",
3
+ "fixtures": "present",
4
+ "static": {
5
+ "token_cost": {
6
+ "desc_chars": 991,
7
+ "body_lines": 95,
8
+ "score": 42
9
+ },
10
+ "caps": {
11
+ "desc_within": true,
12
+ "body_within": true,
13
+ "score": 100
14
+ },
15
+ "description_quality": {
16
+ "has_trigger_cues": false,
17
+ "has_disambiguation_cues": true,
18
+ "adequate_length": true,
19
+ "score": 60
20
+ }
21
+ },
22
+ "router_reachability": {
23
+ "has_curated_rule": true,
24
+ "router_exempt": false,
25
+ "fixtures": "present",
26
+ "fixtures_total": 6,
27
+ "fixtures_best_hit": 0,
28
+ "reachable": false,
29
+ "keyword_alignment": 0
30
+ },
31
+ "behavioral": {
32
+ "trigger_recall": null,
33
+ "trigger_precision": null,
34
+ "disambiguation": null,
35
+ "chain_correctness": null,
36
+ "outcome_quality": null,
37
+ "variance": null,
38
+ "note": "behavioral — W5 (LLM judge): semantic recall/precision/chain/outcome/variance, not deterministic"
39
+ },
40
+ "composite": 63
41
+ }
@@ -14,6 +14,7 @@ description: >
14
14
  merged PR under gates → `smith`; token-bounded state for the Hermes harness →
15
15
  `hermes-forge`.
16
16
  allowed-tools: Read, Bash(forge:*)
17
+ terminal: true
17
18
  ---
18
19
 
19
20
  # Forge kernel surface
@@ -56,6 +57,43 @@ mutating it — a claim returning ok:true does not by itself prove ownership).
56
57
  status → plan → dev → validate → ship → review → verify
57
58
  ```
58
59
 
60
+ ### Chain map (each skill declares its successor)
61
+
62
+ Every skill carries chain metadata in its frontmatter (`next`, `terminal`,
63
+ `subskills`, `handoffs`); each workflow STAGE skill additionally carries a
64
+ HARD-GATE chain line in its body, so each stage announces the next one. The
65
+ linear ladder:
66
+
67
+ | Skill | `next` | `terminal` |
68
+ |-------|--------|-----------|
69
+ | `plan` | `dev` | `false` |
70
+ | `dev` | `validate` | `false` |
71
+ | `validate` | `ship` | `false` |
72
+ | `ship` | `review` | `false` |
73
+ | `review` | `verify` | `false` |
74
+ | `verify` | `ship` | `false` |
75
+
76
+ The `next` column is each stage's DEFAULT / critical-path successor (`plan`
77
+ composes `research`; `ship` and `review` also carry a `shepherd` handoff). The
78
+ actual successor after `ship`, `review`, and `verify` is classification-dependent
79
+ — see the note below. `verify`'s `next` (`ship`) is the `docs`-only pre-ship
80
+ reuse; in every other flow nothing follows `verify`.
81
+
82
+ Feeders into the chain: `triage-ready` → `claim-safety` → `dev` (rank the pick,
83
+ prove the live lease, then work it). `research` is standalone / callable
84
+ mid-workflow and returns to its CALLER (no forced `next`); it is also a `subskill`
85
+ of `plan`. The `smith` orchestrator composes the six stages (`subskills`).
86
+ Utility/terminal skills (`status`, `shepherd`, `kernel`, `issue-basics`, `memory`,
87
+ `rollback`, `research`, `sonarcloud`, `sonarcloud-analysis`,
88
+ `parallel-deep-research`, `using-forge`) declare no forward-stage `next`. Meta
89
+ skills (`hermes-forge`) are chain-exempt.
90
+
91
+ The stage `next` values above are the DEFAULT / critical-path successors. The
92
+ actual successor after `ship`, `review`, and `verify` is
93
+ classification-dependent — the authoritative matrix is `lib/workflow/stages.js`
94
+ (Simple/Hotfix/Refactor end at `ship`; Standard ends at `review`; Critical runs
95
+ through `verify`; the `docs` classification reuses `verify` → `ship`).
96
+
59
97
  ## Orchestrator super-skill
60
98
 
61
99
  `smith` is the flagship: a thin orchestrator that COMPOSES the skills above into