@use-the-fork/spindle 0.0.0-stage → 0.0.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.
Files changed (245) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -2
  3. package/build/Assets/Blueprints/Catalog.js +110 -0
  4. package/build/Assets/Blueprints/agents/general.agent.md +67 -0
  5. package/build/Assets/Blueprints/agents/sdd-code-reviewer.agent.md +62 -0
  6. package/build/Assets/Blueprints/agents/sdd-code-slop-reviewer.agent.md +59 -0
  7. package/build/Assets/Blueprints/agents/sdd-implementer.agent.md +77 -0
  8. package/build/Assets/Blueprints/agents/sdd-orchestrator.agent.md +42 -0
  9. package/build/Assets/Blueprints/agents/sdd-re-review.agent.md +57 -0
  10. package/build/Assets/Blueprints/agents/sdd-reviewer.agent.md +89 -0
  11. package/build/Assets/Blueprints/agents/sdd-task-reviewer.agent.md +54 -0
  12. package/build/Assets/Blueprints/agents/shared-codebase-analyzer.agent.md +151 -0
  13. package/build/Assets/Blueprints/agents/shared-codebase-locator.agent.md +130 -0
  14. package/build/Assets/Blueprints/agents/shared-codebase-pattern-finder.agent.md +247 -0
  15. package/build/Assets/Blueprints/agents/shared-explore.agent.md +53 -0
  16. package/build/Assets/Blueprints/agents/shared-r.agent.md +17 -0
  17. package/build/Assets/Blueprints/agents/shared-rw.agent.md +17 -0
  18. package/build/Assets/Blueprints/agents/shared-rwx.agent.md +17 -0
  19. package/build/Assets/Blueprints/agents/shared-web-search-researcher.agent.md +122 -0
  20. package/build/Assets/Blueprints/instructions/code-commenting.instructions.md +39 -0
  21. package/build/Assets/Blueprints/instructions/source-architecture.instructions.md +15 -0
  22. package/build/Assets/Blueprints/skills/asd-ste100/CREDITS.MD +1 -0
  23. package/build/Assets/Blueprints/skills/asd-ste100/SKILL.md +83 -0
  24. package/build/Assets/Blueprints/skills/asd-ste100/examples/before-after.md +107 -0
  25. package/build/Assets/Blueprints/skills/asd-ste100/references/writing-rules.md +65 -0
  26. package/build/Assets/Blueprints/skills/author-agent/SKILL.md +26 -0
  27. package/build/Assets/Blueprints/skills/author-design/SKILL.md +38 -0
  28. package/build/Assets/Blueprints/skills/author-instruction/SKILL.md +28 -0
  29. package/build/Assets/Blueprints/skills/author-skill/SKILL.md +26 -0
  30. package/build/Assets/Blueprints/skills/grill/SKILL.md +33 -0
  31. package/build/Assets/Blueprints/skills/grill-design/SKILL.md +41 -0
  32. package/build/Assets/Blueprints/skills/grill-with-docs/SKILL.md +14 -0
  33. package/build/Assets/Blueprints/skills/implement/SKILL.md +79 -0
  34. package/build/Assets/Blueprints/skills/implement-spec/SKILL.md +34 -0
  35. package/build/Assets/Blueprints/skills/improve-codebase-architecture/HTML-REPORT.md +129 -0
  36. package/build/Assets/Blueprints/skills/improve-codebase-architecture/SKILL.md +74 -0
  37. package/build/Assets/Blueprints/skills/int-code-review/SKILL.md +76 -0
  38. package/build/Assets/Blueprints/skills/int-code-slop-review/SKILL.md +238 -0
  39. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/_sections.md +36 -0
  40. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/_template.md +42 -0
  41. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/comments-closing-brace-labels.md +112 -0
  42. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/comments-empty-docblocks.md +132 -0
  43. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/comments-narration.md +118 -0
  44. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/comments-placeholder.md +130 -0
  45. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/defensive-generic-catch.md +153 -0
  46. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/defensive-impossible-null.md +157 -0
  47. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/defensive-missing-real.md +157 -0
  48. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/naming-generic-placeholders.md +120 -0
  49. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/naming-over-descriptive.md +108 -0
  50. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/naming-suffix-abuse.md +167 -0
  51. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/naming-type-in-name.md +100 -0
  52. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/over-eng-dependency-creep.md +114 -0
  53. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/over-eng-premature-interface.md +136 -0
  54. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/over-eng-single-method-class.md +161 -0
  55. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/over-eng-useless-wrapper.md +140 -0
  56. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/style-as-any-escape.md +127 -0
  57. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/style-debug-artifacts.md +144 -0
  58. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/style-hyper-consistent.md +84 -0
  59. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/style-no-hack-scars.md +113 -0
  60. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/style-trivial-boilerplate.md +191 -0
  61. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/test-doesnt-throw.md +132 -0
  62. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/test-mirror-implementation.md +125 -0
  63. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/test-mock-everything.md +148 -0
  64. package/build/Assets/Blueprints/skills/int-code-slop-review/rules/test-snapshot-abuse.md +131 -0
  65. package/build/Assets/Blueprints/skills/int-codebase-design/SKILL.md +116 -0
  66. package/build/Assets/Blueprints/skills/int-codebase-design/references/DEEPENING.md +37 -0
  67. package/build/Assets/Blueprints/skills/int-codebase-design/references/DESIGN-IT-TWICE.md +44 -0
  68. package/build/Assets/Blueprints/skills/int-domain-modeling/SKILL.md +78 -0
  69. package/build/Assets/Blueprints/skills/int-domain-modeling/references/ADR-FORMAT.md +47 -0
  70. package/build/Assets/Blueprints/skills/int-domain-modeling/references/GLOSSARY-FORMAT.md +60 -0
  71. package/build/Assets/Blueprints/skills/int-prototype/LOGIC.md +67 -0
  72. package/build/Assets/Blueprints/skills/int-prototype/SKILL.md +30 -0
  73. package/build/Assets/Blueprints/skills/int-prototype/UI.md +112 -0
  74. package/build/Assets/Blueprints/skills/int-retrospective/SKILL.md +88 -0
  75. package/build/Assets/Blueprints/skills/int-retrospective/assets/retrospective-prompt.md +38 -0
  76. package/build/Assets/Blueprints/skills/int-retrospective/references/assessment.md +56 -0
  77. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/SKILL.md +64 -0
  78. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/assets/implementer-prompt.md +40 -0
  79. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/assets/reviewer-prompt.md +43 -0
  80. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/aggregate-review.md +7 -0
  81. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/corrective-rounds.md +72 -0
  82. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/example-workflow.md +25 -0
  83. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/full-spec.md +72 -0
  84. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/implementer-corrections.md +9 -0
  85. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/review-inputs.md +26 -0
  86. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/verification-evidence.md +7 -0
  87. package/build/Assets/Blueprints/skills/int-test-driven-development/SKILL.md +51 -0
  88. package/build/Assets/Blueprints/skills/int-test-driven-development/references/mocking.md +31 -0
  89. package/build/Assets/Blueprints/skills/int-test-driven-development/references/tests.md +68 -0
  90. package/build/Assets/Blueprints/skills/int-testing-agent-guidance/SKILL.md +53 -0
  91. package/build/Assets/Blueprints/skills/int-verification-before-completion/SKILL.md +25 -0
  92. package/build/Assets/Blueprints/skills/int-writing-agents/SKILL.md +66 -0
  93. package/build/Assets/Blueprints/skills/int-writing-for-agents/SKILL.md +86 -0
  94. package/build/Assets/Blueprints/skills/int-writing-instruction/SKILL.md +57 -0
  95. package/build/Assets/Blueprints/skills/int-writing-skills/SKILL.md +129 -0
  96. package/build/Assets/Blueprints/skills/int-writing-skills/assets/interactive.md +83 -0
  97. package/build/Assets/Blueprints/skills/int-writing-skills/assets/reference.md +32 -0
  98. package/build/Assets/Blueprints/skills/int-writing-skills/references/arguments.md +50 -0
  99. package/build/Assets/Blueprints/skills/int-writing-skills/references/interactive-skills.md +53 -0
  100. package/build/Assets/Blueprints/skills/int-writing-skills/references/persuasion-principles.md +220 -0
  101. package/build/Assets/Blueprints/skills/int-writing-skills/references/reference-skills.md +20 -0
  102. package/build/Assets/Blueprints/skills/int-writing-skills/references/testing-skills.md +48 -0
  103. package/build/Assets/Blueprints/skills/retrospective/SKILL.md +16 -0
  104. package/build/Assets/Blueprints/skills/setup-project/SKILL.md +66 -0
  105. package/build/Assets/Blueprints/skills/to-spec/SKILL.md +53 -0
  106. package/build/Assets/Blueprints/skills/to-tickets/SKILL.md +49 -0
  107. package/build/Assets/Blueprints/skills/update-tooling/SKILL.md +86 -0
  108. package/build/Assets/Templates/Catalog.js +12 -0
  109. package/build/Assets/Templates/Catalog.ts +17 -0
  110. package/build/Assets/Templates/project/copilot-instructions.md +17 -0
  111. package/build/Assets/Templates/project/domain.md +51 -0
  112. package/build/Assets/Templates/project/ticket-tracker.md +33 -0
  113. package/build/Assets/Templates/sdd/design.md +25 -0
  114. package/build/Assets/Templates/sdd/spec.md +29 -0
  115. package/build/Assets/Templates/sdd/ticket.md +15 -0
  116. package/build/BlueprintManagement/BlueprintManagementServiceProvider.js +15 -0
  117. package/build/BlueprintManagement/Catalog/BlueprintCatalog.js +238 -0
  118. package/build/BlueprintManagement/Commands/BlueprintCommandOptions.js +9 -0
  119. package/build/BlueprintManagement/Commands/ConflictPolicy.js +6 -0
  120. package/build/BlueprintManagement/Commands/InitCommand.js +117 -0
  121. package/build/BlueprintManagement/Commands/Prompts.js +66 -0
  122. package/build/BlueprintManagement/Commands/UpdateCommand.js +86 -0
  123. package/build/BlueprintManagement/Handlers/Agents/AgentHandler.js +21 -0
  124. package/build/BlueprintManagement/Handlers/BlueprintHandlers.js +4 -0
  125. package/build/BlueprintManagement/Handlers/Instructions/InstructionHandler.js +21 -0
  126. package/build/BlueprintManagement/Handlers/Skills/SkillHandler.js +10 -0
  127. package/build/BlueprintManagement/Reconciliation/BlueprintCatalogPlanner.js +87 -0
  128. package/build/BlueprintManagement/Reconciliation/BlueprintRemovalCoordinator.js +78 -0
  129. package/build/BlueprintManagement/Services/BlueprintReconciliationService.js +391 -0
  130. package/build/BlueprintManagement/Services/InstallationService.js +54 -0
  131. package/build/BlueprintManagement/Support/BlueprintFiles.js +113 -0
  132. package/build/BlueprintManagement/Types/Blueprint.js +1 -0
  133. package/build/BlueprintManagement/Types/Installation.js +1 -0
  134. package/build/BlueprintManagement/Types/Reconciliation.js +1 -0
  135. package/build/BlueprintManagement/Versioning/BlueprintVersion.js +70 -0
  136. package/build/BlueprintManagement/Versioning/BlueprintVersioning.js +55 -0
  137. package/build/Commands/Command.js +3 -0
  138. package/build/Commands/CommandOptions.js +12 -0
  139. package/build/Config/Config.js +3 -0
  140. package/build/Foundation/Application.js +112 -0
  141. package/build/Foundation/ApplicationBuilder.js +23 -0
  142. package/build/Foundation/Bootstrap/Bootstrapper.js +2 -0
  143. package/build/Foundation/Bootstrap/DiscoverGitRoot.js +8 -0
  144. package/build/Foundation/Bootstrap/LoadConsoleArgs.js +47 -0
  145. package/build/Foundation/Bootstrap/LoadProjectConfiguration.js +144 -0
  146. package/build/Foundation/Bootstrap/RegisterProviders.js +12 -0
  147. package/build/Foundation/Bootstrap/RequireProjectConfiguration.js +14 -0
  148. package/build/Foundation/ConsoleInvocation.js +1 -0
  149. package/build/Foundation/Container.js +185 -0
  150. package/build/Foundation/FoundationServiceProvider.js +5 -0
  151. package/build/Foundation/Kernel.js +30 -0
  152. package/build/Foundation/Service.js +23 -0
  153. package/build/Foundation/ServiceProvider.js +12 -0
  154. package/build/Git/GitServiceProvider.js +8 -0
  155. package/build/Git/Services/GitService.js +26 -0
  156. package/build/Project/ProjectServiceProvider.js +8 -0
  157. package/build/Project/Services/ProjectService.js +124 -0
  158. package/build/SubagentDrivenDevelopment/Commands/ChecksRecordCommand.js +35 -0
  159. package/build/SubagentDrivenDevelopment/Commands/ChecksRequireCommand.js +33 -0
  160. package/build/SubagentDrivenDevelopment/Commands/ClaimCommand.js +23 -0
  161. package/build/SubagentDrivenDevelopment/Commands/CorrectCommand.js +37 -0
  162. package/build/SubagentDrivenDevelopment/Commands/CreateCommand.js +26 -0
  163. package/build/SubagentDrivenDevelopment/Commands/FindingCreateCommand.js +39 -0
  164. package/build/SubagentDrivenDevelopment/Commands/FindingUpdateCommand.js +36 -0
  165. package/build/SubagentDrivenDevelopment/Commands/FinishCommand.js +23 -0
  166. package/build/SubagentDrivenDevelopment/Commands/ImplementCommand.js +23 -0
  167. package/build/SubagentDrivenDevelopment/Commands/NextCommand.js +21 -0
  168. package/build/SubagentDrivenDevelopment/Commands/ReadyCommand.js +21 -0
  169. package/build/SubagentDrivenDevelopment/Commands/RequirementsDecideCommand.js +33 -0
  170. package/build/SubagentDrivenDevelopment/Commands/ResumeCommand.js +31 -0
  171. package/build/SubagentDrivenDevelopment/Commands/ReviewCommand.js +55 -0
  172. package/build/SubagentDrivenDevelopment/Commands/ReviewRequireCommand.js +12 -0
  173. package/build/SubagentDrivenDevelopment/Commands/StatusCommand.js +21 -0
  174. package/build/SubagentDrivenDevelopment/Commands/SubmitCommand.js +59 -0
  175. package/build/SubagentDrivenDevelopment/Commands/TicketCommentCommand.js +24 -0
  176. package/build/SubagentDrivenDevelopment/Commands/TicketCreateCommand.js +25 -0
  177. package/build/SubagentDrivenDevelopment/Commands/TicketUpdateCommand.js +31 -0
  178. package/build/SubagentDrivenDevelopment/Commands/groups.js +36 -0
  179. package/build/SubagentDrivenDevelopment/Evidence/GitEvidence.js +449 -0
  180. package/build/SubagentDrivenDevelopment/Evidence/ReportEvidence.js +80 -0
  181. package/build/SubagentDrivenDevelopment/Models/Assignments.js +1 -0
  182. package/build/SubagentDrivenDevelopment/Models/Evidence.js +1 -0
  183. package/build/SubagentDrivenDevelopment/Models/Findings.js +1 -0
  184. package/build/SubagentDrivenDevelopment/Models/Options.js +1 -0
  185. package/build/SubagentDrivenDevelopment/Models/Workflow.js +16 -0
  186. package/build/SubagentDrivenDevelopment/Persistence/AssignmentSchema.js +155 -0
  187. package/build/SubagentDrivenDevelopment/Persistence/CheckSchema.js +71 -0
  188. package/build/SubagentDrivenDevelopment/Persistence/FeatureWorkspace.js +76 -0
  189. package/build/SubagentDrivenDevelopment/Persistence/FileSystem.js +28 -0
  190. package/build/SubagentDrivenDevelopment/Persistence/FindingSchema.js +81 -0
  191. package/build/SubagentDrivenDevelopment/Persistence/LedgerRepository.js +322 -0
  192. package/build/SubagentDrivenDevelopment/Persistence/PathSafety.js +62 -0
  193. package/build/SubagentDrivenDevelopment/Persistence/ProgressSchema.js +95 -0
  194. package/build/SubagentDrivenDevelopment/Persistence/ReadinessReader.js +40 -0
  195. package/build/SubagentDrivenDevelopment/Persistence/ReviewSchema.js +68 -0
  196. package/build/SubagentDrivenDevelopment/Persistence/TicketRepository.js +147 -0
  197. package/build/SubagentDrivenDevelopment/Persistence/WorkspaceTransaction.js +282 -0
  198. package/build/SubagentDrivenDevelopment/Policies/AcceptancePolicy.js +100 -0
  199. package/build/SubagentDrivenDevelopment/Policies/AssignmentPolicy.js +36 -0
  200. package/build/SubagentDrivenDevelopment/Policies/CheckPolicy.js +93 -0
  201. package/build/SubagentDrivenDevelopment/Policies/FindingPolicy.js +53 -0
  202. package/build/SubagentDrivenDevelopment/Policies/InputValidation.js +36 -0
  203. package/build/SubagentDrivenDevelopment/Policies/ReadinessPolicy.js +26 -0
  204. package/build/SubagentDrivenDevelopment/Policies/RequiredReviewers.js +12 -0
  205. package/build/SubagentDrivenDevelopment/Policies/ReviewPolicy.js +87 -0
  206. package/build/SubagentDrivenDevelopment/Policies/WorkflowPolicy.js +85 -0
  207. package/build/SubagentDrivenDevelopment/Services/AssignmentService.js +269 -0
  208. package/build/SubagentDrivenDevelopment/Services/ChecksService.js +319 -0
  209. package/build/SubagentDrivenDevelopment/Services/CorrectionService.js +273 -0
  210. package/build/SubagentDrivenDevelopment/Services/DeliveryCorrectionService.js +253 -0
  211. package/build/SubagentDrivenDevelopment/Services/DeliveryFindingService.js +302 -0
  212. package/build/SubagentDrivenDevelopment/Services/DeliveryService.js +160 -0
  213. package/build/SubagentDrivenDevelopment/Services/DeliverySubmissionService.js +273 -0
  214. package/build/SubagentDrivenDevelopment/Services/FeatureCreationService.js +138 -0
  215. package/build/SubagentDrivenDevelopment/Services/FeatureInspectionService.js +399 -0
  216. package/build/SubagentDrivenDevelopment/Services/FindingService.js +392 -0
  217. package/build/SubagentDrivenDevelopment/Services/IntegrationService.js +258 -0
  218. package/build/SubagentDrivenDevelopment/Services/ReadinessService.js +21 -0
  219. package/build/SubagentDrivenDevelopment/Services/RequirementsService.js +216 -0
  220. package/build/SubagentDrivenDevelopment/Services/ReviewService.js +471 -0
  221. package/build/SubagentDrivenDevelopment/Services/SubmissionService.js +299 -0
  222. package/build/SubagentDrivenDevelopment/Services/TicketService.js +186 -0
  223. package/build/SubagentDrivenDevelopment/SubagentDrivenDevelopmentServiceProvider.js +113 -0
  224. package/build/Support/Records.js +5 -0
  225. package/build/Support/Repository.js +139 -0
  226. package/build/Support/Stacks.js +10 -0
  227. package/build/TemplateRendering/Computed/ComputedContextService.js +13 -0
  228. package/build/TemplateRendering/Computed/ComputedVariableProvider.js +6 -0
  229. package/build/TemplateRendering/Computed/ComputedVariableProviders.js +6 -0
  230. package/build/TemplateRendering/Computed/Providers/InternalSkillDescriptionProvider.js +6 -0
  231. package/build/TemplateRendering/Computed/Providers/SpindlePackageManagerProvider.js +11 -0
  232. package/build/TemplateRendering/Computed/ResolveRenderContext.js +18 -0
  233. package/build/TemplateRendering/Rendering/RenderText.js +43 -0
  234. package/build/TemplateRendering/TemplateRenderingServiceProvider.js +8 -0
  235. package/build/Tooling/Commands/ToolingAddCommand.js +29 -0
  236. package/build/Tooling/Commands/ToolingListCommand.js +19 -0
  237. package/build/Tooling/Commands/ToolingRemoveCommand.js +19 -0
  238. package/build/Tooling/Commands/ToolingUpdateCommand.js +30 -0
  239. package/build/Tooling/Commands/groups.js +4 -0
  240. package/build/Tooling/Models/ToolingEntry.js +1 -0
  241. package/build/Tooling/Services/ToolingService.js +278 -0
  242. package/build/Tooling/ToolingServiceProvider.js +15 -0
  243. package/build/cli.js +36 -0
  244. package/build/index.js +31 -0
  245. package/package.json +54 -3
