forge-workflow 0.0.10 → 0.1.0-beta.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.
- package/.claude/rules/{greptile-review-process.md → review-process.md} +56 -41
- package/.claude/scripts/{greptile-resolve.sh → review-resolve.sh} +13 -3
- package/.cursor/rules/permissions-guidance.mdc +2 -2
- package/.forge/hooks/check-tdd.js +3 -0
- package/.forge/hooks/forge-native-hook.js +245 -0
- package/.forge/protected-paths.yaml +157 -0
- package/AGENTS.md +150 -61
- package/CHANGELOG.md +681 -0
- package/CLAUDE.md +9 -118
- package/QUICKSTART.md +171 -0
- package/README.md +271 -363
- package/bin/forge-cmd.js +120 -9
- package/bin/forge-preflight.js +26 -5
- package/bin/forge.js +461 -489
- package/docs/INDEX.md +93 -0
- package/docs/PROJECT_DESIGN.md +685 -0
- package/docs/architecture/index.md +66 -0
- package/docs/architecture/notes/README.md +35 -0
- package/docs/architecture/subsystems/README.md +46 -0
- package/docs/forge/TOOLCHAIN.md +670 -0
- package/docs/forge/VALIDATION.md +82 -0
- package/docs/{AGENT_INSTALL_PROMPT.md → guides/AGENT_INSTALL_PROMPT.md} +3 -3
- package/docs/guides/BEADS_GITHUB_SYNC.md +32 -0
- package/docs/{ENHANCED_ONBOARDING.md → guides/ENHANCED_ONBOARDING.md} +16 -12
- package/docs/guides/GREPTILE_SETUP.md +46 -0
- package/docs/guides/MANUAL_REVIEW_GUIDE.md +58 -0
- package/docs/guides/MIGRATION.md +56 -0
- package/docs/guides/SETUP.md +118 -0
- package/docs/guides/SUPPORT.md +185 -0
- package/docs/guides/WORKFLOW_TEMPLATES.md +74 -0
- package/docs/guides/memory-backends.md +183 -0
- package/docs/reference/ADAPTERS.md +128 -0
- package/docs/reference/AGENT_SKILL_PARITY.md +175 -0
- package/docs/reference/COMMANDS.md +205 -0
- package/docs/reference/DECISION_DRIFT_GUARDS.md +97 -0
- package/docs/{EXAMPLES.md → reference/EXAMPLES.md} +7 -5
- package/docs/reference/FORGE_KERNEL_STORAGE_MODEL.md +135 -0
- package/docs/reference/HERMES_INTEGRATION.md +118 -0
- package/docs/reference/INSIGHTS_RECAP.md +63 -0
- package/docs/reference/INSTALL.md +164 -0
- package/docs/reference/KERNEL_TAXONOMY_VALIDATION.md +161 -0
- package/docs/reference/PROTECTED_PATH_MANIFEST.md +25 -0
- package/docs/reference/RELEASE.md +68 -0
- package/docs/reference/RESEARCH_TEMPLATE.md +292 -0
- package/docs/{ROADMAP.md → reference/ROADMAP.md} +12 -9
- package/docs/reference/SKILLS.md +35 -0
- package/docs/reference/STATUS_BOARD.md +80 -0
- package/docs/reference/TEMPLATES.md +106 -0
- package/docs/{TOOLCHAIN.md → reference/TOOLCHAIN.md} +62 -47
- package/docs/reference/VALIDATION.md +82 -0
- package/docs/reference/agent-permissions.md +169 -0
- package/docs/reference/beads-to-kernel-migration-ux.md +61 -0
- package/docs/reference/control-plane-guarantees.md +125 -0
- package/docs/reference/dependency-chain.md +331 -0
- package/docs/reference/forge-kernel-issue-command-contract.md +161 -0
- package/docs/reference/forge-kernel-schema.md +72 -0
- package/docs/reference/kernel-conflict-evaluators.md +27 -0
- package/docs/reference/patch-md-format.md +77 -0
- package/docs/reference/protected-state-surfaces.md +59 -0
- package/docs/reference/shepherd.md +115 -0
- package/docs/reference/superpowers-analysis.md +320 -0
- package/docs/reference/superpowers-integration-options.md +404 -0
- package/docs/reference/test-environment.md +519 -0
- package/docs/reference/upgrade-safety.md +59 -0
- package/lefthook.yml +18 -0
- package/lib/adapter-cli.js +307 -0
- package/lib/adapters/beads-issue-adapter.js +127 -0
- package/lib/adapters/beads-kernel-compat.js +1042 -0
- package/lib/adapters/greptile-review-adapter.js +141 -0
- package/lib/adapters/kernel-issue-adapter.js +101 -0
- package/lib/adapters/pr-state-adapter.js +484 -0
- package/lib/adoption-profiles.js +126 -0
- package/lib/agents/README.md +2 -6
- package/lib/agents/claude.plugin.json +3 -8
- package/lib/agents/codex.plugin.json +9 -1
- package/lib/agents/cursor.plugin.json +2 -6
- package/lib/agents/hermes.plugin.json +22 -0
- package/lib/agents-config.js +39 -1236
- package/lib/audit-evidence.js +282 -0
- package/lib/beads-setup.js +121 -0
- package/lib/beads-sync-scaffold.js +25 -101
- package/lib/codex-skills.js +51 -1
- package/lib/commands/_issue.js +741 -77
- package/lib/commands/_manifest.js +91 -0
- package/lib/commands/_registry.js +85 -34
- package/lib/commands/_resolve-command-opts.js +261 -0
- package/lib/commands/_serve-security.js +270 -0
- package/lib/commands/adapter.js +12 -0
- package/lib/commands/add.js +118 -0
- package/lib/commands/audit.js +70 -0
- package/lib/commands/blocked.js +5 -0
- package/lib/commands/board.js +64 -0
- package/lib/commands/claim.js +21 -2
- package/lib/commands/claims.js +7 -0
- package/lib/commands/clean.js +485 -75
- package/lib/commands/close.js +2 -2
- package/lib/commands/comment.js +5 -0
- package/lib/commands/control.js +148 -0
- package/lib/commands/create.js +2 -2
- package/lib/commands/dev.js +185 -7
- package/lib/commands/doc-gate.js +336 -0
- package/lib/commands/doctor.js +156 -0
- package/lib/commands/explain.js +15 -0
- package/lib/commands/export.js +237 -0
- package/lib/commands/gate.js +192 -0
- package/lib/commands/hooks.js +242 -0
- package/lib/commands/inbox.js +118 -0
- package/lib/commands/init.js +598 -0
- package/lib/commands/insights.js +79 -0
- package/lib/commands/issue.js +12 -1
- package/lib/commands/issues.js +17 -0
- package/lib/commands/lint.js +5 -0
- package/lib/commands/list.js +2 -2
- package/lib/commands/merge.js +312 -0
- package/lib/commands/migrate.js +523 -0
- package/lib/commands/new.js +12 -0
- package/lib/commands/options.js +241 -0
- package/lib/commands/orient.js +13 -0
- package/lib/commands/orphans.js +5 -0
- package/lib/commands/patch.js +67 -0
- package/lib/commands/plan.js +436 -24
- package/lib/commands/preflight.js +211 -0
- package/lib/commands/prime.js +13 -0
- package/lib/commands/push.js +69 -2
- package/lib/commands/ready.js +2 -2
- package/lib/commands/recall.js +116 -0
- package/lib/commands/recap.js +61 -0
- package/lib/commands/recommend.js +0 -1
- package/lib/commands/release.js +91 -0
- package/lib/commands/remember.js +74 -0
- package/lib/commands/role.js +99 -0
- package/lib/commands/serve.js +581 -0
- package/lib/commands/setup.js +838 -972
- package/lib/commands/shepherd.js +436 -0
- package/lib/commands/ship.js +23 -1
- package/lib/commands/show.js +2 -2
- package/lib/commands/stage.js +192 -0
- package/lib/commands/stale.js +5 -0
- package/lib/commands/status.js +158 -21
- package/lib/commands/sync.js +34 -46
- package/lib/commands/team.js +4 -1
- package/lib/commands/test.js +43 -27
- package/lib/commands/update.js +2 -2
- package/lib/commands/upgrade.js +47 -0
- package/lib/commands/validate.js +43 -18
- package/lib/commands/worktree.js +307 -100
- package/lib/config-writer.js +202 -0
- package/lib/control-plane.js +236 -0
- package/lib/core/runtime-graph.js +946 -0
- package/lib/dep-guard/keyword-ripple.js +2 -2
- package/lib/deprecated-sync-cleanup.js +362 -0
- package/lib/detect-agent.js +2 -28
- package/lib/detect-worktree.js +35 -9
- package/lib/doc-gate/declaration.js +177 -0
- package/lib/doc-gate/detect.js +289 -0
- package/lib/doc-gate/gate.js +375 -0
- package/lib/doc-gate/okf-config.js +128 -0
- package/lib/doc-gate/okf.js +429 -0
- package/lib/docs-command.js +1161 -6
- package/lib/forge-issues.js +382 -11
- package/lib/forge-lock.js +262 -0
- package/lib/gate-events.js +193 -0
- package/lib/global-flags.js +74 -0
- package/lib/greptile-match.js +7 -63
- package/lib/harness-capability-matrix.js +380 -0
- package/lib/hook-global-installer.js +347 -0
- package/lib/hook-renderer.js +451 -0
- package/lib/inbox.js +391 -0
- package/lib/insights.js +397 -0
- package/lib/issue-adapter.js +156 -0
- package/lib/issue-backend.js +145 -0
- package/lib/issue-render.js +220 -0
- package/lib/kernel/backing-issue.js +305 -0
- package/lib/kernel/broker.js +1218 -0
- package/lib/kernel/cli-broker-factory.js +130 -0
- package/lib/kernel/conflict-signal.js +82 -0
- package/lib/kernel/evaluators.js +195 -0
- package/lib/kernel/fs-class.js +495 -0
- package/lib/kernel/issue-command-contract.js +559 -0
- package/lib/kernel/issue-id-resolver.js +186 -0
- package/lib/kernel/lease-enforcer.js +158 -0
- package/lib/kernel/migrations.js +333 -0
- package/lib/kernel/planning-buckets-schema.js +109 -0
- package/lib/kernel/projection-jsonl-writer.js +450 -0
- package/lib/kernel/readiness-model.js +329 -0
- package/lib/kernel/schema.js +356 -0
- package/lib/kernel/sqlite-driver.js +2504 -0
- package/lib/kernel/taxonomy-validator.js +394 -0
- package/lib/lefthook-check.js +3 -2
- package/lib/lefthook-wiring.js +413 -0
- package/lib/mcp-config-renderer.js +288 -0
- package/lib/memory/graphiti-mcp.js +106 -0
- package/lib/memory/router.js +387 -0
- package/lib/memory/typed-api.js +102 -0
- package/lib/memory-digest.js +195 -0
- package/lib/merge-rules.js +395 -0
- package/lib/migrate-dry-run.js +466 -0
- package/lib/orientation.js +863 -0
- package/lib/package-manager-remediation.js +103 -0
- package/lib/package-root.js +381 -0
- package/lib/patch-intent.js +890 -0
- package/lib/plugin-catalog.js +3 -4
- package/lib/plugin-manager.js +0 -5
- package/lib/pr-bundle.js +186 -0
- package/lib/pr-monitor/differ.js +195 -0
- package/lib/pr-monitor/events.js +0 -0
- package/lib/pr-monitor/gather.js +124 -0
- package/lib/pr-monitor/journal.js +299 -0
- package/lib/pr-monitor/monitor.js +146 -0
- package/lib/pr-monitor/render-sticky.js +157 -0
- package/lib/pr-monitor/watch-lifecycle.js +95 -0
- package/lib/pr-monitor/watch.js +247 -0
- package/lib/pr-pull.js +1273 -0
- package/lib/pr-shepherd.js +494 -0
- package/lib/pr-state-validator.js +59 -0
- package/lib/preflight/gates.js +237 -0
- package/lib/preflight/runner.js +116 -0
- package/lib/project-discovery.js +0 -53
- package/lib/project-memory.js +99 -497
- package/lib/protected-path-manifest.js +281 -0
- package/lib/protected-state-surfaces.js +387 -0
- package/lib/release-readiness.js +2089 -0
- package/lib/reset.js +59 -45
- package/lib/review-adapter.js +68 -0
- package/lib/rules-sync.js +260 -0
- package/lib/runtime-health.js +241 -20
- package/lib/safety-config-renderer.js +268 -0
- package/lib/setup-action-log.js +1 -7
- package/lib/setup.js +27 -65
- package/lib/shell-utils.js +76 -6
- package/lib/skills-sync.js +330 -0
- package/lib/smart-status/scoring.js +17 -3
- package/lib/status/beads-snapshot.js +45 -2
- package/lib/status/presenter.js +169 -18
- package/lib/status/snapshot.js +186 -0
- package/lib/sync-backend.js +202 -0
- package/lib/untrusted-content.js +52 -0
- package/lib/upgrade-safety.js +199 -0
- package/lib/workflow/enforce-stage.js +296 -47
- package/lib/workflow/stage-transition.js +115 -0
- package/lib/workflow/stages.js +30 -6
- package/lib/workflow/state-manager.js +11 -22
- package/lib/workflow/state.js +23 -1
- package/lib/workflow-profiles.js +17 -5
- package/package.json +37 -35
- package/rules/documentation.md +19 -0
- package/rules/kernel-tracking.md +26 -0
- package/rules/security.md +22 -0
- package/rules/tdd.md +20 -0
- package/rules/workflow.md +27 -0
- package/scripts/auto-backing-issue.js +47 -0
- package/scripts/beads-context.sh +81 -57
- package/scripts/beads-upgrade-smoke.sh +24 -3
- package/scripts/bootstrap-windows-tools.sh +78 -0
- package/scripts/branch-protection.js +2 -3
- package/scripts/check-agents.js +34 -137
- package/scripts/commitlint.js +3 -1
- package/scripts/conflict-detect.sh +3 -0
- package/scripts/dep-guard.sh +22 -3
- package/scripts/file-index.sh +3 -0
- package/scripts/forge-team/lib/claim.sh +34 -18
- package/scripts/forge-team/lib/dashboard.sh +61 -86
- package/scripts/forge-team/lib/epic.sh +99 -263
- package/scripts/forge-team/lib/hooks.sh +26 -28
- package/scripts/forge-team/lib/identity.sh +4 -4
- package/scripts/forge-team/lib/sync-github.sh +49 -84
- package/scripts/forge-team/lib/verify.sh +93 -83
- package/scripts/forge-team/lib/workload.sh +41 -65
- package/scripts/forge-team/tests/claim.test.sh +25 -19
- package/scripts/forge-team/tests/dashboard.test.sh +31 -46
- package/scripts/forge-team/tests/epic.test.sh +52 -71
- package/scripts/forge-team/tests/hooks.test.sh +38 -50
- package/scripts/forge-team/tests/identity.test.sh +3 -3
- package/scripts/forge-team/tests/integration.test.sh +44 -66
- package/scripts/forge-team/tests/sync-github.test.sh +50 -83
- package/scripts/forge-team/tests/verify.test.sh +37 -46
- package/scripts/forge-team/tests/workflow-integration.test.sh +4 -4
- package/scripts/forge-team/tests/workload.test.sh +32 -66
- package/scripts/gen-command-manifest.js +153 -0
- package/scripts/gen-embedded-assets.mjs +129 -0
- package/scripts/install.ps1 +139 -0
- package/scripts/install.sh +268 -0
- package/scripts/lib/release-asset.mjs +84 -0
- package/scripts/parity-check.mjs +145 -0
- package/scripts/parity-check.test.mjs +58 -0
- package/scripts/pin-agentic-workflow-images.js +112 -0
- package/scripts/pr-coordinator.sh +3 -0
- package/scripts/preflight-sonar.eslint.config.mjs +44 -0
- package/scripts/preflight.sh +21 -94
- package/scripts/protected-state-check.js +104 -0
- package/scripts/smart-status.sh +60 -57
- package/scripts/spikes/config-race-bench.js +111 -0
- package/scripts/spikes/harness-capability-matrix.js +13 -0
- package/scripts/spikes/patch-anchor-stability-bench.js +125 -0
- package/scripts/spikes/protected-path-manifest.js +20 -0
- package/scripts/spikes/skill-auto-invoke-parity.js +292 -0
- package/scripts/sync-agent-skills.js +62 -0
- package/scripts/sync-utils.sh +3 -0
- package/scripts/test-ci-shard.js +13 -6
- package/scripts/test.js +95 -12
- package/skills/claim-safety/SKILL.md +102 -0
- package/skills/claim-safety/evals/evals.json +46 -0
- package/{.github/prompts/dev.prompt.md → skills/dev/SKILL.md} +44 -50
- package/skills/dev/evals/evals.json +50 -0
- package/skills/hermes-forge/SKILL.md +185 -0
- package/skills/hermes-forge/evals/evals.json +46 -0
- package/skills/issue-basics/SKILL.md +111 -0
- package/skills/issue-basics/evals/evals.json +46 -0
- package/skills/kernel/SKILL.md +166 -0
- package/skills/kernel/evals/evals.json +50 -0
- package/skills/memory/SKILL.md +102 -0
- package/skills/parallel-deep-research/SKILL.md +14 -11
- package/skills/parallel-deep-research/evals/evals.json +11 -27
- package/{.github/prompts/plan.prompt.md → skills/plan/SKILL.md} +132 -157
- package/skills/plan/evals/evals.json +42 -0
- package/skills/research/SKILL.md +195 -0
- package/skills/research/evals/evals.json +42 -0
- package/{.github/prompts/review.prompt.md → skills/review/SKILL.md} +98 -62
- package/skills/review/evals/evals.json +42 -0
- package/skills/rollback/SKILL.md +110 -0
- package/skills/rollback/evals/evals.json +46 -0
- package/skills/rollback/references/methods.md +204 -0
- package/{.cursor/commands/rollback.md → skills/rollback/references/workflow-integration.md} +10 -284
- package/skills/shepherd/SKILL.md +66 -0
- package/skills/shepherd/evals/evals.json +42 -0
- package/{.github/prompts/ship.prompt.md → skills/ship/SKILL.md} +81 -45
- package/skills/ship/evals/evals.json +42 -0
- package/skills/smith/SKILL.md +142 -0
- package/skills/smith/evals/evals.json +46 -0
- package/skills/smith/references/autonomy-and-gates.md +94 -0
- package/{.github/prompts/sonarcloud.prompt.md → skills/sonarcloud/SKILL.md} +14 -3
- package/skills/sonarcloud/evals/evals.json +46 -0
- package/skills/sonarcloud-analysis/SKILL.md +18 -13
- package/skills/sonarcloud-analysis/evals/evals.json +11 -15
- package/{.github/prompts/status.prompt.md → skills/status/SKILL.md} +20 -10
- package/skills/status/evals/evals.json +50 -0
- package/skills/triage-ready/SKILL.md +121 -0
- package/skills/triage-ready/evals/evals.json +42 -0
- package/{.github/prompts/validate.prompt.md → skills/validate/SKILL.md} +52 -29
- package/skills/validate/evals/evals.json +42 -0
- package/skills/verify/SKILL.md +299 -0
- package/skills/verify/evals/evals.json +50 -0
- package/.claude/commands/dev.md +0 -345
- package/.claude/commands/plan.md +0 -566
- package/.claude/commands/premerge.md +0 -186
- package/.claude/commands/research.md +0 -42
- package/.claude/commands/review.md +0 -451
- package/.claude/commands/rollback.md +0 -721
- package/.claude/commands/ship.md +0 -213
- package/.claude/commands/sonarcloud.md +0 -152
- package/.claude/commands/status.md +0 -90
- package/.claude/commands/validate.md +0 -288
- package/.claude/commands/verify.md +0 -269
- package/.claude/rules/workflow.md +0 -121
- package/.cline/workflows/dev.md +0 -342
- package/.cline/workflows/plan.md +0 -563
- package/.cline/workflows/premerge.md +0 -183
- package/.cline/workflows/research.md +0 -39
- package/.cline/workflows/review.md +0 -448
- package/.cline/workflows/rollback.md +0 -718
- package/.cline/workflows/ship.md +0 -210
- package/.cline/workflows/sonarcloud.md +0 -146
- package/.cline/workflows/status.md +0 -87
- package/.cline/workflows/validate.md +0 -285
- package/.cline/workflows/verify.md +0 -266
- package/.codex/config.toml +0 -11
- package/.codex/skills/dev/SKILL.md +0 -345
- package/.codex/skills/plan/SKILL.md +0 -566
- package/.codex/skills/premerge/SKILL.md +0 -186
- package/.codex/skills/research/SKILL.md +0 -42
- package/.codex/skills/review/SKILL.md +0 -451
- package/.codex/skills/rollback/SKILL.md +0 -721
- package/.codex/skills/ship/SKILL.md +0 -213
- package/.codex/skills/sonarcloud/SKILL.md +0 -149
- package/.codex/skills/status/SKILL.md +0 -90
- package/.codex/skills/validate/SKILL.md +0 -288
- package/.codex/skills/verify/SKILL.md +0 -269
- package/.cursor/commands/dev.md +0 -342
- package/.cursor/commands/plan.md +0 -563
- package/.cursor/commands/premerge.md +0 -183
- package/.cursor/commands/research.md +0 -39
- package/.cursor/commands/review.md +0 -448
- package/.cursor/commands/ship.md +0 -210
- package/.cursor/commands/sonarcloud.md +0 -146
- package/.cursor/commands/status.md +0 -87
- package/.cursor/commands/validate.md +0 -285
- package/.cursor/commands/verify.md +0 -266
- package/.cursorrules +0 -149
- package/.github/prompts/premerge.prompt.md +0 -188
- package/.github/prompts/research.prompt.md +0 -44
- package/.github/prompts/rollback.prompt.md +0 -723
- package/.github/prompts/verify.prompt.md +0 -271
- package/.github/workflows/beads-to-github.yml +0 -89
- package/.github/workflows/github-to-beads.yml +0 -100
- package/.kilocode/workflows/dev.md +0 -346
- package/.kilocode/workflows/plan.md +0 -567
- package/.kilocode/workflows/premerge.md +0 -187
- package/.kilocode/workflows/research.md +0 -43
- package/.kilocode/workflows/review.md +0 -452
- package/.kilocode/workflows/rollback.md +0 -722
- package/.kilocode/workflows/ship.md +0 -214
- package/.kilocode/workflows/sonarcloud.md +0 -150
- package/.kilocode/workflows/status.md +0 -91
- package/.kilocode/workflows/validate.md +0 -289
- package/.kilocode/workflows/verify.md +0 -270
- package/.opencode/commands/dev.md +0 -345
- package/.opencode/commands/plan.md +0 -566
- package/.opencode/commands/premerge.md +0 -186
- package/.opencode/commands/research.md +0 -42
- package/.opencode/commands/review.md +0 -451
- package/.opencode/commands/rollback.md +0 -721
- package/.opencode/commands/ship.md +0 -213
- package/.opencode/commands/sonarcloud.md +0 -149
- package/.opencode/commands/status.md +0 -90
- package/.opencode/commands/validate.md +0 -288
- package/.opencode/commands/verify.md +0 -269
- package/.roo/commands/dev.md +0 -346
- package/.roo/commands/plan.md +0 -567
- package/.roo/commands/premerge.md +0 -187
- package/.roo/commands/research.md +0 -43
- package/.roo/commands/review.md +0 -452
- package/.roo/commands/rollback.md +0 -722
- package/.roo/commands/ship.md +0 -214
- package/.roo/commands/sonarcloud.md +0 -150
- package/.roo/commands/status.md +0 -91
- package/.roo/commands/validate.md +0 -289
- package/.roo/commands/verify.md +0 -270
- package/docs/BEADS_GITHUB_SYNC.md +0 -281
- package/docs/GREPTILE_SETUP.md +0 -400
- package/docs/MANUAL_REVIEW_GUIDE.md +0 -106
- package/docs/SETUP.md +0 -663
- package/docs/VALIDATION.md +0 -363
- package/lib/agents/cline.plugin.json +0 -29
- package/lib/agents/copilot.plugin.json +0 -24
- package/lib/agents/kilocode.plugin.json +0 -22
- package/lib/agents/opencode.plugin.json +0 -23
- package/lib/agents/roo.plugin.json +0 -30
- package/lib/beads-bootstrap.js +0 -225
- package/lib/beads-health-check.js +0 -188
- package/lib/commands/commands-reset.js +0 -147
- package/opencode.json +0 -67
- package/scripts/beads-context.test.js +0 -584
- package/scripts/github-beads-sync/comment.mjs +0 -64
- package/scripts/github-beads-sync/config.mjs +0 -148
- package/scripts/github-beads-sync/github-api.mjs +0 -131
- package/scripts/github-beads-sync/index.mjs +0 -356
- package/scripts/github-beads-sync/label-mapper.mjs +0 -54
- package/scripts/github-beads-sync/mapping.mjs +0 -132
- package/scripts/github-beads-sync/reverse-sync-cli.mjs +0 -31
- package/scripts/github-beads-sync/reverse-sync.mjs +0 -162
- package/scripts/github-beads-sync/run-bd.mjs +0 -161
- package/scripts/github-beads-sync/sanitize.mjs +0 -121
- package/scripts/github-beads-sync.config.json +0 -26
- package/scripts/sync-commands.js +0 -600
package/scripts/test.js
CHANGED
|
@@ -23,15 +23,9 @@ const PACKAGE_LEVEL_PATHS = new Set([
|
|
|
23
23
|
]);
|
|
24
24
|
|
|
25
25
|
const KNOWN_TARGETABLE_PREFIXES = [
|
|
26
|
-
'.claude/commands/',
|
|
27
26
|
'.cursor/',
|
|
28
|
-
'.
|
|
29
|
-
'.roo/',
|
|
30
|
-
'.kilocode/',
|
|
31
|
-
'.opencode/',
|
|
32
|
-
'.codex/skills/',
|
|
27
|
+
'.codex/',
|
|
33
28
|
'.forge/',
|
|
34
|
-
'.github/prompts/',
|
|
35
29
|
'.github/agentic-workflows/',
|
|
36
30
|
'.github/workflows/',
|
|
37
31
|
'test/',
|
|
@@ -45,6 +39,65 @@ const ALWAYS_RUN_RISK_TEST_TARGETS = [
|
|
|
45
39
|
|
|
46
40
|
const isWindows = process.platform === 'win32';
|
|
47
41
|
|
|
42
|
+
// Wall-clock ceiling for a single spawned test lane. Bun's per-test `--timeout`
|
|
43
|
+
// races a JS timer and CANNOT preempt a synchronous blocking spawn (e.g. an
|
|
44
|
+
// `execFileSync` of git/bash that hangs during git mid-push state). Without this
|
|
45
|
+
// ceiling such a hang blocks `forge push` indefinitely (observed ~50 min on
|
|
46
|
+
// Windows, issue 8aef79e8). This kills the lane process so the push fails fast
|
|
47
|
+
// instead of hanging forever.
|
|
48
|
+
//
|
|
49
|
+
// The default is a practical 5 minutes for a single TARGETED lane: those run a
|
|
50
|
+
// small, mapped subset that completes in seconds, so 5 min is comfortably a
|
|
51
|
+
// fail-fast ceiling (not the old 15-min wait that made `forge push` feel
|
|
52
|
+
// wedged). Raise it with FORGE_TEST_TIMEOUT_MS for slow machines.
|
|
53
|
+
const DEFAULT_TEST_COMMAND_TIMEOUT_MS = 5 * 60 * 1000;
|
|
54
|
+
|
|
55
|
+
// Wall-clock budget for the FULL-SUITE fallback lane (`scripts/test-full-suite.js`),
|
|
56
|
+
// which runs on package-level, unmapped, or zero-resolved changes. Unlike a
|
|
57
|
+
// targeted lane, a healthy full suite legitimately takes 5-10 min, so the 5-min
|
|
58
|
+
// fail-fast ceiling would kill a good-but-slow full run. Kept at 10 min to stay
|
|
59
|
+
// aligned with the local-validation budget (VALIDATION_COMMAND_TIMEOUT_MS = 600000
|
|
60
|
+
// in lib/commands/validate.js and its "long enough subprocess timeout for the
|
|
61
|
+
// full local suite" regression test). FORGE_TEST_TIMEOUT_MS still overrides.
|
|
62
|
+
const DEFAULT_FULL_SUITE_TIMEOUT_MS = 10 * 60 * 1000;
|
|
63
|
+
|
|
64
|
+
// Conventional shell exit code for a command terminated by a timeout.
|
|
65
|
+
const TIMEOUT_EXIT_CODE = 124;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Reads and validates the FORGE_TEST_TIMEOUT_MS override, if any.
|
|
69
|
+
*
|
|
70
|
+
* @param {NodeJS.ProcessEnv} env Environment to read the override from.
|
|
71
|
+
* @returns {number|null} The positive integer override, or null when unset/invalid.
|
|
72
|
+
*/
|
|
73
|
+
function readTimeoutOverride(env) {
|
|
74
|
+
const parsed = Number.parseInt(env.FORGE_TEST_TIMEOUT_MS, 10);
|
|
75
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Resolves the wall-clock timeout for a targeted/e2e/edge-case lane, honoring
|
|
80
|
+
* FORGE_TEST_TIMEOUT_MS.
|
|
81
|
+
*
|
|
82
|
+
* @param {NodeJS.ProcessEnv} [env=process.env] Environment to read the override from.
|
|
83
|
+
* @returns {number} Timeout in milliseconds (defaults to DEFAULT_TEST_COMMAND_TIMEOUT_MS).
|
|
84
|
+
*/
|
|
85
|
+
function resolveCommandTimeoutMs(env = process.env) {
|
|
86
|
+
return readTimeoutOverride(env) ?? DEFAULT_TEST_COMMAND_TIMEOUT_MS;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Resolves the wall-clock budget for the full-suite fallback lane. An explicit
|
|
91
|
+
* FORGE_TEST_TIMEOUT_MS override wins; otherwise it uses the larger,
|
|
92
|
+
* validation-aligned budget so a healthy-but-slow full run is not failed fast.
|
|
93
|
+
*
|
|
94
|
+
* @param {NodeJS.ProcessEnv} [env=process.env] Environment to read the override from.
|
|
95
|
+
* @returns {number} Timeout in milliseconds (defaults to DEFAULT_FULL_SUITE_TIMEOUT_MS).
|
|
96
|
+
*/
|
|
97
|
+
function resolveFullSuiteTimeoutMs(env = process.env) {
|
|
98
|
+
return readTimeoutOverride(env) ?? DEFAULT_FULL_SUITE_TIMEOUT_MS;
|
|
99
|
+
}
|
|
100
|
+
|
|
48
101
|
/**
|
|
49
102
|
* @typedef {Object} TestExecutionPlan
|
|
50
103
|
* @property {string[]} changedFiles
|
|
@@ -101,7 +154,19 @@ function isKnownTargetablePath(file) {
|
|
|
101
154
|
return true;
|
|
102
155
|
}
|
|
103
156
|
|
|
104
|
-
if (file.
|
|
157
|
+
if (file === 'README.md'
|
|
158
|
+
|| file === 'bin/forge.js'
|
|
159
|
+
|| file === 'QUICKSTART.md'
|
|
160
|
+
|| file === 'CHANGELOG.md'
|
|
161
|
+
|| file === 'AGENTS.md'
|
|
162
|
+
|| file === 'DEVELOPMENT.md'
|
|
163
|
+
|| file === 'docs/INDEX.md'
|
|
164
|
+
|| file === 'docs/PROJECT_DESIGN.md'
|
|
165
|
+
|| file.startsWith('docs/forge/')
|
|
166
|
+
|| file.startsWith('docs/guides/')
|
|
167
|
+
|| file.startsWith('docs/plans/')
|
|
168
|
+
|| file.startsWith('docs/reference/')
|
|
169
|
+
|| file.startsWith('docs/work/')) {
|
|
105
170
|
return true;
|
|
106
171
|
}
|
|
107
172
|
|
|
@@ -257,6 +322,15 @@ function runCommand(command, args, options = {}, spawnSync = defaultSpawnSync) {
|
|
|
257
322
|
});
|
|
258
323
|
|
|
259
324
|
if (result.error) {
|
|
325
|
+
if (result.error.code === 'ETIMEDOUT') {
|
|
326
|
+
console.error('');
|
|
327
|
+
console.error('Test lane exceeded its wall-clock ceiling and was terminated.');
|
|
328
|
+
console.error('A single test likely hung (e.g. a spawned git/bash call that never returns).');
|
|
329
|
+
console.error('Adjust the ceiling with FORGE_TEST_TIMEOUT_MS. Failing the run instead of');
|
|
330
|
+
console.error('blocking the push. See issue 8aef79e8.');
|
|
331
|
+
console.error('');
|
|
332
|
+
return TIMEOUT_EXIT_CODE;
|
|
333
|
+
}
|
|
260
334
|
throw result.error;
|
|
261
335
|
}
|
|
262
336
|
|
|
@@ -276,30 +350,35 @@ function runTestExecutionPlan(plan, deps = {}) {
|
|
|
276
350
|
const env = deps.env || stripGitHookEnv(process.env);
|
|
277
351
|
const bunCommand = deps.bunCommand || env.BUN_EXE || process.env.BUN_EXE || 'bun';
|
|
278
352
|
const label = deps.label || 'tests';
|
|
353
|
+
const timeout = resolveCommandTimeoutMs(env);
|
|
354
|
+
const laneOptions = { env, killSignal: 'SIGKILL', timeout };
|
|
355
|
+
// The full-suite fallback gets a larger, validation-aligned budget so a
|
|
356
|
+
// healthy-but-slow full run is not failed fast by the targeted-lane ceiling.
|
|
357
|
+
const fullSuiteOptions = { env, killSignal: 'SIGKILL', timeout: resolveFullSuiteTimeoutMs(env) };
|
|
279
358
|
|
|
280
359
|
console.log(`Running ${label} (${pkgManager})...`);
|
|
281
360
|
|
|
282
361
|
try {
|
|
283
362
|
if (plan.runFullSuite) {
|
|
284
363
|
console.log(` Mode: full suite (${plan.reason})`);
|
|
285
|
-
const status = runCommand('node', ['scripts/test-full-suite.js'],
|
|
364
|
+
const status = runCommand('node', ['scripts/test-full-suite.js'], fullSuiteOptions, spawnSync);
|
|
286
365
|
if (status !== 0) return status;
|
|
287
366
|
} else if (plan.testTargets.length > 0) {
|
|
288
367
|
console.log(` Mode: targeted (${plan.testTargets.length} test file${plan.testTargets.length === 1 ? '' : 's'})`);
|
|
289
368
|
const command = pkgManager === 'bun' ? bunCommand : pkgManager;
|
|
290
|
-
const status = runCommand(command, ['run', 'test', ...plan.testTargets],
|
|
369
|
+
const status = runCommand(command, ['run', 'test', ...plan.testTargets], laneOptions, spawnSync);
|
|
291
370
|
if (status !== 0) return status;
|
|
292
371
|
}
|
|
293
372
|
|
|
294
373
|
if (plan.runE2E) {
|
|
295
374
|
console.log(' Extra: running affected e2e tests');
|
|
296
|
-
const status = runCommand(bunCommand, ['test', 'test/e2e/'],
|
|
375
|
+
const status = runCommand(bunCommand, ['test', '--timeout', '15000', 'test/e2e/'], laneOptions, spawnSync);
|
|
297
376
|
if (status !== 0) return status;
|
|
298
377
|
}
|
|
299
378
|
|
|
300
379
|
if (!plan.runFullSuite && plan.runTestEnv) {
|
|
301
380
|
console.log(' Extra: running affected edge-case tests');
|
|
302
|
-
const status = runCommand(bunCommand, ['test', 'test-env/'],
|
|
381
|
+
const status = runCommand(bunCommand, ['test', '--timeout', '15000', 'test-env/'], laneOptions, spawnSync);
|
|
303
382
|
if (status !== 0) return status;
|
|
304
383
|
}
|
|
305
384
|
|
|
@@ -348,9 +427,13 @@ if (require.main === module) {
|
|
|
348
427
|
|
|
349
428
|
module.exports = {
|
|
350
429
|
ALWAYS_RUN_RISK_TEST_TARGETS,
|
|
430
|
+
DEFAULT_FULL_SUITE_TIMEOUT_MS,
|
|
431
|
+
DEFAULT_TEST_COMMAND_TIMEOUT_MS,
|
|
351
432
|
buildTestExecutionPlan,
|
|
352
433
|
classifyPushTests,
|
|
353
434
|
detectPackageManager,
|
|
435
|
+
resolveCommandTimeoutMs,
|
|
436
|
+
resolveFullSuiteTimeoutMs,
|
|
354
437
|
runLocalValidationTests,
|
|
355
438
|
runPrePushTests,
|
|
356
439
|
runTestExecutionPlan,
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: claim-safety
|
|
3
|
+
description: >
|
|
4
|
+
Claim a Forge issue and then PROVE you hold the live lease before you touch it, using `forge
|
|
5
|
+
issue owns <id>` (exit 0 iff you hold the single unexpired lease). Use this whenever winning
|
|
6
|
+
the claim matters: right after `forge claim`, before you `dev`/edit/`close`/`release` a
|
|
7
|
+
claimed issue, when two agents or a subagent fan-out contend for the same work, or before
|
|
8
|
+
any irreversible step. A claim's `ok:true` does NOT prove you won — duplicate replays return
|
|
9
|
+
it and expired leases get reclaimed; only `owns` proves it, so re-verify before
|
|
10
|
+
close/release. Trigger on "claim this issue safely", "did I actually win the lease",
|
|
11
|
+
"verify/prove ownership", "claim conflict", "two agents grabbed the same issue", "check I
|
|
12
|
+
still own it before closing", or before ANY mutation of a claimed issue. NOT for plain
|
|
13
|
+
single-issue create/update/close/comment with no ownership question (that is issue-basics),
|
|
14
|
+
and NOT for read-only selecting or ranking the next ready issue without claiming (that is
|
|
15
|
+
triage-ready).
|
|
16
|
+
allowed-tools: Read, Bash(forge:*)
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Claim safety — claim, then prove you own the lease
|
|
20
|
+
|
|
21
|
+
Claiming is not owning. The Forge kernel keys a claim's idempotency on
|
|
22
|
+
`claim.create:<issue_id>:<actor>`, so a **same-key duplicate replay returns
|
|
23
|
+
`ok:true`** echoing the *current* call's `claim_id`. A genuine cross-actor
|
|
24
|
+
conflict returns `ok:false` (the partial-UNIQUE active-lease index guarantees one
|
|
25
|
+
lease) — but `ok:true` **alone does not prove sole ownership**. A live lease can
|
|
26
|
+
also be **reclaimed on expiry** (an expired lease is superseded by the next
|
|
27
|
+
claimant). Therefore every worker MUST verify ownership before mutating a claimed
|
|
28
|
+
issue, and RE-verify before `close`/`release`.
|
|
29
|
+
|
|
30
|
+
This is a reusable, standalone procedure: any skill or agent that mutates a
|
|
31
|
+
claimed issue embeds it (it is NOT folded into one orchestrator).
|
|
32
|
+
|
|
33
|
+
## The verification primitive
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
forge issue owns <id> # exit 0 iff YOU hold the live lease; non-zero otherwise
|
|
37
|
+
forge issue owns <id> --json # { ok:true, data:{ owned, claimed_by, expired, actor, expires_at } }
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`owns` resolves your actor the same way the kernel does — `FORGE_ACTOR` →
|
|
41
|
+
`FORGE_SESSION_ID` → default `forge` — then reports `owned:true` iff you hold the
|
|
42
|
+
**single active claim** AND that lease **has not expired**. It exits `0` when you
|
|
43
|
+
own it and non-zero (conflict, code 4) when you do not, with a clear "you do not
|
|
44
|
+
own the lease for `<id>` (held by `<actor>`)" message. It is a strict READ — it
|
|
45
|
+
never mutates kernel state. (`data.claimed_by` is lease-derived; there is no
|
|
46
|
+
`claims` command.)
|
|
47
|
+
|
|
48
|
+
## Procedure
|
|
49
|
+
|
|
50
|
+
1. **Select** work — `forge issue ready --json` (see the `triage-ready` skill).
|
|
51
|
+
Never claim epics/decisions or defer-windowed items.
|
|
52
|
+
2. **Claim** — `FORGE_ACTOR=<your-actor> forge claim <id>`. Always run under a
|
|
53
|
+
distinct actor so a losing claim reaches the conflict guard instead of
|
|
54
|
+
collapsing to a shared-actor duplicate.
|
|
55
|
+
3. **Prove ownership BEFORE working** — `forge issue owns <id>`.
|
|
56
|
+
- **exit 0 (OWNED)** → the lease is yours; proceed to work.
|
|
57
|
+
- **non-zero (NOT OWNED)** → you lost the race, or your claim collapsed to a
|
|
58
|
+
foreign/duplicate-collapsed claim. Do NOT work the issue. **Reselect** via
|
|
59
|
+
`forge issue ready --json` and start over at step 1.
|
|
60
|
+
4. **Work** the issue (`dev`/edit/etc.).
|
|
61
|
+
5. **RE-verify before `close`/`release`** — a live lease can be reclaimed on
|
|
62
|
+
expiry while you worked. Run `forge issue owns <id>` again:
|
|
63
|
+
- **OWNED** → `forge release check --target <release-ref> --json` (release-readiness; omit `--target` to use the project default), then
|
|
64
|
+
`forge close <id> --reason "…"` or `forge release <id>`.
|
|
65
|
+
- **NOT OWNED** → the lease was reclaimed (likely expired). Do NOT close/
|
|
66
|
+
release someone else's lease; reselect and, if the work is still needed,
|
|
67
|
+
re-claim and reconcile.
|
|
68
|
+
|
|
69
|
+
## Contract (what each result means)
|
|
70
|
+
|
|
71
|
+
| `forge claim` result | Meaning | Action |
|
|
72
|
+
|----------------------|---------|--------|
|
|
73
|
+
| `ok:false` (conflict, code 4) | A live lease is held by another actor | Reselect (`ready`) |
|
|
74
|
+
| `ok:true` | Provisionally yours — **not proof** (duplicate replays also return ok:true) | **Run `forge issue owns <id>`** |
|
|
75
|
+
|
|
76
|
+
| `forge issue owns` | Meaning | Action |
|
|
77
|
+
|--------------------|---------|--------|
|
|
78
|
+
| exit 0, `owned:true` | You hold the live, unexpired lease | Work / close / release |
|
|
79
|
+
| non-zero, `owned:false` | Someone else holds it, or your lease expired | Reselect; never mutate |
|
|
80
|
+
|
|
81
|
+
## Fork points
|
|
82
|
+
|
|
83
|
+
- **Actor source** — how `<your-actor>` is derived (`FORGE_ACTOR` explicit id →
|
|
84
|
+
`FORGE_SESSION_ID` → default `forge`). Use a distinct per-agent actor so
|
|
85
|
+
contending claims reach the conflict guard rather than collapsing to a duplicate.
|
|
86
|
+
- **Expiry / lease TTL** — whether claims carry an `expires_at` and how long;
|
|
87
|
+
`owns` treats an expired lease as NOT owned (it can be reclaimed).
|
|
88
|
+
- **Re-verify cadence** — verify after claim and again before `close`/`release`;
|
|
89
|
+
a longer task may re-verify more often (e.g. before each irreversible step).
|
|
90
|
+
- **Reselection policy** — on NOT-OWNED, how the next item is chosen (ranking /
|
|
91
|
+
filters live in the `triage-ready` skill).
|
|
92
|
+
- **Fail-closed posture** — with no usable clock/state, treat ownership as NOT
|
|
93
|
+
proven (mirror the readiness model's "no usable clock ⇒ not workable").
|
|
94
|
+
|
|
95
|
+
## Reliability notes
|
|
96
|
+
|
|
97
|
+
- A genuine cross-actor conflict returns `ok:false` — there is no phantom
|
|
98
|
+
`ok:true`-on-conflict. The real hazards are (a) a duplicate replay's `ok:true`
|
|
99
|
+
and (b) expiry-driven reclaim. `owns` closes both.
|
|
100
|
+
- Full multi-agent safety depends on the actor-identity kernel fix (distinct
|
|
101
|
+
actors per agent, kernel `d71a824b`): without distinct actors, two agents
|
|
102
|
+
share one idempotency key and `owns` cannot tell them apart.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"query": "I just ran forge claim on forge-abc — how do I make sure the lease is really mine before I start editing?",
|
|
4
|
+
"should_trigger": true
|
|
5
|
+
},
|
|
6
|
+
{
|
|
7
|
+
"query": "Two of my agents may have grabbed the same issue at once — how do I tell which one actually holds it?",
|
|
8
|
+
"should_trigger": true
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"query": "Before I close this ticket, confirm nobody reclaimed it while I was working.",
|
|
12
|
+
"should_trigger": true
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"query": "My claim came back ok:true but I'm not convinced I won the race. Can I trust that?",
|
|
16
|
+
"should_trigger": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"query": "Prove I own forge-42 before the subagent starts mutating it.",
|
|
20
|
+
"should_trigger": true
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"query": "The lease might have expired mid-task — check I still own it before I release.",
|
|
24
|
+
"should_trigger": true
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"query": "What's the next ready issue I should pick up?",
|
|
28
|
+
"should_trigger": false
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"query": "Create a feature issue titled 'Add CSV export'.",
|
|
32
|
+
"should_trigger": false
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"query": "Close forge-19 with reason 'shipped in PR 88'.",
|
|
36
|
+
"should_trigger": false
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"query": "Take forge-30 all the way through to a PR.",
|
|
40
|
+
"should_trigger": false
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"query": "Implement the failing auth tests for this task.",
|
|
44
|
+
"should_trigger": false
|
|
45
|
+
}
|
|
46
|
+
]
|
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dev
|
|
3
|
-
description:
|
|
4
|
-
|
|
3
|
+
description: >
|
|
4
|
+
Forge DEV stage — implement an already-planned /plan task list into committed, test-backed
|
|
5
|
+
code. Reads tasks.md + plan.md, then drives each task through a subagent TDD loop
|
|
6
|
+
(implementer → spec-compliance reviewer → code-quality reviewer) with RED-GREEN-REFACTOR,
|
|
7
|
+
HARD-GATE evidence checks, and a spec-gap decision score. Use when a plan and task list
|
|
8
|
+
already exist and it is time to implement — triggers: "/dev", "start the dev stage", "build
|
|
9
|
+
the tasks", "implement tasks.md test-first", "run the implementer/reviewer TDD loop", "write
|
|
10
|
+
the code for the planned tasks one by one", "work through the task list with subagents".
|
|
11
|
+
Per-task coding ONLY. Do NOT use for creating the design doc or task list (that is plan),
|
|
12
|
+
for the post-build type-check/lint/security/test gate (validate), for pushing the branch or
|
|
13
|
+
opening the PR (ship), for addressing PR review feedback (review), or for orchestrating
|
|
14
|
+
several stages / taking an issue end-to-end to a merged PR (smith).
|
|
15
|
+
allowed-tools: Bash, Read, Write, Edit, Grep, Glob
|
|
5
16
|
---
|
|
6
17
|
|
|
7
18
|
Implement each task from the /plan task list using a subagent-driven loop: implementer → spec compliance reviewer → code quality reviewer per task.
|
|
8
19
|
|
|
9
20
|
# Dev
|
|
10
21
|
|
|
11
|
-
This
|
|
22
|
+
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.
|
|
12
23
|
|
|
13
24
|
## Usage
|
|
14
25
|
|
|
@@ -24,19 +35,19 @@ This command reads the task list created by `/plan` and implements each task usi
|
|
|
24
35
|
|
|
25
36
|
```bash
|
|
26
37
|
# Find task list and design doc
|
|
27
|
-
ls docs/
|
|
38
|
+
ls docs/work/
|
|
28
39
|
```
|
|
29
40
|
|
|
30
41
|
Read:
|
|
31
|
-
- **Task list**: `docs/
|
|
32
|
-
- **Design doc**: `docs/
|
|
42
|
+
- **Task list**: `docs/work/YYYY-MM-DD-<slug>/tasks.md` — extract ALL task text upfront
|
|
43
|
+
- **Design doc**: `docs/work/YYYY-MM-DD-<slug>/plan.md` — including ambiguity policy section
|
|
33
44
|
|
|
34
45
|
### Step 2: Create decisions log
|
|
35
46
|
|
|
36
47
|
Create an empty decisions log at the start of every /dev session:
|
|
37
48
|
|
|
38
49
|
```bash
|
|
39
|
-
# docs/
|
|
50
|
+
# docs/work/YYYY-MM-DD-<slug>/decisions.md
|
|
40
51
|
```
|
|
41
52
|
|
|
42
53
|
Format for each entry:
|
|
@@ -74,8 +85,8 @@ Before starting the per-task loop, check for cross-developer conflicts:
|
|
|
74
85
|
# Auto-sync to get latest team state (non-blocking)
|
|
75
86
|
forge sync || true
|
|
76
87
|
|
|
77
|
-
# Check for conflicts with the current
|
|
78
|
-
bash scripts/conflict-detect.sh --issue <
|
|
88
|
+
# Check for conflicts with the current Forge issue
|
|
89
|
+
bash scripts/conflict-detect.sh --issue <forge-id>
|
|
79
90
|
```
|
|
80
91
|
|
|
81
92
|
If exit code 2 (validation error): show error message, abort — do not show conflict prompt.
|
|
@@ -84,7 +95,7 @@ If exit code 1 (conflicts found):
|
|
|
84
95
|
- Display the conflict output to the developer
|
|
85
96
|
- Ask: "Other developers are working in overlapping areas. Proceed anyway? (y/n)"
|
|
86
97
|
- If `n`: exit cleanly, no side effects
|
|
87
|
-
- If `y`: log override via `
|
|
98
|
+
- If `y`: log override via `forge comment <id> "Conflict override: proceeding despite overlap with <conflicting-issues>"`, then continue to Per-Task Loop
|
|
88
99
|
- Audit: record conflict override per OWASP A09
|
|
89
100
|
|
|
90
101
|
If exit code 0: proceed silently to Per-Task Loop.
|
|
@@ -194,7 +205,7 @@ Reviewer checks:
|
|
|
194
205
|
- Structure: functions not too long, proper separation of concerns
|
|
195
206
|
- Duplication: no copy-paste that could be extracted
|
|
196
207
|
- Test coverage: tests cover happy path and at least one error path
|
|
197
|
-
- No magic numbers, no commented-out code, no TODO without a
|
|
208
|
+
- No magic numbers, no commented-out code, no TODO without a Forge issue
|
|
198
209
|
|
|
199
210
|
If quality issues found: implementer fixes → re-review → repeat until ✅
|
|
200
211
|
|
|
@@ -213,7 +224,7 @@ Do NOT mark task complete or move to next task until ALL confirmed in this sessi
|
|
|
213
224
|
4. Run it fresh — show the actual output. "Last run was fine" is not evidence.
|
|
214
225
|
5. Tests run fresh — actual output shows passing.
|
|
215
226
|
6. Implementer has committed (git log shows the commit).
|
|
216
|
-
7. `
|
|
227
|
+
7. Progress recorded on the Forge issue — `forge comment <id> "task <task-num>/<total> done: <title> (<commit-sha>, <test-count> tests, <gate-count> gates)"` ran successfully (exit code 0). The Forge comment is the kernel-native record. If the recording command errors: STOP, show the error, do not proceed to the next task.
|
|
217
228
|
|
|
218
229
|
Forbidden phrases (these are not evidence):
|
|
219
230
|
- "should pass"
|
|
@@ -274,15 +285,18 @@ Do NOT declare /dev complete until:
|
|
|
274
285
|
</HARD-GATE>
|
|
275
286
|
```
|
|
276
287
|
|
|
277
|
-
###
|
|
288
|
+
### Record stage transition
|
|
278
289
|
|
|
279
290
|
```bash
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
291
|
+
# Confirm the issue carries design + acceptance context.
|
|
292
|
+
forge issue show <id>
|
|
293
|
+
|
|
294
|
+
# Record the dev→validate transition kernel-natively (Stage:/Summary:/Decisions:/Artifacts:/Next: envelope).
|
|
295
|
+
forge comment <id> "Stage: dev complete → ready for validate
|
|
296
|
+
Summary: <N tasks done, M decision gates fired>
|
|
297
|
+
Decisions: <key spec gaps and how they were resolved>
|
|
298
|
+
Artifacts: <changed source files and test files>
|
|
299
|
+
Next: <validation priorities — lint issues, type concerns>"
|
|
286
300
|
```
|
|
287
301
|
|
|
288
302
|
---
|
|
@@ -299,43 +313,23 @@ Document the gate count in the final commit message.
|
|
|
299
313
|
|
|
300
314
|
---
|
|
301
315
|
|
|
302
|
-
##
|
|
316
|
+
## Dynamic Output
|
|
303
317
|
|
|
304
|
-
|
|
305
|
-
✓ Task 1: Types and interfaces — COMPLETE
|
|
306
|
-
Spec: ✅ Quality: ✅ Tests: 4/4 passing Commit: abc1234
|
|
307
|
-
Decision gates: 0
|
|
308
|
-
|
|
309
|
-
✓ Task 2: Validation logic — COMPLETE
|
|
310
|
-
Spec: ✅ Quality: ✅ Tests: 8/8 passing Commit: def5678
|
|
311
|
-
Decision gates: 1 (PROCEED, score 2 — documented in decisions log)
|
|
312
|
-
|
|
313
|
-
✓ Task 3: API endpoint — COMPLETE
|
|
314
|
-
Spec: ✅ Quality: ✅ Tests: 6/6 passing Commit: ghi9012
|
|
315
|
-
Decision gates: 0
|
|
316
|
-
|
|
317
|
-
✓ Final code review: ✅ (coherent, consistent, correctly integrated)
|
|
318
|
+
The completion summary is generated from the live task list, decisions log, Forge issue state, commits, and validation output at runtime. Do not copy a static example into this skill file; run `/dev` to view the current task/status summary.
|
|
318
319
|
|
|
319
|
-
|
|
320
|
-
- Decision 1: RESOLVED (score 2, proceeded with conservative choice)
|
|
321
|
-
- Decision gates fired: 1 (plan quality: Good)
|
|
322
|
-
|
|
323
|
-
✓ Beads updated: forge-xyz → implementation complete
|
|
320
|
+
## Integration with Workflow
|
|
324
321
|
|
|
325
|
-
Ready for /validate
|
|
326
322
|
```
|
|
323
|
+
Utility: /status -> Understand current context before starting
|
|
327
324
|
|
|
328
|
-
|
|
325
|
+
Default template:
|
|
326
|
+
/dev -> Implement each task with subagent-driven TDD (you are here)
|
|
327
|
+
/validate -> Type check, lint, tests, security
|
|
328
|
+
/ship -> Push + create PR
|
|
329
|
+
/review -> Address PR feedback
|
|
330
|
+
/verify -> Post-merge health check
|
|
329
331
|
|
|
330
|
-
|
|
331
|
-
Utility: /status → Understand current context before starting
|
|
332
|
-
Stage 1: /plan → Design intent → research → branch + worktree + task list
|
|
333
|
-
Stage 2: /dev → Implement each task with subagent-driven TDD (you are here)
|
|
334
|
-
Stage 3: /validate → Type check, lint, tests, security — all fresh output
|
|
335
|
-
Stage 4: /ship → Push + create PR
|
|
336
|
-
Stage 5: /review → Address GitHub Actions, Greptile, SonarCloud
|
|
337
|
-
Stage 6: /premerge → Update docs, hand off PR to user
|
|
338
|
-
Stage 7: /verify → Post-merge CI check on main
|
|
332
|
+
Pre-merge gate: doc updates + CI-green checkpoint embedded in /ship and /review (not a separate stage).
|
|
339
333
|
```
|
|
340
334
|
|
|
341
335
|
## Tips
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"query": "/dev",
|
|
4
|
+
"should_trigger": true
|
|
5
|
+
},
|
|
6
|
+
{
|
|
7
|
+
"query": "The plan and task list are done — start implementing the tasks one at a time, tests first.",
|
|
8
|
+
"should_trigger": true
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"query": "Run the implementer then the spec and quality reviewer subagents over each task in tasks.md",
|
|
12
|
+
"should_trigger": true
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"query": "Implement the already-planned tasks one at a time, red-green-refactor each",
|
|
16
|
+
"should_trigger": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"query": "Time to write the code for the planned tasks and TDD each one in this worktree",
|
|
20
|
+
"should_trigger": true
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"query": "Work through tasks.md subagent by subagent until every task is committed and reviewed",
|
|
24
|
+
"should_trigger": true
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"query": "Set up the branch, worktree, and TDD task list for this new feature",
|
|
28
|
+
"should_trigger": false
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"query": "Type-check, lint, and run the full test suite before I open the PR",
|
|
32
|
+
"should_trigger": false
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"query": "Push the validated branch and open the pull request",
|
|
36
|
+
"should_trigger": false
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"query": "The PR has open review threads from the bots — fix each finding, reply, and mark them resolved.",
|
|
40
|
+
"should_trigger": false
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"query": "Grab the next ready issue and drive it all the way to a merged PR",
|
|
44
|
+
"should_trigger": false
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"query": "Which workflow stage am I on and what work is in flight right now?",
|
|
48
|
+
"should_trigger": false
|
|
49
|
+
}
|
|
50
|
+
]
|