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
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Guardrail validation rules DSL
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Provides a declarative DSL for defining guardrail validation rules.
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
6
|
* @module orchestration/guardrails/guardrail-rules
|
|
7
7
|
* @version 3.9.0
|
|
8
8
|
*/
|
|
@@ -30,18 +30,18 @@ const RuleType = {
|
|
|
30
30
|
MAX_LENGTH: 'maxLength',
|
|
31
31
|
MIN_LENGTH: 'minLength',
|
|
32
32
|
PATTERN: 'pattern',
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
// Security rules
|
|
35
35
|
NO_PII: 'noPII',
|
|
36
36
|
NO_PROHIBITED_WORDS: 'noProhibitedWords',
|
|
37
37
|
NO_INJECTION: 'noInjection',
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
// Format rules
|
|
40
40
|
TYPE: 'type',
|
|
41
41
|
ENUM: 'enum',
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
// Custom rules
|
|
44
|
-
CUSTOM: 'custom'
|
|
44
|
+
CUSTOM: 'custom',
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
/**
|
|
@@ -55,11 +55,12 @@ const SecurityPatterns = {
|
|
|
55
55
|
SSN: /\b\d{3}[-\s]?\d{2}[-\s]?\d{4}\b/g,
|
|
56
56
|
CREDIT_CARD: /\b(?:\d{4}[-\s]?){3}\d{4}\b/g,
|
|
57
57
|
IP_ADDRESS: /\b(?:\d{1,3}\.){3}\d{1,3}\b/g,
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
// Injection patterns
|
|
60
|
-
SQL_INJECTION:
|
|
60
|
+
SQL_INJECTION:
|
|
61
|
+
/(\b(SELECT|INSERT|UPDATE|DELETE|DROP|UNION|ALTER)\b.*\b(FROM|INTO|WHERE|TABLE)\b)|(--.*)|(\/\*.*\*\/)/gi,
|
|
61
62
|
XSS: /<script[^>]*>[\s\S]*?<\/script>|javascript:|on\w+\s*=/gi,
|
|
62
|
-
COMMAND_INJECTION: /[;&|`$(){}[\]]/g
|
|
63
|
+
COMMAND_INJECTION: /[;&|`$(){}[\]]/g,
|
|
63
64
|
};
|
|
64
65
|
|
|
65
66
|
/**
|
|
@@ -79,14 +80,14 @@ class RuleBuilder {
|
|
|
79
80
|
this.rules.push({
|
|
80
81
|
id: 'required',
|
|
81
82
|
type: RuleType.REQUIRED,
|
|
82
|
-
check:
|
|
83
|
+
check: value => {
|
|
83
84
|
if (value === null || value === undefined) return false;
|
|
84
85
|
if (typeof value === 'string' && value.trim() === '') return false;
|
|
85
86
|
if (Array.isArray(value) && value.length === 0) return false;
|
|
86
87
|
return true;
|
|
87
88
|
},
|
|
88
89
|
message,
|
|
89
|
-
severity: 'error'
|
|
90
|
+
severity: 'error',
|
|
90
91
|
});
|
|
91
92
|
return this;
|
|
92
93
|
}
|
|
@@ -101,15 +102,15 @@ class RuleBuilder {
|
|
|
101
102
|
this.rules.push({
|
|
102
103
|
id: `maxLength_${max}`,
|
|
103
104
|
type: RuleType.MAX_LENGTH,
|
|
104
|
-
check:
|
|
105
|
+
check: value => {
|
|
105
106
|
if (value === null || value === undefined) return true;
|
|
106
|
-
const len =
|
|
107
|
-
|
|
107
|
+
const len =
|
|
108
|
+
typeof value === 'string' ? value.length : Array.isArray(value) ? value.length : 0;
|
|
108
109
|
return len <= max;
|
|
109
110
|
},
|
|
110
111
|
message: message || `Exceeds maximum length of ${max}`,
|
|
111
112
|
severity: 'error',
|
|
112
|
-
options: { max }
|
|
113
|
+
options: { max },
|
|
113
114
|
});
|
|
114
115
|
return this;
|
|
115
116
|
}
|
|
@@ -124,15 +125,15 @@ class RuleBuilder {
|
|
|
124
125
|
this.rules.push({
|
|
125
126
|
id: `minLength_${min}`,
|
|
126
127
|
type: RuleType.MIN_LENGTH,
|
|
127
|
-
check:
|
|
128
|
+
check: value => {
|
|
128
129
|
if (value === null || value === undefined) return false;
|
|
129
|
-
const len =
|
|
130
|
-
|
|
130
|
+
const len =
|
|
131
|
+
typeof value === 'string' ? value.length : Array.isArray(value) ? value.length : 0;
|
|
131
132
|
return len >= min;
|
|
132
133
|
},
|
|
133
134
|
message: message || `Below minimum length of ${min}`,
|
|
134
135
|
severity: 'error',
|
|
135
|
-
options: { min }
|
|
136
|
+
options: { min },
|
|
136
137
|
});
|
|
137
138
|
return this;
|
|
138
139
|
}
|
|
@@ -147,14 +148,14 @@ class RuleBuilder {
|
|
|
147
148
|
this.rules.push({
|
|
148
149
|
id: `pattern_${pattern.source}`,
|
|
149
150
|
type: RuleType.PATTERN,
|
|
150
|
-
check:
|
|
151
|
+
check: value => {
|
|
151
152
|
if (value === null || value === undefined) return true;
|
|
152
153
|
if (typeof value !== 'string') return false;
|
|
153
154
|
return pattern.test(value);
|
|
154
155
|
},
|
|
155
156
|
message: message || `Does not match required pattern`,
|
|
156
157
|
severity: 'error',
|
|
157
|
-
options: { pattern: pattern.source }
|
|
158
|
+
options: { pattern: pattern.source },
|
|
158
159
|
});
|
|
159
160
|
return this;
|
|
160
161
|
}
|
|
@@ -169,14 +170,14 @@ class RuleBuilder {
|
|
|
169
170
|
this.rules.push({
|
|
170
171
|
id: `noPattern_${pattern.source}`,
|
|
171
172
|
type: RuleType.PATTERN,
|
|
172
|
-
check:
|
|
173
|
+
check: value => {
|
|
173
174
|
if (value === null || value === undefined) return true;
|
|
174
175
|
if (typeof value !== 'string') return true;
|
|
175
176
|
return !pattern.test(value);
|
|
176
177
|
},
|
|
177
178
|
message: message || `Contains prohibited pattern`,
|
|
178
179
|
severity: 'error',
|
|
179
|
-
options: { pattern: pattern.source, inverted: true }
|
|
180
|
+
options: { pattern: pattern.source, inverted: true },
|
|
180
181
|
});
|
|
181
182
|
return this;
|
|
182
183
|
}
|
|
@@ -199,12 +200,12 @@ class RuleBuilder {
|
|
|
199
200
|
this.rules.push({
|
|
200
201
|
id: 'noPII',
|
|
201
202
|
type: RuleType.NO_PII,
|
|
202
|
-
check:
|
|
203
|
+
check: value => {
|
|
203
204
|
if (value === null || value === undefined) return { passed: true };
|
|
204
205
|
if (typeof value !== 'string') return { passed: true };
|
|
205
|
-
|
|
206
|
+
|
|
206
207
|
const detections = [];
|
|
207
|
-
|
|
208
|
+
|
|
208
209
|
if (detectEmail && SecurityPatterns.EMAIL.test(value)) {
|
|
209
210
|
detections.push('email');
|
|
210
211
|
SecurityPatterns.EMAIL.lastIndex = 0;
|
|
@@ -230,12 +231,12 @@ class RuleBuilder {
|
|
|
230
231
|
|
|
231
232
|
return {
|
|
232
233
|
passed: detections.length === 0,
|
|
233
|
-
detections
|
|
234
|
+
detections,
|
|
234
235
|
};
|
|
235
236
|
},
|
|
236
237
|
message: 'Contains personally identifiable information (PII)',
|
|
237
238
|
severity: 'error',
|
|
238
|
-
options
|
|
239
|
+
options,
|
|
239
240
|
});
|
|
240
241
|
return this;
|
|
241
242
|
}
|
|
@@ -249,14 +250,14 @@ class RuleBuilder {
|
|
|
249
250
|
*/
|
|
250
251
|
noProhibitedWords(words, options = {}) {
|
|
251
252
|
const caseSensitive = options.caseSensitive || false;
|
|
252
|
-
|
|
253
|
+
|
|
253
254
|
this.rules.push({
|
|
254
255
|
id: 'noProhibitedWords',
|
|
255
256
|
type: RuleType.NO_PROHIBITED_WORDS,
|
|
256
|
-
check:
|
|
257
|
+
check: value => {
|
|
257
258
|
if (value === null || value === undefined) return { passed: true };
|
|
258
259
|
if (typeof value !== 'string') return { passed: true };
|
|
259
|
-
|
|
260
|
+
|
|
260
261
|
const checkValue = caseSensitive ? value : value.toLowerCase();
|
|
261
262
|
const foundWords = words.filter(word => {
|
|
262
263
|
const checkWord = caseSensitive ? word : word.toLowerCase();
|
|
@@ -265,12 +266,12 @@ class RuleBuilder {
|
|
|
265
266
|
|
|
266
267
|
return {
|
|
267
268
|
passed: foundWords.length === 0,
|
|
268
|
-
foundWords
|
|
269
|
+
foundWords,
|
|
269
270
|
};
|
|
270
271
|
},
|
|
271
272
|
message: 'Contains prohibited content',
|
|
272
273
|
severity: 'error',
|
|
273
|
-
options: { words, caseSensitive }
|
|
274
|
+
options: { words, caseSensitive },
|
|
274
275
|
});
|
|
275
276
|
return this;
|
|
276
277
|
}
|
|
@@ -291,12 +292,12 @@ class RuleBuilder {
|
|
|
291
292
|
this.rules.push({
|
|
292
293
|
id: 'noInjection',
|
|
293
294
|
type: RuleType.NO_INJECTION,
|
|
294
|
-
check:
|
|
295
|
+
check: value => {
|
|
295
296
|
if (value === null || value === undefined) return { passed: true };
|
|
296
297
|
if (typeof value !== 'string') return { passed: true };
|
|
297
|
-
|
|
298
|
+
|
|
298
299
|
const detections = [];
|
|
299
|
-
|
|
300
|
+
|
|
300
301
|
if (checkSql && SecurityPatterns.SQL_INJECTION.test(value)) {
|
|
301
302
|
detections.push('sql');
|
|
302
303
|
SecurityPatterns.SQL_INJECTION.lastIndex = 0;
|
|
@@ -312,12 +313,12 @@ class RuleBuilder {
|
|
|
312
313
|
|
|
313
314
|
return {
|
|
314
315
|
passed: detections.length === 0,
|
|
315
|
-
detections
|
|
316
|
+
detections,
|
|
316
317
|
};
|
|
317
318
|
},
|
|
318
319
|
message: 'Contains potential injection attack',
|
|
319
320
|
severity: 'error',
|
|
320
|
-
options
|
|
321
|
+
options,
|
|
321
322
|
});
|
|
322
323
|
return this;
|
|
323
324
|
}
|
|
@@ -332,9 +333,9 @@ class RuleBuilder {
|
|
|
332
333
|
this.rules.push({
|
|
333
334
|
id: `type_${expectedType}`,
|
|
334
335
|
type: RuleType.TYPE,
|
|
335
|
-
check:
|
|
336
|
+
check: value => {
|
|
336
337
|
if (value === null || value === undefined) return true;
|
|
337
|
-
|
|
338
|
+
|
|
338
339
|
if (expectedType === 'array') {
|
|
339
340
|
return Array.isArray(value);
|
|
340
341
|
}
|
|
@@ -342,7 +343,7 @@ class RuleBuilder {
|
|
|
342
343
|
},
|
|
343
344
|
message: message || `Expected type ${expectedType}`,
|
|
344
345
|
severity: 'error',
|
|
345
|
-
options: { expectedType }
|
|
346
|
+
options: { expectedType },
|
|
346
347
|
});
|
|
347
348
|
return this;
|
|
348
349
|
}
|
|
@@ -357,13 +358,13 @@ class RuleBuilder {
|
|
|
357
358
|
this.rules.push({
|
|
358
359
|
id: 'enum',
|
|
359
360
|
type: RuleType.ENUM,
|
|
360
|
-
check:
|
|
361
|
+
check: value => {
|
|
361
362
|
if (value === null || value === undefined) return true;
|
|
362
363
|
return allowedValues.includes(value);
|
|
363
364
|
},
|
|
364
365
|
message: message || `Must be one of: ${allowedValues.join(', ')}`,
|
|
365
366
|
severity: 'error',
|
|
366
|
-
options: { allowedValues }
|
|
367
|
+
options: { allowedValues },
|
|
367
368
|
});
|
|
368
369
|
return this;
|
|
369
370
|
}
|
|
@@ -382,7 +383,7 @@ class RuleBuilder {
|
|
|
382
383
|
type: RuleType.CUSTOM,
|
|
383
384
|
check: checkFn,
|
|
384
385
|
message,
|
|
385
|
-
severity
|
|
386
|
+
severity,
|
|
386
387
|
});
|
|
387
388
|
return this;
|
|
388
389
|
}
|
|
@@ -480,37 +481,22 @@ const CommonRuleSets = {
|
|
|
480
481
|
/**
|
|
481
482
|
* Basic security rules
|
|
482
483
|
*/
|
|
483
|
-
security: rules()
|
|
484
|
-
.noPII()
|
|
485
|
-
.noInjection()
|
|
486
|
-
.build(),
|
|
484
|
+
security: rules().noPII().noInjection().build(),
|
|
487
485
|
|
|
488
486
|
/**
|
|
489
487
|
* Strict content rules
|
|
490
488
|
*/
|
|
491
|
-
strictContent: rules()
|
|
492
|
-
.required()
|
|
493
|
-
.maxLength(10000)
|
|
494
|
-
.noPII()
|
|
495
|
-
.noInjection()
|
|
496
|
-
.build(),
|
|
489
|
+
strictContent: rules().required().maxLength(10000).noPII().noInjection().build(),
|
|
497
490
|
|
|
498
491
|
/**
|
|
499
492
|
* User input rules
|
|
500
493
|
*/
|
|
501
|
-
userInput: rules()
|
|
502
|
-
.required()
|
|
503
|
-
.maxLength(5000)
|
|
504
|
-
.noInjection()
|
|
505
|
-
.build(),
|
|
494
|
+
userInput: rules().required().maxLength(5000).noInjection().build(),
|
|
506
495
|
|
|
507
496
|
/**
|
|
508
497
|
* Agent output rules
|
|
509
498
|
*/
|
|
510
|
-
agentOutput: rules()
|
|
511
|
-
.required()
|
|
512
|
-
.noPII()
|
|
513
|
-
.build()
|
|
499
|
+
agentOutput: rules().required().noPII().build(),
|
|
514
500
|
};
|
|
515
501
|
|
|
516
502
|
// Global registry instance
|
|
@@ -528,5 +514,5 @@ module.exports = {
|
|
|
528
514
|
RuleRegistry,
|
|
529
515
|
rules,
|
|
530
516
|
CommonRuleSets,
|
|
531
|
-
globalRuleRegistry
|
|
517
|
+
globalRuleRegistry,
|
|
532
518
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Guardrails module exports
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* This module provides guardrail functionality for input/output validation
|
|
5
5
|
* in the MUSUBI orchestration system.
|
|
6
|
-
*
|
|
6
|
+
*
|
|
7
7
|
* @module orchestration/guardrails
|
|
8
8
|
* @version 3.9.0
|
|
9
9
|
*/
|
|
@@ -17,7 +17,7 @@ const {
|
|
|
17
17
|
SafetyCheckGuardrail,
|
|
18
18
|
createSafetyCheckGuardrail,
|
|
19
19
|
SafetyLevel,
|
|
20
|
-
ConstitutionalMapping
|
|
20
|
+
ConstitutionalMapping,
|
|
21
21
|
} = require('./safety-check');
|
|
22
22
|
const {
|
|
23
23
|
RuleType,
|
|
@@ -26,7 +26,7 @@ const {
|
|
|
26
26
|
RuleRegistry,
|
|
27
27
|
rules,
|
|
28
28
|
CommonRuleSets,
|
|
29
|
-
globalRuleRegistry
|
|
29
|
+
globalRuleRegistry,
|
|
30
30
|
} = require('./guardrail-rules');
|
|
31
31
|
|
|
32
32
|
module.exports = {
|
|
@@ -57,5 +57,5 @@ module.exports = {
|
|
|
57
57
|
RuleRegistry,
|
|
58
58
|
rules,
|
|
59
59
|
CommonRuleSets,
|
|
60
|
-
globalRuleRegistry
|
|
60
|
+
globalRuleRegistry,
|
|
61
61
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Input Guardrail for validating agent inputs
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* InputGuardrail validates and sanitizes inputs before they reach agents.
|
|
5
5
|
* Inspired by OpenAI Agents SDK guardrails pattern.
|
|
6
|
-
*
|
|
6
|
+
*
|
|
7
7
|
* @module orchestration/guardrails/input-guardrail
|
|
8
8
|
* @version 3.9.0
|
|
9
9
|
*/
|
|
@@ -51,7 +51,7 @@ class InputGuardrail extends BaseGuardrail {
|
|
|
51
51
|
failFast: config.failFast,
|
|
52
52
|
severity: config.severity,
|
|
53
53
|
tripwireEnabled: config.tripwireEnabled,
|
|
54
|
-
options: config.options
|
|
54
|
+
options: config.options,
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
// Load rules from config, rule set, or default
|
|
@@ -79,9 +79,8 @@ class InputGuardrail extends BaseGuardrail {
|
|
|
79
79
|
* @returns {InputGuardrail} this for chaining
|
|
80
80
|
*/
|
|
81
81
|
addFieldRules(fieldName, rulesOrBuilder) {
|
|
82
|
-
const fieldRules =
|
|
83
|
-
? rulesOrBuilder.build()
|
|
84
|
-
: rulesOrBuilder;
|
|
82
|
+
const fieldRules =
|
|
83
|
+
rulesOrBuilder instanceof RuleBuilder ? rulesOrBuilder.build() : rulesOrBuilder;
|
|
85
84
|
this.fieldRules.set(fieldName, fieldRules);
|
|
86
85
|
return this;
|
|
87
86
|
}
|
|
@@ -106,25 +105,33 @@ class InputGuardrail extends BaseGuardrail {
|
|
|
106
105
|
try {
|
|
107
106
|
const customResult = await this.customValidator(sanitizedInput, context);
|
|
108
107
|
if (customResult === false || (customResult && customResult.passed === false)) {
|
|
109
|
-
violations.push(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
108
|
+
violations.push(
|
|
109
|
+
this.createViolation(
|
|
110
|
+
'CUSTOM_VALIDATION_FAILED',
|
|
111
|
+
customResult.message || 'Custom validation failed',
|
|
112
|
+
'error',
|
|
113
|
+
{ custom: true }
|
|
114
|
+
)
|
|
115
|
+
);
|
|
115
116
|
}
|
|
116
117
|
} catch (error) {
|
|
117
|
-
violations.push(
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
118
|
+
violations.push(
|
|
119
|
+
this.createViolation(
|
|
120
|
+
'CUSTOM_VALIDATOR_ERROR',
|
|
121
|
+
`Custom validator error: ${error.message}`,
|
|
122
|
+
'error',
|
|
123
|
+
{ error: error.message }
|
|
124
|
+
)
|
|
125
|
+
);
|
|
123
126
|
}
|
|
124
127
|
}
|
|
125
128
|
|
|
126
129
|
// Check if input is structured (object) and has field rules
|
|
127
|
-
if (
|
|
130
|
+
if (
|
|
131
|
+
typeof sanitizedInput === 'object' &&
|
|
132
|
+
sanitizedInput !== null &&
|
|
133
|
+
!Array.isArray(sanitizedInput)
|
|
134
|
+
) {
|
|
128
135
|
// Validate each field with field-specific rules
|
|
129
136
|
for (const [fieldName, fieldRules] of this.fieldRules) {
|
|
130
137
|
const fieldValue = sanitizedInput[fieldName];
|
|
@@ -147,12 +154,14 @@ class InputGuardrail extends BaseGuardrail {
|
|
|
147
154
|
return this.createResult(
|
|
148
155
|
passed,
|
|
149
156
|
violations,
|
|
150
|
-
passed
|
|
157
|
+
passed
|
|
158
|
+
? 'Input validation passed'
|
|
159
|
+
: `Input validation failed with ${violations.length} violation(s)`,
|
|
151
160
|
0,
|
|
152
161
|
{
|
|
153
162
|
sanitized: this.sanitize,
|
|
154
163
|
originalInput: input,
|
|
155
|
-
sanitizedInput: this.sanitize ? sanitizedInput : undefined
|
|
164
|
+
sanitizedInput: this.sanitize ? sanitizedInput : undefined,
|
|
156
165
|
}
|
|
157
166
|
);
|
|
158
167
|
}
|
|
@@ -171,7 +180,7 @@ class InputGuardrail extends BaseGuardrail {
|
|
|
171
180
|
for (const rule of rulesToApply) {
|
|
172
181
|
try {
|
|
173
182
|
const result = await Promise.resolve(rule.check(value));
|
|
174
|
-
|
|
183
|
+
|
|
175
184
|
let passed = result;
|
|
176
185
|
let additionalContext = {};
|
|
177
186
|
|
|
@@ -182,24 +191,28 @@ class InputGuardrail extends BaseGuardrail {
|
|
|
182
191
|
}
|
|
183
192
|
|
|
184
193
|
if (!passed) {
|
|
185
|
-
violations.push(
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
194
|
+
violations.push(
|
|
195
|
+
this.createViolation(
|
|
196
|
+
rule.id.toUpperCase(),
|
|
197
|
+
`${fieldName}: ${rule.message}`,
|
|
198
|
+
rule.severity || this.defaultSeverity,
|
|
199
|
+
{ field: fieldName, rule: rule.id, ...additionalContext }
|
|
200
|
+
)
|
|
201
|
+
);
|
|
191
202
|
|
|
192
203
|
if (this.failFast) {
|
|
193
204
|
break;
|
|
194
205
|
}
|
|
195
206
|
}
|
|
196
207
|
} catch (error) {
|
|
197
|
-
violations.push(
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
208
|
+
violations.push(
|
|
209
|
+
this.createViolation(
|
|
210
|
+
'RULE_ERROR',
|
|
211
|
+
`Rule '${rule.id}' execution error: ${error.message}`,
|
|
212
|
+
'error',
|
|
213
|
+
{ field: fieldName, rule: rule.id, error: error.message }
|
|
214
|
+
)
|
|
215
|
+
);
|
|
203
216
|
}
|
|
204
217
|
}
|
|
205
218
|
|
|
@@ -216,18 +229,18 @@ class InputGuardrail extends BaseGuardrail {
|
|
|
216
229
|
if (typeof input === 'string') {
|
|
217
230
|
return input;
|
|
218
231
|
}
|
|
219
|
-
|
|
232
|
+
|
|
220
233
|
if (typeof input === 'object' && input !== null) {
|
|
221
234
|
// For structured input, extract 'message', 'content', or 'text' fields
|
|
222
235
|
if (input.message) return input.message;
|
|
223
236
|
if (input.content) return input.content;
|
|
224
237
|
if (input.text) return input.text;
|
|
225
238
|
if (input.input) return input.input;
|
|
226
|
-
|
|
239
|
+
|
|
227
240
|
// If no known field, stringify the object
|
|
228
241
|
return JSON.stringify(input);
|
|
229
242
|
}
|
|
230
|
-
|
|
243
|
+
|
|
231
244
|
return String(input);
|
|
232
245
|
}
|
|
233
246
|
|
|
@@ -327,7 +340,7 @@ class InputGuardrail extends BaseGuardrail {
|
|
|
327
340
|
rulesCount: this.rules.length,
|
|
328
341
|
fieldRulesCount: this.fieldRules.size,
|
|
329
342
|
sanitize: this.sanitize,
|
|
330
|
-
rules: this.rules.map(r => ({ id: r.id, type: r.type, severity: r.severity }))
|
|
343
|
+
rules: this.rules.map(r => ({ id: r.id, type: r.type, severity: r.severity })),
|
|
331
344
|
};
|
|
332
345
|
}
|
|
333
346
|
}
|
|
@@ -344,14 +357,14 @@ function createInputGuardrail(preset = 'userInput', overrides = {}) {
|
|
|
344
357
|
name: 'SecurityGuardrail',
|
|
345
358
|
description: 'Security-focused input validation',
|
|
346
359
|
ruleSet: 'security',
|
|
347
|
-
tripwireEnabled: true
|
|
360
|
+
tripwireEnabled: true,
|
|
348
361
|
},
|
|
349
362
|
userInput: {
|
|
350
363
|
name: 'UserInputGuardrail',
|
|
351
364
|
description: 'Validates user input',
|
|
352
365
|
ruleSet: 'userInput',
|
|
353
366
|
sanitize: true,
|
|
354
|
-
sanitizeOptions: { trimWhitespace: true }
|
|
367
|
+
sanitizeOptions: { trimWhitespace: true },
|
|
355
368
|
},
|
|
356
369
|
strict: {
|
|
357
370
|
name: 'StrictInputGuardrail',
|
|
@@ -359,20 +372,20 @@ function createInputGuardrail(preset = 'userInput', overrides = {}) {
|
|
|
359
372
|
ruleSet: 'strictContent',
|
|
360
373
|
sanitize: true,
|
|
361
374
|
tripwireEnabled: true,
|
|
362
|
-
failFast: true
|
|
375
|
+
failFast: true,
|
|
363
376
|
},
|
|
364
377
|
minimal: {
|
|
365
378
|
name: 'MinimalInputGuardrail',
|
|
366
379
|
description: 'Minimal validation',
|
|
367
|
-
rules: rules().required().build()
|
|
368
|
-
}
|
|
380
|
+
rules: rules().required().build(),
|
|
381
|
+
},
|
|
369
382
|
};
|
|
370
383
|
|
|
371
|
-
const config = { ...presets[preset] || presets.userInput, ...overrides };
|
|
384
|
+
const config = { ...(presets[preset] || presets.userInput), ...overrides };
|
|
372
385
|
return new InputGuardrail(config);
|
|
373
386
|
}
|
|
374
387
|
|
|
375
388
|
module.exports = {
|
|
376
389
|
InputGuardrail,
|
|
377
|
-
createInputGuardrail
|
|
390
|
+
createInputGuardrail,
|
|
378
391
|
};
|