opencode-telos 1.0.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/README.md +927 -0
- package/dist/code-intelligence/analyzer.d.ts +9 -0
- package/dist/code-intelligence/analyzer.d.ts.map +1 -0
- package/dist/code-intelligence/analyzer.js +321 -0
- package/dist/code-intelligence/analyzer.js.map +1 -0
- package/dist/code-intelligence/ast/cache.d.ts +16 -0
- package/dist/code-intelligence/ast/cache.d.ts.map +1 -0
- package/dist/code-intelligence/ast/cache.js +44 -0
- package/dist/code-intelligence/ast/cache.js.map +1 -0
- package/dist/code-intelligence/ast/common.d.ts +8 -0
- package/dist/code-intelligence/ast/common.d.ts.map +1 -0
- package/dist/code-intelligence/ast/common.js +42 -0
- package/dist/code-intelligence/ast/common.js.map +1 -0
- package/dist/code-intelligence/ast/component.d.ts +10 -0
- package/dist/code-intelligence/ast/component.d.ts.map +1 -0
- package/dist/code-intelligence/ast/component.js +38 -0
- package/dist/code-intelligence/ast/component.js.map +1 -0
- package/dist/code-intelligence/ast/fallback.d.ts +9 -0
- package/dist/code-intelligence/ast/fallback.d.ts.map +1 -0
- package/dist/code-intelligence/ast/fallback.js +38 -0
- package/dist/code-intelligence/ast/fallback.js.map +1 -0
- package/dist/code-intelligence/ast/index.d.ts +5 -0
- package/dist/code-intelligence/ast/index.d.ts.map +1 -0
- package/dist/code-intelligence/ast/index.js +5 -0
- package/dist/code-intelligence/ast/index.js.map +1 -0
- package/dist/code-intelligence/ast/ir.d.ts +72 -0
- package/dist/code-intelligence/ast/ir.d.ts.map +1 -0
- package/dist/code-intelligence/ast/ir.js +2 -0
- package/dist/code-intelligence/ast/ir.js.map +1 -0
- package/dist/code-intelligence/ast/metrics.d.ts +25 -0
- package/dist/code-intelligence/ast/metrics.d.ts.map +1 -0
- package/dist/code-intelligence/ast/metrics.js +38 -0
- package/dist/code-intelligence/ast/metrics.js.map +1 -0
- package/dist/code-intelligence/ast/registry.d.ts +5 -0
- package/dist/code-intelligence/ast/registry.d.ts.map +1 -0
- package/dist/code-intelligence/ast/registry.js +22 -0
- package/dist/code-intelligence/ast/registry.js.map +1 -0
- package/dist/code-intelligence/ast/tree-sitter.d.ts +8 -0
- package/dist/code-intelligence/ast/tree-sitter.d.ts.map +1 -0
- package/dist/code-intelligence/ast/tree-sitter.js +247 -0
- package/dist/code-intelligence/ast/tree-sitter.js.map +1 -0
- package/dist/code-intelligence/ast/typescript.d.ts +8 -0
- package/dist/code-intelligence/ast/typescript.d.ts.map +1 -0
- package/dist/code-intelligence/ast/typescript.js +147 -0
- package/dist/code-intelligence/ast/typescript.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/server.d.ts +27 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +67 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/opencode/hooks.d.ts +9 -0
- package/dist/opencode/hooks.d.ts.map +1 -0
- package/dist/opencode/hooks.js +583 -0
- package/dist/opencode/hooks.js.map +1 -0
- package/dist/opencode/router/categories.d.ts +31 -0
- package/dist/opencode/router/categories.d.ts.map +1 -0
- package/dist/opencode/router/categories.js +165 -0
- package/dist/opencode/router/categories.js.map +1 -0
- package/dist/opencode/router/embeddings.d.ts +41 -0
- package/dist/opencode/router/embeddings.d.ts.map +1 -0
- package/dist/opencode/router/embeddings.js +136 -0
- package/dist/opencode/router/embeddings.js.map +1 -0
- package/dist/opencode/router/graph-state-snapshot.d.ts +35 -0
- package/dist/opencode/router/graph-state-snapshot.d.ts.map +1 -0
- package/dist/opencode/router/graph-state-snapshot.js +129 -0
- package/dist/opencode/router/graph-state-snapshot.js.map +1 -0
- package/dist/opencode/router/index.d.ts +21 -0
- package/dist/opencode/router/index.d.ts.map +1 -0
- package/dist/opencode/router/index.js +23 -0
- package/dist/opencode/router/index.js.map +1 -0
- package/dist/opencode/router/intent-classifier.d.ts +35 -0
- package/dist/opencode/router/intent-classifier.d.ts.map +1 -0
- package/dist/opencode/router/intent-classifier.js +108 -0
- package/dist/opencode/router/intent-classifier.js.map +1 -0
- package/dist/opencode/router/semantic-nudge.d.ts +42 -0
- package/dist/opencode/router/semantic-nudge.d.ts.map +1 -0
- package/dist/opencode/router/semantic-nudge.js +73 -0
- package/dist/opencode/router/semantic-nudge.js.map +1 -0
- package/dist/opencode/router/state-gate.d.ts +25 -0
- package/dist/opencode/router/state-gate.d.ts.map +1 -0
- package/dist/opencode/router/state-gate.js +178 -0
- package/dist/opencode/router/state-gate.js.map +1 -0
- package/dist/opencode/router/tool-embeddings.d.ts +36 -0
- package/dist/opencode/router/tool-embeddings.d.ts.map +1 -0
- package/dist/opencode/router/tool-embeddings.js +140 -0
- package/dist/opencode/router/tool-embeddings.js.map +1 -0
- package/dist/opencode/router/tool-registry.d.ts +45 -0
- package/dist/opencode/router/tool-registry.d.ts.map +1 -0
- package/dist/opencode/router/tool-registry.js +103 -0
- package/dist/opencode/router/tool-registry.js.map +1 -0
- package/dist/opencode/router/tool-taxonomy.d.ts +51 -0
- package/dist/opencode/router/tool-taxonomy.d.ts.map +1 -0
- package/dist/opencode/router/tool-taxonomy.js +250 -0
- package/dist/opencode/router/tool-taxonomy.js.map +1 -0
- package/dist/opencode/router/tools-composite.d.ts +21 -0
- package/dist/opencode/router/tools-composite.d.ts.map +1 -0
- package/dist/opencode/router/tools-composite.js +684 -0
- package/dist/opencode/router/tools-composite.js.map +1 -0
- package/dist/opencode/shell-hooks.d.ts +7 -0
- package/dist/opencode/shell-hooks.d.ts.map +1 -0
- package/dist/opencode/shell-hooks.js +96 -0
- package/dist/opencode/shell-hooks.js.map +1 -0
- package/dist/opencode/system-prompt.d.ts +10 -0
- package/dist/opencode/system-prompt.d.ts.map +1 -0
- package/dist/opencode/system-prompt.js +600 -0
- package/dist/opencode/system-prompt.js.map +1 -0
- package/dist/opencode/tools.d.ts +8 -0
- package/dist/opencode/tools.d.ts.map +1 -0
- package/dist/opencode/tools.js +3731 -0
- package/dist/opencode/tools.js.map +1 -0
- package/dist/opencode/workflows/chains.d.ts +52 -0
- package/dist/opencode/workflows/chains.d.ts.map +1 -0
- package/dist/opencode/workflows/chains.js +170 -0
- package/dist/opencode/workflows/chains.js.map +1 -0
- package/dist/opencode/workflows/executor.d.ts +52 -0
- package/dist/opencode/workflows/executor.d.ts.map +1 -0
- package/dist/opencode/workflows/executor.js +130 -0
- package/dist/opencode/workflows/executor.js.map +1 -0
- package/dist/opencode/workflows/index.d.ts +14 -0
- package/dist/opencode/workflows/index.d.ts.map +1 -0
- package/dist/opencode/workflows/index.js +15 -0
- package/dist/opencode/workflows/index.js.map +1 -0
- package/dist/opencode/workflows/tools-workflow.d.ts +24 -0
- package/dist/opencode/workflows/tools-workflow.d.ts.map +1 -0
- package/dist/opencode/workflows/tools-workflow.js +85 -0
- package/dist/opencode/workflows/tools-workflow.js.map +1 -0
- package/dist/opencode/workflows/types.d.ts +32 -0
- package/dist/opencode/workflows/types.d.ts.map +1 -0
- package/dist/opencode/workflows/types.js +13 -0
- package/dist/opencode/workflows/types.js.map +1 -0
- package/dist/sdd/analysis/compliance.d.ts +30 -0
- package/dist/sdd/analysis/compliance.d.ts.map +1 -0
- package/dist/sdd/analysis/compliance.js +251 -0
- package/dist/sdd/analysis/compliance.js.map +1 -0
- package/dist/sdd/analysis/scalability.d.ts +15 -0
- package/dist/sdd/analysis/scalability.d.ts.map +1 -0
- package/dist/sdd/analysis/scalability.js +72 -0
- package/dist/sdd/analysis/scalability.js.map +1 -0
- package/dist/sdd/analysis/security.d.ts +25 -0
- package/dist/sdd/analysis/security.d.ts.map +1 -0
- package/dist/sdd/analysis/security.js +94 -0
- package/dist/sdd/analysis/security.js.map +1 -0
- package/dist/sdd/brownfield/scanner.d.ts +31 -0
- package/dist/sdd/brownfield/scanner.d.ts.map +1 -0
- package/dist/sdd/brownfield/scanner.js +228 -0
- package/dist/sdd/brownfield/scanner.js.map +1 -0
- package/dist/sdd/cache/manager.d.ts +237 -0
- package/dist/sdd/cache/manager.d.ts.map +1 -0
- package/dist/sdd/cache/manager.js +770 -0
- package/dist/sdd/cache/manager.js.map +1 -0
- package/dist/sdd/cache/snapshot-store.d.ts +39 -0
- package/dist/sdd/cache/snapshot-store.d.ts.map +1 -0
- package/dist/sdd/cache/snapshot-store.js +156 -0
- package/dist/sdd/cache/snapshot-store.js.map +1 -0
- package/dist/sdd/changes/manager.d.ts +58 -0
- package/dist/sdd/changes/manager.d.ts.map +1 -0
- package/dist/sdd/changes/manager.js +235 -0
- package/dist/sdd/changes/manager.js.map +1 -0
- package/dist/sdd/cicd/generators.d.ts +16 -0
- package/dist/sdd/cicd/generators.d.ts.map +1 -0
- package/dist/sdd/cicd/generators.js +1042 -0
- package/dist/sdd/cicd/generators.js.map +1 -0
- package/dist/sdd/code-quality/complexity.d.ts +38 -0
- package/dist/sdd/code-quality/complexity.d.ts.map +1 -0
- package/dist/sdd/code-quality/complexity.js +161 -0
- package/dist/sdd/code-quality/complexity.js.map +1 -0
- package/dist/sdd/code-quality/conventions.d.ts +33 -0
- package/dist/sdd/code-quality/conventions.d.ts.map +1 -0
- package/dist/sdd/code-quality/conventions.js +193 -0
- package/dist/sdd/code-quality/conventions.js.map +1 -0
- package/dist/sdd/code-quality/dependencies.d.ts +27 -0
- package/dist/sdd/code-quality/dependencies.d.ts.map +1 -0
- package/dist/sdd/code-quality/dependencies.js +142 -0
- package/dist/sdd/code-quality/dependencies.js.map +1 -0
- package/dist/sdd/code-quality/import-analyzer.d.ts +49 -0
- package/dist/sdd/code-quality/import-analyzer.d.ts.map +1 -0
- package/dist/sdd/code-quality/import-analyzer.js +213 -0
- package/dist/sdd/code-quality/import-analyzer.js.map +1 -0
- package/dist/sdd/code-quality/metrics.d.ts +35 -0
- package/dist/sdd/code-quality/metrics.d.ts.map +1 -0
- package/dist/sdd/code-quality/metrics.js +172 -0
- package/dist/sdd/code-quality/metrics.js.map +1 -0
- package/dist/sdd/code-quality/smells.d.ts +38 -0
- package/dist/sdd/code-quality/smells.d.ts.map +1 -0
- package/dist/sdd/code-quality/smells.js +319 -0
- package/dist/sdd/code-quality/smells.js.map +1 -0
- package/dist/sdd/code-quality/symbol-parser.d.ts +28 -0
- package/dist/sdd/code-quality/symbol-parser.d.ts.map +1 -0
- package/dist/sdd/code-quality/symbol-parser.js +230 -0
- package/dist/sdd/code-quality/symbol-parser.js.map +1 -0
- package/dist/sdd/code-quality/usage-tracker.d.ts +59 -0
- package/dist/sdd/code-quality/usage-tracker.d.ts.map +1 -0
- package/dist/sdd/code-quality/usage-tracker.js +402 -0
- package/dist/sdd/code-quality/usage-tracker.js.map +1 -0
- package/dist/sdd/code-quality/utils.d.ts +6 -0
- package/dist/sdd/code-quality/utils.d.ts.map +1 -0
- package/dist/sdd/code-quality/utils.js +14 -0
- package/dist/sdd/code-quality/utils.js.map +1 -0
- package/dist/sdd/codegen/generator.d.ts +42 -0
- package/dist/sdd/codegen/generator.d.ts.map +1 -0
- package/dist/sdd/codegen/generator.js +1023 -0
- package/dist/sdd/codegen/generator.js.map +1 -0
- package/dist/sdd/constitution/validator.d.ts +37 -0
- package/dist/sdd/constitution/validator.d.ts.map +1 -0
- package/dist/sdd/constitution/validator.js +192 -0
- package/dist/sdd/constitution/validator.js.map +1 -0
- package/dist/sdd/cost/estimator.d.ts +31 -0
- package/dist/sdd/cost/estimator.d.ts.map +1 -0
- package/dist/sdd/cost/estimator.js +92 -0
- package/dist/sdd/cost/estimator.js.map +1 -0
- package/dist/sdd/coverage/tracker.d.ts +47 -0
- package/dist/sdd/coverage/tracker.d.ts.map +1 -0
- package/dist/sdd/coverage/tracker.js +251 -0
- package/dist/sdd/coverage/tracker.js.map +1 -0
- package/dist/sdd/disaster/recovery.d.ts +11 -0
- package/dist/sdd/disaster/recovery.d.ts.map +1 -0
- package/dist/sdd/disaster/recovery.js +55 -0
- package/dist/sdd/disaster/recovery.js.map +1 -0
- package/dist/sdd/discovery/adaptive.d.ts +14 -0
- package/dist/sdd/discovery/adaptive.d.ts.map +1 -0
- package/dist/sdd/discovery/adaptive.js +145 -0
- package/dist/sdd/discovery/adaptive.js.map +1 -0
- package/dist/sdd/discovery/briefing-analyzer.d.ts +66 -0
- package/dist/sdd/discovery/briefing-analyzer.d.ts.map +1 -0
- package/dist/sdd/discovery/briefing-analyzer.js +672 -0
- package/dist/sdd/discovery/briefing-analyzer.js.map +1 -0
- package/dist/sdd/discovery/briefing.d.ts +109 -0
- package/dist/sdd/discovery/briefing.d.ts.map +1 -0
- package/dist/sdd/discovery/briefing.js +617 -0
- package/dist/sdd/discovery/briefing.js.map +1 -0
- package/dist/sdd/discovery/graph-builder.d.ts +10 -0
- package/dist/sdd/discovery/graph-builder.d.ts.map +1 -0
- package/dist/sdd/discovery/graph-builder.js +510 -0
- package/dist/sdd/discovery/graph-builder.js.map +1 -0
- package/dist/sdd/documentation/generator.d.ts +7 -0
- package/dist/sdd/documentation/generator.d.ts.map +1 -0
- package/dist/sdd/documentation/generator.js +119 -0
- package/dist/sdd/documentation/generator.js.map +1 -0
- package/dist/sdd/domain/types.d.ts +460 -0
- package/dist/sdd/domain/types.d.ts.map +1 -0
- package/dist/sdd/domain/types.js +25 -0
- package/dist/sdd/domain/types.js.map +1 -0
- package/dist/sdd/drift/detector.d.ts +28 -0
- package/dist/sdd/drift/detector.d.ts.map +1 -0
- package/dist/sdd/drift/detector.js +379 -0
- package/dist/sdd/drift/detector.js.map +1 -0
- package/dist/sdd/drift/exclusion.d.ts +54 -0
- package/dist/sdd/drift/exclusion.d.ts.map +1 -0
- package/dist/sdd/drift/exclusion.js +179 -0
- package/dist/sdd/drift/exclusion.js.map +1 -0
- package/dist/sdd/drift/signals.d.ts +52 -0
- package/dist/sdd/drift/signals.d.ts.map +1 -0
- package/dist/sdd/drift/signals.js +470 -0
- package/dist/sdd/drift/signals.js.map +1 -0
- package/dist/sdd/enforcement/interceptor.d.ts +47 -0
- package/dist/sdd/enforcement/interceptor.d.ts.map +1 -0
- package/dist/sdd/enforcement/interceptor.js +365 -0
- package/dist/sdd/enforcement/interceptor.js.map +1 -0
- package/dist/sdd/enforcement/workflow-tracker.d.ts +66 -0
- package/dist/sdd/enforcement/workflow-tracker.d.ts.map +1 -0
- package/dist/sdd/enforcement/workflow-tracker.js +229 -0
- package/dist/sdd/enforcement/workflow-tracker.js.map +1 -0
- package/dist/sdd/graph/engine.d.ts +44 -0
- package/dist/sdd/graph/engine.d.ts.map +1 -0
- package/dist/sdd/graph/engine.js +203 -0
- package/dist/sdd/graph/engine.js.map +1 -0
- package/dist/sdd/graph/index.d.ts +160 -0
- package/dist/sdd/graph/index.d.ts.map +1 -0
- package/dist/sdd/graph/index.js +624 -0
- package/dist/sdd/graph/index.js.map +1 -0
- package/dist/sdd/graph/integrity-guard.d.ts +129 -0
- package/dist/sdd/graph/integrity-guard.d.ts.map +1 -0
- package/dist/sdd/graph/integrity-guard.js +263 -0
- package/dist/sdd/graph/integrity-guard.js.map +1 -0
- package/dist/sdd/graph/integrity.d.ts +79 -0
- package/dist/sdd/graph/integrity.d.ts.map +1 -0
- package/dist/sdd/graph/integrity.js +462 -0
- package/dist/sdd/graph/integrity.js.map +1 -0
- package/dist/sdd/graph/pruner.d.ts +27 -0
- package/dist/sdd/graph/pruner.d.ts.map +1 -0
- package/dist/sdd/graph/pruner.js +203 -0
- package/dist/sdd/graph/pruner.js.map +1 -0
- package/dist/sdd/graph/traverse.d.ts +43 -0
- package/dist/sdd/graph/traverse.d.ts.map +1 -0
- package/dist/sdd/graph/traverse.js +265 -0
- package/dist/sdd/graph/traverse.js.map +1 -0
- package/dist/sdd/incidents/manager.d.ts +10 -0
- package/dist/sdd/incidents/manager.d.ts.map +1 -0
- package/dist/sdd/incidents/manager.js +63 -0
- package/dist/sdd/incidents/manager.js.map +1 -0
- package/dist/sdd/knowledge/transfer.d.ts +24 -0
- package/dist/sdd/knowledge/transfer.d.ts.map +1 -0
- package/dist/sdd/knowledge/transfer.js +94 -0
- package/dist/sdd/knowledge/transfer.js.map +1 -0
- package/dist/sdd/migrations/fixes.d.ts +2 -0
- package/dist/sdd/migrations/fixes.d.ts.map +1 -0
- package/dist/sdd/migrations/fixes.js +159 -0
- package/dist/sdd/migrations/fixes.js.map +1 -0
- package/dist/sdd/migrations/index.d.ts +2 -0
- package/dist/sdd/migrations/index.d.ts.map +1 -0
- package/dist/sdd/migrations/index.js +5 -0
- package/dist/sdd/migrations/index.js.map +1 -0
- package/dist/sdd/migrations/migration-runner.d.ts +41 -0
- package/dist/sdd/migrations/migration-runner.d.ts.map +1 -0
- package/dist/sdd/migrations/migration-runner.js +91 -0
- package/dist/sdd/migrations/migration-runner.js.map +1 -0
- package/dist/sdd/monitoring/setup.d.ts +40 -0
- package/dist/sdd/monitoring/setup.d.ts.map +1 -0
- package/dist/sdd/monitoring/setup.js +177 -0
- package/dist/sdd/monitoring/setup.js.map +1 -0
- package/dist/sdd/monitoring/telemetry.d.ts +18 -0
- package/dist/sdd/monitoring/telemetry.d.ts.map +1 -0
- package/dist/sdd/monitoring/telemetry.js +37 -0
- package/dist/sdd/monitoring/telemetry.js.map +1 -0
- package/dist/sdd/patterns/anti-patterns.d.ts +21 -0
- package/dist/sdd/patterns/anti-patterns.d.ts.map +1 -0
- package/dist/sdd/patterns/anti-patterns.js +286 -0
- package/dist/sdd/patterns/anti-patterns.js.map +1 -0
- package/dist/sdd/patterns/ast-clones.d.ts +23 -0
- package/dist/sdd/patterns/ast-clones.d.ts.map +1 -0
- package/dist/sdd/patterns/ast-clones.js +171 -0
- package/dist/sdd/patterns/ast-clones.js.map +1 -0
- package/dist/sdd/patterns/config-drift.d.ts +16 -0
- package/dist/sdd/patterns/config-drift.d.ts.map +1 -0
- package/dist/sdd/patterns/config-drift.js +322 -0
- package/dist/sdd/patterns/config-drift.js.map +1 -0
- package/dist/sdd/patterns/contradictions.d.ts +38 -0
- package/dist/sdd/patterns/contradictions.d.ts.map +1 -0
- package/dist/sdd/patterns/contradictions.js +237 -0
- package/dist/sdd/patterns/contradictions.js.map +1 -0
- package/dist/sdd/patterns/learner.d.ts +49 -0
- package/dist/sdd/patterns/learner.d.ts.map +1 -0
- package/dist/sdd/patterns/learner.js +226 -0
- package/dist/sdd/patterns/learner.js.map +1 -0
- package/dist/sdd/permissions/access.d.ts +69 -0
- package/dist/sdd/permissions/access.d.ts.map +1 -0
- package/dist/sdd/permissions/access.js +333 -0
- package/dist/sdd/permissions/access.js.map +1 -0
- package/dist/sdd/persistence/repository.d.ts +60 -0
- package/dist/sdd/persistence/repository.d.ts.map +1 -0
- package/dist/sdd/persistence/repository.js +96 -0
- package/dist/sdd/persistence/repository.js.map +1 -0
- package/dist/sdd/persistence/sqlite.d.ts +122 -0
- package/dist/sdd/persistence/sqlite.d.ts.map +1 -0
- package/dist/sdd/persistence/sqlite.js +602 -0
- package/dist/sdd/persistence/sqlite.js.map +1 -0
- package/dist/sdd/persistence/yaml.d.ts +41 -0
- package/dist/sdd/persistence/yaml.d.ts.map +1 -0
- package/dist/sdd/persistence/yaml.js +382 -0
- package/dist/sdd/persistence/yaml.js.map +1 -0
- package/dist/sdd/promises/classifier.d.ts +48 -0
- package/dist/sdd/promises/classifier.d.ts.map +1 -0
- package/dist/sdd/promises/classifier.js +215 -0
- package/dist/sdd/promises/classifier.js.map +1 -0
- package/dist/sdd/promises/tracker.d.ts +20 -0
- package/dist/sdd/promises/tracker.d.ts.map +1 -0
- package/dist/sdd/promises/tracker.js +204 -0
- package/dist/sdd/promises/tracker.js.map +1 -0
- package/dist/sdd/quality/scorer.d.ts +44 -0
- package/dist/sdd/quality/scorer.d.ts.map +1 -0
- package/dist/sdd/quality/scorer.js +216 -0
- package/dist/sdd/quality/scorer.js.map +1 -0
- package/dist/sdd/rollback/manager.d.ts +45 -0
- package/dist/sdd/rollback/manager.d.ts.map +1 -0
- package/dist/sdd/rollback/manager.js +266 -0
- package/dist/sdd/rollback/manager.js.map +1 -0
- package/dist/sdd/session/handoff.d.ts +52 -0
- package/dist/sdd/session/handoff.d.ts.map +1 -0
- package/dist/sdd/session/handoff.js +264 -0
- package/dist/sdd/session/handoff.js.map +1 -0
- package/dist/sdd/sla/tracker.d.ts +11 -0
- package/dist/sdd/sla/tracker.d.ts.map +1 -0
- package/dist/sdd/sla/tracker.js +52 -0
- package/dist/sdd/sla/tracker.js.map +1 -0
- package/dist/sdd/sync/git-sync.d.ts +61 -0
- package/dist/sdd/sync/git-sync.d.ts.map +1 -0
- package/dist/sdd/sync/git-sync.js +297 -0
- package/dist/sdd/sync/git-sync.js.map +1 -0
- package/dist/sdd/toggle/state.d.ts +8 -0
- package/dist/sdd/toggle/state.d.ts.map +1 -0
- package/dist/sdd/toggle/state.js +32 -0
- package/dist/sdd/toggle/state.js.map +1 -0
- package/dist/sdd/transactions/manager.d.ts +12 -0
- package/dist/sdd/transactions/manager.d.ts.map +1 -0
- package/dist/sdd/transactions/manager.js +80 -0
- package/dist/sdd/transactions/manager.js.map +1 -0
- package/dist/sdd/validation/coverage-index.d.ts +117 -0
- package/dist/sdd/validation/coverage-index.d.ts.map +1 -0
- package/dist/sdd/validation/coverage-index.js +251 -0
- package/dist/sdd/validation/coverage-index.js.map +1 -0
- package/dist/sdd/validation/executable.d.ts +26 -0
- package/dist/sdd/validation/executable.d.ts.map +1 -0
- package/dist/sdd/validation/executable.js +122 -0
- package/dist/sdd/validation/executable.js.map +1 -0
- package/dist/sdd/validation/smart-validator.d.ts +53 -0
- package/dist/sdd/validation/smart-validator.d.ts.map +1 -0
- package/dist/sdd/validation/smart-validator.js +347 -0
- package/dist/sdd/validation/smart-validator.js.map +1 -0
- package/dist/sdd/validation/validator.d.ts +39 -0
- package/dist/sdd/validation/validator.d.ts.map +1 -0
- package/dist/sdd/validation/validator.js +512 -0
- package/dist/sdd/validation/validator.js.map +1 -0
- package/dist/sdd/workflow/exporter.d.ts +36 -0
- package/dist/sdd/workflow/exporter.d.ts.map +1 -0
- package/dist/sdd/workflow/exporter.js +112 -0
- package/dist/sdd/workflow/exporter.js.map +1 -0
- package/dist/sdd/workflows/ab-testing.d.ts +18 -0
- package/dist/sdd/workflows/ab-testing.d.ts.map +1 -0
- package/dist/sdd/workflows/ab-testing.js +67 -0
- package/dist/sdd/workflows/ab-testing.js.map +1 -0
- package/dist/sdd/workflows/bug-fix.d.ts +13 -0
- package/dist/sdd/workflows/bug-fix.d.ts.map +1 -0
- package/dist/sdd/workflows/bug-fix.js +65 -0
- package/dist/sdd/workflows/bug-fix.js.map +1 -0
- package/dist/sdd/workflows/data-migration.d.ts +14 -0
- package/dist/sdd/workflows/data-migration.d.ts.map +1 -0
- package/dist/sdd/workflows/data-migration.js +68 -0
- package/dist/sdd/workflows/data-migration.js.map +1 -0
- package/dist/sdd/workflows/deprecation.d.ts +15 -0
- package/dist/sdd/workflows/deprecation.d.ts.map +1 -0
- package/dist/sdd/workflows/deprecation.js +68 -0
- package/dist/sdd/workflows/deprecation.js.map +1 -0
- package/dist/sdd/workflows/feature-flags.d.ts +14 -0
- package/dist/sdd/workflows/feature-flags.d.ts.map +1 -0
- package/dist/sdd/workflows/feature-flags.js +73 -0
- package/dist/sdd/workflows/feature-flags.js.map +1 -0
- package/dist/sdd/workflows/hotfix.d.ts +13 -0
- package/dist/sdd/workflows/hotfix.d.ts.map +1 -0
- package/dist/sdd/workflows/hotfix.js +67 -0
- package/dist/sdd/workflows/hotfix.js.map +1 -0
- package/dist/sdd/workflows/multi-tenancy.d.ts +13 -0
- package/dist/sdd/workflows/multi-tenancy.d.ts.map +1 -0
- package/dist/sdd/workflows/multi-tenancy.js +68 -0
- package/dist/sdd/workflows/multi-tenancy.js.map +1 -0
- package/dist/sdd/workflows/onboarding.d.ts +7 -0
- package/dist/sdd/workflows/onboarding.d.ts.map +1 -0
- package/dist/sdd/workflows/onboarding.js +43 -0
- package/dist/sdd/workflows/onboarding.js.map +1 -0
- package/dist/sdd/workflows/refactoring.d.ts +14 -0
- package/dist/sdd/workflows/refactoring.d.ts.map +1 -0
- package/dist/sdd/workflows/refactoring.js +73 -0
- package/dist/sdd/workflows/refactoring.js.map +1 -0
- package/dist/server/events.d.ts +64 -0
- package/dist/server/events.d.ts.map +1 -0
- package/dist/server/events.js +149 -0
- package/dist/server/events.js.map +1 -0
- package/dist/server/server.d.ts +33 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +1019 -0
- package/dist/server/server.js.map +1 -0
- package/marketplace.json +39 -0
- package/package.json +65 -0
- package/src/code-intelligence/analyzer.ts +350 -0
- package/src/code-intelligence/ast/cache.ts +61 -0
- package/src/code-intelligence/ast/common.ts +62 -0
- package/src/code-intelligence/ast/component.ts +39 -0
- package/src/code-intelligence/ast/fallback.ts +44 -0
- package/src/code-intelligence/ast/index.ts +4 -0
- package/src/code-intelligence/ast/ir.ts +91 -0
- package/src/code-intelligence/ast/metrics.ts +65 -0
- package/src/code-intelligence/ast/registry.ts +28 -0
- package/src/code-intelligence/ast/tree-sitter.ts +226 -0
- package/src/code-intelligence/ast/typescript.ts +140 -0
- package/src/index.ts +22 -0
- package/src/mcp/server.ts +77 -0
- package/src/opencode/hooks.ts +728 -0
- package/src/opencode/router/categories.ts +192 -0
- package/src/opencode/router/embeddings.ts +149 -0
- package/src/opencode/router/graph-state-snapshot.ts +163 -0
- package/src/opencode/router/index.ts +44 -0
- package/src/opencode/router/intent-classifier.ts +140 -0
- package/src/opencode/router/semantic-nudge.ts +89 -0
- package/src/opencode/router/state-gate.ts +192 -0
- package/src/opencode/router/tool-embeddings.ts +162 -0
- package/src/opencode/router/tool-registry.ts +135 -0
- package/src/opencode/router/tool-taxonomy.ts +284 -0
- package/src/opencode/router/tools-composite.ts +685 -0
- package/src/opencode/shell-hooks.ts +115 -0
- package/src/opencode/system-prompt.ts +617 -0
- package/src/opencode/tools.ts +4102 -0
- package/src/opencode/workflows/chains.ts +205 -0
- package/src/opencode/workflows/executor.ts +172 -0
- package/src/opencode/workflows/index.ts +21 -0
- package/src/opencode/workflows/tools-workflow.ts +91 -0
- package/src/opencode/workflows/types.ts +42 -0
- package/src/sdd/analysis/compliance.ts +279 -0
- package/src/sdd/analysis/scalability.ts +97 -0
- package/src/sdd/analysis/security.ts +135 -0
- package/src/sdd/brownfield/scanner.ts +276 -0
- package/src/sdd/cache/manager.ts +899 -0
- package/src/sdd/cache/snapshot-store.ts +185 -0
- package/src/sdd/changes/manager.ts +326 -0
- package/src/sdd/cicd/generators.ts +1095 -0
- package/src/sdd/code-quality/complexity.ts +235 -0
- package/src/sdd/code-quality/conventions.ts +220 -0
- package/src/sdd/code-quality/dependencies.ts +203 -0
- package/src/sdd/code-quality/import-analyzer.ts +294 -0
- package/src/sdd/code-quality/metrics.ts +232 -0
- package/src/sdd/code-quality/smells.ts +415 -0
- package/src/sdd/code-quality/symbol-parser.ts +335 -0
- package/src/sdd/code-quality/usage-tracker.ts +527 -0
- package/src/sdd/code-quality/utils.ts +13 -0
- package/src/sdd/codegen/generator.ts +1181 -0
- package/src/sdd/constitution/validator.ts +253 -0
- package/src/sdd/cost/estimator.ts +147 -0
- package/src/sdd/coverage/tracker.ts +342 -0
- package/src/sdd/disaster/recovery.ts +79 -0
- package/src/sdd/discovery/adaptive.ts +167 -0
- package/src/sdd/discovery/briefing-analyzer.ts +802 -0
- package/src/sdd/discovery/briefing.ts +770 -0
- package/src/sdd/discovery/graph-builder.ts +598 -0
- package/src/sdd/documentation/generator.ts +158 -0
- package/src/sdd/domain/types.ts +658 -0
- package/src/sdd/drift/detector.ts +465 -0
- package/src/sdd/drift/exclusion.ts +223 -0
- package/src/sdd/drift/signals.ts +577 -0
- package/src/sdd/enforcement/interceptor.ts +444 -0
- package/src/sdd/enforcement/workflow-tracker.ts +263 -0
- package/src/sdd/graph/engine.ts +277 -0
- package/src/sdd/graph/index.ts +700 -0
- package/src/sdd/graph/integrity-guard.ts +348 -0
- package/src/sdd/graph/integrity.ts +628 -0
- package/src/sdd/graph/pruner.ts +221 -0
- package/src/sdd/graph/traverse.ts +331 -0
- package/src/sdd/incidents/manager.ts +87 -0
- package/src/sdd/knowledge/transfer.ts +140 -0
- package/src/sdd/migrations/fixes.ts +154 -0
- package/src/sdd/migrations/index.ts +14 -0
- package/src/sdd/migrations/migration-runner.ts +118 -0
- package/src/sdd/monitoring/setup.ts +237 -0
- package/src/sdd/monitoring/telemetry.ts +44 -0
- package/src/sdd/patterns/anti-patterns.ts +333 -0
- package/src/sdd/patterns/ast-clones.ts +214 -0
- package/src/sdd/patterns/config-drift.ts +346 -0
- package/src/sdd/patterns/contradictions.ts +323 -0
- package/src/sdd/patterns/learner.ts +266 -0
- package/src/sdd/permissions/access.ts +478 -0
- package/src/sdd/persistence/repository.ts +166 -0
- package/src/sdd/persistence/sqlite.ts +703 -0
- package/src/sdd/persistence/yaml.ts +409 -0
- package/src/sdd/promises/classifier.ts +253 -0
- package/src/sdd/promises/tracker.ts +258 -0
- package/src/sdd/quality/scorer.ts +263 -0
- package/src/sdd/rollback/manager.ts +361 -0
- package/src/sdd/session/handoff.ts +354 -0
- package/src/sdd/sla/tracker.ts +68 -0
- package/src/sdd/sync/git-sync.ts +401 -0
- package/src/sdd/toggle/state.ts +38 -0
- package/src/sdd/transactions/manager.ts +93 -0
- package/src/sdd/validation/coverage-index.ts +339 -0
- package/src/sdd/validation/executable.ts +127 -0
- package/src/sdd/validation/smart-validator.ts +470 -0
- package/src/sdd/validation/validator.ts +641 -0
- package/src/sdd/workflow/exporter.ts +169 -0
- package/src/sdd/workflows/ab-testing.ts +90 -0
- package/src/sdd/workflows/bug-fix.ts +81 -0
- package/src/sdd/workflows/data-migration.ts +86 -0
- package/src/sdd/workflows/deprecation.ts +87 -0
- package/src/sdd/workflows/feature-flags.ts +91 -0
- package/src/sdd/workflows/hotfix.ts +83 -0
- package/src/sdd/workflows/multi-tenancy.ts +84 -0
- package/src/sdd/workflows/onboarding.ts +82 -0
- package/src/sdd/workflows/refactoring.ts +90 -0
- package/src/server/events.ts +184 -0
- package/src/server/server.ts +1088 -0
|
@@ -0,0 +1,641 @@
|
|
|
1
|
+
import type { KnowledgeGraph } from "../domain/types.js"
|
|
2
|
+
import { validateAgainstConstitution } from "../constitution/validator.js"
|
|
3
|
+
import { getPromiseReport } from "../promises/tracker.js"
|
|
4
|
+
import { detectContradictions } from "../patterns/contradictions.js"
|
|
5
|
+
import { getExclusionSets, isNodeExcludedOrDeprecated } from "../drift/exclusion.js"
|
|
6
|
+
import { ensureGraphIntegrity, formatIntegrityReport } from "../graph/integrity.js"
|
|
7
|
+
import type { IntegrityReport } from "../graph/integrity.js"
|
|
8
|
+
import { isGraphTampered } from "../graph/integrity-guard.js"
|
|
9
|
+
|
|
10
|
+
export interface ValidationResult {
|
|
11
|
+
valid: boolean
|
|
12
|
+
errors: ValidationError[]
|
|
13
|
+
warnings: ValidationWarning[]
|
|
14
|
+
integrity?: IntegrityReport
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ValidationError {
|
|
18
|
+
code: string
|
|
19
|
+
message: string
|
|
20
|
+
node_id?: string
|
|
21
|
+
relationship_id?: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ValidationWarning {
|
|
25
|
+
code: string
|
|
26
|
+
message: string
|
|
27
|
+
node_id?: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface ValidationPolicy {
|
|
31
|
+
critical_requirement_without_test: "error" | "warning"
|
|
32
|
+
missing_verification_scenario: "error" | "warning"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const DEFAULT_VALIDATION_POLICY: ValidationPolicy = {
|
|
36
|
+
critical_requirement_without_test: "error",
|
|
37
|
+
missing_verification_scenario: "warning",
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ── Validation cache for incremental analysis ────────────────────────
|
|
41
|
+
// Thread-safe: each module instance gets its own cache via closure.
|
|
42
|
+
// In worker environments, each worker has a separate module scope.
|
|
43
|
+
|
|
44
|
+
interface ValidationCache {
|
|
45
|
+
result: ValidationResult
|
|
46
|
+
graphVersion: string
|
|
47
|
+
nodeCount: number
|
|
48
|
+
version: number
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function createValidationCache() {
|
|
52
|
+
let cache: ValidationCache | null = null
|
|
53
|
+
let version = 0
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
get(graphVersion: string): ValidationCache | null {
|
|
57
|
+
if (cache && cache.graphVersion === graphVersion) return cache
|
|
58
|
+
return null
|
|
59
|
+
},
|
|
60
|
+
set(result: ValidationResult, graphVersion: string, nodeCount: number): void {
|
|
61
|
+
version++
|
|
62
|
+
cache = { result, graphVersion, nodeCount, version }
|
|
63
|
+
},
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const validationCache = createValidationCache()
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Full graph validation. Checks structural integrity, semantic correctness,
|
|
71
|
+
* references, completeness, constitution, promises, contradictions, and graph integrity.
|
|
72
|
+
*/
|
|
73
|
+
export function validateGraph(
|
|
74
|
+
graph: KnowledgeGraph,
|
|
75
|
+
policy: ValidationPolicy = DEFAULT_VALIDATION_POLICY,
|
|
76
|
+
): ValidationResult {
|
|
77
|
+
const errors: ValidationError[] = []
|
|
78
|
+
const warnings: ValidationWarning[] = []
|
|
79
|
+
|
|
80
|
+
// Anti-bypass: check for out-of-band modifications
|
|
81
|
+
// We need projectDir to check integrity — extract from graph context
|
|
82
|
+
try {
|
|
83
|
+
// If graph metadata contains a tamper warning, surface it as an error
|
|
84
|
+
const tamperWarning = (graph.metadata as any).__tamper_warning
|
|
85
|
+
if (tamperWarning) {
|
|
86
|
+
errors.push({
|
|
87
|
+
code: "GRAPH_TAMPERED",
|
|
88
|
+
message: tamperWarning,
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
} catch {}
|
|
92
|
+
|
|
93
|
+
validateStructural(graph, errors, warnings)
|
|
94
|
+
validateSemantic(graph, errors, warnings, policy)
|
|
95
|
+
validateReferences(graph, errors, warnings)
|
|
96
|
+
validateCompleteness(graph, errors, warnings)
|
|
97
|
+
|
|
98
|
+
const constitutionResult = validateAgainstConstitution(graph)
|
|
99
|
+
for (const v of constitutionResult.violations) {
|
|
100
|
+
errors.push({
|
|
101
|
+
code: "CONSTITUTION_VIOLATION",
|
|
102
|
+
message: v.description,
|
|
103
|
+
node_id: v.node_id,
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const promiseReport = getPromiseReport(graph)
|
|
108
|
+
if (promiseReport.violated > 0) {
|
|
109
|
+
warnings.push({
|
|
110
|
+
code: "PROMISES_VIOLATED",
|
|
111
|
+
message: `${promiseReport.violated} specification promises violated`,
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const contradictionReport = detectContradictions(graph)
|
|
116
|
+
for (const c of contradictionReport.contradictions) {
|
|
117
|
+
warnings.push({
|
|
118
|
+
code: "CONTRADICTION",
|
|
119
|
+
message: c.description,
|
|
120
|
+
node_id: c.node_a,
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Run graph integrity check (detects orphans, disconnected groups, redundancies)
|
|
125
|
+
const integrity = ensureGraphIntegrity(graph, { auto_fix: false })
|
|
126
|
+
if (!integrity.summary.graph_connected) {
|
|
127
|
+
warnings.push({
|
|
128
|
+
code: "DISCONNECTED_GRAPH",
|
|
129
|
+
message: `Graph has ${integrity.summary.disconnected_groups_found} disconnected group(s) with ${integrity.summary.orphans_found} orphan node(s)`,
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
if (integrity.summary.redundant_relationships_found > 0) {
|
|
133
|
+
warnings.push({
|
|
134
|
+
code: "REDUNDANT_RELATIONSHIPS",
|
|
135
|
+
message: `${integrity.summary.redundant_relationships_found} redundant relationship(s) detected`,
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const result = {
|
|
140
|
+
valid: errors.length === 0,
|
|
141
|
+
errors,
|
|
142
|
+
warnings,
|
|
143
|
+
integrity,
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Cache for incremental comparison
|
|
147
|
+
validationCache.set(result, graph.metadata.updated_at, graph.nodes.length)
|
|
148
|
+
|
|
149
|
+
return result
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ── Non-incremental validators (used by full validation) ─────────────
|
|
153
|
+
|
|
154
|
+
function validateStructural(
|
|
155
|
+
graph: KnowledgeGraph,
|
|
156
|
+
errors: ValidationError[],
|
|
157
|
+
warnings: ValidationWarning[],
|
|
158
|
+
): void {
|
|
159
|
+
const ids = new Set<string>()
|
|
160
|
+
|
|
161
|
+
for (const rawNode of graph.nodes) {
|
|
162
|
+
const node = rawNode as { id?: string; type?: string; name?: string; status?: string }
|
|
163
|
+
if (!node.id) {
|
|
164
|
+
errors.push({ code: "MISSING_ID", message: "Node missing ID" })
|
|
165
|
+
continue
|
|
166
|
+
}
|
|
167
|
+
if (ids.has(node.id)) {
|
|
168
|
+
errors.push({
|
|
169
|
+
code: "DUPLICATE_ID",
|
|
170
|
+
message: `Duplicate node ID: ${node.id}`,
|
|
171
|
+
node_id: node.id,
|
|
172
|
+
})
|
|
173
|
+
}
|
|
174
|
+
ids.add(node.id)
|
|
175
|
+
|
|
176
|
+
if (!node.type) {
|
|
177
|
+
errors.push({
|
|
178
|
+
code: "MISSING_TYPE",
|
|
179
|
+
message: `Node ${node.id} missing type`,
|
|
180
|
+
node_id: node.id,
|
|
181
|
+
})
|
|
182
|
+
}
|
|
183
|
+
if (!node.name) {
|
|
184
|
+
warnings.push({
|
|
185
|
+
code: "MISSING_NAME",
|
|
186
|
+
message: `Node ${node.id} missing name`,
|
|
187
|
+
node_id: node.id,
|
|
188
|
+
})
|
|
189
|
+
}
|
|
190
|
+
if (!node.status) {
|
|
191
|
+
warnings.push({
|
|
192
|
+
code: "MISSING_STATUS",
|
|
193
|
+
message: `Node ${node.id} missing status`,
|
|
194
|
+
node_id: node.id,
|
|
195
|
+
})
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
for (const rel of graph.relationships) {
|
|
200
|
+
if (!rel.from) {
|
|
201
|
+
errors.push({
|
|
202
|
+
code: "MISSING_RELATIONSHIP_FROM",
|
|
203
|
+
message: `Relationship ${rel.id} missing 'from'`,
|
|
204
|
+
relationship_id: rel.id,
|
|
205
|
+
})
|
|
206
|
+
}
|
|
207
|
+
if (!rel.to) {
|
|
208
|
+
errors.push({
|
|
209
|
+
code: "MISSING_RELATIONSHIP_TO",
|
|
210
|
+
message: `Relationship ${rel.id} missing 'to'`,
|
|
211
|
+
relationship_id: rel.id,
|
|
212
|
+
})
|
|
213
|
+
}
|
|
214
|
+
if (!rel.type) {
|
|
215
|
+
errors.push({
|
|
216
|
+
code: "MISSING_RELATIONSHIP_TYPE",
|
|
217
|
+
message: `Relationship ${rel.id} missing type`,
|
|
218
|
+
relationship_id: rel.id,
|
|
219
|
+
})
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function validateSemantic(
|
|
225
|
+
graph: KnowledgeGraph,
|
|
226
|
+
errors: ValidationError[],
|
|
227
|
+
warnings: ValidationWarning[],
|
|
228
|
+
policy: ValidationPolicy = DEFAULT_VALIDATION_POLICY,
|
|
229
|
+
): void {
|
|
230
|
+
const { removed, deprecated } = getExclusionSets(graph)
|
|
231
|
+
const requirements = graph.nodes.filter((n) => n.type === "requirement")
|
|
232
|
+
const entities = graph.nodes.filter((n) => n.type === "entity")
|
|
233
|
+
|
|
234
|
+
// Check for requirements without tasks
|
|
235
|
+
for (const req of requirements) {
|
|
236
|
+
if (isNodeExcludedOrDeprecated(req.id, req.status, removed, deprecated)) continue
|
|
237
|
+
const hasTask = graph.relationships.some(
|
|
238
|
+
(r) =>
|
|
239
|
+
r.from === req.id &&
|
|
240
|
+
(r.type === "implemented_by" || r.type === "contains" || r.type === "belongs_to"),
|
|
241
|
+
)
|
|
242
|
+
// VERIFIED requirements are already validated, skip warning
|
|
243
|
+
if (!hasTask && req.status !== "VERIFIED") {
|
|
244
|
+
warnings.push({
|
|
245
|
+
code: "REQUIREMENT_NO_TASK",
|
|
246
|
+
message: `Requirement ${req.id} has no implementing task`,
|
|
247
|
+
node_id: req.id,
|
|
248
|
+
})
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const meta = req.metadata as Record<string, unknown>
|
|
252
|
+
const priority = String(meta.priority || "").toLowerCase()
|
|
253
|
+
const hasTestEvidence = graph.relationships.some(
|
|
254
|
+
(r) => r.from === req.id && (r.type === "tested_by" || r.type === "tests"),
|
|
255
|
+
)
|
|
256
|
+
if (priority === "critical" && !hasTestEvidence) {
|
|
257
|
+
const issue = {
|
|
258
|
+
code: "CRITICAL_REQUIREMENT_UNTESTED",
|
|
259
|
+
message: `Critical requirement ${req.id} has no linked test evidence`,
|
|
260
|
+
node_id: req.id,
|
|
261
|
+
}
|
|
262
|
+
if (policy.critical_requirement_without_test === "error") errors.push(issue)
|
|
263
|
+
else warnings.push(issue)
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const verification = meta.verification as Record<string, unknown> | undefined
|
|
267
|
+
if (!Array.isArray(verification?.scenarios) || verification.scenarios.length === 0) {
|
|
268
|
+
const issue = {
|
|
269
|
+
code: "REQUIREMENT_NOT_EXECUTABLE",
|
|
270
|
+
message: `Requirement ${req.id} has no Given/When/Then verification scenario`,
|
|
271
|
+
node_id: req.id,
|
|
272
|
+
}
|
|
273
|
+
if (policy.missing_verification_scenario === "error") errors.push(issue)
|
|
274
|
+
else warnings.push(issue)
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Check for entities without persistence (multiple strategies)
|
|
279
|
+
for (const entity of entities) {
|
|
280
|
+
if (isNodeExcludedOrDeprecated(entity.id, entity.status, removed, deprecated)) continue
|
|
281
|
+
if (!hasPersistenceMapping(entity, graph)) {
|
|
282
|
+
warnings.push({
|
|
283
|
+
code: "ENTITY_NO_TABLE",
|
|
284
|
+
message: `Entity ${entity.id} has no corresponding table`,
|
|
285
|
+
node_id: entity.id,
|
|
286
|
+
})
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function validateReferences(
|
|
292
|
+
graph: KnowledgeGraph,
|
|
293
|
+
errors: ValidationError[],
|
|
294
|
+
_warnings: ValidationWarning[],
|
|
295
|
+
): void {
|
|
296
|
+
const nodeIds = new Set(graph.nodes.map((n) => n.id))
|
|
297
|
+
|
|
298
|
+
for (const rel of graph.relationships) {
|
|
299
|
+
if (rel.from && !nodeIds.has(rel.from)) {
|
|
300
|
+
errors.push({
|
|
301
|
+
code: "DANGLING_REFERENCE",
|
|
302
|
+
message: `Relationship ${rel.id} references non-existent source: ${rel.from}`,
|
|
303
|
+
relationship_id: rel.id,
|
|
304
|
+
})
|
|
305
|
+
}
|
|
306
|
+
if (rel.to && !nodeIds.has(rel.to)) {
|
|
307
|
+
errors.push({
|
|
308
|
+
code: "DANGLING_REFERENCE",
|
|
309
|
+
message: `Relationship ${rel.id} references non-existent target: ${rel.to}`,
|
|
310
|
+
relationship_id: rel.id,
|
|
311
|
+
})
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Check file references
|
|
316
|
+
for (const node of graph.nodes) {
|
|
317
|
+
const meta = node.metadata as Record<string, unknown>
|
|
318
|
+
if (Array.isArray(meta.files)) {
|
|
319
|
+
// Files are checked by drift detection, not validation
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function validateCompleteness(
|
|
325
|
+
graph: KnowledgeGraph,
|
|
326
|
+
errors: ValidationError[],
|
|
327
|
+
warnings: ValidationWarning[],
|
|
328
|
+
): void {
|
|
329
|
+
const hasProject = graph.nodes.some((n) => n.type === "project")
|
|
330
|
+
if (!hasProject) {
|
|
331
|
+
errors.push({ code: "NO_PROJECT_NODE", message: "Graph has no project node" })
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const features = graph.nodes.filter((n) => n.type === "feature")
|
|
335
|
+
if (features.length === 0) {
|
|
336
|
+
warnings.push({
|
|
337
|
+
code: "NO_FEATURES",
|
|
338
|
+
message: "Graph has no feature nodes",
|
|
339
|
+
})
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const requirements = graph.nodes.filter((n) => n.type === "requirement")
|
|
343
|
+
if (requirements.length === 0 && features.length > 0) {
|
|
344
|
+
warnings.push({
|
|
345
|
+
code: "FEATURES_NO_REQUIREMENTS",
|
|
346
|
+
message: "Features exist but no requirements defined",
|
|
347
|
+
})
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// ── Cross-layer dependency validation ──────────────────────────────
|
|
351
|
+
validateCrossLayerDependencies(graph, errors, warnings)
|
|
352
|
+
|
|
353
|
+
// ── Deep semantic validation ───────────────────────────────────────
|
|
354
|
+
validateSemanticDeep(graph, errors, warnings)
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Detect architecture violations: frontend files importing from backend packages,
|
|
359
|
+
* database files importing from frontend, etc.
|
|
360
|
+
*/
|
|
361
|
+
function validateCrossLayerDependencies(
|
|
362
|
+
graph: KnowledgeGraph,
|
|
363
|
+
_errors: ValidationError[],
|
|
364
|
+
warnings: ValidationWarning[],
|
|
365
|
+
): void {
|
|
366
|
+
// Build layer map from architecture components
|
|
367
|
+
const layerByModule = new Map<string, string>()
|
|
368
|
+
const archNodes = graph.nodes.filter((n) => n.type === "architecture_component")
|
|
369
|
+
for (const arch of archNodes) {
|
|
370
|
+
const meta = arch.metadata as { layer?: string; technology?: string }
|
|
371
|
+
if (meta.layer) {
|
|
372
|
+
layerByModule.set(arch.id, meta.layer)
|
|
373
|
+
// Also map by technology name
|
|
374
|
+
if (meta.technology) {
|
|
375
|
+
layerByModule.set(meta.technology.toLowerCase(), meta.layer)
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Build file→layer map from file metadata
|
|
381
|
+
const fileLayerMap = new Map<string, string>()
|
|
382
|
+
const fileNodes = graph.nodes.filter((n) => n.type === "file")
|
|
383
|
+
for (const file of fileNodes) {
|
|
384
|
+
const meta = file.metadata as { path?: string }
|
|
385
|
+
if (!meta.path) continue
|
|
386
|
+
const path = meta.path.toLowerCase()
|
|
387
|
+
|
|
388
|
+
// Infer layer from path patterns
|
|
389
|
+
if (path.includes("client") || path.includes("frontend") || path.includes("pages/") || path.includes("components/")) {
|
|
390
|
+
fileLayerMap.set(file.id, "frontend")
|
|
391
|
+
} else if (path.includes("server") || path.includes("backend") || path.includes("routes/") || path.includes("controllers/") || path.includes("services/") || path.includes("repositories/")) {
|
|
392
|
+
fileLayerMap.set(file.id, "backend")
|
|
393
|
+
} else if (path.includes("database") || path.includes("migrations/") || path.includes("schema")) {
|
|
394
|
+
fileLayerMap.set(file.id, "database")
|
|
395
|
+
} else if (path.includes("shared") || path.includes("common")) {
|
|
396
|
+
fileLayerMap.set(file.id, "shared")
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Check file→file dependencies for cross-layer imports
|
|
401
|
+
const fileDeps = graph.relationships.filter(
|
|
402
|
+
(r) => r.type === "uses" || r.type === "depends_on"
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
const LAYER_ORDER: Record<string, number> = {
|
|
406
|
+
shared: 0,
|
|
407
|
+
database: 1,
|
|
408
|
+
backend: 2,
|
|
409
|
+
frontend: 3,
|
|
410
|
+
infrastructure: 4,
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
for (const dep of fileDeps) {
|
|
414
|
+
const fromLayer = fileLayerMap.get(dep.from)
|
|
415
|
+
const toLayer = fileLayerMap.get(dep.to)
|
|
416
|
+
if (!fromLayer || !toLayer || fromLayer === toLayer || fromLayer === "shared" || toLayer === "shared") continue
|
|
417
|
+
|
|
418
|
+
const fromOrder = LAYER_ORDER[fromLayer] ?? 2
|
|
419
|
+
const toOrder = LAYER_ORDER[toLayer] ?? 2
|
|
420
|
+
|
|
421
|
+
// Frontend importing from backend/database is a violation
|
|
422
|
+
if (fromOrder > toOrder) {
|
|
423
|
+
const fromNode = graph.nodes.find((n) => n.id === dep.from)
|
|
424
|
+
const toNode = graph.nodes.find((n) => n.id === dep.to)
|
|
425
|
+
warnings.push({
|
|
426
|
+
code: "CROSS_LAYER_IMPORT",
|
|
427
|
+
message: `${fromLayer} file "${fromNode?.name || dep.from}" imports from ${toLayer} file "${toNode?.name || dep.to}" — architecture violation`,
|
|
428
|
+
node_id: dep.from,
|
|
429
|
+
})
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// Also check symbol→symbol dependencies for cross-layer
|
|
434
|
+
const symbolDeps = graph.relationships.filter(
|
|
435
|
+
(r) => r.type === "calls" || r.type === "uses"
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
for (const dep of symbolDeps) {
|
|
439
|
+
const fromSymbol = graph.nodes.find((n) => n.id === dep.from && n.type === "symbol")
|
|
440
|
+
const toSymbol = graph.nodes.find((n) => n.id === dep.to && n.type === "symbol")
|
|
441
|
+
if (!fromSymbol || !toSymbol) continue
|
|
442
|
+
|
|
443
|
+
const fromMeta = fromSymbol.metadata as { file_path?: string }
|
|
444
|
+
const toMeta = toSymbol.metadata as { file_path?: string }
|
|
445
|
+
if (!fromMeta.file_path || !toMeta.file_path) continue
|
|
446
|
+
|
|
447
|
+
// Infer layer from file path
|
|
448
|
+
const fromPath = fromMeta.file_path.toLowerCase()
|
|
449
|
+
const toPath = toMeta.file_path.toLowerCase()
|
|
450
|
+
|
|
451
|
+
const fromIsFrontend = fromPath.includes("client") || fromPath.includes("frontend") || fromPath.includes("pages/") || fromPath.includes("components/")
|
|
452
|
+
const toIsBackend = toPath.includes("server") || toPath.includes("backend") || toPath.includes("routes/") || toPath.includes("controllers/") || toPath.includes("services/") || toPath.includes("repositories/")
|
|
453
|
+
const toIsDatabase = toPath.includes("database") || toPath.includes("migrations/") || toPath.includes("schema")
|
|
454
|
+
|
|
455
|
+
if (fromIsFrontend && (toIsBackend || toIsDatabase)) {
|
|
456
|
+
warnings.push({
|
|
457
|
+
code: "CROSS_LAYER_IMPORT",
|
|
458
|
+
message: `Frontend symbol "${fromSymbol.name}" (${fromMeta.file_path}) depends on ${toIsDatabase ? "database" : "backend"} symbol "${toSymbol.name}" (${toMeta.file_path}) — architecture violation`,
|
|
459
|
+
node_id: dep.from,
|
|
460
|
+
})
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// ── Persistence mapping check (multiple strategies) ────────────────
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Check if an entity has a valid persistence mapping.
|
|
469
|
+
* Supports multiple strategies:
|
|
470
|
+
* 1. Relationship: persists_to → database/table node
|
|
471
|
+
* 2. Metadata: metadata.table, tableName, stored_in, persists_in, uses, mapped_to
|
|
472
|
+
* 3. Unified schema: entity has fields defined (acceptable for schema.sql patterns)
|
|
473
|
+
*/
|
|
474
|
+
export function hasPersistenceMapping(entity: any, graph: KnowledgeGraph): boolean {
|
|
475
|
+
// Strategy 1: Explicit relationship
|
|
476
|
+
const hasRel = graph.relationships.some(
|
|
477
|
+
(r) => r.from === entity.id && r.type === "persists_to",
|
|
478
|
+
)
|
|
479
|
+
if (hasRel) return true
|
|
480
|
+
|
|
481
|
+
// Strategy 2: Metadata fields indicating storage
|
|
482
|
+
const meta = entity.metadata as Record<string, unknown>
|
|
483
|
+
if (meta.table || meta.tableName || meta.stored_in || meta.persists_in || meta.uses || meta.mapped_to) {
|
|
484
|
+
return true
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// Strategy 3: Unified schema pattern — entity has fields defined
|
|
488
|
+
// This is a legitimate architectural decision (e.g., schema.sql)
|
|
489
|
+
const fields = (meta.fields as any[]) || []
|
|
490
|
+
if (Array.isArray(fields) && fields.length > 0) {
|
|
491
|
+
return true
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
return false
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// ── Formatting ───────────────────────────────────────────────────────
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Deep semantic validation: checks meaning and intent, not just structure.
|
|
501
|
+
*/
|
|
502
|
+
function validateSemanticDeep(
|
|
503
|
+
graph: KnowledgeGraph,
|
|
504
|
+
_errors: ValidationError[],
|
|
505
|
+
warnings: ValidationWarning[],
|
|
506
|
+
): void {
|
|
507
|
+
// 1. Endpoint path params should match entity fields
|
|
508
|
+
const endpoints = graph.nodes.filter(n => n.type === "endpoint")
|
|
509
|
+
const entities = graph.nodes.filter(n => n.type === "entity")
|
|
510
|
+
|
|
511
|
+
for (const endpoint of endpoints) {
|
|
512
|
+
const meta = endpoint.metadata as { path?: string; method?: string }
|
|
513
|
+
if (!meta.path) continue
|
|
514
|
+
|
|
515
|
+
// Extract path params like :id, :userId
|
|
516
|
+
const paramMatches = meta.path.matchAll(/:(\w+)/g)
|
|
517
|
+
for (const match of paramMatches) {
|
|
518
|
+
const paramName = match[1]
|
|
519
|
+
// Check if any related entity has this field
|
|
520
|
+
const relatedEntities = graph.relationships
|
|
521
|
+
.filter(r => r.from === endpoint.id && r.type === "exposes")
|
|
522
|
+
.map(r => graph.nodes.find(n => n.id === r.to))
|
|
523
|
+
.filter(n => n?.type === "entity")
|
|
524
|
+
|
|
525
|
+
if (relatedEntities.length > 0) {
|
|
526
|
+
const hasField = relatedEntities.some(e => {
|
|
527
|
+
const fields = (e!.metadata as any).fields || []
|
|
528
|
+
return fields.some((f: any) => f.name === paramName)
|
|
529
|
+
})
|
|
530
|
+
if (!hasField) {
|
|
531
|
+
warnings.push({
|
|
532
|
+
code: "ENDPOINT_PARAM_MISMATCH",
|
|
533
|
+
message: `Endpoint ${meta.method} ${meta.path} has param ":${paramName}" but no related entity has this field`,
|
|
534
|
+
node_id: endpoint.id,
|
|
535
|
+
})
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// 2. Features should connect to at least one requirement or endpoint
|
|
542
|
+
const features = graph.nodes.filter(n => n.type === "feature")
|
|
543
|
+
for (const feature of features) {
|
|
544
|
+
const hasConnection = graph.relationships.some(
|
|
545
|
+
r => (r.from === feature.id || r.to === feature.id) &&
|
|
546
|
+
["contains", "satisfied_by", "requires", "uses"].includes(r.type)
|
|
547
|
+
)
|
|
548
|
+
if (!hasConnection) {
|
|
549
|
+
warnings.push({
|
|
550
|
+
code: "FEATURE_NO_CONNECTIONS",
|
|
551
|
+
message: `Feature "${feature.name}" has no relationships to requirements, endpoints, or entities`,
|
|
552
|
+
node_id: feature.id,
|
|
553
|
+
})
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// 3. Business rules should constrain something
|
|
558
|
+
const rules = graph.nodes.filter(n => n.type === "business_rule")
|
|
559
|
+
for (const rule of rules) {
|
|
560
|
+
const constrainsSomething = graph.relationships.some(
|
|
561
|
+
r => r.from === rule.id && r.type === "constrains"
|
|
562
|
+
)
|
|
563
|
+
if (!constrainsSomething) {
|
|
564
|
+
warnings.push({
|
|
565
|
+
code: "RULE_NO_TARGET",
|
|
566
|
+
message: `Business rule "${rule.name}" doesn't constrain any feature or requirement`,
|
|
567
|
+
node_id: rule.id,
|
|
568
|
+
})
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// 4. Entities without fields
|
|
573
|
+
for (const entity of entities) {
|
|
574
|
+
const fields = (entity.metadata as any).fields || []
|
|
575
|
+
if (fields.length === 0) {
|
|
576
|
+
warnings.push({
|
|
577
|
+
code: "ENTITY_NO_FIELDS",
|
|
578
|
+
message: `Entity "${entity.name}" has no fields defined`,
|
|
579
|
+
node_id: entity.id,
|
|
580
|
+
})
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// 5. Requirements without acceptance criteria
|
|
585
|
+
const reqs = graph.nodes.filter(n => n.type === "requirement")
|
|
586
|
+
for (const req of reqs) {
|
|
587
|
+
const meta = req.metadata as any
|
|
588
|
+
if (!meta.acceptance_criteria || meta.acceptance_criteria.length === 0) {
|
|
589
|
+
if (!req.description || req.description.length < 10) {
|
|
590
|
+
warnings.push({
|
|
591
|
+
code: "REQUIREMENT_NO_CRITERIA",
|
|
592
|
+
message: `Requirement "${req.name}" has no acceptance criteria and minimal description`,
|
|
593
|
+
node_id: req.id,
|
|
594
|
+
})
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
export function formatValidationResult(result: ValidationResult): string {
|
|
601
|
+
const lines: string[] = []
|
|
602
|
+
|
|
603
|
+
if (result.valid) {
|
|
604
|
+
lines.push("✅ SDD Validation: PASSED\n")
|
|
605
|
+
} else {
|
|
606
|
+
lines.push("❌ SDD Validation: FAILED\n")
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
if (result.errors.length > 0) {
|
|
610
|
+
lines.push(`### Errors (${result.errors.length})`)
|
|
611
|
+
const errorsToShow = result.errors.slice(0, 20)
|
|
612
|
+
for (const err of errorsToShow) {
|
|
613
|
+
const nodeRef = err.node_id ? ` [${err.node_id}]` : ""
|
|
614
|
+
lines.push(`- [${err.code}]${nodeRef} ${err.message}`)
|
|
615
|
+
}
|
|
616
|
+
if (result.errors.length > 20) {
|
|
617
|
+
lines.push(`\n... and ${result.errors.length - 20} more errors`)
|
|
618
|
+
}
|
|
619
|
+
lines.push("")
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
if (result.warnings.length > 0) {
|
|
623
|
+
lines.push(`### Warnings (${result.warnings.length})`)
|
|
624
|
+
const warningsToShow = result.warnings.slice(0, 20)
|
|
625
|
+
for (const warn of warningsToShow) {
|
|
626
|
+
const nodeRef = warn.node_id ? ` [${warn.node_id}]` : ""
|
|
627
|
+
lines.push(`- [${warn.code}]${nodeRef} ${warn.message}`)
|
|
628
|
+
}
|
|
629
|
+
if (result.warnings.length > 20) {
|
|
630
|
+
lines.push(`\n... and ${result.warnings.length - 20} more warnings`)
|
|
631
|
+
}
|
|
632
|
+
lines.push("")
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// Include integrity report if available
|
|
636
|
+
if (result.integrity) {
|
|
637
|
+
lines.push(formatIntegrityReport(result.integrity))
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
return lines.join("\n")
|
|
641
|
+
}
|