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,148 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `forge control <gate-id|rail-id> <mandatory|optional|permission>`
|
|
5
|
+
* `forge control status [--json]`
|
|
6
|
+
*
|
|
7
|
+
* Tri-state control for the gate/rail CONFIG registry (`gate.*` / `rail.*`) —
|
|
8
|
+
* this sets *declared* intent, NOT runtime enforcement. Setting a state writes
|
|
9
|
+
* the SAME resolver-consumed field `forge gate` writes
|
|
10
|
+
* (`workflow.gates.<id>.enabled`); there is deliberately NO parallel `controls:`
|
|
11
|
+
* key, because a key the resolver never reads would be doubly-fake. The tri-state
|
|
12
|
+
* is the vocabulary; `enabled` is the stored truth (state is derived at read
|
|
13
|
+
* time). IMPORTANT: as of 2026-07-15 no runtime consumer denies on these flags —
|
|
14
|
+
* real enforcement lives independently (lefthook TDD hook, fail-closed
|
|
15
|
+
* validate/preflight, enforce-stage order+completion). See the guarantee matrix.
|
|
16
|
+
*
|
|
17
|
+
* For MCP servers / rules / skills it REFUSES with a clear "presence-only, not
|
|
18
|
+
* enforceable" message pointing at docs/reference/control-plane-guarantees.md,
|
|
19
|
+
* rather than pretend a control it cannot honor.
|
|
20
|
+
*
|
|
21
|
+
* `status` renders the all-surface read view with enforcement-locus badges
|
|
22
|
+
* (724356ea) so the UI never implies enforcement a surface lacks.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
const path = require('node:path');
|
|
26
|
+
const { setConfigOverride } = require('../config-writer');
|
|
27
|
+
const { getDefaultRuntimeGraph, getResolvedRuntimeGraph } = require('../core/runtime-graph');
|
|
28
|
+
const {
|
|
29
|
+
classifySurface,
|
|
30
|
+
isControllable,
|
|
31
|
+
describeControl,
|
|
32
|
+
planControl,
|
|
33
|
+
GUARANTEE_DOC,
|
|
34
|
+
} = require('../control-plane');
|
|
35
|
+
|
|
36
|
+
function usage() {
|
|
37
|
+
return [
|
|
38
|
+
'Usage: forge control <gate-id|rail-id> <mandatory|optional|permission>',
|
|
39
|
+
' forge control status [--json]',
|
|
40
|
+
'',
|
|
41
|
+
`Tri-state control for the gate/rail registry. These flags are DECLARED intent`,
|
|
42
|
+
`— today no runtime consumer denies on them (see the guarantee matrix). MCP/`,
|
|
43
|
+
`rules/skills are presence-only and refused — see ${GUARANTEE_DOC}.`,
|
|
44
|
+
].join('\n');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// The known toggleable set is gates PLUS unlocked rails — exactly the surface
|
|
48
|
+
// `forge gate` governs. Combined lookup because gate.* / rail.* namespaces are
|
|
49
|
+
// disjoint. Used to validate an id BEFORE writing (never mid-run).
|
|
50
|
+
function knownPrimitive(id) {
|
|
51
|
+
const graph = getDefaultRuntimeGraph();
|
|
52
|
+
return [...graph.gates, ...graph.rails].find(primitive => primitive.id === id);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function resolvedControls(projectRoot) {
|
|
56
|
+
const graph = getResolvedRuntimeGraph({ projectRoot });
|
|
57
|
+
return [...graph.gates, ...graph.rails].map(describeControl);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function renderStatus(records) {
|
|
61
|
+
const lines = ['Control plane — enforcement-locus per surface (honest to today wiring):', ''];
|
|
62
|
+
for (const rec of records) {
|
|
63
|
+
const state = rec.state ? ` [${rec.state}]` : '';
|
|
64
|
+
lines.push(`- ${rec.id}${state} ${rec.badge} (${rec.locus})`);
|
|
65
|
+
}
|
|
66
|
+
lines.push('');
|
|
67
|
+
lines.push(`No flag above is a wired runtime deny yet: real enforcement lives in`);
|
|
68
|
+
lines.push(`the lefthook TDD hook, fail-closed validate/preflight, and enforce-stage`);
|
|
69
|
+
lines.push(`order+completion — all independent of these flags. MCP/rules/skills are`);
|
|
70
|
+
lines.push(`presence-only (advisory) and not controllable here. See ${GUARANTEE_DOC}.`);
|
|
71
|
+
return `${lines.join('\n')}\n`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function statusCommand(projectRoot, json) {
|
|
75
|
+
const records = resolvedControls(projectRoot);
|
|
76
|
+
if (json) {
|
|
77
|
+
return { success: true, output: `${JSON.stringify({ items: records }, null, 2)}\n` };
|
|
78
|
+
}
|
|
79
|
+
return { success: true, output: renderStatus(records) };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function setCommand(id, state, projectRoot) {
|
|
83
|
+
// Advisory surfaces (and unknown namespaces) are refused up front with the
|
|
84
|
+
// guarantee-matrix pointer — nothing is written.
|
|
85
|
+
if (!isControllable(id)) {
|
|
86
|
+
const plan = planControl({ id }, state);
|
|
87
|
+
return { success: false, error: plan.error };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Validate the id is a real primitive BEFORE writing (mirrors `forge gate`).
|
|
91
|
+
const primitive = knownPrimitive(id);
|
|
92
|
+
if (!primitive) {
|
|
93
|
+
return {
|
|
94
|
+
success: false,
|
|
95
|
+
error: `Unknown ${classifySurface(id)} '${id}'. Run 'forge control status' to list controllable surfaces.`,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const plan = planControl({ id, locked: primitive.locked === true }, state);
|
|
100
|
+
if (!plan.ok) {
|
|
101
|
+
return { success: false, error: plan.error };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const { configPath } = setConfigOverride(
|
|
105
|
+
projectRoot,
|
|
106
|
+
['workflow', 'gates', id, 'enabled'],
|
|
107
|
+
plan.enabled,
|
|
108
|
+
);
|
|
109
|
+
const where = path.relative(projectRoot, configPath) || configPath;
|
|
110
|
+
return {
|
|
111
|
+
success: true,
|
|
112
|
+
output: `set '${id}' to ${state} (workflow.gates.${id}.enabled=${plan.enabled}) in ${where}`,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async function handler(args, flags = {}, projectRoot = process.cwd()) {
|
|
117
|
+
const [first, second] = args;
|
|
118
|
+
|
|
119
|
+
if (first === 'status') {
|
|
120
|
+
// Reject junk after `status` (only the optional --json flag is allowed) so a
|
|
121
|
+
// typo like `forge control status enabled` errors instead of silently
|
|
122
|
+
// ignoring the extra token.
|
|
123
|
+
const extra = args.slice(1).filter(arg => arg !== '--json');
|
|
124
|
+
if (extra.length > 0) {
|
|
125
|
+
return {
|
|
126
|
+
success: false,
|
|
127
|
+
error: `Unexpected argument(s) for status: ${extra.join(', ')}.\n${usage()}`,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return statusCommand(projectRoot, flags.json === true || args.includes('--json'));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (!first) {
|
|
134
|
+
return { success: false, error: usage() };
|
|
135
|
+
}
|
|
136
|
+
if (!second) {
|
|
137
|
+
return { success: false, error: `Missing state.\n${usage()}` };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return setCommand(first, second, projectRoot);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
module.exports = {
|
|
144
|
+
name: 'control',
|
|
145
|
+
description: 'Set tri-state control (mandatory/optional/permission) for a gate or rail',
|
|
146
|
+
usage: usage(),
|
|
147
|
+
handler,
|
|
148
|
+
};
|
package/lib/commands/create.js
CHANGED
package/lib/commands/dev.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
const { execFileSync } = require('node:child_process');
|
|
12
12
|
const fs = require('node:fs');
|
|
13
13
|
const path = require('node:path');
|
|
14
|
+
const { recordAndLabelSubagentAuditEvent } = require('../audit-evidence');
|
|
14
15
|
|
|
15
16
|
function getExecOptions() {
|
|
16
17
|
return { encoding: 'utf8', cwd: process.cwd(), timeout: 120000 };
|
|
@@ -380,21 +381,24 @@ async function executeDev(featureName, options = {}) {
|
|
|
380
381
|
// Use --phase flag to explicitly specify GREEN or REFACTOR.
|
|
381
382
|
currentPhase = detectTDDPhase({ sourceFiles, testFiles, testsPassing });
|
|
382
383
|
|
|
383
|
-
|
|
384
|
+
const result = {
|
|
384
385
|
success: true,
|
|
385
386
|
detectedPhase: currentPhase,
|
|
386
387
|
autoDetected: true,
|
|
387
388
|
guidance: getTDDGuidance(currentPhase),
|
|
388
389
|
summary: `Default ${currentPhase} phase (use --phase flag for explicit phase control)`,
|
|
389
390
|
};
|
|
391
|
+
|
|
392
|
+
return withDevAuditEvidence(featureName, currentPhase, result, options);
|
|
390
393
|
}
|
|
391
394
|
|
|
392
395
|
// Validate REFACTOR requires passing tests
|
|
393
396
|
if (phase === 'REFACTOR' && testsPassing === false) {
|
|
394
|
-
|
|
397
|
+
const result = {
|
|
395
398
|
success: false,
|
|
396
399
|
error: 'Cannot proceed to REFACTOR phase: tests are failing. Complete GREEN phase first.',
|
|
397
400
|
};
|
|
401
|
+
return withDevAuditEvidence(featureName, currentPhase, result, options);
|
|
398
402
|
}
|
|
399
403
|
|
|
400
404
|
// Execute based on phase
|
|
@@ -409,7 +413,8 @@ async function executeDev(featureName, options = {}) {
|
|
|
409
413
|
result.summary = 'Write failing tests for the feature';
|
|
410
414
|
} else if (currentPhase === 'GREEN') {
|
|
411
415
|
// Run tests to check status
|
|
412
|
-
const
|
|
416
|
+
const runPhaseTests = options.runTests || runTests;
|
|
417
|
+
const testResults = await runPhaseTests();
|
|
413
418
|
result.testResults = testResults;
|
|
414
419
|
result.success = testResults.success; // Reflect actual test outcome
|
|
415
420
|
if (!testResults.success) {
|
|
@@ -422,7 +427,7 @@ async function executeDev(featureName, options = {}) {
|
|
|
422
427
|
result.summary = 'Improve code quality while keeping tests green';
|
|
423
428
|
}
|
|
424
429
|
|
|
425
|
-
return result;
|
|
430
|
+
return withDevAuditEvidence(featureName, currentPhase, result, options);
|
|
426
431
|
} catch (error) {
|
|
427
432
|
return {
|
|
428
433
|
success: false,
|
|
@@ -431,6 +436,74 @@ async function executeDev(featureName, options = {}) {
|
|
|
431
436
|
}
|
|
432
437
|
}
|
|
433
438
|
|
|
439
|
+
function withDevAuditEvidence(featureName, phase, result, options = {}) {
|
|
440
|
+
if (!options.audit) {
|
|
441
|
+
return result;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
const auditEvent = {
|
|
445
|
+
issueId: options.issueId,
|
|
446
|
+
phase,
|
|
447
|
+
taskTitle: `forge dev ${featureName}`,
|
|
448
|
+
prompt: `forge dev ${featureName} ${phase}`,
|
|
449
|
+
response: result.success === false
|
|
450
|
+
? result.error || result.summary || result.guidance || ''
|
|
451
|
+
: result.summary || result.error || result.guidance || '',
|
|
452
|
+
verdict: result.success === false ? 'FAIL' : 'PASS',
|
|
453
|
+
metadata: {
|
|
454
|
+
featureName,
|
|
455
|
+
phase,
|
|
456
|
+
detectedPhase: result.detectedPhase,
|
|
457
|
+
nextPhase: result.nextPhase,
|
|
458
|
+
autoDetected: Boolean(result.autoDetected),
|
|
459
|
+
success: result.success !== false,
|
|
460
|
+
},
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
try {
|
|
464
|
+
const auditEvidence = emitImplementerAuditEvidence(auditEvent, options.auditOptions || {});
|
|
465
|
+
if (auditEvidence.record?.success === false) {
|
|
466
|
+
const auditError = auditEvidence.record.error || 'bd audit record failed';
|
|
467
|
+
return {
|
|
468
|
+
...result,
|
|
469
|
+
success: false,
|
|
470
|
+
error: result.success === false ? result.error : `Audit evidence persistence failed: ${auditError}`,
|
|
471
|
+
auditEvidence,
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
return {
|
|
476
|
+
...result,
|
|
477
|
+
auditEvidence,
|
|
478
|
+
};
|
|
479
|
+
} catch (error) {
|
|
480
|
+
if (isAuditCommandUnavailableError(error)) {
|
|
481
|
+
return {
|
|
482
|
+
...result,
|
|
483
|
+
auditEvidence: {
|
|
484
|
+
success: false,
|
|
485
|
+
skipped: true,
|
|
486
|
+
error: error.message,
|
|
487
|
+
},
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
return {
|
|
492
|
+
...result,
|
|
493
|
+
success: false,
|
|
494
|
+
error: result.success === false ? result.error : `Audit evidence persistence failed: ${error.message}`,
|
|
495
|
+
auditEvidence: {
|
|
496
|
+
success: false,
|
|
497
|
+
error: error.message,
|
|
498
|
+
},
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
function isAuditCommandUnavailableError(error) {
|
|
504
|
+
return error?.code === 'ENOENT' || /\bbd\b.*not found/i.test(error?.message || '');
|
|
505
|
+
}
|
|
506
|
+
|
|
434
507
|
/**
|
|
435
508
|
* Decision gate route constants
|
|
436
509
|
*
|
|
@@ -557,12 +630,109 @@ function verifyTaskCompletion(taskTitle, ownedFiles, opts = {}) {
|
|
|
557
630
|
return { committed: true, autoCommitted: true, commitSha, hasChanges: true };
|
|
558
631
|
}
|
|
559
632
|
|
|
633
|
+
function emitDevSubagentAuditEvidence(role, phase, event = {}, options = {}) {
|
|
634
|
+
const safeEvent = event && typeof event === 'object' ? event : {};
|
|
635
|
+
return recordAndLabelSubagentAuditEvent({
|
|
636
|
+
...safeEvent,
|
|
637
|
+
command: 'dev',
|
|
638
|
+
role,
|
|
639
|
+
phase: phase || safeEvent.phase,
|
|
640
|
+
}, options);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
function emitImplementerAuditEvidence(event, options = {}) {
|
|
644
|
+
return emitDevSubagentAuditEvidence('implementer', event?.phase || 'GREEN', event, options);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
function emitSpecReviewerAuditEvidence(event, options = {}) {
|
|
648
|
+
return emitDevSubagentAuditEvidence('spec_reviewer', 'SPEC', event, options);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
function emitQualityReviewerAuditEvidence(event, options = {}) {
|
|
652
|
+
return emitDevSubagentAuditEvidence('quality_reviewer', 'QUALITY', event, options);
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
function isMissingDevFlagValue(value) {
|
|
656
|
+
return value === undefined || value === '' || (typeof value === 'string' && value.startsWith('--'));
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
function missingDevFlagValue(name, parsedArgs, flags) {
|
|
660
|
+
return { args: parsedArgs, flags, error: `${name} requires a value` };
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
function consumeSeparatedDevFlag(name, key, rawArgs, index, parsedArgs, flags) {
|
|
664
|
+
const value = rawArgs[index + 1];
|
|
665
|
+
if (isMissingDevFlagValue(value)) {
|
|
666
|
+
return missingDevFlagValue(name, parsedArgs, flags);
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
flags[key] = value;
|
|
670
|
+
return { consumed: 2 };
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
function consumeEqualsDevFlag(prefix, name, key, arg, parsedArgs, flags) {
|
|
674
|
+
const value = arg.slice(prefix.length);
|
|
675
|
+
if (value === '') {
|
|
676
|
+
return missingDevFlagValue(name, parsedArgs, flags);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
flags[key] = value;
|
|
680
|
+
return { consumed: 1 };
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
function consumeDevFlag(rawArgs, index, parsedArgs, flags) {
|
|
684
|
+
const arg = rawArgs[index];
|
|
685
|
+
if (arg === '--issue-id') {
|
|
686
|
+
return consumeSeparatedDevFlag('--issue-id', 'issueId', rawArgs, index, parsedArgs, flags);
|
|
687
|
+
}
|
|
688
|
+
if (typeof arg === 'string' && arg.startsWith('--issue-id=')) {
|
|
689
|
+
return consumeEqualsDevFlag('--issue-id=', '--issue-id', 'issueId', arg, parsedArgs, flags);
|
|
690
|
+
}
|
|
691
|
+
if (arg === '--phase') {
|
|
692
|
+
return consumeSeparatedDevFlag('--phase', 'phase', rawArgs, index, parsedArgs, flags);
|
|
693
|
+
}
|
|
694
|
+
if (typeof arg === 'string' && arg.startsWith('--phase=')) {
|
|
695
|
+
return consumeEqualsDevFlag('--phase=', '--phase', 'phase', arg, parsedArgs, flags);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
return { consumed: 0 };
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
function parseDevHandlerInput(rawArgs = [], rawFlags = {}) {
|
|
702
|
+
const parsedArgs = [];
|
|
703
|
+
const flags = { ...rawFlags };
|
|
704
|
+
if (flags['issue-id'] && !flags.issueId) {
|
|
705
|
+
flags.issueId = flags['issue-id'];
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
for (let i = 0; i < rawArgs.length; i++) {
|
|
709
|
+
const consumed = consumeDevFlag(rawArgs, i, parsedArgs, flags);
|
|
710
|
+
if (consumed.error) {
|
|
711
|
+
return consumed;
|
|
712
|
+
}
|
|
713
|
+
if (consumed.consumed > 0) {
|
|
714
|
+
i += consumed.consumed - 1;
|
|
715
|
+
continue;
|
|
716
|
+
}
|
|
717
|
+
parsedArgs.push(rawArgs[i]);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
return { args: parsedArgs, flags };
|
|
721
|
+
}
|
|
722
|
+
|
|
560
723
|
module.exports = {
|
|
561
724
|
name: 'dev',
|
|
562
725
|
description: 'Run the TDD development stage with phase guidance',
|
|
563
726
|
handler: async (args, flags = {}) => {
|
|
564
|
-
const
|
|
565
|
-
|
|
727
|
+
const parsed = parseDevHandlerInput(args, flags);
|
|
728
|
+
if (parsed.error) {
|
|
729
|
+
return {
|
|
730
|
+
success: false,
|
|
731
|
+
error: parsed.error,
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
const featureName = parsed.args[0] || 'feature';
|
|
735
|
+
const phaseInput = parsed.flags.phase || parsed.args[1];
|
|
566
736
|
const phase = typeof phaseInput === 'string' ? phaseInput.toUpperCase() : undefined;
|
|
567
737
|
if (phase && !['RED', 'GREEN', 'REFACTOR'].includes(phase)) {
|
|
568
738
|
return {
|
|
@@ -571,7 +741,12 @@ module.exports = {
|
|
|
571
741
|
};
|
|
572
742
|
}
|
|
573
743
|
|
|
574
|
-
const result = await executeDev(featureName,
|
|
744
|
+
const result = await executeDev(featureName, {
|
|
745
|
+
...(phase ? { phase } : {}),
|
|
746
|
+
audit: true,
|
|
747
|
+
issueId: parsed.flags.issueId,
|
|
748
|
+
auditOptions: parsed.flags.auditOptions,
|
|
749
|
+
});
|
|
575
750
|
if (!result.success) {
|
|
576
751
|
return result;
|
|
577
752
|
}
|
|
@@ -591,6 +766,9 @@ module.exports = {
|
|
|
591
766
|
generateCommitMessage,
|
|
592
767
|
identifyParallelWork,
|
|
593
768
|
executeDev,
|
|
769
|
+
emitImplementerAuditEvidence,
|
|
770
|
+
emitSpecReviewerAuditEvidence,
|
|
771
|
+
emitQualityReviewerAuditEvidence,
|
|
594
772
|
calculateDecisionRoute,
|
|
595
773
|
DECISION_ROUTES,
|
|
596
774
|
verifyTaskCompletion,
|