@rsaglobaltech/specgate 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1016 -0
- package/README.md +148 -0
- package/bin/specgate.js +2 -0
- package/bin/specgate.ts +383 -0
- package/dist/bin/specgate.js +342 -0
- package/dist/bin/specgate.js.map +1 -0
- package/dist/packages/core/src/application/AddRequirementUseCase.js +24 -0
- package/dist/packages/core/src/application/AddRequirementUseCase.js.map +1 -0
- package/dist/packages/core/src/application/ArchiveChangeUseCase.js +185 -0
- package/dist/packages/core/src/application/ArchiveChangeUseCase.js.map +1 -0
- package/dist/packages/core/src/application/CheckAgainstLockUseCase.js +134 -0
- package/dist/packages/core/src/application/CheckAgainstLockUseCase.js.map +1 -0
- package/dist/packages/core/src/application/GenerateAgentPromptUseCase.js +25 -0
- package/dist/packages/core/src/application/GenerateAgentPromptUseCase.js.map +1 -0
- package/dist/packages/core/src/application/GeneratePlanUseCase.js +135 -0
- package/dist/packages/core/src/application/GeneratePlanUseCase.js.map +1 -0
- package/dist/packages/core/src/application/LinkRequirementUseCase.js +25 -0
- package/dist/packages/core/src/application/LinkRequirementUseCase.js.map +1 -0
- package/dist/packages/core/src/application/RemovePackUseCase.js +28 -0
- package/dist/packages/core/src/application/RemovePackUseCase.js.map +1 -0
- package/dist/packages/core/src/application/UpdateRequirementStatusUseCase.js +37 -0
- package/dist/packages/core/src/application/UpdateRequirementStatusUseCase.js.map +1 -0
- package/dist/packages/core/src/application/ValidateChangeUseCase.js +86 -0
- package/dist/packages/core/src/application/ValidateChangeUseCase.js.map +1 -0
- package/dist/packages/core/src/application/ValidateProjectUseCase.js +101 -0
- package/dist/packages/core/src/application/ValidateProjectUseCase.js.map +1 -0
- package/dist/packages/core/src/application/ports/IDomainPackRepository.js +3 -0
- package/dist/packages/core/src/application/ports/IDomainPackRepository.js.map +1 -0
- package/dist/packages/core/src/application/ports/IHarnessConfigRepository.js +3 -0
- package/dist/packages/core/src/application/ports/IHarnessConfigRepository.js.map +1 -0
- package/dist/packages/core/src/application/ports/ILockfileRepository.js +3 -0
- package/dist/packages/core/src/application/ports/ILockfileRepository.js.map +1 -0
- package/dist/packages/core/src/application/ports/IManifestRepository.js +3 -0
- package/dist/packages/core/src/application/ports/IManifestRepository.js.map +1 -0
- package/dist/packages/core/src/application/ports/IProjectRepository.js +3 -0
- package/dist/packages/core/src/application/ports/IProjectRepository.js.map +1 -0
- package/dist/packages/core/src/application/ports/IRequirementGraphRepository.js +3 -0
- package/dist/packages/core/src/application/ports/IRequirementGraphRepository.js.map +1 -0
- package/dist/packages/core/src/application/ports/ITraceabilityRepository.js +3 -0
- package/dist/packages/core/src/application/ports/ITraceabilityRepository.js.map +1 -0
- package/dist/packages/core/src/domain/AgentPrompt.js +79 -0
- package/dist/packages/core/src/domain/AgentPrompt.js.map +1 -0
- package/dist/packages/core/src/domain/ArchivePlan.js +26 -0
- package/dist/packages/core/src/domain/ArchivePlan.js.map +1 -0
- package/dist/packages/core/src/domain/AuthoringScope.js +48 -0
- package/dist/packages/core/src/domain/AuthoringScope.js.map +1 -0
- package/dist/packages/core/src/domain/ChangeTemplates.js +133 -0
- package/dist/packages/core/src/domain/ChangeTemplates.js.map +1 -0
- package/dist/packages/core/src/domain/CucumberMessages.js +256 -0
- package/dist/packages/core/src/domain/CucumberMessages.js.map +1 -0
- package/dist/packages/core/src/domain/DeclaredArtifacts.js +117 -0
- package/dist/packages/core/src/domain/DeclaredArtifacts.js.map +1 -0
- package/dist/packages/core/src/domain/DeltaSpec.js +219 -0
- package/dist/packages/core/src/domain/DeltaSpec.js.map +1 -0
- package/dist/packages/core/src/domain/Diagnostic.js +75 -0
- package/dist/packages/core/src/domain/Diagnostic.js.map +1 -0
- package/dist/packages/core/src/domain/DomainPack.js +62 -0
- package/dist/packages/core/src/domain/DomainPack.js.map +1 -0
- package/dist/packages/core/src/domain/EmptyAttempt.js +60 -0
- package/dist/packages/core/src/domain/EmptyAttempt.js.map +1 -0
- package/dist/packages/core/src/domain/FileChangeSet.js +37 -0
- package/dist/packages/core/src/domain/FileChangeSet.js.map +1 -0
- package/dist/packages/core/src/domain/Gherkin.js +272 -0
- package/dist/packages/core/src/domain/Gherkin.js.map +1 -0
- package/dist/packages/core/src/domain/GherkinDialects.js +97 -0
- package/dist/packages/core/src/domain/GherkinDialects.js.map +1 -0
- package/dist/packages/core/src/domain/GherkinQuality.js +160 -0
- package/dist/packages/core/src/domain/GherkinQuality.js.map +1 -0
- package/dist/packages/core/src/domain/GherkinTags.js +119 -0
- package/dist/packages/core/src/domain/GherkinTags.js.map +1 -0
- package/dist/packages/core/src/domain/GitSafety.js +77 -0
- package/dist/packages/core/src/domain/GitSafety.js.map +1 -0
- package/dist/packages/core/src/domain/HarnessConfig.js +58 -0
- package/dist/packages/core/src/domain/HarnessConfig.js.map +1 -0
- package/dist/packages/core/src/domain/HarnessReport.js +162 -0
- package/dist/packages/core/src/domain/HarnessReport.js.map +1 -0
- package/dist/packages/core/src/domain/HarnessRun.js +154 -0
- package/dist/packages/core/src/domain/HarnessRun.js.map +1 -0
- package/dist/packages/core/src/domain/InboundChange.js +127 -0
- package/dist/packages/core/src/domain/InboundChange.js.map +1 -0
- package/dist/packages/core/src/domain/Language.js +112 -0
- package/dist/packages/core/src/domain/Language.js.map +1 -0
- package/dist/packages/core/src/domain/Lockfile.js +64 -0
- package/dist/packages/core/src/domain/Lockfile.js.map +1 -0
- package/dist/packages/core/src/domain/PackContribution.js +106 -0
- package/dist/packages/core/src/domain/PackContribution.js.map +1 -0
- package/dist/packages/core/src/domain/PackDelta.js +298 -0
- package/dist/packages/core/src/domain/PackDelta.js.map +1 -0
- package/dist/packages/core/src/domain/PackSpec.js +481 -0
- package/dist/packages/core/src/domain/PackSpec.js.map +1 -0
- package/dist/packages/core/src/domain/ProfileMatch.js +87 -0
- package/dist/packages/core/src/domain/ProfileMatch.js.map +1 -0
- package/dist/packages/core/src/domain/Reconciliation.js +72 -0
- package/dist/packages/core/src/domain/Reconciliation.js.map +1 -0
- package/dist/packages/core/src/domain/RequirementGraph.js +197 -0
- package/dist/packages/core/src/domain/RequirementGraph.js.map +1 -0
- package/dist/packages/core/src/domain/RequirementPlan.js +85 -0
- package/dist/packages/core/src/domain/RequirementPlan.js.map +1 -0
- package/dist/packages/core/src/domain/RequirementReadiness.js +115 -0
- package/dist/packages/core/src/domain/RequirementReadiness.js.map +1 -0
- package/dist/packages/core/src/domain/RequirementSyntax.js +91 -0
- package/dist/packages/core/src/domain/RequirementSyntax.js.map +1 -0
- package/dist/packages/core/src/domain/ResumeState.js +115 -0
- package/dist/packages/core/src/domain/ResumeState.js.map +1 -0
- package/dist/packages/core/src/domain/RunBudget.js +103 -0
- package/dist/packages/core/src/domain/RunBudget.js.map +1 -0
- package/dist/packages/core/src/domain/SpecDiff.js +48 -0
- package/dist/packages/core/src/domain/SpecDiff.js.map +1 -0
- package/dist/packages/core/src/domain/SpecParser.js +406 -0
- package/dist/packages/core/src/domain/SpecParser.js.map +1 -0
- package/dist/packages/core/src/domain/SpecopsManifest.js +90 -0
- package/dist/packages/core/src/domain/SpecopsManifest.js.map +1 -0
- package/dist/packages/core/src/domain/TraceabilityFormat.js +317 -0
- package/dist/packages/core/src/domain/TraceabilityFormat.js.map +1 -0
- package/dist/packages/core/src/domain/TraceabilityMatrix.js +200 -0
- package/dist/packages/core/src/domain/TraceabilityMatrix.js.map +1 -0
- package/dist/packages/core/src/domain/TraceabilityMerge.js +180 -0
- package/dist/packages/core/src/domain/TraceabilityMerge.js.map +1 -0
- package/dist/packages/core/src/domain/ValidationReport.js +53 -0
- package/dist/packages/core/src/domain/ValidationReport.js.map +1 -0
- package/dist/packages/core/src/domain/ValueAnnotations.js +138 -0
- package/dist/packages/core/src/domain/ValueAnnotations.js.map +1 -0
- package/dist/packages/core/src/domain/WriteScope.js +155 -0
- package/dist/packages/core/src/domain/WriteScope.js.map +1 -0
- package/dist/packages/core/src/domain/YamlLite.js +226 -0
- package/dist/packages/core/src/domain/YamlLite.js.map +1 -0
- package/dist/packages/core/src/index.js +120 -0
- package/dist/packages/core/src/index.js.map +1 -0
- package/dist/packages/core/src/infrastructure/ChangeWorkspace.js +276 -0
- package/dist/packages/core/src/infrastructure/ChangeWorkspace.js.map +1 -0
- package/dist/packages/core/src/infrastructure/ConsoleReporter.js +19 -0
- package/dist/packages/core/src/infrastructure/ConsoleReporter.js.map +1 -0
- package/dist/packages/core/src/infrastructure/DirectorySnapshot.js +106 -0
- package/dist/packages/core/src/infrastructure/DirectorySnapshot.js.map +1 -0
- package/dist/packages/core/src/infrastructure/DiskDomainPackRepository.js +57 -0
- package/dist/packages/core/src/infrastructure/DiskDomainPackRepository.js.map +1 -0
- package/dist/packages/core/src/infrastructure/DiskHarnessConfigRepository.js +58 -0
- package/dist/packages/core/src/infrastructure/DiskHarnessConfigRepository.js.map +1 -0
- package/dist/packages/core/src/infrastructure/DiskLanguageRepository.js +69 -0
- package/dist/packages/core/src/infrastructure/DiskLanguageRepository.js.map +1 -0
- package/dist/packages/core/src/infrastructure/DiskLockfileRepository.js +64 -0
- package/dist/packages/core/src/infrastructure/DiskLockfileRepository.js.map +1 -0
- package/dist/packages/core/src/infrastructure/DiskManifestRepository.js +88 -0
- package/dist/packages/core/src/infrastructure/DiskManifestRepository.js.map +1 -0
- package/dist/packages/core/src/infrastructure/DiskPackDeltaRepository.js +138 -0
- package/dist/packages/core/src/infrastructure/DiskPackDeltaRepository.js.map +1 -0
- package/dist/packages/core/src/infrastructure/DiskPackRepository.js +130 -0
- package/dist/packages/core/src/infrastructure/DiskPackRepository.js.map +1 -0
- package/dist/packages/core/src/infrastructure/DiskProjectRepository.js +127 -0
- package/dist/packages/core/src/infrastructure/DiskProjectRepository.js.map +1 -0
- package/dist/packages/core/src/infrastructure/DiskRequirementGraphRepository.js +124 -0
- package/dist/packages/core/src/infrastructure/DiskRequirementGraphRepository.js.map +1 -0
- package/dist/packages/core/src/infrastructure/DiskTraceabilityRepository.js +53 -0
- package/dist/packages/core/src/infrastructure/DiskTraceabilityRepository.js.map +1 -0
- package/dist/packages/core/src/infrastructure/GitContributionStager.js +99 -0
- package/dist/packages/core/src/infrastructure/GitContributionStager.js.map +1 -0
- package/dist/packages/core/src/infrastructure/GitMergeDriver.js +103 -0
- package/dist/packages/core/src/infrastructure/GitMergeDriver.js.map +1 -0
- package/dist/packages/core/src/infrastructure/HarnessConfigFile.js +348 -0
- package/dist/packages/core/src/infrastructure/HarnessConfigFile.js.map +1 -0
- package/dist/packages/core/src/infrastructure/PackChangeDeposit.js +106 -0
- package/dist/packages/core/src/infrastructure/PackChangeDeposit.js.map +1 -0
- package/dist/packages/core/src/infrastructure/RemotePackResolver.js +181 -0
- package/dist/packages/core/src/infrastructure/RemotePackResolver.js.map +1 -0
- package/dist/packages/core/src/infrastructure/SpecopsConfigFile.js +94 -0
- package/dist/packages/core/src/infrastructure/SpecopsConfigFile.js.map +1 -0
- package/dist/packages/core/test/unit/authoring-scope.test.js +102 -0
- package/dist/packages/core/test/unit/authoring-scope.test.js.map +1 -0
- package/dist/packages/core/test/unit/change-templates.test.js +96 -0
- package/dist/packages/core/test/unit/change-templates.test.js.map +1 -0
- package/dist/packages/core/test/unit/cucumber-messages.test.js +232 -0
- package/dist/packages/core/test/unit/cucumber-messages.test.js.map +1 -0
- package/dist/packages/core/test/unit/declared-artifacts.test.js +124 -0
- package/dist/packages/core/test/unit/declared-artifacts.test.js.map +1 -0
- package/dist/packages/core/test/unit/empty-attempt.test.js +79 -0
- package/dist/packages/core/test/unit/empty-attempt.test.js.map +1 -0
- package/dist/packages/core/test/unit/gherkin-dialects.test.js +115 -0
- package/dist/packages/core/test/unit/gherkin-dialects.test.js.map +1 -0
- package/dist/packages/core/test/unit/gherkin-keyword-case.test.js +110 -0
- package/dist/packages/core/test/unit/gherkin-keyword-case.test.js.map +1 -0
- package/dist/packages/core/test/unit/gherkin-quality.test.js +151 -0
- package/dist/packages/core/test/unit/gherkin-quality.test.js.map +1 -0
- package/dist/packages/core/test/unit/gherkin-tags.test.js +127 -0
- package/dist/packages/core/test/unit/gherkin-tags.test.js.map +1 -0
- package/dist/packages/core/test/unit/git-safety.test.js +104 -0
- package/dist/packages/core/test/unit/git-safety.test.js.map +1 -0
- package/dist/packages/core/test/unit/harness-report.test.js +192 -0
- package/dist/packages/core/test/unit/harness-report.test.js.map +1 -0
- package/dist/packages/core/test/unit/harness-roles.test.js +86 -0
- package/dist/packages/core/test/unit/harness-roles.test.js.map +1 -0
- package/dist/packages/core/test/unit/inbound-change.test.js +145 -0
- package/dist/packages/core/test/unit/inbound-change.test.js.map +1 -0
- package/dist/packages/core/test/unit/matrix-dependencies.test.js +100 -0
- package/dist/packages/core/test/unit/matrix-dependencies.test.js.map +1 -0
- package/dist/packages/core/test/unit/profile-match.test.js +115 -0
- package/dist/packages/core/test/unit/profile-match.test.js.map +1 -0
- package/dist/packages/core/test/unit/reconciliation.test.js +112 -0
- package/dist/packages/core/test/unit/reconciliation.test.js.map +1 -0
- package/dist/packages/core/test/unit/requirement-readiness.test.js +161 -0
- package/dist/packages/core/test/unit/requirement-readiness.test.js.map +1 -0
- package/dist/packages/core/test/unit/resume-state.test.js +124 -0
- package/dist/packages/core/test/unit/resume-state.test.js.map +1 -0
- package/dist/packages/core/test/unit/run-budget.test.js +113 -0
- package/dist/packages/core/test/unit/run-budget.test.js.map +1 -0
- package/dist/packages/core/test/unit/traceability-merge.test.js +159 -0
- package/dist/packages/core/test/unit/traceability-merge.test.js.map +1 -0
- package/dist/packages/core/test/unit/validate-project.test.js +156 -0
- package/dist/packages/core/test/unit/validate-project.test.js.map +1 -0
- package/dist/packages/core/test/unit/value-annotations.test.js +149 -0
- package/dist/packages/core/test/unit/value-annotations.test.js.map +1 -0
- package/dist/packages/core/test/unit/write-scope.test.js +165 -0
- package/dist/packages/core/test/unit/write-scope.test.js.map +1 -0
- package/dist/packages/core/test/unit/yaml-lite.test.js +78 -0
- package/dist/packages/core/test/unit/yaml-lite.test.js.map +1 -0
- package/dist/scripts/adopt_project.js +11 -0
- package/dist/scripts/adopt_project.js.map +1 -0
- package/dist/scripts/agents/commands.js +100 -0
- package/dist/scripts/agents/commands.js.map +1 -0
- package/dist/scripts/agents/init.js +482 -0
- package/dist/scripts/agents/init.js.map +1 -0
- package/dist/scripts/alm/cli.js +154 -0
- package/dist/scripts/alm/cli.js.map +1 -0
- package/dist/scripts/alm/clients.js +30 -0
- package/dist/scripts/alm/clients.js.map +1 -0
- package/dist/scripts/alm/core.js +258 -0
- package/dist/scripts/alm/core.js.map +1 -0
- package/dist/scripts/alm/port.js +116 -0
- package/dist/scripts/alm/port.js.map +1 -0
- package/dist/scripts/alm/providers/azure.js +79 -0
- package/dist/scripts/alm/providers/azure.js.map +1 -0
- package/dist/scripts/alm/providers/github.js +124 -0
- package/dist/scripts/alm/providers/github.js.map +1 -0
- package/dist/scripts/alm/providers/http-client.js +47 -0
- package/dist/scripts/alm/providers/http-client.js.map +1 -0
- package/dist/scripts/alm/providers/index.js +107 -0
- package/dist/scripts/alm/providers/index.js.map +1 -0
- package/dist/scripts/alm/providers/jira.js +129 -0
- package/dist/scripts/alm/providers/jira.js.map +1 -0
- package/dist/scripts/bundle_pack.js +10 -0
- package/dist/scripts/bundle_pack.js.map +1 -0
- package/dist/scripts/change/archive.js +68 -0
- package/dist/scripts/change/archive.js.map +1 -0
- package/dist/scripts/change/artifacts.js +143 -0
- package/dist/scripts/change/artifacts.js.map +1 -0
- package/dist/scripts/change/cli.js +39 -0
- package/dist/scripts/change/cli.js.map +1 -0
- package/dist/scripts/change/delta.js +20 -0
- package/dist/scripts/change/delta.js.map +1 -0
- package/dist/scripts/change/instructions.js +339 -0
- package/dist/scripts/change/instructions.js.map +1 -0
- package/dist/scripts/ci_init.js +12 -0
- package/dist/scripts/ci_init.js.map +1 -0
- package/dist/scripts/cli/commands/alm/PullCommand.js +238 -0
- package/dist/scripts/cli/commands/alm/PullCommand.js.map +1 -0
- package/dist/scripts/cli/commands/change/ChangeCommand.js +867 -0
- package/dist/scripts/cli/commands/change/ChangeCommand.js.map +1 -0
- package/dist/scripts/cli/commands/config/CiInitCommand.js +144 -0
- package/dist/scripts/cli/commands/config/CiInitCommand.js.map +1 -0
- package/dist/scripts/cli/commands/config/CompletionCommand.js +160 -0
- package/dist/scripts/cli/commands/config/CompletionCommand.js.map +1 -0
- package/dist/scripts/cli/commands/config/ConfigInitCommand.js +108 -0
- package/dist/scripts/cli/commands/config/ConfigInitCommand.js.map +1 -0
- package/dist/scripts/cli/commands/config/ConfigSetCommand.js +166 -0
- package/dist/scripts/cli/commands/config/ConfigSetCommand.js.map +1 -0
- package/dist/scripts/cli/commands/config/GenAgentContractCommand.js +212 -0
- package/dist/scripts/cli/commands/config/GenAgentContractCommand.js.map +1 -0
- package/dist/scripts/cli/commands/harness/RunCommand.js +1922 -0
- package/dist/scripts/cli/commands/harness/RunCommand.js.map +1 -0
- package/dist/scripts/cli/commands/mcp/McpInstallCommand.js +114 -0
- package/dist/scripts/cli/commands/mcp/McpInstallCommand.js.map +1 -0
- package/dist/scripts/cli/commands/mcp/index.js +29 -0
- package/dist/scripts/cli/commands/mcp/index.js.map +1 -0
- package/dist/scripts/cli/commands/pack/BundlePackCommand.js +59 -0
- package/dist/scripts/cli/commands/pack/BundlePackCommand.js.map +1 -0
- package/dist/scripts/cli/commands/pack/ExpandDomainPackCommand.js +559 -0
- package/dist/scripts/cli/commands/pack/ExpandDomainPackCommand.js.map +1 -0
- package/dist/scripts/cli/commands/pack/InferPackCommand.js +304 -0
- package/dist/scripts/cli/commands/pack/InferPackCommand.js.map +1 -0
- package/dist/scripts/cli/commands/pack/InitPackCommand.js +368 -0
- package/dist/scripts/cli/commands/pack/InitPackCommand.js.map +1 -0
- package/dist/scripts/cli/commands/pack/LintPackCommand.js +631 -0
- package/dist/scripts/cli/commands/pack/LintPackCommand.js.map +1 -0
- package/dist/scripts/cli/commands/pack/pack-args.js +83 -0
- package/dist/scripts/cli/commands/pack/pack-args.js.map +1 -0
- package/dist/scripts/cli/commands/project/AdoptCommand.js +414 -0
- package/dist/scripts/cli/commands/project/AdoptCommand.js.map +1 -0
- package/dist/scripts/cli/commands/project/InitFromPackCommand.js +188 -0
- package/dist/scripts/cli/commands/project/InitFromPackCommand.js.map +1 -0
- package/dist/scripts/cli/commands/project/InitProjectCommand.js +791 -0
- package/dist/scripts/cli/commands/project/InitProjectCommand.js.map +1 -0
- package/dist/scripts/cli/commands/project/OnboardCommand.js +655 -0
- package/dist/scripts/cli/commands/project/OnboardCommand.js.map +1 -0
- package/dist/scripts/cli/commands/project/UpdateCommand.js +206 -0
- package/dist/scripts/cli/commands/project/UpdateCommand.js.map +1 -0
- package/dist/scripts/cli/commands/project/WizardCommand.js +166 -0
- package/dist/scripts/cli/commands/project/WizardCommand.js.map +1 -0
- package/dist/scripts/cli/commands/quality/DoctorCommand.js +553 -0
- package/dist/scripts/cli/commands/quality/DoctorCommand.js.map +1 -0
- package/dist/scripts/cli/commands/quality/FixCommand.js +201 -0
- package/dist/scripts/cli/commands/quality/FixCommand.js.map +1 -0
- package/dist/scripts/cli/commands/quality/LicenseCheckCommand.js +187 -0
- package/dist/scripts/cli/commands/quality/LicenseCheckCommand.js.map +1 -0
- package/dist/scripts/cli/commands/quality/ReportCommand.js +557 -0
- package/dist/scripts/cli/commands/quality/ReportCommand.js.map +1 -0
- package/dist/scripts/cli/commands/quality/ValidateSpecsCommand.js +764 -0
- package/dist/scripts/cli/commands/quality/ValidateSpecsCommand.js.map +1 -0
- package/dist/scripts/cli/commands/spec/DoneCommand.js +116 -0
- package/dist/scripts/cli/commands/spec/DoneCommand.js.map +1 -0
- package/dist/scripts/cli/commands/spec/PlanCommand.js +397 -0
- package/dist/scripts/cli/commands/spec/PlanCommand.js.map +1 -0
- package/dist/scripts/cli/commands/spec/ReqCommand.js +303 -0
- package/dist/scripts/cli/commands/spec/ReqCommand.js.map +1 -0
- package/dist/scripts/cli/commands/spec/StatusCommand.js +206 -0
- package/dist/scripts/cli/commands/spec/StatusCommand.js.map +1 -0
- package/dist/scripts/cli/commands/spec/StudioCommand.js +241 -0
- package/dist/scripts/cli/commands/spec/StudioCommand.js.map +1 -0
- package/dist/scripts/cli/commands/specops/ContributeCommand.js +313 -0
- package/dist/scripts/cli/commands/specops/ContributeCommand.js.map +1 -0
- package/dist/scripts/cli/commands/specops/DiffCommand.js +394 -0
- package/dist/scripts/cli/commands/specops/DiffCommand.js.map +1 -0
- package/dist/scripts/cli/commands/specops/SyncCommand.js +380 -0
- package/dist/scripts/cli/commands/specops/SyncCommand.js.map +1 -0
- package/dist/scripts/completion.js +24 -0
- package/dist/scripts/completion.js.map +1 -0
- package/dist/scripts/config_init.js +12 -0
- package/dist/scripts/config_init.js.map +1 -0
- package/dist/scripts/config_set.js +20 -0
- package/dist/scripts/config_set.js.map +1 -0
- package/dist/scripts/docs/blocks.js +137 -0
- package/dist/scripts/docs/blocks.js.map +1 -0
- package/dist/scripts/docs/build-site.js +425 -0
- package/dist/scripts/docs/build-site.js.map +1 -0
- package/dist/scripts/docs/nav.js +198 -0
- package/dist/scripts/docs/nav.js.map +1 -0
- package/dist/scripts/docs/record-terminal.js +477 -0
- package/dist/scripts/docs/record-terminal.js.map +1 -0
- package/dist/scripts/docs/terminal-storyboard.js +121 -0
- package/dist/scripts/docs/terminal-storyboard.js.map +1 -0
- package/dist/scripts/doctor.js +14 -0
- package/dist/scripts/doctor.js.map +1 -0
- package/dist/scripts/done.js +17 -0
- package/dist/scripts/done.js.map +1 -0
- package/dist/scripts/expand_domain_pack.js +18 -0
- package/dist/scripts/expand_domain_pack.js.map +1 -0
- package/dist/scripts/fix.js +12 -0
- package/dist/scripts/fix.js.map +1 -0
- package/dist/scripts/gen_agent_contract.js +14 -0
- package/dist/scripts/gen_agent_contract.js.map +1 -0
- package/dist/scripts/gen_mcp_tools.js +264 -0
- package/dist/scripts/gen_mcp_tools.js.map +1 -0
- package/dist/scripts/harness/init.js +358 -0
- package/dist/scripts/harness/init.js.map +1 -0
- package/dist/scripts/harness/prompt.js +18 -0
- package/dist/scripts/harness/prompt.js.map +1 -0
- package/dist/scripts/harness/report.js +323 -0
- package/dist/scripts/harness/report.js.map +1 -0
- package/dist/scripts/harness/run.js +33 -0
- package/dist/scripts/harness/run.js.map +1 -0
- package/dist/scripts/infer_pack.js +17 -0
- package/dist/scripts/infer_pack.js.map +1 -0
- package/dist/scripts/init_from_pack.js +16 -0
- package/dist/scripts/init_from_pack.js.map +1 -0
- package/dist/scripts/init_pack.js +16 -0
- package/dist/scripts/init_pack.js.map +1 -0
- package/dist/scripts/init_project.js +17 -0
- package/dist/scripts/init_project.js.map +1 -0
- package/dist/scripts/lib/agent.js +99 -0
- package/dist/scripts/lib/agent.js.map +1 -0
- package/dist/scripts/lib/capability-specs.js +80 -0
- package/dist/scripts/lib/capability-specs.js.map +1 -0
- package/dist/scripts/lib/command.js +17 -0
- package/dist/scripts/lib/command.js.map +1 -0
- package/dist/scripts/lib/diagnostics.js +62 -0
- package/dist/scripts/lib/diagnostics.js.map +1 -0
- package/dist/scripts/lib/monorepo-fanout.js +118 -0
- package/dist/scripts/lib/monorepo-fanout.js.map +1 -0
- package/dist/scripts/lib/placeholders.js +190 -0
- package/dist/scripts/lib/placeholders.js.map +1 -0
- package/dist/scripts/lib/project-root.js +124 -0
- package/dist/scripts/lib/project-root.js.map +1 -0
- package/dist/scripts/lib/requirement-graph.js +31 -0
- package/dist/scripts/lib/requirement-graph.js.map +1 -0
- package/dist/scripts/lib/surface.js +609 -0
- package/dist/scripts/lib/surface.js.map +1 -0
- package/dist/scripts/license_check.js +15 -0
- package/dist/scripts/license_check.js.map +1 -0
- package/dist/scripts/lint_pack.js +18 -0
- package/dist/scripts/lint_pack.js.map +1 -0
- package/dist/scripts/merge-traceability.js +106 -0
- package/dist/scripts/merge-traceability.js.map +1 -0
- package/dist/scripts/onboard.js +22 -0
- package/dist/scripts/onboard.js.map +1 -0
- package/dist/scripts/plan.js +17 -0
- package/dist/scripts/plan.js.map +1 -0
- package/dist/scripts/plugin/gate-hook.js +171 -0
- package/dist/scripts/plugin/gate-hook.js.map +1 -0
- package/dist/scripts/report.js +17 -0
- package/dist/scripts/report.js.map +1 -0
- package/dist/scripts/req.js +22 -0
- package/dist/scripts/req.js.map +1 -0
- package/dist/scripts/schema/cli.js +215 -0
- package/dist/scripts/schema/cli.js.map +1 -0
- package/dist/scripts/schema/registry.js +264 -0
- package/dist/scripts/schema/registry.js.map +1 -0
- package/dist/scripts/specops/add.js +180 -0
- package/dist/scripts/specops/add.js.map +1 -0
- package/dist/scripts/specops/against_lock.js +100 -0
- package/dist/scripts/specops/against_lock.js.map +1 -0
- package/dist/scripts/specops/as_change.js +49 -0
- package/dist/scripts/specops/as_change.js.map +1 -0
- package/dist/scripts/specops/contribute.js +24 -0
- package/dist/scripts/specops/contribute.js.map +1 -0
- package/dist/scripts/specops/diff.js +32 -0
- package/dist/scripts/specops/diff.js.map +1 -0
- package/dist/scripts/specops/lock.js +39 -0
- package/dist/scripts/specops/lock.js.map +1 -0
- package/dist/scripts/specops/manifest.js +90 -0
- package/dist/scripts/specops/manifest.js.map +1 -0
- package/dist/scripts/specops/remove.js +102 -0
- package/dist/scripts/specops/remove.js.map +1 -0
- package/dist/scripts/specops/sync.js +27 -0
- package/dist/scripts/specops/sync.js.map +1 -0
- package/dist/scripts/specops/verify.js +149 -0
- package/dist/scripts/specops/verify.js.map +1 -0
- package/dist/scripts/status.js +17 -0
- package/dist/scripts/status.js.map +1 -0
- package/dist/scripts/studio.js +14 -0
- package/dist/scripts/studio.js.map +1 -0
- package/dist/scripts/update.js +17 -0
- package/dist/scripts/update.js.map +1 -0
- package/dist/scripts/validate_specs.js +10 -0
- package/dist/scripts/validate_specs.js.map +1 -0
- package/examples/project.config.example +19 -0
- package/examples/project.yaml.example +17 -0
- package/package.json +105 -0
- package/templates/adopt/AI_RULES.md.tpl +27 -0
- package/templates/adopt/adr-readme.md.tpl +5 -0
- package/templates/adopt/baseline.feature.tpl +9 -0
- package/templates/adopt/spec.md.tpl +25 -0
- package/templates/adopt/traceability.md.tpl +11 -0
- package/templates/backend/AI_RULES.md.tpl +35 -0
- package/templates/backend/features/core/health.feature.tpl +7 -0
- package/templates/base/.devcontainer/devcontainer.json.tpl +18 -0
- package/templates/base/.dockerignore.tpl +11 -0
- package/templates/base/.env.dev.app.tpl +13 -0
- package/templates/base/.env.dev.infra.tpl +6 -0
- package/templates/base/.env.dev.tpl +16 -0
- package/templates/base/.env.example.tpl +17 -0
- package/templates/base/.env.feature.app.tpl +11 -0
- package/templates/base/.env.feature.infra.tpl +4 -0
- package/templates/base/.env.feature.tpl +16 -0
- package/templates/base/.env.prod.app.tpl +13 -0
- package/templates/base/.env.prod.infra.tpl +6 -0
- package/templates/base/.env.prod.tpl +16 -0
- package/templates/base/.github/workflows/specs.yml.tpl +26 -0
- package/templates/base/.gitignore.tpl +9 -0
- package/templates/base/.pre-commit-config.yaml.tpl +10 -0
- package/templates/base/AGENTS.md.tpl +32 -0
- package/templates/base/README.md.tpl +32 -0
- package/templates/base/docker-compose.yml.tpl +13 -0
- package/templates/base/docs/specs/adr/README.md.tpl +10 -0
- package/templates/base/docs/specs/aggregates.md.tpl +5 -0
- package/templates/base/docs/specs/commands.md.tpl +13 -0
- package/templates/base/docs/specs/domain-model.md.tpl +30 -0
- package/templates/base/docs/specs/events.md.tpl +5 -0
- package/templates/base/docs/specs/review-checklist.md.tpl +18 -0
- package/templates/base/docs/specs/runtime-environments.md.tpl +26 -0
- package/templates/base/docs/specs/status-model.md.tpl +16 -0
- package/templates/base/docs/specs/traceability.md.tpl +7 -0
- package/templates/base/docs/specs/use-cases.md.tpl +5 -0
- package/templates/base/spec.md.tpl +63 -0
- package/templates/ci/azure.yml.tpl +40 -0
- package/templates/ci/github.yml.tpl +40 -0
- package/templates/ci/gitlab.yml.tpl +21 -0
- package/templates/ci/jenkins.tpl +35 -0
- package/templates/contracts/AI_RULES.md.tpl +55 -0
- package/templates/contracts/asyncapi-stub.yaml.tpl +24 -0
- package/templates/contracts/contract-traceability.md.tpl +10 -0
- package/templates/contracts/openapi-stub.yaml.tpl +29 -0
- package/templates/contracts/pacts-gitkeep.tpl +0 -0
- package/templates/contracts/test-strategy.md.tpl +94 -0
- package/templates/frontend/AI_RULES.md.tpl +34 -0
- package/templates/frontend/features/core/health.feature.tpl +6 -0
- package/templates/harness/harness.config.yaml.tpl +74 -0
- package/templates/harness/prompt-prefix.md.tpl +60 -0
- package/templates/mobile/AI_RULES.md.tpl +56 -0
- package/templates/mobile/features/core/health.feature.tpl +7 -0
- package/templates/modules/auth/backend/registration_and_login.feature.tpl +10 -0
- package/templates/modules/auth/frontend/login.feature.tpl +5 -0
- package/templates/modules/billing/backend/billing_settlement.feature.tpl +5 -0
- package/templates/modules/billing/frontend/billing_summary.feature.tpl +5 -0
- package/templates/modules/dashboard/backend/dashboard_kpi.feature.tpl +5 -0
- package/templates/modules/dashboard/frontend/dashboard.feature.tpl +5 -0
- package/vendor/mermaid.min.js +3636 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Did the green diff touch what the matrix said it would? (A2)
|
|
4
|
+
*
|
|
5
|
+
* ## The lie this catches
|
|
6
|
+
*
|
|
7
|
+
* A matrix row declares `test_artifact` and `technical_artifact`, and the
|
|
8
|
+
* prompt hands both to the agent. Nothing checked that the diff contained them.
|
|
9
|
+
* An agent can implement somewhere else entirely, pass the scenario, and leave
|
|
10
|
+
* the matrix pointing at a file where the logic does not live — exactly the
|
|
11
|
+
* documentary lie this repository forbids itself in `AI_RULES.md`.
|
|
12
|
+
*
|
|
13
|
+
* ## Why this is a warning and not a gate
|
|
14
|
+
*
|
|
15
|
+
* There are legitimate cases. An implementation can land in a shared module
|
|
16
|
+
* that already exists, and the row naming the new module is still the honest
|
|
17
|
+
* summary. Turning that into a hard failure without evidence would be the kind
|
|
18
|
+
* of gate that rejects good work — which already cost two runs on REQ-002.
|
|
19
|
+
* `--strict-artifacts` is there for a project that wants the stricter reading.
|
|
20
|
+
*
|
|
21
|
+
* ## The part that decides whether any of this is usable
|
|
22
|
+
*
|
|
23
|
+
* Most declarations in a real matrix are **not paths**. The scaffolded row says
|
|
24
|
+
* `` `API /health`, smoke test `` and its test artifact says `TBD`. Comparing
|
|
25
|
+
* prose against a diff would report every scaffolded project as untouched,
|
|
26
|
+
* which is noise, and noise is how a warning gets ignored — the failure mode
|
|
27
|
+
* that made `--strict`-only rules useless in H14.
|
|
28
|
+
*
|
|
29
|
+
* So a declaration is only checked when it names something a diff could
|
|
30
|
+
* plausibly contain. Everything else is skipped in silence: this module reports
|
|
31
|
+
* what it can substantiate, and nothing else.
|
|
32
|
+
*/
|
|
33
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
+
exports.ARTIFACT_CODES = void 0;
|
|
35
|
+
exports.looksLikePath = looksLikePath;
|
|
36
|
+
exports.declaredPaths = declaredPaths;
|
|
37
|
+
exports.checkDeclaredArtifacts = checkDeclaredArtifacts;
|
|
38
|
+
const Diagnostic_1 = require("./Diagnostic");
|
|
39
|
+
exports.ARTIFACT_CODES = Object.freeze({
|
|
40
|
+
UNTOUCHED: "declared_artifact_untouched",
|
|
41
|
+
});
|
|
42
|
+
/**
|
|
43
|
+
* Does this fragment name a file rather than describe one?
|
|
44
|
+
*
|
|
45
|
+
* The rule: no whitespace, and either a directory separator or a file
|
|
46
|
+
* extension. `src/App.java` and `App.java` qualify; `API /health`, `smoke test`
|
|
47
|
+
* and `TBD` do not. It is a heuristic, and it is deliberately biased towards
|
|
48
|
+
* saying no — a missed check costs a warning nobody sees, while a false one
|
|
49
|
+
* teaches people that this warning is wrong and should be ignored.
|
|
50
|
+
*/
|
|
51
|
+
function looksLikePath(fragment) {
|
|
52
|
+
const value = fragment.trim();
|
|
53
|
+
if (!value)
|
|
54
|
+
return false;
|
|
55
|
+
if (/\s/.test(value))
|
|
56
|
+
return false;
|
|
57
|
+
if (/^(TBD|TODO|N\/A|-|—)$/i.test(value))
|
|
58
|
+
return false;
|
|
59
|
+
return value.includes("/") || /\.[A-Za-z0-9]{1,10}$/.test(value);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The file paths a matrix cell declares.
|
|
63
|
+
*
|
|
64
|
+
* A cell is markdown written by a person: back-ticked, comma-separated, and
|
|
65
|
+
* frequently part path and part prose — `` `src/Health.java`, smoke test ``
|
|
66
|
+
* declares one path and one intention. Both halves are kept apart rather than
|
|
67
|
+
* forcing the cell to be all one or all the other.
|
|
68
|
+
*/
|
|
69
|
+
function declaredPaths(cell) {
|
|
70
|
+
if (!cell)
|
|
71
|
+
return [];
|
|
72
|
+
return String(cell)
|
|
73
|
+
.split(",")
|
|
74
|
+
.map((part) => part.replace(/`/g, "").trim())
|
|
75
|
+
.filter((part) => looksLikePath(part))
|
|
76
|
+
.map((part) => part.replace(/\\/g, "/").replace(/^\.\//, ""));
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* A declared path counts as touched when the diff contains it, or contains
|
|
80
|
+
* something inside it — a row may name a directory (`src/health/`) and the work
|
|
81
|
+
* lands on files within.
|
|
82
|
+
*/
|
|
83
|
+
function wasTouched(declared, touched) {
|
|
84
|
+
const target = declared.replace(/\/$/, "");
|
|
85
|
+
return touched.some((path) => path === target || path.startsWith(`${target}/`) || path.endsWith(`/${target}`));
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Declared artifacts the diff never went near.
|
|
89
|
+
*
|
|
90
|
+
* `strict` promotes the finding to an error. Default is a warning, deliberately
|
|
91
|
+
* — see the module note.
|
|
92
|
+
*/
|
|
93
|
+
function checkDeclaredArtifacts(input, strict = false) {
|
|
94
|
+
const target = input.requirement || "";
|
|
95
|
+
const found = [];
|
|
96
|
+
const raise = strict ? Diagnostic_1.error : Diagnostic_1.warning;
|
|
97
|
+
const kinds = [
|
|
98
|
+
["test", input.testArtifact],
|
|
99
|
+
["production", input.technicalArtifact],
|
|
100
|
+
];
|
|
101
|
+
for (const [kind, cell] of kinds) {
|
|
102
|
+
for (const declared of declaredPaths(cell)) {
|
|
103
|
+
if (wasTouched(declared, input.touched))
|
|
104
|
+
continue;
|
|
105
|
+
found.push(raise(exports.ARTIFACT_CODES.UNTOUCHED, `the matrix declares \`${declared}\` as this requirement's ${kind} artifact, ` +
|
|
106
|
+
`but the diff never touches it.`, {
|
|
107
|
+
target,
|
|
108
|
+
// `--code`, not `--impl`: the flag is verified against ReqCommand.
|
|
109
|
+
// A fix naming a flag that does not exist is worse than no fix.
|
|
110
|
+
fix: `Either implement it there, or correct the row: ` +
|
|
111
|
+
`\`specgate req link ${target || "<REQ>"} --${kind === "test" ? "test" : "code"} <path>\`.`,
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return found;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=DeclaredArtifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeclaredArtifacts.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/DeclaredArtifacts.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;;;AAkBH,sCAMC;AAUD,sCAOC;AA6BD,wDAmCC;AAtGD,6CAA8C;AAEjC,QAAA,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1C,SAAS,EAAE,6BAA6B;CACzC,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,SAAgB,aAAa,CAAC,QAAgB;IAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,IAAI,wBAAwB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACvD,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACnE,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,aAAa,CAAC,IAA+B;IAC3D,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,OAAO,MAAM,CAAC,IAAI,CAAC;SAChB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;SAC5C,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;SACrC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAClE,CAAC;AAWD;;;;GAIG;AACH,SAAS,UAAU,CAAC,QAAgB,EAAE,OAA0B;IAC9D,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC3C,OAAO,OAAO,CAAC,IAAI,CACjB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,EAAE,CAAC,CAC1F,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,sBAAsB,CACpC,KAA6B,EAC7B,MAAM,GAAG,KAAK;IAEd,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC;IACvC,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,kBAAK,CAAC,CAAC,CAAC,oBAAO,CAAC;IAEvC,MAAM,KAAK,GAA+C;QACxD,CAAC,MAAM,EAAE,KAAK,CAAC,YAAY,CAAC;QAC5B,CAAC,YAAY,EAAE,KAAK,CAAC,iBAAiB,CAAC;KACxC,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;QACjC,KAAK,MAAM,QAAQ,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,IAAI,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC;gBAAE,SAAS;YAClD,KAAK,CAAC,IAAI,CACR,KAAK,CACH,sBAAc,CAAC,SAAS,EACxB,yBAAyB,QAAQ,4BAA4B,IAAI,aAAa;gBAC5E,gCAAgC,EAClC;gBACE,MAAM;gBACN,mEAAmE;gBACnE,gEAAgE;gBAChE,GAAG,EACD,iDAAiD;oBACjD,uBAAuB,MAAM,IAAI,OAAO,MAAM,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,YAAY;aAC9F,CACF,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DeltaSpec = exports.GHERKIN_STEP = exports.VALID_SECTIONS = void 0;
|
|
4
|
+
exports.isPlaceholderStep = isPlaceholderStep;
|
|
5
|
+
const SpecParser_1 = require("./SpecParser");
|
|
6
|
+
const Diagnostic_1 = require("./Diagnostic");
|
|
7
|
+
// RFC2119 lives in RequirementSyntax.ts now (F6) — this is the only importer,
|
|
8
|
+
// so nothing needs a re-export.
|
|
9
|
+
const RequirementSyntax_1 = require("./RequirementSyntax");
|
|
10
|
+
exports.VALID_SECTIONS = [
|
|
11
|
+
"## Purpose",
|
|
12
|
+
"## ADDED Requirements",
|
|
13
|
+
"## MODIFIED Requirements",
|
|
14
|
+
"## REMOVED Requirements",
|
|
15
|
+
];
|
|
16
|
+
exports.GHERKIN_STEP = /^\s*(GIVEN|WHEN|THEN|AND|BUT|DADO|CUANDO|ENTONCES|Y)\b/i;
|
|
17
|
+
/**
|
|
18
|
+
* A step that names a keyword and then says nothing.
|
|
19
|
+
*
|
|
20
|
+
* `GIVEN <!-- the precondition -->` and `WHEN TODO` are Gherkin by shape and
|
|
21
|
+
* empty by content. They are what a generator writes when it has no acceptance
|
|
22
|
+
* criterion to offer — `alm pull` writes them deliberately — and what a person
|
|
23
|
+
* writes when they mean to come back later.
|
|
24
|
+
*/
|
|
25
|
+
function isPlaceholderStep(step) {
|
|
26
|
+
// `(?:[^-]|-(?!->))*` instead of a lazy `[\s\S]*?`: it consumes without ever
|
|
27
|
+
// needing to backtrack, which is the difference between linear and quadratic
|
|
28
|
+
// on a step that contains many dashes.
|
|
29
|
+
const withoutComments = String(step).replace(/<!--(?:[^-]|-(?!->))*-->/g, " ");
|
|
30
|
+
// The parser hands steps over without their bullet, but this is exported and
|
|
31
|
+
// a caller may well pass the raw line, so both forms have to read the same.
|
|
32
|
+
const withoutBullet = withoutComments.replace(/^\s*[-*]\s*/, "");
|
|
33
|
+
const body = withoutBullet.replace(exports.GHERKIN_STEP, "").trim();
|
|
34
|
+
if (body === "")
|
|
35
|
+
return true;
|
|
36
|
+
return /^(todo|tbd|\.\.\.|…|<[^>]*>)$/i.test(body);
|
|
37
|
+
}
|
|
38
|
+
class DeltaSpec {
|
|
39
|
+
static validate(deltaSource, opts) {
|
|
40
|
+
const o = opts || {};
|
|
41
|
+
const file = o.file || "spec.md";
|
|
42
|
+
const diags = [];
|
|
43
|
+
const delta = (0, SpecParser_1.parseDelta)(deltaSource);
|
|
44
|
+
for (const unknown of delta.unknownSections) {
|
|
45
|
+
diags.push((0, Diagnostic_1.error)("delta_unknown_section", `Unknown delta section: "## ${unknown.heading}".`, {
|
|
46
|
+
file,
|
|
47
|
+
line: unknown.line,
|
|
48
|
+
target: unknown.heading,
|
|
49
|
+
fix: `Use one of: ${exports.VALID_SECTIONS.join(", ")}.`,
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
const all = [...delta.added, ...delta.modified, ...delta.removed];
|
|
53
|
+
if (all.length === 0 && !delta.purpose) {
|
|
54
|
+
diags.push((0, Diagnostic_1.error)("delta_empty", "Delta declares no requirement changes and no Purpose.", {
|
|
55
|
+
file,
|
|
56
|
+
fix: "Add a `## ADDED Requirements` section, or delete the delta file.",
|
|
57
|
+
}));
|
|
58
|
+
}
|
|
59
|
+
const seen = new Map();
|
|
60
|
+
for (const req of all) {
|
|
61
|
+
const key = (0, SpecParser_1.requirementKey)(req);
|
|
62
|
+
if (seen.has(key)) {
|
|
63
|
+
diags.push((0, Diagnostic_1.error)("duplicate_requirement", `Requirement "${req.heading}" appears more than once in this delta.`, {
|
|
64
|
+
file,
|
|
65
|
+
line: req.line,
|
|
66
|
+
target: key,
|
|
67
|
+
fix: `Merge the two blocks; the first one is at line ${seen.get(key)}.`,
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
seen.set(key, req.line);
|
|
72
|
+
}
|
|
73
|
+
if (req.id && !SpecParser_1.REQ_ID.test(req.id)) {
|
|
74
|
+
diags.push((0, Diagnostic_1.error)("invalid_requirement_id", `"${req.id}" is not a valid requirement id.`, {
|
|
75
|
+
file,
|
|
76
|
+
line: req.line,
|
|
77
|
+
target: req.id,
|
|
78
|
+
fix: "Use the form REQ-NNN, e.g. REQ-014 — or drop the id entirely.",
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
for (const req of [...delta.added, ...delta.modified]) {
|
|
83
|
+
if (!req.scenarios || req.scenarios.length === 0) {
|
|
84
|
+
diags.push((0, Diagnostic_1.error)("requirement_without_scenario", `Requirement "${req.name}" has no scenario, so "done" is undefined.`, {
|
|
85
|
+
file,
|
|
86
|
+
line: req.line,
|
|
87
|
+
target: (0, SpecParser_1.requirementKey)(req),
|
|
88
|
+
fix: "Add a `#### Scenario:` block with GIVEN / WHEN / THEN steps.",
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
for (const sc of req.scenarios || []) {
|
|
92
|
+
if (!sc.steps || sc.steps.length === 0) {
|
|
93
|
+
diags.push((0, Diagnostic_1.error)("scenario_without_steps", `Scenario "${sc.name}" has no steps.`, {
|
|
94
|
+
file,
|
|
95
|
+
line: sc.line,
|
|
96
|
+
target: sc.name,
|
|
97
|
+
fix: "Add `- GIVEN …`, `- WHEN …`, `- THEN …` bullets under the scenario.",
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
else if (sc.steps.every((s) => isPlaceholderStep(s))) {
|
|
101
|
+
// Every step is a keyword with nothing behind it — `GIVEN <!-- the
|
|
102
|
+
// precondition -->`, or a bare `WHEN TODO`. These pass the checks
|
|
103
|
+
// above because they *are* Gherkin, and that is the problem: the
|
|
104
|
+
// scenario satisfies the gate without describing any behaviour, which
|
|
105
|
+
// turns the gate from a check into a formality.
|
|
106
|
+
//
|
|
107
|
+
// ADR-0021 rejected exactly this shape when it refused to import
|
|
108
|
+
// tickets with placeholder scenarios. `alm pull` writes deltas in
|
|
109
|
+
// precisely this state on purpose, so the gate has to be the thing
|
|
110
|
+
// that keeps them from being archived.
|
|
111
|
+
diags.push((0, Diagnostic_1.error)("scenario_steps_unwritten", `Scenario "${sc.name}" has placeholder steps, so it asserts nothing.`, {
|
|
112
|
+
file,
|
|
113
|
+
line: sc.line,
|
|
114
|
+
target: sc.name,
|
|
115
|
+
fix: "Write what actually has to hold: `- GIVEN a customer on the flat tariff`, not `- GIVEN <!-- the precondition -->`.",
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
else if (!sc.steps.some((s) => exports.GHERKIN_STEP.test(s))) {
|
|
119
|
+
diags.push((0, Diagnostic_1.warning)("scenario_not_gherkin", `Scenario "${sc.name}" has no GIVEN/WHEN/THEN step, so it cannot generate a .feature.`, {
|
|
120
|
+
file,
|
|
121
|
+
line: sc.line,
|
|
122
|
+
target: sc.name,
|
|
123
|
+
fix: "Start each step with GIVEN, WHEN, THEN or AND.",
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const requirementText = (0, SpecParser_1.blockText)(req.text);
|
|
128
|
+
if (requirementText && !RequirementSyntax_1.RFC2119.test(requirementText)) {
|
|
129
|
+
diags.push((0, Diagnostic_1.warning)("no_rfc2119_keyword", `Requirement "${req.name}" states no obligation (SHALL / MUST / SHOULD / MAY).`, {
|
|
130
|
+
file,
|
|
131
|
+
line: req.line,
|
|
132
|
+
target: (0, SpecParser_1.requirementKey)(req),
|
|
133
|
+
fix: 'Rewrite the body as "The system SHALL …".',
|
|
134
|
+
}));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (o.specSource !== undefined && o.specSource !== null) {
|
|
138
|
+
const spec = (0, SpecParser_1.parseSpec)(o.specSource);
|
|
139
|
+
const existing = new Set(spec.requirements.map((r) => (0, SpecParser_1.requirementKey)(r)));
|
|
140
|
+
for (const req of delta.added) {
|
|
141
|
+
if (existing.has((0, SpecParser_1.requirementKey)(req))) {
|
|
142
|
+
diags.push((0, Diagnostic_1.error)("requirement_already_exists", `ADDED requirement "${req.heading}" already exists in the capability spec.`, {
|
|
143
|
+
file,
|
|
144
|
+
line: req.line,
|
|
145
|
+
target: (0, SpecParser_1.requirementKey)(req),
|
|
146
|
+
fix: "Move the block to `## MODIFIED Requirements`.",
|
|
147
|
+
}));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
for (const req of [...delta.modified, ...delta.removed]) {
|
|
151
|
+
if (!existing.has((0, SpecParser_1.requirementKey)(req))) {
|
|
152
|
+
diags.push((0, Diagnostic_1.error)("unknown_requirement", `${req.op.toUpperCase()} requirement "${req.heading}" does not exist in the capability spec.`, {
|
|
153
|
+
file,
|
|
154
|
+
line: req.line,
|
|
155
|
+
target: (0, SpecParser_1.requirementKey)(req),
|
|
156
|
+
fix: req.op === "modified"
|
|
157
|
+
? "Move the block to `## ADDED Requirements`, or fix the heading to match the spec."
|
|
158
|
+
: "Remove the block — there is nothing to delete.",
|
|
159
|
+
}));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return { delta, diagnostics: diags };
|
|
164
|
+
}
|
|
165
|
+
static apply(specSource, deltaSource, opts) {
|
|
166
|
+
const o = opts || {};
|
|
167
|
+
const delta = (0, SpecParser_1.parseDelta)(deltaSource);
|
|
168
|
+
const spec = specSource
|
|
169
|
+
? (0, SpecParser_1.parseSpec)(specSource)
|
|
170
|
+
: { title: o.title || "Specification", purpose: "", requirements: [], sections: [] };
|
|
171
|
+
if (!specSource && delta.purpose)
|
|
172
|
+
spec.purpose = delta.purpose;
|
|
173
|
+
if (!spec.title)
|
|
174
|
+
spec.title = delta.title || o.title || "Specification";
|
|
175
|
+
const applied = { added: [], modified: [], removed: [] };
|
|
176
|
+
const byKey = new Map(spec.requirements.map((r) => [(0, SpecParser_1.requirementKey)(r), r]));
|
|
177
|
+
for (const req of delta.removed) {
|
|
178
|
+
const key = (0, SpecParser_1.requirementKey)(req);
|
|
179
|
+
if (byKey.has(key)) {
|
|
180
|
+
byKey.delete(key);
|
|
181
|
+
applied.removed.push(key);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
for (const req of delta.modified) {
|
|
185
|
+
const key = (0, SpecParser_1.requirementKey)(req);
|
|
186
|
+
if (byKey.has(key)) {
|
|
187
|
+
byKey.set(key, this.stripOp(req));
|
|
188
|
+
applied.modified.push(key);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
for (const req of delta.added) {
|
|
192
|
+
const key = (0, SpecParser_1.requirementKey)(req);
|
|
193
|
+
if (!byKey.has(key)) {
|
|
194
|
+
byKey.set(key, this.stripOp(req));
|
|
195
|
+
applied.added.push(key);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const order = spec.requirements
|
|
199
|
+
.map((r) => (0, SpecParser_1.requirementKey)(r))
|
|
200
|
+
.filter((k) => byKey.has(k));
|
|
201
|
+
for (const key of byKey.keys()) {
|
|
202
|
+
if (!order.includes(key))
|
|
203
|
+
order.push(key);
|
|
204
|
+
}
|
|
205
|
+
spec.requirements = order.map((k) => byKey.get(k));
|
|
206
|
+
return {
|
|
207
|
+
markdown: (0, SpecParser_1.renderSpec)(spec),
|
|
208
|
+
spec,
|
|
209
|
+
applied,
|
|
210
|
+
retired: spec.requirements.length === 0 && applied.removed.length > 0,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
static stripOp(req) {
|
|
214
|
+
const { op: _op, ...rest } = req;
|
|
215
|
+
return rest;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
exports.DeltaSpec = DeltaSpec;
|
|
219
|
+
//# sourceMappingURL=DeltaSpec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeltaSpec.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/DeltaSpec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The one diagnostic envelope every machine-readable surface of the CLI emits.
|
|
4
|
+
*
|
|
5
|
+
* { severity, code, message, target?, fix?, file?, line? }
|
|
6
|
+
*
|
|
7
|
+
* `code` is a stable snake_case string — callers (CI, agents, the VS Code
|
|
8
|
+
* extension) branch on it, never on the message text. `fix` is one actionable
|
|
9
|
+
* sentence or command; a diagnostic without a fix is a diagnostic the user
|
|
10
|
+
* cannot act on, so treat writing one as part of writing the check.
|
|
11
|
+
*
|
|
12
|
+
* Casing is camelCase everywhere in JSON output, decided once here so we do not
|
|
13
|
+
* inherit the snake/camel split that OpenSpec documents as a known defect.
|
|
14
|
+
*
|
|
15
|
+
* This module is the envelope and nothing else: no colours, no streams, no
|
|
16
|
+
* `process`. Rendering a diagnostic for a terminal is a delivery concern and
|
|
17
|
+
* lives in `scripts/lib/diagnostics`, which re-exports everything here.
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.info = exports.warning = exports.error = exports.SEVERITY = void 0;
|
|
21
|
+
exports.diagnostic = diagnostic;
|
|
22
|
+
exports.hasErrors = hasErrors;
|
|
23
|
+
exports.countBySeverity = countBySeverity;
|
|
24
|
+
exports.errorMessage = errorMessage;
|
|
25
|
+
exports.SEVERITY = Object.freeze({
|
|
26
|
+
ERROR: "error",
|
|
27
|
+
WARNING: "warning",
|
|
28
|
+
INFO: "info",
|
|
29
|
+
});
|
|
30
|
+
function diagnostic(severity, code, message, extra) {
|
|
31
|
+
const d = { severity, code, message };
|
|
32
|
+
if (extra) {
|
|
33
|
+
if (extra.target !== undefined)
|
|
34
|
+
d.target = extra.target;
|
|
35
|
+
if (extra.fix !== undefined)
|
|
36
|
+
d.fix = extra.fix;
|
|
37
|
+
if (extra.file !== undefined)
|
|
38
|
+
d.file = extra.file;
|
|
39
|
+
if (extra.line !== undefined && extra.line !== null)
|
|
40
|
+
d.line = extra.line;
|
|
41
|
+
}
|
|
42
|
+
return d;
|
|
43
|
+
}
|
|
44
|
+
const error = (code, message, extra) => diagnostic(exports.SEVERITY.ERROR, code, message, extra);
|
|
45
|
+
exports.error = error;
|
|
46
|
+
const warning = (code, message, extra) => diagnostic(exports.SEVERITY.WARNING, code, message, extra);
|
|
47
|
+
exports.warning = warning;
|
|
48
|
+
const info = (code, message, extra) => diagnostic(exports.SEVERITY.INFO, code, message, extra);
|
|
49
|
+
exports.info = info;
|
|
50
|
+
function hasErrors(diags) {
|
|
51
|
+
return (diags || []).some((d) => d.severity === exports.SEVERITY.ERROR);
|
|
52
|
+
}
|
|
53
|
+
function countBySeverity(diags) {
|
|
54
|
+
const out = { error: 0, warning: 0, info: 0 };
|
|
55
|
+
for (const d of diags || []) {
|
|
56
|
+
if (out[d.severity] !== undefined)
|
|
57
|
+
out[d.severity]++;
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The message of whatever was thrown.
|
|
63
|
+
*
|
|
64
|
+
* `catch (err)` appeared eleven times across `scripts/` purely to reach
|
|
65
|
+
* `.message`. A catch binding is genuinely `unknown` — anything can be thrown —
|
|
66
|
+
* so the honest form is to narrow it once, here.
|
|
67
|
+
*/
|
|
68
|
+
function errorMessage(err) {
|
|
69
|
+
if (err instanceof Error)
|
|
70
|
+
return err.message;
|
|
71
|
+
if (typeof err === "string")
|
|
72
|
+
return err;
|
|
73
|
+
return String(err);
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=Diagnostic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Diagnostic.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/Diagnostic.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;;;AA0BH,gCASC;AASD,8BAEC;AAED,0CAMC;AASD,oCAIC;AA/CY,QAAA,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;IACpC,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;CACb,CAAC,CAAC;AAEH,SAAgB,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,KAAuB;IACzE,MAAM,CAAC,GAAe,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAClD,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;YAAE,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QACxD,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS;YAAE,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;QAC/C,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;YAAE,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QAClD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI;YAAE,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IAC3E,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAEM,MAAM,KAAK,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,KAAuB,EAAE,EAAE,CAC9D,UAAU,CAAC,gBAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AADtC,QAAA,KAAK,SACiC;AAC5C,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,KAAuB,EAAE,EAAE,CAChE,UAAU,CAAC,gBAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AADxC,QAAA,OAAO,WACiC;AAC9C,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,KAAuB,EAAE,EAAE,CAC7D,UAAU,CAAC,gBAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AADrC,QAAA,IAAI,QACiC;AAElD,SAAgB,SAAS,CAAC,KAAK;IAC7B,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,gBAAQ,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC;AAED,SAAgB,eAAe,CAAC,KAAK;IACnC,MAAM,GAAG,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC9C,KAAK,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;QAC5B,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,SAAS;YAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;IACvD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,YAAY,CAAC,GAAY;IACvC,IAAI,GAAG,YAAY,KAAK;QAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IAC7C,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IACxC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DomainPack = void 0;
|
|
4
|
+
class DomainPack {
|
|
5
|
+
packId;
|
|
6
|
+
model;
|
|
7
|
+
version;
|
|
8
|
+
constructor(packId, model, version = "") {
|
|
9
|
+
this.packId = packId;
|
|
10
|
+
this.model = model;
|
|
11
|
+
this.version = version;
|
|
12
|
+
}
|
|
13
|
+
get requirements() {
|
|
14
|
+
return Array.isArray(this.model?.requirements) ? this.model.requirements : [];
|
|
15
|
+
}
|
|
16
|
+
get scenarios() {
|
|
17
|
+
return Array.isArray(this.model?.scenarios) ? this.model.scenarios : [];
|
|
18
|
+
}
|
|
19
|
+
getRequirementsById() {
|
|
20
|
+
const out = new Map();
|
|
21
|
+
for (const req of this.requirements) {
|
|
22
|
+
if (req && req.id)
|
|
23
|
+
out.set(String(req.id), req);
|
|
24
|
+
}
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
getScenariosByRequirement() {
|
|
28
|
+
const out = new Map();
|
|
29
|
+
for (const sc of this.scenarios) {
|
|
30
|
+
if (!sc || !sc.requirement_id)
|
|
31
|
+
continue;
|
|
32
|
+
const key = String(sc.requirement_id);
|
|
33
|
+
if (!out.has(key))
|
|
34
|
+
out.set(key, []);
|
|
35
|
+
out.get(key).push(sc);
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
static computeRequirementFingerprint(req, scenarios = []) {
|
|
40
|
+
const norm = (v) => String(v === undefined || v === null ? "" : v).trim();
|
|
41
|
+
const scenarioPart = (scenarios || [])
|
|
42
|
+
.map((sc) => [
|
|
43
|
+
norm(sc.id),
|
|
44
|
+
norm(sc.scenario),
|
|
45
|
+
norm(sc.use_case),
|
|
46
|
+
norm(sc.command),
|
|
47
|
+
norm(sc.aggregate),
|
|
48
|
+
(Array.isArray(sc.events) ? sc.events : []).map(norm).sort().join(","),
|
|
49
|
+
].join("|"))
|
|
50
|
+
.sort()
|
|
51
|
+
.join("\n");
|
|
52
|
+
return [
|
|
53
|
+
norm(req.title),
|
|
54
|
+
norm(req.description),
|
|
55
|
+
norm(req.priority),
|
|
56
|
+
norm(req.status),
|
|
57
|
+
scenarioPart,
|
|
58
|
+
].join("\n");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.DomainPack = DomainPack;
|
|
62
|
+
//# sourceMappingURL=DomainPack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DomainPack.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/DomainPack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Did the agent write anything at all? (H19)
|
|
4
|
+
*
|
|
5
|
+
* ## The defect this closes
|
|
6
|
+
*
|
|
7
|
+
* The harness gate runs *before* `specgate done`, so at gate time the requirement
|
|
8
|
+
* is still `Draft` — and `--strict-tdd`'s "no `Test Artifact = TBD` past
|
|
9
|
+
* Draft" rule does not apply to a Draft row. `done` then flips the status to
|
|
10
|
+
* `Implemented` and nothing validates again.
|
|
11
|
+
*
|
|
12
|
+
* Reproduced on 2026-08-26 against a freshly generated project, with
|
|
13
|
+
* `--agent "cat {prompt_file} > /dev/null"` — an agent that writes nothing:
|
|
14
|
+
*
|
|
15
|
+
* ✅ REQ-000 pass (1 attempt) → harness/REQ-000
|
|
16
|
+
*
|
|
17
|
+
* The branch carried the archived prompt and one changed line: the matrix row
|
|
18
|
+
* moved to `Implemented`, its Test artifact still `TBD`. No code, no test.
|
|
19
|
+
* It is H1's root cause exactly — the gate approving what it did not check.
|
|
20
|
+
*
|
|
21
|
+
* ## Why a hard failure and not another opt-in flag
|
|
22
|
+
*
|
|
23
|
+
* `--strict-artifacts` cannot catch this: it compares the diff against the
|
|
24
|
+
* paths the row declares, and a row declaring none has nothing to compare.
|
|
25
|
+
*
|
|
26
|
+
* So the harness asks the one question that needs no declaration and has no
|
|
27
|
+
* legitimate negative answer: did anything change? An agent that produced no
|
|
28
|
+
* files cannot have implemented a requirement, whatever the gate concludes
|
|
29
|
+
* about the documents around it. Under the rule ADR-0023 sets out — a content
|
|
30
|
+
* check is a gate only when failing it is always a defect — this one qualifies,
|
|
31
|
+
* which is why it is not behind a flag.
|
|
32
|
+
*
|
|
33
|
+
* ## Why the prompt archive does not count
|
|
34
|
+
*
|
|
35
|
+
* The harness writes the archive itself. Counting it would mean the harness's
|
|
36
|
+
* own bookkeeping vouches for the agent, which is the same circularity as a
|
|
37
|
+
* gate that grades the file it told the agent to write.
|
|
38
|
+
*/
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.PROMPT_ARCHIVE_DIR = void 0;
|
|
41
|
+
exports.agentAuthoredPaths = agentAuthoredPaths;
|
|
42
|
+
exports.isEmptyAttempt = isEmptyAttempt;
|
|
43
|
+
/** Where the harness archives the prompt it handed the agent. */
|
|
44
|
+
exports.PROMPT_ARCHIVE_DIR = ".specops/harness-prompts";
|
|
45
|
+
/**
|
|
46
|
+
* Everything the agent actually wrote, with the harness's own bookkeeping
|
|
47
|
+
* removed. Paths are worktree-relative, as `git status --porcelain` reports
|
|
48
|
+
* them.
|
|
49
|
+
*/
|
|
50
|
+
function agentAuthoredPaths(touched) {
|
|
51
|
+
return (touched || []).filter((p) => p !== exports.PROMPT_ARCHIVE_DIR && !p.startsWith(`${exports.PROMPT_ARCHIVE_DIR}/`));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* True when the attempt left nothing behind — there is nothing to gate, and a
|
|
55
|
+
* green gate over it would mean nothing.
|
|
56
|
+
*/
|
|
57
|
+
function isEmptyAttempt(touched) {
|
|
58
|
+
return agentAuthoredPaths(touched).length === 0;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=EmptyAttempt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmptyAttempt.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/EmptyAttempt.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;;;AAUH,gDAIC;AAMD,wCAEC;AApBD,iEAAiE;AACpD,QAAA,kBAAkB,GAAG,0BAA0B,CAAC;AAE7D;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,OAA0B;IAC3D,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,CAC3B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,0BAAkB,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,0BAAkB,GAAG,CAAC,CAC3E,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,cAAc,CAAC,OAA0B;IACvD,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Comparing two renderings of the same pack, file by file.
|
|
4
|
+
*
|
|
5
|
+
* `specops diff` asks what a version bump would do to a project. The answer is
|
|
6
|
+
* a classification over content hashes, which is judgement, not I/O: walking a
|
|
7
|
+
* directory and hashing its files is the caller's job, and
|
|
8
|
+
* `infrastructure/DirectorySnapshot` does it.
|
|
9
|
+
*
|
|
10
|
+
* The comparison is one-directional on purpose. A file present in the baseline
|
|
11
|
+
* but absent from the candidate is not reported as removed, because `expand`
|
|
12
|
+
* never deletes: it writes what the pack declares and leaves everything else
|
|
13
|
+
* alone, so a file only the baseline has is a file the project owns.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.IGNORE_FILES = exports.IGNORE_DIRS = void 0;
|
|
17
|
+
exports.classifyFileChanges = classifyFileChanges;
|
|
18
|
+
/** Directories never worth walking into: caches, VCS metadata, build output. */
|
|
19
|
+
exports.IGNORE_DIRS = new Set([".git", "node_modules", "_site", ".cache", ".specops"]);
|
|
20
|
+
/** Files a diff must not report on, because they describe the diff itself. */
|
|
21
|
+
exports.IGNORE_FILES = new Set([".specops.lock"]);
|
|
22
|
+
function classifyFileChanges(baseline, candidate) {
|
|
23
|
+
const added = [];
|
|
24
|
+
const modified = [];
|
|
25
|
+
const unchanged = [];
|
|
26
|
+
for (const [rel, hash] of candidate) {
|
|
27
|
+
const before = baseline.get(rel);
|
|
28
|
+
if (before === undefined)
|
|
29
|
+
added.push(rel);
|
|
30
|
+
else if (before !== hash)
|
|
31
|
+
modified.push(rel);
|
|
32
|
+
else
|
|
33
|
+
unchanged.push(rel);
|
|
34
|
+
}
|
|
35
|
+
return { added, modified, unchanged };
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=FileChangeSet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileChangeSet.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/FileChangeSet.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;AAiBH,kDAaC;AAnBD,gFAAgF;AACnE,QAAA,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;AAE5F,8EAA8E;AACjE,QAAA,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;AAEvD,SAAgB,mBAAmB,CAAC,QAAoB,EAAE,SAAqB;IAC7E,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,SAAS,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;aACrC,IAAI,MAAM,KAAK,IAAI;YAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;;YACxC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACxC,CAAC"}
|