agent-sdd 1.0.3
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/LICENSE +21 -0
- package/README.md +1028 -0
- package/README.ru.md +1046 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +867 -0
- package/dist/features/approve/adapters/inbound/CliApproveHandler.d.ts +17 -0
- package/dist/features/approve/adapters/inbound/CliApproveHandler.js +108 -0
- package/dist/features/approve/adapters/outbound/NodeApproveFileSystem.d.ts +8 -0
- package/dist/features/approve/adapters/outbound/NodeApproveFileSystem.js +147 -0
- package/dist/features/approve/adapters/outbound/NodePlanFileWriter.d.ts +6 -0
- package/dist/features/approve/adapters/outbound/NodePlanFileWriter.js +92 -0
- package/dist/features/approve/adapters/outbound/SystemApproveClock.d.ts +4 -0
- package/dist/features/approve/adapters/outbound/SystemApproveClock.js +5 -0
- package/dist/features/approve/application/ApplyApproval.d.ts +19 -0
- package/dist/features/approve/application/ApplyApproval.js +30 -0
- package/dist/features/approve/application/WriteAttestation.d.ts +19 -0
- package/dist/features/approve/application/WriteAttestation.js +23 -0
- package/dist/features/approve/domain/ApproveRequest.d.ts +24 -0
- package/dist/features/approve/domain/ApproveRequest.js +24 -0
- package/dist/features/approve/domain/Rewrite.d.ts +1 -0
- package/dist/features/approve/domain/Rewrite.js +6 -0
- package/dist/features/approve/ports/inbound/ApproveCommand.d.ts +10 -0
- package/dist/features/approve/ports/inbound/ApproveCommand.js +1 -0
- package/dist/features/approve/ports/outbound/ApproveClock.d.ts +3 -0
- package/dist/features/approve/ports/outbound/ApproveClock.js +1 -0
- package/dist/features/approve/ports/outbound/ApproveConfigPort.d.ts +4 -0
- package/dist/features/approve/ports/outbound/ApproveConfigPort.js +1 -0
- package/dist/features/approve/ports/outbound/ApproveFileSystem.d.ts +8 -0
- package/dist/features/approve/ports/outbound/ApproveFileSystem.js +1 -0
- package/dist/features/approve/ports/outbound/PlanFileWriter.d.ts +13 -0
- package/dist/features/approve/ports/outbound/PlanFileWriter.js +1 -0
- package/dist/features/check/adapters/inbound/CliCheckHandler.d.ts +8 -0
- package/dist/features/check/adapters/inbound/CliCheckHandler.js +62 -0
- package/dist/features/check/adapters/outbound/ChildProcessCheckGit.d.ts +8 -0
- package/dist/features/check/adapters/outbound/ChildProcessCheckGit.js +112 -0
- package/dist/features/check/adapters/outbound/NodeCheckFileReader.d.ts +7 -0
- package/dist/features/check/adapters/outbound/NodeCheckFileReader.js +44 -0
- package/dist/features/check/application/CheckBaseline.d.ts +28 -0
- package/dist/features/check/application/CheckBaseline.js +54 -0
- package/dist/features/check/domain/BaselineComparison.d.ts +1 -0
- package/dist/features/check/domain/BaselineComparison.js +2 -0
- package/dist/features/check/ports/inbound/CheckCommand.d.ts +4 -0
- package/dist/features/check/ports/inbound/CheckCommand.js +1 -0
- package/dist/features/check/ports/outbound/CheckConfigPort.d.ts +4 -0
- package/dist/features/check/ports/outbound/CheckConfigPort.js +1 -0
- package/dist/features/check/ports/outbound/CheckGitPort.d.ts +7 -0
- package/dist/features/check/ports/outbound/CheckGitPort.js +1 -0
- package/dist/features/check/ports/outbound/CheckSpecPort.d.ts +9 -0
- package/dist/features/check/ports/outbound/CheckSpecPort.js +1 -0
- package/dist/features/doctor/adapters/inbound/CliDoctorHandler.d.ts +8 -0
- package/dist/features/doctor/adapters/inbound/CliDoctorHandler.js +77 -0
- package/dist/features/doctor/adapters/outbound/NodeRegistryReader.d.ts +5 -0
- package/dist/features/doctor/adapters/outbound/NodeRegistryReader.js +40 -0
- package/dist/features/doctor/application/RunDoctor.d.ts +30 -0
- package/dist/features/doctor/application/RunDoctor.js +78 -0
- package/dist/features/doctor/domain/RegistryRow.d.ts +23 -0
- package/dist/features/doctor/domain/RegistryRow.js +114 -0
- package/dist/features/doctor/domain/SemverRange.d.ts +7 -0
- package/dist/features/doctor/domain/SemverRange.js +82 -0
- package/dist/features/doctor/ports/inbound/DoctorCommand.d.ts +8 -0
- package/dist/features/doctor/ports/inbound/DoctorCommand.js +1 -0
- package/dist/features/doctor/ports/outbound/RegistryReader.d.ts +12 -0
- package/dist/features/doctor/ports/outbound/RegistryReader.js +1 -0
- package/dist/features/finalize/adapters/inbound/CliFinalizeHandler.d.ts +8 -0
- package/dist/features/finalize/adapters/inbound/CliFinalizeHandler.js +80 -0
- package/dist/features/finalize/adapters/outbound/NodeFinalizeFileSystem.d.ts +11 -0
- package/dist/features/finalize/adapters/outbound/NodeFinalizeFileSystem.js +167 -0
- package/dist/features/finalize/adapters/outbound/NodePlanRepo.d.ts +7 -0
- package/dist/features/finalize/adapters/outbound/NodePlanRepo.js +82 -0
- package/dist/features/finalize/adapters/outbound/SystemFinalizeClock.d.ts +4 -0
- package/dist/features/finalize/adapters/outbound/SystemFinalizeClock.js +5 -0
- package/dist/features/finalize/application/RunFinalize.d.ts +34 -0
- package/dist/features/finalize/application/RunFinalize.js +98 -0
- package/dist/features/finalize/domain/ValidateFinalizeGraph.d.ts +9 -0
- package/dist/features/finalize/domain/ValidateFinalizeGraph.js +86 -0
- package/dist/features/finalize/ports/inbound/FinalizeCommand.d.ts +7 -0
- package/dist/features/finalize/ports/inbound/FinalizeCommand.js +1 -0
- package/dist/features/finalize/ports/outbound/FinalizeClock.d.ts +3 -0
- package/dist/features/finalize/ports/outbound/FinalizeClock.js +1 -0
- package/dist/features/finalize/ports/outbound/FinalizeConfigPort.d.ts +4 -0
- package/dist/features/finalize/ports/outbound/FinalizeConfigPort.js +1 -0
- package/dist/features/finalize/ports/outbound/FinalizeFileSystem.d.ts +14 -0
- package/dist/features/finalize/ports/outbound/FinalizeFileSystem.js +1 -0
- package/dist/features/finalize/ports/outbound/PlanRepo.d.ts +21 -0
- package/dist/features/finalize/ports/outbound/PlanRepo.js +1 -0
- package/dist/features/install/adapters/inbound/CliInstallHandler.d.ts +8 -0
- package/dist/features/install/adapters/inbound/CliInstallHandler.js +54 -0
- package/dist/features/install/adapters/outbound/NodeInstallSource.d.ts +7 -0
- package/dist/features/install/adapters/outbound/NodeInstallSource.js +24 -0
- package/dist/features/install/adapters/outbound/NodeInstallTargetFs.d.ts +7 -0
- package/dist/features/install/adapters/outbound/NodeInstallTargetFs.js +30 -0
- package/dist/features/install/application/InstallRules.d.ts +10 -0
- package/dist/features/install/application/InstallRules.js +73 -0
- package/dist/features/install/domain/InstallPlan.d.ts +27 -0
- package/dist/features/install/domain/InstallPlan.js +168 -0
- package/dist/features/install/domain/InstallResult.d.ts +23 -0
- package/dist/features/install/domain/InstallResult.js +1 -0
- package/dist/features/install/domain/InstallTarget.d.ts +6 -0
- package/dist/features/install/domain/InstallTarget.js +7 -0
- package/dist/features/install/domain/ManagedBlock.d.ts +3 -0
- package/dist/features/install/domain/ManagedBlock.js +20 -0
- package/dist/features/install/domain/RuleManifest.d.ts +17 -0
- package/dist/features/install/domain/RuleManifest.js +69 -0
- package/dist/features/install/domain/SettingsMerge.d.ts +5 -0
- package/dist/features/install/domain/SettingsMerge.js +43 -0
- package/dist/features/install/ports/inbound/InstallCommand.d.ts +10 -0
- package/dist/features/install/ports/inbound/InstallCommand.js +1 -0
- package/dist/features/install/ports/outbound/InstallSource.d.ts +4 -0
- package/dist/features/install/ports/outbound/InstallSource.js +1 -0
- package/dist/features/install/ports/outbound/InstallTargetFs.d.ts +6 -0
- package/dist/features/install/ports/outbound/InstallTargetFs.js +1 -0
- package/dist/features/lint/adapters/inbound/CliLintHandler.d.ts +8 -0
- package/dist/features/lint/adapters/inbound/CliLintHandler.js +61 -0
- package/dist/features/lint/adapters/outbound/NodeLintFileReader.d.ts +7 -0
- package/dist/features/lint/adapters/outbound/NodeLintFileReader.js +165 -0
- package/dist/features/lint/application/RunLint.d.ts +10 -0
- package/dist/features/lint/application/RunLint.js +100 -0
- package/dist/features/lint/domain/Diagnostic.d.ts +1 -0
- package/dist/features/lint/domain/Diagnostic.js +2 -0
- package/dist/features/lint/domain/Record.d.ts +1 -0
- package/dist/features/lint/domain/Record.js +5 -0
- package/dist/features/lint/domain/Rules.d.ts +1 -0
- package/dist/features/lint/domain/Rules.js +2 -0
- package/dist/features/lint/domain/SpecParser.d.ts +1 -0
- package/dist/features/lint/domain/SpecParser.js +2 -0
- package/dist/features/lint/ports/inbound/LintCommand.d.ts +4 -0
- package/dist/features/lint/ports/inbound/LintCommand.js +1 -0
- package/dist/features/lint/ports/outbound/LintConfigPort.d.ts +4 -0
- package/dist/features/lint/ports/outbound/LintConfigPort.js +1 -0
- package/dist/features/lint/ports/outbound/LintFileReader.d.ts +10 -0
- package/dist/features/lint/ports/outbound/LintFileReader.js +1 -0
- package/dist/features/plan/adapters/inbound/CliPlanShowHandler.d.ts +8 -0
- package/dist/features/plan/adapters/inbound/CliPlanShowHandler.js +73 -0
- package/dist/features/plan/adapters/outbound/NodePlanReader.d.ts +7 -0
- package/dist/features/plan/adapters/outbound/NodePlanReader.js +68 -0
- package/dist/features/plan/application/ShowPlan.d.ts +7 -0
- package/dist/features/plan/application/ShowPlan.js +4 -0
- package/dist/features/plan/ports/inbound/PlanShowCommand.d.ts +7 -0
- package/dist/features/plan/ports/inbound/PlanShowCommand.js +1 -0
- package/dist/features/plan/ports/outbound/PlanConfigPort.d.ts +4 -0
- package/dist/features/plan/ports/outbound/PlanConfigPort.js +1 -0
- package/dist/features/plan/ports/outbound/PlanReader.d.ts +19 -0
- package/dist/features/plan/ports/outbound/PlanReader.js +1 -0
- package/dist/features/ready/adapters/inbound/CliReadyHandler.d.ts +8 -0
- package/dist/features/ready/adapters/inbound/CliReadyHandler.js +79 -0
- package/dist/features/ready/adapters/outbound/ChildProcessReadyGit.d.ts +9 -0
- package/dist/features/ready/adapters/outbound/ChildProcessReadyGit.js +113 -0
- package/dist/features/ready/adapters/outbound/NodeReadyFileSystem.d.ts +8 -0
- package/dist/features/ready/adapters/outbound/NodeReadyFileSystem.js +159 -0
- package/dist/features/ready/application/RunReady.d.ts +16 -0
- package/dist/features/ready/application/RunReady.js +572 -0
- package/dist/features/ready/domain/AggregatedRules.d.ts +16 -0
- package/dist/features/ready/domain/AggregatedRules.js +42 -0
- package/dist/features/ready/domain/MarkerParser.d.ts +17 -0
- package/dist/features/ready/domain/MarkerParser.js +108 -0
- package/dist/features/ready/domain/PartitionResolver.d.ts +1 -0
- package/dist/features/ready/domain/PartitionResolver.js +5 -0
- package/dist/features/ready/domain/ReadyInput.d.ts +6 -0
- package/dist/features/ready/domain/ReadyInput.js +1 -0
- package/dist/features/ready/domain/ReadyViolation.d.ts +38 -0
- package/dist/features/ready/domain/ReadyViolation.js +19 -0
- package/dist/features/ready/domain/Rules.d.ts +22 -0
- package/dist/features/ready/domain/Rules.js +243 -0
- package/dist/features/ready/domain/SpecDiff.d.ts +33 -0
- package/dist/features/ready/domain/SpecDiff.js +321 -0
- package/dist/features/ready/ports/inbound/ReadyCommand.d.ts +4 -0
- package/dist/features/ready/ports/inbound/ReadyCommand.js +1 -0
- package/dist/features/ready/ports/outbound/ReadyConfigPort.d.ts +4 -0
- package/dist/features/ready/ports/outbound/ReadyConfigPort.js +1 -0
- package/dist/features/ready/ports/outbound/ReadyFileReader.d.ts +12 -0
- package/dist/features/ready/ports/outbound/ReadyFileReader.js +1 -0
- package/dist/features/ready/ports/outbound/ReadyGitPort.d.ts +10 -0
- package/dist/features/ready/ports/outbound/ReadyGitPort.js +5 -0
- package/dist/features/record/adapters/inbound/CliRecordHandler.d.ts +10 -0
- package/dist/features/record/adapters/inbound/CliRecordHandler.js +111 -0
- package/dist/features/record/adapters/outbound/NodeRecordFileSystem.d.ts +9 -0
- package/dist/features/record/adapters/outbound/NodeRecordFileSystem.js +152 -0
- package/dist/features/record/application/AddRecord.d.ts +11 -0
- package/dist/features/record/application/AddRecord.js +84 -0
- package/dist/features/record/application/GetRecord.d.ts +8 -0
- package/dist/features/record/application/GetRecord.js +22 -0
- package/dist/features/record/application/ListRecords.d.ts +9 -0
- package/dist/features/record/application/ListRecords.js +24 -0
- package/dist/features/record/application/SetRecord.d.ts +11 -0
- package/dist/features/record/application/SetRecord.js +68 -0
- package/dist/features/record/domain/RecordBody.d.ts +12 -0
- package/dist/features/record/domain/RecordBody.js +66 -0
- package/dist/features/record/domain/RecordPartition.d.ts +1 -0
- package/dist/features/record/domain/RecordPartition.js +7 -0
- package/dist/features/record/domain/RecordSlice.d.ts +7 -0
- package/dist/features/record/domain/RecordSlice.js +1 -0
- package/dist/features/record/domain/RecordSummary.d.ts +11 -0
- package/dist/features/record/domain/RecordSummary.js +13 -0
- package/dist/features/record/domain/RecordWrite.d.ts +14 -0
- package/dist/features/record/domain/RecordWrite.js +8 -0
- package/dist/features/record/ports/inbound/RecordCommand.d.ts +19 -0
- package/dist/features/record/ports/inbound/RecordCommand.js +1 -0
- package/dist/features/record/ports/outbound/RecordConfigPort.d.ts +4 -0
- package/dist/features/record/ports/outbound/RecordConfigPort.js +1 -0
- package/dist/features/record/ports/outbound/RecordFileReader.d.ts +10 -0
- package/dist/features/record/ports/outbound/RecordFileReader.js +1 -0
- package/dist/features/record/ports/outbound/RecordFileWriter.d.ts +6 -0
- package/dist/features/record/ports/outbound/RecordFileWriter.js +1 -0
- package/dist/features/refresh/adapters/inbound/CliRefreshHandler.d.ts +8 -0
- package/dist/features/refresh/adapters/inbound/CliRefreshHandler.js +24 -0
- package/dist/features/refresh/adapters/outbound/ChildProcessRefreshGit.d.ts +8 -0
- package/dist/features/refresh/adapters/outbound/ChildProcessRefreshGit.js +118 -0
- package/dist/features/refresh/adapters/outbound/NodeRefreshFileReader.d.ts +7 -0
- package/dist/features/refresh/adapters/outbound/NodeRefreshFileReader.js +44 -0
- package/dist/features/refresh/adapters/outbound/SystemRefreshClock.d.ts +4 -0
- package/dist/features/refresh/adapters/outbound/SystemRefreshClock.js +5 -0
- package/dist/features/refresh/application/BuildRefreshStubs.d.ts +25 -0
- package/dist/features/refresh/application/BuildRefreshStubs.js +43 -0
- package/dist/features/refresh/domain/DiffStubs.d.ts +24 -0
- package/dist/features/refresh/domain/DiffStubs.js +81 -0
- package/dist/features/refresh/domain/Footprint.d.ts +14 -0
- package/dist/features/refresh/domain/Footprint.js +45 -0
- package/dist/features/refresh/ports/inbound/RefreshCommand.d.ts +4 -0
- package/dist/features/refresh/ports/inbound/RefreshCommand.js +1 -0
- package/dist/features/refresh/ports/outbound/RefreshClockPort.d.ts +3 -0
- package/dist/features/refresh/ports/outbound/RefreshClockPort.js +1 -0
- package/dist/features/refresh/ports/outbound/RefreshConfigPort.d.ts +4 -0
- package/dist/features/refresh/ports/outbound/RefreshConfigPort.js +1 -0
- package/dist/features/refresh/ports/outbound/RefreshGitPort.d.ts +7 -0
- package/dist/features/refresh/ports/outbound/RefreshGitPort.js +1 -0
- package/dist/features/refresh/ports/outbound/RefreshSpecPort.d.ts +9 -0
- package/dist/features/refresh/ports/outbound/RefreshSpecPort.js +1 -0
- package/dist/features/report/adapters/inbound/CliReportHandler.d.ts +8 -0
- package/dist/features/report/adapters/inbound/CliReportHandler.js +35 -0
- package/dist/features/report/adapters/outbound/NodeReportFileSystem.d.ts +7 -0
- package/dist/features/report/adapters/outbound/NodeReportFileSystem.js +128 -0
- package/dist/features/report/application/RunReport.d.ts +19 -0
- package/dist/features/report/application/RunReport.js +161 -0
- package/dist/features/report/ports/inbound/ReportCommand.d.ts +8 -0
- package/dist/features/report/ports/inbound/ReportCommand.js +1 -0
- package/dist/features/report/ports/outbound/ReportConfigPort.d.ts +4 -0
- package/dist/features/report/ports/outbound/ReportConfigPort.js +1 -0
- package/dist/features/report/ports/outbound/ReportFileReader.d.ts +7 -0
- package/dist/features/report/ports/outbound/ReportFileReader.js +1 -0
- package/dist/features/token/adapters/inbound/CliTokenHandler.d.ts +8 -0
- package/dist/features/token/adapters/inbound/CliTokenHandler.js +53 -0
- package/dist/features/token/adapters/outbound/ChildProcessTokenGit.d.ts +8 -0
- package/dist/features/token/adapters/outbound/ChildProcessTokenGit.js +112 -0
- package/dist/features/token/adapters/outbound/NodeTokenConfigReader.d.ts +5 -0
- package/dist/features/token/adapters/outbound/NodeTokenConfigReader.js +41 -0
- package/dist/features/token/application/ComputeToken.d.ts +18 -0
- package/dist/features/token/application/ComputeToken.js +27 -0
- package/dist/features/token/ports/inbound/TokenCommand.d.ts +4 -0
- package/dist/features/token/ports/inbound/TokenCommand.js +1 -0
- package/dist/features/token/ports/outbound/TokenConfigPort.d.ts +4 -0
- package/dist/features/token/ports/outbound/TokenConfigPort.js +1 -0
- package/dist/features/token/ports/outbound/TokenGitPort.d.ts +7 -0
- package/dist/features/token/ports/outbound/TokenGitPort.js +1 -0
- package/dist/shared/domain/AgentBlocklist.d.ts +5 -0
- package/dist/shared/domain/AgentBlocklist.js +28 -0
- package/dist/shared/domain/BoundaryReachability.d.ts +5 -0
- package/dist/shared/domain/BoundaryReachability.js +71 -0
- package/dist/shared/domain/CheckOutcome.d.ts +10 -0
- package/dist/shared/domain/CheckOutcome.js +7 -0
- package/dist/shared/domain/CliOutput.d.ts +10 -0
- package/dist/shared/domain/CliOutput.js +29 -0
- package/dist/shared/domain/Config.d.ts +29 -0
- package/dist/shared/domain/Config.js +201 -0
- package/dist/shared/domain/DiagnosticRegistry.d.ts +8 -0
- package/dist/shared/domain/DiagnosticRegistry.js +71 -0
- package/dist/shared/domain/Errors.d.ts +12 -0
- package/dist/shared/domain/Errors.js +23 -0
- package/dist/shared/domain/GlobMatch.d.ts +2 -0
- package/dist/shared/domain/GlobMatch.js +58 -0
- package/dist/shared/domain/LintReport.d.ts +16 -0
- package/dist/shared/domain/LintReport.js +11 -0
- package/dist/shared/domain/LintRules.d.ts +67 -0
- package/dist/shared/domain/LintRules.js +956 -0
- package/dist/shared/domain/PartitionGrammar.d.ts +4 -0
- package/dist/shared/domain/PartitionGrammar.js +16 -0
- package/dist/shared/domain/PlanFile.d.ts +28 -0
- package/dist/shared/domain/PlanFile.js +112 -0
- package/dist/shared/domain/Scope.d.ts +1 -0
- package/dist/shared/domain/Scope.js +3 -0
- package/dist/shared/domain/SpecApprovalRewrite.d.ts +23 -0
- package/dist/shared/domain/SpecApprovalRewrite.js +254 -0
- package/dist/shared/domain/SpecBlocks.d.ts +12 -0
- package/dist/shared/domain/SpecBlocks.js +96 -0
- package/dist/shared/domain/SpecRecord.d.ts +17 -0
- package/dist/shared/domain/SpecRecord.js +208 -0
- package/dist/shared/domain/TemplateFieldMetadata.d.ts +2 -0
- package/dist/shared/domain/TemplateFieldMetadata.js +177 -0
- package/dist/shared/domain/Token.d.ts +2 -0
- package/dist/shared/domain/Token.js +5 -0
- package/dist/shared/domain/WeaselWords.d.ts +3 -0
- package/dist/shared/domain/WeaselWords.js +32 -0
- package/package.json +71 -0
- package/rules/enforcement_registry.md +126 -0
- package/rules/hooks/sdd-lint-reminder.sh +33 -0
- package/rules/hooks/sdd-spec-read-guard.sh +73 -0
- package/rules/manifest.json +15 -0
- package/rules/review-sdd.md +9 -0
- package/rules/sdd-cli-usage.md +91 -0
- package/rules/skills/spec-driven-development/SKILL.md +554 -0
- package/rules/skills/spec-driven-development/data/weasel-words.json +22 -0
- package/rules/spec-driven-development.md +69 -0
- package/rules/tdd-sdd.md +127 -0
- package/rules/workflow-sdd.md +56 -0
- package/schema/sdd.config.schema.json +104 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# PreToolUse guard. Matcher: Read|Bash|Grep|Glob.
|
|
3
|
+
# Stdin: JSON with tool_name, tool_input, cwd.
|
|
4
|
+
# Purpose: in an SDD project (a tree carrying .sdd/config.json), DENY any
|
|
5
|
+
# attempt to read spec/*.md directly. The spec is navigated via
|
|
6
|
+
# `sdd record list` / `sdd record get <id>`, not by reading the whole file.
|
|
7
|
+
# Heuristic Bash/Grep/Glob matching is intentional — false positives are
|
|
8
|
+
# preferred over letting a raw spec read through.
|
|
9
|
+
input=$(cat)
|
|
10
|
+
tool=$(printf '%s' "$input" | jq -r '.tool_name // empty')
|
|
11
|
+
cwd=$(printf '%s' "$input" | jq -r '.cwd // empty')
|
|
12
|
+
|
|
13
|
+
[ -n "$cwd" ] || exit 0
|
|
14
|
+
|
|
15
|
+
# Only guard inside an SDD project: walk up from cwd looking for .sdd/config.json.
|
|
16
|
+
dir="$cwd"
|
|
17
|
+
found=
|
|
18
|
+
while [ -n "$dir" ] && [ "$dir" != "/" ]; do
|
|
19
|
+
if [ -f "$dir/.sdd/config.json" ]; then found=1; break; fi
|
|
20
|
+
dir="$(dirname "$dir")"
|
|
21
|
+
done
|
|
22
|
+
[ -n "$found" ] || exit 0
|
|
23
|
+
|
|
24
|
+
# True (0) when $1 names/contains a spec markdown path or a glob over one.
|
|
25
|
+
# Boundary before `spec/` is start-of-string, slash, whitespace, or a quote
|
|
26
|
+
# so it matches absolute paths, relative paths, and tokens inside a command.
|
|
27
|
+
is_spec_md() {
|
|
28
|
+
printf '%s' "$1" | grep -Eq '(^|[/[:space:]"'"'"'])spec/[^[:space:]"'"'"']*\.md' && return 0
|
|
29
|
+
printf '%s' "$1" | grep -Eq '(^|[/[:space:]"'"'"'])spec/(\*\*|\*)' && return 0
|
|
30
|
+
return 1
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
deny=
|
|
34
|
+
case "$tool" in
|
|
35
|
+
Read)
|
|
36
|
+
p=$(printf '%s' "$input" | jq -r '.tool_input.file_path // .tool_input.path // empty')
|
|
37
|
+
is_spec_md "$p" && deny=1
|
|
38
|
+
;;
|
|
39
|
+
Glob)
|
|
40
|
+
pat=$(printf '%s' "$input" | jq -r '.tool_input.pattern // empty')
|
|
41
|
+
base=$(printf '%s' "$input" | jq -r '.tool_input.path // empty')
|
|
42
|
+
{ is_spec_md "$pat" || is_spec_md "$base/$pat"; } && deny=1
|
|
43
|
+
;;
|
|
44
|
+
Grep)
|
|
45
|
+
gp=$(printf '%s' "$input" | jq -r '.tool_input.path // empty')
|
|
46
|
+
gg=$(printf '%s' "$input" | jq -r '.tool_input.glob // empty')
|
|
47
|
+
if printf '%s' "$gp" | grep -Eq '(^|/)spec($|/)' || is_spec_md "$gg"; then deny=1; fi
|
|
48
|
+
;;
|
|
49
|
+
Bash)
|
|
50
|
+
cmd=$(printf '%s' "$input" | jq -r '.tool_input.command // empty')
|
|
51
|
+
# Only treat the command as a spec *read* when the program being invoked
|
|
52
|
+
# (the FIRST token) is a content reader/pager/search tool AND a spec/*.md
|
|
53
|
+
# path is referenced. This deliberately never blocks git, sdd, npm, etc.,
|
|
54
|
+
# so `git add ./spec/*.md`, `git diff spec/spec.md` and friends pass.
|
|
55
|
+
prog=$(printf '%s' "$cmd" | sed -E 's/^[[:space:]]+//' | awk '{print $1}')
|
|
56
|
+
case "$prog" in
|
|
57
|
+
cat|bat|less|more|head|tail|nl|sed|awk|grep|egrep|fgrep|rg|ag|view|vi|vim|nano|open)
|
|
58
|
+
is_spec_md "$cmd" && deny=1
|
|
59
|
+
;;
|
|
60
|
+
esac
|
|
61
|
+
;;
|
|
62
|
+
*) exit 0 ;;
|
|
63
|
+
esac
|
|
64
|
+
|
|
65
|
+
[ -n "$deny" ] || exit 0
|
|
66
|
+
|
|
67
|
+
jq -n '{
|
|
68
|
+
hookSpecificOutput: {
|
|
69
|
+
hookEventName: "PreToolUse",
|
|
70
|
+
permissionDecision: "deny",
|
|
71
|
+
permissionDecisionReason: "Spec files in an SDD project are read via `sdd record list` and `sdd record get <id>`, not by reading spec/*.md directly. See @sdd/sdd-cli-usage.md."
|
|
72
|
+
}
|
|
73
|
+
}'
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format_version": 1,
|
|
3
|
+
"artifacts": [
|
|
4
|
+
{ "source": "spec-driven-development.md", "kind": "context", "targets": ["claude", "codex"] },
|
|
5
|
+
{ "source": "workflow-sdd.md", "kind": "context", "targets": ["claude", "codex"] },
|
|
6
|
+
{ "source": "tdd-sdd.md", "kind": "context", "targets": ["claude", "codex"] },
|
|
7
|
+
{ "source": "sdd-cli-usage.md", "kind": "context", "targets": ["claude", "codex"] },
|
|
8
|
+
{ "source": "review-sdd.md", "kind": "context", "targets": ["claude", "codex"] },
|
|
9
|
+
{ "source": "skills/spec-driven-development/SKILL.md", "kind": "skill", "skill_name": "spec-driven-development", "targets": ["claude", "codex"] },
|
|
10
|
+
{ "source": "enforcement_registry.md", "kind": "reference", "targets": ["claude", "codex"] },
|
|
11
|
+
{ "source": "skills/spec-driven-development/data/weasel-words.json", "kind": "data", "targets": ["claude", "codex"] },
|
|
12
|
+
{ "source": "hooks/sdd-lint-reminder.sh", "kind": "hook", "event": "Edit|Write", "targets": ["claude"] },
|
|
13
|
+
{ "source": "hooks/sdd-spec-read-guard.sh", "kind": "hook", "event": "Read|Bash|Grep|Glob", "targets": ["claude"] }
|
|
14
|
+
]
|
|
15
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Self-Review — SDD Addendum
|
|
2
|
+
|
|
3
|
+
Extends the `## Tests` block of `@rules/review.md` when the project carries
|
|
4
|
+
`.sdd/config.json`. Add these checks alongside the existing test bullets
|
|
5
|
+
before presenting changes or committing.
|
|
6
|
+
|
|
7
|
+
## Tests (SDD)
|
|
8
|
+
- [ ] `sdd lint` exit 0 (if project carries `.sdd/config.json`)
|
|
9
|
+
- [ ] `sdd ready` exit 0 (if project carries `.sdd/config.json`)
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# sdd-cli Usage
|
|
2
|
+
|
|
3
|
+
Operational rules for invoking `agent-sdd` (the `sdd` CLI) as part of SDD workflow.
|
|
4
|
+
This file maps each workflow phase to the CLI command(s) that close the
|
|
5
|
+
mechanical part of the corresponding gate. The full mapping
|
|
6
|
+
requirement → enforcement_class → executor lives in `enforcement_registry.md`;
|
|
7
|
+
this file is the *trigger* layer (when to run what).
|
|
8
|
+
|
|
9
|
+
## Phase-to-command mapping
|
|
10
|
+
|
|
11
|
+
| Workflow phase | Command | Expected exit | If non-zero |
|
|
12
|
+
|---|---|---|---|
|
|
13
|
+
| After every spec edit | `sdd lint` | 0 | Fix diagnostics; do not proceed to Implement until 0 |
|
|
14
|
+
| After scope-touching commit | `sdd check` | 0 | Run `sdd refresh > stubs.yaml`; fill Delta/Open-Q stubs in spec; recompute token via `sdd token`; paste into BL block |
|
|
15
|
+
| Before proposing commit | `sdd ready` | 0 | Address violations (uncovered, unapproved, surface_unapproved_ref, semver cascade, debt_budget_increased, etc.); never commit on exit 1 |
|
|
16
|
+
| Before release tag | `sdd ready` | 0 | Same as above; release without exit 0 violates SDD «spec is source of truth» invariant |
|
|
17
|
+
| When promoting `proposed → approved` | `sdd approve --id <X> --approver <human> ...` then `sdd finalize` | 0 + 0 | If `sdd finalize` exits 1 with `proposed-references` — promote referenced IDs first or include them in the same plan |
|
|
18
|
+
| On new checkout / version drift | `sdd doctor --rule-version --rules rules/enforcement_registry.md` | 0 | Investigate `version_mismatch` / `missing_diagnostic` / `stale_diagnostic`; either bump CLI or update `enforcement_registry.md` |
|
|
19
|
+
| Before opening PR | `sdd report --pr-summary --against <base>` | 0 | Paste output into PR description; expand «Internal decisions» section manually (mechanical part is just a skeleton) |
|
|
20
|
+
| Locating / inspecting a record in a large spec | `sdd record list [--partition <p>]` / `sdd record get <id>` | 0 | Read-only (INV-002); use instead of opening the whole spec file |
|
|
21
|
+
| Editing / adding a single draft\|proposed record | `sdd record set <id> …` / `sdd record add --after <id> …` | 0 | Then `sdd lint` MUST be 0; refuses approved/deprecated/removed records |
|
|
22
|
+
|
|
23
|
+
## Navigating and editing the spec (`sdd record`)
|
|
24
|
+
|
|
25
|
+
Spec files grow to thousands of lines. **Do not read or hand-edit the whole file** to work on one record — use `sdd record`, which keeps the agent's context scoped to the records that matter and edits a single record atomically.
|
|
26
|
+
|
|
27
|
+
| Goal | Command | Notes |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| Compact index of every record | `sdd record list [--partition <name>] [--format=json\|human]` | One row per record: `id` · `type` · `lifecycle.status` · derived title (`title`, else Surface `name`, else blank). `--partition` keeps only records whose partition component (id minus its trailing `:<ID-tail>`) equals `<name>`. Read-only (INV-002). |
|
|
30
|
+
| Read ONE record verbatim | `sdd record get <id> [--format=json\|human]` | Prints the record's exact source body (round-trips into `set`); JSON adds `file` + `start_line`/`end_line`. Exit 1 if not found. |
|
|
31
|
+
| Replace a record body in place | `sdd record set <id> (--from-file <p> \| --content <s>)` | Edits a **draft/proposed** record; surrounding fence and `---` are preserved. Body may be bare (as `get` emits) or wrapped in a ```yaml fence — both are normalised. |
|
|
32
|
+
| Insert a new record | `sdd record add --after <id> (--from-file <p> \| --content <s>)` | Inserts a new ```yaml-fenced record immediately after the anchor's fence. Body `id` must be new; status `draft`/`proposed`. |
|
|
33
|
+
|
|
34
|
+
Rules:
|
|
35
|
+
- **Prefer `sdd record list`/`get` over `Read`** to find or inspect records in a large spec — `Read` only when you genuinely need broad surrounding context.
|
|
36
|
+
- **Prefer `sdd record set`/`add` over `Edit`/`Write`** for single-record changes. The write is atomic and scoped to `lint.spec_files` (INV-015); `get → edit → set` round-trips byte-for-byte.
|
|
37
|
+
- **`set`/`add` refuse `approved`/`deprecated`/`removed` records** (exit 1, `record-protected`). Changing a governed record is a `Delta` + `sdd approve`/`sdd finalize` job — never a `set`.
|
|
38
|
+
- **Pass multi-line YAML via `--from-file <path>`** (use `--content` only for one-liners); never inline multi-line YAML through the shell.
|
|
39
|
+
- **`set`/`add` are not a lint substitute** — the body is spliced verbatim. Always run `sdd lint` afterwards (it MUST be 0), then the normal gates.
|
|
40
|
+
|
|
41
|
+
## Universal rules
|
|
42
|
+
|
|
43
|
+
1. **Never bypass `sdd ready` exit 1 with `--no-verify` or by commenting out checks.** The exit code is the gate — work around it by fixing the underlying issue, not the verifier.
|
|
44
|
+
2. **Never write `approval_record` directly in spec files.** Use `sdd approve` (writes pending attestation to a plan-namespace artefact) followed by `sdd finalize` (atomic flip with graph validation). Direct edits bypass graph validation. Legacy `sdd approve --inline` is deprecated and removed in v1.1.0 of the CLI Surface.
|
|
45
|
+
3. **Self-approval is forbidden.** `sdd approve --approver <agent-id>` exits with `agent-approver` reason; this includes Claude, Codex, any `bot:*` identity, and `sdd-cli` itself. The CLI enforces this; the agent must not retry with a different bot identity.
|
|
46
|
+
4. **`sdd lint` is read-only.** It never modifies spec files. Diagnostics with `--format=json` are stable per `Surface: diagnostics` semver — pin against `compatible_sdd_cli` from `enforcement_registry.md`.
|
|
47
|
+
5. **`sdd refresh` writes only to stdout.** Apply emitted Delta/Open-Q stubs by hand; review every stub before pasting into spec.
|
|
48
|
+
6. **Never hand-craft a `--plan <plan_id>` for `sdd approve`.** The id must match the minted grammar `^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{6}Z-[a-z0-9]{5}$` (e.g. `2026-05-20T210159Z-038af`); an arbitrary string is accepted on first write but the CLI throws on the next append/parse. Prefer omitting `--plan` so the CLI mints a valid id and writes `.sdd/plans/.active` (subsequent `approve` calls without `--plan` append to it; `sdd finalize` without `--plan` consumes it). To approve N IDs that reference each other (e.g. a `Surface` and its member `Contract`s), queue all N into **one** plan, then a single `sdd finalize` flips them atomically — piecemeal finalize fails with `proposed-references`.
|
|
49
|
+
7. **Use `sdd record` to navigate and edit large specs.** `record list`/`get` are read-only (INV-002) and keep context scoped to single records — prefer them over `Read` on big spec files. `record set`/`add` edit one record atomically (INV-015) and only touch `draft`/`proposed` — prefer them over `Edit`/`Write`, and never use them on `approved`/`deprecated`/`removed` records (that's a `Delta` + `sdd approve`/`finalize`). After any `set`/`add`, `sdd lint` MUST be 0.
|
|
50
|
+
|
|
51
|
+
## Exit-code taxonomy (across commands)
|
|
52
|
+
|
|
53
|
+
| Exit | Meaning | Action |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| 0 | Clean / mergeable | Proceed to next phase |
|
|
56
|
+
| 1 | Drift / violation / refusal | Fix the underlying issue (see command-specific `reason` / `kind`) |
|
|
57
|
+
| 2 | Configuration error | Fix `.sdd/config.json` or spec syntax; do not retry until parseable |
|
|
58
|
+
| 3 | Environment error | Fix env (`git` on PATH, inside repo, `HEAD` resolves, etc.) |
|
|
59
|
+
|
|
60
|
+
## Spec-file glob (for the lint hook)
|
|
61
|
+
|
|
62
|
+
Spec files that trigger `sdd lint` reminders are anything matching `**/spec/**/*.md` or paths declared under `lint.spec_files` in `.sdd/config.json`. The hook (`sdd/hooks/sdd-lint-reminder.sh`) is non-blocking — the agent decides whether to actually run `sdd lint` based on whether the change is normative (touched a YAML block with `id:` and `lifecycle.status:`) vs purely descriptive (Context/Glossary edits).
|
|
63
|
+
|
|
64
|
+
## Troubleshooting
|
|
65
|
+
|
|
66
|
+
| Symptom | Likely cause | Fix |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| `sdd ready` flags `[uncovered]` | Approved ID has no `@covers <id>` marker in test files | Add `// @covers <id>` next to a test that closes the obligation, OR set `Test obligation: not_applicable + reason` in the spec |
|
|
69
|
+
| `sdd ready` flags `[unapproved]` | A `proposed`/`draft` ID lives outside `sandbox_paths` | Move the spec file under `partitions[*].sandbox_paths` OR promote via `sdd approve` + `sdd finalize` |
|
|
70
|
+
| `sdd ready` flags `[unknown_partition_covers]` | Marker `@covers <prefix>:<id>` uses a partition not declared in config | Add the partition to `.sdd/config.json#partitions`, or fix the marker prefix |
|
|
71
|
+
| `sdd approve` throws `plan_id "..." does not match grammar` | Hand-crafted `--plan <id>` that isn't `YYYY-MM-DDTHHMMSSZ-<5 lowercase alnum>` (first `approve` wrote the file; the next append re-parses and throws) | Delete the stale `.sdd/plans/<bad-id>.yaml`, then re-run omitting `--plan` (CLI mints a valid id) or pass a grammar-valid id. No spec mutation occurred — `approve` only queues; `finalize` flips |
|
|
72
|
+
| `sdd record set/add` exits 1 `record-protected` | Target (or supplied body) is `approved`/`deprecated`/`removed` | Don't edit governed records via `set`/`add`; author a `Delta` and use `sdd approve` + `sdd finalize` |
|
|
73
|
+
| `sdd record set/add` exits 1 `record-not-found` / `anchor-not-found` / `duplicate-id` | id missing, `--after` anchor missing, or the new body `id` already exists | Verify ids with `sdd record list`; for `add` pick an existing `--after` anchor and a fresh `id` |
|
|
74
|
+
| `sdd record set/add` exits 2 `invalid-body` | Body has no `id:`, doesn't parse, both/neither `--from-file`/`--content`, or (set) the body `id` ≠ `<id>` | Provide exactly one input flag; ensure the body parses as one YAML mapping whose `id:` matches |
|
|
75
|
+
| `sdd ready` flags `[surface_semver_cascade]` | Policy/Invariant(contractual) referenced by a Surface changed predicate, but Surface declared bump < required | Bump the Surface major (predicate change) or minor (content change); see `enforcement_registry.md#ENF-004A` |
|
|
76
|
+
| `sdd ready` flags `[generated_artifact_structural_diff_unbumped]` | GeneratedArtifact emission has structural-breaking diff but its Surface bump is < major | Bump the generated Surface major; see ENF-019 |
|
|
77
|
+
| `sdd ready` flags `[debt_budget_increased]` | `Partition.unmodeled_budget.current` exceeds `--against <ref>` value | Reduce `current` (close `unmodeled` items) or adjust `baseline_at`/`baseline_value` with explicit owner approval |
|
|
78
|
+
| `sdd check` reports `baseline-dirty` | Uncommitted scope-touching edits | `git commit` or `git stash`, then re-run |
|
|
79
|
+
| `sdd check` reports `baseline-stale` | Scope-touching commit since recorded baseline | `sdd refresh > stubs.yaml` → fill Delta/Open-Q → commit → `sdd token --format=json` → paste new token + sha into BL block |
|
|
80
|
+
| `sdd finalize` fails with `proposed-references` | Plan tries to flip an ID whose Surface members or Policy refs are still proposed | Include referenced IDs in the same plan, or promote them first; `sdd plan show` lists current pending attestations |
|
|
81
|
+
| `sdd doctor` reports `missing_diagnostic` | `enforcement_registry.md` declares a rule the current CLI does not publish | Either: (a) bump CLI to a version that implements it, (b) downgrade `maturity: implemented → planned` in registry until CLI catches up |
|
|
82
|
+
| `sdd doctor` reports `stale_diagnostic` | CLI publishes a rule registry does not know | Add a row to `enforcement_registry.md` with the new rule_id and appropriate ENF-id |
|
|
83
|
+
| `sdd doctor` reports `version_mismatch` | `package.json#version` of CLI is outside `compatible_sdd_cli` range from registry | Bump registry's `compatible_sdd_cli` (after coordinated review) or pin the consumer to a compatible CLI version |
|
|
84
|
+
|
|
85
|
+
## Cross-references
|
|
86
|
+
|
|
87
|
+
- Operational gate definitions: `@sdd/enforcement_registry.md`
|
|
88
|
+
- Methodology principles: `@sdd/spec-driven-development.md` (rule), `@sdd/skills/spec-driven-development/SKILL.md` (full)
|
|
89
|
+
- Hook implementation: `sdd/hooks/sdd-lint-reminder.sh`
|
|
90
|
+
- Self-review checklist: `@rules/review.md` + `@sdd/review-sdd.md`
|
|
91
|
+
- Workflow integration: `@rules/workflow.md` + `@sdd/workflow-sdd.md`
|