@polymorphism-tech/morph-spec 8.47.0 → 9.1.0
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.md +51 -43
- package/README.md +39 -38
- package/bin/morph-spec.js +41 -113
- package/bin/validate.js +1 -147
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +41 -101
- package/framework/MORPH.md +95 -252
- package/framework/agents.json +86 -21
- package/framework/commands/morph-apply.md +5 -28
- package/framework/commands/morph-archive.md +1 -1
- package/framework/commands/morph-hotfix.md +8 -8
- package/framework/commands/morph-infra.md +1 -1
- package/framework/commands/morph-preflight.md +2 -3
- package/framework/commands/morph-status.md +4 -4
- package/framework/docs/CLI.md +574 -286
- package/framework/evals/review-checklist.md +82 -41
- package/framework/hooks/README.md +10 -11
- package/framework/hooks/claude-code/core/block-destructive-worktree-removal.js +6 -49
- package/framework/hooks/claude-code/core/block-raw-worktree-add.js +2 -35
- package/framework/hooks/claude-code/core/chain.js +4 -65
- package/framework/hooks/claude-code/core/comment-guard.js +3 -17
- package/framework/hooks/claude-code/core/denylist.json +33 -3
- package/framework/hooks/claude-code/core/enforce-phase-writes.js +15 -63
- package/framework/hooks/claude-code/core/gate-guard.js +9 -78
- package/framework/hooks/claude-code/core/graph-refresh-kick.js +3 -24
- package/framework/hooks/claude-code/core/heavy-gate.js +3 -21
- package/framework/hooks/claude-code/core/heavy-release.js +2 -13
- package/framework/hooks/claude-code/core/loop-detect.js +2 -31
- package/framework/hooks/claude-code/core/pre-bash-denylist.js +36 -2
- package/framework/hooks/claude-code/core/protect-spec-files.js +25 -297
- package/framework/hooks/claude-code/core/state-sync.js +15 -85
- package/framework/hooks/claude-code/core/telemetry-log.js +15 -96
- package/framework/hooks/claude-code/core/validate-completion.js +37 -147
- package/framework/hooks/claude-code/core/warn-bash-source-write.js +23 -0
- package/framework/hooks/claude-code/core/worktree-context.js +15 -114
- package/framework/hooks/claude-code/core/worktree-create.js +6 -70
- package/framework/hooks/claude-code/core/worktree-env-inject.js +5 -56
- package/framework/hooks/claude-code/core/worktree-remove.js +5 -31
- package/framework/hooks/claude-code/statusline.py +55 -41
- package/framework/hooks/package.json +3 -0
- package/framework/hooks/shared/activity-logger.js +9 -89
- package/framework/hooks/shared/agent-reap.js +2 -17
- package/framework/hooks/shared/build-check.js +11 -76
- package/framework/hooks/shared/claim-registry.js +9 -119
- package/framework/hooks/shared/command-tokens.js +168 -44
- package/framework/hooks/shared/comment-rules.js +5 -20
- package/framework/hooks/shared/comment-scanner.js +11 -43
- package/framework/hooks/shared/comment-stripper.js +11 -85
- package/framework/hooks/shared/e2e-check.js +0 -0
- package/framework/hooks/shared/errata.js +59 -0
- package/framework/hooks/shared/feature-locator.js +11 -95
- package/framework/hooks/shared/frontend-locations.js +4 -0
- package/framework/hooks/shared/gate-question.js +12 -0
- package/framework/hooks/shared/git-exclude.js +3 -20
- package/framework/hooks/shared/git-paths.js +8 -104
- package/framework/hooks/shared/graph-freshness.js +22 -166
- package/framework/hooks/shared/graph-refresh.js +21 -149
- package/framework/hooks/shared/heavy-command.js +4 -12
- package/framework/hooks/shared/hook-response.js +8 -83
- package/framework/hooks/shared/morph-cli.js +8 -52
- package/framework/hooks/shared/payload-utils.js +10 -132
- package/framework/hooks/shared/phase-utils.js +14 -72
- package/framework/hooks/shared/redact-secrets.js +4 -15
- package/framework/hooks/shared/reparse-scan.js +6 -66
- package/framework/hooks/shared/slice-progress.js +99 -0
- package/framework/hooks/shared/source-files.js +4 -17
- package/framework/hooks/shared/spawn-command.js +23 -0
- package/framework/hooks/shared/state-reader.js +51 -247
- package/framework/hooks/shared/state-writer.js +9 -54
- package/framework/hooks/shared/stdin-reader.js +1 -11
- package/framework/hooks/shared/telemetry-logger.js +7 -67
- package/framework/hooks/shared/transcript-usage.js +7 -29
- package/framework/hooks/shared/worktree-root.js +7 -29
- package/framework/mcp/registry.json +3 -4
- package/framework/phases.json +23 -39
- package/framework/rules/csharp-standards.md +1 -1
- package/framework/rules/frontend-standards.md +1 -0
- package/framework/rules/hangfire-standards.md +1 -1
- package/framework/rules/neon-standards.md +1 -1
- package/framework/schemas/config.schema.json +14 -9
- package/framework/schemas/feature.schema.json +15 -50
- package/framework/skills/README.md +3 -4
- package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
- package/framework/skills/core/morph-apply/SKILL.md +149 -222
- package/framework/skills/core/morph-hotfix/SKILL.md +33 -42
- package/framework/skills/core/morph-machine/SKILL.md +2 -2
- package/framework/skills/core/morph-media/SKILL.md +1 -1
- package/framework/skills/core/morph-plan/SKILL.md +137 -299
- package/framework/skills/core/morph-review/SKILL.md +111 -136
- package/framework/skills/core/morph-standards/SKILL.md +27 -39
- package/framework/skills/core/morph-uiux/SKILL.md +94 -152
- package/framework/standards/STANDARDS.json +109 -1219
- package/framework/standards/STANDARDS.meta.json +1319 -0
- package/framework/standards/ai-agents/agent-archetypes.md +2 -2
- package/framework/standards/ai-agents/agent-session.md +1 -1
- package/framework/standards/ai-agents/conversational-agent-with-phases.md +4 -4
- package/framework/standards/ai-agents/durable-workflows-hitl.md +3 -3
- package/framework/standards/ai-agents/evals-with-cache.md +1 -2
- package/framework/standards/ai-agents/guardrails.md +1 -1
- package/framework/standards/ai-agents/multi-agent-patterns.md +2 -2
- package/framework/standards/ai-agents/observability-patterns.md +1 -1
- package/framework/standards/ai-agents/production.md +1 -1
- package/framework/standards/ai-agents/prompt-sources.md +2 -2
- package/framework/standards/ai-agents/providers/model-registry.md +1 -1
- package/framework/standards/ai-agents/rag-custom-pgvector.md +2 -2
- package/framework/standards/ai-agents/setup.md +3 -3
- package/framework/standards/ai-agents/sweet-spot.md +2 -2
- package/framework/standards/ai-agents/tool-adapters.md +0 -2
- package/framework/standards/ai-agents/vector-data-extensions.md +4 -4
- package/framework/standards/ai-agents/workflows.md +1 -1
- package/framework/standards/architecture/code-comments.md +7 -7
- package/framework/standards/architecture/vertical-slice/vertical-slice.md +1 -1
- package/framework/standards/backend/api/validation.md +1 -1
- package/framework/standards/backend/dotnet/vsa-handler-patterns.md +5 -5
- package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +1 -1
- package/framework/standards/backend/integrations/neon-auth/neon-auth.md +2 -2
- package/framework/standards/data/nosql/cache/redis.md +1 -1
- package/framework/standards/data/nosql/cosmos-db.md +3 -3
- package/framework/standards/frontend/admin-app/forms.md +1 -1
- package/framework/standards/frontend/design-system/art-direction.md +88 -0
- package/framework/standards/frontend/design-system/premium-finish.md +77 -2
- package/framework/standards/infrastructure/neon/neon-pgvector.md +5 -5
- package/framework/standards/integration/mcp/mcp-tools.md +7 -7
- package/framework/templates/CLAUDE.md.core.template +3 -3
- package/framework/templates/README.md +2 -3
- package/framework/templates/REGISTRY.json +15 -179
- package/framework/templates/docs/plan.md +72 -0
- package/framework/templates/docs/ui-mockups.md +4 -0
- package/framework/templates/dotnet/ai-kit/README.md +1 -9
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Morph.AiKit.Tests.csproj +0 -10
- package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -1
- package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +1 -1
- package/framework/templates/meta-prompts/squad-leaders/squad-leader.md +1 -1
- package/framework/templates/meta-prompts/validators/pre-commit-validator.md +3 -4
- package/package.json +1 -1
- package/src/commands/context/context-refresh.js +0 -16
- package/src/commands/dashboard/dashboard.js +2 -8
- package/src/commands/e2e/e2e.js +18 -105
- package/src/commands/graph/affected.js +0 -14
- package/src/commands/graph/build.js +11 -50
- package/src/commands/graph/explain.js +0 -16
- package/src/commands/graph/status.js +1 -12
- package/src/commands/mcp/mcp-setup.js +4 -62
- package/src/commands/observability/cost.js +17 -111
- package/src/commands/observability/telemetry.js +1 -14
- package/src/commands/project/branch.js +4 -45
- package/src/commands/project/claim.js +4 -48
- package/src/commands/project/doctor-procs.js +1 -1
- package/src/commands/project/doctor.js +53 -307
- package/src/commands/project/env.js +1 -27
- package/src/commands/project/fleet.js +6 -35
- package/src/commands/project/heavy.js +3 -3
- package/src/commands/project/init.js +8 -68
- package/src/commands/project/install-plugin-cmd.js +0 -1
- package/src/commands/project/setup-infra-cmd.js +2 -1
- package/src/commands/project/stack-scan.js +58 -0
- package/src/commands/project/standards.js +65 -72
- package/src/commands/project/status.js +28 -121
- package/src/commands/project/update.js +31 -223
- package/src/commands/project/worktree.js +109 -883
- package/src/commands/scaffold/scaffold.js +0 -25
- package/src/commands/state/advance.js +65 -120
- package/src/commands/state/approve.js +87 -229
- package/src/commands/state/archive.js +23 -139
- package/src/commands/state/auto-approval.js +65 -0
- package/src/commands/state/create.js +49 -109
- package/src/commands/state/delete.js +11 -63
- package/src/commands/state/finish.js +105 -494
- package/src/commands/state/gate-check.js +74 -183
- package/src/commands/state/gate-decision.js +8 -42
- package/src/commands/state/handoff.js +4 -31
- package/src/commands/state/list.js +21 -91
- package/src/commands/state/report-check.js +134 -338
- package/src/commands/state/retype.js +12 -28
- package/src/commands/validation/index.js +0 -3
- package/src/commands/validation/mutate.js +79 -19
- package/src/commands/validation/plan-check.js +81 -0
- package/src/commands/validation/validate-feature.js +52 -216
- package/src/commands/validation/verify.js +45 -160
- package/src/core/paths/output-schema.js +9 -155
- package/src/core/state/feature-identity.js +1 -25
- package/src/core/state/gate-order.js +2 -30
- package/src/core/state/lifecycle-audit.js +8 -100
- package/src/core/state/state-manager.js +32 -395
- package/src/core/templates/template-registry.js +2 -97
- package/src/core/templates/template-renderer.js +13 -93
- package/src/core/templates/template-seed.js +21 -0
- package/src/core/work-types.js +10 -45
- package/src/dashboard/app/App.jsx +1 -8
- package/src/dashboard/app/components/ActivityFeed.jsx +2 -8
- package/src/dashboard/app/components/CommandPalette.jsx +4 -11
- package/src/dashboard/app/components/DetailPanel.jsx +1 -5
- package/src/dashboard/app/components/EntityLink.jsx +0 -12
- package/src/dashboard/app/components/ErrorBoundary.jsx +1 -8
- package/src/dashboard/app/components/KnowledgeMarkdown.jsx +0 -11
- package/src/dashboard/app/components/Markdown.jsx +0 -9
- package/src/dashboard/app/components/PhaseRail.jsx +0 -11
- package/src/dashboard/app/components/SearchFilter.jsx +0 -4
- package/src/dashboard/app/components/Sidebar.jsx +0 -5
- package/src/dashboard/app/hooks/useMorphQuery.js +1 -11
- package/src/dashboard/app/hooks/usePref.js +1 -5
- package/src/dashboard/app/lib/format.js +0 -2
- package/src/dashboard/app/lib/phases.js +3 -9
- package/src/dashboard/app/lib/project.js +0 -12
- package/src/dashboard/app/pages/Activity.jsx +1 -1
- package/src/dashboard/app/pages/AgentMap.jsx +1 -8
- package/src/dashboard/app/pages/FeatureDetail.jsx +139 -133
- package/src/dashboard/app/pages/Features.jsx +9 -16
- package/src/dashboard/app/pages/Guide.jsx +2 -3
- package/src/dashboard/app/pages/HookInspector.jsx +2 -23
- package/src/dashboard/app/pages/PhasePipeline.jsx +3 -7
- package/src/dashboard/app/pages/Portfolio.jsx +0 -1
- package/src/dashboard/app/pages/RulesMap.jsx +1 -16
- package/src/dashboard/app/pages/SkillsLibrary.jsx +1 -16
- package/src/dashboard/app/pages/Standards.jsx +2 -17
- package/src/dashboard/scanner/activity-scanner.js +14 -83
- package/src/dashboard/scanner/agents-scanner.js +1 -23
- package/src/dashboard/scanner/docs-scanner.js +1 -7
- package/src/dashboard/scanner/feature-status.js +2 -5
- package/src/dashboard/scanner/features-scanner.js +92 -113
- package/src/dashboard/scanner/hooks-scanner.js +5 -28
- package/src/dashboard/scanner/index.js +0 -4
- package/src/dashboard/scanner/portfolio.js +5 -29
- package/src/dashboard/scanner/project-api.js +8 -54
- package/src/dashboard/scanner/rules-scanner.js +1 -2
- package/src/dashboard/scanner/skills-scanner.js +2 -12
- package/src/dashboard/scanner/standards-scanner.js +4 -7
- package/src/dashboard/vite-plugin-morph-data.js +5 -19
- package/src/lib/ai/ai-checks.js +7 -52
- package/src/lib/ai/ai-project-scan.js +14 -108
- package/src/lib/ai/code-audit.js +7 -63
- package/src/lib/ai/pin-drift.js +8 -51
- package/src/lib/ai/registry-audit.js +11 -90
- package/src/lib/ci/ci-verify.js +14 -13
- package/src/lib/ci/github-ci.js +9 -37
- package/src/lib/ci/workflow-scaffold.js +2 -10
- package/src/lib/detectors/claude-config-detector.js +13 -74
- package/src/lib/detectors/index.js +8 -59
- package/src/lib/e2e/compose-env.js +5 -66
- package/src/lib/e2e/stack-teardown.js +6 -40
- package/src/lib/generators/architecture-scanner.js +18 -156
- package/src/lib/generators/handoff-generator.js +37 -112
- package/src/lib/generators/scaffold-generator.js +5 -101
- package/src/lib/generators/settings-generator.js +11 -122
- package/src/lib/git/branch-classifier.js +11 -84
- package/src/lib/git/default-branch.js +14 -169
- package/src/lib/git/evidence-staleness.js +2 -1
- package/src/lib/git/gh.js +2 -17
- package/src/lib/git/pending-prs.js +6 -37
- package/src/lib/git/pr-files.js +3 -28
- package/src/lib/git/pr-index.js +3 -34
- package/src/lib/git/tree-fingerprint.js +17 -17
- package/src/lib/git/tree-state.js +6 -33
- package/src/lib/graph/god-nodes.js +2 -22
- package/src/lib/graph/graph-health.js +3 -24
- package/src/lib/graph/graph-loader.js +5 -56
- package/src/lib/graph/graphify-runtime.js +7 -37
- package/src/lib/graph/graphifyignore.js +8 -74
- package/src/lib/graph/sanitize.js +16 -136
- package/src/lib/heavy/cleanup.js +2 -6
- package/src/lib/installers/effects.js +8 -93
- package/src/lib/installers/mcp-installer.js +9 -169
- package/src/lib/installers/memory-installer.js +8 -33
- package/src/lib/installers/templates-reconcile.js +5 -60
- package/src/lib/mutation/commands.js +3 -2
- package/src/lib/mutation/dotnet-introspection.js +281 -0
- package/src/lib/mutation/plan.js +14 -6
- package/src/lib/mutation/runner.js +1 -1
- package/src/lib/mutation/subset.js +47 -13
- package/src/lib/plan/artifact-vocabulary.js +40 -0
- package/src/lib/plan/checks.js +208 -0
- package/src/lib/plan/plan-parser.js +204 -0
- package/src/lib/plan/plan-template.js +18 -0
- package/src/lib/projects/registry.js +7 -44
- package/src/lib/review-reports.js +204 -0
- package/src/lib/risk-detector.js +131 -274
- package/src/lib/specs/adr-index.js +38 -85
- package/src/lib/specs/design-seed.js +18 -0
- package/src/lib/specs/frontmatter.js +31 -0
- package/src/lib/specs/gfm-table.js +11 -0
- package/src/lib/specs/revocations.js +31 -102
- package/src/lib/specs/screen-checklist.js +56 -132
- package/src/lib/stack/dotnet-build-ignores.js +43 -0
- package/src/lib/stack/stack-profile.js +1 -28
- package/src/lib/stack/stack-scan.js +260 -0
- package/src/lib/stack-filter.js +4 -27
- package/src/lib/standards/registry.js +37 -0
- package/src/lib/standards/sections.js +47 -0
- package/src/lib/standards/verified-against.js +19 -191
- package/src/lib/tasks/eval-node.js +23 -179
- package/src/lib/tasks/linux-runner.js +18 -142
- package/src/lib/tasks/test-nodes.js +43 -313
- package/src/lib/tasks/test-runner.js +107 -447
- package/src/lib/telemetry/metrics.js +13 -103
- package/src/lib/telemetry/telemetry-reader.js +13 -238
- package/src/lib/telemetry/verify-event.js +4 -34
- package/src/lib/validators/code-budget/code-budget-validator.js +4 -44
- package/src/lib/validators/code-budget/index.js +0 -7
- package/src/lib/validators/contracts/contract-compliance-validator.js +4 -26
- package/src/lib/validators/contracts/index.js +0 -6
- package/src/lib/validators/nextjs/index.js +0 -5
- package/src/lib/validators/nextjs/next-component-validator.js +4 -81
- package/src/lib/validators/packages/index.js +0 -6
- package/src/lib/validators/packages/package-validator.js +6 -56
- package/src/lib/validators/reuse/index.js +0 -8
- package/src/lib/validators/reuse/reuse-validator.js +24 -137
- package/src/lib/validators/reuse/symbol-scanner.js +6 -62
- package/src/lib/validators/traceability-check.js +54 -156
- package/src/lib/validators/validation-runner.js +20 -125
- package/src/lib/validators/verify-runner.js +152 -575
- package/src/lib/work-type-detector.js +5 -67
- package/src/lib/worktree/docker-audit.js +17 -137
- package/src/lib/worktree/env-allocator.js +10 -98
- package/src/lib/worktree/feature-truth.js +12 -115
- package/src/lib/worktree/finish-backup.js +32 -242
- package/src/lib/worktree/fleet-scanner.js +31 -126
- package/src/lib/worktree/ignored-triage.js +15 -91
- package/src/lib/worktree/vscode-settings.js +2 -3
- package/src/lib/worktree/worktree-audit.js +21 -213
- package/src/lib/worktree/worktree-include.js +3 -5
- package/src/scripts/global-install.js +3 -9
- package/src/scripts/install-plugin.js +1 -13
- package/src/scripts/setup-infra.js +17 -138
- package/src/utils/agents-installer.js +92 -272
- package/src/utils/banner.js +4 -25
- package/src/utils/claude-md-injector.js +1 -37
- package/src/utils/claude-settings-manager.js +1 -87
- package/src/utils/file-copier.js +32 -90
- package/src/utils/hooks-installer.js +26 -296
- package/src/utils/skills-installer.js +4 -102
- package/src/utils/version-checker.js +4 -83
- package/framework/commands/morph-proposal.md +0 -57
- package/framework/evals/trace-schema.md +0 -67
- package/framework/hooks/claude-code/core/tasks-json-guard.js +0 -83
- package/framework/hooks/claude-code/core/trace-autogen.js +0 -277
- package/framework/hooks/git/pre-commit/specs.sh +0 -50
- package/framework/hooks/shared/tasks-validator.js +0 -111
- package/framework/rules/morph-task-tracking.md +0 -54
- package/framework/rules/morph-workflow.md +0 -244
- package/framework/schemas/tasks.schema.json +0 -79
- package/framework/skills/core/morph-brainstorming/SKILL.md +0 -161
- package/framework/skills/core/morph-implement/SKILL.md +0 -194
- package/framework/skills/core/morph-proposal/SKILL.md +0 -152
- package/framework/skills/core/morph-stack-scan/SKILL.md +0 -145
- package/framework/templates/docs/proposal.md +0 -192
- package/framework/templates/docs/spec.md +0 -57
- package/framework/templates/docs/ui-components.md +0 -52
- package/framework/templates/docs/ui-design-system.md +0 -76
- package/framework/templates/docs/ui-flows.md +0 -167
- package/framework/templates/examples/spec-examples.md +0 -91
- package/framework/templates/feature/decisions.md +0 -124
- package/framework/templates/feature/recap.md +0 -145
- package/framework/templates/tasks.template.json +0 -17
- package/src/commands/state/usecase.js +0 -143
- package/src/commands/tasks/dag.js +0 -181
- package/src/commands/utils/index.js +0 -3
- package/src/lib/agents/output-collector.js +0 -76
- package/src/lib/detectors/design-system-detector.js +0 -188
- package/src/lib/evaluator-report.js +0 -104
- package/src/lib/generators/design-system-generator.js +0 -508
- package/src/lib/specs/acervo-format.js +0 -70
- package/src/lib/specs/acervo-lifecycle.js +0 -264
- package/src/lib/specs/done-criteria-check.js +0 -200
- package/src/lib/specs/usecase-check.js +0 -301
- package/src/lib/specs/usecase-promoter.js +0 -301
- package/src/lib/specs/usecase-registry.js +0 -237
- package/src/lib/tasks/dispatch-planner.js +0 -319
- package/src/lib/tasks/dotnet-test-introspection.js +0 -632
- package/src/lib/tasks/mermaid-renderer.js +0 -132
- package/src/lib/tasks/task-classifier.js +0 -30
- package/src/lib/tasks/task-parser.js +0 -209
- package/src/lib/tasks/tasks-json-parser.js +0 -296
- package/src/lib/tasks/test-scope.js +0 -597
- package/src/utils/agent-id-mapper.js +0 -11
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MORPH-SPEC Validation Runner
|
|
3
|
-
*
|
|
4
|
-
* Unified orchestrator that runs the right validators based on the project's
|
|
5
|
-
* stack profile. Called by task-done before marking tasks complete.
|
|
6
|
-
*
|
|
7
|
-
* MORPH-SPEC 3.0 - Phase A: Active Validation Pipeline
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
1
|
import { existsSync } from 'fs';
|
|
11
2
|
import chalk from 'chalk';
|
|
12
3
|
import { getAbsoluteOutputPath, resolveContractsOutputType } from '../../core/paths/output-schema.js';
|
|
@@ -18,14 +9,8 @@ const HEAVY_VALIDATORS = new Set([
|
|
|
18
9
|
]);
|
|
19
10
|
|
|
20
11
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* @param {string} projectPath - Project root path
|
|
24
|
-
* @param {string} featureName - Feature name from state.json
|
|
25
|
-
* @param {Object} options - Options
|
|
26
|
-
* @param {boolean} options.verbose - Show detailed output
|
|
27
|
-
* @param {string[]} options.validators - Specific validators to run (overrides stack-based detection)
|
|
28
|
-
* @returns {Object} { passed, errors, warnings, issues, summary }
|
|
12
|
+
* @param {string[]} [options.validators] - overrides stack-based detection
|
|
13
|
+
* @returns {Object} { passed, errors, warnings, issues, summary, results, skipped, _skipReason? }
|
|
29
14
|
*/
|
|
30
15
|
export async function runValidation(projectPath, featureName, options = {}) {
|
|
31
16
|
const result = {
|
|
@@ -34,24 +19,13 @@ export async function runValidation(projectPath, featureName, options = {}) {
|
|
|
34
19
|
warnings: 0,
|
|
35
20
|
issues: [],
|
|
36
21
|
summary: '',
|
|
37
|
-
results: {}
|
|
22
|
+
results: {}
|
|
38
23
|
};
|
|
39
24
|
|
|
40
|
-
//
|
|
41
|
-
const constraints = {
|
|
42
|
-
enabledValidators: [], // No constraint-based validators
|
|
43
|
-
validators: {} // No validator-specific constraints
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
// Determine which validators to run.
|
|
47
|
-
// COPY: the mode filter below used to splice in place, and when the caller
|
|
48
|
-
// passed `options.validators` that array WAS this array — so a light run
|
|
49
|
-
// emptied the caller's own list, and running the same list twice validated
|
|
50
|
-
// less the second time.
|
|
25
|
+
// A copy: filtering in place would empty the caller's own `options.validators`.
|
|
51
26
|
const detected = options.validators || detectValidators(projectPath);
|
|
52
27
|
let validatorIds = [...detected];
|
|
53
28
|
|
|
54
|
-
// Filter by mode: 'light' skips heavy validators, 'full' (default) runs all
|
|
55
29
|
const mode = options.mode || 'full';
|
|
56
30
|
const droppedByMode = [];
|
|
57
31
|
if (mode === 'light') {
|
|
@@ -61,35 +35,17 @@ export async function runValidation(projectPath, featureName, options = {}) {
|
|
|
61
35
|
});
|
|
62
36
|
}
|
|
63
37
|
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// Reuse is stack-agnostic: "isto já existe?" é a mesma pergunta em C# e em
|
|
68
|
-
// TypeScript, e o validador se cala sozinho quando não há grafo (ADR-002).
|
|
69
|
-
// Por isso ele não entra no `defaultValidators` de stack profile nenhum —
|
|
70
|
-
// entra aqui, ANTES do early-return de "nenhum validador": num projeto de
|
|
71
|
-
// stack `empty`/`nodejs-cli` não há outro validador para carregá-lo, e é
|
|
72
|
-
// exatamente lá que ele seria a única verificação a rodar.
|
|
73
|
-
// Em `light` (checkpoint) ele fica de fora, como todo validador pesado — é
|
|
74
|
-
// uma leitura de graph.json (11-24 MB nos repos medidos) — e por isso está
|
|
75
|
-
// em HEAVY_VALIDATORS, que é onde essa política se declara. Não entra em
|
|
76
|
-
// `droppedByMode`: essa lista responde "o que o modo tirou da SUA lista", e
|
|
77
|
-
// é ela que distingue "light pulou os pesados" de "este stack não tem
|
|
78
|
-
// validador nenhum" na mensagem final.
|
|
38
|
+
// Stack-agnostic validators join here, before the "no validators" early return:
|
|
39
|
+
// on an `empty`/`nodejs-cli` stack they are the only check. Not in `droppedByMode`,
|
|
40
|
+
// which only lists what light mode removed from the stack's own list.
|
|
79
41
|
if (!options.skipReuse && mode !== 'light') {
|
|
80
42
|
validatorIds.push('reuse');
|
|
81
43
|
}
|
|
82
|
-
// Mesma política, pelo mesmo motivo: comentário e orçamento de teste valem
|
|
83
|
-
// em qualquer stack, e a medida é da feature, não de um checkpoint.
|
|
84
44
|
if (mode !== 'light') {
|
|
85
45
|
validatorIds.push('code-budget');
|
|
86
46
|
}
|
|
87
47
|
|
|
88
48
|
if (validatorIds.length === 0) {
|
|
89
|
-
// Say which of the two it is. On a pure `dotnet` project every default
|
|
90
|
-
// validator is heavy, so a light run legitimately runs none — but the old
|
|
91
|
-
// message blamed the stack ("no validators configured"), which reads as
|
|
92
|
-
// "your stack has nothing to check" when the full run has two.
|
|
93
49
|
result.summary = droppedByMode.length > 0
|
|
94
50
|
? `No validators ran — light mode skipped ${droppedByMode.length} heavy validator(s): ${droppedByMode.join(', ')}`
|
|
95
51
|
: 'No validators ran — no validators configured for this stack';
|
|
@@ -99,49 +55,29 @@ export async function runValidation(projectPath, featureName, options = {}) {
|
|
|
99
55
|
return result;
|
|
100
56
|
}
|
|
101
57
|
|
|
102
|
-
// Always show what's running (even non-verbose) — helps confirm validators are active
|
|
103
58
|
console.log(chalk.gray(`\n Running ${validatorIds.length} validator(s): ${validatorIds.join(', ')}`));
|
|
104
|
-
if (constraints.enabledValidators.length > 0) {
|
|
105
|
-
console.log(chalk.gray(` (+ ${constraints.enabledValidators.length} from decisions)`));
|
|
106
|
-
}
|
|
107
59
|
|
|
108
|
-
// Always run contract compliance if the contracts file exists (stack-aware)
|
|
109
60
|
if (!options.skipContracts) {
|
|
110
61
|
const _profileForContracts = getStackProfile(projectPath);
|
|
111
62
|
const contractsType = resolveContractsOutputType(_profileForContracts.stack);
|
|
112
63
|
const contractsPath = getAbsoluteOutputPath(projectPath, featureName, contractsType);
|
|
113
|
-
// Positive
|
|
114
|
-
//
|
|
115
|
-
// "dotnet-nextjs" stack that has a .NET backend but is ALSO isNextjs.
|
|
116
|
-
// `mode: 'light'` has to hold here too. This push sits AFTER the mode
|
|
117
|
-
// filter, so contract-compliance — which is in HEAVY_VALIDATORS — used to
|
|
118
|
-
// slip into every light run that had a contracts file, making light mode
|
|
119
|
-
// heavier than declared on exactly the compound stacks it matters for.
|
|
64
|
+
// Positive `isDotnet`, not `!isNextjs`: a "dotnet-nextjs" stack is both. This push
|
|
65
|
+
// sits after the mode filter, so light mode has to be honored again here.
|
|
120
66
|
const contractsIsHeavyAndSkipped = mode === 'light' && HEAVY_VALIDATORS.has('contract-compliance');
|
|
121
67
|
if (existsSync(contractsPath) && _profileForContracts.isDotnet && !contractsIsHeavyAndSkipped) {
|
|
122
68
|
validatorIds.push('contract-compliance');
|
|
123
69
|
}
|
|
124
70
|
}
|
|
125
71
|
|
|
126
|
-
// Deduplicate
|
|
127
72
|
const uniqueValidators = [...new Set(validatorIds)];
|
|
128
73
|
|
|
129
|
-
//
|
|
130
|
-
// projeto sem grafo). Um validador assim não acha nada — e "não achou nada"
|
|
131
|
-
// é indistinguível de "verificou e está limpo" se ninguém contar.
|
|
74
|
+
// A validator that declared itself inapplicable found nothing, which is not "clean".
|
|
132
75
|
const selfSkipped = [];
|
|
133
76
|
result.skipped = selfSkipped;
|
|
134
77
|
|
|
135
|
-
// Run each validator
|
|
136
78
|
for (const validatorId of uniqueValidators) {
|
|
137
79
|
try {
|
|
138
|
-
|
|
139
|
-
const validatorOptions = {
|
|
140
|
-
...options,
|
|
141
|
-
constraints: constraints.validators[validatorId] || {}
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
const validatorResult = await runSingleValidator(validatorId, projectPath, featureName, validatorOptions);
|
|
80
|
+
const validatorResult = await runSingleValidator(validatorId, projectPath, featureName, options);
|
|
145
81
|
|
|
146
82
|
if (validatorResult) {
|
|
147
83
|
if (validatorResult._skipReason) {
|
|
@@ -156,8 +92,6 @@ export async function runValidation(projectPath, featureName, options = {}) {
|
|
|
156
92
|
result.warnings += warnings;
|
|
157
93
|
result.issues.push(...issues);
|
|
158
94
|
|
|
159
|
-
// A validator that skipped itself checked nothing: in `results` it would
|
|
160
|
-
// read as a validator that ran clean.
|
|
161
95
|
if (!validatorResult._skipReason) result.results[validatorId] = { passed: errors === 0, issues };
|
|
162
96
|
}
|
|
163
97
|
} catch (err) {
|
|
@@ -178,10 +112,7 @@ export async function runValidation(projectPath, featureName, options = {}) {
|
|
|
178
112
|
}
|
|
179
113
|
}
|
|
180
114
|
|
|
181
|
-
//
|
|
182
|
-
// verde. Sem isto, um projeto de stack sem validadores e sem grafo receberia
|
|
183
|
-
// `validators: pass` do `morph-spec verify` tendo verificado exatamente nada
|
|
184
|
-
// — o modo de falha que este repositório já pagou caro (guardrail inerte).
|
|
115
|
+
// Every validator self-skipped: SKIP, never a green over nothing checked.
|
|
185
116
|
if (selfSkipped.length > 0 && selfSkipped.length === uniqueValidators.length) {
|
|
186
117
|
result._skipReason = `No validators ran — ${selfSkipped.map((s) => `${s.validator}: ${s.reason}`).join('; ')}`;
|
|
187
118
|
result.summary = result._skipReason;
|
|
@@ -196,44 +127,20 @@ export async function runValidation(projectPath, featureName, options = {}) {
|
|
|
196
127
|
return result;
|
|
197
128
|
}
|
|
198
129
|
|
|
199
|
-
/**
|
|
200
|
-
* Detect which validators to run, driven by the project's stack profile.
|
|
201
|
-
* @param {string} projectPath - Project root path (default: current directory)
|
|
202
|
-
* @returns {string[]} Array of validator IDs to run
|
|
203
|
-
*/
|
|
204
130
|
function detectValidators(projectPath = '.') {
|
|
205
131
|
const profile = getStackProfile(projectPath);
|
|
206
132
|
return [...profile.defaultValidators];
|
|
207
133
|
}
|
|
208
134
|
|
|
209
135
|
/**
|
|
210
|
-
* Reduce any validator's return
|
|
211
|
-
* `
|
|
212
|
-
*
|
|
213
|
-
* Validators were written at different times and return different shapes. The
|
|
214
|
-
* runner used to read `errors`/`warnings`/`issues` off the raw object, so a
|
|
215
|
-
* validator that reports through any other shape contributed ZERO — and since
|
|
216
|
-
* `passed = errors === 0`, its findings were recorded as a pass. Measured: of
|
|
217
|
-
* seven validators only two returned all three keys. `packages` — one of the
|
|
218
|
-
* two defaults for the `dotnet` stack — returned
|
|
219
|
-
* `{status, totalFiles, filesWithIssues, results}` and had every NuGet
|
|
220
|
-
* incompatibility it found thrown away, while `verify` reported green.
|
|
221
|
-
*
|
|
222
|
-
* Reading the nested `results` shape here keeps that contract in ONE place
|
|
223
|
-
* instead of asking every validator to remember it.
|
|
224
|
-
*
|
|
225
|
-
* @param {string} validatorId
|
|
226
|
-
* @param {Object} raw - whatever the validator returned
|
|
227
|
-
* @returns {{errors: number, warnings: number, issues: Array}}
|
|
136
|
+
* Reduce any validator's return shape to `{ errors, warnings, issues }`, so a
|
|
137
|
+
* validator reporting through nested `results` never contributes zero and reads as a pass.
|
|
228
138
|
*/
|
|
229
139
|
export function normalizeValidatorResult(validatorId, raw) {
|
|
230
140
|
if (!raw || typeof raw !== 'object') return { errors: 0, warnings: 0, issues: [] };
|
|
231
141
|
|
|
232
|
-
//
|
|
233
|
-
//
|
|
234
|
-
// them keyed by check name. The nested read is a FALLBACK,
|
|
235
|
-
// never additive: validators that expose both would otherwise report every
|
|
236
|
-
// finding twice.
|
|
142
|
+
// The nested read is a FALLBACK, never additive: validators exposing both
|
|
143
|
+
// shapes would otherwise report every finding twice.
|
|
237
144
|
const topLevel = Array.isArray(raw.issues) ? raw.issues : [];
|
|
238
145
|
const nested = raw.results && typeof raw.results === 'object'
|
|
239
146
|
? (Array.isArray(raw.results) ? raw.results : Object.values(raw.results))
|
|
@@ -242,8 +149,7 @@ export function normalizeValidatorResult(validatorId, raw) {
|
|
|
242
149
|
const issues = (topLevel.length ? topLevel : nested)
|
|
243
150
|
.map(i => ({ validator: validatorId, ...i }));
|
|
244
151
|
|
|
245
|
-
//
|
|
246
|
-
// issues differently than one-each. Otherwise derive from the issue levels.
|
|
152
|
+
// The validator's own counts win: it may weigh issues differently than one-each.
|
|
247
153
|
const counted = {
|
|
248
154
|
errors: issues.filter(i => i.level === 'error').length,
|
|
249
155
|
warnings: issues.filter(i => i.level === 'warning').length,
|
|
@@ -251,8 +157,7 @@ export function normalizeValidatorResult(validatorId, raw) {
|
|
|
251
157
|
const errors = Number.isFinite(raw.errors) ? raw.errors : counted.errors;
|
|
252
158
|
const warnings = Number.isFinite(raw.warnings) ? raw.warnings : counted.warnings;
|
|
253
159
|
|
|
254
|
-
//
|
|
255
|
-
// countable detail still must not read as a pass.
|
|
160
|
+
// `status: 'error'` with no countable detail still must not read as a pass.
|
|
256
161
|
if (errors === 0 && raw.status === 'error') {
|
|
257
162
|
return {
|
|
258
163
|
errors: 1,
|
|
@@ -268,9 +173,6 @@ export function normalizeValidatorResult(validatorId, raw) {
|
|
|
268
173
|
return { errors, warnings, issues };
|
|
269
174
|
}
|
|
270
175
|
|
|
271
|
-
/**
|
|
272
|
-
* Run a single validator by ID
|
|
273
|
-
*/
|
|
274
176
|
async function runSingleValidator(validatorId, projectPath, featureName, options) {
|
|
275
177
|
switch (validatorId) {
|
|
276
178
|
case 'packages': {
|
|
@@ -299,11 +201,8 @@ async function runSingleValidator(validatorId, projectPath, featureName, options
|
|
|
299
201
|
}
|
|
300
202
|
|
|
301
203
|
default:
|
|
302
|
-
// A warning, not silence
|
|
303
|
-
// a
|
|
304
|
-
// found nothing. A typo in a validator list would have read as a clean
|
|
305
|
-
// pass. Not an error — an unknown id is a configuration mistake, not a
|
|
306
|
-
// defect in the code under validation.
|
|
204
|
+
// A warning, not silence (a typo would read as a clean pass) and not an
|
|
205
|
+
// error (a config mistake, not a defect in the code under validation).
|
|
307
206
|
if (options.verbose) {
|
|
308
207
|
console.log(chalk.gray(` Unknown validator: ${validatorId}`));
|
|
309
208
|
}
|
|
@@ -320,9 +219,6 @@ async function runSingleValidator(validatorId, projectPath, featureName, options
|
|
|
320
219
|
}
|
|
321
220
|
}
|
|
322
221
|
|
|
323
|
-
/**
|
|
324
|
-
* Format validation results for console output
|
|
325
|
-
*/
|
|
326
222
|
export function formatValidationResults(result) {
|
|
327
223
|
if (result.passed && result.warnings === 0) {
|
|
328
224
|
const ranCount = Object.keys(result.results || {}).length;
|
|
@@ -337,7 +233,6 @@ export function formatValidationResults(result) {
|
|
|
337
233
|
console.log(chalk.red(`\n ❌ Validation FAILED: ${result.errors} error(s), ${result.warnings} warning(s)\n`));
|
|
338
234
|
}
|
|
339
235
|
|
|
340
|
-
// Group issues by level
|
|
341
236
|
const errors = result.issues.filter(i => i.level === 'error');
|
|
342
237
|
const warnings = result.issues.filter(i => i.level === 'warning');
|
|
343
238
|
|