@@ -0,0 +1,399 @@
1
+ import { realpathSync } from "node:fs";
2
+ import { isAbsolute, relative, resolve, sep } from "node:path";
3
+ import { Service } from "../../Foundation/Service.js";
4
+ import { FEATURE_DIRECTORY, HISTORICAL_DATE_DIRECTORY, } from "../Models/Workflow.js";
5
+ import { isPathInside } from "../Persistence/FileSystem.js";
6
+ import { requiredDeliveryReviewers } from "../Policies/RequiredReviewers.js";
7
+ export class FeatureInspectionService extends Service {
8
+ gitEvidence;
9
+ reportEvidence;
10
+ featureWorkspace;
11
+ ticketRepository;
12
+ acceptancePolicy;
13
+ assignmentPolicy;
14
+ checkPolicy;
15
+ findingPolicy;
16
+ reviewPolicy;
17
+ constructor(app, gitEvidence, reportEvidence, featureWorkspace, ticketRepository, acceptancePolicy, assignmentPolicy, checkPolicy, findingPolicy, reviewPolicy) {
18
+ super(app);
19
+ this.gitEvidence = gitEvidence;
20
+ this.reportEvidence = reportEvidence;
21
+ this.featureWorkspace = featureWorkspace;
22
+ this.ticketRepository = ticketRepository;
23
+ this.acceptancePolicy = acceptancePolicy;
24
+ this.assignmentPolicy = assignmentPolicy;
25
+ this.checkPolicy = checkPolicy;
26
+ this.findingPolicy = findingPolicy;
27
+ this.reviewPolicy = reviewPolicy;
28
+ }
29
+ status({ spec }) {
30
+ const feature = this.resolvePaths(spec);
31
+ const tickets = this.ticketRepository.readTickets(feature.workspace);
32
+ this.ticketRepository.validateDependencyGraph(tickets);
33
+ const byId = new Map(tickets.map((ticket) => [ticket.id, ticket]));
34
+ const progressById = new Map(feature.state.tickets.map((item) => [item.id, item]));
35
+ let checkoutChanges;
36
+ try {
37
+ checkoutChanges = this.gitEvidence.gitChangeSummary(feature);
38
+ }
39
+ catch {
40
+ checkoutChanges = undefined;
41
+ }
42
+ const actions = [];
43
+ const snapshots = [];
44
+ const findings = [];
45
+ const requirementsDecisions = [];
46
+ const pendingAssignments = [];
47
+ const blockers = [];
48
+ for (const progress of feature.state.tickets) {
49
+ const ticket = byId.get(progress.id);
50
+ if (!ticket) {
51
+ blockers.push({ ticket: progress.id, reason: "Ticket Markdown is missing." });
52
+ continue;
53
+ }
54
+ const identity = this.gitEvidence.contentIdentity(feature, ticket, progress.baseSha, progress.checks);
55
+ snapshots.push({ ticket: progress.id, ...identity });
56
+ if (ticket.status === "closed")
57
+ continue;
58
+ for (const finding of progress.findings ?? []) {
59
+ findings.push({ ticket: progress.id, finding });
60
+ }
61
+ for (const decision of progress.requirementsDecisions ?? []) {
62
+ requirementsDecisions.push({ ticket: progress.id, decision });
63
+ if (decision.status === "rejected" &&
64
+ decision.requirementsSnapshot === identity.requirementsSnapshot) {
65
+ blockers.push({
66
+ ticket: progress.id,
67
+ reason: `Requirements decision ${decision.id} was rejected; acceptance requires an approved decision and fresh review.`,
68
+ });
69
+ }
70
+ }
71
+ const checkBlockers = this.checkPolicy.checkBlockers(feature, ticket, progress, identity);
72
+ for (const reason of checkBlockers)
73
+ blockers.push({ ticket: progress.id, reason });
74
+ for (const reason of this.findingPolicy.findingBlockers(progress, identity)) {
75
+ blockers.push({ ticket: progress.id, reason });
76
+ }
77
+ if (progress.adjudication?.status === "pending") {
78
+ blockers.push({
79
+ ticket: progress.id,
80
+ reason: `Correction is paused for adjudication (${progress.adjudication.reason}).`,
81
+ });
82
+ actions.push({ ticket: progress.id, action: "adjudicate" });
83
+ continue;
84
+ }
85
+ if (progress.execution === "unstarted") {
86
+ if (ticket.status !== "open" || ticket.blocker) {
87
+ blockers.push({
88
+ ticket: progress.id,
89
+ reason: ticket.blocker ?? `Ticket status is ${ticket.status}.`,
90
+ });
91
+ continue;
92
+ }
93
+ const unmet = ticket.blocked_by.filter((dependency) => {
94
+ const dependencyTicket = byId.get(dependency);
95
+ return (!dependencyTicket || dependencyTicket.status !== "closed" || !!dependencyTicket.blocker);
96
+ });
97
+ if (unmet.length > 0) {
98
+ blockers.push({
99
+ ticket: progress.id,
100
+ reason: `Dependencies are not closed: ${unmet.join(", ")}.`,
101
+ });
102
+ continue;
103
+ }
104
+ if (checkoutChanges === undefined) {
105
+ blockers.push({
106
+ ticket: progress.id,
107
+ reason: "Checkout cleanliness could not be verified; claim is unavailable.",
108
+ });
109
+ continue;
110
+ }
111
+ if (checkoutChanges) {
112
+ blockers.push({
113
+ ticket: progress.id,
114
+ reason: `Checkout is dirty; claim requires no staged, unstaged, or untracked changes: ${checkoutChanges}`,
115
+ });
116
+ continue;
117
+ }
118
+ actions.push({ ticket: progress.id, action: "claim" });
119
+ }
120
+ else if (progress.execution === "claimed") {
121
+ if (progress.owner && progress.baseSha) {
122
+ actions.push({ ticket: progress.id, action: "implement" });
123
+ }
124
+ else {
125
+ blockers.push({
126
+ ticket: progress.id,
127
+ reason: "Claim has no recorded owner or baseline; implementation is unavailable.",
128
+ });
129
+ }
130
+ }
131
+ else if (progress.execution === "implementing") {
132
+ if (progress.assignment) {
133
+ pendingAssignments.push({
134
+ ticket: progress.id,
135
+ id: progress.assignment.id,
136
+ role: progress.assignment.role,
137
+ action: progress.assignment.action,
138
+ report: progress.assignment.report,
139
+ status: progress.assignment.status,
140
+ });
141
+ if (progress.assignment.status === "submitted") {
142
+ const reason = this.assignmentPolicy.implementationReportBlocker(feature, progress.assignment);
143
+ if (reason)
144
+ blockers.push({ ticket: progress.id, reason });
145
+ else if (checkBlockers.length === 0)
146
+ actions.push({ ticket: progress.id, action: "review" });
147
+ }
148
+ else {
149
+ actions.push({ ticket: progress.id, action: "await-implementation-report" });
150
+ }
151
+ }
152
+ else {
153
+ blockers.push({
154
+ ticket: progress.id,
155
+ reason: "Implementation is marked in progress without a recorded assignment.",
156
+ });
157
+ }
158
+ }
159
+ else if (progress.execution === "reviewing") {
160
+ const reason = this.assignmentPolicy.implementationReportBlocker(feature, progress.assignment);
161
+ if (reason) {
162
+ blockers.push({ ticket: progress.id, reason });
163
+ continue;
164
+ }
165
+ const reviewCheckBlockers = this.checkPolicy.reviewCheckBlockers(feature, ticket, progress, identity);
166
+ for (const blocker of reviewCheckBlockers)
167
+ blockers.push({ ticket: progress.id, reason: blocker });
168
+ const latestAttempt = progress.correctionAttempts?.at(-1);
169
+ const assignments = progress.assignment?.action === "correct"
170
+ ? (latestAttempt?.reviewAssignments ?? [])
171
+ : (progress.reviewAssignments ?? []);
172
+ for (const assignment of assignments) {
173
+ if (assignment.status === "pending") {
174
+ pendingAssignments.push({
175
+ ticket: progress.id,
176
+ id: assignment.id,
177
+ role: assignment.role,
178
+ action: "review",
179
+ report: assignment.report,
180
+ status: assignment.status,
181
+ agent: assignment.agent,
182
+ scope: assignment.scope,
183
+ ...(assignment.objective ? { objective: assignment.objective } : {}),
184
+ });
185
+ }
186
+ const assignmentBlocker = this.reviewPolicy.reviewAssignmentBlocker(feature, progress, assignment, identity);
187
+ if (assignmentBlocker)
188
+ blockers.push({ ticket: progress.id, reason: assignmentBlocker });
189
+ }
190
+ if (reviewCheckBlockers.length === 0) {
191
+ if (assignments.length === 0)
192
+ actions.push({ ticket: progress.id, action: "review" });
193
+ else if (assignments.some((assignment) => assignment.status === "pending")) {
194
+ actions.push({ ticket: progress.id, action: "await-review-report" });
195
+ }
196
+ else if (assignments.every((assignment) => assignment.status === "submitted" && assignment.result === "passed") &&
197
+ assignments.every((assignment) => this.reviewPolicy.reviewAssignmentBlocker(feature, progress, assignment, identity) === undefined)) {
198
+ actions.push({
199
+ ticket: progress.id,
200
+ action: this.findingPolicy.findingBlockers(progress, identity).length > 0
201
+ ? "resolve-findings"
202
+ : "accept",
203
+ });
204
+ }
205
+ }
206
+ else if (progress.assignment?.status === "submitted" &&
207
+ reviewCheckBlockers.some((blocker) => blocker.includes(" is failed."))) {
208
+ actions.push({ ticket: progress.id, action: "correct" });
209
+ }
210
+ }
211
+ else if (progress.execution === "changes-requested") {
212
+ blockers.push({
213
+ ticket: progress.id,
214
+ reason: "A correction decision is required before another implementation dispatch.",
215
+ });
216
+ actions.push({
217
+ ticket: progress.id,
218
+ action: (progress.findings ?? []).some((finding) => finding.status === "confirmed") ||
219
+ (progress.correctionAttempts?.length ?? 0) > 0
220
+ ? "correct"
221
+ : this.findingPolicy.findingBlockers(progress, identity).length > 0
222
+ ? "adjudicate-findings"
223
+ : "controller-correction-decision",
224
+ });
225
+ }
226
+ else if (progress.execution === "blocked") {
227
+ blockers.push({ ticket: progress.id, reason: "Ticket execution is blocked." });
228
+ }
229
+ else if (progress.execution === "accepted") {
230
+ const acceptanceBlockers = this.acceptancePolicy.acceptBlockers(feature, feature.state, ticket, progress, identity);
231
+ for (const reason of acceptanceBlockers) {
232
+ if (!blockers.some((blocker) => blocker.ticket === progress.id && blocker.reason === reason)) {
233
+ blockers.push({ ticket: progress.id, reason });
234
+ }
235
+ }
236
+ if (acceptanceBlockers.length === 0)
237
+ actions.push({ ticket: progress.id, action: "integrate" });
238
+ }
239
+ }
240
+ for (const ticket of tickets) {
241
+ if (!progressById.has(ticket.id)) {
242
+ blockers.push({ ticket: ticket.id, reason: "Ticket has no ledger execution record." });
243
+ }
244
+ }
245
+ const delivery = this.deliveryStatus(feature, feature.state, tickets);
246
+ return {
247
+ ...feature,
248
+ snapshots,
249
+ findings,
250
+ requirementsDecisions,
251
+ actions,
252
+ pendingAssignments,
253
+ blockers,
254
+ delivery,
255
+ };
256
+ }
257
+ resolveFeature(spec) {
258
+ const absoluteSpec = isAbsolute(spec) ? relative(this.app.workspaceRoot, spec) : spec;
259
+ return this.resolvePaths(absoluteSpec);
260
+ }
261
+ resolvePaths(spec) {
262
+ this.assertApplicationBooted();
263
+ if (!spec.trim())
264
+ throw new Error("Spec path must not be empty.");
265
+ if (spec.includes("\\"))
266
+ throw new Error("Spec path must use checkout-relative path separators.");
267
+ const inputSegments = spec.startsWith("/") ? spec.slice(1).split("/") : spec.split("/");
268
+ if (inputSegments.some((segment) => !segment || segment === "." || segment === "..")) {
269
+ throw new Error("Spec path must not contain empty, current, or parent path segments.");
270
+ }
271
+ const root = realpathSync(this.app.workspaceRoot);
272
+ const specPath = resolve(root, spec);
273
+ if (!isPathInside(root, specPath))
274
+ throw new Error("Spec must be inside this checkout.");
275
+ const relativeSpec = relative(root, specPath);
276
+ const segments = relativeSpec.split(sep);
277
+ if (segments.length !== 3 ||
278
+ segments[0] !== ".scratch" ||
279
+ segments[2] !== "spec.md" ||
280
+ HISTORICAL_DATE_DIRECTORY.test(segments[1] ?? "") ||
281
+ !FEATURE_DIRECTORY.test(segments[1] ?? "")) {
282
+ throw new Error("Spec must be spec.md in a numbered feature workspace under .scratch.");
283
+ }
284
+ return this.featureWorkspace.statusFromPaths(root, specPath, relativeSpec, segments);
285
+ }
286
+ deliveryStatus(feature, ledger, tickets) {
287
+ const delivery = ledger.delivery;
288
+ const blockers = [];
289
+ const allClosed = ledger.tickets.length > 0 && ledger.tickets.every((ticket) => ticket.status === "closed");
290
+ let identity;
291
+ if (!allClosed) {
292
+ const missing = ledger.tickets
293
+ .filter((ticket) => ticket.status !== "closed")
294
+ .map((ticket) => ticket.id);
295
+ blockers.push(`Tickets are not closed: ${missing.join(", ") || "feature has no tickets"}.`);
296
+ }
297
+ else {
298
+ try {
299
+ identity = this.gitEvidence.deliveryIdentity(feature, ledger, tickets);
300
+ blockers.push(...this.checkPolicy.deliveryCheckBlockers(delivery, identity));
301
+ if (delivery.adjudication?.status === "pending") {
302
+ blockers.push(`Correction is paused for adjudication (${delivery.adjudication.reason}).`);
303
+ }
304
+ blockers.push(...this.findingPolicy.deliveryFindingBlockers(feature, ledger, delivery, identity));
305
+ const required = requiredDeliveryReviewers(ledger, delivery);
306
+ const assignments = delivery.reviewAssignments ?? [];
307
+ if (assignments.length !== required.length) {
308
+ blockers.push("Aggregate review assignment batch is incomplete.");
309
+ }
310
+ for (const item of required) {
311
+ const matching = assignments.filter((assignment) => assignment.agent === item.agent &&
312
+ assignment.objective === item.details &&
313
+ assignment.scope === "delivery");
314
+ if (matching.length !== 1) {
315
+ blockers.push(`Required aggregate reviewer '${item.agent}' has no unique current assignment.`);
316
+ continue;
317
+ }
318
+ const assignment = matching[0];
319
+ if (assignment.status !== "submitted" || assignment.result !== "passed") {
320
+ blockers.push(`Required aggregate review '${item.agent}' is ${assignment.status === "pending" ? "pending" : (assignment.result ?? "incomplete")}.`);
321
+ }
322
+ else {
323
+ const reason = this.reviewPolicy.reviewAssignmentBlocker(feature, delivery, assignment, identity);
324
+ if (reason)
325
+ blockers.push(reason);
326
+ }
327
+ }
328
+ }
329
+ catch (error) {
330
+ blockers.push(error instanceof Error ? error.message : String(error));
331
+ }
332
+ }
333
+ if (delivery.finished?.report || delivery.finished?.reportSha256) {
334
+ try {
335
+ if (!delivery.finished.report ||
336
+ !delivery.finished.reportSha256 ||
337
+ this.reportEvidence.readReportDigest(feature, delivery.finished.report) !==
338
+ delivery.finished.reportSha256) {
339
+ blockers.push("Finished delivery retrospective evidence is stale or incomplete.");
340
+ }
341
+ }
342
+ catch {
343
+ blockers.push("Finished delivery retrospective evidence is unavailable or invalid.");
344
+ }
345
+ }
346
+ let action;
347
+ if (delivery.finished)
348
+ action = blockers.length > 0 ? "completion-invalidated" : "finished";
349
+ else if (!allClosed)
350
+ action = "close-tickets";
351
+ else if (delivery.adjudication?.status === "pending")
352
+ action = "adjudicate";
353
+ else if (delivery.assignment &&
354
+ ["pending", "unavailable"].includes(delivery.assignment.status)) {
355
+ action = "await-implementation-report";
356
+ }
357
+ else if (this.checkPolicy.deliveryCheckBlockers(delivery, identity ?? {
358
+ snapshot: "",
359
+ codeSnapshot: "",
360
+ requirementsSnapshot: "",
361
+ headSha: "",
362
+ }).length > 0) {
363
+ action = "record-final-checks";
364
+ }
365
+ else if (!(delivery.reviewAssignments ?? []).length ||
366
+ blockers.some((reason) => /aggregate review|reviewer|Review assignment/i.test(reason))) {
367
+ action = "review";
368
+ }
369
+ else if ((delivery.reviewAssignments ?? []).some((assignment) => assignment.status === "pending")) {
370
+ action = "await-review-report";
371
+ }
372
+ else if (this.findingPolicy.deliveryFindingBlockers(feature, ledger, delivery, identity ?? { snapshot: "", codeSnapshot: "", requirementsSnapshot: "", headSha: "" }).length > 0) {
373
+ action = "correct";
374
+ }
375
+ else if (blockers.length > 0)
376
+ action = "review";
377
+ else
378
+ action = "finish";
379
+ return {
380
+ scope: "delivery",
381
+ status: delivery.status ?? (delivery.finished ? "complete" : "active"),
382
+ execution: delivery.execution,
383
+ action,
384
+ ...identity,
385
+ ...(delivery.baseSha ? { baseSha: delivery.baseSha } : {}),
386
+ retrospectiveRequired: ledger.retrospectiveRequired,
387
+ finished: !!delivery.finished,
388
+ findings: delivery.findings ?? [],
389
+ correctionAttempts: delivery.correctionAttempts ?? [],
390
+ reviewRequirements: delivery.reviewRequirements ?? [],
391
+ reviewAssignments: delivery.reviewAssignments ?? [],
392
+ ...(delivery.assignment ? { assignment: delivery.assignment } : {}),
393
+ ...(delivery.adjudication ? { adjudication: delivery.adjudication } : {}),
394
+ requiredChecks: (delivery.checks?.required ?? []).filter((check) => !check.removedAt),
395
+ checkRecords: delivery.checks?.records ?? [],
396
+ blockers,
397
+ };
398
+ }
399
+ }