@decibelsystems/tools 2.1.4 → 3.0.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 (295) hide show
  1. package/CHANGELOG.md +160 -0
  2. package/README.md +1 -1
  3. package/dist/agentPresence.d.ts +80 -0
  4. package/dist/agentPresence.d.ts.map +1 -1
  5. package/dist/agentPresence.js +177 -0
  6. package/dist/agentPresence.js.map +1 -1
  7. package/dist/agentic/index.d.ts +18 -8
  8. package/dist/agentic/index.d.ts.map +1 -1
  9. package/dist/agentic/index.js +18 -144
  10. package/dist/agentic/index.js.map +1 -1
  11. package/dist/agentic/types.d.ts +106 -0
  12. package/dist/agentic/types.d.ts.map +1 -1
  13. package/dist/agentic/types.js +77 -1
  14. package/dist/agentic/types.js.map +1 -1
  15. package/dist/architectAdrs.d.ts +14 -2
  16. package/dist/architectAdrs.d.ts.map +1 -1
  17. package/dist/architectAdrs.js +9 -3
  18. package/dist/architectAdrs.js.map +1 -1
  19. package/dist/client/transports.d.ts.map +1 -1
  20. package/dist/client/transports.js +13 -3
  21. package/dist/client/transports.js.map +1 -1
  22. package/dist/daemon.d.ts +19 -0
  23. package/dist/daemon.d.ts.map +1 -1
  24. package/dist/daemon.js +181 -38
  25. package/dist/daemon.js.map +1 -1
  26. package/dist/daemonConfig.d.ts +30 -0
  27. package/dist/daemonConfig.d.ts.map +1 -1
  28. package/dist/daemonConfig.js +56 -9
  29. package/dist/daemonConfig.js.map +1 -1
  30. package/dist/decibelPaths.d.ts.map +1 -1
  31. package/dist/decibelPaths.js +39 -6
  32. package/dist/decibelPaths.js.map +1 -1
  33. package/dist/domain/issue.d.ts +77 -0
  34. package/dist/domain/issue.d.ts.map +1 -0
  35. package/dist/domain/issue.js +134 -0
  36. package/dist/domain/issue.js.map +1 -0
  37. package/dist/domain/issueCodec.d.ts +39 -0
  38. package/dist/domain/issueCodec.d.ts.map +1 -0
  39. package/dist/domain/issueCodec.js +298 -0
  40. package/dist/domain/issueCodec.js.map +1 -0
  41. package/dist/domain/issueRepository.d.ts +91 -0
  42. package/dist/domain/issueRepository.d.ts.map +1 -0
  43. package/dist/domain/issueRepository.js +257 -0
  44. package/dist/domain/issueRepository.js.map +1 -0
  45. package/dist/facades/definitions.d.ts +0 -1
  46. package/dist/facades/definitions.d.ts.map +1 -1
  47. package/dist/facades/definitions.js +94 -98
  48. package/dist/facades/definitions.js.map +1 -1
  49. package/dist/facades/index.d.ts +2 -1
  50. package/dist/facades/index.d.ts.map +1 -1
  51. package/dist/facades/index.js +1 -1
  52. package/dist/facades/index.js.map +1 -1
  53. package/dist/facades/types.d.ts +17 -0
  54. package/dist/facades/types.d.ts.map +1 -1
  55. package/dist/httpArgs.d.ts +11 -0
  56. package/dist/httpArgs.d.ts.map +1 -0
  57. package/dist/httpArgs.js +39 -0
  58. package/dist/httpArgs.js.map +1 -0
  59. package/dist/httpServer.d.ts +1 -12
  60. package/dist/httpServer.d.ts.map +1 -1
  61. package/dist/httpServer.js +173 -98
  62. package/dist/httpServer.js.map +1 -1
  63. package/dist/kernel.d.ts +55 -1
  64. package/dist/kernel.d.ts.map +1 -1
  65. package/dist/kernel.js +366 -31
  66. package/dist/kernel.js.map +1 -1
  67. package/dist/lib/agent-services/assumptions.d.ts.map +1 -1
  68. package/dist/lib/agent-services/assumptions.js +8 -2
  69. package/dist/lib/agent-services/assumptions.js.map +1 -1
  70. package/dist/lib/atomicWrite.d.ts +26 -0
  71. package/dist/lib/atomicWrite.d.ts.map +1 -0
  72. package/dist/lib/atomicWrite.js +73 -0
  73. package/dist/lib/atomicWrite.js.map +1 -0
  74. package/dist/lib/envelope.d.ts +31 -0
  75. package/dist/lib/envelope.d.ts.map +1 -0
  76. package/dist/lib/envelope.js +80 -0
  77. package/dist/lib/envelope.js.map +1 -0
  78. package/dist/lib/fileLock.d.ts +38 -0
  79. package/dist/lib/fileLock.d.ts.map +1 -0
  80. package/dist/lib/fileLock.js +124 -0
  81. package/dist/lib/fileLock.js.map +1 -0
  82. package/dist/lib/recordIdAllocator.d.ts +86 -0
  83. package/dist/lib/recordIdAllocator.d.ts.map +1 -0
  84. package/dist/lib/recordIdAllocator.js +161 -0
  85. package/dist/lib/recordIdAllocator.js.map +1 -0
  86. package/dist/license.js +3 -3
  87. package/dist/license.js.map +1 -1
  88. package/dist/projectRegistry.d.ts +65 -3
  89. package/dist/projectRegistry.d.ts.map +1 -1
  90. package/dist/projectRegistry.js +233 -33
  91. package/dist/projectRegistry.js.map +1 -1
  92. package/dist/runtime/circuitBreaker.d.ts +95 -0
  93. package/dist/runtime/circuitBreaker.d.ts.map +1 -0
  94. package/dist/runtime/circuitBreaker.js +178 -0
  95. package/dist/runtime/circuitBreaker.js.map +1 -0
  96. package/dist/runtime/ensureRuntime.d.ts +103 -0
  97. package/dist/runtime/ensureRuntime.d.ts.map +1 -0
  98. package/dist/runtime/ensureRuntime.js +281 -0
  99. package/dist/runtime/ensureRuntime.js.map +1 -0
  100. package/dist/runtime/extensions.d.ts +57 -0
  101. package/dist/runtime/extensions.d.ts.map +1 -0
  102. package/dist/runtime/extensions.js +216 -0
  103. package/dist/runtime/extensions.js.map +1 -0
  104. package/dist/runtime/localHttp.d.ts +24 -0
  105. package/dist/runtime/localHttp.d.ts.map +1 -0
  106. package/dist/runtime/localHttp.js +84 -0
  107. package/dist/runtime/localHttp.js.map +1 -0
  108. package/dist/runtime/projectResolution.d.ts +29 -0
  109. package/dist/runtime/projectResolution.d.ts.map +1 -0
  110. package/dist/runtime/projectResolution.js +67 -0
  111. package/dist/runtime/projectResolution.js.map +1 -0
  112. package/dist/runtime/protocol.d.ts +62 -0
  113. package/dist/runtime/protocol.d.ts.map +1 -0
  114. package/dist/runtime/protocol.js +74 -0
  115. package/dist/runtime/protocol.js.map +1 -0
  116. package/dist/sentinelIssues.d.ts +26 -2
  117. package/dist/sentinelIssues.d.ts.map +1 -1
  118. package/dist/sentinelIssues.js +163 -76
  119. package/dist/sentinelIssues.js.map +1 -1
  120. package/dist/server.js +65 -12
  121. package/dist/server.js.map +1 -1
  122. package/dist/setup.d.ts +83 -0
  123. package/dist/setup.d.ts.map +1 -0
  124. package/dist/setup.js +445 -0
  125. package/dist/setup.js.map +1 -0
  126. package/dist/store/markdown.d.ts +14 -1
  127. package/dist/store/markdown.d.ts.map +1 -1
  128. package/dist/store/markdown.js +36 -3
  129. package/dist/store/markdown.js.map +1 -1
  130. package/dist/tools/agentic/index.d.ts.map +1 -1
  131. package/dist/tools/agentic/index.js +28 -2
  132. package/dist/tools/agentic/index.js.map +1 -1
  133. package/dist/tools/architect/index.d.ts.map +1 -1
  134. package/dist/tools/architect/index.js +7 -2
  135. package/dist/tools/architect/index.js.map +1 -1
  136. package/dist/tools/conductor/index.d.ts +9 -0
  137. package/dist/tools/conductor/index.d.ts.map +1 -0
  138. package/dist/tools/conductor/index.js +242 -0
  139. package/dist/tools/conductor/index.js.map +1 -0
  140. package/dist/tools/context.d.ts +10 -5
  141. package/dist/tools/context.d.ts.map +1 -1
  142. package/dist/tools/context.js +45 -18
  143. package/dist/tools/context.js.map +1 -1
  144. package/dist/tools/coordinator/coordinator.d.ts.map +1 -1
  145. package/dist/tools/coordinator/coordinator.js +48 -19
  146. package/dist/tools/coordinator/coordinator.js.map +1 -1
  147. package/dist/tools/crit.d.ts +2 -1
  148. package/dist/tools/crit.d.ts.map +1 -1
  149. package/dist/tools/crit.js +19 -4
  150. package/dist/tools/crit.js.map +1 -1
  151. package/dist/tools/designer/index.d.ts.map +1 -1
  152. package/dist/tools/designer/index.js +4 -3
  153. package/dist/tools/designer/index.js.map +1 -1
  154. package/dist/tools/designer/lateral-tools.d.ts.map +1 -1
  155. package/dist/tools/designer/lateral-tools.js +4 -2
  156. package/dist/tools/designer/lateral-tools.js.map +1 -1
  157. package/dist/tools/designer.d.ts +2 -1
  158. package/dist/tools/designer.d.ts.map +1 -1
  159. package/dist/tools/designer.js +24 -12
  160. package/dist/tools/designer.js.map +1 -1
  161. package/dist/tools/dojo.d.ts +3 -2
  162. package/dist/tools/dojo.d.ts.map +1 -1
  163. package/dist/tools/dojo.js +64 -22
  164. package/dist/tools/dojo.js.map +1 -1
  165. package/dist/tools/dojoPolicy.js +1 -1
  166. package/dist/tools/dojoPolicy.js.map +1 -1
  167. package/dist/tools/friction.d.ts.map +1 -1
  168. package/dist/tools/friction.js +16 -6
  169. package/dist/tools/friction.js.map +1 -1
  170. package/dist/tools/guardian.d.ts +29 -7
  171. package/dist/tools/guardian.d.ts.map +1 -1
  172. package/dist/tools/guardian.js +90 -75
  173. package/dist/tools/guardian.js.map +1 -1
  174. package/dist/tools/hygiene/oracle-hygiene.d.ts.map +1 -1
  175. package/dist/tools/hygiene/oracle-hygiene.js +8 -2
  176. package/dist/tools/hygiene/oracle-hygiene.js.map +1 -1
  177. package/dist/tools/index.d.ts.map +1 -1
  178. package/dist/tools/index.js +29 -18
  179. package/dist/tools/index.js.map +1 -1
  180. package/dist/tools/learnings.d.ts +2 -1
  181. package/dist/tools/learnings.d.ts.map +1 -1
  182. package/dist/tools/learnings.js +31 -15
  183. package/dist/tools/learnings.js.map +1 -1
  184. package/dist/tools/oracle.d.ts.map +1 -1
  185. package/dist/tools/oracle.js +19 -6
  186. package/dist/tools/oracle.js.map +1 -1
  187. package/dist/tools/policy.d.ts +2 -1
  188. package/dist/tools/policy.d.ts.map +1 -1
  189. package/dist/tools/policy.js +28 -9
  190. package/dist/tools/policy.js.map +1 -1
  191. package/dist/tools/postoffice/index.d.ts +10 -0
  192. package/dist/tools/postoffice/index.d.ts.map +1 -0
  193. package/dist/tools/postoffice/index.js +218 -0
  194. package/dist/tools/postoffice/index.js.map +1 -0
  195. package/dist/tools/postoffice.d.ts +78 -0
  196. package/dist/tools/postoffice.d.ts.map +1 -0
  197. package/dist/tools/postoffice.js +199 -0
  198. package/dist/tools/postoffice.js.map +1 -0
  199. package/dist/tools/provenance.d.ts +7 -0
  200. package/dist/tools/provenance.d.ts.map +1 -1
  201. package/dist/tools/provenance.js +42 -16
  202. package/dist/tools/provenance.js.map +1 -1
  203. package/dist/tools/registry/index.d.ts.map +1 -1
  204. package/dist/tools/registry/index.js +41 -12
  205. package/dist/tools/registry/index.js.map +1 -1
  206. package/dist/tools/sentinel/index.d.ts +1 -0
  207. package/dist/tools/sentinel/index.d.ts.map +1 -1
  208. package/dist/tools/sentinel/index.js +88 -4
  209. package/dist/tools/sentinel/index.js.map +1 -1
  210. package/dist/tools/sentinel.d.ts +117 -1
  211. package/dist/tools/sentinel.d.ts.map +1 -1
  212. package/dist/tools/sentinel.js +761 -339
  213. package/dist/tools/sentinel.js.map +1 -1
  214. package/dist/tools/shared/index.d.ts +2 -1
  215. package/dist/tools/shared/index.d.ts.map +1 -1
  216. package/dist/tools/shared/index.js +2 -1
  217. package/dist/tools/shared/index.js.map +1 -1
  218. package/dist/tools/shared/response.d.ts +24 -0
  219. package/dist/tools/shared/response.d.ts.map +1 -1
  220. package/dist/tools/shared/response.js +61 -7
  221. package/dist/tools/shared/response.js.map +1 -1
  222. package/dist/tools/shared/storeRead.d.ts +153 -0
  223. package/dist/tools/shared/storeRead.d.ts.map +1 -0
  224. package/dist/tools/shared/storeRead.js +242 -0
  225. package/dist/tools/shared/storeRead.js.map +1 -0
  226. package/dist/tools/testSpec.d.ts +3 -2
  227. package/dist/tools/testSpec.d.ts.map +1 -1
  228. package/dist/tools/testSpec.js +51 -14
  229. package/dist/tools/testSpec.js.map +1 -1
  230. package/dist/tools/vector.d.ts +33 -1
  231. package/dist/tools/vector.d.ts.map +1 -1
  232. package/dist/tools/vector.js +31 -5
  233. package/dist/tools/vector.js.map +1 -1
  234. package/dist/tools/zoom/index.d.ts +15 -0
  235. package/dist/tools/zoom/index.d.ts.map +1 -0
  236. package/dist/tools/zoom/index.js +174 -0
  237. package/dist/tools/zoom/index.js.map +1 -0
  238. package/dist/tools/zoom.d.ts +234 -0
  239. package/dist/tools/zoom.d.ts.map +1 -0
  240. package/dist/tools/zoom.js +627 -0
  241. package/dist/tools/zoom.js.map +1 -0
  242. package/dist/transports/bridge.d.ts +1 -1
  243. package/dist/transports/bridge.d.ts.map +1 -1
  244. package/dist/transports/bridge.js +2 -0
  245. package/dist/transports/bridge.js.map +1 -1
  246. package/dist/transports/http.d.ts +1 -1
  247. package/dist/transports/http.d.ts.map +1 -1
  248. package/dist/transports/http.js +3 -1
  249. package/dist/transports/http.js.map +1 -1
  250. package/dist/transports/index.d.ts +1 -0
  251. package/dist/transports/index.d.ts.map +1 -1
  252. package/dist/transports/index.js +1 -0
  253. package/dist/transports/index.js.map +1 -1
  254. package/dist/transports/mcp.d.ts +1 -1
  255. package/dist/transports/mcp.d.ts.map +1 -1
  256. package/dist/transports/mcp.js +7 -3
  257. package/dist/transports/mcp.js.map +1 -1
  258. package/dist/transports/stdio.d.ts +1 -1
  259. package/dist/transports/stdio.d.ts.map +1 -1
  260. package/dist/transports/stdio.js +2 -0
  261. package/dist/transports/stdio.js.map +1 -1
  262. package/dist/transports/thinStdio.d.ts +22 -0
  263. package/dist/transports/thinStdio.d.ts.map +1 -0
  264. package/dist/transports/thinStdio.js +218 -0
  265. package/dist/transports/thinStdio.js.map +1 -0
  266. package/dist/transports/types.d.ts +8 -1
  267. package/dist/transports/types.d.ts.map +1 -1
  268. package/dist/types/agent-services.d.ts +7 -0
  269. package/dist/types/agent-services.d.ts.map +1 -1
  270. package/package.json +9 -4
  271. package/templates/com.decibel.daemon.plist +6 -1
  272. package/dist/tools/deck.d.ts +0 -11
  273. package/dist/tools/deck.d.ts.map +0 -1
  274. package/dist/tools/deck.js +0 -1656
  275. package/dist/tools/deck.js.map +0 -1
  276. package/dist/tools/mother.d.ts +0 -11
  277. package/dist/tools/mother.d.ts.map +0 -1
  278. package/dist/tools/mother.js +0 -503
  279. package/dist/tools/mother.js.map +0 -1
  280. package/dist/tools/registry.d.ts +0 -3
  281. package/dist/tools/registry.d.ts.map +0 -1
  282. package/dist/tools/registry.js +0 -189
  283. package/dist/tools/registry.js.map +0 -1
  284. package/dist/tools/senken.d.ts +0 -11
  285. package/dist/tools/senken.d.ts.map +0 -1
  286. package/dist/tools/senken.js +0 -482
  287. package/dist/tools/senken.js.map +0 -1
  288. package/dist/tools/terminal.d.ts +0 -17
  289. package/dist/tools/terminal.d.ts.map +0 -1
  290. package/dist/tools/terminal.js +0 -968
  291. package/dist/tools/terminal.js.map +0 -1
  292. package/dist/tools/toolsIndex.d.ts +0 -5
  293. package/dist/tools/toolsIndex.d.ts.map +0 -1
  294. package/dist/tools/toolsIndex.js +0 -37
  295. package/dist/tools/toolsIndex.js.map +0 -1
