dna-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +58 -0
  3. package/dist/adapters/embedding/onnx.d.ts +32 -0
  4. package/dist/adapters/embedding/onnx.js +51 -0
  5. package/dist/adapters/filesystem/cache.d.ts +16 -0
  6. package/dist/adapters/filesystem/cache.js +113 -0
  7. package/dist/adapters/filesystem/index.d.ts +2 -0
  8. package/dist/adapters/filesystem/index.js +2 -0
  9. package/dist/adapters/filesystem/source.d.ts +82 -0
  10. package/dist/adapters/filesystem/source.js +357 -0
  11. package/dist/adapters/postgres/index.d.ts +2 -0
  12. package/dist/adapters/postgres/index.js +2 -0
  13. package/dist/adapters/postgres/migrations.d.ts +14 -0
  14. package/dist/adapters/postgres/migrations.js +88 -0
  15. package/dist/adapters/postgres/source.d.ts +172 -0
  16. package/dist/adapters/postgres/source.js +569 -0
  17. package/dist/adapters/resolvers/github.d.ts +12 -0
  18. package/dist/adapters/resolvers/github.js +47 -0
  19. package/dist/adapters/resolvers/http.d.ts +22 -0
  20. package/dist/adapters/resolvers/http.js +145 -0
  21. package/dist/adapters/resolvers/index.d.ts +3 -0
  22. package/dist/adapters/resolvers/index.js +3 -0
  23. package/dist/adapters/resolvers/local.d.ts +24 -0
  24. package/dist/adapters/resolvers/local.js +132 -0
  25. package/dist/adapters/search/driver.d.ts +45 -0
  26. package/dist/adapters/search/driver.js +138 -0
  27. package/dist/adapters/search/migrations.d.ts +26 -0
  28. package/dist/adapters/search/migrations.js +58 -0
  29. package/dist/adapters/search/rrf.d.ts +23 -0
  30. package/dist/adapters/search/rrf.js +42 -0
  31. package/dist/adapters/search/sqlite-vec.d.ts +66 -0
  32. package/dist/adapters/search/sqlite-vec.js +294 -0
  33. package/dist/bootstrap.d.ts +45 -0
  34. package/dist/bootstrap.js +134 -0
  35. package/dist/extensions/agentskills/DOCS.md +18 -0
  36. package/dist/extensions/agentskills.d.ts +28 -0
  37. package/dist/extensions/agentskills.js +252 -0
  38. package/dist/extensions/agentsmd/DOCS.md +18 -0
  39. package/dist/extensions/agentsmd.d.ts +22 -0
  40. package/dist/extensions/agentsmd.js +170 -0
  41. package/dist/extensions/audit/kinds/audit-log.kind.yaml +148 -0
  42. package/dist/extensions/audit.d.ts +25 -0
  43. package/dist/extensions/audit.js +62 -0
  44. package/dist/extensions/automation/kinds/automation.kind.yaml +296 -0
  45. package/dist/extensions/automation/query.d.ts +49 -0
  46. package/dist/extensions/automation/query.js +77 -0
  47. package/dist/extensions/automation/write-guards.d.ts +59 -0
  48. package/dist/extensions/automation/write-guards.js +153 -0
  49. package/dist/extensions/automation.d.ts +41 -0
  50. package/dist/extensions/automation.js +54 -0
  51. package/dist/extensions/collab.d.ts +16 -0
  52. package/dist/extensions/collab.js +79 -0
  53. package/dist/extensions/doc/kinds/doc.kind.yaml +118 -0
  54. package/dist/extensions/doc.d.ts +25 -0
  55. package/dist/extensions/doc.js +10 -0
  56. package/dist/extensions/eval/kinds/eval-baseline.kind.yaml +65 -0
  57. package/dist/extensions/eval/kinds/eval-case.kind.yaml +140 -0
  58. package/dist/extensions/eval/kinds/eval-run.kind.yaml +134 -0
  59. package/dist/extensions/eval/kinds/eval-suite.kind.yaml +87 -0
  60. package/dist/extensions/eval.d.ts +24 -0
  61. package/dist/extensions/eval.js +31 -0
  62. package/dist/extensions/evidence/kinds/evidence.kind.yaml +92 -0
  63. package/dist/extensions/evidence.d.ts +17 -0
  64. package/dist/extensions/evidence.js +94 -0
  65. package/dist/extensions/federation.d.ts +22 -0
  66. package/dist/extensions/federation.js +173 -0
  67. package/dist/extensions/guardrails/DOCS.md +20 -0
  68. package/dist/extensions/guardrails.d.ts +31 -0
  69. package/dist/extensions/guardrails.js +228 -0
  70. package/dist/extensions/helix/DOCS-Actor.md +20 -0
  71. package/dist/extensions/helix/DOCS-Agent.md +20 -0
  72. package/dist/extensions/helix/DOCS-UseCase.md +20 -0
  73. package/dist/extensions/helix/layers.d.ts +12 -0
  74. package/dist/extensions/helix/layers.js +18 -0
  75. package/dist/extensions/helix/write-guards.d.ts +70 -0
  76. package/dist/extensions/helix/write-guards.js +172 -0
  77. package/dist/extensions/helix.d.ts +29 -0
  78. package/dist/extensions/helix.js +963 -0
  79. package/dist/extensions/helix_extras.d.ts +124 -0
  80. package/dist/extensions/helix_extras.js +328 -0
  81. package/dist/extensions/hooks.d.ts +31 -0
  82. package/dist/extensions/hooks.js +247 -0
  83. package/dist/extensions/kinddef/DOCS.md +24 -0
  84. package/dist/extensions/kinddef.d.ts +40 -0
  85. package/dist/extensions/kinddef.js +171 -0
  86. package/dist/extensions/lesson.d.ts +6 -0
  87. package/dist/extensions/lesson.js +194 -0
  88. package/dist/extensions/modelreg/kinds/model-profile.kind.yaml +155 -0
  89. package/dist/extensions/modelreg.d.ts +30 -0
  90. package/dist/extensions/modelreg.js +38 -0
  91. package/dist/extensions/recognizer.d.ts +34 -0
  92. package/dist/extensions/recognizer.js +272 -0
  93. package/dist/extensions/research.d.ts +32 -0
  94. package/dist/extensions/research.js +292 -0
  95. package/dist/extensions/safety.d.ts +33 -0
  96. package/dist/extensions/safety.js +230 -0
  97. package/dist/extensions/sdlc/kinds/adr.kind.yaml +136 -0
  98. package/dist/extensions/sdlc/kinds/archive-proposal.kind.yaml +107 -0
  99. package/dist/extensions/sdlc/kinds/changelog.kind.yaml +108 -0
  100. package/dist/extensions/sdlc/kinds/cognitive-policy.kind.yaml +470 -0
  101. package/dist/extensions/sdlc/kinds/forecast.kind.yaml +125 -0
  102. package/dist/extensions/sdlc/kinds/insight.kind.yaml +87 -0
  103. package/dist/extensions/sdlc/kinds/kaizen.kind.yaml +106 -0
  104. package/dist/extensions/sdlc/kinds/lesson-learned.kind.yaml +270 -0
  105. package/dist/extensions/sdlc/kinds/narrative.kind.yaml +189 -0
  106. package/dist/extensions/sdlc/kinds/pattern-insight.kind.yaml +204 -0
  107. package/dist/extensions/sdlc/kinds/postmortem.kind.yaml +168 -0
  108. package/dist/extensions/sdlc/kinds/pre-mortem.kind.yaml +145 -0
  109. package/dist/extensions/sdlc/kinds/prompt-template.kind.yaml +109 -0
  110. package/dist/extensions/sdlc/kinds/retrospective.kind.yaml +186 -0
  111. package/dist/extensions/sdlc/kinds/risk-register.kind.yaml +178 -0
  112. package/dist/extensions/sdlc/kinds/saved-view.kind.yaml +127 -0
  113. package/dist/extensions/sdlc/kinds/status-report.kind.yaml +129 -0
  114. package/dist/extensions/sdlc/kinds/synthesis-run.kind.yaml +279 -0
  115. package/dist/extensions/sdlc/kinds/synthesizer-state.kind.yaml +196 -0
  116. package/dist/extensions/sdlc/kinds/workflow-event.kind.yaml +195 -0
  117. package/dist/extensions/sdlc.d.ts +32 -0
  118. package/dist/extensions/sdlc.js +1318 -0
  119. package/dist/extensions/soulspec/DOCS.md +19 -0
  120. package/dist/extensions/soulspec.d.ts +22 -0
  121. package/dist/extensions/soulspec.js +287 -0
  122. package/dist/extensions/tenant.d.ts +6 -0
  123. package/dist/extensions/tenant.js +291 -0
  124. package/dist/extensions/testkit.d.ts +24 -0
  125. package/dist/extensions/testkit.js +211 -0
  126. package/dist/index.d.ts +80 -0
  127. package/dist/index.js +102 -0
  128. package/dist/kernel/_text.d.ts +28 -0
  129. package/dist/kernel/_text.js +42 -0
  130. package/dist/kernel/bundle-handle.d.ts +83 -0
  131. package/dist/kernel/bundle-handle.js +184 -0
  132. package/dist/kernel/capabilities.d.ts +157 -0
  133. package/dist/kernel/capabilities.js +109 -0
  134. package/dist/kernel/collaborator-ports.d.ts +91 -0
  135. package/dist/kernel/collaborator-ports.js +1 -0
  136. package/dist/kernel/composition-resolver.d.ts +215 -0
  137. package/dist/kernel/composition-resolver.js +558 -0
  138. package/dist/kernel/composition.d.ts +10 -0
  139. package/dist/kernel/composition.js +1 -0
  140. package/dist/kernel/descriptor-loader.d.ts +13 -0
  141. package/dist/kernel/descriptor-loader.js +48 -0
  142. package/dist/kernel/document.d.ts +43 -0
  143. package/dist/kernel/document.js +71 -0
  144. package/dist/kernel/embedding.d.ts +28 -0
  145. package/dist/kernel/embedding.js +78 -0
  146. package/dist/kernel/errors.d.ts +62 -0
  147. package/dist/kernel/errors.js +82 -0
  148. package/dist/kernel/events.d.ts +6 -0
  149. package/dist/kernel/events.js +21 -0
  150. package/dist/kernel/evidence-capture.d.ts +69 -0
  151. package/dist/kernel/evidence-capture.js +138 -0
  152. package/dist/kernel/fs.d.ts +20 -0
  153. package/dist/kernel/fs.js +128 -0
  154. package/dist/kernel/generic-rw.d.ts +33 -0
  155. package/dist/kernel/generic-rw.js +235 -0
  156. package/dist/kernel/hooks.d.ts +172 -0
  157. package/dist/kernel/hooks.js +256 -0
  158. package/dist/kernel/index.d.ts +624 -0
  159. package/dist/kernel/index.js +1638 -0
  160. package/dist/kernel/instance.d.ts +211 -0
  161. package/dist/kernel/instance.js +487 -0
  162. package/dist/kernel/kind-registry.d.ts +183 -0
  163. package/dist/kernel/kind-registry.js +710 -0
  164. package/dist/kernel/kind_base.d.ts +106 -0
  165. package/dist/kernel/kind_base.js +244 -0
  166. package/dist/kernel/layer-resolver.d.ts +48 -0
  167. package/dist/kernel/layer-resolver.js +284 -0
  168. package/dist/kernel/lock-manager.d.ts +21 -0
  169. package/dist/kernel/lock-manager.js +43 -0
  170. package/dist/kernel/lock.d.ts +38 -0
  171. package/dist/kernel/lock.js +115 -0
  172. package/dist/kernel/meta.d.ts +135 -0
  173. package/dist/kernel/meta.js +817 -0
  174. package/dist/kernel/models.d.ts +3089 -0
  175. package/dist/kernel/models.js +764 -0
  176. package/dist/kernel/navigator.d.ts +36 -0
  177. package/dist/kernel/navigator.js +132 -0
  178. package/dist/kernel/port-surface.d.ts +33 -0
  179. package/dist/kernel/port-surface.js +180 -0
  180. package/dist/kernel/preview.d.ts +60 -0
  181. package/dist/kernel/preview.js +54 -0
  182. package/dist/kernel/prompt-budget.d.ts +39 -0
  183. package/dist/kernel/prompt-budget.js +43 -0
  184. package/dist/kernel/prompt-builder.d.ts +25 -0
  185. package/dist/kernel/prompt-builder.js +237 -0
  186. package/dist/kernel/protocols.d.ts +751 -0
  187. package/dist/kernel/protocols.js +493 -0
  188. package/dist/kernel/reports.d.ts +26 -0
  189. package/dist/kernel/reports.js +215 -0
  190. package/dist/kernel/resolver.d.ts +146 -0
  191. package/dist/kernel/resolver.js +232 -0
  192. package/dist/kernel/resource.d.ts +57 -0
  193. package/dist/kernel/resource.js +97 -0
  194. package/dist/kernel/runtime.d.ts +16 -0
  195. package/dist/kernel/runtime.js +18 -0
  196. package/dist/kernel/safety-scanner.d.ts +38 -0
  197. package/dist/kernel/safety-scanner.js +228 -0
  198. package/dist/kernel/serialize-to-files.d.ts +29 -0
  199. package/dist/kernel/serialize-to-files.js +23 -0
  200. package/dist/kernel/spec-access.d.ts +23 -0
  201. package/dist/kernel/spec-access.js +40 -0
  202. package/dist/kernel/studio_ui.d.ts +88 -0
  203. package/dist/kernel/studio_ui.js +135 -0
  204. package/dist/kernel/templates.d.ts +77 -0
  205. package/dist/kernel/templates.js +116 -0
  206. package/dist/kernel/tool-registry.d.ts +52 -0
  207. package/dist/kernel/tool-registry.js +89 -0
  208. package/dist/kernel/write-pipeline.d.ts +65 -0
  209. package/dist/kernel/write-pipeline.js +271 -0
  210. package/dist/kernel/writer-helpers.d.ts +24 -0
  211. package/dist/kernel/writer-helpers.js +42 -0
  212. package/dist/memory/decay.d.ts +31 -0
  213. package/dist/memory/decay.js +97 -0
  214. package/dist/memory/ecphory.d.ts +25 -0
  215. package/dist/memory/ecphory.js +178 -0
  216. package/dist/memory/encodingContext.d.ts +21 -0
  217. package/dist/memory/encodingContext.js +62 -0
  218. package/dist/memory/index.d.ts +23 -0
  219. package/dist/memory/index.js +23 -0
  220. package/dist/memory/memoryType.d.ts +7 -0
  221. package/dist/memory/memoryType.js +24 -0
  222. package/dist/memory/policy.d.ts +35 -0
  223. package/dist/memory/policy.js +35 -0
  224. package/dist/memory/retrieval.d.ts +21 -0
  225. package/dist/memory/retrieval.js +145 -0
  226. package/dist/testing/index.d.ts +8 -0
  227. package/dist/testing/index.js +8 -0
  228. package/dist/testing/recordSearchConformance.d.ts +43 -0
  229. package/dist/testing/recordSearchConformance.js +147 -0
  230. package/dist/viz/ascii.d.ts +7 -0
  231. package/dist/viz/ascii.js +60 -0
  232. package/dist/viz/health.d.ts +8 -0
  233. package/dist/viz/health.js +161 -0
  234. package/dist/viz/index.d.ts +10 -0
  235. package/dist/viz/index.js +10 -0
  236. package/dist/viz/matrix.d.ts +8 -0
  237. package/dist/viz/matrix.js +84 -0
  238. package/dist/viz/mermaid.d.ts +38 -0
  239. package/dist/viz/mermaid.js +706 -0
  240. package/package.json +82 -0
