@devtrack-solution/codesdd 1.2.2 → 1.2.4-rc3
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/.sdd/skills/curated/api-clean-flask-langgraph/SKILL.md +17 -17
- package/.sdd/skills/curated/devtrack-api/SKILL.md +170 -31
- package/.sdd/skills/curated/devtrack-api/agents/claude-code.yaml +8 -0
- package/.sdd/skills/curated/devtrack-api/agents/codex.yaml +8 -0
- package/.sdd/skills/curated/devtrack-api/agents/cursor.yaml +8 -0
- package/.sdd/skills/curated/devtrack-api/agents/gemini.yaml +8 -0
- package/.sdd/skills/curated/devtrack-api/agents/kimi.yaml +8 -0
- package/.sdd/skills/curated/devtrack-api/agents/openai.yaml +4 -2
- package/.sdd/skills/curated/devtrack-api/agents/opencode.yaml +10 -0
- package/.sdd/skills/curated/devtrack-api/references/application-presentation.md +2 -2
- package/.sdd/skills/curated/devtrack-api/references/architecture-governance.md +8 -7
- package/.sdd/skills/curated/devtrack-api/references/consumer-sync-policy.md +93 -0
- package/.sdd/skills/curated/devtrack-api/references/contract-pack.yaml +372 -0
- package/.sdd/skills/curated/devtrack-api/references/domain-modeling.md +13 -13
- package/.sdd/skills/curated/devtrack-api/references/field-validation-protocol.md +95 -0
- package/.sdd/skills/curated/devtrack-api/references/foundation-layout.md +294 -0
- package/.sdd/skills/curated/devtrack-api/references/implementation-checklist.md +5 -5
- package/.sdd/skills/curated/devtrack-api/references/imports-lint.md +4 -0
- package/.sdd/skills/curated/devtrack-api/references/portable-agent-contract.md +41 -0
- package/.sdd/skills/curated/devtrack-api/references/testing-validation.md +2 -2
- package/.sdd/skills/curated/devtrack-api/references/typeorm-infrastructure.md +7 -9
- package/LICENSE +1 -1
- package/README.md +399 -53
- package/bin/codesdd.js +3 -2
- package/dist/applications/sdd/index.d.ts +16 -0
- package/dist/applications/sdd/index.js +16 -0
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.js +11 -558
- package/dist/cli/program.d.ts +14 -0
- package/dist/cli/program.js +645 -0
- package/dist/commands/change.js +5 -5
- package/dist/commands/completion.d.ts +1 -1
- package/dist/commands/completion.js +9 -2
- package/dist/commands/config.js +320 -20
- package/dist/commands/feedback.js +1 -1
- package/dist/commands/schema.d.ts +63 -0
- package/dist/commands/schema.js +12 -12
- package/dist/commands/sdd/backlog.d.ts +3 -0
- package/dist/commands/sdd/backlog.js +54 -0
- package/dist/commands/sdd/execution.js +489 -28
- package/dist/commands/sdd/plugin.d.ts +3 -0
- package/dist/commands/sdd/plugin.js +158 -0
- package/dist/commands/sdd/shared.d.ts +1 -0
- package/dist/commands/sdd/shared.js +11 -22
- package/dist/commands/sdd/skills.js +7 -0
- package/dist/commands/sdd.js +107 -15
- package/dist/commands/spec.js +9 -9
- package/dist/commands/validate.js +6 -6
- package/dist/commands/workflow/instructions.js +6 -6
- package/dist/commands/workflow/new-change.js +3 -3
- package/dist/commands/workflow/shared.d.ts +1 -1
- package/dist/commands/workflow/shared.js +4 -4
- package/dist/core/archive.js +15 -5
- package/dist/core/artifact-graph/instruction-loader.d.ts +1 -1
- package/dist/core/artifact-graph/instruction-loader.js +3 -3
- package/dist/core/artifact-graph/resolver.d.ts +4 -4
- package/dist/core/artifact-graph/resolver.js +6 -6
- package/dist/core/branding.js +3 -3
- package/dist/core/cli/command-matrix.js +19 -1
- package/dist/core/cli-command-quality.d.ts +27 -0
- package/dist/core/cli-command-quality.js +180 -0
- package/dist/core/command-generation/adapters/costrict.d.ts +1 -1
- package/dist/core/command-generation/adapters/costrict.js +2 -2
- package/dist/core/command-generation/types.d.ts +1 -1
- package/dist/core/completions/command-registry.d.ts +1 -1
- package/dist/core/completions/command-registry.js +200 -12
- package/dist/core/completions/completion-provider.d.ts +14 -1
- package/dist/core/completions/completion-provider.js +29 -1
- package/dist/core/completions/generators/bash-generator.d.ts +1 -1
- package/dist/core/completions/generators/bash-generator.js +20 -12
- package/dist/core/completions/generators/fish-generator.d.ts +9 -1
- package/dist/core/completions/generators/fish-generator.js +39 -25
- package/dist/core/completions/generators/powershell-generator.d.ts +1 -1
- package/dist/core/completions/generators/powershell-generator.js +21 -11
- package/dist/core/completions/generators/zsh-generator.d.ts +3 -6
- package/dist/core/completions/generators/zsh-generator.js +21 -42
- package/dist/core/completions/installers/bash-installer.js +6 -6
- package/dist/core/completions/installers/fish-installer.js +1 -1
- package/dist/core/completions/installers/powershell-installer.js +14 -14
- package/dist/core/completions/installers/zsh-installer.d.ts +7 -1
- package/dist/core/completions/installers/zsh-installer.js +36 -8
- package/dist/core/completions/templates/bash-templates.d.ts +1 -1
- package/dist/core/completions/templates/bash-templates.js +12 -6
- package/dist/core/completions/templates/fish-templates.d.ts +2 -2
- package/dist/core/completions/templates/fish-templates.js +20 -9
- package/dist/core/completions/templates/powershell-templates.d.ts +1 -1
- package/dist/core/completions/templates/powershell-templates.js +13 -4
- package/dist/core/completions/templates/zsh-templates.d.ts +1 -1
- package/dist/core/completions/templates/zsh-templates.js +18 -9
- package/dist/core/config-schema.d.ts +20 -1
- package/dist/core/config-schema.js +70 -2
- package/dist/core/config.d.ts +3 -3
- package/dist/core/config.js +4 -4
- package/dist/core/global-config.d.ts +57 -12
- package/dist/core/global-config.js +344 -27
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +2 -2
- package/dist/core/init.d.ts +6 -1
- package/dist/core/init.js +99 -77
- package/dist/core/legacy-cleanup.d.ts +17 -17
- package/dist/core/legacy-cleanup.js +96 -79
- package/dist/core/list.js +18 -4
- package/dist/core/migration.d.ts +3 -1
- package/dist/core/migration.js +7 -8
- package/dist/core/parsers/change-parser.js +1 -1
- package/dist/core/parsers/markdown-parser.js +2 -2
- package/dist/core/profile-sync-drift.d.ts +1 -1
- package/dist/core/profile-sync-drift.js +13 -13
- package/dist/core/project-config.d.ts +4 -4
- package/dist/core/project-config.js +11 -11
- package/dist/core/schemas/change.schema.d.ts +1 -1
- package/dist/core/schemas/change.schema.js +1 -1
- package/dist/core/schemas/spec.schema.d.ts +1 -1
- package/dist/core/schemas/spec.schema.js +1 -1
- package/dist/core/sdd/adr.js +23 -1
- package/dist/core/sdd/agent-binding.d.ts +346 -0
- package/dist/core/sdd/agent-binding.js +343 -0
- package/dist/core/sdd/agent-runtime-contract.d.ts +204 -0
- package/dist/core/sdd/agent-runtime-contract.js +200 -0
- package/dist/core/sdd/backlog-cli.d.ts +16 -0
- package/dist/core/sdd/backlog-cli.js +146 -0
- package/dist/core/sdd/backlog-conflict-policy.d.ts +58 -0
- package/dist/core/sdd/backlog-conflict-policy.js +230 -0
- package/dist/core/sdd/backlog-projection.d.ts +8 -0
- package/dist/core/sdd/backlog-projection.js +89 -0
- package/dist/core/sdd/backlog-provider-contract.d.ts +252 -0
- package/dist/core/sdd/backlog-provider-contract.js +158 -0
- package/dist/core/sdd/bootstrap.js +2 -2
- package/dist/core/sdd/check.d.ts +44 -0
- package/dist/core/sdd/check.js +62 -24
- package/dist/core/sdd/contract.d.ts +13 -0
- package/dist/core/sdd/contract.js +36 -0
- package/dist/core/sdd/coordination/coordination-adapters.d.ts +53 -8
- package/dist/core/sdd/coordination/coordination-adapters.js +182 -16
- package/dist/core/sdd/coordination/index.d.ts +1 -0
- package/dist/core/sdd/coordination/index.js +1 -0
- package/dist/core/sdd/coordination/redis-runtime.d.ts +131 -0
- package/dist/core/sdd/coordination/redis-runtime.js +698 -0
- package/dist/core/sdd/deepagent-contracts.d.ts +370 -0
- package/dist/core/sdd/deepagent-contracts.js +235 -0
- package/dist/core/sdd/deepagents/adr-governor.d.ts +2 -0
- package/dist/core/sdd/deepagents/adr-governor.js +30 -0
- package/dist/core/sdd/deepagents/backend.d.ts +63 -0
- package/dist/core/sdd/deepagents/backend.js +174 -0
- package/dist/core/sdd/deepagents/codesdd-tools.d.ts +39 -0
- package/dist/core/sdd/deepagents/codesdd-tools.js +83 -0
- package/dist/core/sdd/deepagents/evidence-mapper.d.ts +86 -0
- package/dist/core/sdd/deepagents/evidence-mapper.js +178 -0
- package/dist/core/sdd/deepagents/model-provider.d.ts +53 -0
- package/dist/core/sdd/deepagents/model-provider.js +379 -0
- package/dist/core/sdd/deepagents/policy-enforcement.d.ts +30 -0
- package/dist/core/sdd/deepagents/policy-enforcement.js +90 -0
- package/dist/core/sdd/deepagents/policy.d.ts +75 -0
- package/dist/core/sdd/deepagents/policy.js +358 -0
- package/dist/core/sdd/deepagents/quality-witness.d.ts +3 -0
- package/dist/core/sdd/deepagents/quality-witness.js +77 -0
- package/dist/core/sdd/deepagents/reversa-subagents.d.ts +75 -0
- package/dist/core/sdd/deepagents/reversa-subagents.js +182 -0
- package/dist/core/sdd/deepagents/runtime-factory.d.ts +90 -0
- package/dist/core/sdd/deepagents/runtime-factory.js +231 -0
- package/dist/core/sdd/deepagents/runtime-loader.d.ts +16 -0
- package/dist/core/sdd/deepagents/runtime-loader.js +65 -0
- package/dist/core/sdd/default-bootstrap-files.d.ts +3 -3
- package/dist/core/sdd/default-bootstrap-files.js +50 -10
- package/dist/core/sdd/default-skills.d.ts +30 -0
- package/dist/core/sdd/default-skills.js +288 -8
- package/dist/core/sdd/devtrack-api-appliance.d.ts +91 -0
- package/dist/core/sdd/devtrack-api-appliance.js +280 -0
- package/dist/core/sdd/devtrack-api-architecture.d.ts +31 -0
- package/dist/core/sdd/devtrack-api-architecture.js +608 -0
- package/dist/core/sdd/devtrack-api-import-boundary.d.ts +19 -0
- package/dist/core/sdd/devtrack-api-import-boundary.js +32 -0
- package/dist/core/sdd/diagnose.d.ts +59 -0
- package/dist/core/sdd/diagnose.js +37 -37
- package/dist/core/sdd/docs-sync.js +54 -20
- package/dist/core/sdd/domain/capability-diff.d.ts +63 -0
- package/dist/core/sdd/domain/capability-diff.js +200 -0
- package/dist/core/sdd/domain/change-safety-guardrails.d.ts +74 -0
- package/dist/core/sdd/domain/change-safety-guardrails.js +333 -0
- package/dist/core/sdd/domain/post-active-validation.d.ts +7 -0
- package/dist/core/sdd/domain/post-active-validation.js +61 -0
- package/dist/core/sdd/domain/semantic-intent-classifier.d.ts +29 -0
- package/dist/core/sdd/domain/semantic-intent-classifier.js +117 -0
- package/dist/core/sdd/domain/transition-engine.js +1 -0
- package/dist/core/sdd/entity-reference.d.ts +5 -0
- package/dist/core/sdd/entity-reference.js +22 -0
- package/dist/core/sdd/foundation-artifact-map-validator.d.ts +16 -0
- package/dist/core/sdd/foundation-artifact-map-validator.js +71 -0
- package/dist/core/sdd/foundation-layer-manifest.d.ts +24 -0
- package/dist/core/sdd/foundation-layer-manifest.js +117 -0
- package/dist/core/sdd/governance-backfill.d.ts +31 -0
- package/dist/core/sdd/governance-backfill.js +359 -0
- package/dist/core/sdd/governance-parser.d.ts +21 -0
- package/dist/core/sdd/governance-parser.js +91 -0
- package/dist/core/sdd/governance-schemas.d.ts +245 -0
- package/dist/core/sdd/governance-schemas.js +143 -0
- package/dist/core/sdd/{import-openspec.d.ts → import-legacy-spec.d.ts} +7 -7
- package/dist/core/sdd/{import-openspec.js → import-legacy-spec.js} +21 -29
- package/dist/core/sdd/init.d.ts +3 -0
- package/dist/core/sdd/init.js +6 -3
- package/dist/core/sdd/intent-guard.d.ts +22 -0
- package/dist/core/sdd/intent-guard.js +67 -0
- package/dist/core/sdd/json-schema.js +108 -6
- package/dist/core/sdd/knowledge-graph.d.ts +45 -0
- package/dist/core/sdd/knowledge-graph.js +288 -0
- package/dist/core/sdd/legacy-operations.js +507 -44
- package/dist/core/sdd/lenses.d.ts +1 -0
- package/dist/core/sdd/lenses.js +29 -1
- package/dist/core/sdd/migrate-workspace.js +95 -2
- package/dist/core/sdd/migrate.d.ts +1 -1
- package/dist/core/sdd/migrate.js +36 -2
- package/dist/core/sdd/package-security-gates.d.ts +21 -0
- package/dist/core/sdd/package-security-gates.js +119 -0
- package/dist/core/sdd/package-structure-gate.d.ts +83 -0
- package/dist/core/sdd/package-structure-gate.js +357 -0
- package/dist/core/sdd/parallel-feat-automation.d.ts +330 -0
- package/dist/core/sdd/parallel-feat-automation.js +424 -0
- package/dist/core/sdd/plugin-broker.d.ts +777 -0
- package/dist/core/sdd/plugin-broker.js +492 -0
- package/dist/core/sdd/plugin-certification.d.ts +79 -0
- package/dist/core/sdd/plugin-certification.js +453 -0
- package/dist/core/sdd/plugin-cli.d.ts +139 -0
- package/dist/core/sdd/plugin-cli.js +265 -0
- package/dist/core/sdd/plugin-evidence.d.ts +348 -0
- package/dist/core/sdd/plugin-evidence.js +307 -0
- package/dist/core/sdd/plugin-manifest.d.ts +232 -0
- package/dist/core/sdd/plugin-manifest.js +225 -0
- package/dist/core/sdd/plugin-policy-pack.d.ts +88 -0
- package/dist/core/sdd/plugin-policy-pack.js +236 -0
- package/dist/core/sdd/plugin-policy.d.ts +68 -0
- package/dist/core/sdd/plugin-policy.js +212 -0
- package/dist/core/sdd/plugin-registry.d.ts +447 -0
- package/dist/core/sdd/plugin-registry.js +138 -0
- package/dist/core/sdd/plugin-sdk-contract.d.ts +363 -0
- package/dist/core/sdd/plugin-sdk-contract.js +268 -0
- package/dist/core/sdd/plugin-skill-binding.d.ts +151 -0
- package/dist/core/sdd/plugin-skill-binding.js +339 -0
- package/dist/core/sdd/quality-artifact-manifest-validator.d.ts +28 -0
- package/dist/core/sdd/quality-artifact-manifest-validator.js +167 -0
- package/dist/core/sdd/quality-evidence-renderer.d.ts +65 -0
- package/dist/core/sdd/quality-evidence-renderer.js +218 -0
- package/dist/core/sdd/quality-scenario-runner.d.ts +42 -0
- package/dist/core/sdd/quality-scenario-runner.js +613 -0
- package/dist/core/sdd/quality-validation.d.ts +620 -0
- package/dist/core/sdd/quality-validation.js +239 -0
- package/dist/core/sdd/release-readiness.d.ts +19 -0
- package/dist/core/sdd/release-readiness.js +472 -0
- package/dist/core/sdd/resolve-project-root.d.ts +2 -2
- package/dist/core/sdd/resolve-project-root.js +11 -5
- package/dist/core/sdd/runtime-boundary-contract.d.ts +45 -0
- package/dist/core/sdd/runtime-boundary-contract.js +90 -0
- package/dist/core/sdd/sanitize.d.ts +30 -1
- package/dist/core/sdd/sanitize.js +23 -23
- package/dist/core/sdd/sdk-agent-plugin-quality-gates.d.ts +150 -0
- package/dist/core/sdd/sdk-agent-plugin-quality-gates.js +258 -0
- package/dist/core/sdd/services/agent-run.service.d.ts +97 -0
- package/dist/core/sdd/services/agent-run.service.js +261 -0
- package/dist/core/sdd/services/breakdown.service.js +2 -1
- package/dist/core/sdd/services/capability-diff.service.d.ts +18 -0
- package/dist/core/sdd/services/capability-diff.service.js +26 -0
- package/dist/core/sdd/services/change-safety-preflight.service.d.ts +17 -0
- package/dist/core/sdd/services/change-safety-preflight.service.js +17 -0
- package/dist/core/sdd/services/context.service.d.ts +43 -340
- package/dist/core/sdd/services/context.service.js +341 -25
- package/dist/core/sdd/services/debate.service.js +15 -2
- package/dist/core/sdd/services/feature-lint.service.d.ts +22 -0
- package/dist/core/sdd/services/feature-lint.service.js +105 -5
- package/dist/core/sdd/services/finalize.service.d.ts +105 -0
- package/dist/core/sdd/services/finalize.service.js +499 -38
- package/dist/core/sdd/services/frontend-gap.service.js +22 -7
- package/dist/core/sdd/services/frontend-impact.service.d.ts +1 -1
- package/dist/core/sdd/services/governance-control-plane-runtime-adapters.d.ts +17 -0
- package/dist/core/sdd/services/governance-control-plane-runtime-adapters.js +38 -0
- package/dist/core/sdd/services/governance-control-plane.service.d.ts +66 -0
- package/dist/core/sdd/services/governance-control-plane.service.js +134 -0
- package/dist/core/sdd/services/ingest-deposito.service.js +1 -1
- package/dist/core/sdd/services/legacy-capability.service.d.ts +10 -7
- package/dist/core/sdd/services/legacy-capability.service.js +38 -21
- package/dist/core/sdd/services/mcp-runtime.service.d.ts +123 -8
- package/dist/core/sdd/services/mcp-runtime.service.js +1085 -33
- package/dist/core/sdd/services/onboard.service.js +2 -1
- package/dist/core/sdd/services/rebuild.service.js +6 -1
- package/dist/core/sdd/services/semantic-intent-classifier.service.d.ts +6 -0
- package/dist/core/sdd/services/semantic-intent-classifier.service.js +7 -0
- package/dist/core/sdd/services/skills-sync.service.d.ts +17 -5
- package/dist/core/sdd/services/skills-sync.service.js +55 -2
- package/dist/core/sdd/services/start.service.js +6 -4
- package/dist/core/sdd/skill-bundles-curation-schema.d.ts +66 -0
- package/dist/core/sdd/skill-bundles-curation-schema.js +52 -0
- package/dist/core/sdd/skill-evidence.d.ts +19 -0
- package/dist/core/sdd/skill-evidence.js +38 -0
- package/dist/core/sdd/skill-policy-pool.d.ts +46 -0
- package/dist/core/sdd/skill-policy-pool.js +185 -0
- package/dist/core/sdd/state.d.ts +23 -0
- package/dist/core/sdd/state.js +313 -66
- package/dist/core/sdd/store/sdd-stores.js +2 -2
- package/dist/core/sdd/structural-health.d.ts +55 -55
- package/dist/core/sdd/types.d.ts +60 -19
- package/dist/core/sdd/types.js +21 -0
- package/dist/core/sdd/upgrade-to-codesdd.d.ts +45 -0
- package/dist/core/sdd/upgrade-to-codesdd.js +179 -0
- package/dist/core/sdd/views.js +17 -0
- package/dist/core/sdd/workspace-schemas.d.ts +670 -19
- package/dist/core/sdd/workspace-schemas.js +285 -5
- package/dist/core/sdd/write-manifest.js +22 -4
- package/dist/core/shared/skill-generation.d.ts +1 -1
- package/dist/core/shared/skill-generation.js +15 -15
- package/dist/core/shared/tool-detection.d.ts +3 -3
- package/dist/core/shared/tool-detection.js +14 -14
- package/dist/core/specs-apply.js +6 -6
- package/dist/core/templates/index.d.ts +1 -1
- package/dist/core/templates/index.js +1 -1
- package/dist/core/templates/workflows/apply-change.js +14 -14
- package/dist/core/templates/workflows/archive-change.js +32 -32
- package/dist/core/templates/workflows/bulk-archive-change.js +25 -25
- package/dist/core/templates/workflows/continue-change.js +12 -12
- package/dist/core/templates/workflows/explore.js +29 -29
- package/dist/core/templates/workflows/feedback.js +6 -6
- package/dist/core/templates/workflows/ff-change.js +24 -24
- package/dist/core/templates/workflows/new-change.js +20 -20
- package/dist/core/templates/workflows/onboard.js +33 -33
- package/dist/core/templates/workflows/propose.js +23 -23
- package/dist/core/templates/workflows/sdd.js +8 -8
- package/dist/core/templates/workflows/sync-specs.js +19 -19
- package/dist/core/templates/workflows/verify-change.js +17 -17
- package/dist/core/update.d.ts +2 -2
- package/dist/core/update.js +16 -15
- package/dist/core/validation/constants.d.ts +1 -1
- package/dist/core/validation/constants.js +1 -1
- package/dist/core/view.js +11 -11
- package/dist/domains/sdd/index.d.ts +6 -0
- package/dist/domains/sdd/index.js +6 -0
- package/dist/infrastructures/sdd/index.d.ts +7 -0
- package/dist/infrastructures/sdd/index.js +6 -0
- package/dist/presentations/cli/sdd/index.d.ts +3 -0
- package/dist/presentations/cli/sdd/index.js +3 -0
- package/dist/shared/sdd/index.d.ts +3 -0
- package/dist/shared/sdd/index.js +2 -0
- package/dist/telemetry/config.d.ts +2 -1
- package/dist/telemetry/config.js +17 -8
- package/dist/telemetry/index.d.ts +10 -2
- package/dist/telemetry/index.js +40 -7
- package/dist/ui/ascii-patterns.d.ts +2 -2
- package/dist/ui/ascii-patterns.js +2 -2
- package/dist/ui/welcome-screen.js +2 -2
- package/dist/utils/change-metadata.d.ts +4 -4
- package/dist/utils/change-metadata.js +6 -6
- package/dist/utils/change-utils.d.ts +3 -3
- package/dist/utils/change-utils.js +5 -5
- package/dist/utils/file-system.js +1 -1
- package/dist/utils/interactive.js +1 -1
- package/dist/utils/item-discovery.js +4 -4
- package/dist/utils/legacy-spec-compat.d.ts +2 -0
- package/dist/utils/legacy-spec-compat.js +2 -0
- package/dist/utils/shell-detection.d.ts +1 -0
- package/dist/utils/shell-detection.js +16 -0
- package/package.json +34 -21
- package/schemas/sdd/1-spec.schema.json +1 -1
- package/schemas/sdd/2-plan.schema.json +280 -3
- package/schemas/sdd/3-tasks.schema.json +73 -1
- package/schemas/sdd/4-changelog.schema.json +1 -1
- package/schemas/sdd/5-quality.schema.json +701 -5
- package/schemas/sdd/adr.schema.json +148 -0
- package/schemas/sdd/agent-binding-adapter.schema.json +210 -0
- package/schemas/sdd/agent-binding-resolution.schema.json +338 -0
- package/schemas/sdd/agent-runtime-command-plan.schema.json +212 -0
- package/schemas/sdd/agent-runtime-opencode-run-evidence.schema.json +270 -0
- package/schemas/sdd/backlog-projection-plan.schema.json +180 -0
- package/schemas/sdd/backlog-provider-contract.schema.json +260 -0
- package/schemas/sdd/codesdd-plugin.schema.json +645 -0
- package/schemas/sdd/debate.schema.json +244 -0
- package/schemas/sdd/deepagent-decision-evidence.schema.json +58 -0
- package/schemas/sdd/deepagent-env-contract.schema.json +143 -0
- package/schemas/sdd/deepagent-quality-evidence.schema.json +108 -0
- package/schemas/sdd/deepagent-run-evidence.schema.json +192 -0
- package/schemas/sdd/deepagent-run-plan.schema.json +197 -0
- package/schemas/sdd/deepagent-run-request.schema.json +637 -0
- package/schemas/sdd/deepagent-subagent-evidence.schema.json +110 -0
- package/schemas/sdd/deepagent-tool-call-evidence.schema.json +78 -0
- package/schemas/sdd/discarded.schema.json +127 -0
- package/schemas/sdd/epic.schema.json +147 -0
- package/schemas/sdd/insight.schema.json +136 -0
- package/schemas/sdd/parallel-feat-automation-plan.schema.json +304 -0
- package/schemas/sdd/parallel-feat-automation-request.schema.json +109 -0
- package/schemas/sdd/parallel-feat-scheduler-request.schema.json +116 -0
- package/schemas/sdd/parallel-feat-scheduler-result.schema.json +404 -0
- package/schemas/sdd/plugin-artifact-manifest.schema.json +259 -0
- package/schemas/sdd/plugin-artifact-map.schema.json +223 -0
- package/schemas/sdd/plugin-compliance-index.schema.json +136 -0
- package/schemas/sdd/plugin-dry-run-plan.schema.json +260 -0
- package/schemas/sdd/plugin-evidence-manifest.schema.json +678 -0
- package/schemas/sdd/plugin-language-runtime.schema.json +103 -0
- package/schemas/sdd/plugin-package-governance.schema.json +74 -0
- package/schemas/sdd/plugin-policy-evaluation.schema.json +92 -0
- package/schemas/sdd/plugin-policy-pack-evaluation.schema.json +94 -0
- package/schemas/sdd/plugin-policy-pack.schema.json +196 -0
- package/schemas/sdd/plugin-registry.schema.json +729 -0
- package/schemas/sdd/plugin-rollback-manifest.schema.json +87 -0
- package/schemas/sdd/plugin-runtime-invocation-plan.schema.json +954 -0
- package/schemas/sdd/plugin-skill-binding-resolution.schema.json +305 -0
- package/schemas/sdd/plugin-skill-binding.schema.json +88 -0
- package/schemas/sdd/plugin-validation-manifest.schema.json +123 -0
- package/schemas/sdd/quality-architecture-schema.schema.json +216 -0
- package/schemas/sdd/quality-evidence-bundle.schema.json +1337 -0
- package/schemas/sdd/quality-run.schema.json +197 -0
- package/schemas/sdd/quality-scenario.schema.json +252 -0
- package/schemas/sdd/sdk-agent-plugin-quality-gate-input.schema.json +168 -0
- package/schemas/sdd/sdk-agent-plugin-quality-gate-report.schema.json +160 -0
- package/schemas/sdd/workspace-catalog.schema.json +13232 -35
- package/schemas/spec-driven/schema.yaml +4 -4
- package/schemas/spec-driven/templates/proposal.md +1 -1
- package/dist/utils/openspec-compat.d.ts +0 -2
- package/dist/utils/openspec-compat.js +0 -2
|
@@ -0,0 +1,613 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { pluginArtifactManifestSchema, } from './plugin-broker.js';
|
|
3
|
+
import { pluginComplianceIndexSchema, pluginValidationManifestSchema, } from './plugin-evidence.js';
|
|
4
|
+
import { parseQualityArchitectureSchema, parseQualityEvidenceBundle, parseQualityRun, parseQualityScenario, } from './quality-validation.js';
|
|
5
|
+
const KNOWN_EVIDENCE_KEYS = new Set([
|
|
6
|
+
'artifact_manifest',
|
|
7
|
+
'validation_manifest',
|
|
8
|
+
'compliance_index',
|
|
9
|
+
'architecture_schema',
|
|
10
|
+
'filesystem_snapshot',
|
|
11
|
+
'import_graph',
|
|
12
|
+
'command_log',
|
|
13
|
+
'checksums',
|
|
14
|
+
]);
|
|
15
|
+
const WARNING_ONLY_PLUGIN_REF = {
|
|
16
|
+
id: 'codesdd-warning-only-runner',
|
|
17
|
+
version: '0.0.0',
|
|
18
|
+
};
|
|
19
|
+
export function runQualityScenarioWarningOnly(input) {
|
|
20
|
+
const scenario = parseQualityScenario(input.scenario);
|
|
21
|
+
const startedAt = toIsoTimestamp(input.startedAt ?? new Date());
|
|
22
|
+
const finishedAt = toIsoTimestamp(input.finishedAt ?? input.startedAt ?? new Date(startedAt));
|
|
23
|
+
const runId = input.runId ?? buildRunId(startedAt, scenario.id);
|
|
24
|
+
const featureRef = input.featureRef ?? scenario.feature_ref;
|
|
25
|
+
if (!featureRef) {
|
|
26
|
+
throw new Error(`Quality scenario ${scenario.id} must declare feature_ref or receive featureRef.`);
|
|
27
|
+
}
|
|
28
|
+
const artifactManifest = input.artifactManifest
|
|
29
|
+
? pluginArtifactManifestSchema.parse(input.artifactManifest)
|
|
30
|
+
: undefined;
|
|
31
|
+
const validationManifest = input.validationManifest
|
|
32
|
+
? pluginValidationManifestSchema.parse(input.validationManifest)
|
|
33
|
+
: undefined;
|
|
34
|
+
const complianceIndex = input.complianceIndex
|
|
35
|
+
? pluginComplianceIndexSchema.parse(input.complianceIndex)
|
|
36
|
+
: undefined;
|
|
37
|
+
const architectureSchema = input.architectureResult?.schema
|
|
38
|
+
? parseQualityArchitectureSchema(input.architectureResult.schema)
|
|
39
|
+
: undefined;
|
|
40
|
+
const reportRoot = `.sdd/reports/quality-runs/${runId}`;
|
|
41
|
+
const commandLogRef = `${reportRoot}/command-log.txt`;
|
|
42
|
+
const commandArgv = input.commandArgv ?? [
|
|
43
|
+
'codesdd',
|
|
44
|
+
'sdd',
|
|
45
|
+
'validate-quality',
|
|
46
|
+
'--scenario',
|
|
47
|
+
scenario.id,
|
|
48
|
+
'--warning-only',
|
|
49
|
+
];
|
|
50
|
+
const findings = [
|
|
51
|
+
warningFinding({
|
|
52
|
+
code: 'QUALITY_WARNING_ONLY_RUNNER',
|
|
53
|
+
message: `Scenario ${scenario.id} was evaluated by the warning-only runner without plugin spawn, apply, or filesystem writes.`,
|
|
54
|
+
remediation: 'Review warnings and promote checks to enforced validation only after the baseline is accepted.',
|
|
55
|
+
}),
|
|
56
|
+
];
|
|
57
|
+
collectArtifactManifestFindings({
|
|
58
|
+
scenario,
|
|
59
|
+
featureRef,
|
|
60
|
+
artifactManifest,
|
|
61
|
+
findings,
|
|
62
|
+
});
|
|
63
|
+
collectArchitectureFindings({
|
|
64
|
+
scenario,
|
|
65
|
+
architectureResult: input.architectureResult,
|
|
66
|
+
architectureSchema,
|
|
67
|
+
findings,
|
|
68
|
+
});
|
|
69
|
+
collectValidationFindings(validationManifest, findings);
|
|
70
|
+
collectComplianceFindings(complianceIndex, findings);
|
|
71
|
+
const syntheticEvidence = collectSyntheticEvidenceNeeds({
|
|
72
|
+
scenario,
|
|
73
|
+
artifactManifest,
|
|
74
|
+
validationManifest,
|
|
75
|
+
complianceIndex,
|
|
76
|
+
architectureSchema,
|
|
77
|
+
architectureResult: input.architectureResult,
|
|
78
|
+
findings,
|
|
79
|
+
});
|
|
80
|
+
const effectiveArtifactManifest = artifactManifest ?? (syntheticEvidence.artifact_manifest
|
|
81
|
+
? buildSyntheticArtifactManifest({ scenario, featureRef, generatedAt: startedAt })
|
|
82
|
+
: undefined);
|
|
83
|
+
const effectiveValidationManifest = validationManifest ?? (syntheticEvidence.validation_manifest
|
|
84
|
+
? buildSyntheticValidationManifest({
|
|
85
|
+
scenario,
|
|
86
|
+
featureRef,
|
|
87
|
+
generatedAt: startedAt,
|
|
88
|
+
artifactManifest: effectiveArtifactManifest,
|
|
89
|
+
})
|
|
90
|
+
: undefined);
|
|
91
|
+
const effectiveComplianceIndex = complianceIndex ?? (syntheticEvidence.compliance_index
|
|
92
|
+
? buildSyntheticComplianceIndex({ scenario, featureRef, generatedAt: startedAt })
|
|
93
|
+
: undefined);
|
|
94
|
+
const effectiveArchitectureSchema = architectureSchema ?? (syntheticEvidence.architecture_schema
|
|
95
|
+
? buildSyntheticArchitectureSchema(scenario)
|
|
96
|
+
: undefined);
|
|
97
|
+
const artifacts = buildRunArtifactRefs({
|
|
98
|
+
reportRoot,
|
|
99
|
+
scenario,
|
|
100
|
+
artifactManifest: effectiveArtifactManifest,
|
|
101
|
+
architectureResult: input.architectureResult,
|
|
102
|
+
});
|
|
103
|
+
const filesystemSnapshot = buildEvidenceFilesystemSnapshot({
|
|
104
|
+
reportRoot,
|
|
105
|
+
artifactManifest: effectiveArtifactManifest,
|
|
106
|
+
architectureResult: input.architectureResult,
|
|
107
|
+
});
|
|
108
|
+
const importGraph = buildEvidenceImportGraph({
|
|
109
|
+
architectureResult: input.architectureResult,
|
|
110
|
+
filesystemSnapshot,
|
|
111
|
+
scenario,
|
|
112
|
+
});
|
|
113
|
+
const checksums = buildEvidenceChecksums({
|
|
114
|
+
commandLogRef,
|
|
115
|
+
commandArgv,
|
|
116
|
+
artifactManifest: effectiveArtifactManifest,
|
|
117
|
+
});
|
|
118
|
+
const run = parseQualityRun({
|
|
119
|
+
schema_version: 1,
|
|
120
|
+
run_id: runId,
|
|
121
|
+
scenario_ref: scenario.id,
|
|
122
|
+
feature_ref: featureRef,
|
|
123
|
+
started_at: startedAt,
|
|
124
|
+
finished_at: finishedAt,
|
|
125
|
+
mode: scenario.mode,
|
|
126
|
+
status: 'warning',
|
|
127
|
+
plugin_ref: effectiveArtifactManifest
|
|
128
|
+
? {
|
|
129
|
+
id: effectiveArtifactManifest.plugin_ref.id,
|
|
130
|
+
version: effectiveArtifactManifest.plugin_ref.version,
|
|
131
|
+
capability: effectiveArtifactManifest.capability,
|
|
132
|
+
}
|
|
133
|
+
: undefined,
|
|
134
|
+
command: {
|
|
135
|
+
argv: commandArgv,
|
|
136
|
+
cwd: input.cwd ?? '.',
|
|
137
|
+
env_keys: [],
|
|
138
|
+
},
|
|
139
|
+
schema_versions: {
|
|
140
|
+
scenario: String(scenario.schema_version),
|
|
141
|
+
run: '1',
|
|
142
|
+
evidence_bundle: '1',
|
|
143
|
+
artifact_manifest: effectiveArtifactManifest ? String(effectiveArtifactManifest.schema_version) : 'absent',
|
|
144
|
+
architecture_schema: effectiveArchitectureSchema ? String(effectiveArchitectureSchema.schema_version) : 'absent',
|
|
145
|
+
},
|
|
146
|
+
artifacts,
|
|
147
|
+
findings,
|
|
148
|
+
evidence_bundle_path: `${reportRoot}/evidence-bundle.yaml`,
|
|
149
|
+
metadata: {
|
|
150
|
+
warning_only: true,
|
|
151
|
+
spawned_process: false,
|
|
152
|
+
applied_changes: false,
|
|
153
|
+
synthetic_evidence: syntheticEvidence,
|
|
154
|
+
...input.metadata,
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
const evidenceBundle = parseQualityEvidenceBundle({
|
|
158
|
+
schema_version: 1,
|
|
159
|
+
run,
|
|
160
|
+
scenario,
|
|
161
|
+
architecture_schema: effectiveArchitectureSchema,
|
|
162
|
+
artifact_manifest: effectiveArtifactManifest,
|
|
163
|
+
validation_manifest: effectiveValidationManifest,
|
|
164
|
+
compliance_index: effectiveComplianceIndex,
|
|
165
|
+
filesystem_snapshot: filesystemSnapshot,
|
|
166
|
+
import_graph: importGraph,
|
|
167
|
+
command_log_ref: commandLogRef,
|
|
168
|
+
exceptions: [],
|
|
169
|
+
checksums,
|
|
170
|
+
});
|
|
171
|
+
return {
|
|
172
|
+
run,
|
|
173
|
+
evidence_bundle: evidenceBundle,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
function collectArtifactManifestFindings(input) {
|
|
177
|
+
const { scenario, featureRef, artifactManifest, findings } = input;
|
|
178
|
+
if (!artifactManifest) {
|
|
179
|
+
if (scenario.expected_artifacts.some((artifact) => artifact.required)) {
|
|
180
|
+
findings.push(warningFinding({
|
|
181
|
+
code: 'QUALITY_ARTIFACT_MANIFEST_MISSING',
|
|
182
|
+
message: `Scenario ${scenario.id} declares expected artifacts but no artifact manifest was provided.`,
|
|
183
|
+
remediation: 'Attach an artifact manifest from the dry-run/apply planning path before enforcing artifact gates.',
|
|
184
|
+
}));
|
|
185
|
+
}
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
if (artifactManifest.feature_ref !== featureRef) {
|
|
189
|
+
findings.push(warningFinding({
|
|
190
|
+
code: 'QUALITY_ARTIFACT_FEATURE_MISMATCH',
|
|
191
|
+
message: `Artifact manifest feature_ref ${artifactManifest.feature_ref} does not match run feature_ref ${featureRef}.`,
|
|
192
|
+
remediation: 'Regenerate the artifact manifest for the same feature as the quality scenario.',
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
if (artifactManifest.mode !== 'dry-run') {
|
|
196
|
+
findings.push(warningFinding({
|
|
197
|
+
code: 'QUALITY_ARTIFACT_MODE_NOT_DRY_RUN',
|
|
198
|
+
message: `Artifact manifest mode is ${artifactManifest.mode}; the warning-only runner did not execute apply.`,
|
|
199
|
+
remediation: 'Use dry-run artifact evidence for warning-only baselines, or review external apply evidence separately.',
|
|
200
|
+
}));
|
|
201
|
+
}
|
|
202
|
+
for (const validation of artifactManifest.validation_evidence) {
|
|
203
|
+
if (validation.status === 'passed')
|
|
204
|
+
continue;
|
|
205
|
+
findings.push(warningFinding({
|
|
206
|
+
code: `QUALITY_ARTIFACT_VALIDATION_${validation.status.toUpperCase().replace(/-/gu, '_')}`,
|
|
207
|
+
message: `Artifact manifest validation "${validation.command}" is ${validation.status}.`,
|
|
208
|
+
remediation: 'Run or replace pending/skipped/failed validation evidence before enabling hard gates.',
|
|
209
|
+
}));
|
|
210
|
+
}
|
|
211
|
+
const artifactPaths = artifactManifest.artifacts.map((artifact) => artifact.path);
|
|
212
|
+
for (const expectedArtifact of scenario.expected_artifacts) {
|
|
213
|
+
if (!expectedArtifact.required)
|
|
214
|
+
continue;
|
|
215
|
+
const matchingArtifacts = artifactManifest.artifacts.filter((artifact) => globToRegExp(expectedArtifact.path_pattern).test(normalizeRelativePath(artifact.path)));
|
|
216
|
+
if (matchingArtifacts.length === 0) {
|
|
217
|
+
findings.push(warningFinding({
|
|
218
|
+
code: 'QUALITY_EXPECTED_ARTIFACT_UNVERIFIED',
|
|
219
|
+
message: `No artifact manifest entry matched required pattern "${expectedArtifact.path_pattern}".`,
|
|
220
|
+
remediation: 'Add the generated artifact to the manifest or update the scenario expectation.',
|
|
221
|
+
path: expectedArtifact.path_pattern,
|
|
222
|
+
}));
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
if (expectedArtifact.checksum_required) {
|
|
226
|
+
for (const artifact of matchingArtifacts) {
|
|
227
|
+
if (!artifact.checksum_after) {
|
|
228
|
+
findings.push(warningFinding({
|
|
229
|
+
code: 'QUALITY_EXPECTED_CHECKSUM_MISSING',
|
|
230
|
+
message: `Artifact "${artifact.path}" matched ${expectedArtifact.path_pattern} but has no checksum_after.`,
|
|
231
|
+
remediation: 'Regenerate the artifact manifest with checksums before enforcing checksum gates.',
|
|
232
|
+
path: artifact.path,
|
|
233
|
+
}));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
for (const artifactPath of artifactPaths) {
|
|
239
|
+
if (!isSafeRelativePath(normalizeRelativePath(artifactPath))) {
|
|
240
|
+
findings.push(warningFinding({
|
|
241
|
+
code: 'QUALITY_ARTIFACT_PATH_UNSAFE',
|
|
242
|
+
message: `Artifact path "${artifactPath}" is unsafe for project-relative evidence.`,
|
|
243
|
+
remediation: 'Use a project-relative artifact path without absolute roots or traversal segments.',
|
|
244
|
+
path: artifactPath,
|
|
245
|
+
}));
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
function collectArchitectureFindings(input) {
|
|
250
|
+
const { scenario, architectureResult, architectureSchema, findings } = input;
|
|
251
|
+
if (!architectureResult) {
|
|
252
|
+
if (scenario.required_evidence.includes('architecture_schema')) {
|
|
253
|
+
findings.push(warningFinding({
|
|
254
|
+
code: 'QUALITY_ARCHITECTURE_RESULT_MISSING',
|
|
255
|
+
message: `Scenario ${scenario.id} requires architecture evidence but no architecture result was provided.`,
|
|
256
|
+
remediation: 'Attach an architecture result before promoting the scenario to enforced validation.',
|
|
257
|
+
}));
|
|
258
|
+
}
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
if (!architectureSchema && scenario.required_evidence.includes('architecture_schema')) {
|
|
262
|
+
findings.push(warningFinding({
|
|
263
|
+
code: 'QUALITY_ARCHITECTURE_SCHEMA_MISSING',
|
|
264
|
+
message: `Architecture result for ${scenario.id} did not include a schema.`,
|
|
265
|
+
remediation: 'Attach the architecture gateway schema used to evaluate this scenario.',
|
|
266
|
+
}));
|
|
267
|
+
}
|
|
268
|
+
if (architectureResult.status && architectureResult.status !== 'passed') {
|
|
269
|
+
findings.push(warningFinding({
|
|
270
|
+
code: 'QUALITY_ARCHITECTURE_RESULT_WARNING',
|
|
271
|
+
message: `Architecture result status is ${architectureResult.status}; warning-only mode recorded it without blocking.`,
|
|
272
|
+
remediation: 'Resolve architecture findings before switching this scenario to an enforced gate.',
|
|
273
|
+
}));
|
|
274
|
+
}
|
|
275
|
+
for (const finding of architectureResult.findings ?? []) {
|
|
276
|
+
findings.push(warningFinding({
|
|
277
|
+
code: normalizeIssueCode(finding.code),
|
|
278
|
+
message: finding.message,
|
|
279
|
+
remediation: finding.remediation ?? 'Resolve this architecture finding before enabling hard gates.',
|
|
280
|
+
path: finding.path,
|
|
281
|
+
gate_id: finding.gate_id,
|
|
282
|
+
}));
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
function collectValidationFindings(validationManifest, findings) {
|
|
286
|
+
if (!validationManifest)
|
|
287
|
+
return;
|
|
288
|
+
if (validationManifest.status !== 'passed') {
|
|
289
|
+
findings.push(warningFinding({
|
|
290
|
+
code: 'QUALITY_VALIDATION_MANIFEST_WARNING',
|
|
291
|
+
message: `Validation manifest status is ${validationManifest.status}.`,
|
|
292
|
+
remediation: 'Complete validation evidence before promoting the scenario to enforced gates.',
|
|
293
|
+
}));
|
|
294
|
+
}
|
|
295
|
+
for (const validation of validationManifest.validations) {
|
|
296
|
+
if (validation.status === 'passed')
|
|
297
|
+
continue;
|
|
298
|
+
findings.push(warningFinding({
|
|
299
|
+
code: `QUALITY_VALIDATION_${validation.status.toUpperCase().replace(/-/gu, '_')}`,
|
|
300
|
+
message: `Validation "${validation.command}" is ${validation.status}.`,
|
|
301
|
+
remediation: 'Run or replace pending/skipped/failed validation evidence before enabling hard gates.',
|
|
302
|
+
}));
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
function collectComplianceFindings(complianceIndex, findings) {
|
|
306
|
+
if (!complianceIndex)
|
|
307
|
+
return;
|
|
308
|
+
if (complianceIndex.decision !== 'compliant') {
|
|
309
|
+
findings.push(warningFinding({
|
|
310
|
+
code: 'QUALITY_COMPLIANCE_INDEX_WARNING',
|
|
311
|
+
message: `Compliance index decision is ${complianceIndex.decision} with score ${complianceIndex.score}.`,
|
|
312
|
+
remediation: 'Resolve compliance criteria before promoting the scenario to enforced gates.',
|
|
313
|
+
}));
|
|
314
|
+
}
|
|
315
|
+
for (const criterion of complianceIndex.criteria) {
|
|
316
|
+
if (criterion.status === 'pass')
|
|
317
|
+
continue;
|
|
318
|
+
findings.push(warningFinding({
|
|
319
|
+
code: normalizeIssueCode(`QUALITY_COMPLIANCE_${criterion.id}`),
|
|
320
|
+
message: `Compliance criterion "${criterion.label}" is ${criterion.status}.`,
|
|
321
|
+
remediation: 'Resolve this compliance criterion before enabling hard gates.',
|
|
322
|
+
}));
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
function collectSyntheticEvidenceNeeds(input) {
|
|
326
|
+
const syntheticEvidence = {};
|
|
327
|
+
for (const evidenceKey of input.scenario.required_evidence) {
|
|
328
|
+
if (!KNOWN_EVIDENCE_KEYS.has(evidenceKey))
|
|
329
|
+
continue;
|
|
330
|
+
const missing = evidenceKey === 'artifact_manifest' ? !input.artifactManifest
|
|
331
|
+
: evidenceKey === 'validation_manifest' ? !input.validationManifest
|
|
332
|
+
: evidenceKey === 'compliance_index' ? !input.complianceIndex
|
|
333
|
+
: evidenceKey === 'architecture_schema' ? !input.architectureSchema
|
|
334
|
+
: false;
|
|
335
|
+
if (!missing)
|
|
336
|
+
continue;
|
|
337
|
+
syntheticEvidence[evidenceKey] = true;
|
|
338
|
+
input.findings.push(warningFinding({
|
|
339
|
+
code: normalizeIssueCode(`QUALITY_${evidenceKey}_SYNTHETIC`),
|
|
340
|
+
message: `Required evidence "${evidenceKey}" was not supplied; warning-only mode attached a synthetic placeholder.`,
|
|
341
|
+
remediation: `Provide real ${evidenceKey} evidence before enforcing this quality scenario.`,
|
|
342
|
+
}));
|
|
343
|
+
}
|
|
344
|
+
if (input.scenario.required_evidence.includes('import_graph')) {
|
|
345
|
+
const graph = input.architectureResult?.import_graph;
|
|
346
|
+
if (!graph || (graph.nodes.length === 0 && graph.edges.length === 0)) {
|
|
347
|
+
syntheticEvidence.import_graph = true;
|
|
348
|
+
input.findings.push(warningFinding({
|
|
349
|
+
code: 'QUALITY_IMPORT_GRAPH_SYNTHETIC',
|
|
350
|
+
message: 'Required import_graph evidence was not supplied; warning-only mode derived a minimal graph.',
|
|
351
|
+
remediation: 'Provide a real import graph before enforcing architecture or dependency gates.',
|
|
352
|
+
}));
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (input.scenario.required_evidence.includes('checksums')) {
|
|
356
|
+
const hasManifestChecksum = input.artifactManifest?.artifacts.some((artifact) => Boolean(artifact.checksum_after));
|
|
357
|
+
if (!hasManifestChecksum) {
|
|
358
|
+
syntheticEvidence.checksums = true;
|
|
359
|
+
input.findings.push(warningFinding({
|
|
360
|
+
code: 'QUALITY_CHECKSUMS_SYNTHETIC',
|
|
361
|
+
message: 'Required checksum evidence was not supplied; warning-only mode checksummed the command log reference.',
|
|
362
|
+
remediation: 'Provide artifact checksums before enforcing checksum gates.',
|
|
363
|
+
}));
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return syntheticEvidence;
|
|
367
|
+
}
|
|
368
|
+
function buildRunArtifactRefs(input) {
|
|
369
|
+
const refs = new Set([
|
|
370
|
+
`${input.reportRoot}/run.json`,
|
|
371
|
+
`${input.reportRoot}/evidence-bundle.yaml`,
|
|
372
|
+
`${input.reportRoot}/command-log.txt`,
|
|
373
|
+
]);
|
|
374
|
+
for (const artifact of input.artifactManifest?.artifacts ?? []) {
|
|
375
|
+
const normalized = normalizeRelativePath(artifact.path);
|
|
376
|
+
if (isSafeRelativePath(normalized))
|
|
377
|
+
refs.add(normalized);
|
|
378
|
+
}
|
|
379
|
+
for (const artifact of input.architectureResult?.artifacts ?? []) {
|
|
380
|
+
const normalized = normalizeRelativePath(artifact);
|
|
381
|
+
if (isSafeRelativePath(normalized))
|
|
382
|
+
refs.add(normalized);
|
|
383
|
+
}
|
|
384
|
+
for (const evidenceKey of input.scenario.required_evidence) {
|
|
385
|
+
if (!KNOWN_EVIDENCE_KEYS.has(evidenceKey)) {
|
|
386
|
+
refs.add(`${input.reportRoot}/${slugify(evidenceKey)}.txt`);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return [...refs];
|
|
390
|
+
}
|
|
391
|
+
function buildEvidenceFilesystemSnapshot(input) {
|
|
392
|
+
const byPath = new Map();
|
|
393
|
+
for (const file of input.architectureResult?.filesystem_snapshot?.files ?? []) {
|
|
394
|
+
const normalized = normalizeRelativePath(file.path);
|
|
395
|
+
if (isSafeRelativePath(normalized)) {
|
|
396
|
+
byPath.set(normalized, {
|
|
397
|
+
...file,
|
|
398
|
+
path: normalized,
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
for (const artifact of input.artifactManifest?.artifacts ?? []) {
|
|
403
|
+
const normalized = normalizeRelativePath(artifact.path);
|
|
404
|
+
if (isSafeRelativePath(normalized) && artifact.operation !== 'deleted') {
|
|
405
|
+
byPath.set(normalized, {
|
|
406
|
+
path: normalized,
|
|
407
|
+
size_bytes: 0,
|
|
408
|
+
sha256: artifact.checksum_after,
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
for (const reportPath of [
|
|
413
|
+
`${input.reportRoot}/run.json`,
|
|
414
|
+
`${input.reportRoot}/evidence-bundle.yaml`,
|
|
415
|
+
`${input.reportRoot}/command-log.txt`,
|
|
416
|
+
]) {
|
|
417
|
+
byPath.set(reportPath, {
|
|
418
|
+
path: reportPath,
|
|
419
|
+
size_bytes: 0,
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
return {
|
|
423
|
+
root: '.',
|
|
424
|
+
files: [...byPath.values()],
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
function buildEvidenceImportGraph(input) {
|
|
428
|
+
const graph = input.architectureResult?.import_graph;
|
|
429
|
+
if (graph && (graph.nodes.length > 0 || graph.edges.length > 0)) {
|
|
430
|
+
return graph;
|
|
431
|
+
}
|
|
432
|
+
const nodes = new Set();
|
|
433
|
+
if (input.scenario.input.fixture_path) {
|
|
434
|
+
nodes.add(input.scenario.input.fixture_path);
|
|
435
|
+
}
|
|
436
|
+
for (const file of input.filesystemSnapshot.files.slice(0, 10)) {
|
|
437
|
+
nodes.add(file.path);
|
|
438
|
+
}
|
|
439
|
+
return {
|
|
440
|
+
nodes: [...nodes],
|
|
441
|
+
edges: [],
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
function buildEvidenceChecksums(input) {
|
|
445
|
+
const checksums = new Map();
|
|
446
|
+
checksums.set(input.commandLogRef, sha256(input.commandArgv.join('\n')));
|
|
447
|
+
for (const artifact of input.artifactManifest?.artifacts ?? []) {
|
|
448
|
+
const normalized = normalizeRelativePath(artifact.path);
|
|
449
|
+
if (artifact.checksum_after && isSafeRelativePath(normalized)) {
|
|
450
|
+
checksums.set(normalized, artifact.checksum_after);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
return [...checksums.entries()].map(([path, checksum]) => ({
|
|
454
|
+
path,
|
|
455
|
+
sha256: checksum,
|
|
456
|
+
}));
|
|
457
|
+
}
|
|
458
|
+
function buildSyntheticArtifactManifest(input) {
|
|
459
|
+
return pluginArtifactManifestSchema.parse({
|
|
460
|
+
schema_version: 1,
|
|
461
|
+
operation_id: syntheticOperationId(input.scenario),
|
|
462
|
+
generated_at: input.generatedAt,
|
|
463
|
+
feature_ref: input.featureRef,
|
|
464
|
+
plugin_ref: WARNING_ONLY_PLUGIN_REF,
|
|
465
|
+
capability: 'quality.scenario.warning-only',
|
|
466
|
+
mode: 'dry-run',
|
|
467
|
+
status: 'planned',
|
|
468
|
+
artifacts: [],
|
|
469
|
+
validation_evidence: [],
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
function buildSyntheticValidationManifest(input) {
|
|
473
|
+
return pluginValidationManifestSchema.parse({
|
|
474
|
+
schema_version: 1,
|
|
475
|
+
operation_id: input.artifactManifest?.operation_id ?? syntheticOperationId(input.scenario),
|
|
476
|
+
generated_at: input.generatedAt,
|
|
477
|
+
feature_ref: input.featureRef,
|
|
478
|
+
plugin_ref: input.artifactManifest?.plugin_ref ?? WARNING_ONLY_PLUGIN_REF,
|
|
479
|
+
capability: input.artifactManifest?.capability ?? 'quality.scenario.warning-only',
|
|
480
|
+
status: 'partial',
|
|
481
|
+
validations: [],
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
function buildSyntheticComplianceIndex(input) {
|
|
485
|
+
return pluginComplianceIndexSchema.parse({
|
|
486
|
+
schema_version: 1,
|
|
487
|
+
generated_at: input.generatedAt,
|
|
488
|
+
feature_ref: input.featureRef,
|
|
489
|
+
operation_id: syntheticOperationId(input.scenario),
|
|
490
|
+
plugin_ref: WARNING_ONLY_PLUGIN_REF,
|
|
491
|
+
capability: 'quality.scenario.warning-only',
|
|
492
|
+
score: 0,
|
|
493
|
+
decision: 'warning',
|
|
494
|
+
criteria: [
|
|
495
|
+
{
|
|
496
|
+
id: 'warning-only-baseline',
|
|
497
|
+
label: 'Warning-only baseline',
|
|
498
|
+
status: 'warn',
|
|
499
|
+
score: 0,
|
|
500
|
+
max_score: 1,
|
|
501
|
+
evidence: 'Synthetic compliance evidence recorded by warning-only quality scenario runner.',
|
|
502
|
+
issues: ['QUALITY_COMPLIANCE_INDEX_SYNTHETIC'],
|
|
503
|
+
},
|
|
504
|
+
],
|
|
505
|
+
evidence_refs: [`quality:${input.scenario.id}`],
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
function buildSyntheticArchitectureSchema(scenario) {
|
|
509
|
+
return parseQualityArchitectureSchema({
|
|
510
|
+
schema_version: 1,
|
|
511
|
+
id: `ARCH-GATE-${slugify(scenario.id)}`,
|
|
512
|
+
title: `${scenario.title} warning-only architecture baseline`,
|
|
513
|
+
stack: 'warning-only',
|
|
514
|
+
authority: scenario.authority,
|
|
515
|
+
applies_to: {},
|
|
516
|
+
layers: {
|
|
517
|
+
baseline: {
|
|
518
|
+
path_patterns: ['**/*'],
|
|
519
|
+
allowed_file_patterns: [],
|
|
520
|
+
forbidden_file_patterns: [],
|
|
521
|
+
allowed_imports: [],
|
|
522
|
+
forbidden_imports: [],
|
|
523
|
+
required_evidence: ['warning-only'],
|
|
524
|
+
},
|
|
525
|
+
},
|
|
526
|
+
exceptions: {
|
|
527
|
+
require_adr: false,
|
|
528
|
+
require_expiration: false,
|
|
529
|
+
allowed_refs: [],
|
|
530
|
+
},
|
|
531
|
+
update_policy: {
|
|
532
|
+
owner: 'codesdd-quality-runner',
|
|
533
|
+
review_trigger: 'Replace synthetic warning-only architecture evidence before enforcing gates.',
|
|
534
|
+
},
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
function warningFinding(input) {
|
|
538
|
+
return {
|
|
539
|
+
code: normalizeIssueCode(input.code),
|
|
540
|
+
severity: 'warn',
|
|
541
|
+
message: input.message,
|
|
542
|
+
remediation: input.remediation,
|
|
543
|
+
path: input.path && isSafeRelativePath(normalizeRelativePath(input.path))
|
|
544
|
+
? normalizeRelativePath(input.path)
|
|
545
|
+
: undefined,
|
|
546
|
+
gate_id: input.gate_id,
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
function buildRunId(startedAt, scenarioId) {
|
|
550
|
+
const timestamp = startedAt
|
|
551
|
+
.replace(/[-:]/gu, '')
|
|
552
|
+
.replace(/\.\d{3}Z$/u, 'z')
|
|
553
|
+
.replace('T', 't');
|
|
554
|
+
return `qrun-${timestamp}-${slugify(scenarioId)}`;
|
|
555
|
+
}
|
|
556
|
+
function toIsoTimestamp(value) {
|
|
557
|
+
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
|
|
558
|
+
}
|
|
559
|
+
function syntheticOperationId(scenario) {
|
|
560
|
+
return `quality-${slugify(scenario.id)}`;
|
|
561
|
+
}
|
|
562
|
+
function normalizeIssueCode(value) {
|
|
563
|
+
const normalized = value
|
|
564
|
+
.trim()
|
|
565
|
+
.replace(/[^A-Za-z0-9]+/gu, '_')
|
|
566
|
+
.replace(/^_+|_+$/gu, '')
|
|
567
|
+
.toUpperCase();
|
|
568
|
+
return normalized || 'QUALITY_WARNING';
|
|
569
|
+
}
|
|
570
|
+
function normalizeRelativePath(value) {
|
|
571
|
+
return value.replace(/\\/gu, '/').replace(/^\.\//u, '');
|
|
572
|
+
}
|
|
573
|
+
function isSafeRelativePath(value) {
|
|
574
|
+
return Boolean(value)
|
|
575
|
+
&& !value.startsWith('/')
|
|
576
|
+
&& !/^[A-Za-z]:[\\/]/u.test(value)
|
|
577
|
+
&& !value.split('/').some((segment) => segment === '..');
|
|
578
|
+
}
|
|
579
|
+
function globToRegExp(pattern) {
|
|
580
|
+
const normalized = normalizeRelativePath(pattern);
|
|
581
|
+
let source = '';
|
|
582
|
+
for (let index = 0; index < normalized.length; index += 1) {
|
|
583
|
+
const char = normalized[index];
|
|
584
|
+
const next = normalized[index + 1];
|
|
585
|
+
if (char === '*' && next === '*') {
|
|
586
|
+
source += '.*';
|
|
587
|
+
index += 1;
|
|
588
|
+
continue;
|
|
589
|
+
}
|
|
590
|
+
if (char === '*') {
|
|
591
|
+
source += '[^/]*';
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
source += escapeRegExp(char);
|
|
595
|
+
}
|
|
596
|
+
return new RegExp(`^${source}$`, 'u');
|
|
597
|
+
}
|
|
598
|
+
function escapeRegExp(value) {
|
|
599
|
+
return value.replace(/[|\\{}()[\]^$+?.]/gu, '\\$&');
|
|
600
|
+
}
|
|
601
|
+
function slugify(value) {
|
|
602
|
+
const slug = value
|
|
603
|
+
.toLowerCase()
|
|
604
|
+
.replace(/[^a-z0-9]+/gu, '-')
|
|
605
|
+
.replace(/^-+|-+$/gu, '');
|
|
606
|
+
return slug || 'quality';
|
|
607
|
+
}
|
|
608
|
+
function sha256(value) {
|
|
609
|
+
const hash = createHash('sha256');
|
|
610
|
+
hash.update(value);
|
|
611
|
+
return hash.digest('hex');
|
|
612
|
+
}
|
|
613
|
+
//# sourceMappingURL=quality-scenario-runner.js.map
|