@@ -14,13 +14,33 @@ import { log } from './config.js';
14
14
  /**
15
15
  * Check if a directory exists
16
16
  */
17
+ /**
18
+ * Does this directory exist — and say so only when we could actually tell.
19
+ *
20
+ * ISS-0153, second round. The readdir calls below were made to THROW on an
21
+ * unreadable store rather than return empty, and the fix was reported as
22
+ * landed. It never fired: every one of them sits behind this guard, and this
23
+ * guard caught everything. A store at chmod 000 makes stat() fail with EACCES
24
+ * on the directory INSIDE it, so `dirExists` answered false, the readdir was
25
+ * skipped, and the throw was unreachable. The result was the exact behaviour
26
+ * the fix was written to remove — "no issues" for a project whose issues could
27
+ * not be read — with the code that says otherwise sitting right there.
28
+ *
29
+ * ENOENT and ENOTDIR mean the directory genuinely is not there, which is what
30
+ * an untouched project looks like. Every other errno means it may well be
31
+ * there and this process cannot see it, and that is not an answer this
32
+ * function is entitled to give.
33
+ */
17
34
  async function dirExists(dirPath) {
18
35
  try {
19
36
  const stat = await fs.stat(dirPath);
20
37
  return stat.isDirectory();
21
38
  }
22
- catch {
23
- return false;
39
+ catch (err) {
40
+ const code = err.code;
41
+ if (code === 'ENOENT' || code === 'ENOTDIR')
42
+ return false;
43
+ throw new Error(`STORE_UNREADABLE: cannot stat ${dirPath} (${code ?? 'unknown'})`);
24
44
  }
25
45
  }
26
46
  // ============================================================================
@@ -107,6 +127,17 @@ export async function readFilesFromBothPaths(projectId, subpath, extensions = ['
107
127
  const paths = await resolveDecibelPaths(projectId, subpath);
108
128
  const seen = new Set();
109
129
  const results = [];
130
+ // ISS-0153: a directory that exists but cannot be opened is NOT an empty
131
+ // directory. Both reads below used to `catch { /* Directory read failed */ }`
132
+ // and return whatever had been collected — which, for an unreadable store,
133
+ // was nothing. Every caller then reported "no issues" for a project whose
134
+ // issues it simply could not see.
135
+ //
136
+ // These now THROW. "I could not look" is an exceptional condition, not an
137
+ // empty result, and letting it propagate turns it into a loud tool failure at
138
+ // no cost to the six call sites. Note the dirExists() guard above already
139
+ // handles the ordinary not-created-yet case, so reaching the readdir at all
140
+ // means the directory is really there.
110
141
  // Read primary first (takes precedence)
111
142
  if (await dirExists(paths.primary)) {
112
143
  try {
@@ -121,8 +152,9 @@ export async function readFilesFromBothPaths(projectId, subpath, extensions = ['
121
152
  }
122
153
  }
123
154
  }
124
- catch {
125
- // Directory read failed
155
+ catch (err) {
156
+ const code = err.code ?? 'unknown';
157
+ throw new Error(`STORE_UNREADABLE: cannot read ${paths.primary} (${code})`);
126
158
  }
127
159
  }
128
160
  // Read legacy, skip duplicates
@@ -141,8 +173,9 @@ export async function readFilesFromBothPaths(projectId, subpath, extensions = ['
141
173
  }
142
174
  }
143
175
  }
144
- catch {
145
- // Directory read failed
176
+ catch (err) {
177
+ const code = err.code ?? 'unknown';
178
+ throw new Error(`STORE_UNREADABLE: cannot read ${paths.legacy} (${code})`);
146
179
  }
147
180
  }
148
181
  return results;
@@ -1 +1 @@
1
- {"version":3,"file":"decibelPaths.js","sourceRoot":"","sources":["../src/decibelPaths.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"decibelPaths.js","sourceRoot":"","sources":["../src/decibelPaths.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * The complete status vocabulary. Closed set — if a value is not here, it is
3
+ * not a status, and normalizeStatus decides what to do about it.
4
+ */
5
+ export declare const ISSUE_STATUSES: readonly ["open", "in_progress", "blocked", "closed", "wontfix"];
6
+ export type IssueStatus = (typeof ISSUE_STATUSES)[number];
7
+ /** Statuses meaning "no longer needs work". Everything else is live. */
8
+ export declare const TERMINAL_STATUSES: ReadonlySet<IssueStatus>;
9
+ export declare function isTerminal(status: IssueStatus): boolean;
10
+ export declare function isLive(status: IssueStatus): boolean;
11
+ export interface NormalizedStatus {
12
+ status: IssueStatus;
13
+ /** Set when the raw value was not already canonical. */
14
+ normalizedFrom?: string;
15
+ /**
16
+ * True when the raw value matched nothing and the fallback was used. The
17
+ * caller decides whether that is a warning or a hard error; the model will
18
+ * not invent a meaning for a value it does not recognize.
19
+ */
20
+ unrecognized?: boolean;
21
+ }
22
+ /**
23
+ * Map any on-disk status to the canonical vocabulary.
24
+ *
25
+ * Missing status defaults to `open` — that matches the previous reader's
26
+ * behaviour and is the safe direction: a record wrongly shown as open gets
27
+ * triaged, whereas one wrongly shown as closed disappears.
28
+ */
29
+ export declare function normalizeStatus(raw: unknown): NormalizedStatus;
30
+ export declare const ISSUE_SEVERITIES: readonly ["low", "med", "high", "critical"];
31
+ export type IssueSeverity = (typeof ISSUE_SEVERITIES)[number];
32
+ export declare const ISSUE_PRIORITIES: readonly ["low", "medium", "high", "critical"];
33
+ export type IssuePriority = (typeof ISSUE_PRIORITIES)[number];
34
+ /**
35
+ * A stable identifier that survives everything the human-facing id does not.
36
+ *
37
+ * ISS-NNNN is a display name: it is derived from a directory scan, it is
38
+ * reassigned when duplicates are repaired (four were, in Phase 2), and it is
39
+ * allocated independently per checkout — which is exactly how the same issue
40
+ * came to exist as ISS-0112 on one volume and ISS-0115 on another with nothing
41
+ * in the data connecting them. `uid` is the identity; `id` is the label.
42
+ *
43
+ * UUIDv7 rather than v4 because it is time-ordered: records sort by creation
44
+ * without consulting a timestamp field, and a Postgres index on it stays local
45
+ * rather than scattering writes across the tree when this reaches HQ sync.
46
+ */
47
+ export declare function newUid(now?: number): string;
48
+ export declare function isUid(value: unknown): value is string;
49
+ /**
50
+ * One issue, as the rest of the system should think about it.
51
+ *
52
+ * Deliberately absent: file path, file format, frontmatter layout, and the
53
+ * `**Status:**` line that markdown records carry in their body. That line is a
54
+ * rendering of `status`, not a second copy of it — treating it as data is what
55
+ * let sixteen records drift into saying `open` while the tools read them as
56
+ * closed. The codec regenerates it on write; nothing else may touch it.
57
+ */
58
+ export interface Issue {
59
+ /** Stable identity. Optional only until the backfill completes. */
60
+ uid?: string;
61
+ /** Human-facing label, e.g. ISS-0112. Renumberable; not identity. */
62
+ id: string;
63
+ title: string;
64
+ status: IssueStatus;
65
+ severity?: IssueSeverity;
66
+ priority?: IssuePriority;
67
+ tags?: string[];
68
+ epicId?: string;
69
+ project?: string;
70
+ /** Prose body: the markdown after the header block, or `description:`. */
71
+ details?: string;
72
+ resolution?: string;
73
+ created_at?: string;
74
+ updated_at?: string;
75
+ closed_at?: string;
76
+ }
77
+ //# sourceMappingURL=issue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue.d.ts","sourceRoot":"","sources":["../../src/domain/issue.ts"],"names":[],"mappings":"AA8BA;;;GAGG;AACH,eAAO,MAAM,cAAc,kEAMjB,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,WAAW,CAGrD,CAAC;AAEH,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAEvD;AAED,wBAAgB,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAEnD;AA2BD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,WAAW,CAAC;IACpB,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,CAmB9D;AAED,eAAO,MAAM,gBAAgB,6CAA8C,CAAC;AAC5E,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D,eAAO,MAAM,gBAAgB,gDAAiD,CAAC;AAC/E,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D;;;;;;;;;;;;GAYG;AACH,wBAAgB,MAAM,CAAC,GAAG,GAAE,MAAmB,GAAG,MAAM,CAgBvD;AAID,wBAAgB,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAErD;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,KAAK;IACpB,mEAAmE;IACnE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
@@ -0,0 +1,134 @@
1
+ // ============================================================================
2
+ // Canonical issue model — EPIC-0038 Phase 3
3
+ // ============================================================================
4
+ // The one definition of what an issue IS, independent of how it is stored.
5
+ //
6
+ // Before this file there were three, and they disagreed:
7
+ //
8
+ // src/sentinelIssues.ts 'open' | 'in_progress' | 'done' | 'blocked'
9
+ // src/tools/sentinel.ts 'open' | 'in_progress' | 'blocked' | 'closed' | 'wontfix'
10
+ // src/store/types.ts both unions merged, plus 'done'
11
+ //
12
+ // No two agree. `update_issue` could write `done`, which the reader's type did
13
+ // not contain; `close_issue` wrote `closed`, which the updater's type did not
14
+ // contain. Neither was a type error, because status crossed the boundary as a
15
+ // bare string: buildIssueSummary read it with `typeof parsed.status === 'string'`
16
+ // and the list filter compared it with `!==`. An out-of-vocabulary value was
17
+ // therefore not rejected and not normalized — it was stored, returned, and
18
+ // matched by no query.
19
+ //
20
+ // ISS-0026 is the proof. It sits on disk with `status: resolved`, a value no
21
+ // writer in this codebase can produce and no filter can select. It is finished
22
+ // work that is invisible to `list_issues(status: 'open')` and equally invisible
23
+ // to `list_issues(status: 'closed')`.
24
+ //
25
+ // So the vocabulary is closed, and everything entering the model goes through
26
+ // normalizeStatus(). Unknown values are mapped or flagged, never passed through.
27
+ // ============================================================================
28
+ import { randomBytes } from 'crypto';
29
+ /**
30
+ * The complete status vocabulary. Closed set — if a value is not here, it is
31
+ * not a status, and normalizeStatus decides what to do about it.
32
+ */
33
+ export const ISSUE_STATUSES = [
34
+ 'open',
35
+ 'in_progress',
36
+ 'blocked',
37
+ 'closed',
38
+ 'wontfix',
39
+ ];
40
+ /** Statuses meaning "no longer needs work". Everything else is live. */
41
+ export const TERMINAL_STATUSES = new Set([
42
+ 'closed',
43
+ 'wontfix',
44
+ ]);
45
+ export function isTerminal(status) {
46
+ return TERMINAL_STATUSES.has(status);
47
+ }
48
+ export function isLive(status) {
49
+ return !isTerminal(status);
50
+ }
51
+ /**
52
+ * Values seen on disk that predate the closed vocabulary, and what they meant.
53
+ *
54
+ * `done` came from sentinelIssues.updateIssue, whose union had it. `resolved`
55
+ * came from a hand-edit or an older tool; ISS-0026 is the only instance. Both
56
+ * mean the work finished, so both map to `closed` — the mapping is recorded on
57
+ * the decoded record rather than applied silently, so a caller can tell the
58
+ * difference between a record that said `closed` and one that was interpreted.
59
+ */
60
+ const STATUS_ALIASES = {
61
+ done: 'closed',
62
+ resolved: 'closed',
63
+ complete: 'closed',
64
+ completed: 'closed',
65
+ fixed: 'closed',
66
+ wont_fix: 'wontfix',
67
+ 'wont-fix': 'wontfix',
68
+ duplicate: 'closed',
69
+ reopened: 'open',
70
+ todo: 'open',
71
+ new: 'open',
72
+ active: 'in_progress',
73
+ in_review: 'in_progress',
74
+ };
75
+ /**
76
+ * Map any on-disk status to the canonical vocabulary.
77
+ *
78
+ * Missing status defaults to `open` — that matches the previous reader's
79
+ * behaviour and is the safe direction: a record wrongly shown as open gets
80
+ * triaged, whereas one wrongly shown as closed disappears.
81
+ */
82
+ export function normalizeStatus(raw) {
83
+ if (typeof raw !== 'string' || raw.trim() === '') {
84
+ // Absent is not the same as wrong: a record with no status is defaulted
85
+ // quietly, while a record whose status is an empty string or a number is
86
+ // flagged, because something wrote that on purpose.
87
+ if (raw === undefined || raw === null)
88
+ return { status: 'open' };
89
+ return { status: 'open', normalizedFrom: String(raw), unrecognized: true };
90
+ }
91
+ const key = raw.trim().toLowerCase();
92
+ if (ISSUE_STATUSES.includes(key)) {
93
+ const status = key;
94
+ return key === raw ? { status } : { status, normalizedFrom: raw };
95
+ }
96
+ const aliased = STATUS_ALIASES[key];
97
+ if (aliased)
98
+ return { status: aliased, normalizedFrom: raw };
99
+ return { status: 'open', normalizedFrom: raw, unrecognized: true };
100
+ }
101
+ export const ISSUE_SEVERITIES = ['low', 'med', 'high', 'critical'];
102
+ export const ISSUE_PRIORITIES = ['low', 'medium', 'high', 'critical'];
103
+ /**
104
+ * A stable identifier that survives everything the human-facing id does not.
105
+ *
106
+ * ISS-NNNN is a display name: it is derived from a directory scan, it is
107
+ * reassigned when duplicates are repaired (four were, in Phase 2), and it is
108
+ * allocated independently per checkout — which is exactly how the same issue
109
+ * came to exist as ISS-0112 on one volume and ISS-0115 on another with nothing
110
+ * in the data connecting them. `uid` is the identity; `id` is the label.
111
+ *
112
+ * UUIDv7 rather than v4 because it is time-ordered: records sort by creation
113
+ * without consulting a timestamp field, and a Postgres index on it stays local
114
+ * rather than scattering writes across the tree when this reaches HQ sync.
115
+ */
116
+ export function newUid(now = Date.now()) {
117
+ const bytes = randomBytes(16);
118
+ // 48-bit big-endian millisecond timestamp.
119
+ bytes[0] = (now / 2 ** 40) & 0xff;
120
+ bytes[1] = (now / 2 ** 32) & 0xff;
121
+ bytes[2] = (now / 2 ** 24) & 0xff;
122
+ bytes[3] = (now / 2 ** 16) & 0xff;
123
+ bytes[4] = (now / 2 ** 8) & 0xff;
124
+ bytes[5] = now & 0xff;
125
+ bytes[6] = (bytes[6] & 0x0f) | 0x70; // version 7
126
+ bytes[8] = (bytes[8] & 0x3f) | 0x80; // RFC 4122 variant
127
+ const hex = bytes.toString('hex');
128
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
129
+ }
130
+ const UID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
131
+ export function isUid(value) {
132
+ return typeof value === 'string' && UID_RE.test(value);
133
+ }
134
+ //# sourceMappingURL=issue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue.js","sourceRoot":"","sources":["../../src/domain/issue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { Issue } from './issue.js';
2
+ export type IssueFormat = 'md' | 'yaml';
3
+ export interface DecodedIssue {
4
+ issue: Issue;
5
+ format: IssueFormat;
6
+ /**
7
+ * Everything needed to reconstruct the file byte-for-byte apart from the
8
+ * fields the model owns. Callers should treat this as opaque and pass it back
9
+ * to encodeIssue unchanged.
10
+ */
11
+ raw: {
12
+ data: Record<string, unknown>;
13
+ body: string;
14
+ };
15
+ /**
16
+ * Non-fatal observations: a normalized status, an unrecognized value, a
17
+ * missing title. Surfaced so callers can report integrity problems rather
18
+ * than discovering them months later.
19
+ */
20
+ warnings: string[];
21
+ }
22
+ /**
23
+ * Split a bare-YAML record into its YAML head and any markdown tail at column 0.
24
+ *
25
+ * The column-0 anchor is load-bearing and must not gain `\s*`: headings indented
26
+ * inside a `description:` block scalar are body text, not a tail, and matching
27
+ * them would truncate the record at parse time. Phase 2 verified no record in
28
+ * the store relies on the difference, but nothing else pins it, so it is pinned
29
+ * by test here.
30
+ */
31
+ export declare function splitBareYaml(content: string): {
32
+ head: string;
33
+ tail: string;
34
+ };
35
+ export declare function decodeIssue(filename: string, content: string): DecodedIssue;
36
+ export declare function encodeIssue(decoded: DecodedIssue): string;
37
+ /** Apply changes to a decoded record, keeping derived state consistent. */
38
+ export declare function applyIssueChanges(decoded: DecodedIssue, changes: Partial<Issue>): DecodedIssue;
39
+ //# sourceMappingURL=issueCodec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issueCodec.d.ts","sourceRoot":"","sources":["../../src/domain/issueCodec.ts"],"names":[],"mappings":"AAyBA,OAAO,EACL,KAAK,EAKN,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,MAAM,CAAC;AAExC,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB;;;;OAIG;IACH,GAAG,EAAE;QACH,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9B,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF;;;;OAIG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAkCD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAK7E;AA8BD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CA4G3E;AA0CD,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAuDzD;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,CAE9F"}