@@ -0,0 +1,1318 @@
1
+ /**
2
+ * SdlcExtension — software-development lifecycle Kinds.
3
+ *
4
+ * Seven Kinds for declarative product/engineering management as YAML/markdown:
5
+ *
6
+ * - Roadmap (sdlc-roadmap) — top-level, lists epics across horizons
7
+ * - Epic (sdlc-epic) — Jira/ADO-aligned aggregation umbrella; optional target date
8
+ * - Feature (sdlc-feature) — shippable unit; implements UseCases
9
+ * - Story (sdlc-story) — granular task with owner + estimate
10
+ * - Issue (sdlc-issue) — bug/enhancement/question/task; can link to a Finding
11
+ * - Spec (sdlc-spec) — top-level design artifact (ADR-style)
12
+ * - Plan (sdlc-plan) — implementation plan, child of a Spec
13
+ *
14
+ * 1:1 parity with Python ``dna.extensions.sdlc`` for the KIND
15
+ * surface (registration, descriptors, schemas, write-guards).
16
+ *
17
+ * Known Py-only helpers (verified 2026-07-08, s-dna-sdlc-cli-extraction —
18
+ * documented here on purpose, not silently): ``journey_derive.py`` (the
19
+ * derived per-work-item journey computation consumed by the server journey/
20
+ * focus routes and the CLI) and ``work_item_outputs.py`` (produces[]
21
+ * resolution) have NO TS twin. They are pure read-side helpers OVER Kind
22
+ * data, not Kind behavior — port them when a TS consumer needs the derived
23
+ * journey, and add their members to the parity fixtures at that point.
24
+ *
25
+ * v1.3 BREAKING: Milestone Kind renamed to Epic.
26
+ */
27
+ import { KindBase } from "../kernel/kind_base.js";
28
+ import { SD, TenantScope } from "../kernel/protocols.js";
29
+ import { loadDescriptors } from "../kernel/descriptor-loader.js";
30
+ const API_VERSION = "github.com/ruinosus/dna/sdlc/v1";
31
+ // v1.3: MILESTONE_STATUSES → EPIC_STATUSES (Jira/ADO alignment).
32
+ const EPIC_STATUSES = ["planning", "in-progress", "done", "cancelled", "deprecated"];
33
+ const FEATURE_STATUSES = ["discovery", "in-development", "done", "cancelled", "blocked"];
34
+ // 2026-05-26 — rec-triage-as-status (Py twin): needs-triage prepended,
35
+ // deferred antes de cancelled. Stories existentes em `todo` permanecem.
36
+ const STORY_STATUSES = [
37
+ "needs-triage",
38
+ "todo",
39
+ "in-progress",
40
+ "review",
41
+ "done",
42
+ "blocked",
43
+ "deferred",
44
+ "cancelled",
45
+ ];
46
+ const ISSUE_STATUSES = ["open", "triaged", "in-progress", "resolved", "wont-fix", "duplicate"];
47
+ const ISSUE_TYPES = ["bug", "enhancement", "question", "task"];
48
+ const ISSUE_SEVERITIES = ["low", "medium", "high", "critical"];
49
+ // v1.13: the Kaizen observation arc (observed → routed → resolved) lives
50
+ // ONLY in the descriptor sdlc/kinds/kaizen.kind.yaml since F3 P2 — the
51
+ // enum is the schema's `status.enum`; CLI call sites use literals.
52
+ // v1.5: shared priority enum across Story/Feature/Epic/Issue (Jira-aligned).
53
+ const PRIORITIES = ["highest", "high", "medium", "low", "lowest"];
54
+ // Universal journey phases — additive layer over Story/Feature/Epic
55
+ // status, Spec phase, etc. Maps to Superpowers / BMAD / Spec Kit / Kiro.
56
+ const JOURNEY_PHASES = ["discover", "specify", "plan", "build", "verify", "reflect"];
57
+ // v1.6: Activity Timeline event types — RECOGNIZED names, but the schema
58
+ // deliberately does NOT close the vocabulary (no enum): documentation-style
59
+ // so future types just work. Load-bearing since s-write-path-validation
60
+ // (i-008): writes really validate now, and the CLI already stamps types
61
+ // beyond these five ("pr_opened" from `dna sdlc story pr`).
62
+ const TIMELINE_TYPES = [
63
+ "status_change", "groom", "comment", "decision", "artifact_produced",
64
+ ];
65
+ const TIMELINE_SOURCES = [
66
+ "cli", "studio", "agent-session-extracted", "system",
67
+ ];
68
+ // produces[] — a work item is a HUB of the artifacts it produced, of ANY
69
+ // Kind (mirror of AgentSession.produced_artifacts + the Python
70
+ // _produces_field_schema). Read by the derived journey + FOCUS panel +
71
+ // `dna sdlc produces list` via resolveWorkItemOutputs (produces ∪ legacy).
72
+ // Parity: keep byte-aligned with packages/sdk-py .../sdlc/__init__.py.
73
+ function producesFieldSchema() {
74
+ return {
75
+ type: "array",
76
+ description: "Artifacts this work item produced — any Kind (hub).",
77
+ items: {
78
+ type: "object",
79
+ required: ["kind", "name"],
80
+ additionalProperties: true,
81
+ properties: {
82
+ kind: { type: "string", description: "Artifact Kind (any)." },
83
+ name: { type: "string", description: "Artifact doc name." },
84
+ role: { type: "string", description: "Optional role hint (e.g. visual-spec, plan, investigation)." },
85
+ at: { type: "string", format: "date-time" },
86
+ },
87
+ },
88
+ };
89
+ }
90
+ function timelineFieldSchema() {
91
+ return {
92
+ type: "array",
93
+ description: "Append-only activity log. Auto-stamped by the CLI on every " +
94
+ "status flip / groom / artifact write; populated by AgentSession " +
95
+ "capture for decision + artifact_produced events.",
96
+ items: {
97
+ type: "object",
98
+ required: ["at", "actor", "type"],
99
+ additionalProperties: true,
100
+ properties: {
101
+ at: { type: "string", format: "date-time" },
102
+ actor: { type: "string" },
103
+ type: {
104
+ type: "string",
105
+ description: "Event type. Recognized: " + TIMELINE_TYPES.join(", ") +
106
+ " (open vocabulary — new types are additive, e.g. pr_opened).",
107
+ },
108
+ source: { type: "string", enum: [...TIMELINE_SOURCES] },
109
+ from: { type: "string" },
110
+ to: { type: "string" },
111
+ fields: { type: "object" },
112
+ summary: { type: "string" },
113
+ excerpt: { type: "string" },
114
+ paths: { type: "array", items: { type: "string" } },
115
+ commit_ref: { type: "string" },
116
+ session_ref: { type: "string" },
117
+ },
118
+ },
119
+ };
120
+ }
121
+ // ---------------------------------------------------------------------------
122
+ // Roadmap
123
+ // ---------------------------------------------------------------------------
124
+ class RoadmapKind extends KindBase {
125
+ apiVersion = API_VERSION;
126
+ scope = TenantScope.GLOBAL; // SDLC primitives are project-level
127
+ kind = "Roadmap";
128
+ alias = "sdlc-roadmap";
129
+ scopeInheritable = false;
130
+ origin = "github.com/ruinosus/dna/sdlc";
131
+ isPromptTarget = false;
132
+ promptTargetPriority = 0;
133
+ flattenInContext = false;
134
+ plane = "record";
135
+ storage = SD.yaml("roadmaps");
136
+ graphStyle = { fill: "#0EA5E9", stroke: "#0284C7", textColor: "#fff" };
137
+ asciiIcon = "🗺️";
138
+ displayLabel = "Roadmaps";
139
+ docs = "A Roadmap groups Epics across time horizons (e.g. Q1 2026, " +
140
+ "Q2 2026). Pure organizational doc — no status of its own; the " +
141
+ "rolled-up status comes from the Epics it lists.";
142
+ depFilters() { return { epics: "sdlc-epic" }; }
143
+ schema() {
144
+ return {
145
+ type: "object",
146
+ required: ["description", "horizons"],
147
+ additionalProperties: true,
148
+ properties: {
149
+ description: { type: "string" },
150
+ owner_team: { type: "string" },
151
+ horizons: {
152
+ type: "array",
153
+ items: {
154
+ type: "object",
155
+ required: ["label", "epics"],
156
+ properties: {
157
+ label: { type: "string", description: "e.g. 'Q1 2026'" },
158
+ start_date: { type: "string", format: "date" },
159
+ end_date: { type: "string", format: "date" },
160
+ epics: {
161
+ type: "array",
162
+ items: { type: "string" },
163
+ description: "Names of Epic docs in this horizon",
164
+ },
165
+ },
166
+ },
167
+ },
168
+ links: {
169
+ type: "array",
170
+ items: { type: "string" },
171
+ description: "External URLs (Confluence, Notion, etc.)",
172
+ },
173
+ },
174
+ };
175
+ }
176
+ summary(doc) {
177
+ const spec = (doc.spec ?? {});
178
+ const horizons = spec.horizons ?? [];
179
+ const total = horizons.reduce((sum, h) => sum + (h.epics?.length ?? 0), 0);
180
+ const desc = spec.description ?? "";
181
+ return {
182
+ description: desc.slice(0, 80),
183
+ horizons: horizons.length,
184
+ epics: total,
185
+ };
186
+ }
187
+ }
188
+ // ---------------------------------------------------------------------------
189
+ // Epic — Jira/ADO-aligned aggregation umbrella (was Milestone in v1.2)
190
+ // ---------------------------------------------------------------------------
191
+ class EpicKind extends KindBase {
192
+ apiVersion = API_VERSION;
193
+ scope = TenantScope.GLOBAL; // SDLC primitives are project-level
194
+ kind = "Epic";
195
+ alias = "sdlc-epic";
196
+ origin = "github.com/ruinosus/dna/sdlc";
197
+ isPromptTarget = false;
198
+ promptTargetPriority = 0;
199
+ flattenInContext = false;
200
+ plane = "record";
201
+ storage = SD.yaml("epics");
202
+ graphStyle = { fill: "#8B5CF6", stroke: "#7C3AED", textColor: "#fff" };
203
+ asciiIcon = "🎯";
204
+ displayLabel = "Epics";
205
+ docs = "An Epic groups Features under a single business goal " +
206
+ "(Jira/ADO terminology). May optionally carry a target_date when " +
207
+ "the Epic doubles as a dated release; otherwise it's a pure " +
208
+ "aggregation umbrella. status: planning → in-progress → done.";
209
+ depFilters() { return { features: "sdlc-feature" }; }
210
+ schema() {
211
+ return {
212
+ type: "object",
213
+ required: ["status"], // v1.3: target_date no longer required
214
+ additionalProperties: true,
215
+ properties: {
216
+ title: {
217
+ type: "string",
218
+ description: "Human-readable display name (Jira 'summary').",
219
+ },
220
+ description: { type: "string" },
221
+ target_date: { type: "string", format: "date" },
222
+ status: { type: "string", enum: [...EPIC_STATUSES] },
223
+ target_package: {
224
+ type: "string",
225
+ description: "owner/name reference to a Genome",
226
+ },
227
+ target_version: {
228
+ type: "string",
229
+ description: "Semver to match Genome.spec.version when done",
230
+ },
231
+ features: { type: "array", items: { type: "string" } },
232
+ closed_at: { type: "string", format: "date-time" },
233
+ cancelled_reason: { type: "string" },
234
+ // v1.5 — board-grade common fields. Epics drop sprint_ref +
235
+ // time_tracking + mockups + release_target.
236
+ priority: { type: "string", enum: [...PRIORITIES] },
237
+ labels: { type: "array", items: { type: "string" } },
238
+ reporter: { type: "string" },
239
+ watchers: { type: "array", items: { type: "string" } },
240
+ journey_phase: { type: "string", enum: [...JOURNEY_PHASES] },
241
+ created_at: { type: "string", format: "date-time" },
242
+ updated_at: { type: "string", format: "date-time" },
243
+ definition_of_done: { type: "array", items: { type: "string" } },
244
+ business_value: { type: "number", minimum: 0, maximum: 1000 },
245
+ produces: producesFieldSchema(),
246
+ timeline: timelineFieldSchema(),
247
+ },
248
+ };
249
+ }
250
+ summary(doc) {
251
+ const spec = (doc.spec ?? {});
252
+ return {
253
+ status: spec.status ?? "planning",
254
+ target_date: spec.target_date ?? "",
255
+ target_package: spec.target_package ?? "",
256
+ target_version: spec.target_version ?? "",
257
+ features: (spec.features ?? []).length,
258
+ priority: spec.priority ?? "medium",
259
+ labels: spec.labels ?? [],
260
+ business_value: spec.business_value,
261
+ };
262
+ }
263
+ }
264
+ // ---------------------------------------------------------------------------
265
+ // Feature
266
+ // ---------------------------------------------------------------------------
267
+ class FeatureKind extends KindBase {
268
+ apiVersion = API_VERSION;
269
+ scope = TenantScope.GLOBAL; // SDLC primitives are project-level
270
+ kind = "Feature";
271
+ alias = "sdlc-feature";
272
+ scopeInheritable = false;
273
+ origin = "github.com/ruinosus/dna/sdlc";
274
+ isPromptTarget = false;
275
+ promptTargetPriority = 0;
276
+ flattenInContext = false;
277
+ plane = "record";
278
+ storage = SD.yaml("features");
279
+ graphStyle = { fill: "#10B981", stroke: "#059669", textColor: "#fff" };
280
+ asciiIcon = "🚀";
281
+ displayLabel = "Features";
282
+ docs = "A Feature is a shippable unit. It implements one or more " +
283
+ "UseCases, decomposes into Stories, and is owned by an Actor. " +
284
+ "Its status reflects the development pipeline: discovery → " +
285
+ "in-development → done.";
286
+ depFilters() {
287
+ return {
288
+ stories: "sdlc-story",
289
+ use_cases: "helix-usecase",
290
+ owner: "helix-actor",
291
+ epic: "sdlc-epic",
292
+ };
293
+ }
294
+ schema() {
295
+ return {
296
+ type: "object",
297
+ required: ["description", "status"],
298
+ additionalProperties: true,
299
+ properties: {
300
+ title: { type: "string", description: "Human-readable display name." },
301
+ description: { type: "string" },
302
+ // User-story slots (2026-05-11 UX audit) — Py parity.
303
+ as_a: { type: "string", description: "Role: 'As a <role>'." },
304
+ i_want: { type: "string", description: "Goal: 'I want <goal>'." },
305
+ so_that: { type: "string", description: "Benefit: 'so that <benefit>'." },
306
+ acceptance_criteria: { type: "array", items: { type: "string" } },
307
+ definition_of_done: { type: "array", items: { type: "string" } },
308
+ narrative_line: {
309
+ type: "string",
310
+ description: "One-sentence agent-curated prose summary of what this " +
311
+ "Feature has been DOING (past-tense, semantic) — shown next " +
312
+ "to the Feature in Studio's narrative swimlane. Distinct " +
313
+ "from `description` (intent / problem statement).",
314
+ },
315
+ status: { type: "string", enum: [...FEATURE_STATUSES] },
316
+ epic: { type: "string", description: "Parent Epic name" },
317
+ stories: { type: "array", items: { type: "string" } },
318
+ use_cases: { type: "array", items: { type: "string" } },
319
+ owner: { type: "string", description: "Actor name" },
320
+ estimate: {
321
+ type: "string",
322
+ description: "T-shirt size or story points (free-form)",
323
+ },
324
+ closed_at: { type: "string", format: "date-time" },
325
+ blocked_reason: { type: "string" },
326
+ // v1.5 — board-grade fields.
327
+ priority: { type: "string", enum: [...PRIORITIES] },
328
+ labels: { type: "array", items: { type: "string" } },
329
+ reporter: { type: "string" },
330
+ watchers: { type: "array", items: { type: "string" } },
331
+ journey_phase: { type: "string", enum: [...JOURNEY_PHASES] },
332
+ created_at: { type: "string", format: "date-time" },
333
+ updated_at: { type: "string", format: "date-time" },
334
+ sprint_ref: { type: "string" },
335
+ time_tracking: {
336
+ type: "object",
337
+ additionalProperties: false,
338
+ properties: {
339
+ logged_h: { type: "number", minimum: 0 },
340
+ remaining_h: { type: "number", minimum: 0 },
341
+ original_estimate_h: { type: "number", minimum: 0 },
342
+ },
343
+ },
344
+ // NB: `definition_of_done` already declared above on line 285;
345
+ // dedupe pra TS1117. business_value/mockups/release_target/
346
+ // timeline ficam aqui na board-grade section.
347
+ business_value: { type: "number", minimum: 0, maximum: 1000 },
348
+ mockups: { type: "array", items: { type: "string" } },
349
+ release_target: { type: "string" },
350
+ produces: producesFieldSchema(),
351
+ timeline: timelineFieldSchema(),
352
+ },
353
+ };
354
+ }
355
+ summary(doc) {
356
+ const spec = (doc.spec ?? {});
357
+ return {
358
+ status: spec.status ?? "discovery",
359
+ epic: spec.epic ?? "",
360
+ owner: spec.owner ?? "",
361
+ stories: (spec.stories ?? []).length,
362
+ use_cases: (spec.use_cases ?? []).length,
363
+ priority: spec.priority ?? "medium",
364
+ labels: spec.labels ?? [],
365
+ sprint_ref: spec.sprint_ref ?? "",
366
+ business_value: spec.business_value,
367
+ };
368
+ }
369
+ }
370
+ // ---------------------------------------------------------------------------
371
+ // Story
372
+ // ---------------------------------------------------------------------------
373
+ class StoryKind extends KindBase {
374
+ apiVersion = API_VERSION;
375
+ scope = TenantScope.GLOBAL; // SDLC primitives are project-level
376
+ kind = "Story";
377
+ alias = "sdlc-story";
378
+ scopeInheritable = false;
379
+ origin = "github.com/ruinosus/dna/sdlc";
380
+ isPromptTarget = false;
381
+ promptTargetPriority = 0;
382
+ flattenInContext = false;
383
+ plane = "record";
384
+ storage = SD.yaml("stories");
385
+ graphStyle = { fill: "#F59E0B", stroke: "#D97706", textColor: "#fff" };
386
+ asciiIcon = "📖";
387
+ displayLabel = "Stories";
388
+ docs = "A Story is a granular task: one developer, one PR, one estimate. " +
389
+ "Lists acceptance criteria, dependencies (other Stories that must " +
390
+ "land first), and rolls up to a Feature.";
391
+ depFilters() {
392
+ return {
393
+ feature: "sdlc-feature",
394
+ owner: "helix-actor",
395
+ dependencies: "sdlc-story",
396
+ spec_refs: "sdlc-spec",
397
+ };
398
+ }
399
+ schema() {
400
+ return {
401
+ type: "object",
402
+ required: ["description", "status"],
403
+ additionalProperties: true,
404
+ properties: {
405
+ title: { type: "string", description: "Human-readable display name." },
406
+ description: { type: "string" },
407
+ // User-story slots (2026-05-11 UX audit) — Py parity.
408
+ as_a: { type: "string", description: "Role: 'As a <role>'." },
409
+ i_want: { type: "string", description: "Goal: 'I want <goal>'." },
410
+ so_that: { type: "string", description: "Benefit: 'so that <benefit>'." },
411
+ status: { type: "string", enum: [...STORY_STATUSES] },
412
+ feature: { type: "string", description: "Parent Feature name" },
413
+ owner: { type: "string", description: "Actor name" },
414
+ estimate: {
415
+ type: "number",
416
+ description: "Fibonacci story points (1, 2, 3, 5, 8, 13, 21)",
417
+ },
418
+ acceptance_criteria: {
419
+ type: "array",
420
+ items: {
421
+ oneOf: [
422
+ { type: "string" },
423
+ {
424
+ type: "object",
425
+ required: ["text"],
426
+ properties: {
427
+ text: { type: "string" },
428
+ done: { type: "boolean" },
429
+ done_at: { type: "string", format: "date-time" },
430
+ done_by: { type: "string" },
431
+ },
432
+ },
433
+ ],
434
+ },
435
+ description: "Acceptance criteria. Legacy: string[]. New " +
436
+ "(s-ac-dod-checklist-state): list of {text, done?, done_at?, " +
437
+ "done_by?} for per-item state tracking.",
438
+ },
439
+ dependencies: {
440
+ type: "array",
441
+ items: { type: "string" },
442
+ description: "Other Story names that must land first",
443
+ },
444
+ spec_refs: {
445
+ type: "array",
446
+ items: { type: "string" },
447
+ description: "Spec docs (kind=Spec) this Story implements. M:N linkage " +
448
+ "between the planning axis (Story) and the design axis (Spec).",
449
+ },
450
+ closed_at: { type: "string", format: "date-time" },
451
+ blocked_reason: { type: "string" },
452
+ // v1.5 — board-grade fields (all opt; back-compat preserved).
453
+ priority: { type: "string", enum: [...PRIORITIES] },
454
+ labels: { type: "array", items: { type: "string" } },
455
+ reporter: { type: "string" },
456
+ watchers: { type: "array", items: { type: "string" } },
457
+ journey_phase: { type: "string", enum: [...JOURNEY_PHASES] },
458
+ created_at: { type: "string", format: "date-time" },
459
+ updated_at: { type: "string", format: "date-time" },
460
+ sprint_ref: { type: "string" },
461
+ time_tracking: {
462
+ type: "object",
463
+ additionalProperties: false,
464
+ properties: {
465
+ logged_h: { type: "number", minimum: 0 },
466
+ remaining_h: { type: "number", minimum: 0 },
467
+ original_estimate_h: { type: "number", minimum: 0 },
468
+ },
469
+ },
470
+ definition_of_done: {
471
+ type: "array",
472
+ items: {
473
+ oneOf: [
474
+ { type: "string" },
475
+ {
476
+ type: "object",
477
+ required: ["text"],
478
+ properties: {
479
+ text: { type: "string" },
480
+ done: { type: "boolean" },
481
+ done_at: { type: "string", format: "date-time" },
482
+ done_by: { type: "string" },
483
+ },
484
+ },
485
+ ],
486
+ },
487
+ description: "Per-Story DoD. Same union shape as acceptance_criteria — " +
488
+ "legacy string[] OR list of {text, done?, done_at?, done_by?}.",
489
+ },
490
+ business_value: { type: "number", minimum: 0, maximum: 1000 },
491
+ mockups: { type: "array", items: { type: "string" } },
492
+ release_target: { type: "string" },
493
+ produces: producesFieldSchema(),
494
+ timeline: timelineFieldSchema(),
495
+ },
496
+ };
497
+ }
498
+ summary(doc) {
499
+ const spec = (doc.spec ?? {});
500
+ return {
501
+ status: spec.status ?? "todo",
502
+ feature: spec.feature ?? "",
503
+ owner: spec.owner ?? "",
504
+ estimate: spec.estimate,
505
+ spec_refs: (spec.spec_refs ?? []).length,
506
+ priority: spec.priority ?? "medium",
507
+ labels: spec.labels ?? [],
508
+ sprint_ref: spec.sprint_ref ?? "",
509
+ business_value: spec.business_value,
510
+ };
511
+ }
512
+ }
513
+ // ---------------------------------------------------------------------------
514
+ // Issue
515
+ // ---------------------------------------------------------------------------
516
+ class IssueKind extends KindBase {
517
+ apiVersion = API_VERSION;
518
+ scope = TenantScope.GLOBAL; // SDLC primitives are project-level
519
+ kind = "Issue";
520
+ alias = "sdlc-issue";
521
+ scopeInheritable = false;
522
+ origin = "github.com/ruinosus/dna/sdlc";
523
+ isPromptTarget = false;
524
+ promptTargetPriority = 0;
525
+ flattenInContext = false;
526
+ plane = "record";
527
+ storage = SD.yaml("issues");
528
+ graphStyle = { fill: "#EF4444", stroke: "#DC2626", textColor: "#fff" };
529
+ asciiIcon = "🐞";
530
+ displayLabel = "Issues";
531
+ docs = "An Issue is a human-authored ticket — bug, enhancement, question, " +
532
+ "or task. Tracked across open → triaged → in-progress → resolved. " +
533
+ "Optional links to a parent Feature (work it belongs to) and a " +
534
+ "related Finding (eval-detected origin).";
535
+ depFilters() {
536
+ return {
537
+ related_feature: "sdlc-feature",
538
+ owner: "helix-actor",
539
+ };
540
+ }
541
+ schema() {
542
+ return {
543
+ type: "object",
544
+ required: ["description", "type", "severity", "status"],
545
+ additionalProperties: true,
546
+ properties: {
547
+ title: { type: "string", description: "Human-readable display name." },
548
+ description: { type: "string" },
549
+ type: { type: "string", enum: [...ISSUE_TYPES] },
550
+ severity: { type: "string", enum: [...ISSUE_SEVERITIES] },
551
+ status: { type: "string", enum: [...ISSUE_STATUSES] },
552
+ owner: { type: "string", description: "Actor name" },
553
+ related_feature: { type: "string", description: "Feature name" },
554
+ related_finding: { type: "string", description: "Finding name" },
555
+ reproduction_steps: { type: "array", items: { type: "string" } },
556
+ expected_behavior: { type: "string" },
557
+ actual_behavior: { type: "string" },
558
+ closed_at: { type: "string", format: "date-time" },
559
+ resolution: { type: "string" },
560
+ // GitHub-bridge provenance (s-github-issues-bridge): an Issue can
561
+ // be PUBLISHED to / IMPORTED from a GitHub issue (`dna sdlc issue
562
+ // publish|import|sync`). These fields are the provenance link —
563
+ // the bridge mirrors WITH provenance, it never replaces the
564
+ // github.com artifact.
565
+ github_number: {
566
+ type: "integer",
567
+ minimum: 1,
568
+ description: "GitHub issue number this doc is bridged to.",
569
+ },
570
+ github_url: {
571
+ type: "string",
572
+ description: "Canonical https URL of the GitHub issue.",
573
+ },
574
+ github_state: {
575
+ type: "string",
576
+ enum: ["open", "closed"],
577
+ description: "Last observed GitHub-side state.",
578
+ },
579
+ github_synced_at: {
580
+ type: "string",
581
+ format: "date-time",
582
+ description: "When the GitHub side was last observed/synced.",
583
+ },
584
+ // v1.5 — board-grade common fields. Issues use `severity`
585
+ // natively; `priority` is orthogonal (severity = how bad,
586
+ // priority = how soon).
587
+ priority: { type: "string", enum: [...PRIORITIES] },
588
+ labels: { type: "array", items: { type: "string" } },
589
+ reporter: { type: "string" },
590
+ watchers: { type: "array", items: { type: "string" } },
591
+ journey_phase: { type: "string", enum: [...JOURNEY_PHASES] },
592
+ created_at: { type: "string", format: "date-time" },
593
+ updated_at: { type: "string", format: "date-time" },
594
+ produces: producesFieldSchema(),
595
+ timeline: timelineFieldSchema(),
596
+ },
597
+ };
598
+ }
599
+ summary(doc) {
600
+ const spec = (doc.spec ?? {});
601
+ return {
602
+ type: spec.type ?? "bug",
603
+ severity: spec.severity ?? "medium",
604
+ status: spec.status ?? "open",
605
+ owner: spec.owner ?? "",
606
+ related_feature: spec.related_feature ?? "",
607
+ priority: spec.priority ?? "medium",
608
+ labels: spec.labels ?? [],
609
+ };
610
+ }
611
+ }
612
+ // ---------------------------------------------------------------------------
613
+ // Spec — pattern-agnostic pointer to design doc
614
+ // ---------------------------------------------------------------------------
615
+ // ADR-style status (Nygard). Plan reuses the same enum.
616
+ const ARTIFACT_STATUSES = ["draft", "proposed", "accepted", "deprecated", "superseded"];
617
+ // Spec.phase — Superpowers/Spec-Kit phase progression. Orthogonal to status.
618
+ const SPEC_PHASES = ["brainstorm", "spec", "plan_ready", "implementing", "done"];
619
+ class SpecKind extends KindBase {
620
+ apiVersion = API_VERSION;
621
+ scope = TenantScope.GLOBAL; // SDLC primitives are project-level
622
+ kind = "Spec";
623
+ alias = "sdlc-spec";
624
+ origin = "github.com/ruinosus/dna/sdlc";
625
+ isPromptTarget = false;
626
+ promptTargetPriority = 0;
627
+ flattenInContext = false;
628
+ plane = "record";
629
+ storage = SD.bundle("specs", "SPEC.md", "text", "body");
630
+ // Embeddable (s-spec-embeddable): the markdown body is the design's
631
+ // substance — Plan/Issue/Epic/Doc/Research already embed; Spec was the
632
+ // lone SDLC-artifact gap so `dna cognitive search` missed design docs.
633
+ embedFields = ["title", "summary", "body"];
634
+ graphStyle = { fill: "#6366F1", stroke: "#4F46E5", textColor: "#fff" };
635
+ asciiIcon = "📐";
636
+ displayLabel = "Specs";
637
+ docs = "A Spec is a top-level design artifact. Cross-cutting by default — " +
638
+ "linkage to work items happens via Story.spec_refs[] (M:N). " +
639
+ "Pattern-agnostic: superpowers, BMAD, droid, RFC, ADR, Spec Kit. " +
640
+ "ADR-style status; phase tracks the orthogonal SDLC view.";
641
+ depFilters() {
642
+ return { epic: "sdlc-epic", supersedes: "sdlc-spec" };
643
+ }
644
+ schema() {
645
+ return {
646
+ type: "object",
647
+ required: ["title", "date", "status"],
648
+ additionalProperties: true,
649
+ properties: {
650
+ title: { type: "string" },
651
+ date: { type: "string", format: "date" },
652
+ status: { type: "string", enum: [...ARTIFACT_STATUSES] },
653
+ phase: {
654
+ type: "string",
655
+ enum: [...SPEC_PHASES],
656
+ description: "Where in the SDLC this spec's work sits. Orthogonal to status.",
657
+ },
658
+ pattern: { type: "string" },
659
+ body: { type: "string" }, origin: { type: "string" },
660
+ epic: { type: "string" },
661
+ authors: { type: "array", items: { type: "string" } },
662
+ tags: { type: "array", items: { type: "string" } },
663
+ supersedes: { type: "string" },
664
+ summary: { type: "string" },
665
+ },
666
+ };
667
+ }
668
+ summary(doc) {
669
+ const spec = (doc.spec ?? {});
670
+ return {
671
+ title: (spec.title ?? "").slice(0, 80),
672
+ date: spec.date ?? "",
673
+ status: spec.status ?? "draft",
674
+ phase: spec.phase ?? "",
675
+ pattern: spec.pattern ?? "",
676
+ epic: spec.epic ?? "",
677
+ };
678
+ }
679
+ }
680
+ class PlanKind extends KindBase {
681
+ apiVersion = API_VERSION;
682
+ scope = TenantScope.GLOBAL; // SDLC primitives are project-level
683
+ kind = "Plan";
684
+ alias = "sdlc-plan";
685
+ scopeInheritable = false;
686
+ origin = "github.com/ruinosus/dna/sdlc";
687
+ isPromptTarget = false;
688
+ promptTargetPriority = 0;
689
+ flattenInContext = false;
690
+ plane = "record";
691
+ storage = SD.bundle("plans", "PLAN.md", "text", "body");
692
+ graphStyle = { fill: "#06B6D4", stroke: "#0891B2", textColor: "#fff" };
693
+ asciiIcon = "📋";
694
+ displayLabel = "Plans";
695
+ docs = "A Plan is a pointer to an implementation plan. Usually descends " +
696
+ "from a Spec via spec_ref. Pattern-agnostic.";
697
+ depFilters() {
698
+ return {
699
+ spec_ref: "sdlc-spec",
700
+ epic: "sdlc-epic",
701
+ };
702
+ }
703
+ schema() {
704
+ return {
705
+ type: "object",
706
+ required: ["title", "date", "status"],
707
+ additionalProperties: true,
708
+ properties: {
709
+ title: { type: "string" },
710
+ date: { type: "string", format: "date" },
711
+ status: { type: "string", enum: [...ARTIFACT_STATUSES] },
712
+ pattern: { type: "string" },
713
+ body: { type: "string" }, origin: { type: "string" },
714
+ spec_ref: { type: "string" },
715
+ epic: { type: "string" },
716
+ authors: { type: "array", items: { type: "string" } },
717
+ tags: { type: "array", items: { type: "string" } },
718
+ summary: { type: "string" },
719
+ // Parity with the Py twin (PlanKind.schema): journey_phase lights the
720
+ // derived `plan` phase; methodology records which planning method
721
+ // produced the plan (superpowers/bmad/...) — opt-in, agnostic.
722
+ journey_phase: { type: "string", enum: [...JOURNEY_PHASES] },
723
+ methodology: { type: "string", enum: [...JOURNEY_METHODOLOGIES] },
724
+ },
725
+ };
726
+ }
727
+ summary(doc) {
728
+ const spec = (doc.spec ?? {});
729
+ return {
730
+ title: (spec.title ?? "").slice(0, 80),
731
+ date: spec.date ?? "",
732
+ status: spec.status ?? "draft",
733
+ pattern: spec.pattern ?? "",
734
+ spec_ref: spec.spec_ref ?? "",
735
+ };
736
+ }
737
+ }
738
+ // ---------------------------------------------------------------------------
739
+ // AgentSession — chat dev↔AI as versioned project artifact (Karpathy 2025)
740
+ // ---------------------------------------------------------------------------
741
+ class AgentSessionKind extends KindBase {
742
+ apiVersion = API_VERSION;
743
+ scope = TenantScope.GLOBAL; // SDLC primitives are project-level
744
+ kind = "AgentSession";
745
+ alias = "sdlc-agent-session";
746
+ origin = "github.com/ruinosus/dna/sdlc";
747
+ isPromptTarget = false;
748
+ promptTargetPriority = 0;
749
+ flattenInContext = false;
750
+ plane = "record";
751
+ storage = SD.bundle("agent-sessions", "SESSION.md", "text", "body");
752
+ graphStyle = { fill: "#EC4899", stroke: "#DB2777", textColor: "#fff" };
753
+ asciiIcon = "📜";
754
+ displayLabel = "Vibe Sessions";
755
+ docs = "A AgentSession captures a developer↔AI coding conversation as a " +
756
+ "versioned project artifact. Tool-agnostic (Claude Code, Cursor, " +
757
+ "Cline, Codex, Aider) via per-tool adapters.";
758
+ depFilters() {
759
+ return { participants: "helix-actor" };
760
+ }
761
+ schema() {
762
+ return {
763
+ type: "object",
764
+ required: ["title", "tool", "session_id", "started_at"],
765
+ additionalProperties: true,
766
+ properties: {
767
+ title: { type: "string" },
768
+ tool: {
769
+ type: "string",
770
+ description: "claude-code | cursor | cline | codex | aider | specstory | other",
771
+ },
772
+ tool_version: { type: "string" },
773
+ session_id: { type: "string" },
774
+ model: { type: "string" },
775
+ workspace_path: { type: "string" },
776
+ started_at: { type: "string", format: "date-time" },
777
+ ended_at: { type: "string", format: "date-time" },
778
+ participants: { type: "array", items: { type: "string" } },
779
+ produced_artifacts: {
780
+ type: "array",
781
+ items: {
782
+ type: "object",
783
+ required: ["kind", "name"],
784
+ properties: {
785
+ kind: { type: "string" },
786
+ name: { type: "string" },
787
+ },
788
+ },
789
+ },
790
+ applied_commits: { type: "array", items: { type: "string" } },
791
+ file_changes: { type: "array", items: { type: "string" } },
792
+ token_usage: { type: "object" },
793
+ cost_usd: { type: "number" },
794
+ summary: { type: "string" },
795
+ body: { type: "string" },
796
+ raw_source: { type: "string" },
797
+ tool_specific: { type: "object" },
798
+ },
799
+ };
800
+ }
801
+ summary(doc) {
802
+ const spec = (doc.spec ?? {});
803
+ return {
804
+ title: (spec.title ?? "").slice(0, 80),
805
+ tool: spec.tool ?? "",
806
+ model: spec.model ?? "",
807
+ started_at: spec.started_at ?? "",
808
+ produced_artifacts: (spec.produced_artifacts ?? []).length,
809
+ };
810
+ }
811
+ }
812
+ // ---------------------------------------------------------------------------
813
+ // Narrative — agent-curated project storytelling (1:1 twin of Py)
814
+ // ---------------------------------------------------------------------------
815
+ // Narrative — F3 lote-2 (spec 2026-06-10-kinds-descriptor-f3): the twin NarrativeKind classes (Py+TS) were
816
+ // DELETED — synthesized from kinds/narrative.kind.yaml (parity-critical
817
+ // package data, byte-identical Py↔TS) via the loadDescriptors loop in
818
+ // register(). Equivalence with the extinct class frozen in
819
+ // tests/test_lote2_descriptor_equivalence.py (golden:
820
+ // tests/goldens/lote2/Narrative.golden.json).
821
+ // ---------------------------------------------------------------------------
822
+ // Bug / Task / Spike — granular work items (split from Issue umbrella)
823
+ // ---------------------------------------------------------------------------
824
+ const BUG_SEVERITY = ["low", "medium", "high", "critical"];
825
+ const BUG_STATUSES = ["open", "triaged", "in-progress", "resolved", "wont-fix", "duplicate", "regression"];
826
+ const TASK_STATUSES = ["todo", "in-progress", "done", "blocked", "cancelled"];
827
+ const SPIKE_STATUSES = ["proposed", "in-progress", "answered", "abandoned"];
828
+ class BugKind extends KindBase {
829
+ apiVersion = API_VERSION;
830
+ scope = TenantScope.GLOBAL;
831
+ kind = "Bug";
832
+ alias = "sdlc-bug";
833
+ origin = "github.com/ruinosus/dna/sdlc";
834
+ isPromptTarget = false;
835
+ promptTargetPriority = 0;
836
+ flattenInContext = false;
837
+ plane = "record";
838
+ storage = SD.bundle("bugs", "BUG.md", "text", "body");
839
+ graphStyle = { fill: "#DC2626", stroke: "#991B1B", textColor: "#fff" };
840
+ asciiIcon = "🐛";
841
+ displayLabel = "Bugs";
842
+ docs = "Defeito factual com repro + severity. Schema dedicado " +
843
+ "(repro_steps, environment, root_cause, fix_summary).";
844
+ depFilters() {
845
+ return {
846
+ related_story: "sdlc-story",
847
+ related_feature: "sdlc-feature",
848
+ fix_adr: "sdlc-adr",
849
+ };
850
+ }
851
+ schema() {
852
+ return {
853
+ type: "object",
854
+ required: ["title", "severity", "status"],
855
+ additionalProperties: true,
856
+ properties: {
857
+ title: { type: "string" },
858
+ description: { type: "string" },
859
+ severity: { type: "string", enum: [...BUG_SEVERITY] },
860
+ status: { type: "string", enum: [...BUG_STATUSES] },
861
+ repro_steps: { type: "array", items: { type: "string" } },
862
+ expected: { type: "string" },
863
+ actual: { type: "string" },
864
+ environment: { type: "string" },
865
+ root_cause: { type: "string" },
866
+ fix_summary: { type: "string" },
867
+ fix_adr: { type: "string" },
868
+ related_story: { type: "string" },
869
+ related_feature: { type: "string" },
870
+ related_finding: { type: "string" },
871
+ reporter: { type: "string" },
872
+ owner: { type: "string" },
873
+ found_at: { type: "string", format: "date-time" },
874
+ resolved_at: { type: "string", format: "date-time" },
875
+ labels: { type: "array", items: { type: "string" } },
876
+ priority: { type: "string", enum: [...PRIORITIES] },
877
+ body: { type: "string" },
878
+ produces: producesFieldSchema(),
879
+ timeline: timelineFieldSchema(),
880
+ created_at: { type: "string", format: "date-time" },
881
+ updated_at: { type: "string", format: "date-time" },
882
+ },
883
+ };
884
+ }
885
+ summary(doc) {
886
+ const spec = (doc.spec ?? {});
887
+ return {
888
+ title: spec.title ?? "",
889
+ severity: spec.severity ?? "",
890
+ status: spec.status ?? "",
891
+ };
892
+ }
893
+ }
894
+ class TaskKind extends KindBase {
895
+ apiVersion = API_VERSION;
896
+ scope = TenantScope.GLOBAL;
897
+ kind = "Task";
898
+ alias = "sdlc-task";
899
+ origin = "github.com/ruinosus/dna/sdlc";
900
+ isPromptTarget = false;
901
+ promptTargetPriority = 0;
902
+ flattenInContext = false;
903
+ plane = "record";
904
+ storage = SD.bundle("tasks", "TASK.md", "text", "body");
905
+ graphStyle = { fill: "#3B82F6", stroke: "#1D4ED8", textColor: "#fff" };
906
+ asciiIcon = "✅";
907
+ displayLabel = "Tasks";
908
+ docs = "Work item granular (horas-dias). Sub-item de Story (Atlassian " +
909
+ "Jira Align hierarchy: Story → Task → Sub-task).";
910
+ depFilters() { return { story_ref: "sdlc-story", owner: "helix-actor" }; }
911
+ schema() {
912
+ return {
913
+ type: "object",
914
+ required: ["title", "status"],
915
+ additionalProperties: true,
916
+ properties: {
917
+ title: { type: "string" },
918
+ description: { type: "string" },
919
+ status: { type: "string", enum: [...TASK_STATUSES] },
920
+ story_ref: { type: "string" },
921
+ owner: { type: "string" },
922
+ estimate_hours: { type: "number", minimum: 0 },
923
+ logged_hours: { type: "number", minimum: 0 },
924
+ due: { type: "string", format: "date" },
925
+ priority: { type: "string", enum: [...PRIORITIES] },
926
+ labels: { type: "array", items: { type: "string" } },
927
+ blocked_reason: { type: "string" },
928
+ closed_at: { type: "string", format: "date-time" },
929
+ body: { type: "string" },
930
+ produces: producesFieldSchema(),
931
+ timeline: timelineFieldSchema(),
932
+ created_at: { type: "string", format: "date-time" },
933
+ updated_at: { type: "string", format: "date-time" },
934
+ },
935
+ };
936
+ }
937
+ summary(doc) {
938
+ const spec = (doc.spec ?? {});
939
+ return {
940
+ title: spec.title ?? "",
941
+ status: spec.status ?? "",
942
+ owner: spec.owner ?? "",
943
+ };
944
+ }
945
+ }
946
+ class SpikeKind extends KindBase {
947
+ apiVersion = API_VERSION;
948
+ scope = TenantScope.GLOBAL;
949
+ kind = "Spike";
950
+ alias = "sdlc-spike";
951
+ origin = "github.com/ruinosus/dna/sdlc";
952
+ isPromptTarget = false;
953
+ promptTargetPriority = 0;
954
+ flattenInContext = false;
955
+ plane = "record";
956
+ storage = SD.bundle("spikes", "SPIKE.md", "text", "body");
957
+ graphStyle = { fill: "#A855F7", stroke: "#7E22CE", textColor: "#fff" };
958
+ asciiIcon = "🔬";
959
+ displayLabel = "Spikes";
960
+ docs = "Time-boxed technical investigation. ONE question + finite " +
961
+ "time + outcome handoff (findings → Story or ADR).";
962
+ depFilters() {
963
+ return {
964
+ follow_up_story: "sdlc-story",
965
+ follow_up_adr: "sdlc-adr",
966
+ follow_up_spec: "sdlc-spec",
967
+ feature: "sdlc-feature",
968
+ // Multi-ref attachments (2026-05-26 — design-spike workflow).
969
+ references: "sdlc-reference",
970
+ related_spikes: "sdlc-spike",
971
+ };
972
+ }
973
+ schema() {
974
+ return {
975
+ type: "object",
976
+ required: ["title", "question_to_answer", "status"],
977
+ additionalProperties: true,
978
+ properties: {
979
+ title: { type: "string" },
980
+ question_to_answer: { type: "string" },
981
+ status: { type: "string", enum: [...SPIKE_STATUSES] },
982
+ time_box_hours: { type: "number", minimum: 0, default: 8 },
983
+ logged_hours: { type: "number", minimum: 0 },
984
+ findings: { type: "string" },
985
+ recommendation: { type: "string" },
986
+ follow_up_story: { type: "string" },
987
+ follow_up_adr: { type: "string" },
988
+ follow_up_spec: { type: "string" },
989
+ feature: { type: "string" },
990
+ owner: { type: "string" },
991
+ html_artifacts: { type: "array", items: { type: "string" } },
992
+ research_refs: { type: "array", items: { type: "string" } },
993
+ references: { type: "array", items: { type: "string" } },
994
+ related_spikes: { type: "array", items: { type: "string" } },
995
+ started_at: { type: "string", format: "date-time" },
996
+ completed_at: { type: "string", format: "date-time" },
997
+ labels: { type: "array", items: { type: "string" } },
998
+ body: { type: "string" },
999
+ produces: producesFieldSchema(),
1000
+ timeline: timelineFieldSchema(),
1001
+ created_at: { type: "string", format: "date-time" },
1002
+ updated_at: { type: "string", format: "date-time" },
1003
+ },
1004
+ };
1005
+ }
1006
+ summary(doc) {
1007
+ const spec = (doc.spec ?? {});
1008
+ return {
1009
+ title: spec.title ?? "",
1010
+ status: spec.status ?? "",
1011
+ time_box_hours: spec.time_box_hours ?? null,
1012
+ };
1013
+ }
1014
+ }
1015
+ // ---------------------------------------------------------------------------
1016
+ // Initiative — investment unit (Atlassian Jira Align hierarchy)
1017
+ // ---------------------------------------------------------------------------
1018
+ const INITIATIVE_STATUSES = ["proposed", "in-flight", "done", "cancelled", "deferred"];
1019
+ class InitiativeKind extends KindBase {
1020
+ apiVersion = API_VERSION;
1021
+ scope = TenantScope.GLOBAL;
1022
+ kind = "Initiative";
1023
+ alias = "sdlc-initiative";
1024
+ origin = "github.com/ruinosus/dna/sdlc";
1025
+ isPromptTarget = false;
1026
+ promptTargetPriority = 0;
1027
+ flattenInContext = false;
1028
+ plane = "record";
1029
+ storage = SD.bundle("initiatives", "INITIATIVE.md", "text", "body");
1030
+ graphStyle = { fill: "#0EA5E9", stroke: "#0284C7", textColor: "#fff" };
1031
+ asciiIcon = "🎲";
1032
+ displayLabel = "Initiatives";
1033
+ docs = "Investment-level umbrella (1-2 quarters) between Theme/OKR and " +
1034
+ "Epic. Atlassian Jira Align hierarchy.";
1035
+ depFilters() {
1036
+ return { epics: "sdlc-epic", owner: "helix-actor" };
1037
+ }
1038
+ schema() {
1039
+ return {
1040
+ type: "object",
1041
+ required: ["title", "status"],
1042
+ additionalProperties: true,
1043
+ properties: {
1044
+ title: { type: "string" },
1045
+ description: { type: "string" },
1046
+ status: { type: "string", enum: [...INITIATIVE_STATUSES] },
1047
+ owner: { type: "string" },
1048
+ horizon_start: { type: "string", format: "date" },
1049
+ horizon_end: { type: "string", format: "date" },
1050
+ outcome_metric: { type: "string" },
1051
+ target_value: { type: "string" },
1052
+ epics: { type: "array", items: { type: "string" } },
1053
+ theme_ref: { type: "string" },
1054
+ business_value: { type: "number" },
1055
+ priority: { type: "string", enum: [...PRIORITIES] },
1056
+ labels: { type: "array", items: { type: "string" } },
1057
+ body: { type: "string" },
1058
+ created_at: { type: "string", format: "date-time" },
1059
+ updated_at: { type: "string", format: "date-time" },
1060
+ },
1061
+ };
1062
+ }
1063
+ summary(doc) {
1064
+ const spec = (doc.spec ?? {});
1065
+ return {
1066
+ title: spec.title ?? "",
1067
+ status: spec.status ?? "",
1068
+ epics_count: (spec.epics ?? []).length,
1069
+ };
1070
+ }
1071
+ }
1072
+ // ---------------------------------------------------------------------------
1073
+ // Reference — external citation artifact
1074
+ // ---------------------------------------------------------------------------
1075
+ const REFERENCE_KIND_OFS = ["web", "paper", "book", "file", "internal-doc", "other"];
1076
+ /**
1077
+ * Reference — external citation artifact (web/paper/book/file/internal-doc).
1078
+ *
1079
+ * Wraps external sources with metadata so SDLC docs can cite evidence
1080
+ * durably. Any other Kind (Story, Feature, Spec, Plan, Engram, etc.)
1081
+ * gains an optional `spec.references: list[str]` field naming Reference
1082
+ * doc slugs. CLI `dna sdlc cite` maintains the bidirectional graph
1083
+ * (Reference.spec.cited_by += caller_ref).
1084
+ *
1085
+ * Ported from Python for s-alias-generated-not-typed: Spike.depFilters
1086
+ * points at `sdlc-reference`, and validateDepFilters requires every
1087
+ * builtin dep_filter alias to resolve — the Kind can no longer be
1088
+ * py-only. 1:1 twin of dna.extensions.sdlc.ReferenceKind.
1089
+ *
1090
+ * Spec: docs/superpowers/specs/2026-05-12-f-reference-citation-kind.md
1091
+ */
1092
+ class ReferenceKind extends KindBase {
1093
+ apiVersion = API_VERSION;
1094
+ scope = TenantScope.GLOBAL;
1095
+ kind = "Reference";
1096
+ alias = "sdlc-reference";
1097
+ origin = "github.com/ruinosus/dna/sdlc";
1098
+ isPromptTarget = false;
1099
+ promptTargetPriority = 0;
1100
+ flattenInContext = false;
1101
+ plane = "record";
1102
+ storage = SD.yaml("references");
1103
+ graphStyle = { fill: "#6366F1", stroke: "#4F46E5", textColor: "#fff" };
1104
+ asciiIcon = "📚";
1105
+ displayLabel = "References";
1106
+ depFilters() {
1107
+ return {};
1108
+ }
1109
+ schema() {
1110
+ return {
1111
+ type: "object",
1112
+ required: ["title", "kind_of", "summary"],
1113
+ additionalProperties: true,
1114
+ properties: {
1115
+ title: { type: "string" },
1116
+ kind_of: { type: "string", enum: [...REFERENCE_KIND_OFS] },
1117
+ url: { type: "string" },
1118
+ fetched_at: { type: "string", format: "date-time" },
1119
+ summary: { type: "string", description: "1-2 sentence what this source says." },
1120
+ key_quotes: { type: "array", items: { type: "string" }, default: [] },
1121
+ relevance: { type: "string", description: "Why this matters for THIS project." },
1122
+ tags: { type: "array", items: { type: "string" }, default: [] },
1123
+ cited_by: {
1124
+ type: "array",
1125
+ items: { type: "string" },
1126
+ default: [],
1127
+ description: "Auto-maintained by `dna sdlc cite`. Don't author by hand.",
1128
+ },
1129
+ content_path: {
1130
+ type: "string",
1131
+ description: "Optional path to rich-content sidecar (e.g. docs/superpowers/research/<slug>.md)",
1132
+ },
1133
+ owner: { type: "string", default: "claude-code" },
1134
+ created_at: { type: "string", format: "date-time" },
1135
+ updated_at: { type: "string", format: "date-time" },
1136
+ },
1137
+ };
1138
+ }
1139
+ summary(doc) {
1140
+ const spec = (doc.spec ?? {});
1141
+ return {
1142
+ title: spec.title ?? "",
1143
+ kind_of: spec.kind_of ?? "other",
1144
+ url: spec.url ?? "",
1145
+ cited_by_count: (spec.cited_by ?? []).length,
1146
+ };
1147
+ }
1148
+ }
1149
+ // ---------------------------------------------------------------------------
1150
+ // Changelog — Keep a Changelog 1.1.0 + SemVer 2.0
1151
+ // ---------------------------------------------------------------------------
1152
+ // Changelog — F3 lote-2 (spec 2026-06-10-kinds-descriptor-f3): the twin ChangelogKind classes (Py+TS) were
1153
+ // DELETED — synthesized from kinds/changelog.kind.yaml (parity-critical
1154
+ // package data, byte-identical Py↔TS) via the loadDescriptors loop in
1155
+ // register(). Equivalence with the extinct class frozen in
1156
+ // tests/test_lote2_descriptor_equivalence.py (golden:
1157
+ // tests/goldens/lote2/Changelog.golden.json).
1158
+ // ---------------------------------------------------------------------------
1159
+ // Postmortem — Google SRE blameless incident analysis
1160
+ // ---------------------------------------------------------------------------
1161
+ // Postmortem — F3 lote-2 (spec 2026-06-10-kinds-descriptor-f3): the twin PostmortemKind classes (Py+TS) were
1162
+ // DELETED — synthesized from kinds/postmortem.kind.yaml (parity-critical
1163
+ // package data, byte-identical Py↔TS) via the loadDescriptors loop in
1164
+ // register(). Equivalence with the extinct class frozen in
1165
+ // tests/test_lote2_descriptor_equivalence.py (golden:
1166
+ // tests/goldens/lote2/Postmortem.golden.json).
1167
+ // ---------------------------------------------------------------------------
1168
+ // RiskRegister — PMBOK 7 + ISO 31000:2018
1169
+ // ---------------------------------------------------------------------------
1170
+ // RiskRegister — F3 lote-2 (spec 2026-06-10-kinds-descriptor-f3): the twin RiskRegisterKind classes (Py+TS) were
1171
+ // DELETED — synthesized from kinds/risk-register.kind.yaml (parity-critical
1172
+ // package data, byte-identical Py↔TS) via the loadDescriptors loop in
1173
+ // register(). Equivalence with the extinct class frozen in
1174
+ // tests/test_lote2_descriptor_equivalence.py (golden:
1175
+ // tests/goldens/lote2/RiskRegister.golden.json).
1176
+ // ---------------------------------------------------------------------------
1177
+ // ADR — Architecture Decision Record (Nygard 2011 / MADR)
1178
+ // ---------------------------------------------------------------------------
1179
+ // ADR — F3 lote-2 (spec 2026-06-10-kinds-descriptor-f3): the twin ADRKind classes (Py+TS) were
1180
+ // DELETED — synthesized from kinds/adr.kind.yaml (parity-critical
1181
+ // package data, byte-identical Py↔TS) via the loadDescriptors loop in
1182
+ // register(). Equivalence with the extinct class frozen in
1183
+ // tests/test_lote2_descriptor_equivalence.py (golden:
1184
+ // tests/goldens/lote2/ADR.golden.json).
1185
+ // ---------------------------------------------------------------------------
1186
+ // Retrospective — sprint/release/incident retro (Atlassian 4 Ls)
1187
+ // ---------------------------------------------------------------------------
1188
+ // Retrospective — F3 lote-1 (spec 2026-06-10-kinds-descriptor-f3): the twin
1189
+ // RetrospectiveKind classes (Py+TS) were DELETED — synthesized from
1190
+ // kinds/retrospective.kind.yaml (parity-critical package data) via the
1191
+ // loadDescriptors loop in register(). The old TS-only summary()/slim schema
1192
+ // drifted from Py; the descriptor unifies on the canonical (Py) surface.
1193
+ // ---------------------------------------------------------------------------
1194
+ // Extension
1195
+ // ---------------------------------------------------------------------------
1196
+ // ---------------------------------------------------------------------------
1197
+ // WorkflowEvent — append-only ledger of phase transitions (1:1 twin of Py)
1198
+ // ---------------------------------------------------------------------------
1199
+ const JOURNEY_METHODOLOGIES = [
1200
+ "superpowers", "bmad", "spec-kit", "kiro",
1201
+ "rfc", "adr", "ad-hoc", "custom",
1202
+ ];
1203
+ // ---------------------------------------------------------------------------
1204
+ // SavedView — named filter+groupBy+sort+layout entity (Linear/Notion pattern)
1205
+ // ---------------------------------------------------------------------------
1206
+ // SavedView — F3 lote-2 (spec 2026-06-10-kinds-descriptor-f3): the twin SavedViewKind classes (Py+TS) were
1207
+ // DELETED — synthesized from kinds/saved-view.kind.yaml (parity-critical
1208
+ // package data, byte-identical Py↔TS) via the loadDescriptors loop in
1209
+ // register(). Equivalence with the extinct class frozen in
1210
+ // tests/test_lote2_descriptor_equivalence.py (golden:
1211
+ // tests/goldens/lote2/SavedView.golden.json).
1212
+ // WorkflowEvent — F3 lote-1: twin classes deleted — synthesized from
1213
+ // kinds/workflow-event.kind.yaml. Old TS summary defaults ("") drifted from
1214
+ // Py (null); the descriptor unifies on the canonical (Py) surface.
1215
+ // Insight — F3 lote-2 (spec 2026-06-10-kinds-descriptor-f3): the twin InsightKind classes (Py+TS) were
1216
+ // DELETED — synthesized from kinds/insight.kind.yaml (parity-critical
1217
+ // package data, byte-identical Py↔TS) via the loadDescriptors loop in
1218
+ // register(). Equivalence with the extinct class frozen in
1219
+ // tests/test_lote2_descriptor_equivalence.py (golden:
1220
+ // tests/goldens/lote2/Insight.golden.json).
1221
+ // StatusReport — F3 lote-2 (spec 2026-06-10-kinds-descriptor-f3): the twin StatusReportKind classes (Py+TS) were
1222
+ // DELETED — synthesized from kinds/status-report.kind.yaml (parity-critical
1223
+ // package data, byte-identical Py↔TS) via the loadDescriptors loop in
1224
+ // register(). Equivalence with the extinct class frozen in
1225
+ // tests/test_lote2_descriptor_equivalence.py (golden:
1226
+ // tests/goldens/lote2/StatusReport.golden.json).
1227
+ // ---------------------------------------------------------------------------
1228
+ // Cognitive Memory Triad (v1.9.0) — LessonLearned + SynthesisRun + ArchiveProposal
1229
+ //
1230
+ // Spec: docs/superpowers/specs/2026-05-11-cognitive-memory-triad.md
1231
+ // Surface labels (pt-BR) in Studio: "Lições Aprendidas" / "Sínteses" / "Arquivamento".
1232
+ // Kind names stay English per repo convention (same pattern as Insight).
1233
+ // ---------------------------------------------------------------------------
1234
+ // REMEMBRANCE_AFFECTS / REMEMBRANCE_SURFACE_TRIGGERS now live ONLY in
1235
+ // kinds/lesson-learned.kind.yaml (F3 lote-1) — the descriptor is the
1236
+ // single source for the LessonLearned enums.
1237
+ // F3 lote-2: the per-Kind enum consts that used to live here
1238
+ // (DREAM_*/FORGETTING_*/ADR_STATUSES/RISK_*/SAVED_VIEW_*/POSTMORTEM_SEVERITY/
1239
+ // INSIGHT_CONFIDENCE_LEVELS) died with the classes — the descriptors under
1240
+ // sdlc/kinds/*.kind.yaml are the single source for the enums; tests read
1241
+ // them from the synthesized port's schema.
1242
+ // LessonLearned — F3 lote-1: twin classes deleted — synthesized from
1243
+ // kinds/lesson-learned.kind.yaml. The old TS class was strict + missing
1244
+ // affect_reason/affect_evidence_refs (real drift); the descriptor unifies
1245
+ // on the canonical (Py) surface.
1246
+ // SynthesisRun — F3 lote-2 (spec 2026-06-10-kinds-descriptor-f3): the twin SynthesisRunKind classes (Py+TS) were
1247
+ // DELETED — synthesized from kinds/synthesis-run.kind.yaml (parity-critical
1248
+ // package data, byte-identical Py↔TS) via the loadDescriptors loop in
1249
+ // register(). Equivalence with the extinct class frozen in
1250
+ // tests/test_lote2_descriptor_equivalence.py (golden:
1251
+ // tests/goldens/lote2/SynthesisRun.golden.json).
1252
+ // ArchiveProposal — F3 lote-2 (spec 2026-06-10-kinds-descriptor-f3): the twin ArchiveProposalKind classes (Py+TS) were
1253
+ // DELETED — synthesized from kinds/archive-proposal.kind.yaml (parity-critical
1254
+ // package data, byte-identical Py↔TS) via the loadDescriptors loop in
1255
+ // register(). Equivalence with the extinct class frozen in
1256
+ // tests/test_lote2_descriptor_equivalence.py (golden:
1257
+ // tests/goldens/lote2/ArchiveProposal.golden.json).
1258
+ // ---------------------------------------------------------------------------
1259
+ // PromptTemplate — expr batch B (plan 2026-06-11-descriptor-expressiveness,
1260
+ // Chunk 4): the twin classes were DELETED; synthesized from
1261
+ // sdlc/kinds/prompt-template.kind.yaml via the loadDescriptors loop in
1262
+ // register().
1263
+ //
1264
+ // s-consolidate-cognitive-policies (f-kind-catalog-governance, 2026-07-07):
1265
+ // the 9 cognitive policy Kinds (RecallPolicy, DecayPolicy, MemoryPolicy, the
1266
+ // old CognitivePolicy, AllocationPolicy, PaginationPolicy,
1267
+ // EngramStrengthPolicy, EmbeddingProfile, AffectPalette) were consolidated
1268
+ // into ONE expanded CognitivePolicy descriptor
1269
+ // (sdlc/kinds/cognitive-policy.kind.yaml) with one top-level spec section per
1270
+ // former Kind. The 8 retired names are pinned in the Py kernel's
1271
+ // _REMOVED_KINDS (+ _REMOVED_KIND_NOTES; the write path is Py-only).
1272
+ // ---------------------------------------------------------------------------
1273
+ // ---------------------------------------------------------------------------
1274
+ // Kaizen — first-class improvement observation (record plane)
1275
+ //
1276
+ // F3 P2 (spec 2026-06-10-kinds-descriptor-f3): the twin KaizenKind classes
1277
+ // (Py + TS) were DELETED — the Kind is now synthesized from the descriptor
1278
+ // sdlc/kinds/kaizen.kind.yaml (parity-critical package data, byte-identical
1279
+ // Py↔TS) via kernel.kindFromDescriptor in register() below. Equivalence with
1280
+ // the old class is frozen in sdk-py tests/test_kaizen_descriptor_equivalence.py
1281
+ // + tests/sdlc.test.ts.
1282
+ // ---------------------------------------------------------------------------
1283
+ export class SdlcExtension {
1284
+ name = "sdlc";
1285
+ // v1.14.0 — s-consolidate-cognitive-policies: the 9 cognitive policy
1286
+ // Kinds consolidated into one expanded CognitivePolicy (TS parity with
1287
+ // Python SdlcExtension v1.14.0).
1288
+ version = "1.14.0";
1289
+ register(kernel) {
1290
+ kernel.kind(new RoadmapKind());
1291
+ kernel.kind(new EpicKind());
1292
+ kernel.kind(new FeatureKind());
1293
+ kernel.kind(new StoryKind());
1294
+ kernel.kind(new IssueKind());
1295
+ kernel.kind(new SpecKind());
1296
+ kernel.kind(new PlanKind());
1297
+ kernel.kind(new AgentSessionKind());
1298
+ kernel.kind(new BugKind());
1299
+ kernel.kind(new TaskKind());
1300
+ kernel.kind(new SpikeKind());
1301
+ kernel.kind(new InitiativeKind());
1302
+ // v1.10.0 — f-reference-citation-kind (ported from Python for
1303
+ // s-alias-generated-not-typed: Spike.depFilters → "sdlc-reference").
1304
+ kernel.kind(new ReferenceKind());
1305
+ // expr batch B: PromptTemplate is a descriptor now — registered via the
1306
+ // loadDescriptors loop below. s-consolidate-cognitive-policies: the
1307
+ // cognitive policy family is ONE descriptor (cognitive-policy.kind.yaml).
1308
+ // F3 P2 (spec 2026-06-10-kinds-descriptor-f3): builtin record Kinds
1309
+ // expressed as descriptors — kinds/*.kind.yaml package data registered
1310
+ // through the SAME funnel as per-scope KindDefinitions (plane lint +
1311
+ // digest idempotency + builtin conflict marker). Structured as a loop
1312
+ // so migration batches just drop files into sdlc/kinds/ — no per-Kind
1313
+ // code. Pilot: Kaizen (v1.13.0 s-kaizen-kind, class twins deleted).
1314
+ for (const raw of loadDescriptors(import.meta.url, "sdlc/kinds")) {
1315
+ kernel.kindFromDescriptor(raw);
1316
+ }
1317
+ }
1318
+ }