@khoavu882/doflow 0.0.0-stage → 2.0.0-beta.3
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/LICENSE +21 -0
- package/README.md +132 -2
- package/bin/doflow.js +44 -0
- package/core/.antigravity-plugin/hooks.json +39 -0
- package/core/.antigravity-plugin/mcp_config.json +18 -0
- package/core/.antigravity-plugin/plugin.json +31 -0
- package/core/.claude-plugin/marketplace.json +20 -0
- package/core/.claude-plugin/plugin.json +21 -0
- package/core/.codex-plugin/marketplace.json +20 -0
- package/core/.codex-plugin/plugin.json +35 -0
- package/core/.plugin/plugin.json +19 -0
- package/core/harnesses/antigravity/hooks/pre-implementation-gate.sh +9 -0
- package/core/harnesses/antigravity/hooks/stop-check.sh +10 -0
- package/core/harnesses/claude/hooks/lib.sh +304 -0
- package/core/harnesses/claude/hooks/mcp-tool-guard.sh +20 -0
- package/core/harnesses/claude/hooks/permission-audit.sh +47 -0
- package/core/harnesses/claude/hooks/post-compact.sh +74 -0
- package/core/harnesses/claude/hooks/post-edit-lint.sh +36 -0
- package/core/harnesses/claude/hooks/post-tool-failure.sh +47 -0
- package/core/harnesses/claude/hooks/pre-bash-guard.sh +20 -0
- package/core/harnesses/claude/hooks/pre-compact.sh +43 -0
- package/core/harnesses/claude/hooks/pre-implement-gate.sh +21 -0
- package/core/harnesses/claude/hooks/session-end.sh +89 -0
- package/core/harnesses/claude/hooks/session-start.sh +5 -0
- package/core/harnesses/claude/hooks/skill-config-audit.sh +39 -0
- package/core/harnesses/claude/hooks/stop-check.sh +5 -0
- package/core/harnesses/claude/hooks/subagent-audit.sh +7 -0
- package/core/harnesses/claude/hooks/user-prompt-submit.sh +5 -0
- package/core/harnesses/claude/settings/keybindings.json +20 -0
- package/core/harnesses/claude/settings/settings.json +201 -0
- package/core/harnesses/claude/statusline/doflow-statusline.sh +49 -0
- package/core/harnesses/codex/agents/core-implementer.toml +7 -0
- package/core/harnesses/codex/agents/quality-guardian.toml +8 -0
- package/core/harnesses/codex/agents/research-writer.toml +8 -0
- package/core/harnesses/codex/agents/spec-analyst.toml +8 -0
- package/core/harnesses/codex/agents/system-architect.toml +9 -0
- package/core/harnesses/codex/config/config.toml +10 -0
- package/core/harnesses/codex/hooks/hooks.json +122 -0
- package/core/harnesses/codex/hooks/lib.sh +335 -0
- package/core/harnesses/codex/hooks/mcp-tool-guard.sh +18 -0
- package/core/harnesses/codex/hooks/post-edit-lint.impl.sh +52 -0
- package/core/harnesses/codex/hooks/post-edit-lint.sh +6 -0
- package/core/harnesses/codex/hooks/pre-bash-guard.sh +18 -0
- package/core/harnesses/codex/hooks/pre-compact.impl.sh +46 -0
- package/core/harnesses/codex/hooks/pre-compact.sh +9 -0
- package/core/harnesses/codex/hooks/pre-implement-gate.sh +19 -0
- package/core/harnesses/codex/hooks/session-end.impl.sh +92 -0
- package/core/harnesses/codex/hooks/session-end.sh +5 -0
- package/core/harnesses/codex/hooks/session-start.sh +5 -0
- package/core/harnesses/codex/hooks/stop-check.sh +8 -0
- package/core/harnesses/codex/hooks/subagent-audit.sh +8 -0
- package/core/harnesses/codex/hooks/user-prompt-submit.sh +6 -0
- package/core/harnesses/gemini/hooks/hooks.json +77 -0
- package/core/harnesses/gemini/hooks/lib.sh +302 -0
- package/core/harnesses/gemini/hooks/mcp-tool-guard.sh +21 -0
- package/core/harnesses/gemini/hooks/post-edit-lint.sh +39 -0
- package/core/harnesses/gemini/hooks/pre-bash-guard.sh +21 -0
- package/core/harnesses/gemini/hooks/pre-compact.sh +38 -0
- package/core/harnesses/gemini/hooks/pre-implement-gate.sh +22 -0
- package/core/harnesses/gemini/hooks/session-end.impl.sh +89 -0
- package/core/harnesses/gemini/hooks/session-end.sh +5 -0
- package/core/harnesses/gemini/hooks/session-start.sh +5 -0
- package/core/harnesses/gemini/settings/adapter-defaults.json +4 -0
- package/core/harnesses/kiro/agents/doflow.json +58 -0
- package/core/harnesses/kiro/hooks/doflow.json +53 -0
- package/core/harnesses/kiro/hooks/lib.sh +324 -0
- package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +9 -0
- package/core/harnesses/kiro/hooks/pre-bash-guard.sh +9 -0
- package/core/harnesses/kiro/hooks/pre-implement-gate.sh +9 -0
- package/core/harnesses/kiro/hooks/session-start.sh +9 -0
- package/core/harnesses/kiro/hooks/stop-check.sh +43 -0
- package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +39 -0
- package/core/harnesses/shared/hooks/adapters/antigravity.js +111 -0
- package/core/harnesses/shared/hooks/adapters/arg-fields.js +19 -0
- package/core/harnesses/shared/hooks/adapters/gemini.js +114 -0
- package/core/harnesses/shared/hooks/hooks.json +47 -0
- package/core/harnesses/shared/hooks/policies/blocked-patterns.conf +91 -0
- package/core/harnesses/shared/hooks/policies/capture-failure.sh +97 -0
- package/core/harnesses/shared/hooks/policies/deny-json.sh +29 -0
- package/core/harnesses/shared/hooks/policies/lib.sh +501 -0
- package/core/harnesses/shared/hooks/policies/mcp-policy.conf +21 -0
- package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +91 -0
- package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +328 -0
- package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +496 -0
- package/core/harnesses/shared/hooks/policies/prompt-nudge.jq +131 -0
- package/core/harnesses/shared/hooks/policies/session-context.sh +141 -0
- package/core/harnesses/shared/hooks/policies/stop-check.sh +264 -0
- package/core/harnesses/shared/hooks/policies/subagent-audit.sh +46 -0
- package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +235 -0
- package/core/harnesses/shared/hooks/stream-hook-runner.js +590 -0
- package/core/harnesses/shared/locator/doflow-run +87 -0
- package/core/registry/advice.json +101 -0
- package/core/registry/assets.json +792 -0
- package/core/registry/capabilities.json +120 -0
- package/core/registry/contracts.json +189 -0
- package/core/registry/external-tools.json +191 -0
- package/core/registry/harnesses.json +2062 -0
- package/core/registry/lifecycle.json +231 -0
- package/core/registry/mcp.json +18 -0
- package/core/registry/models.json +79 -0
- package/core/registry/readiness-templates.json +118 -0
- package/core/registry/routes.json +47 -0
- package/core/registry/storage.json +1057 -0
- package/core/registry/verification.json +258 -0
- package/core/registry/workflows.json +790 -0
- package/core/shared/agent-specs/core-implementer.md +73 -0
- package/core/shared/agent-specs/quality-guardian.md +28 -0
- package/core/shared/agent-specs/research-writer.md +31 -0
- package/core/shared/agent-specs/spec-analyst.md +33 -0
- package/core/shared/agent-specs/system-architect.md +29 -0
- package/core/shared/guidance/DOFLOW_CORE.md +8 -0
- package/core/shared/guidance/FLAGS.md +25 -0
- package/core/shared/guidance/PRINCIPLES.md +61 -0
- package/core/shared/guidance/VERSION +1 -0
- package/core/shared/guidance/mcp/MCP_Context7.md +18 -0
- package/core/shared/guidance/mcp/MCP_Sequential.md +17 -0
- package/core/shared/guidance/modes/MODE_Brainstorming.md +46 -0
- package/core/shared/guidance/modes/MODE_DeepResearch.md +69 -0
- package/core/shared/guidance/modes/MODE_Introspection.md +33 -0
- package/core/shared/guidance/modes/MODE_Orchestration.md +57 -0
- package/core/shared/guidance/modes/MODE_Task_Management.md +74 -0
- package/core/shared/guidance/pointers/claude-gemini.md +2 -0
- package/core/shared/guidance/pointers/codex.md +6 -0
- package/core/shared/guidance/references/ARTIFACT_FORMAT.md +373 -0
- package/core/shared/guidance/references/ARTIFACT_VOICE.md +104 -0
- package/core/shared/guidance/references/CONSTITUTION_BASE.md +47 -0
- package/core/shared/guidance/references/DIAGRAM_GUIDE.md +161 -0
- package/core/shared/guidance/references/DOFLOW_CHAIN.md +87 -0
- package/core/shared/guidance/references/EVIDENCE_LEDGER.md +93 -0
- package/core/shared/guidance/references/MODEL_SELECTION.md +74 -0
- package/core/shared/guidance/references/ORCHESTRATION.md +36 -0
- package/core/shared/guidance/references/RESEARCH_CONFIG.md +21 -0
- package/core/shared/guidance/references/WORKFLOW_HANDOFF.md +81 -0
- package/core/shared/guidance/rules/RULE_01_SAFETY.md +25 -0
- package/core/shared/guidance/rules/RULE_02_WORKFLOW.md +23 -0
- package/core/shared/guidance/rules/RULE_03_QUALITY.md +14 -0
- package/core/shared/guidance/rules/RULE_04_QUESTIONS.md +46 -0
- package/core/shared/scripts/doflow/assets/mermaid-theme.json +46 -0
- package/core/shared/scripts/doflow/bash/do-exec-paths.sh +167 -0
- package/core/shared/scripts/doflow/bash/do-git-state.sh +546 -0
- package/core/shared/scripts/doflow/bash/do-parallel-check.sh +208 -0
- package/core/shared/scripts/doflow/bash/do-paths.sh +347 -0
- package/core/shared/scripts/doflow/bash/do-prereqs.sh +66 -0
- package/core/shared/scripts/doflow/bash/do-review-package.sh +127 -0
- package/core/shared/scripts/doflow/bash/do-task-brief.sh +698 -0
- package/core/shared/scripts/doflow/bash/render-audit.sh +224 -0
- package/core/shared/scripts/doflow/bash/render-diagrams.sh +177 -0
- package/core/shared/scripts/doflow/bash/render-puml.sh +223 -0
- package/core/shared/scripts/doflow/bash/sync-context.sh +66 -0
- package/core/shared/scripts/doflow/bash/validate-artifacts.sh +526 -0
- package/core/shared/scripts/doflow/bin/doflow-run +592 -0
- package/core/shared/skills/do/SKILL.md +128 -0
- package/core/shared/skills/do/references/estimation.md +13 -0
- package/core/shared/skills/do/references/pm_routing.md +25 -0
- package/core/shared/skills/do/references/tool_matrix.md +52 -0
- package/core/shared/skills/do-brainstorm/SKILL.md +252 -0
- package/core/shared/skills/do-code-review/README.md +49 -0
- package/core/shared/skills/do-code-review/SKILL.md +333 -0
- package/core/shared/skills/do-code-review/assets/sample_c_clean.c +71 -0
- package/core/shared/skills/do-code-review/assets/sample_c_smells.c +66 -0
- package/core/shared/skills/do-code-review/assets/sample_cpp_shift.cpp +19 -0
- package/core/shared/skills/do-code-review/assets/sample_csharp_clean.cs +100 -0
- package/core/shared/skills/do-code-review/assets/sample_csharp_smells.cs +78 -0
- package/core/shared/skills/do-code-review/assets/sample_java_clean.java +55 -0
- package/core/shared/skills/do-code-review/assets/sample_java_smells.java +56 -0
- package/core/shared/skills/do-code-review/assets/sample_json_clean.json +7 -0
- package/core/shared/skills/do-code-review/assets/sample_markdown_clean.md +30 -0
- package/core/shared/skills/do-code-review/assets/sample_markdown_smells.md +29 -0
- package/core/shared/skills/do-code-review/assets/sample_shell_heredoc.sh +38 -0
- package/core/shared/skills/do-code-review/assets/sample_shell_smells.sh +15 -0
- package/core/shared/skills/do-code-review/assets/sample_typescript_strings.ts +36 -0
- package/core/shared/skills/do-code-review/assets/sample_yaml_smells.yaml +6 -0
- package/core/shared/skills/do-code-review/content-types/config.md +83 -0
- package/core/shared/skills/do-code-review/content-types/markdown.md +132 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_c_clean_quality.json +79 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_c_smells_quality.json +169 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_cpp_shift_quality.json +49 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_csharp_clean_quality.json +149 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_csharp_smells_quality.json +157 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_java_clean_quality.json +67 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_java_smells_quality.json +97 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_json_clean_quality.json +33 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_markdown_clean_quality.json +1 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_markdown_smells_quality.json +16 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_shell_heredoc_quality.json +54 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_shell_smells_quality.json +91 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_typescript_strings_quality.json +60 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_yaml_smells_quality.json +46 -0
- package/core/shared/skills/do-code-review/languages/c.md +103 -0
- package/core/shared/skills/do-code-review/languages/cpp.md +103 -0
- package/core/shared/skills/do-code-review/languages/csharp.md +97 -0
- package/core/shared/skills/do-code-review/languages/dart.md +108 -0
- package/core/shared/skills/do-code-review/languages/go.md +92 -0
- package/core/shared/skills/do-code-review/languages/java.md +103 -0
- package/core/shared/skills/do-code-review/languages/kotlin.md +88 -0
- package/core/shared/skills/do-code-review/languages/php.md +109 -0
- package/core/shared/skills/do-code-review/languages/python.md +94 -0
- package/core/shared/skills/do-code-review/languages/ruby.md +105 -0
- package/core/shared/skills/do-code-review/languages/rust.md +99 -0
- package/core/shared/skills/do-code-review/languages/shell.md +90 -0
- package/core/shared/skills/do-code-review/languages/swift.md +88 -0
- package/core/shared/skills/do-code-review/languages/typescript.md +97 -0
- package/core/shared/skills/do-code-review/review-policy.json +47 -0
- package/core/shared/skills/do-code-review/rules/universal.md +49 -0
- package/core/shared/skills/do-code-review/scripts/code_quality_checker.py +1696 -0
- package/core/shared/skills/do-code-review/scripts/doc_quality_checker.py +532 -0
- package/core/shared/skills/do-code-review/scripts/pr_analyzer.py +620 -0
- package/core/shared/skills/do-code-review/scripts/review_report_generator.py +505 -0
- package/core/shared/skills/do-constitution/SKILL.md +72 -0
- package/core/shared/skills/do-design/SKILL.md +212 -0
- package/core/shared/skills/do-diagnose/SKILL.md +156 -0
- package/core/shared/skills/do-diagnose/references/code_audit.md +15 -0
- package/core/shared/skills/do-diagnose/references/refactoring.md +12 -0
- package/core/shared/skills/do-diagnose/references/root_cause.md +17 -0
- package/core/shared/skills/do-document/SKILL.md +81 -0
- package/core/shared/skills/do-document/references/api-reference.md +42 -0
- package/core/shared/skills/do-document/references/deep_research.md +18 -0
- package/core/shared/skills/do-document/references/embedded-research.md +11 -0
- package/core/shared/skills/do-document/references/implementation-flow.md +105 -0
- package/core/shared/skills/do-document/references/index_generator.md +9 -0
- package/core/shared/skills/do-document/references/user-guide.md +22 -0
- package/core/shared/skills/do-execute-plan/SKILL.md +261 -0
- package/core/shared/skills/do-execute-plan/references/handoff_record.md +57 -0
- package/core/shared/skills/do-execute-plan/references/parallel_dispatch.md +92 -0
- package/core/shared/skills/do-execute-plan/references/readiness_gate.md +155 -0
- package/core/shared/skills/do-execute-plan/references/run_position.md +63 -0
- package/core/shared/skills/do-execute-plan/references/scaffold.md +441 -0
- package/core/shared/skills/do-execute-plan/references/task_attempts.md +41 -0
- package/core/shared/skills/do-flow/SKILL.md +186 -0
- package/core/shared/skills/do-flow/references/task_classes.md +134 -0
- package/core/shared/skills/do-git/SKILL.md +115 -0
- package/core/shared/skills/do-git/references/hotfix-ritual.md +44 -0
- package/core/shared/skills/do-git/references/lifecycle-policy.md +54 -0
- package/core/shared/skills/do-git/references/release-ritual.md +64 -0
- package/core/shared/skills/do-implement/SKILL.md +222 -0
- package/core/shared/skills/do-plan/SKILL.md +219 -0
- package/core/shared/skills/do-test/SKILL.md +113 -0
- package/core/shared/templates/doflow/constitution-template.md +28 -0
- package/core/shared/templates/doflow/data-model-template.md +169 -0
- package/core/shared/templates/doflow/design-template.md +193 -0
- package/core/shared/templates/doflow/external-contract-template.md +35 -0
- package/core/shared/templates/doflow/intent-template.md +45 -0
- package/core/shared/templates/doflow/plan-template.md +151 -0
- package/core/shared/templates/doflow/question-log-template.md +51 -0
- package/core/shared/templates/doflow/requirement-template.md +126 -0
- package/core/shared/templates/doflow/specs-template.md +55 -0
- package/core/shared/templates/doflow/state-template.md +59 -0
- package/core/shared/workflows/do-flow-chain.md +17 -0
- package/package.json +46 -4
- package/src/adapters/antigravity/index.ts +631 -0
- package/src/adapters/claude/index.ts +548 -0
- package/src/adapters/claude/mcp.ts +94 -0
- package/src/adapters/codex/agents.ts +208 -0
- package/src/adapters/codex/config.ts +272 -0
- package/src/adapters/codex/hooks.ts +203 -0
- package/src/adapters/codex/index.ts +707 -0
- package/src/adapters/codex/mcp.ts +271 -0
- package/src/adapters/codex/native-projection.ts +34 -0
- package/src/adapters/copilot/index.ts +413 -0
- package/src/adapters/copy-tree.ts +620 -0
- package/src/adapters/gemini/hooks.ts +210 -0
- package/src/adapters/gemini/index.ts +390 -0
- package/src/adapters/hook-commands.ts +60 -0
- package/src/adapters/index.ts +106 -0
- package/src/adapters/kiro/index.ts +310 -0
- package/src/adapters/mcp-entries.ts +331 -0
- package/src/adapters/opencode/index.ts +466 -0
- package/src/adapters/pi/index.ts +279 -0
- package/src/adapters/pi/json-members.ts +185 -0
- package/src/adapters/pi/mcp.ts +373 -0
- package/src/adapters/resolve-source.ts +19 -0
- package/src/cli/commands/install.ts +218 -0
- package/src/cli/commands/list-backups.ts +21 -0
- package/src/cli/commands/reconcile.ts +120 -0
- package/src/cli/commands/remove.ts +82 -0
- package/src/cli/commands/rollback.ts +172 -0
- package/src/cli/commands/self-update.ts +33 -0
- package/src/cli/commands/status.ts +138 -0
- package/src/cli/commands/tools.ts +92 -0
- package/src/cli/commands/update.ts +162 -0
- package/src/cli/index.ts +568 -0
- package/src/cli/runtime-commands.ts +281 -0
- package/src/cli/shared.ts +218 -0
- package/src/helper/bash-helper.ts +34 -0
- package/src/helper/git.ts +24 -0
- package/src/helper/guardrails.ts +49 -0
- package/src/helper/harness-paths.ts +140 -0
- package/src/helper/marker-merge.ts +116 -0
- package/src/helper/prompt.ts +61 -0
- package/src/helper/repo-root.ts +29 -0
- package/src/helper/settings-merge.ts +151 -0
- package/src/helper/settings-scope.ts +33 -0
- package/src/helper/toml.ts +244 -0
- package/src/install/backup-set.ts +149 -0
- package/src/install/backup.ts +724 -0
- package/src/install/context.ts +58 -0
- package/src/install/manifest.ts +145 -0
- package/src/install/mcp.ts +254 -0
- package/src/install/paths.ts +84 -0
- package/src/install/targets.ts +90 -0
- package/src/install/tool-lifecycle.ts +151 -0
- package/src/lifecycle/bash-availability.ts +25 -0
- package/src/lifecycle/index.ts +812 -0
- package/src/lifecycle/mcp-index.ts +28 -0
- package/src/lifecycle/policies.ts +73 -0
- package/src/lifecycle/view.ts +175 -0
- package/src/registry/index.ts +611 -0
- package/src/release/sync-plugin-versions.ts +66 -0
- package/src/runtime/advice/cli.ts +283 -0
- package/src/runtime/advice/client.ts +324 -0
- package/src/runtime/advice/config.ts +189 -0
- package/src/runtime/advice/doctor.ts +169 -0
- package/src/runtime/advice/endpoint-guard.ts +134 -0
- package/src/runtime/advice/kinds.ts +154 -0
- package/src/runtime/advice/providers/ollama-systemone.ts +209 -0
- package/src/runtime/advice/record.ts +166 -0
- package/src/runtime/advice/registry.ts +170 -0
- package/src/runtime/advice/strength.ts +66 -0
- package/src/runtime/brief-tools.ts +342 -0
- package/src/runtime/c4-project.ts +371 -0
- package/src/runtime/capability-router.ts +484 -0
- package/src/runtime/checkouts.ts +170 -0
- package/src/runtime/claims.ts +468 -0
- package/src/runtime/cli-result.ts +55 -0
- package/src/runtime/cli.ts +678 -0
- package/src/runtime/command-detect.ts +516 -0
- package/src/runtime/context-pack.ts +492 -0
- package/src/runtime/decision-register.ts +493 -0
- package/src/runtime/evidence-ledger.ts +338 -0
- package/src/runtime/failure/capture.ts +272 -0
- package/src/runtime/failure/classifier.ts +68 -0
- package/src/runtime/failure/cli.ts +178 -0
- package/src/runtime/failure/home.ts +64 -0
- package/src/runtime/failure/store.ts +226 -0
- package/src/runtime/feature-resolve.ts +79 -0
- package/src/runtime/freshness.ts +177 -0
- package/src/runtime/health.ts +863 -0
- package/src/runtime/history-compactor.ts +237 -0
- package/src/runtime/implementation-gate.ts +321 -0
- package/src/runtime/inventory/coverage.ts +218 -0
- package/src/runtime/inventory/identity.ts +65 -0
- package/src/runtime/inventory/index.ts +705 -0
- package/src/runtime/inventory/precedence.ts +134 -0
- package/src/runtime/inventory/read-scopes.ts +131 -0
- package/src/runtime/inventory/siblings.ts +192 -0
- package/src/runtime/knowledge/chunker.ts +124 -0
- package/src/runtime/knowledge/hybrid.ts +149 -0
- package/src/runtime/knowledge/index-store.ts +145 -0
- package/src/runtime/knowledge/retrieval.ts +194 -0
- package/src/runtime/leak-scan.ts +185 -0
- package/src/runtime/lifecycle/cli.ts +276 -0
- package/src/runtime/lifecycle/event-store.ts +340 -0
- package/src/runtime/lifecycle/fold.ts +353 -0
- package/src/runtime/lifecycle/followup.ts +432 -0
- package/src/runtime/lifecycle/goal.ts +249 -0
- package/src/runtime/lifecycle/intent-writer.ts +86 -0
- package/src/runtime/lifecycle/overview.ts +292 -0
- package/src/runtime/lifecycle/release.ts +241 -0
- package/src/runtime/lifecycle/report-store.ts +221 -0
- package/src/runtime/lifecycle/retention.ts +212 -0
- package/src/runtime/lifecycle/root.ts +71 -0
- package/src/runtime/lifecycle/status.ts +353 -0
- package/src/runtime/lifecycle/store-upkeep.ts +393 -0
- package/src/runtime/locator-resolve.ts +158 -0
- package/src/runtime/mask.ts +210 -0
- package/src/runtime/mcp-consultations.ts +412 -0
- package/src/runtime/mcp-reach.ts +157 -0
- package/src/runtime/model-router.ts +153 -0
- package/src/runtime/outcome.ts +467 -0
- package/src/runtime/reach.ts +148 -0
- package/src/runtime/readiness-record.ts +150 -0
- package/src/runtime/readiness.ts +435 -0
- package/src/runtime/recovery.ts +282 -0
- package/src/runtime/research-request.ts +231 -0
- package/src/runtime/retrieval-plan.ts +578 -0
- package/src/runtime/scaffold/artifacts.ts +217 -0
- package/src/runtime/scaffold/fingerprint.ts +56 -0
- package/src/runtime/scaffold/generate.ts +911 -0
- package/src/runtime/scaffold/languages.ts +245 -0
- package/src/runtime/storage/cli.ts +64 -0
- package/src/runtime/storage/engine.ts +249 -0
- package/src/runtime/storage/registry.ts +130 -0
- package/src/runtime/storage/roots.ts +63 -0
- package/src/runtime/storage/rules.ts +282 -0
- package/src/runtime/storage/upkeep.ts +243 -0
- package/src/runtime/storage/work-status.ts +326 -0
- package/src/runtime/task-attempts.ts +415 -0
- package/src/runtime/task-classifier.ts +550 -0
- package/src/runtime/task-scope.ts +130 -0
- package/src/runtime/task-state.ts +176 -0
- package/src/runtime/trace/indicators.ts +235 -0
- package/src/runtime/trace/ledger.ts +626 -0
- package/src/runtime/trace/render.ts +76 -0
- package/src/runtime/trace/views.ts +459 -0
- package/src/runtime/verification/contract-runner.ts +341 -0
- package/src/runtime/verification/engine.ts +1461 -0
- package/src/runtime/verification/registry.ts +130 -0
- package/src/runtime/verification/scope-bound.ts +418 -0
- package/src/runtime/verification/test-selection.ts +172 -0
- package/src/runtime/workflow-engine.ts +588 -0
- package/src/runtime/workflow-orchestrator.ts +953 -0
- package/src/runtime/worktree.ts +340 -0
- package/src/state/index.ts +193 -0
- package/src/state/lockfile.ts +136 -0
- package/src/state/run-lock.ts +408 -0
- package/types/node-commonjs.d.ts +68 -0
- package/types/runtime.d.ts +91 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: do-code-review
|
|
3
|
+
description: Code review automation for TypeScript, JavaScript, Python, Go, Swift, Kotlin, C#, .NET, Java, C, C++, Rust, Ruby, PHP, Dart/Flutter, and Shell, plus declarative YAML/JSON config and OpenAPI specs. Analyzes PRs for complexity and risk, checks code quality for SOLID violations and code smells, generates review reports. Use when reviewing pull requests, analyzing code quality, identifying issues, generating review checklists.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Code Reviewer
|
|
7
|
+
|
|
8
|
+
Automated code review tools for analyzing pull requests, detecting code quality issues, and generating review reports.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## How This Skill Is Organized
|
|
13
|
+
|
|
14
|
+
### Loading order for every review
|
|
15
|
+
|
|
16
|
+
1. This file (`SKILL.md`) — tools and thresholds
|
|
17
|
+
2. `rules/universal.md` — always, for every language
|
|
18
|
+
3. The matching `languages/*.md` — one file based on the extension table below
|
|
19
|
+
|
|
20
|
+
Two additional files for code (`rules/universal.md` + one `languages/*.md`); one for prose
|
|
21
|
+
(`content-types/markdown.md`, which has no universal counterpart).
|
|
22
|
+
|
|
23
|
+
| Extension(s) | Load |
|
|
24
|
+
|---|---|
|
|
25
|
+
| `.py` | `languages/python.md` |
|
|
26
|
+
| `.ts`, `.tsx`, `.js`, `.jsx`, `.mjs` | `languages/typescript.md` |
|
|
27
|
+
| `.go` | `languages/go.md` |
|
|
28
|
+
| `.swift` | `languages/swift.md` |
|
|
29
|
+
| `.kt`, `.kts` | `languages/kotlin.md` |
|
|
30
|
+
| `.cs`, `.csx`, `.razor`, `.cshtml` | `languages/csharp.md` |
|
|
31
|
+
| `.java` | `languages/java.md` |
|
|
32
|
+
| `.c`, `.h` | `languages/c.md` |
|
|
33
|
+
| `.cpp`, `.cc`, `.cxx`, `.hpp`, `.hh`, `.hxx` | `languages/cpp.md` |
|
|
34
|
+
| `.rs` | `languages/rust.md` |
|
|
35
|
+
| `.rb`, `.rake`, `.gemspec`, `.ru` | `languages/ruby.md` |
|
|
36
|
+
| `.php`, `.phtml` | `languages/php.md` |
|
|
37
|
+
| `.dart` | `languages/dart.md` |
|
|
38
|
+
| `.sh`, `.bash`, `.zsh` | `languages/shell.md` |
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
### Content-type dispatch
|
|
43
|
+
|
|
44
|
+
For non-code content, a second axis applies alongside (or instead of) the language table above:
|
|
45
|
+
|
|
46
|
+
| Content type | Extension(s) | Load |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| Markdown / prose | `.md` | `content-types/markdown.md` |
|
|
49
|
+
| Declarative config | `.yaml`, `.yml`, `.json` | `content-types/config.md` |
|
|
50
|
+
|
|
51
|
+
Markdown dispatch runs `scripts/doc_quality_checker.py` instead of `code_quality_checker.py` — see
|
|
52
|
+
`content-types/markdown.md` for the checks it performs. Declarative config stays with
|
|
53
|
+
`code_quality_checker.py`, which routes those extensions to a structural path that reports no
|
|
54
|
+
complexity, function count or SOLID verdict — see `content-types/config.md` for why.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## The Review Contract
|
|
59
|
+
|
|
60
|
+
State this before producing a single finding, and report against it when the review ends.
|
|
61
|
+
|
|
62
|
+
1. **The file set, and how it was derived** — the `pr_analyzer.py` diff between base and head, the
|
|
63
|
+
paths the user named, or the working tree. Name the derivation, not just the count. A file the
|
|
64
|
+
derivation includes but the review never opened is reported as not reviewed; it is never dropped
|
|
65
|
+
from the list.
|
|
66
|
+
2. **The rules files that will load** — from the dispatch tables above: `rules/universal.md` plus
|
|
67
|
+
one `languages/*.md` per code file, `content-types/markdown.md` per prose file. Name them before
|
|
68
|
+
loading them, so a file reviewed under the wrong rules is visible rather than plausible.
|
|
69
|
+
3. **What this review refuses to conclude** — it does not certify a file it did not open, does not
|
|
70
|
+
report a threshold the analyzer does not implement, and does not convert a score into a verdict
|
|
71
|
+
the table below does not define. A check that could not run is reported as not run.
|
|
72
|
+
4. **The coverage the analyzer actually achieved** — `code_quality_checker.py` reports
|
|
73
|
+
`files_analyzed`, `files_skipped` and a `coverage` of `complete` or `partial`. Report all three.
|
|
74
|
+
A `partial` coverage means the verdict describes the analysed subset, and saying so is not
|
|
75
|
+
optional: a score presented as if it covered the whole change is the defect this contract exists
|
|
76
|
+
to prevent.
|
|
77
|
+
5. **Process-leak scan** — run
|
|
78
|
+
`doflow leak-scan --path <each reviewed file> --json` over the reviewed set. These are DoFlow's
|
|
79
|
+
own identifiers (`FR-###`, `agent-docs/`, chain artifact names) reaching files that ship to
|
|
80
|
+
people who never used DoFlow. Occurrences inside `agent-docs/` are correct usage and the verb
|
|
81
|
+
excludes them itself. The verb reports and never blocks.
|
|
82
|
+
|
|
83
|
+
**Say which kind of repository you are scanning before you list anything.** A repository that
|
|
84
|
+
*uses* DoFlow should contain none of this vocabulary outside `agent-docs/`, so every finding is
|
|
85
|
+
worth a line. A repository that *implements* it — DoFlow's own tree, or any project vendoring the
|
|
86
|
+
chain — contains it correctly and by the hundred: its scaffold generator writes `requirement.md`,
|
|
87
|
+
its guards assert on `FR-###`, its changelog describes the chain. Listing those individually
|
|
88
|
+
teaches a reviewer to skip this step, and a skipped check protects nothing.
|
|
89
|
+
|
|
90
|
+
So: in an implementing repository, narrow the scan with `--exclude <segment>` (repeatable, and it
|
|
91
|
+
extends the artifact-directory exclusion rather than replacing it), and report the count you
|
|
92
|
+
excluded alongside the findings you kept. Never silently drop a path — the verb reports an
|
|
93
|
+
excluded file as `unscanned` with its reason, and so should you.
|
|
94
|
+
|
|
95
|
+
**Derive the exclusion set, do not judge it by eye.** What a repository *implements* is what its
|
|
96
|
+
package manifest ships plus its tests — for DoFlow that is `package.json`'s
|
|
97
|
+
`files: ["bin/", "src/", "core/"]`, so the set is `--exclude bin --exclude src --exclude core
|
|
98
|
+
--exclude test`. Reading "the code that ships onward" as a matter of judgement is how this step
|
|
99
|
+
was first narrowed wrong: `bin/` was left in and its internal requirement references were
|
|
100
|
+
reported as leaks, when `bin/` is as much DoFlow's implementation as `src/` is.
|
|
101
|
+
|
|
102
|
+
What survives that exclusion in an implementing repository is documentation *about* the chain —
|
|
103
|
+
a changelog, a docs tree — which contains the vocabulary correctly and in volume. Report the
|
|
104
|
+
count and say so, rather than pasting it. In DoFlow's own repository this step therefore has no
|
|
105
|
+
applicable surface at all, and saying that plainly is the honest result, not a failure to look.
|
|
106
|
+
|
|
107
|
+
**Stop when** every file in the reviewed set the contract names has an answer or a stated gap, **and** the last round produced no new file in the reviewed set. A round that only restates what you already have is the last round. Report the remaining gaps rather than continuing.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Tools
|
|
112
|
+
|
|
113
|
+
### PR Analyzer
|
|
114
|
+
|
|
115
|
+
Analyzes git diff between branches to assess review complexity and identify risks.
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# Analyze current branch against main
|
|
119
|
+
python scripts/pr_analyzer.py /path/to/repo
|
|
120
|
+
|
|
121
|
+
# Compare specific branches
|
|
122
|
+
python scripts/pr_analyzer.py . --base main --head feature-branch
|
|
123
|
+
|
|
124
|
+
# JSON output for integration
|
|
125
|
+
python scripts/pr_analyzer.py /path/to/repo --json
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Extracted — what the analyzer detects** (universal; see also the language file for
|
|
129
|
+
language-specific signals):
|
|
130
|
+
- Hardcoded secrets (passwords, API keys, tokens, connection strings)
|
|
131
|
+
- SQL / query injection patterns
|
|
132
|
+
- Debug statements left in production code
|
|
133
|
+
- Lint / analyzer suppression annotations
|
|
134
|
+
- TODO/FIXME comments
|
|
135
|
+
|
|
136
|
+
**Language-specific detections** are defined in each `languages/*.md` file.
|
|
137
|
+
|
|
138
|
+
**Inferred — what the report concludes from those detections:**
|
|
139
|
+
- Complexity score (1-10)
|
|
140
|
+
- Risk categorization (critical, high, medium, low)
|
|
141
|
+
- File prioritization for review order
|
|
142
|
+
- Commit message validation
|
|
143
|
+
|
|
144
|
+
Report the two halves apart. A detection is a locator in a file; a conclusion is your reading of
|
|
145
|
+
several of them, and merging them into one line is how a reading stops being falsifiable.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
### Code Quality Checker
|
|
150
|
+
|
|
151
|
+
Analyzes source code for structural issues, code smells, and SOLID violations.
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# Analyze a directory
|
|
155
|
+
python scripts/code_quality_checker.py /path/to/code
|
|
156
|
+
|
|
157
|
+
# Analyze specific language
|
|
158
|
+
# Valid values: python, typescript, javascript, go, swift, kotlin, csharp, java, c, cpp, rust, ruby, php, dart
|
|
159
|
+
python scripts/code_quality_checker.py . --language java
|
|
160
|
+
|
|
161
|
+
# JSON output
|
|
162
|
+
python scripts/code_quality_checker.py /path/to/code --json
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Universal thresholds:** declared in `review-policy.json`, never here. A guard fails the suite if a
|
|
166
|
+
number from it reappears in any document. Read what a run applies from the run: `--json` carries a
|
|
167
|
+
`policy` block naming the thresholds in force and the tiers that supplied them.
|
|
168
|
+
|
|
169
|
+
Three tiers resolve into one, lowest precedence first: the analyzer's built-in literal, the shipped
|
|
170
|
+
`review-policy.json` beside this file, then `agent-docs/review-policy.json` in the repository under
|
|
171
|
+
review, which a project's tech lead owns. A per-repo file is **partial** — declare only what you are
|
|
172
|
+
changing — and its absence is the ordinary state. A file that does not parse, names an unknown group,
|
|
173
|
+
or gives a threshold a non-integer value stops the analyzer naming the file and the problem rather
|
|
174
|
+
than reverting to defaults under a maintainer who believes their tuning applies. The policy also
|
|
175
|
+
declares severities, the verdict bands below, and the globs a review excludes.
|
|
176
|
+
|
|
177
|
+
The per-repo tier is found by walking up from the analysed path, so a target outside any repository
|
|
178
|
+
resolves none, which the `policy` block makes visible.
|
|
179
|
+
|
|
180
|
+
Language-specific checks are defined in each `languages/*.md` file.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
### Review Report Generator
|
|
185
|
+
|
|
186
|
+
Combines PR analysis and code quality findings into structured review reports.
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
# Generate report for current repo
|
|
190
|
+
python scripts/review_report_generator.py /path/to/repo
|
|
191
|
+
|
|
192
|
+
# Markdown output
|
|
193
|
+
python scripts/review_report_generator.py . --format markdown --output review.md
|
|
194
|
+
|
|
195
|
+
# Use pre-computed analyses
|
|
196
|
+
python scripts/review_report_generator.py . \
|
|
197
|
+
--pr-analysis pr_results.json \
|
|
198
|
+
--quality-analysis quality_results.json
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Verdicts:** the bands live in `review-policy.json` under `verdictBands`, for the same reason the
|
|
202
|
+
thresholds do. They are **declared, never applied**: they orient a reviewer reading a score, and
|
|
203
|
+
nothing computes the verdict from one. A verdict may therefore disagree with the band a score falls
|
|
204
|
+
in, provided the report says so and why.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Recording the Review
|
|
209
|
+
|
|
210
|
+
1. **Resolve the runtime seam** — every DoFlow runtime call in this skill goes through the runtime
|
|
211
|
+
seam. Resolve it **once** here and reuse `$DOFLOW` for every later call in this skill:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# Resolve the DoFlow runtime: nearest project install wins, then the global one.
|
|
215
|
+
D=$PWD; while [ "$D" != / ] && [ ! -x "$D/.doflow/scripts/doflow/bin/doflow-run" ]; do D=$(dirname "$D"); done
|
|
216
|
+
DOFLOW="$D/.doflow/scripts/doflow/bin/doflow-run"
|
|
217
|
+
[ -x "$DOFLOW" ] || DOFLOW="$HOME/.doflow/scripts/doflow/bin/doflow-run"
|
|
218
|
+
[ -x "$DOFLOW" ] || { echo "doflow: no runtime found in any .doflow/ above $PWD, nor at $HOME/.doflow. Run: npx @khoavu882/doflow install -t <harness>" >&2; exit 2; }
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Run every command below from the project root — the walk-up starts at `$PWD`. On exit 2, print
|
|
222
|
+
the message verbatim and stop; it names every path searched.
|
|
223
|
+
|
|
224
|
+
2. **Batch this stage's evidence** — one pass here at the stage boundary, never one call per fact.
|
|
225
|
+
`<task id>` is the unit these stores key on — the same id the chain's earlier stages recorded
|
|
226
|
+
against, or the feature slug when this review runs standalone. Use it for every `evidence` and
|
|
227
|
+
`claim` call this review makes:
|
|
228
|
+
```bash
|
|
229
|
+
"$DOFLOW" evidence --task-id "<task id>" --action add --batch <batch>.json --json
|
|
230
|
+
"$DOFLOW" claim --task-id "<task id>" --action add --statement "<one conclusion>"
|
|
231
|
+
```
|
|
232
|
+
Item schema, provenance rules, and the refused-field list: the guidance tree's
|
|
233
|
+
`references/EVIDENCE_LEDGER.md`. Read it before writing the batch.
|
|
234
|
+
|
|
235
|
+
This stage's items are its findings. A finding read from code — a detection surfaced by the PR
|
|
236
|
+
Analyzer, the Code Quality Checker, or your own reading of a diff line — is `extracted` and
|
|
237
|
+
carries a `locator`. A judgement the reviewer reached about that finding — severity, root cause,
|
|
238
|
+
whether it blocks — is `inferred` and carries `content`. Keep the two distinguishable in the
|
|
239
|
+
batch the way the Tools section above already keeps a detection distinguishable from a
|
|
240
|
+
conclusion in the report: never file a judgement as if it were something the code itself stated.
|
|
241
|
+
Add the review's verdict rationale and any other conclusion as a claim in the same pass.
|
|
242
|
+
|
|
243
|
+
A finding never carries `score`, `confidence`, `relevance` or a similarity field — the runtime
|
|
244
|
+
refuses those keys by name and the whole batch writes nothing. The Complexity score and Risk
|
|
245
|
+
categorization this skill's Tools compute are inputs to your `content`, never fields on the item.
|
|
246
|
+
|
|
247
|
+
This gains the review no gate: recording evidence and claims here is bookkeeping, not authority.
|
|
248
|
+
`do-code-review` still cannot block a merge or stop a downstream stage — only the Block verdict
|
|
249
|
+
in its own report, read by a human or by `/do-implement`, does that.
|
|
250
|
+
|
|
251
|
+
3. **Record the handoff, then handle this stage's gate** — read the guidance tree's
|
|
252
|
+
`references/WORKFLOW_HANDOFF.md`. When a feature is active, use its slug:
|
|
253
|
+
```bash
|
|
254
|
+
"$DOFLOW" orchestrate --action handoff --task-id "<feature_slug>" --calling-skill do-code-review --result <passed|failed> --note "<verdict and finding counts>" --json
|
|
255
|
+
```
|
|
256
|
+
The runtime derives the class and stage from the existing run. `standalone` creates no run
|
|
257
|
+
and asks no gate question. `deferred` reports a prior gate, unfinished mutating stage or
|
|
258
|
+
rejected run: report its `reason` and leave that transition to its owner. `completed` records
|
|
259
|
+
the review; `annotated` records a re-review without replaying any stage.
|
|
260
|
+
Only a `completed` handoff can present a newly reached gate owned by this stage, below.
|
|
261
|
+
- **The gate after this stage — check that one exists before trying to resolve one.** Read the
|
|
262
|
+
handoff response's `awaitingGate` field; do not re-derive it from `workflow.gates[]`.
|
|
263
|
+
- **`awaitingGate` is non-null and its `gateId` is anchored after this stage** — `gate-b`,
|
|
264
|
+
"Before commit or merge", in the `feature` workflow, which is the only shipped class with any
|
|
265
|
+
gate at all. This stage is that workflow's last and nothing downstream runs to ask it (its own
|
|
266
|
+
`handoff` sends commit and merge to `/do-git`, outside the workflow), so ask it here: put
|
|
267
|
+
`awaitingGate.prompt` to the user through `AskUserQuestion` as a plain go/no-go. Its trigger
|
|
268
|
+
is `always` — nothing in this review's own output answers it, so never approve it mechanically.
|
|
269
|
+
No gate is ever auto-approved by `catch-up`, `clarification`-kind included — only a human or
|
|
270
|
+
that gate's own owning skill decides it. On approve:
|
|
271
|
+
```bash
|
|
272
|
+
"$DOFLOW" orchestrate --action decide-gate --task-id "<feature_slug>" --gate "<awaitingGate.gateId>" --decision approve --note "<the user's own answer, one line>" --json
|
|
273
|
+
```
|
|
274
|
+
On "not yet", leave the gate open and say so plainly — the run stays `AWAITING_GATE` and the
|
|
275
|
+
user can decide later. Do not send `--decision reject` for a deferral: reject terminates the
|
|
276
|
+
run outright, which is a different answer from "not now", and do not force the approval.
|
|
277
|
+
- **`awaitingGate` is `null`** — there is no gate to resolve. `bug`, `refactor`, `review`,
|
|
278
|
+
`documentation` and `dependency-change` declare none, so the response comes back with the run
|
|
279
|
+
either `COMPLETED` or simply advanced. Say the review is recorded and stop: do not fabricate a
|
|
280
|
+
prompt, and do not call `decide-gate` on a gate that does not exist.
|
|
281
|
+
- When `/do-flow` is driving the chain it presents this gate and records the answer itself. That
|
|
282
|
+
needs no special-casing here: a gate it already decided is no longer open, so the `catch-up`
|
|
283
|
+
above never stops on it and `awaitingGate` comes back `null` — the same no-op branch.
|
|
284
|
+
Finish by rendering the trail — the `--slug` value attaches with an `=`; a space-separated one
|
|
285
|
+
is rejected with an error rather than silently rendering the wrong feature's trail:
|
|
286
|
+
```bash
|
|
287
|
+
"$DOFLOW" render-audit --slug="<feature_slug>" --json
|
|
288
|
+
```
|
|
289
|
+
- This step gains the review no authority either, exactly as step 2's own note says: the gate
|
|
290
|
+
records the user's answer, it does not produce one. If any call here fails for a reason outside
|
|
291
|
+
this flow's control (an unwritable local state directory, say), report the failure plainly and
|
|
292
|
+
continue — a missing `audit.md` entry changes nothing about the verdict already reported.
|
|
293
|
+
|
|
294
|
+
## Embedded feature research
|
|
295
|
+
|
|
296
|
+
For an external fact gap or explicit request, follow the conditional protocol in `../do-document/references/embedded-research.md` before stage completion.
|
|
297
|
+
|
|
298
|
+
## Boundaries
|
|
299
|
+
|
|
300
|
+
**Will:** Analyze source and prose for complexity, risk, SOLID violations, and code/doc smells;
|
|
301
|
+
generate structured review reports with a verdict (Approve / Approve with suggestions / Request
|
|
302
|
+
changes / Block); dispatch by language or content type to the matching rules file; record the review
|
|
303
|
+
stage's handoff and put the workflow's final approval gate to the user when this review is part of a
|
|
304
|
+
chain *and* the run reports such a gate open.
|
|
305
|
+
|
|
306
|
+
**Will Not:** Edit files, apply fixes, or otherwise remediate the findings it reports — that is
|
|
307
|
+
`/do-implement`'s job once a review has run. It does not answer the final gate on the user's behalf,
|
|
308
|
+
approve it mechanically from its own verdict, ask for a gate the workflow does not declare, resolve a
|
|
309
|
+
gate anchored before its own stage, or start a workflow run for a standalone review. It also does not orchestrate a multi-task checklist
|
|
310
|
+
through specialist subagents (`/do-execute-plan`'s job) or replace human judgment on a Block verdict.
|
|
311
|
+
|
|
312
|
+
## Running the review in a subagent
|
|
313
|
+
|
|
314
|
+
A review over a large change can be dispatched whole to the `quality-guardian` archetype, which
|
|
315
|
+
already declares code quality review among its capabilities, and which returns its report to the
|
|
316
|
+
calling session. Use it when the analysis would otherwise consume context the caller still needs for
|
|
317
|
+
the work itself.
|
|
318
|
+
|
|
319
|
+
This changes **where** the review runs and nothing else: the dispatched review loads the same rules
|
|
320
|
+
files by the same dispatch tables, states the same Review Contract, and returns the same verdict
|
|
321
|
+
vocabulary. A dispatched review that reports differently from an in-session one is a defect, not a
|
|
322
|
+
variant.
|
|
323
|
+
|
|
324
|
+
Review read-only at `frontier`, with an agent and model different from the author; pass `model:`
|
|
325
|
+
where supported. Re-review only an open blocker tests cannot settle, after asking. See
|
|
326
|
+
`references/MODEL_SELECTION.md`.
|
|
327
|
+
|
|
328
|
+
This is not the multi-task orchestration the boundary above rules out: one review, one subagent, one
|
|
329
|
+
report back.
|
|
330
|
+
|
|
331
|
+
## Next Step
|
|
332
|
+
After review, use `/do-implement` to address requested changes, then rerun `/do-code-review`.
|
|
333
|
+
On a clean review with nothing left to fix, consider `/do-document --type impl` to record what was built — optional, and does not gate or pause completion.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* sample_c_clean.c — sample_c_smells.c refactored per
|
|
3
|
+
* rules/universal.md + languages/c.md. Same surface area, zero
|
|
4
|
+
* detector hits.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
#include <stdio.h>
|
|
8
|
+
#include <stdlib.h>
|
|
9
|
+
#include <string.h>
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
void safe_input(void) {
|
|
13
|
+
char buf[64];
|
|
14
|
+
|
|
15
|
+
/* fgets is bounds-aware */
|
|
16
|
+
if (fgets(buf, sizeof(buf), stdin) == NULL) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
char dest[10];
|
|
21
|
+
/* strncpy with explicit bound + manual null-terminate */
|
|
22
|
+
strncpy(dest, buf, sizeof(dest) - 1);
|
|
23
|
+
dest[sizeof(dest) - 1] = '\0';
|
|
24
|
+
|
|
25
|
+
/* strncat with remaining-space bound */
|
|
26
|
+
size_t room = sizeof(dest) - strlen(dest) - 1;
|
|
27
|
+
strncat(dest, "world", room);
|
|
28
|
+
|
|
29
|
+
char msg[100];
|
|
30
|
+
/* snprintf is bounds-aware */
|
|
31
|
+
snprintf(msg, sizeof(msg), "%s says hello", buf);
|
|
32
|
+
|
|
33
|
+
/* Format string is a literal; buf is an argument */
|
|
34
|
+
printf("%s\n", buf);
|
|
35
|
+
|
|
36
|
+
char name[32];
|
|
37
|
+
/* %s with explicit width prevents overflow */
|
|
38
|
+
scanf("%31s", name);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
void checked_alloc(int n) {
|
|
43
|
+
/* malloc result is NULL-checked before any dereference */
|
|
44
|
+
char *buf = malloc(n);
|
|
45
|
+
if (buf == NULL) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
buf[0] = 'x';
|
|
49
|
+
buf[1] = 'y';
|
|
50
|
+
strncpy(buf, "ok", n - 1);
|
|
51
|
+
|
|
52
|
+
free(buf);
|
|
53
|
+
buf = NULL;
|
|
54
|
+
printf("done\n");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
void run_safe_cmd(void) {
|
|
59
|
+
/* system() with a string literal — no command-injection surface */
|
|
60
|
+
system("ls -la");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
int main(int argc, char *argv[]) {
|
|
65
|
+
(void)argc;
|
|
66
|
+
(void)argv;
|
|
67
|
+
safe_input();
|
|
68
|
+
checked_alloc(100);
|
|
69
|
+
run_safe_cmd();
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* sample_c_smells.c — labelled instances of every C-specific pattern
|
|
3
|
+
* the code-reviewer skill flags. Every smell is annotated inline with
|
|
4
|
+
* its CWE and the rule from languages/c.md.
|
|
5
|
+
*
|
|
6
|
+
* Refactored counterpart: sample_c_clean.c
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#include <stdio.h>
|
|
10
|
+
#include <stdlib.h>
|
|
11
|
+
#include <string.h>
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
void unsafe_input(void) {
|
|
15
|
+
char buf[64];
|
|
16
|
+
|
|
17
|
+
/* RULE: banned function gets() — CWE-242, no bounds check */
|
|
18
|
+
gets(buf);
|
|
19
|
+
|
|
20
|
+
char dest[10];
|
|
21
|
+
/* RULE: banned function strcpy() — no bounds check */
|
|
22
|
+
strcpy(dest, buf);
|
|
23
|
+
|
|
24
|
+
/* RULE: banned function strcat() — no bounds check */
|
|
25
|
+
strcat(dest, "world");
|
|
26
|
+
|
|
27
|
+
char msg[100];
|
|
28
|
+
/* RULE: banned function sprintf() — no bounds check */
|
|
29
|
+
sprintf(msg, "%s says hello", buf);
|
|
30
|
+
|
|
31
|
+
/* RULE: format-string vulnerability — CWE-134, buf controls format */
|
|
32
|
+
printf(buf);
|
|
33
|
+
|
|
34
|
+
char name[32];
|
|
35
|
+
/* RULE: unbounded scanf — %s without width, CWE-120 */
|
|
36
|
+
scanf("%s", name);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
void leaky_alloc(int n) {
|
|
41
|
+
/* RULE: malloc result not NULL-checked within 5 lines — CWE-690 */
|
|
42
|
+
char *buf = malloc(n);
|
|
43
|
+
buf[0] = 'x';
|
|
44
|
+
buf[1] = 'y';
|
|
45
|
+
strcpy(buf, "leak");
|
|
46
|
+
|
|
47
|
+
/* RULE: free without zeroing pointer — CWE-416 dangling */
|
|
48
|
+
free(buf);
|
|
49
|
+
printf("done\n");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
void run_user_cmd(const char *cmd_from_user) {
|
|
54
|
+
/* RULE: system() with non-literal argument — CWE-78 command injection */
|
|
55
|
+
system(cmd_from_user);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
int main(int argc, char *argv[]) {
|
|
60
|
+
if (argc > 1) {
|
|
61
|
+
unsafe_input();
|
|
62
|
+
leaky_alloc(100);
|
|
63
|
+
run_user_cmd(argv[1]);
|
|
64
|
+
}
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Fixture guarding the heredoc language gate. `<<` here is stream insertion, not a heredoc
|
|
2
|
+
// opener, and the lone `total` line below is an expression statement, not a terminator.
|
|
3
|
+
// Without the gate this function scored complexity 1 instead of 7: every branch between the
|
|
4
|
+
// two was blanked as a heredoc body. See _blank_heredocs in code_quality_checker.py.
|
|
5
|
+
#include <iostream>
|
|
6
|
+
|
|
7
|
+
void report(int total) {
|
|
8
|
+
std::cout << total
|
|
9
|
+
if (total > 0 && total < 100) {
|
|
10
|
+
for (int i = 0; i < total; i++) {
|
|
11
|
+
if (i % 2) { log(i); }
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
while (total-- > 0) {
|
|
15
|
+
switch (total) { case 1: break; default: break; }
|
|
16
|
+
}
|
|
17
|
+
total
|
|
18
|
+
;
|
|
19
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Sample C# file showing the fixed version of sample_csharp_smells.cs.
|
|
2
|
+
// Same shape, but every smell has been resolved per the patterns documented
|
|
3
|
+
// in rules/universal.md and languages/csharp.md.
|
|
4
|
+
//
|
|
5
|
+
// Run:
|
|
6
|
+
// python scripts/code_quality_checker.py assets/sample_csharp_clean.cs
|
|
7
|
+
//
|
|
8
|
+
// Expected: no HIGH C#-specific smells flagged.
|
|
9
|
+
|
|
10
|
+
using System;
|
|
11
|
+
using System.Net.Http;
|
|
12
|
+
using System.Threading.Tasks;
|
|
13
|
+
using System.Data.SqlClient;
|
|
14
|
+
using Microsoft.Extensions.Logging;
|
|
15
|
+
using Microsoft.Extensions.Options;
|
|
16
|
+
|
|
17
|
+
namespace Sample
|
|
18
|
+
{
|
|
19
|
+
public class DbOptions
|
|
20
|
+
{
|
|
21
|
+
// FIX: connection string from configuration, never inlined.
|
|
22
|
+
public string ConnectionString { get; init; } = "";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public class UserService
|
|
26
|
+
{
|
|
27
|
+
private readonly string _connectionString;
|
|
28
|
+
private readonly HttpClient _httpClient;
|
|
29
|
+
private readonly ILogger<UserService> _logger;
|
|
30
|
+
|
|
31
|
+
// FIX: IHttpClientFactory + IOptions, no hardcoded secrets, no `new HttpClient()`.
|
|
32
|
+
public UserService(
|
|
33
|
+
IHttpClientFactory httpClientFactory,
|
|
34
|
+
IOptions<DbOptions> dbOptions,
|
|
35
|
+
ILogger<UserService> logger)
|
|
36
|
+
{
|
|
37
|
+
_httpClient = httpClientFactory.CreateClient("api");
|
|
38
|
+
_connectionString = dbOptions.Value.ConnectionString;
|
|
39
|
+
_logger = logger;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// FIX: async Task (not async void) so callers can await and observe exceptions.
|
|
43
|
+
public async Task HandleClickAsync()
|
|
44
|
+
{
|
|
45
|
+
// FIX: await the Task instead of blocking on it.
|
|
46
|
+
var data = await FetchAsync().ConfigureAwait(false);
|
|
47
|
+
_logger.LogInformation("Fetched {Length} bytes", data.Length);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public async Task<string> FetchAsync()
|
|
51
|
+
{
|
|
52
|
+
try
|
|
53
|
+
{
|
|
54
|
+
// FIX: await the async call — Task is no longer discarded.
|
|
55
|
+
await FireAndForgetAsync().ConfigureAwait(false);
|
|
56
|
+
|
|
57
|
+
// FIX: real null check, no `!`.
|
|
58
|
+
var user = await GetCurrentUserAsync().ConfigureAwait(false);
|
|
59
|
+
if (user is null)
|
|
60
|
+
{
|
|
61
|
+
throw new InvalidOperationException("No current user");
|
|
62
|
+
}
|
|
63
|
+
_ = user.Name;
|
|
64
|
+
|
|
65
|
+
return await _httpClient
|
|
66
|
+
.GetStringAsync("https://api.example/data")
|
|
67
|
+
.ConfigureAwait(false);
|
|
68
|
+
}
|
|
69
|
+
catch (HttpRequestException ex)
|
|
70
|
+
{
|
|
71
|
+
// FIX: catch specific exception, log with context, rethrow.
|
|
72
|
+
_logger.LogError(ex, "Upstream fetch failed");
|
|
73
|
+
throw;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// FIX: real type, not `dynamic`.
|
|
78
|
+
public User? CurrentUser { get; private set; }
|
|
79
|
+
|
|
80
|
+
// FIX: `unsafe` removed — none of the logic actually needed pointers.
|
|
81
|
+
public int FirstValue(int[] values) => values.Length > 0 ? values[0] : 0;
|
|
82
|
+
|
|
83
|
+
// FIX: no #pragma / [SuppressMessage] — root cause fixed instead.
|
|
84
|
+
public string GetName(int id)
|
|
85
|
+
{
|
|
86
|
+
// FIX: `using var` disposes connection + command deterministically.
|
|
87
|
+
using var conn = new SqlConnection(_connectionString);
|
|
88
|
+
// FIX: parameterized query, no string concatenation.
|
|
89
|
+
using var cmd = new SqlCommand("SELECT name FROM users WHERE id = @id", conn);
|
|
90
|
+
cmd.Parameters.AddWithValue("@id", id);
|
|
91
|
+
conn.Open();
|
|
92
|
+
return (string)cmd.ExecuteScalar();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private Task<User?> GetCurrentUserAsync() => Task.FromResult<User?>(null);
|
|
96
|
+
private Task FireAndForgetAsync() => Task.CompletedTask;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
public record User(int Id, string Name);
|
|
100
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Sample C# file demonstrating every C#-specific pattern the code-reviewer
|
|
2
|
+
// skill detects. Each smell is labelled inline. This file is NOT meant to
|
|
3
|
+
// compile cleanly — it is a fixture for code_quality_checker.py and
|
|
4
|
+
// pr_analyzer.py.
|
|
5
|
+
//
|
|
6
|
+
// Run:
|
|
7
|
+
// python scripts/code_quality_checker.py assets/sample_csharp_smells.cs
|
|
8
|
+
//
|
|
9
|
+
// Expected output: see expected_outputs/sample_csharp_smells_quality.json
|
|
10
|
+
|
|
11
|
+
using System;
|
|
12
|
+
using System.Net.Http;
|
|
13
|
+
using System.Threading.Tasks;
|
|
14
|
+
using System.Data.SqlClient;
|
|
15
|
+
using System.Diagnostics.CodeAnalysis;
|
|
16
|
+
|
|
17
|
+
namespace Sample
|
|
18
|
+
{
|
|
19
|
+
public class UserService
|
|
20
|
+
{
|
|
21
|
+
// [hardcoded_secrets] hardcoded connection string with password
|
|
22
|
+
public string ConnectionString = "Server=prod;Database=app;Password=hunter2;";
|
|
23
|
+
|
|
24
|
+
// [csharp_async_void] async void on a non-event-handler signature
|
|
25
|
+
public async void HandleClick(object sender, EventArgs e)
|
|
26
|
+
{
|
|
27
|
+
// [csharp_blocking_async] .Result blocks on Task in a sync context
|
|
28
|
+
var data = FetchAsync().Result;
|
|
29
|
+
// [console_log] Debug.WriteLine output statement
|
|
30
|
+
Debug.WriteLine(data);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public async Task<string> FetchAsync()
|
|
34
|
+
{
|
|
35
|
+
// [csharp_new_httpclient] new HttpClient() in method body
|
|
36
|
+
// [csharp_undisposed_idisposable] HttpClient not in `using`
|
|
37
|
+
var client = new HttpClient();
|
|
38
|
+
|
|
39
|
+
try
|
|
40
|
+
{
|
|
41
|
+
// [csharp_missing_await] FireAndForgetAsync() returns Task, never awaited
|
|
42
|
+
FireAndForgetAsync();
|
|
43
|
+
|
|
44
|
+
// [csharp_null_forgiving] `user!.Name` forces null-forgiving
|
|
45
|
+
var name = user!.Name;
|
|
46
|
+
|
|
47
|
+
return await client.GetStringAsync("https://api.example/data");
|
|
48
|
+
}
|
|
49
|
+
catch (Exception)
|
|
50
|
+
{
|
|
51
|
+
// [csharp_swallowed_exception] empty catch (Exception)
|
|
52
|
+
}
|
|
53
|
+
return null!;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// [loose_type] C# `dynamic` overuse
|
|
57
|
+
public dynamic Untyped = null;
|
|
58
|
+
|
|
59
|
+
// [csharp_unsafe_block] `unsafe` modifier on a method
|
|
60
|
+
public unsafe void Pointers()
|
|
61
|
+
{
|
|
62
|
+
int x = 0;
|
|
63
|
+
int* p = &x;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// [analyzer_disable] #pragma warning disable
|
|
67
|
+
#pragma warning disable CS0168
|
|
68
|
+
// [analyzer_disable] [SuppressMessage] attribute
|
|
69
|
+
[SuppressMessage("Style", "IDE0060")]
|
|
70
|
+
public string GetName(SqlConnection conn, int id)
|
|
71
|
+
{
|
|
72
|
+
// [csharp_undisposed_idisposable] SqlCommand without `using`
|
|
73
|
+
// [sql_concatenation] string concatenation builds SQL with user input
|
|
74
|
+
var cmd = new SqlCommand("SELECT name FROM users WHERE id = " + id, conn);
|
|
75
|
+
return cmd.ExecuteScalar().ToString();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|