forge-workflow 0.0.9 → 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 +151 -61
- package/CHANGELOG.md +681 -0
- package/CLAUDE.md +9 -106
- 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 +466 -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/{TOOLCHAIN.md → forge/TOOLCHAIN.md} +56 -47
- 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/reference/TOOLCHAIN.md +658 -0
- 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 +225 -28
- package/lib/beads-sync-scaffold.js +36 -107
- package/lib/codex-skills.js +51 -1
- package/lib/commands/_issue.js +744 -70
- 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 +66 -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 +22 -2
- 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 +851 -979
- 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 +329 -11
- package/lib/commands/sync.js +34 -46
- package/lib/commands/team.js +15 -2
- package/lib/commands/test.js +58 -7
- package/lib/commands/update.js +2 -2
- package/lib/commands/upgrade.js +47 -0
- package/lib/commands/validate.js +56 -25
- package/lib/commands/worktree.js +308 -128
- 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 +184 -0
- package/lib/deprecated-sync-cleanup.js +362 -0
- package/lib/detect-agent.js +2 -28
- package/lib/detect-worktree.js +42 -17
- 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 +697 -0
- 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/issue-sync/authority.js +100 -0
- package/lib/issue-sync/github-pull.js +184 -0
- package/lib/issue-sync/import-primitives.js +98 -0
- package/lib/issue-sync/legacy-link-bridge.js +436 -0
- package/lib/issue-sync/link-store.js +292 -0
- package/lib/issue-sync/project-github.js +123 -0
- package/lib/issue-sync/reconcile.js +195 -0
- package/lib/issue-sync/schema.js +126 -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 +8 -4
- 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 +166 -0
- 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 +332 -23
- 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/conflicts.js +205 -0
- package/lib/smart-status/scoring.js +191 -0
- package/lib/status/beads-snapshot.js +145 -0
- package/lib/status/presenter.js +216 -0
- 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 +298 -47
- package/lib/workflow/stage-transition.js +115 -0
- package/lib/workflow/stages.js +30 -6
- package/lib/workflow/state-manager.js +159 -14
- package/lib/workflow/state.js +23 -1
- package/lib/workflow-profiles.js +17 -5
- package/package.json +46 -36
- 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 +165 -22
- package/scripts/beads-migrate-to-dolt.sh +7 -0
- package/scripts/beads-upgrade-smoke.sh +284 -0
- package/scripts/behavioral-judge.sh +115 -11
- package/scripts/benchmark.js +349 -63
- 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-analyze.js +52 -17
- package/scripts/dep-guard-keyword-ripple.js +29 -0
- package/scripts/dep-guard-render-review.js +86 -0
- package/scripts/dep-guard.sh +64 -232
- 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 +144 -47
- 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 +183 -79
- 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/beads-migrate-to-dolt.mjs +503 -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 +108 -0
- package/scripts/protected-state-check.js +104 -0
- package/scripts/smart-status-score.js +31 -0
- package/scripts/smart-status-sessions.js +51 -0
- package/scripts/smart-status.sh +117 -369
- 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-agentic-workflow.js +48 -0
- package/scripts/sync-utils.sh +3 -0
- package/scripts/test-ci-shard.js +251 -0
- package/scripts/test-dashboard.js +188 -52
- package/scripts/test-full-suite.js +186 -0
- package/scripts/test-profile.js +278 -0
- package/scripts/test.js +302 -28
- package/scripts/validate.js +143 -0
- package/scripts/validate.sh +18 -1
- 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} +46 -52
- 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} +134 -159
- 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/skills/ship/SKILL.md +251 -0
- 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/skills/status/SKILL.md +102 -0
- 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/ship.prompt.md +0 -215
- package/.github/prompts/status.prompt.md +0 -92
- package/.github/prompts/verify.prompt.md +0 -271
- package/.github/workflows/beads-to-github.yml +0 -56
- package/.github/workflows/github-to-beads.yml +0 -97
- 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 -255
- 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-health-check.js +0 -143
- package/lib/commands/commands-reset.js +0 -147
- package/opencode.json +0 -67
- package/scripts/beads-context.test.js +0 -567
- 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 -332
- package/scripts/github-beads-sync/label-mapper.mjs +0 -54
- package/scripts/github-beads-sync/mapping.mjs +0 -78
- package/scripts/github-beads-sync/reverse-sync-cli.mjs +0 -31
- package/scripts/github-beads-sync/reverse-sync.mjs +0 -138
- 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
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { STAGE_IDS: WORKFLOW_STAGE_IDS } = require('./workflow/stages');
|
|
4
|
+
|
|
5
|
+
const HARNESS_IDS = ['claude', 'cursor', 'codex', 'hermes'];
|
|
6
|
+
|
|
7
|
+
const CAPABILITY_IDS = [
|
|
8
|
+
'instructions',
|
|
9
|
+
'skills',
|
|
10
|
+
'rules',
|
|
11
|
+
'mcp',
|
|
12
|
+
'hooks',
|
|
13
|
+
'commands',
|
|
14
|
+
'agents',
|
|
15
|
+
'stages',
|
|
16
|
+
'beads',
|
|
17
|
+
'typedMemory',
|
|
18
|
+
'patchOverrides',
|
|
19
|
+
'marketplaceTrust',
|
|
20
|
+
'extensionPacks',
|
|
21
|
+
'permissions',
|
|
22
|
+
'ignore',
|
|
23
|
+
'sandbox',
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
const STAGE_IDS = [...WORKFLOW_STAGE_IDS];
|
|
27
|
+
const UTILITY_SKILL_IDS = ['status', 'shepherd'];
|
|
28
|
+
|
|
29
|
+
const SOURCE_ROWS = [
|
|
30
|
+
['S1', 'Claude Code skills', 'https://code.claude.com/docs/en/skills', 'Claude Code skills use SKILL.md frontmatter descriptions for automatic invocation; commands remain compatible but skills are recommended.'],
|
|
31
|
+
['S2', 'Claude Agent SDK skills', 'https://code.claude.com/docs/en/agent-sdk/skills.md', 'Claude SDK loads project/user/plugin skills and invokes them based on description metadata.'],
|
|
32
|
+
['S3', 'Cursor rules', 'https://docs.cursor.com/en/context', 'Cursor project rules live in .cursor/rules as .mdc files with description, globs, and alwaysApply metadata.'],
|
|
33
|
+
['S4', 'Cursor MCP', 'https://docs.cursor.com/context/model-context-protocol', 'Cursor connects external tools and data sources through MCP using stdio, SSE, and streamable HTTP transports.'],
|
|
34
|
+
['S5', 'Codex skills', 'https://developers.openai.com/codex/skills', 'Codex skills package instructions, resources, and scripts; Codex scans .agents/skills from cwd up to the repo root for repo-scope discovery. Forge installs the global $CODEX_HOME/skills from the canonical skills/ source AND commits the repo-local .agents/skills mirror (kept in sync with skills/ by a pre-commit hook + drift gate) for teammate-clone discovery.'],
|
|
35
|
+
['S6', 'Codex MCP', 'https://developers.openai.com/codex/mcp', 'Codex configures MCP servers in config.toml and supports plugin-provided MCP servers.'],
|
|
36
|
+
['S7', 'Codex hooks', 'https://developers.openai.com/codex/hooks', 'Codex hooks run deterministic scripts during lifecycle events.'],
|
|
37
|
+
['S8', 'Codex plugins and marketplaces', 'https://developers.openai.com/codex/plugins/build', 'Codex plugins can package skills, apps, MCP servers, hooks, and marketplace metadata.'],
|
|
38
|
+
['S9', 'AGENTS.md standard', 'https://agents.md/', 'AGENTS.md provides repository instructions for coding agents.'],
|
|
39
|
+
['S10', 'Cursor Agent Skills', 'https://docs.cursor.com/en/agent/skills', 'Cursor reads on-demand Agent Skills from .cursor/skills/<name>/SKILL.md; Forge populates them at setup from the canonical skills/ source.'],
|
|
40
|
+
['S11', 'Claude Code settings permissions', 'https://docs.claude.com/en/docs/claude-code/settings', 'Claude Code reads project-local .claude/settings.json with a permissions block (allow/deny/ask rule arrays, evaluated deny then ask then allow); rule syntax is Bash(prefix:*), Read(glob), WebFetch(domain:...).'],
|
|
41
|
+
['S12', 'Cursor ignore files', 'https://cursor.com/docs/reference/ignore-file', 'Cursor reads project-local .cursorignore (blocks AI access + indexing) and .cursorindexingignore (index-only), gitignore-style; .gitignore and common secret/lock files are ignored by default.'],
|
|
42
|
+
['S13', 'Codex sandbox and approvals config', 'https://developers.openai.com/codex/config-reference', 'Codex config.toml sets sandbox_mode (read-only/workspace-write/danger-full-access) and approval_policy (untrusted/on-request/never); a project-local .codex/config.toml is honored ONLY when the project is trusted in the GLOBAL $CODEX_HOME/config.toml (projects.<path>.trust_level).'],
|
|
43
|
+
['S14', 'Claude Code hooks', 'https://code.claude.com/docs/en/hooks', 'Claude Code hooks live in .claude/settings.json under a `hooks` block; a PreToolUse matcher group (e.g. "Write|Edit"/"Bash") runs a command that can deny the tool call via hookSpecificOutput.permissionDecision.'],
|
|
44
|
+
['S15', 'Cursor hooks', 'https://cursor.com/docs/hooks', 'Cursor 1.7+ reads project-local .cursor/hooks.json ({ version: 1, hooks }); only before* events (beforeShellExecution/beforeReadFile/beforeMCPExecution) can deny — there is no pre-edit deny event, so afterFileEdit is observational.'],
|
|
45
|
+
['S16', 'Hermes Agent event hooks', 'https://hermes-agent.nousresearch.com/docs/user-guide/features/hooks/', 'Hermes (NousResearch) shell hooks are declared in a `hooks:` block in the GLOBAL ~/.hermes/config.yaml; each matcher/command entry runs as a subprocess over a JSON-stdin/stdout wire protocol, and a pre_tool_call hook CAN deny a tool call ({action:block, message} — it also accepts the Claude-Code {decision:block, reason} shape).'],
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
// The closed set of capability statuses. Every capability-matrix target status MUST
|
|
49
|
+
// be one of these — a test in test/harness-capability-matrix.test.js enforces it so
|
|
50
|
+
// no future row can introduce an off-vocabulary (and likely dishonest) status.
|
|
51
|
+
const STATUS_VOCABULARY = [
|
|
52
|
+
'native', // Forge renders the harness's native surface and it is delivered
|
|
53
|
+
'shim', // instruction shim (e.g. CLAUDE.md → AGENTS.md)
|
|
54
|
+
'projection', // policy projected into an instruction file (delivered)
|
|
55
|
+
'cli-consumed', // consumed through the forge CLI (Hermes)
|
|
56
|
+
'forge-owned', // Forge-owned state/projection (beads, patch overrides, .hermes/skills, locks)
|
|
57
|
+
'packaged', // packaged/staged for install into a global/harness location
|
|
58
|
+
'fallback', // skill fallback stands in for an unsupported surface
|
|
59
|
+
'skill-first', // stage delivered as a skill (no command surface)
|
|
60
|
+
'plugin-aware', // delivered via the harness plugin/marketplace mechanism
|
|
61
|
+
'generated', // composite of other generated surfaces
|
|
62
|
+
'contract-only', // capability delivered via a contract (git hooks), NOT a harness-native render
|
|
63
|
+
'not-delivered', // Forge does not yet render this surface (honest not-yet-delivered)
|
|
64
|
+
'unsupported', // the harness has no such surface
|
|
65
|
+
'removed', // the surface was intentionally removed
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
const SOURCES = SOURCE_ROWS.map(([label, title, url, summary]) => ({
|
|
69
|
+
label,
|
|
70
|
+
title,
|
|
71
|
+
url,
|
|
72
|
+
summary,
|
|
73
|
+
}));
|
|
74
|
+
|
|
75
|
+
function capability(status, primarySurface, options = {}) {
|
|
76
|
+
return {
|
|
77
|
+
status,
|
|
78
|
+
primarySurface,
|
|
79
|
+
role: options.role || 'native surface',
|
|
80
|
+
activation: options.activation || 'explicit or harness-defined',
|
|
81
|
+
renderer: options.renderer || null,
|
|
82
|
+
evidence: options.evidence || [],
|
|
83
|
+
knownIssue: options.knownIssue || null,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const HARNESS_NAMES = {
|
|
88
|
+
claude: 'Claude Code',
|
|
89
|
+
cursor: 'Cursor',
|
|
90
|
+
codex: 'OpenAI Codex',
|
|
91
|
+
hermes: 'Hermes',
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
function harnessTargets(entries) {
|
|
95
|
+
return Object.fromEntries(entries.map(([id, target]) => [id, target]));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function target(status, surface, overrides = {}) {
|
|
99
|
+
return { status, surface, ...overrides };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function row(id, renderer, role, entries) {
|
|
103
|
+
return {
|
|
104
|
+
id,
|
|
105
|
+
renderer,
|
|
106
|
+
role,
|
|
107
|
+
harnesses: harnessTargets(entries),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const CAPABILITY_ROWS = [
|
|
112
|
+
row('instructions', 'instructions', 'project instruction projection', [
|
|
113
|
+
['claude', target('shim', 'CLAUDE.md', { evidence: ['S1', 'S9'] })],
|
|
114
|
+
['cursor', target('native', 'AGENTS.md', { evidence: ['S3', 'S9'] })],
|
|
115
|
+
['codex', target('native', 'AGENTS.md', { evidence: ['S9'] })],
|
|
116
|
+
['hermes', target('cli-consumed', 'AGENTS.md via forge orient/recap', { role: 'CLI-consumed instruction projection', evidence: ['S9'] })],
|
|
117
|
+
]),
|
|
118
|
+
row('skills', 'skills', 'on-demand workflow', [
|
|
119
|
+
['claude', target('native', '.claude/skills/<skill>/SKILL.md', { activation: 'description match or /skill-name', evidence: ['S1', 'S2'] })],
|
|
120
|
+
['cursor', target('native', '.cursor/skills/<skill>/SKILL.md', { activation: 'description match or explicit skill invocation', evidence: ['S3', 'S10'] })],
|
|
121
|
+
['codex', target('packaged', '$CODEX_HOME/skills/<skill>/SKILL.md', { role: 'installed from the canonical skills/ source (generated at setup)', activation: 'description match or explicit $skill mention after install', evidence: ['S5'], knownIssue: 'Codex installs to the GLOBAL $CODEX_HOME/skills, generated at setup from canonical skills/. Repo-local discovery uses .agents/skills/<skill>/SKILL.md, the committed mirror (generated from skills/, kept byte-identical by a pre-commit hook + drift gate) so a fresh clone gets discovery without setup (kernel issue 55dfeccf).' })],
|
|
122
|
+
['hermes', target('forge-owned', '.hermes/skills/<skill>/SKILL.md', { role: 'Forge-owned skill projection consumed via forge orient/recap', activation: 'forge orient/recap CLI' })],
|
|
123
|
+
]),
|
|
124
|
+
row('rules', 'rules', null, [
|
|
125
|
+
['claude', target('shim', 'CLAUDE.md', { role: 'always-on policy projection', evidence: ['S1'] })],
|
|
126
|
+
['cursor', target('native', '.cursor/rules/<rule>.mdc', { role: 'always-on or scoped policy', activation: 'description, globs, alwaysApply, or manual rule mention', evidence: ['S3'] })],
|
|
127
|
+
['codex', target('projection', 'AGENTS.md', { role: 'always-on policy projection', evidence: ['S9'] })],
|
|
128
|
+
['hermes', target('projection', 'AGENTS.md via forge orient', { role: 'always-on policy projection', evidence: ['S9'] })],
|
|
129
|
+
]),
|
|
130
|
+
row('mcp', 'mcp', 'tool and resource plumbing', [
|
|
131
|
+
['claude', target('native', '.mcp.json', { evidence: ['S1'] })],
|
|
132
|
+
['cursor', target('native', '.cursor/mcp.json', { evidence: ['S4'] })],
|
|
133
|
+
['codex', target('not-delivered', null, { role: 'Codex reads the GLOBAL $CODEX_HOME/config.toml (per agents-config.js), not a project-local file', knownIssue: 'Forge does not write the global Codex MCP config during project setup; the Codex TOML renderer exists and is tested but is not wired. Tracked as kernel epic 90f2f631.', evidence: ['S6'] })],
|
|
134
|
+
['hermes', target('unsupported', null, { knownIssue: 'Hermes consumes Forge state through the CLI (forge orient/recap); it has no native MCP config surface.' })],
|
|
135
|
+
]),
|
|
136
|
+
row('hooks', 'hooks', 'lifecycle enforcement', [
|
|
137
|
+
['claude', target('native', '.claude/settings.json', { role: 'native PreToolUse hooks projecting Forge TDD-gate + protected-path enforcement (lib/hook-renderer.js), invoking the installed .forge/hooks/forge-native-hook.js adapter', evidence: ['S14'] })],
|
|
138
|
+
['cursor', target('native', '.cursor/hooks.json', { role: 'native Cursor 1.7+ hooks projecting Forge enforcement via the installed forge-native-hook.js adapter', knownIssue: 'Cursor 1.7+ has NO pre-edit deny event: SHELL writes to protected paths ARE denied on beforeShellExecution (the adapter inspects the command for write intent on a protected path), but editor-tool edits are only audited observationally via afterFileEdit; the git-hook path remains the authoritative pre-commit gate.', evidence: ['S15'] })],
|
|
139
|
+
['codex', target('packaged', '$CODEX_HOME/config.toml', { role: 'Codex [hooks] TOML rendered (renderCodexHooksToml) and installable via the opt-in, consent-guarded `forge hooks install --global` (lib/hook-global-installer.js); Codex reads the GLOBAL ~/.codex/config.toml (per #311 / agents-config.js), so project setup still never writes it', activation: 'explicit `forge hooks install --global` (never project setup)', knownIssue: 'Codex hooks live in the GLOBAL ~/.codex/config.toml, so they are NOT delivered by project `forge setup` — the opt-in `forge hooks install --global [--harness codex]` path (delivered-on-request, epic 90f2f631) merges the [[hooks.PreToolUse]] groups into the global config, preserving user config and requiring explicit consent. Global scope caveat remains: the install affects every project on the machine, and the hook command resolves the project-local .forge/hooks/forge-native-hook.js adapter from the workspace root, failing open where Forge is not set up.', evidence: ['S7'] })],
|
|
140
|
+
['hermes', target('packaged', '~/.hermes/config.yaml', { role: 'Hermes `hooks:` shell-hook YAML rendered (renderHermesHooksYaml) and installable via the opt-in, consent-guarded `forge hooks install --global` (lib/hook-global-installer.js); Hermes reads the GLOBAL ~/.hermes/config.yaml, so project setup still never writes it', activation: 'explicit `forge hooks install --global` (never project setup)', knownIssue: 'Hermes DOES have a native hook surface: shell hooks in the `hooks:` block of ~/.hermes/config.yaml, where a pre_tool_call hook can DENY a tool call (it even accepts Claude\'s {decision:block} shape). That config is global (home dir), so project `forge setup` never writes it — the opt-in `forge hooks install --global [--harness hermes]` path (delivered-on-request, epic 90f2f631) merges the pre_tool_call entries into the global config with explicit consent, preserving user config. Global scope caveat remains: the install affects every project on the machine, the hook command resolves the project-local .forge/hooks/forge-native-hook.js adapter from the workspace root (failing open where Forge is not set up), and the git-hook + forge-CLI-gate tier remains the authoritative enforcement path when the global install has not been run.', evidence: ['S16'] })],
|
|
141
|
+
]),
|
|
142
|
+
row('commands', 'commands', null, [
|
|
143
|
+
['claude', target('removed', null, { role: 'legacy .claude/commands/ surface removed in A0d; stage skills live in .claude/skills/<stage>/SKILL.md', evidence: ['S1'] })],
|
|
144
|
+
['cursor', target('removed', null, { role: 'legacy .cursor/commands/ surface removed in A0d; stage skills live in .cursor/skills/<stage>/SKILL.md', evidence: ['S3'] })],
|
|
145
|
+
['codex', target('fallback', '$CODEX_HOME/skills/<stage>/SKILL.md', { role: 'skill fallback (generated at setup from canonical skills/) instead of command authority', activation: 'explicit $skill or description match after install', evidence: ['S5'], knownIssue: 'Repo-local Codex discovery uses .agents/skills, the committed mirror (generated from skills/, kept in sync by a pre-commit hook + drift gate) (kernel issue 55dfeccf).' })],
|
|
146
|
+
['hermes', target('cli-consumed', 'forge orient / forge recap', { role: 'CLI command surface instead of command files' })],
|
|
147
|
+
]),
|
|
148
|
+
row('agents', 'agents', 'subagent role mapping', [
|
|
149
|
+
['claude', target('not-delivered', null, { role: 'Claude supports .claude/agents/<role>.md, but Forge renders no subagent files', knownIssue: 'The whole agents/subagents domain is unimplemented — no renderer, manifest, wiring, or tests for any harness. Tracked as kernel issue 802aa4d8 (epic 90f2f631).', evidence: ['S1'] })],
|
|
150
|
+
['cursor', target('not-delivered', null, { knownIssue: 'No Cursor subagent renderer; the agents domain is unimplemented. Tracked as kernel issue 802aa4d8 (epic 90f2f631).' })],
|
|
151
|
+
['codex', target('not-delivered', null, { role: 'skill-backing not implemented', knownIssue: 'No Codex subagent/skill-backing renderer; the agents domain is unimplemented. Tracked as kernel issue 802aa4d8 (epic 90f2f631).', evidence: ['S5'] })],
|
|
152
|
+
['hermes', target('unsupported', null, { knownIssue: 'Hermes has no subagent file contract; it is a CLI-consumed harness.' })],
|
|
153
|
+
]),
|
|
154
|
+
row('stages', 'stage-graph', 'super skill with addressable subskills', [
|
|
155
|
+
['claude', target('skill-first', '.claude/skills/<stage>/SKILL.md', { evidence: ['S1'] })],
|
|
156
|
+
['cursor', target('native', '.cursor/skills/<stage>/SKILL.md', { evidence: ['S3', 'S10'] })],
|
|
157
|
+
['codex', target('skill-first', '$CODEX_HOME/skills/<stage>/SKILL.md', { role: 'generated at setup from canonical skills/', evidence: ['S5'], knownIssue: 'Repo-local Codex discovery uses .agents/skills/<stage>/SKILL.md, the committed mirror (generated from skills/, kept in sync by a pre-commit hook + drift gate) (kernel issue 55dfeccf).' })],
|
|
158
|
+
['hermes', target('forge-owned', '.hermes/skills/<stage>/SKILL.md', { role: 'Forge-owned stage-skill projection consumed via forge orient/recap' })],
|
|
159
|
+
]),
|
|
160
|
+
row('beads', 'state-and-memory', 'issue and audit state authority', HARNESS_IDS.map(id => [id, target('forge-owned', 'forge CLI + bd adapter')])),
|
|
161
|
+
row('typedMemory', 'state-and-memory', 'typed memory projection', [
|
|
162
|
+
['claude', target('not-delivered', null, { knownIssue: 'Typed memory is WRITE-ONLY (insights.js); no generator projects a memory section into any Claude instruction/rule file. Tracked as kernel issue dce9da46 (epic 90f2f631).' })],
|
|
163
|
+
['cursor', target('not-delivered', null, { knownIssue: 'Typed memory is write-only; no memory-projection renderer emits a Cursor memory section. Tracked as kernel issue dce9da46 (epic 90f2f631).' })],
|
|
164
|
+
['codex', target('not-delivered', null, { knownIssue: 'Typed memory is write-only; no memory-projection renderer emits a Codex memory section. Tracked as kernel issue dce9da46 (epic 90f2f631).' })],
|
|
165
|
+
['hermes', target('not-delivered', null, { knownIssue: 'Typed memory is write-only; forge recall reads notes but no renderer emits a Hermes memory section. Tracked as kernel issue dce9da46 (epic 90f2f631).' })],
|
|
166
|
+
]),
|
|
167
|
+
row('patchOverrides', 'state-and-memory', 'project override source', HARNESS_IDS.map(id => [id, target('forge-owned', '.forge/patch.md')])),
|
|
168
|
+
row('marketplaceTrust', 'distribution', 'trusted distribution metadata', [
|
|
169
|
+
['claude', target('plugin-aware', 'Claude plugin or Forge lock metadata', { evidence: ['S1'] })],
|
|
170
|
+
['cursor', target('forge-owned', 'extension lock metadata')],
|
|
171
|
+
['codex', target('native', '.agents/plugins/marketplace.json plus plugin lock metadata', { evidence: ['S8'] })],
|
|
172
|
+
['hermes', target('forge-owned', 'Forge extension lock metadata')],
|
|
173
|
+
]),
|
|
174
|
+
row('extensionPacks', 'distribution', null, [
|
|
175
|
+
['claude', target('plugin-aware', 'plugin skills/commands/hooks', { role: 'installable Forge extension pack', evidence: ['S1'] })],
|
|
176
|
+
['cursor', target('generated', '.cursor/skills + .cursor/rules + .cursor/mcp.json', { role: 'installable Forge extension pack projection' })],
|
|
177
|
+
['codex', target('native', 'Codex plugin with skills, MCP servers, hooks, and apps', { role: 'installable Forge extension pack', evidence: ['S8'] })],
|
|
178
|
+
['hermes', target('forge-owned', '.hermes/skills projected from Forge extension state', { role: 'installable Forge extension pack projection' })],
|
|
179
|
+
]),
|
|
180
|
+
// ---- Native SAFETY surfaces (Tier-2 parity) ----
|
|
181
|
+
// Security/safety boundaries each harness ships that Forge sets sane defaults for.
|
|
182
|
+
row('permissions', 'safety', 'tool-permission allowlist', [
|
|
183
|
+
['claude', target('native', '.claude/settings.json (permissions allow/deny/ask)', { role: 'declarative tool-permission allowlist rendered with safe forge/dev defaults', activation: 'evaluated deny -> ask -> allow on each tool call', evidence: ['S11'] })],
|
|
184
|
+
['cursor', target('unsupported', null, { knownIssue: 'Cursor command allow/deny lists are IDE/global settings (Settings > Chat & Composer), not a project-local committable file; Forge cannot render a project-local Cursor permission allowlist.' })],
|
|
185
|
+
['codex', target('not-delivered', null, { role: "Codex approvals live in config.toml (approval_policy)", knownIssue: 'Codex approval_policy is a config.toml surface honored project-locally ONLY when the project is trusted in the GLOBAL $CODEX_HOME/config.toml (projects.<path>.trust_level). Forge cannot grant that global trust during project-local setup, so it is deferred to global-scope wiring. Tracked as kernel epic 90f2f631 (#311).', evidence: ['S13'] })],
|
|
186
|
+
['hermes', target('unsupported', null, { knownIssue: 'Hermes is CLI-consumed (forge orient/recap); it has no tool-permission allowlist surface.' })],
|
|
187
|
+
]),
|
|
188
|
+
row('ignore', 'safety', 'AI read/index boundary', [
|
|
189
|
+
['claude', target('projection', '.claude/settings.json (permissions.deny Read rules)', { role: 'read/secret boundary projected into permission deny rules (no dedicated ignore file)', knownIssue: 'Claude Code has no .claudeignore file; the read/secret boundary is delivered as permissions.deny Read(...) rules by the permissions renderer, not a separate ignore file.', evidence: ['S11'] })],
|
|
190
|
+
['cursor', target('native', '.cursorignore', { role: 'keeps secrets and large/generated dirs out of AI context + index (also .cursorindexingignore for index-only)', activation: 'gitignore-style patterns honored by Cursor AI features', evidence: ['S12'], knownIssue: '.cursorignore blocks Cursor AI features and indexing but is NOT a hard security boundary — terminal/MCP tools can still reach the files.' })],
|
|
191
|
+
['codex', target('unsupported', null, { knownIssue: 'Codex has no dedicated AI read/index-ignore file; it honors .gitignore. No project-local ignore surface for Forge to render.' })],
|
|
192
|
+
['hermes', target('unsupported', null, { knownIssue: 'Hermes has no AI index/read-ignore surface.' })],
|
|
193
|
+
]),
|
|
194
|
+
row('sandbox', 'safety', 'execution sandbox and approval policy', [
|
|
195
|
+
['claude', target('unsupported', null, { role: 'no config-file execution sandbox', knownIssue: 'Claude Code has no config.toml-style execution sandbox; execution safety is delivered by the tool-permission allowlist (permissions row), not a sandbox surface.' })],
|
|
196
|
+
['cursor', target('unsupported', null, { knownIssue: 'Cursor has no project-local execution-sandbox config surface.' })],
|
|
197
|
+
['codex', target('not-delivered', null, { role: 'Codex sandbox_mode + approval_policy in config.toml', knownIssue: 'Codex sandbox_mode/approval_policy live in config.toml, honored project-locally ONLY when the project is trusted in the GLOBAL $CODEX_HOME/config.toml (projects.<path>.trust_level). Forge cannot grant that global trust during project-local setup, so a rendered project-local sandbox policy would not take effect; deferred to global-scope wiring. Tracked as kernel epic 90f2f631 (#311).', evidence: ['S13'] })],
|
|
198
|
+
['hermes', target('unsupported', null, { knownIssue: 'Hermes runs through the Forge CLI; it has no harness execution-sandbox surface.' })],
|
|
199
|
+
]),
|
|
200
|
+
];
|
|
201
|
+
|
|
202
|
+
function rowCapability(row, harnessId) {
|
|
203
|
+
const target = row.harnesses[harnessId];
|
|
204
|
+
return capability(target.status, target.surface, {
|
|
205
|
+
role: target.role || row.role,
|
|
206
|
+
activation: target.activation || row.activation,
|
|
207
|
+
renderer: row.renderer,
|
|
208
|
+
evidence: target.evidence,
|
|
209
|
+
knownIssue: target.knownIssue,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function buildHarnessCapabilities(harnessId) {
|
|
214
|
+
return Object.fromEntries(
|
|
215
|
+
CAPABILITY_ROWS.map(row => [row.id, rowCapability(row, harnessId)]),
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function buildHarnessCapabilityMatrix() {
|
|
220
|
+
return {
|
|
221
|
+
schemaVersion: '1.0.0',
|
|
222
|
+
kind: 'forge.harnessCapabilityMatrix',
|
|
223
|
+
scope: 'v3.0-mvp',
|
|
224
|
+
harnesses: Object.fromEntries(HARNESS_IDS.map(id => [id, {
|
|
225
|
+
id,
|
|
226
|
+
name: HARNESS_NAMES[id],
|
|
227
|
+
capabilities: buildHarnessCapabilities(id),
|
|
228
|
+
}])),
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const STAGE_SUBSKILLS = {
|
|
233
|
+
status: ['status.context_scan', 'status.issue_scan', 'status.git_scan'],
|
|
234
|
+
shepherd: ['shepherd.poll', 'shepherd.rerun', 'shepherd.escalate'],
|
|
235
|
+
plan: ['plan.intent_capture', 'plan.parallel_research', 'plan.parallel_critics', 'plan.synthesis', 'plan.final_lock'],
|
|
236
|
+
dev: ['dev.red', 'dev.green', 'dev.refactor', 'dev.spec_review', 'dev.quality_review'],
|
|
237
|
+
validate: ['validate.typecheck', 'validate.lint', 'validate.tests', 'validate.security', 'validate.context'],
|
|
238
|
+
ship: ['ship.freshness', 'ship.push', 'ship.pr_body', 'ship.pr_create'],
|
|
239
|
+
review: ['review.collect_feedback', 'review.classify', 'review.fix', 'review.resolve_threads'],
|
|
240
|
+
verify: ['verify.merge_state', 'verify.default_branch_ci', 'verify.cleanup', 'verify.issue_close'],
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
function buildSkillsFirstStageGraph() {
|
|
244
|
+
const renderTargetsForSkill = (id) => ({
|
|
245
|
+
claude: {
|
|
246
|
+
// Stage skills are skill-first: `.claude/commands/` was removed in A0d, so
|
|
247
|
+
// there is NO command shim (that contradicted the commands capability row).
|
|
248
|
+
skill: `.claude/skills/${id}/SKILL.md`,
|
|
249
|
+
},
|
|
250
|
+
cursor: {
|
|
251
|
+
// Forge populates .cursor/skills/<stage>/SKILL.md at setup (populateAgentSkills).
|
|
252
|
+
// No per-stage .cursor/rules/<stage>.mdc is generated — Forge only renders the
|
|
253
|
+
// 4 policy rules — so no rule-policy fallback is advertised here.
|
|
254
|
+
skill: `.cursor/skills/${id}/SKILL.md`,
|
|
255
|
+
status: 'native',
|
|
256
|
+
},
|
|
257
|
+
codex: {
|
|
258
|
+
// .codex/skills is a setup-generated, gitignored local mirror (not committed);
|
|
259
|
+
// skills install to the GLOBAL $CODEX_HOME/skills, generated at setup from the
|
|
260
|
+
// canonical skills/ source. .agents/skills is the COMMITTED repo-local
|
|
261
|
+
// discovery mirror that Codex scans cwd → repo root (kept byte-identical to
|
|
262
|
+
// skills/ by a pre-commit hook + drift gate). skills/ is the canonical source.
|
|
263
|
+
skill: `$CODEX_HOME/skills/${id}/SKILL.md`,
|
|
264
|
+
stagingMirror: `.codex/skills/${id}/SKILL.md`,
|
|
265
|
+
installTarget: '$CODEX_HOME/skills',
|
|
266
|
+
directRepoDiscoveryTarget: `.agents/skills/${id}/SKILL.md`,
|
|
267
|
+
},
|
|
268
|
+
hermes: {
|
|
269
|
+
// Forge populates .hermes/skills/<stage>/SKILL.md at setup (populateAgentSkills);
|
|
270
|
+
// Hermes then consumes them through `forge orient` / `forge recap`.
|
|
271
|
+
skill: `.hermes/skills/${id}/SKILL.md`,
|
|
272
|
+
status: 'forge-owned',
|
|
273
|
+
via: 'forge orient / forge recap',
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
return {
|
|
278
|
+
schemaVersion: '1.0.0',
|
|
279
|
+
kind: 'forge.skillsFirstStageGraph',
|
|
280
|
+
rule: 'Stages are canonical super skills; commands are compatibility shims only.',
|
|
281
|
+
stages: STAGE_IDS.map(id => ({
|
|
282
|
+
id,
|
|
283
|
+
canonicalSurface: 'skill',
|
|
284
|
+
workflowStage: true,
|
|
285
|
+
superSkill: id,
|
|
286
|
+
subskills: STAGE_SUBSKILLS[id].map(subskillId => ({
|
|
287
|
+
id: subskillId,
|
|
288
|
+
parent: id,
|
|
289
|
+
})),
|
|
290
|
+
renderTargets: renderTargetsForSkill(id),
|
|
291
|
+
})),
|
|
292
|
+
utilitySkills: UTILITY_SKILL_IDS.map(id => ({
|
|
293
|
+
id,
|
|
294
|
+
canonicalSurface: 'skill',
|
|
295
|
+
workflowStage: false,
|
|
296
|
+
superSkill: id,
|
|
297
|
+
subskills: STAGE_SUBSKILLS[id].map(subskillId => ({
|
|
298
|
+
id: subskillId,
|
|
299
|
+
parent: id,
|
|
300
|
+
})),
|
|
301
|
+
renderTargets: renderTargetsForSkill(id),
|
|
302
|
+
})),
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const RENDERER_FAMILIES = [
|
|
307
|
+
['instructions', 'Forge typed instruction sections', ['semantic section comparison', 'target path exists']],
|
|
308
|
+
['skills', 'agentskills.io-compatible SKILL.md', ['frontmatter name/description', 'description-match fixture']],
|
|
309
|
+
['rules', 'Forge rule manifest', ['policy scope', 'activation metadata', 'unsupported target note']],
|
|
310
|
+
['mcp', 'Forge MCP manifest', ['config render', 'server probe or known issue']],
|
|
311
|
+
['hooks', 'Forge hook manifest', ['lifecycle event mapping', 'deny/allow behavior proof']],
|
|
312
|
+
['commands', 'Forge command shim manifest', ['shim points to canonical skill', 'no duplicated stage body']],
|
|
313
|
+
['agents', 'Forge agent role spec', ['role mapping', 'parallelism or fallback policy']],
|
|
314
|
+
['stage-graph', 'Forge skills-first stage graph', ['super skill target', 'subskill target list', 'gate mapping']],
|
|
315
|
+
['state-and-memory', 'Beads, typed memory, and patch override manifests', ['state authority', 'projection provenance', 'protected path policy']],
|
|
316
|
+
['distribution', 'Forge extension manifest and lock metadata', ['lock hash', 'trusted source', 'generated target inventory']],
|
|
317
|
+
['safety', 'Forge safety-surface manifest (permissions, ignore, sandbox)', ['permission scope (allow/deny/ask)', 'read/index ignore boundary', 'sandbox/approval policy or global-scope deferral note']],
|
|
318
|
+
];
|
|
319
|
+
|
|
320
|
+
function buildRendererContract() {
|
|
321
|
+
return {
|
|
322
|
+
schemaVersion: '1.0.0',
|
|
323
|
+
kind: 'forge.harnessRendererContract',
|
|
324
|
+
scope: 'contract-only',
|
|
325
|
+
beforeAddingRenderer: [
|
|
326
|
+
'capability-matrix-entry',
|
|
327
|
+
'target-path-contract',
|
|
328
|
+
'activation-metadata-contract',
|
|
329
|
+
'machine-readable-evidence',
|
|
330
|
+
'known-issue-if-unproven',
|
|
331
|
+
],
|
|
332
|
+
rendererFamilies: RENDERER_FAMILIES.map(([id, canonicalInput, requiredEvidence]) => ({
|
|
333
|
+
id,
|
|
334
|
+
canonicalInput,
|
|
335
|
+
requiredEvidence,
|
|
336
|
+
})),
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function getHarnessCapabilityMatrix() {
|
|
341
|
+
return buildHarnessCapabilityMatrix();
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function getSkillsFirstStageGraph() {
|
|
345
|
+
return buildSkillsFirstStageGraph();
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
function getRendererContract() {
|
|
349
|
+
return buildRendererContract();
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function buildHarnessCapabilityEvidence() {
|
|
353
|
+
const matrix = getHarnessCapabilityMatrix();
|
|
354
|
+
return {
|
|
355
|
+
schemaVersion: matrix.schemaVersion,
|
|
356
|
+
kind: 'forge.harnessCapabilityEvidence',
|
|
357
|
+
scope: matrix.scope,
|
|
358
|
+
harnesses: HARNESS_IDS.map(id => ({
|
|
359
|
+
id,
|
|
360
|
+
name: matrix.harnesses[id].name,
|
|
361
|
+
capabilities: matrix.harnesses[id].capabilities,
|
|
362
|
+
})),
|
|
363
|
+
stageGraph: getSkillsFirstStageGraph(),
|
|
364
|
+
rendererContract: getRendererContract(),
|
|
365
|
+
sources: SOURCES,
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
module.exports = {
|
|
370
|
+
CAPABILITY_IDS,
|
|
371
|
+
HARNESS_IDS,
|
|
372
|
+
SOURCES,
|
|
373
|
+
STAGE_IDS,
|
|
374
|
+
STATUS_VOCABULARY,
|
|
375
|
+
UTILITY_SKILL_IDS,
|
|
376
|
+
buildHarnessCapabilityEvidence,
|
|
377
|
+
getHarnessCapabilityMatrix,
|
|
378
|
+
getRendererContract,
|
|
379
|
+
getSkillsFirstStageGraph,
|
|
380
|
+
};
|