musubi-sdd 5.1.0 ā 5.6.1
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/README.ja.md +106 -48
- package/README.md +110 -32
- package/bin/musubi-analyze.js +74 -67
- package/bin/musubi-browser.js +27 -26
- package/bin/musubi-change.js +48 -47
- package/bin/musubi-checkpoint.js +10 -7
- package/bin/musubi-convert.js +25 -25
- package/bin/musubi-costs.js +27 -10
- package/bin/musubi-gui.js +52 -46
- package/bin/musubi-init.js +1952 -10
- package/bin/musubi-orchestrate.js +327 -239
- package/bin/musubi-remember.js +69 -56
- package/bin/musubi-resolve.js +53 -45
- package/bin/musubi-trace.js +51 -22
- package/bin/musubi-validate.js +39 -30
- package/bin/musubi-workflow.js +33 -34
- package/bin/musubi.js +39 -2
- package/package.json +1 -1
- package/src/agents/agent-loop.js +94 -95
- package/src/agents/agentic/code-generator.js +119 -109
- package/src/agents/agentic/code-reviewer.js +105 -108
- package/src/agents/agentic/index.js +4 -4
- package/src/agents/browser/action-executor.js +13 -13
- package/src/agents/browser/ai-comparator.js +11 -10
- package/src/agents/browser/context-manager.js +6 -6
- package/src/agents/browser/index.js +5 -5
- package/src/agents/browser/nl-parser.js +31 -46
- package/src/agents/browser/screenshot.js +2 -2
- package/src/agents/browser/test-generator.js +6 -4
- package/src/agents/function-tool.js +71 -65
- package/src/agents/index.js +7 -7
- package/src/agents/schema-generator.js +98 -94
- package/src/analyzers/ast-extractor.js +158 -146
- package/src/analyzers/codegraph-auto-update.js +858 -0
- package/src/analyzers/complexity-analyzer.js +536 -0
- package/src/analyzers/context-optimizer.js +241 -126
- package/src/analyzers/impact-analyzer.js +1 -1
- package/src/analyzers/large-project-analyzer.js +766 -0
- package/src/analyzers/repository-map.js +77 -81
- package/src/analyzers/security-analyzer.js +19 -11
- package/src/analyzers/stuck-detector.js +19 -17
- package/src/converters/index.js +78 -57
- package/src/converters/ir/types.js +12 -12
- package/src/converters/parsers/musubi-parser.js +134 -126
- package/src/converters/parsers/openapi-parser.js +70 -53
- package/src/converters/parsers/speckit-parser.js +239 -175
- package/src/converters/writers/musubi-writer.js +123 -118
- package/src/converters/writers/speckit-writer.js +124 -113
- package/src/generators/rust-migration-generator.js +512 -0
- package/src/gui/public/index.html +1365 -1211
- package/src/gui/server.js +41 -40
- package/src/gui/services/file-watcher.js +23 -8
- package/src/gui/services/project-scanner.js +26 -20
- package/src/gui/services/replanning-service.js +27 -23
- package/src/gui/services/traceability-service.js +8 -8
- package/src/gui/services/workflow-service.js +14 -7
- package/src/index.js +151 -0
- package/src/integrations/cicd.js +90 -104
- package/src/integrations/codegraph-mcp.js +643 -0
- package/src/integrations/documentation.js +142 -103
- package/src/integrations/examples.js +95 -80
- package/src/integrations/github-client.js +17 -17
- package/src/integrations/index.js +5 -5
- package/src/integrations/mcp/index.js +21 -21
- package/src/integrations/mcp/mcp-context-provider.js +76 -78
- package/src/integrations/mcp/mcp-discovery.js +74 -72
- package/src/integrations/mcp/mcp-tool-registry.js +99 -94
- package/src/integrations/mcp-connector.js +70 -66
- package/src/integrations/platforms.js +50 -49
- package/src/integrations/tool-discovery.js +37 -31
- package/src/llm-providers/anthropic-provider.js +11 -11
- package/src/llm-providers/base-provider.js +16 -18
- package/src/llm-providers/copilot-provider.js +22 -19
- package/src/llm-providers/index.js +26 -25
- package/src/llm-providers/ollama-provider.js +11 -11
- package/src/llm-providers/openai-provider.js +12 -12
- package/src/managers/agent-memory.js +36 -24
- package/src/managers/checkpoint-manager.js +4 -8
- package/src/managers/delta-spec.js +19 -19
- package/src/managers/index.js +13 -4
- package/src/managers/memory-condenser.js +35 -45
- package/src/managers/repo-skill-manager.js +57 -31
- package/src/managers/skill-loader.js +25 -22
- package/src/managers/skill-tools.js +36 -72
- package/src/managers/workflow.js +30 -22
- package/src/monitoring/cost-tracker.js +48 -46
- package/src/monitoring/incident-manager.js +116 -106
- package/src/monitoring/index.js +144 -134
- package/src/monitoring/observability.js +75 -62
- package/src/monitoring/quality-dashboard.js +45 -41
- package/src/monitoring/release-manager.js +63 -53
- package/src/orchestration/agent-skill-binding.js +39 -47
- package/src/orchestration/error-handler.js +65 -107
- package/src/orchestration/guardrails/base-guardrail.js +26 -24
- package/src/orchestration/guardrails/guardrail-rules.js +50 -64
- package/src/orchestration/guardrails/index.js +5 -5
- package/src/orchestration/guardrails/input-guardrail.js +58 -45
- package/src/orchestration/guardrails/output-guardrail.js +104 -81
- package/src/orchestration/guardrails/safety-check.js +79 -79
- package/src/orchestration/index.js +38 -55
- package/src/orchestration/mcp-tool-adapters.js +96 -99
- package/src/orchestration/orchestration-engine.js +21 -21
- package/src/orchestration/pattern-registry.js +60 -45
- package/src/orchestration/patterns/auto.js +34 -47
- package/src/orchestration/patterns/group-chat.js +59 -65
- package/src/orchestration/patterns/handoff.js +67 -65
- package/src/orchestration/patterns/human-in-loop.js +51 -72
- package/src/orchestration/patterns/nested.js +25 -40
- package/src/orchestration/patterns/sequential.js +35 -34
- package/src/orchestration/patterns/swarm.js +63 -56
- package/src/orchestration/patterns/triage.js +150 -109
- package/src/orchestration/reasoning/index.js +9 -9
- package/src/orchestration/reasoning/planning-engine.js +143 -140
- package/src/orchestration/reasoning/reasoning-engine.js +206 -144
- package/src/orchestration/reasoning/self-correction.js +121 -128
- package/src/orchestration/replanning/adaptive-goal-modifier.js +107 -112
- package/src/orchestration/replanning/alternative-generator.js +37 -42
- package/src/orchestration/replanning/config.js +63 -59
- package/src/orchestration/replanning/goal-progress-tracker.js +98 -100
- package/src/orchestration/replanning/index.js +24 -20
- package/src/orchestration/replanning/plan-evaluator.js +49 -50
- package/src/orchestration/replanning/plan-monitor.js +32 -28
- package/src/orchestration/replanning/proactive-path-optimizer.js +175 -178
- package/src/orchestration/replanning/replan-history.js +33 -26
- package/src/orchestration/replanning/replanning-engine.js +106 -108
- package/src/orchestration/skill-executor.js +107 -109
- package/src/orchestration/skill-registry.js +85 -89
- package/src/orchestration/workflow-examples.js +228 -231
- package/src/orchestration/workflow-executor.js +65 -68
- package/src/orchestration/workflow-orchestrator.js +72 -73
- package/src/phase4-integration.js +47 -40
- package/src/phase5-integration.js +89 -30
- package/src/reporters/coverage-report.js +82 -30
- package/src/reporters/hierarchical-reporter.js +498 -0
- package/src/reporters/traceability-matrix-report.js +29 -20
- package/src/resolvers/issue-resolver.js +43 -31
- package/src/steering/advanced-validation.js +133 -124
- package/src/steering/auto-updater.js +60 -73
- package/src/steering/index.js +6 -6
- package/src/steering/quality-metrics.js +41 -35
- package/src/steering/steering-auto-update.js +83 -86
- package/src/steering/steering-validator.js +98 -106
- package/src/steering/template-constraints.js +53 -54
- package/src/templates/agents/claude-code/CLAUDE.md +32 -32
- package/src/templates/agents/claude-code/skills/agent-assistant/SKILL.md +13 -5
- package/src/templates/agents/claude-code/skills/ai-ml-engineer/mlops-guide.md +23 -23
- package/src/templates/agents/claude-code/skills/ai-ml-engineer/model-card-template.md +60 -41
- package/src/templates/agents/claude-code/skills/api-designer/api-patterns.md +27 -19
- package/src/templates/agents/claude-code/skills/api-designer/openapi-template.md +11 -7
- package/src/templates/agents/claude-code/skills/bug-hunter/SKILL.md +4 -3
- package/src/templates/agents/claude-code/skills/bug-hunter/root-cause-analysis.md +37 -15
- package/src/templates/agents/claude-code/skills/change-impact-analyzer/dependency-graph-patterns.md +36 -42
- package/src/templates/agents/claude-code/skills/change-impact-analyzer/impact-analysis-template.md +69 -60
- package/src/templates/agents/claude-code/skills/cloud-architect/aws-patterns.md +31 -38
- package/src/templates/agents/claude-code/skills/cloud-architect/azure-patterns.md +28 -23
- package/src/templates/agents/claude-code/skills/code-reviewer/SKILL.md +61 -0
- package/src/templates/agents/claude-code/skills/code-reviewer/best-practices.md +27 -0
- package/src/templates/agents/claude-code/skills/code-reviewer/review-checklist.md +29 -10
- package/src/templates/agents/claude-code/skills/code-reviewer/review-standards.md +29 -24
- package/src/templates/agents/claude-code/skills/constitution-enforcer/SKILL.md +8 -6
- package/src/templates/agents/claude-code/skills/constitution-enforcer/constitutional-articles.md +62 -26
- package/src/templates/agents/claude-code/skills/constitution-enforcer/phase-minus-one-gates.md +35 -16
- package/src/templates/agents/claude-code/skills/database-administrator/backup-recovery.md +27 -17
- package/src/templates/agents/claude-code/skills/database-administrator/tuning-guide.md +25 -20
- package/src/templates/agents/claude-code/skills/database-schema-designer/schema-patterns.md +39 -22
- package/src/templates/agents/claude-code/skills/devops-engineer/ci-cd-templates.md +25 -22
- package/src/templates/agents/claude-code/skills/issue-resolver/SKILL.md +24 -21
- package/src/templates/agents/claude-code/skills/orchestrator/SKILL.md +148 -63
- package/src/templates/agents/claude-code/skills/orchestrator/patterns.md +35 -16
- package/src/templates/agents/claude-code/skills/orchestrator/selection-matrix.md +69 -64
- package/src/templates/agents/claude-code/skills/performance-engineer/optimization-playbook.md +47 -47
- package/src/templates/agents/claude-code/skills/performance-optimizer/SKILL.md +69 -0
- package/src/templates/agents/claude-code/skills/performance-optimizer/benchmark-template.md +63 -45
- package/src/templates/agents/claude-code/skills/performance-optimizer/optimization-patterns.md +33 -35
- package/src/templates/agents/claude-code/skills/project-manager/SKILL.md +7 -6
- package/src/templates/agents/claude-code/skills/project-manager/agile-ceremonies.md +47 -28
- package/src/templates/agents/claude-code/skills/project-manager/project-templates.md +94 -78
- package/src/templates/agents/claude-code/skills/quality-assurance/SKILL.md +20 -17
- package/src/templates/agents/claude-code/skills/quality-assurance/qa-plan-template.md +63 -49
- package/src/templates/agents/claude-code/skills/release-coordinator/SKILL.md +5 -5
- package/src/templates/agents/claude-code/skills/release-coordinator/feature-flag-guide.md +30 -26
- package/src/templates/agents/claude-code/skills/release-coordinator/release-plan-template.md +67 -35
- package/src/templates/agents/claude-code/skills/requirements-analyst/ears-format.md +54 -42
- package/src/templates/agents/claude-code/skills/requirements-analyst/validation-rules.md +36 -33
- package/src/templates/agents/claude-code/skills/security-auditor/SKILL.md +77 -19
- package/src/templates/agents/claude-code/skills/security-auditor/audit-checklists.md +24 -24
- package/src/templates/agents/claude-code/skills/security-auditor/owasp-top-10.md +61 -20
- package/src/templates/agents/claude-code/skills/security-auditor/vulnerability-patterns.md +43 -11
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/incident-response-template.md +55 -25
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/observability-patterns.md +78 -68
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/slo-sli-guide.md +73 -53
- package/src/templates/agents/claude-code/skills/software-developer/solid-principles.md +83 -37
- package/src/templates/agents/claude-code/skills/software-developer/test-first-workflow.md +38 -31
- package/src/templates/agents/claude-code/skills/steering/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/steering/auto-update-rules.md +31 -0
- package/src/templates/agents/claude-code/skills/system-architect/adr-template.md +25 -7
- package/src/templates/agents/claude-code/skills/system-architect/c4-model-guide.md +74 -61
- package/src/templates/agents/claude-code/skills/technical-writer/doc-templates/documentation-templates.md +70 -52
- package/src/templates/agents/claude-code/skills/test-engineer/SKILL.md +2 -0
- package/src/templates/agents/claude-code/skills/test-engineer/ears-test-mapping.md +75 -71
- package/src/templates/agents/claude-code/skills/test-engineer/test-types.md +85 -63
- package/src/templates/agents/claude-code/skills/traceability-auditor/coverage-matrix-template.md +39 -36
- package/src/templates/agents/claude-code/skills/traceability-auditor/gap-detection-rules.md +22 -17
- package/src/templates/agents/claude-code/skills/ui-ux-designer/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/ui-ux-designer/accessibility-guidelines.md +49 -75
- package/src/templates/agents/claude-code/skills/ui-ux-designer/design-system-components.md +71 -59
- package/src/templates/agents/codex/AGENTS.md +74 -42
- package/src/templates/agents/cursor/AGENTS.md +74 -42
- package/src/templates/agents/gemini-cli/GEMINI.md +74 -42
- package/src/templates/agents/github-copilot/AGENTS.md +83 -51
- package/src/templates/agents/qwen-code/QWEN.md +74 -42
- package/src/templates/agents/windsurf/AGENTS.md +74 -42
- package/src/templates/architectures/README.md +41 -0
- package/src/templates/architectures/clean-architecture/README.md +113 -0
- package/src/templates/architectures/event-driven/README.md +162 -0
- package/src/templates/architectures/hexagonal/README.md +130 -0
- package/src/templates/index.js +6 -1
- package/src/templates/locale-manager.js +16 -16
- package/src/templates/shared/delta-spec-template.md +20 -13
- package/src/templates/shared/github-actions/musubi-issue-resolver.yml +5 -5
- package/src/templates/shared/github-actions/musubi-security-check.yml +3 -3
- package/src/templates/shared/github-actions/musubi-validate.yml +4 -4
- package/src/templates/shared/steering/structure.md +95 -0
- package/src/templates/skills/browser-agent.md +21 -16
- package/src/templates/skills/web-gui.md +8 -0
- package/src/templates/template-constraints.js +50 -53
- package/src/validators/advanced-validation.js +30 -36
- package/src/validators/constitutional-validator.js +77 -73
- package/src/validators/critic-system.js +49 -59
- package/src/validators/delta-format.js +59 -55
- package/src/validators/traceability-validator.js +7 -11
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Constitutional Validator
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
6
|
* Validates compliance with the 9 Constitutional Articles.
|
|
7
7
|
* Part of MUSUBI SDD governance system.
|
|
8
8
|
*/
|
|
@@ -25,15 +25,15 @@ class ConstitutionalValidator {
|
|
|
25
25
|
async validateAll() {
|
|
26
26
|
console.log('šļø Constitutional Validation Starting...\n');
|
|
27
27
|
|
|
28
|
-
await this.validateArticleI();
|
|
29
|
-
await this.validateArticleII();
|
|
30
|
-
await this.validateArticleIII();
|
|
31
|
-
await this.validateArticleIV();
|
|
32
|
-
await this.validateArticleV();
|
|
33
|
-
await this.validateArticleVI();
|
|
34
|
-
await this.validateArticleVII();
|
|
28
|
+
await this.validateArticleI(); // Library-First
|
|
29
|
+
await this.validateArticleII(); // CLI Interface
|
|
30
|
+
await this.validateArticleIII(); // Test-First
|
|
31
|
+
await this.validateArticleIV(); // EARS Format
|
|
32
|
+
await this.validateArticleV(); // Traceability
|
|
33
|
+
await this.validateArticleVI(); // Project Memory
|
|
34
|
+
await this.validateArticleVII(); // Simplicity Gate
|
|
35
35
|
await this.validateArticleVIII(); // Anti-Abstraction
|
|
36
|
-
await this.validateArticleIX();
|
|
36
|
+
await this.validateArticleIX(); // Integration-First
|
|
37
37
|
|
|
38
38
|
return this.generateReport();
|
|
39
39
|
}
|
|
@@ -43,9 +43,9 @@ class ConstitutionalValidator {
|
|
|
43
43
|
*/
|
|
44
44
|
async validateArticleI() {
|
|
45
45
|
const article = 'Article I: Library-First';
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
// Check for lib/ or packages/ directory
|
|
48
|
-
const libDirs = ['lib', 'packages', 'libs'].filter(dir =>
|
|
48
|
+
const libDirs = ['lib', 'packages', 'libs'].filter(dir =>
|
|
49
49
|
fs.existsSync(path.join(this.projectRoot, dir))
|
|
50
50
|
);
|
|
51
51
|
|
|
@@ -53,31 +53,31 @@ class ConstitutionalValidator {
|
|
|
53
53
|
this.warnings.push({
|
|
54
54
|
article,
|
|
55
55
|
message: 'No library directory found (lib/, packages/, libs/)',
|
|
56
|
-
recommendation: 'Create a lib/ directory for reusable components'
|
|
56
|
+
recommendation: 'Create a lib/ directory for reusable components',
|
|
57
57
|
});
|
|
58
58
|
} else {
|
|
59
59
|
this.passes.push({
|
|
60
60
|
article,
|
|
61
|
-
message: `Library directory found: ${libDirs.join(', ')}
|
|
61
|
+
message: `Library directory found: ${libDirs.join(', ')}`,
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
// Check if features have test suites
|
|
66
66
|
const libPath = path.join(this.projectRoot, libDirs[0] || 'lib');
|
|
67
67
|
if (fs.existsSync(libPath)) {
|
|
68
|
-
const subDirs = fs
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
const subDirs = fs
|
|
69
|
+
.readdirSync(libPath)
|
|
70
|
+
.filter(f => fs.statSync(path.join(libPath, f)).isDirectory());
|
|
71
71
|
|
|
72
72
|
for (const lib of subDirs) {
|
|
73
73
|
const testPath = path.join(libPath, lib, 'tests');
|
|
74
74
|
const testFile = glob.sync(path.join(libPath, lib, '*.test.{js,ts}'));
|
|
75
|
-
|
|
75
|
+
|
|
76
76
|
if (!fs.existsSync(testPath) && testFile.length === 0) {
|
|
77
77
|
this.warnings.push({
|
|
78
78
|
article,
|
|
79
79
|
message: `Library '${lib}' has no test suite`,
|
|
80
|
-
recommendation: `Add tests to ${libPath}/${lib}
|
|
80
|
+
recommendation: `Add tests to ${libPath}/${lib}/`,
|
|
81
81
|
});
|
|
82
82
|
}
|
|
83
83
|
}
|
|
@@ -89,7 +89,7 @@ class ConstitutionalValidator {
|
|
|
89
89
|
*/
|
|
90
90
|
async validateArticleII() {
|
|
91
91
|
const article = 'Article II: CLI Interface';
|
|
92
|
-
|
|
92
|
+
|
|
93
93
|
// Check for bin/ directory
|
|
94
94
|
const binPath = path.join(this.projectRoot, 'bin');
|
|
95
95
|
const packageJson = this.readPackageJson();
|
|
@@ -98,18 +98,18 @@ class ConstitutionalValidator {
|
|
|
98
98
|
const cliFiles = fs.readdirSync(binPath);
|
|
99
99
|
this.passes.push({
|
|
100
100
|
article,
|
|
101
|
-
message: `CLI interfaces found in bin/: ${cliFiles.length} file(s)
|
|
101
|
+
message: `CLI interfaces found in bin/: ${cliFiles.length} file(s)`,
|
|
102
102
|
});
|
|
103
103
|
} else if (packageJson?.bin) {
|
|
104
104
|
this.passes.push({
|
|
105
105
|
article,
|
|
106
|
-
message: `CLI entry points defined in package.json
|
|
106
|
+
message: `CLI entry points defined in package.json`,
|
|
107
107
|
});
|
|
108
108
|
} else {
|
|
109
109
|
this.warnings.push({
|
|
110
110
|
article,
|
|
111
111
|
message: 'No CLI interface found',
|
|
112
|
-
recommendation: 'Add bin/ directory or define "bin" in package.json'
|
|
112
|
+
recommendation: 'Add bin/ directory or define "bin" in package.json',
|
|
113
113
|
});
|
|
114
114
|
}
|
|
115
115
|
}
|
|
@@ -119,7 +119,7 @@ class ConstitutionalValidator {
|
|
|
119
119
|
*/
|
|
120
120
|
async validateArticleIII() {
|
|
121
121
|
const article = 'Article III: Test-First';
|
|
122
|
-
|
|
122
|
+
|
|
123
123
|
// Check for test directory
|
|
124
124
|
const testDirs = ['tests', 'test', '__tests__', 'spec'].filter(dir =>
|
|
125
125
|
fs.existsSync(path.join(this.projectRoot, dir))
|
|
@@ -130,7 +130,7 @@ class ConstitutionalValidator {
|
|
|
130
130
|
article,
|
|
131
131
|
message: 'No test directory found',
|
|
132
132
|
severity: 'critical',
|
|
133
|
-
recommendation: 'Create tests/ directory with test files'
|
|
133
|
+
recommendation: 'Create tests/ directory with test files',
|
|
134
134
|
});
|
|
135
135
|
return;
|
|
136
136
|
}
|
|
@@ -143,12 +143,12 @@ class ConstitutionalValidator {
|
|
|
143
143
|
this.warnings.push({
|
|
144
144
|
article,
|
|
145
145
|
message: 'No test coverage configuration found',
|
|
146
|
-
recommendation: 'Configure test coverage (80% threshold required)'
|
|
146
|
+
recommendation: 'Configure test coverage (80% threshold required)',
|
|
147
147
|
});
|
|
148
148
|
} else {
|
|
149
149
|
this.passes.push({
|
|
150
150
|
article,
|
|
151
|
-
message: `Test infrastructure found: ${testDirs.join(', ')}
|
|
151
|
+
message: `Test infrastructure found: ${testDirs.join(', ')}`,
|
|
152
152
|
});
|
|
153
153
|
}
|
|
154
154
|
}
|
|
@@ -158,17 +158,17 @@ class ConstitutionalValidator {
|
|
|
158
158
|
*/
|
|
159
159
|
async validateArticleIV() {
|
|
160
160
|
const article = 'Article IV: EARS Format';
|
|
161
|
-
|
|
161
|
+
|
|
162
162
|
// Find requirements files
|
|
163
163
|
const reqFiles = glob.sync(path.join(this.projectRoot, '**/*requirements*.md'), {
|
|
164
|
-
ignore: ['**/node_modules/**', '**/templates/**']
|
|
164
|
+
ignore: ['**/node_modules/**', '**/templates/**'],
|
|
165
165
|
});
|
|
166
166
|
|
|
167
167
|
if (reqFiles.length === 0) {
|
|
168
168
|
this.warnings.push({
|
|
169
169
|
article,
|
|
170
170
|
message: 'No requirements files found',
|
|
171
|
-
recommendation: 'Create requirements using EARS format'
|
|
171
|
+
recommendation: 'Create requirements using EARS format',
|
|
172
172
|
});
|
|
173
173
|
return;
|
|
174
174
|
}
|
|
@@ -183,18 +183,18 @@ class ConstitutionalValidator {
|
|
|
183
183
|
article,
|
|
184
184
|
message: `${path.basename(file)} not in EARS format`,
|
|
185
185
|
severity: 'high',
|
|
186
|
-
recommendation: 'Use EARS patterns: WHEN/WHILE/IF/WHERE + SHALL'
|
|
186
|
+
recommendation: 'Use EARS patterns: WHEN/WHILE/IF/WHERE + SHALL',
|
|
187
187
|
});
|
|
188
188
|
} else if (hasAmbiguous) {
|
|
189
189
|
this.warnings.push({
|
|
190
190
|
article,
|
|
191
191
|
message: `${path.basename(file)} contains ambiguous keywords`,
|
|
192
|
-
recommendation: 'Replace should/may with SHALL/MUST'
|
|
192
|
+
recommendation: 'Replace should/may with SHALL/MUST',
|
|
193
193
|
});
|
|
194
194
|
} else {
|
|
195
195
|
this.passes.push({
|
|
196
196
|
article,
|
|
197
|
-
message: `${path.basename(file)} uses EARS format
|
|
197
|
+
message: `${path.basename(file)} uses EARS format`,
|
|
198
198
|
});
|
|
199
199
|
}
|
|
200
200
|
}
|
|
@@ -205,28 +205,28 @@ class ConstitutionalValidator {
|
|
|
205
205
|
*/
|
|
206
206
|
async validateArticleV() {
|
|
207
207
|
const article = 'Article V: Traceability';
|
|
208
|
-
|
|
208
|
+
|
|
209
209
|
// Check for traceability matrix
|
|
210
210
|
const traceFiles = glob.sync(path.join(this.projectRoot, '**/*{trace,coverage-matrix}*.md'), {
|
|
211
|
-
ignore: ['**/node_modules/**']
|
|
211
|
+
ignore: ['**/node_modules/**'],
|
|
212
212
|
});
|
|
213
213
|
|
|
214
214
|
if (traceFiles.length === 0) {
|
|
215
215
|
this.warnings.push({
|
|
216
216
|
article,
|
|
217
217
|
message: 'No traceability matrix found',
|
|
218
|
-
recommendation: 'Create coverage-matrix.md linking REQ ā Design ā Test'
|
|
218
|
+
recommendation: 'Create coverage-matrix.md linking REQ ā Design ā Test',
|
|
219
219
|
});
|
|
220
220
|
} else {
|
|
221
221
|
this.passes.push({
|
|
222
222
|
article,
|
|
223
|
-
message: `Traceability files found: ${traceFiles.length}
|
|
223
|
+
message: `Traceability files found: ${traceFiles.length}`,
|
|
224
224
|
});
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
// Check for REQ-XXX patterns in test files
|
|
228
228
|
const testFiles = glob.sync(path.join(this.projectRoot, '**/*.test.{js,ts}'), {
|
|
229
|
-
ignore: ['**/node_modules/**']
|
|
229
|
+
ignore: ['**/node_modules/**'],
|
|
230
230
|
});
|
|
231
231
|
|
|
232
232
|
let testsWithReqs = 0;
|
|
@@ -241,7 +241,7 @@ class ConstitutionalValidator {
|
|
|
241
241
|
this.warnings.push({
|
|
242
242
|
article,
|
|
243
243
|
message: 'Test files do not reference requirement IDs',
|
|
244
|
-
recommendation: 'Add REQ-XXX-NNN references to test descriptions'
|
|
244
|
+
recommendation: 'Add REQ-XXX-NNN references to test descriptions',
|
|
245
245
|
});
|
|
246
246
|
}
|
|
247
247
|
}
|
|
@@ -251,7 +251,7 @@ class ConstitutionalValidator {
|
|
|
251
251
|
*/
|
|
252
252
|
async validateArticleVI() {
|
|
253
253
|
const article = 'Article VI: Project Memory';
|
|
254
|
-
|
|
254
|
+
|
|
255
255
|
const steeringPath = path.join(this.projectRoot, 'steering');
|
|
256
256
|
const requiredFiles = ['structure.md', 'tech.md', 'product.md'];
|
|
257
257
|
|
|
@@ -260,7 +260,7 @@ class ConstitutionalValidator {
|
|
|
260
260
|
article,
|
|
261
261
|
message: 'No steering/ directory found',
|
|
262
262
|
severity: 'critical',
|
|
263
|
-
recommendation: 'Run "musubi init" to create steering files'
|
|
263
|
+
recommendation: 'Run "musubi init" to create steering files',
|
|
264
264
|
});
|
|
265
265
|
return;
|
|
266
266
|
}
|
|
@@ -272,12 +272,12 @@ class ConstitutionalValidator {
|
|
|
272
272
|
article,
|
|
273
273
|
message: `Missing steering file: ${file}`,
|
|
274
274
|
severity: 'high',
|
|
275
|
-
recommendation: `Create steering/${file}
|
|
275
|
+
recommendation: `Create steering/${file}`,
|
|
276
276
|
});
|
|
277
277
|
} else {
|
|
278
278
|
this.passes.push({
|
|
279
279
|
article,
|
|
280
|
-
message: `Found steering/${file}
|
|
280
|
+
message: `Found steering/${file}`,
|
|
281
281
|
});
|
|
282
282
|
}
|
|
283
283
|
}
|
|
@@ -288,7 +288,7 @@ class ConstitutionalValidator {
|
|
|
288
288
|
*/
|
|
289
289
|
async validateArticleVII() {
|
|
290
290
|
const article = 'Article VII: Simplicity Gate';
|
|
291
|
-
|
|
291
|
+
|
|
292
292
|
// Count top-level directories that look like projects
|
|
293
293
|
const projectIndicators = ['package.json', 'Cargo.toml', 'pyproject.toml', 'go.mod'];
|
|
294
294
|
let projectCount = 0;
|
|
@@ -307,9 +307,7 @@ class ConstitutionalValidator {
|
|
|
307
307
|
const subProjects = fs.readdirSync(packagesPath).filter(f => {
|
|
308
308
|
const subPath = path.join(packagesPath, f);
|
|
309
309
|
if (!fs.statSync(subPath).isDirectory()) return false;
|
|
310
|
-
return projectIndicators.some(ind =>
|
|
311
|
-
fs.existsSync(path.join(subPath, ind))
|
|
312
|
-
);
|
|
310
|
+
return projectIndicators.some(ind => fs.existsSync(path.join(subPath, ind)));
|
|
313
311
|
});
|
|
314
312
|
projectCount += subProjects.length;
|
|
315
313
|
}
|
|
@@ -321,19 +319,19 @@ class ConstitutionalValidator {
|
|
|
321
319
|
article,
|
|
322
320
|
message: `${projectCount} projects detected (> 3 limit)`,
|
|
323
321
|
severity: 'high',
|
|
324
|
-
recommendation: 'Document justification in steering/complexity-tracking.md'
|
|
322
|
+
recommendation: 'Document justification in steering/complexity-tracking.md',
|
|
325
323
|
});
|
|
326
324
|
} else {
|
|
327
325
|
this.warnings.push({
|
|
328
326
|
article,
|
|
329
327
|
message: `${projectCount} projects (complexity justified)`,
|
|
330
|
-
recommendation: 'Review complexity-tracking.md periodically'
|
|
328
|
+
recommendation: 'Review complexity-tracking.md periodically',
|
|
331
329
|
});
|
|
332
330
|
}
|
|
333
331
|
} else {
|
|
334
332
|
this.passes.push({
|
|
335
333
|
article,
|
|
336
|
-
message: `${projectCount} project(s) - within limit
|
|
334
|
+
message: `${projectCount} project(s) - within limit`,
|
|
337
335
|
});
|
|
338
336
|
}
|
|
339
337
|
}
|
|
@@ -343,20 +341,20 @@ class ConstitutionalValidator {
|
|
|
343
341
|
*/
|
|
344
342
|
async validateArticleVIII() {
|
|
345
343
|
const article = 'Article VIII: Anti-Abstraction';
|
|
346
|
-
|
|
344
|
+
|
|
347
345
|
// Check for common wrapper patterns
|
|
348
346
|
const wrapperPatterns = [
|
|
349
347
|
'**/BaseRepository.{js,ts}',
|
|
350
348
|
'**/BaseService.{js,ts}',
|
|
351
349
|
'**/AbstractFactory.{js,ts}',
|
|
352
350
|
'**/wrapper/*.{js,ts}',
|
|
353
|
-
'**/adapters/*.{js,ts}'
|
|
351
|
+
'**/adapters/*.{js,ts}',
|
|
354
352
|
];
|
|
355
353
|
|
|
356
354
|
const potentialWrappers = [];
|
|
357
355
|
for (const pattern of wrapperPatterns) {
|
|
358
356
|
const matches = glob.sync(path.join(this.projectRoot, pattern), {
|
|
359
|
-
ignore: ['**/node_modules/**', '**/templates/**']
|
|
357
|
+
ignore: ['**/node_modules/**', '**/templates/**'],
|
|
360
358
|
});
|
|
361
359
|
potentialWrappers.push(...matches);
|
|
362
360
|
}
|
|
@@ -365,12 +363,12 @@ class ConstitutionalValidator {
|
|
|
365
363
|
this.warnings.push({
|
|
366
364
|
article,
|
|
367
365
|
message: `Potential wrapper abstractions detected: ${potentialWrappers.length} file(s)`,
|
|
368
|
-
recommendation: 'Verify abstractions are justified per Phase -1 Gate'
|
|
366
|
+
recommendation: 'Verify abstractions are justified per Phase -1 Gate',
|
|
369
367
|
});
|
|
370
368
|
} else {
|
|
371
369
|
this.passes.push({
|
|
372
370
|
article,
|
|
373
|
-
message: 'No unnecessary abstraction layers detected'
|
|
371
|
+
message: 'No unnecessary abstraction layers detected',
|
|
374
372
|
});
|
|
375
373
|
}
|
|
376
374
|
}
|
|
@@ -380,14 +378,15 @@ class ConstitutionalValidator {
|
|
|
380
378
|
*/
|
|
381
379
|
async validateArticleIX() {
|
|
382
380
|
const article = 'Article IX: Integration-First';
|
|
383
|
-
|
|
381
|
+
|
|
384
382
|
// Check for docker-compose for test infrastructure
|
|
385
|
-
const hasDockerCompose =
|
|
386
|
-
|
|
383
|
+
const hasDockerCompose =
|
|
384
|
+
fs.existsSync(path.join(this.projectRoot, 'docker-compose.yml')) ||
|
|
385
|
+
fs.existsSync(path.join(this.projectRoot, 'docker-compose.test.yml'));
|
|
387
386
|
|
|
388
387
|
// Check for mock usage
|
|
389
388
|
const testFiles = glob.sync(path.join(this.projectRoot, '**/*.test.{js,ts}'), {
|
|
390
|
-
ignore: ['**/node_modules/**']
|
|
389
|
+
ignore: ['**/node_modules/**'],
|
|
391
390
|
});
|
|
392
391
|
|
|
393
392
|
let mockCount = 0;
|
|
@@ -401,12 +400,12 @@ class ConstitutionalValidator {
|
|
|
401
400
|
this.warnings.push({
|
|
402
401
|
article,
|
|
403
402
|
message: 'No docker-compose for test infrastructure',
|
|
404
|
-
recommendation: 'Add docker-compose.yml for real service testing'
|
|
403
|
+
recommendation: 'Add docker-compose.yml for real service testing',
|
|
405
404
|
});
|
|
406
405
|
} else if (hasDockerCompose) {
|
|
407
406
|
this.passes.push({
|
|
408
407
|
article,
|
|
409
|
-
message: 'Docker Compose available for integration tests'
|
|
408
|
+
message: 'Docker Compose available for integration tests',
|
|
410
409
|
});
|
|
411
410
|
}
|
|
412
411
|
|
|
@@ -414,7 +413,7 @@ class ConstitutionalValidator {
|
|
|
414
413
|
this.warnings.push({
|
|
415
414
|
article,
|
|
416
415
|
message: `High mock usage detected (${mockCount} mocks)`,
|
|
417
|
-
recommendation: 'Prefer real services; document mock justifications'
|
|
416
|
+
recommendation: 'Prefer real services; document mock justifications',
|
|
418
417
|
});
|
|
419
418
|
}
|
|
420
419
|
}
|
|
@@ -441,19 +440,21 @@ class ConstitutionalValidator {
|
|
|
441
440
|
passes: this.passes.length,
|
|
442
441
|
warnings: this.warnings.length,
|
|
443
442
|
violations: this.violations.length,
|
|
444
|
-
status: this.violations.length === 0 ? 'COMPLIANT' : 'NON-COMPLIANT'
|
|
443
|
+
status: this.violations.length === 0 ? 'COMPLIANT' : 'NON-COMPLIANT',
|
|
445
444
|
},
|
|
446
445
|
passes: this.passes,
|
|
447
446
|
warnings: this.warnings,
|
|
448
|
-
violations: this.violations
|
|
447
|
+
violations: this.violations,
|
|
449
448
|
};
|
|
450
449
|
|
|
451
450
|
console.log('\n' + '='.repeat(60));
|
|
452
451
|
console.log('š CONSTITUTIONAL VALIDATION REPORT');
|
|
453
452
|
console.log('='.repeat(60));
|
|
454
453
|
console.log(`Status: ${report.summary.status}`);
|
|
455
|
-
console.log(
|
|
456
|
-
|
|
454
|
+
console.log(
|
|
455
|
+
`Passes: ${report.summary.passes} | Warnings: ${report.summary.warnings} | Violations: ${report.summary.violations}`
|
|
456
|
+
);
|
|
457
|
+
|
|
457
458
|
if (this.violations.length > 0) {
|
|
458
459
|
console.log('\nā VIOLATIONS:');
|
|
459
460
|
this.violations.forEach(v => {
|
|
@@ -481,14 +482,17 @@ class ConstitutionalValidator {
|
|
|
481
482
|
if (require.main === module) {
|
|
482
483
|
const projectRoot = process.argv[2] || process.cwd();
|
|
483
484
|
const validator = new ConstitutionalValidator(projectRoot);
|
|
484
|
-
|
|
485
|
-
validator
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
485
|
+
|
|
486
|
+
validator
|
|
487
|
+
.validateAll()
|
|
488
|
+
.then(report => {
|
|
489
|
+
const exitCode = report.summary.violations > 0 ? 1 : 0;
|
|
490
|
+
process.exit(exitCode);
|
|
491
|
+
})
|
|
492
|
+
.catch(err => {
|
|
493
|
+
console.error('Validation error:', err);
|
|
494
|
+
process.exit(1);
|
|
495
|
+
});
|
|
492
496
|
}
|
|
493
497
|
|
|
494
498
|
module.exports = { ConstitutionalValidator };
|