codetrellis 0.0.0-stage → 0.3.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 (448) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +27 -2
  3. package/bin/codetrellis.mjs +4 -0
  4. package/package.json +41 -4
  5. package/reader/material-reader.mjs +130346 -0
  6. package/resources/tree-sitter/README.md +150 -0
  7. package/resources/tree-sitter/tree-sitter-c-sharp.wasm +0 -0
  8. package/resources/tree-sitter/tree-sitter-go.wasm +0 -0
  9. package/resources/tree-sitter/tree-sitter-java.wasm +0 -0
  10. package/resources/tree-sitter/tree-sitter-javascript.wasm +0 -0
  11. package/resources/tree-sitter/tree-sitter-kotlin.wasm +0 -0
  12. package/resources/tree-sitter/tree-sitter-php.wasm +0 -0
  13. package/resources/tree-sitter/tree-sitter-python.wasm +0 -0
  14. package/resources/tree-sitter/tree-sitter-ruby.wasm +0 -0
  15. package/resources/tree-sitter/tree-sitter-rust.wasm +0 -0
  16. package/resources/tree-sitter/tree-sitter-swift.wasm +0 -0
  17. package/resources/tree-sitter/tree-sitter-tsx.wasm +0 -0
  18. package/resources/tree-sitter/tree-sitter-typescript.wasm +0 -0
  19. package/resources/tree-sitter/tree-sitter.wasm +0 -0
  20. package/src/backend/agent/claude-code-watcher.js +270 -0
  21. package/src/backend/index.js +8 -0
  22. package/src/backend/lib/sha256-file.js +39 -0
  23. package/src/backend/lib/zip-entries.js +98 -0
  24. package/src/backend/lifecycle.js +102 -0
  25. package/src/backend/mcp/binding-headers.js +54 -0
  26. package/src/backend/mcp/client-identity.js +44 -0
  27. package/src/backend/mcp/connector/command.js +110 -0
  28. package/src/backend/mcp/connector/core.js +278 -0
  29. package/src/backend/mcp/connector/files.js +121 -0
  30. package/src/backend/mcp/connector/hook.js +284 -0
  31. package/src/backend/mcp/connector/main.js +126 -0
  32. package/src/backend/mcp/connector/sse-upstream.js +152 -0
  33. package/src/backend/mcp/helpers.js +43 -0
  34. package/src/backend/mcp/prompt-builders.js +104 -0
  35. package/src/backend/mcp/resources.js +197 -0
  36. package/src/backend/mcp/server.js +813 -0
  37. package/src/backend/mcp/skill-guide.js +1528 -0
  38. package/src/backend/mcp/tools/architecture-tools.js +273 -0
  39. package/src/backend/mcp/tools/audio-tools.js +117 -0
  40. package/src/backend/mcp/tools/awareness-tools.js +623 -0
  41. package/src/backend/mcp/tools/budget-tools.js +185 -0
  42. package/src/backend/mcp/tools/channel-tools.js +205 -0
  43. package/src/backend/mcp/tools/contribution-tools.js +181 -0
  44. package/src/backend/mcp/tools/drift-tools.js +252 -0
  45. package/src/backend/mcp/tools/git-tools.js +316 -0
  46. package/src/backend/mcp/tools/governance-tools.js +175 -0
  47. package/src/backend/mcp/tools/graph-tools.js +181 -0
  48. package/src/backend/mcp/tools/intake-tools.js +244 -0
  49. package/src/backend/mcp/tools/mobile-tools.js +118 -0
  50. package/src/backend/mcp/tools/peer-tools.js +330 -0
  51. package/src/backend/mcp/tools/plan-item-tools.js +1601 -0
  52. package/src/backend/mcp/tools/plan-tools.js +680 -0
  53. package/src/backend/mcp/tools/presence-tools.js +185 -0
  54. package/src/backend/mcp/tools/project-config-tools.js +150 -0
  55. package/src/backend/mcp/tools/review-tools.js +172 -0
  56. package/src/backend/mcp/tools/session-tools.js +554 -0
  57. package/src/backend/mcp/tools/system-docs-tools.js +168 -0
  58. package/src/backend/mcp/tools/terminal-tools.js +186 -0
  59. package/src/backend/mcp/tools/test-tools.js +117 -0
  60. package/src/backend/mcp/tools/ui-tools.js +356 -0
  61. package/src/backend/mcp/types.js +15 -0
  62. package/src/backend/middleware/local-auth.js +116 -0
  63. package/src/backend/server.js +5951 -0
  64. package/src/backend/services/agent-event-log.js +350 -0
  65. package/src/backend/services/architecture-rule.js +584 -0
  66. package/src/backend/services/architecture-rules.js +275 -0
  67. package/src/backend/services/artefact-content-service.js +181 -0
  68. package/src/backend/services/artefact-service.js +305 -0
  69. package/src/backend/services/artefact-watcher.js +167 -0
  70. package/src/backend/services/ast-parser.js +327 -0
  71. package/src/backend/services/audio-buffer-service.js +152 -0
  72. package/src/backend/services/awareness-notices.js +139 -0
  73. package/src/backend/services/awareness-replies.js +194 -0
  74. package/src/backend/services/awareness-service.js +344 -0
  75. package/src/backend/services/awareness-signals.js +267 -0
  76. package/src/backend/services/baseline-store.js +83 -0
  77. package/src/backend/services/branch-workstreams.js +341 -0
  78. package/src/backend/services/breakpoint-service.js +584 -0
  79. package/src/backend/services/brief-service.js +299 -0
  80. package/src/backend/services/budget-service.js +528 -0
  81. package/src/backend/services/callsites/base.js +15 -0
  82. package/src/backend/services/callsites/csharp.js +148 -0
  83. package/src/backend/services/callsites/go.js +163 -0
  84. package/src/backend/services/callsites/index.js +53 -0
  85. package/src/backend/services/callsites/kotlin.js +123 -0
  86. package/src/backend/services/callsites/process-env.js +125 -0
  87. package/src/backend/services/callsites/python.js +91 -0
  88. package/src/backend/services/callsites/ruby.js +164 -0
  89. package/src/backend/services/callsites/shared.js +198 -0
  90. package/src/backend/services/callsites/swift.js +115 -0
  91. package/src/backend/services/callsites/typescript.js +87 -0
  92. package/src/backend/services/capability-token.js +108 -0
  93. package/src/backend/services/change-check.js +156 -0
  94. package/src/backend/services/channel-dispatcher-service.js +235 -0
  95. package/src/backend/services/channel-event-file-service.js +125 -0
  96. package/src/backend/services/channel-event-service.js +297 -0
  97. package/src/backend/services/check-runs.js +177 -0
  98. package/src/backend/services/checkout-identity.js +73 -0
  99. package/src/backend/services/claude-code-parallel.js +221 -0
  100. package/src/backend/services/claude-desktop-config.js +186 -0
  101. package/src/backend/services/cli-install.js +249 -0
  102. package/src/backend/services/clock.js +57 -0
  103. package/src/backend/services/cloud-files.js +191 -0
  104. package/src/backend/services/coalesce.js +50 -0
  105. package/src/backend/services/code-breakpoints.js +291 -0
  106. package/src/backend/services/comment-service.js +168 -0
  107. package/src/backend/services/commit-attribution.js +134 -0
  108. package/src/backend/services/commit-edges.js +99 -0
  109. package/src/backend/services/confined-fs.js +241 -0
  110. package/src/backend/services/conformity-gate.js +132 -0
  111. package/src/backend/services/contribution-service.js +409 -0
  112. package/src/backend/services/coverage-service.js +173 -0
  113. package/src/backend/services/criteria-service.js +721 -0
  114. package/src/backend/services/criterion-checks.js +387 -0
  115. package/src/backend/services/criterion-loop-service.js +411 -0
  116. package/src/backend/services/cross-system-service.js +231 -0
  117. package/src/backend/services/database.js +916 -0
  118. package/src/backend/services/db-schema.js +1358 -0
  119. package/src/backend/services/deviation-service.js +344 -0
  120. package/src/backend/services/diff-engine.js +168 -0
  121. package/src/backend/services/evidence.js +363 -0
  122. package/src/backend/services/external-intake-service.js +269 -0
  123. package/src/backend/services/external-pointer-service.js +195 -0
  124. package/src/backend/services/external-refs-service.js +214 -0
  125. package/src/backend/services/file-history.js +158 -0
  126. package/src/backend/services/file-watcher.js +193 -0
  127. package/src/backend/services/folder-requests.js +118 -0
  128. package/src/backend/services/freeze-service.js +189 -0
  129. package/src/backend/services/gemini-cli-hook.js +172 -0
  130. package/src/backend/services/git-activity-service.js +325 -0
  131. package/src/backend/services/git-blobs.js +70 -0
  132. package/src/backend/services/git-branches.js +357 -0
  133. package/src/backend/services/git-checkout.js +153 -0
  134. package/src/backend/services/git-commit-service.js +91 -0
  135. package/src/backend/services/git-env.js +121 -0
  136. package/src/backend/services/git-identity.js +84 -0
  137. package/src/backend/services/git-refs.js +386 -0
  138. package/src/backend/services/git-safety.js +58 -0
  139. package/src/backend/services/grant-guard.js +67 -0
  140. package/src/backend/services/html-view-policy.js +135 -0
  141. package/src/backend/services/human-decision.js +55 -0
  142. package/src/backend/services/importers.js +159 -0
  143. package/src/backend/services/intent-service.js +105 -0
  144. package/src/backend/services/ipc-dispatcher.js +164 -0
  145. package/src/backend/services/item-git-state.js +208 -0
  146. package/src/backend/services/line-changes.js +232 -0
  147. package/src/backend/services/line-history.js +174 -0
  148. package/src/backend/services/local-api-changes.js +40 -0
  149. package/src/backend/services/logger.js +217 -0
  150. package/src/backend/services/material-footprints.js +203 -0
  151. package/src/backend/services/material-place.js +82 -0
  152. package/src/backend/services/material-reader/docx-markdown.js +198 -0
  153. package/src/backend/services/material-reader/fixtures.test-helper.js +169 -0
  154. package/src/backend/services/material-reader/quote.js +44 -0
  155. package/src/backend/services/material-reader/reader-host.js +202 -0
  156. package/src/backend/services/material-signals.js +141 -0
  157. package/src/backend/services/mcp-capabilities.js +390 -0
  158. package/src/backend/services/mdns-service.js +304 -0
  159. package/src/backend/services/mobile-api-server.js +281 -0
  160. package/src/backend/services/mobile-approvals.js +306 -0
  161. package/src/backend/services/mobile-awareness.js +180 -0
  162. package/src/backend/services/mobile-breakpoints.js +115 -0
  163. package/src/backend/services/mobile-budget.js +98 -0
  164. package/src/backend/services/mobile-freeze.js +106 -0
  165. package/src/backend/services/mobile-proposals.js +100 -0
  166. package/src/backend/services/mobile-rpc-service.js +1289 -0
  167. package/src/backend/services/mobile-workstreams.js +160 -0
  168. package/src/backend/services/monorepo-detector.js +131 -0
  169. package/src/backend/services/other-work.js +45 -0
  170. package/src/backend/services/pack-seal.js +129 -0
  171. package/src/backend/services/paired-device-service.js +192 -0
  172. package/src/backend/services/pairing-server.js +323 -0
  173. package/src/backend/services/pairing-service.js +200 -0
  174. package/src/backend/services/pantry-resolution-service.js +166 -0
  175. package/src/backend/services/parsers/base.js +124 -0
  176. package/src/backend/services/parsers/csharp.js +224 -0
  177. package/src/backend/services/parsers/go.js +180 -0
  178. package/src/backend/services/parsers/index.js +101 -0
  179. package/src/backend/services/parsers/java.js +103 -0
  180. package/src/backend/services/parsers/kotlin.js +252 -0
  181. package/src/backend/services/parsers/php.js +113 -0
  182. package/src/backend/services/parsers/python.js +189 -0
  183. package/src/backend/services/parsers/ruby.js +212 -0
  184. package/src/backend/services/parsers/rust.js +97 -0
  185. package/src/backend/services/parsers/swift.js +221 -0
  186. package/src/backend/services/parsers/typescript.js +235 -0
  187. package/src/backend/services/pattern-scan.js +65 -0
  188. package/src/backend/services/patterns.js +281 -0
  189. package/src/backend/services/peer-audit-service.js +123 -0
  190. package/src/backend/services/peer-auth.js +153 -0
  191. package/src/backend/services/peer-capabilities.js +209 -0
  192. package/src/backend/services/peer-connection-service.js +450 -0
  193. package/src/backend/services/peer-grants.js +33 -0
  194. package/src/backend/services/persistence.js +116 -0
  195. package/src/backend/services/personal-sync-service.js +232 -0
  196. package/src/backend/services/pipeline-approvals.js +72 -0
  197. package/src/backend/services/pipeline.js +232 -0
  198. package/src/backend/services/plan-arrivals.js +68 -0
  199. package/src/backend/services/plan-changes-service.js +273 -0
  200. package/src/backend/services/plan-conflict-service.js +288 -0
  201. package/src/backend/services/plan-dependencies.js +91 -0
  202. package/src/backend/services/plan-doc-guard.js +90 -0
  203. package/src/backend/services/plan-documents-service.js +275 -0
  204. package/src/backend/services/plan-event-service.js +154 -0
  205. package/src/backend/services/plan-file-refs.js +106 -0
  206. package/src/backend/services/plan-file-service.js +1564 -0
  207. package/src/backend/services/plan-history-service.js +156 -0
  208. package/src/backend/services/plan-import-service.js +261 -0
  209. package/src/backend/services/plan-item-service.js +1223 -0
  210. package/src/backend/services/plan-migrate-service.js +395 -0
  211. package/src/backend/services/plan-overlay-service.js +173 -0
  212. package/src/backend/services/plan-phases-service.js +182 -0
  213. package/src/backend/services/plan-progress-service.js +134 -0
  214. package/src/backend/services/plan-review-service.js +262 -0
  215. package/src/backend/services/plan-service.js +682 -0
  216. package/src/backend/services/plan-status.js +113 -0
  217. package/src/backend/services/plan-template-publish-service.js +217 -0
  218. package/src/backend/services/plan-templates-service.js +242 -0
  219. package/src/backend/services/plan-templates.js +1164 -0
  220. package/src/backend/services/planned-overlap-actions.js +200 -0
  221. package/src/backend/services/plans-home.js +224 -0
  222. package/src/backend/services/play-forward.js +256 -0
  223. package/src/backend/services/playback-service.js +117 -0
  224. package/src/backend/services/power-service.js +167 -0
  225. package/src/backend/services/power-signals.js +81 -0
  226. package/src/backend/services/pr-draft-service.js +142 -0
  227. package/src/backend/services/presence-service.js +122 -0
  228. package/src/backend/services/pricing.js +60 -0
  229. package/src/backend/services/project-config-service.js +474 -0
  230. package/src/backend/services/project-scanner.js +184 -0
  231. package/src/backend/services/projection-service.js +69 -0
  232. package/src/backend/services/push-notification-service.js +288 -0
  233. package/src/backend/services/recent-projects-service.js +204 -0
  234. package/src/backend/services/record-chain.js +162 -0
  235. package/src/backend/services/recurrence-rule.js +63 -0
  236. package/src/backend/services/recurring-agent.js +89 -0
  237. package/src/backend/services/recurring-scheduler.js +77 -0
  238. package/src/backend/services/recurring-service.js +276 -0
  239. package/src/backend/services/reference-service.js +169 -0
  240. package/src/backend/services/release-public-key.js +30 -0
  241. package/src/backend/services/release-signature.js +64 -0
  242. package/src/backend/services/remote-audio-service.js +224 -0
  243. package/src/backend/services/remote-interaction-service.js +275 -0
  244. package/src/backend/services/remote-terminal-service.js +324 -0
  245. package/src/backend/services/rendition/child/main.js +76 -0
  246. package/src/backend/services/rendition/engine-host.js +249 -0
  247. package/src/backend/services/rendition/engine-lock.js +39 -0
  248. package/src/backend/services/rendition/engine-lock.json +14 -0
  249. package/src/backend/services/rendition/engine-manifest.js +97 -0
  250. package/src/backend/services/rendition/network-proof.js +73 -0
  251. package/src/backend/services/rendition/rendition-service.js +175 -0
  252. package/src/backend/services/replay-frames.js +387 -0
  253. package/src/backend/services/replay-state.js +201 -0
  254. package/src/backend/services/resolvers/base.js +108 -0
  255. package/src/backend/services/resolvers/csharp.js +109 -0
  256. package/src/backend/services/resolvers/go.js +105 -0
  257. package/src/backend/services/resolvers/index.js +60 -0
  258. package/src/backend/services/resolvers/java.js +63 -0
  259. package/src/backend/services/resolvers/kotlin.js +109 -0
  260. package/src/backend/services/resolvers/php.js +89 -0
  261. package/src/backend/services/resolvers/python.js +154 -0
  262. package/src/backend/services/resolvers/ruby.js +103 -0
  263. package/src/backend/services/resolvers/rust.js +77 -0
  264. package/src/backend/services/resolvers/swift.js +98 -0
  265. package/src/backend/services/resolvers/typescript.js +71 -0
  266. package/src/backend/services/retention.js +54 -0
  267. package/src/backend/services/review-architecture.js +236 -0
  268. package/src/backend/services/review-attest.js +68 -0
  269. package/src/backend/services/review-bundle.js +226 -0
  270. package/src/backend/services/review-graduation.js +93 -0
  271. package/src/backend/services/review-host/bitbucket.js +79 -0
  272. package/src/backend/services/review-host/detect.js +80 -0
  273. package/src/backend/services/review-host/github.js +97 -0
  274. package/src/backend/services/review-host/gitlab.js +77 -0
  275. package/src/backend/services/review-host/host-state.js +103 -0
  276. package/src/backend/services/review-host/http.js +58 -0
  277. package/src/backend/services/review-host/switch.js +120 -0
  278. package/src/backend/services/review-marks.js +72 -0
  279. package/src/backend/services/review-notes.js +169 -0
  280. package/src/backend/services/review-other-work.js +90 -0
  281. package/src/backend/services/review-queue-service.js +147 -0
  282. package/src/backend/services/review-risk.js +127 -0
  283. package/src/backend/services/review-task.js +121 -0
  284. package/src/backend/services/rule-approvals.js +275 -0
  285. package/src/backend/services/rule-baseline.js +134 -0
  286. package/src/backend/services/rule-changes.js +162 -0
  287. package/src/backend/services/rule-preview.js +47 -0
  288. package/src/backend/services/rule-proposals.js +104 -0
  289. package/src/backend/services/rule-scope.js +76 -0
  290. package/src/backend/services/rulebook.js +286 -0
  291. package/src/backend/services/rules-at.js +56 -0
  292. package/src/backend/services/rules-overview.js +88 -0
  293. package/src/backend/services/schema-reconciler.js +250 -0
  294. package/src/backend/services/secret-store.js +119 -0
  295. package/src/backend/services/section-workstreams.js +95 -0
  296. package/src/backend/services/self-write-tracker.js +75 -0
  297. package/src/backend/services/sensor-bridge-service.js +285 -0
  298. package/src/backend/services/session-service.js +192 -0
  299. package/src/backend/services/settings-service.js +324 -0
  300. package/src/backend/services/signal-breakpoints.js +172 -0
  301. package/src/backend/services/signed-approval-record.js +86 -0
  302. package/src/backend/services/signed-approvals.js +244 -0
  303. package/src/backend/services/signoff-pack.js +328 -0
  304. package/src/backend/services/signoff-rows.js +114 -0
  305. package/src/backend/services/skill-arrival-service.js +138 -0
  306. package/src/backend/services/skill-model.js +193 -0
  307. package/src/backend/services/skill-use-service.js +140 -0
  308. package/src/backend/services/skills-service.js +150 -0
  309. package/src/backend/services/snapshot-compare-service.js +397 -0
  310. package/src/backend/services/source-control.js +189 -0
  311. package/src/backend/services/spec-links-service.js +123 -0
  312. package/src/backend/services/spec-proposal-withdraw.js +50 -0
  313. package/src/backend/services/spec-proposals-service.js +470 -0
  314. package/src/backend/services/sql/embedded.js +95 -0
  315. package/src/backend/services/sql/index.js +63 -0
  316. package/src/backend/services/sql/refs.js +357 -0
  317. package/src/backend/services/sql/schema.js +312 -0
  318. package/src/backend/services/sql/tokenizer.js +195 -0
  319. package/src/backend/services/stack-overlaps.js +117 -0
  320. package/src/backend/services/stack-service.js +225 -0
  321. package/src/backend/services/state-sync-service.js +384 -0
  322. package/src/backend/services/stuck-sensor-service.js +200 -0
  323. package/src/backend/services/system-discovery.js +481 -0
  324. package/src/backend/services/system-docs-service.js +701 -0
  325. package/src/backend/services/task-attachments-service.js +340 -0
  326. package/src/backend/services/task-grounding.js +60 -0
  327. package/src/backend/services/task-records/check-run-record.js +146 -0
  328. package/src/backend/services/task-records/check-runs.js +115 -0
  329. package/src/backend/services/task-records/heads.js +88 -0
  330. package/src/backend/services/task-records/material-reads.js +225 -0
  331. package/src/backend/services/task-records/read-record.js +100 -0
  332. package/src/backend/services/task-records/record.js +173 -0
  333. package/src/backend/services/task-records/run-record.js +136 -0
  334. package/src/backend/services/task-records/shared-state.js +548 -0
  335. package/src/backend/services/task-records/signing.js +140 -0
  336. package/src/backend/services/task-records/split-signals.js +52 -0
  337. package/src/backend/services/task-records/test-runs.js +164 -0
  338. package/src/backend/services/task-records/trust.js +243 -0
  339. package/src/backend/services/task-rules.js +81 -0
  340. package/src/backend/services/task-workstreams.js +90 -0
  341. package/src/backend/services/terminal-history-service.js +266 -0
  342. package/src/backend/services/terminal-service.js +267 -0
  343. package/src/backend/services/test-clock.js +53 -0
  344. package/src/backend/services/tests/grounding.js +266 -0
  345. package/src/backend/services/tests/junit.js +104 -0
  346. package/src/backend/services/tests/teammate-runs.js +134 -0
  347. package/src/backend/services/tests/test-results.js +234 -0
  348. package/src/backend/services/tree-watcher.js +204 -0
  349. package/src/backend/services/trellis-service.js +204 -0
  350. package/src/backend/services/trusted-roots.js +186 -0
  351. package/src/backend/services/update-download-service.js +342 -0
  352. package/src/backend/services/update-service.js +266 -0
  353. package/src/backend/services/watch-ignore.js +76 -0
  354. package/src/backend/services/webhook-egress.js +206 -0
  355. package/src/backend/services/webrtc-service.js +413 -0
  356. package/src/backend/services/work-changes.js +59 -0
  357. package/src/backend/services/workstream-binding.js +82 -0
  358. package/src/backend/services/workstream-commits.js +116 -0
  359. package/src/backend/services/workstream-imports.js +177 -0
  360. package/src/backend/services/workstream-service.js +335 -0
  361. package/src/backend/services/workstream-symbols.js +223 -0
  362. package/src/backend/services/workstream-watch-service.js +391 -0
  363. package/src/backend/services/worktree-service.js +235 -0
  364. package/src/cli/agent.js +100 -0
  365. package/src/cli/args.js +209 -0
  366. package/src/cli/conformity.js +106 -0
  367. package/src/cli/desktop.js +91 -0
  368. package/src/cli/main.js +411 -0
  369. package/src/cli/pipeline.js +109 -0
  370. package/src/cli/plan-verbs.js +259 -0
  371. package/src/cli/review-adapters.js +220 -0
  372. package/src/cli/review-output.js +93 -0
  373. package/src/cli/review-post.js +89 -0
  374. package/src/cli/review-sink.js +183 -0
  375. package/src/cli/review-skill.js +44 -0
  376. package/src/cli/review-verify.js +104 -0
  377. package/src/cli/review.js +386 -0
  378. package/src/cli/sarif.js +148 -0
  379. package/src/cli/verbs.js +360 -0
  380. package/src/shared/build-info.js +39 -0
  381. package/src/shared/lib/agent-review.js +199 -0
  382. package/src/shared/lib/agent-turns.js +140 -0
  383. package/src/shared/lib/awareness-digest.js +120 -0
  384. package/src/shared/lib/branch-name.js +45 -0
  385. package/src/shared/lib/breakpoint-words.js +118 -0
  386. package/src/shared/lib/budget-words.js +56 -0
  387. package/src/shared/lib/burst.js +69 -0
  388. package/src/shared/lib/call-entry.js +105 -0
  389. package/src/shared/lib/check-compare.js +42 -0
  390. package/src/shared/lib/check-words.js +216 -0
  391. package/src/shared/lib/csv.js +62 -0
  392. package/src/shared/lib/folder-entry.js +87 -0
  393. package/src/shared/lib/freeze-words.js +60 -0
  394. package/src/shared/lib/fuzzy.js +84 -0
  395. package/src/shared/lib/git-state-words.js +80 -0
  396. package/src/shared/lib/grep-entry.js +86 -0
  397. package/src/shared/lib/grounding-line.js +61 -0
  398. package/src/shared/lib/import-line.js +71 -0
  399. package/src/shared/lib/item-status.js +249 -0
  400. package/src/shared/lib/line-changes.js +53 -0
  401. package/src/shared/lib/locator.js +71 -0
  402. package/src/shared/lib/matcher.js +120 -0
  403. package/src/shared/lib/merge-order.js +65 -0
  404. package/src/shared/lib/open-findings.js +68 -0
  405. package/src/shared/lib/other-work.js +108 -0
  406. package/src/shared/lib/package-entry.js +142 -0
  407. package/src/shared/lib/plan-vocab.js +40 -0
  408. package/src/shared/lib/pptx-xml.js +86 -0
  409. package/src/shared/lib/proposal-words.js +61 -0
  410. package/src/shared/lib/recurrence.js +183 -0
  411. package/src/shared/lib/references.js +72 -0
  412. package/src/shared/lib/rule-pattern.js +56 -0
  413. package/src/shared/lib/sdp-fingerprint.js +115 -0
  414. package/src/shared/lib/sdp-minimal.js +123 -0
  415. package/src/shared/lib/secret-paths.js +34 -0
  416. package/src/shared/lib/signal-words.js +172 -0
  417. package/src/shared/lib/signoff.js +56 -0
  418. package/src/shared/lib/skills-note.js +60 -0
  419. package/src/shared/lib/spec-sections.js +78 -0
  420. package/src/shared/lib/symbol-entry.js +60 -0
  421. package/src/shared/lib/tool-phrasing.js +338 -0
  422. package/src/shared/lib/turn-gap.js +27 -0
  423. package/src/shared/lib/workstream-words.js +38 -0
  424. package/src/shared/lib/xlsx-xml.js +144 -0
  425. package/src/shared/lib/zip-reader.js +99 -0
  426. package/src/shared/types/agent.js +27 -0
  427. package/src/shared/types/architecture-rules.js +30 -0
  428. package/src/shared/types/ast.js +15 -0
  429. package/src/shared/types/breakpoint.js +33 -0
  430. package/src/shared/types/channel.js +41 -0
  431. package/src/shared/types/criteria.js +15 -0
  432. package/src/shared/types/graph.js +15 -0
  433. package/src/shared/types/index.js +53 -0
  434. package/src/shared/types/peer.js +36 -0
  435. package/src/shared/types/pipeline.js +15 -0
  436. package/src/shared/types/plan.js +15 -0
  437. package/src/shared/types/play-forward.js +15 -0
  438. package/src/shared/types/power.js +15 -0
  439. package/src/shared/types/presence.js +15 -0
  440. package/src/shared/types/project-config.js +35 -0
  441. package/src/shared/types/project.js +15 -0
  442. package/src/shared/types/record.js +15 -0
  443. package/src/shared/types/recurring.js +15 -0
  444. package/src/shared/types/review.js +15 -0
  445. package/src/shared/types/settings.js +114 -0
  446. package/src/shared/types/stack.js +15 -0
  447. package/src/shared/types/system-doc.js +15 -0
  448. package/src/shared/types/system.js +15 -0
@@ -0,0 +1,1358 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var db_schema_exports = {};
19
+ __export(db_schema_exports, {
20
+ EPHEMERAL_TABLES: () => EPHEMERAL_TABLES,
21
+ PERSISTENT_SCHEMA_SQL: () => PERSISTENT_SCHEMA_SQL,
22
+ RECONCILED_SCHEMA_SQL: () => RECONCILED_SCHEMA_SQL,
23
+ SCHEMA_AST: () => SCHEMA_AST,
24
+ SCHEMA_ATTACHMENTS: () => SCHEMA_ATTACHMENTS,
25
+ SCHEMA_EXTERNAL_REFS: () => SCHEMA_EXTERNAL_REFS,
26
+ SCHEMA_PLANS_CORE: () => SCHEMA_PLANS_CORE,
27
+ SCHEMA_PLAN_ITEMS: () => SCHEMA_PLAN_ITEMS,
28
+ SCHEMA_SYSTEM_DOCS: () => SCHEMA_SYSTEM_DOCS
29
+ });
30
+ module.exports = __toCommonJS(db_schema_exports);
31
+ const SCHEMA_AST = `
32
+ CREATE TABLE IF NOT EXISTS files (
33
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
34
+ path TEXT UNIQUE NOT NULL,
35
+ relative_path TEXT NOT NULL,
36
+ language TEXT NOT NULL,
37
+ content_hash TEXT NOT NULL,
38
+ last_parsed INTEGER NOT NULL
39
+ );
40
+
41
+ CREATE TABLE IF NOT EXISTS symbols (
42
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
43
+ file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
44
+ parent_symbol_id INTEGER REFERENCES symbols(id),
45
+ name TEXT NOT NULL,
46
+ kind TEXT NOT NULL,
47
+ start_line INTEGER,
48
+ end_line INTEGER,
49
+ modifiers TEXT,
50
+ FOREIGN KEY (file_id) REFERENCES files(id)
51
+ );
52
+
53
+ CREATE TABLE IF NOT EXISTS imports (
54
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
55
+ file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
56
+ source_path TEXT NOT NULL,
57
+ specifiers TEXT,
58
+ is_default INTEGER DEFAULT 0,
59
+ is_namespace INTEGER DEFAULT 0,
60
+ is_relative INTEGER DEFAULT 0,
61
+ -- Phase 32 A2.2: \`export \u2026 from\` \u2014 the file passes these names on
62
+ -- rather than using them, so an importer lookup follows it.
63
+ is_reexport INTEGER DEFAULT 0
64
+ );
65
+
66
+ CREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file_id);
67
+ CREATE INDEX IF NOT EXISTS idx_symbols_kind ON symbols(kind);
68
+ CREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);
69
+ CREATE INDEX IF NOT EXISTS idx_imports_file ON imports(file_id);
70
+
71
+ -- Callsites are non-import couplings. The columns are generic "what was
72
+ -- referenced" slots shared across protocols, not HTTP-specific ones:
73
+ -- HTTP: method = GET/POST\u2026, url_pattern = /api/orders
74
+ -- SQL: method = READ/WRITE, url_pattern = table name, sql_text = snippet
75
+ -- idx_callsites_url therefore serves both the route matcher and the
76
+ -- table matcher. See services/sql/index.ts.
77
+ CREATE TABLE IF NOT EXISTS callsites (
78
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
79
+ file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
80
+ kind TEXT NOT NULL,
81
+ protocol TEXT NOT NULL,
82
+ method TEXT,
83
+ url_pattern TEXT,
84
+ sql_text TEXT,
85
+ line INTEGER,
86
+ context TEXT,
87
+ -- Phase 33 R7: an outbound call's host, which url_pattern drops.
88
+ host TEXT
89
+ );
90
+ CREATE INDEX IF NOT EXISTS idx_callsites_file ON callsites(file_id);
91
+ CREATE INDEX IF NOT EXISTS idx_callsites_kind ON callsites(kind);
92
+ CREATE INDEX IF NOT EXISTS idx_callsites_url ON callsites(url_pattern);
93
+
94
+ CREATE TABLE IF NOT EXISTS cross_system_edges (
95
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
96
+ source_file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
97
+ target_file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
98
+ protocol TEXT NOT NULL,
99
+ label TEXT,
100
+ confidence REAL DEFAULT 1.0
101
+ );
102
+ CREATE INDEX IF NOT EXISTS idx_xs_edges_source ON cross_system_edges(source_file_id);
103
+ CREATE INDEX IF NOT EXISTS idx_xs_edges_target ON cross_system_edges(target_file_id);
104
+ CREATE INDEX IF NOT EXISTS idx_xs_edges_protocol ON cross_system_edges(protocol);
105
+ `;
106
+ const SCHEMA_PLANS_CORE = `
107
+ CREATE TABLE IF NOT EXISTS plans (
108
+ uid TEXT PRIMARY KEY,
109
+ title TEXT NOT NULL,
110
+ description TEXT DEFAULT '',
111
+ status TEXT NOT NULL DEFAULT 'draft',
112
+ author TEXT NOT NULL,
113
+ author_type TEXT NOT NULL DEFAULT 'human',
114
+ project_path TEXT NOT NULL,
115
+ created_at INTEGER NOT NULL,
116
+ updated_at INTEGER NOT NULL
117
+ );
118
+
119
+ CREATE TABLE IF NOT EXISTS plan_versions (
120
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
121
+ plan_uid TEXT NOT NULL REFERENCES plans(uid),
122
+ version INTEGER NOT NULL,
123
+ snapshot TEXT NOT NULL,
124
+ change_summary TEXT,
125
+ author TEXT NOT NULL,
126
+ -- How the edit arrived (carried 2b). Null on rows from before it was kept.
127
+ author_type TEXT,
128
+ created_at INTEGER NOT NULL,
129
+ UNIQUE(plan_uid, version)
130
+ );
131
+
132
+ CREATE TABLE IF NOT EXISTS tasks (
133
+ uid TEXT PRIMARY KEY,
134
+ plan_uid TEXT NOT NULL REFERENCES plans(uid),
135
+ sort_order INTEGER NOT NULL,
136
+ description TEXT NOT NULL,
137
+ status TEXT NOT NULL DEFAULT 'pending',
138
+ assignee TEXT,
139
+ assignee_type TEXT,
140
+ assignee_model TEXT,
141
+ affected_files TEXT DEFAULT '[]',
142
+ affected_symbols TEXT DEFAULT '[]',
143
+ new_connections TEXT DEFAULT '[]',
144
+ removed_connections TEXT DEFAULT '[]',
145
+ dependencies TEXT DEFAULT '[]',
146
+ file_spec TEXT,
147
+ symbol_specs TEXT DEFAULT '[]',
148
+ created_at INTEGER NOT NULL,
149
+ updated_at INTEGER NOT NULL
150
+ );
151
+
152
+ CREATE TABLE IF NOT EXISTS plan_phases (
153
+ uid TEXT PRIMARY KEY,
154
+ plan_uid TEXT NOT NULL REFERENCES plans(uid),
155
+ phase_number INTEGER NOT NULL,
156
+ title TEXT NOT NULL,
157
+ scope TEXT NOT NULL DEFAULT '',
158
+ prerequisites TEXT NOT NULL DEFAULT '',
159
+ git_checkpoint TEXT,
160
+ acceptance_criteria TEXT NOT NULL DEFAULT '',
161
+ status TEXT NOT NULL DEFAULT 'pending',
162
+ created_at INTEGER NOT NULL,
163
+ updated_at INTEGER NOT NULL
164
+ );
165
+
166
+ CREATE INDEX IF NOT EXISTS idx_plan_phases_plan ON plan_phases(plan_uid);
167
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_plan_phases_unique ON plan_phases(plan_uid, phase_number);
168
+
169
+ CREATE TABLE IF NOT EXISTS comments (
170
+ uid TEXT PRIMARY KEY,
171
+ target_type TEXT NOT NULL,
172
+ target_uid TEXT NOT NULL,
173
+ parent_uid TEXT,
174
+ author TEXT NOT NULL,
175
+ author_type TEXT NOT NULL DEFAULT 'human',
176
+ body TEXT NOT NULL,
177
+ comment_type TEXT NOT NULL DEFAULT 'comment',
178
+ created_at INTEGER NOT NULL
179
+ );
180
+
181
+ CREATE TABLE IF NOT EXISTS agent_sessions (
182
+ session_id TEXT PRIMARY KEY,
183
+ agent_type TEXT NOT NULL,
184
+ model TEXT,
185
+ active_plan_uid TEXT REFERENCES plans(uid),
186
+ connected_at INTEGER NOT NULL,
187
+ last_seen INTEGER NOT NULL,
188
+ status TEXT NOT NULL DEFAULT 'active',
189
+ -- The workstream it works in (Phase 32 A1.1): a trusted root or one of
190
+ -- its worktrees, as the user opened it. Re-derived on every connect.
191
+ workstream_root TEXT
192
+ );
193
+
194
+ -- Phase 32 B1: every agent event that was broadcast (tool calls, watcher
195
+ -- events, sessions starting and ending), kept so the Timeline survives a
196
+ -- reload and replay has a record. Stamped at the tap with the session, the
197
+ -- agent and the workstream it works in. Kept 14 days (agent-event-log.ts).
198
+ CREATE TABLE IF NOT EXISTS agent_events (
199
+ id TEXT PRIMARY KEY,
200
+ at INTEGER NOT NULL,
201
+ source TEXT NOT NULL,
202
+ type TEXT NOT NULL,
203
+ session_id TEXT,
204
+ agent_type TEXT,
205
+ workstream_root TEXT,
206
+ payload TEXT NOT NULL
207
+ );
208
+ CREATE INDEX IF NOT EXISTS idx_agent_events_at ON agent_events(at);
209
+ CREATE INDEX IF NOT EXISTS idx_agent_events_session ON agent_events(session_id, at);
210
+ CREATE INDEX IF NOT EXISTS idx_agent_events_workstream ON agent_events(workstream_root, at);
211
+
212
+ -- Phase 32 B10.1: the record. One link per agent event, each hashing the
213
+ -- one before it, so a change, a removal or a forged row is found by
214
+ -- walking it (record-chain.ts). The anchor is the last link retention
215
+ -- trimmed, so what is kept still verifies.
216
+ CREATE TABLE IF NOT EXISTS record_chain (
217
+ seq INTEGER PRIMARY KEY,
218
+ event_id TEXT NOT NULL UNIQUE,
219
+ linked_at INTEGER NOT NULL,
220
+ digest TEXT NOT NULL,
221
+ prev TEXT NOT NULL,
222
+ hash TEXT NOT NULL
223
+ );
224
+ CREATE INDEX IF NOT EXISTS idx_record_chain_linked ON record_chain(linked_at);
225
+ CREATE TABLE IF NOT EXISTS record_anchor (
226
+ id INTEGER PRIMARY KEY CHECK (id = 1),
227
+ through_seq INTEGER NOT NULL,
228
+ hash TEXT NOT NULL,
229
+ at INTEGER NOT NULL
230
+ );
231
+
232
+ -- Phase 32 C1.3: proof a skill was used on a task. Claude Code records each
233
+ -- skill it loads as a Skill tool call; the watcher stores one row per task
234
+ -- that a Claude Code session in the same workstream is working. Kept with
235
+ -- the task, not the 14-day event log: the sign-off pack cites it.
236
+ CREATE TABLE IF NOT EXISTS skill_uses (
237
+ item_uid TEXT NOT NULL,
238
+ skill TEXT NOT NULL,
239
+ session_id TEXT,
240
+ workstream_root TEXT,
241
+ at INTEGER NOT NULL,
242
+ -- Phase 32 A8.4: how it was seen. 'session_log' (Claude Code's own log,
243
+ -- read by the watcher) or 'mcp' (read through get_skill, any client).
244
+ source TEXT
245
+ );
246
+ CREATE INDEX IF NOT EXISTS idx_skill_uses_item ON skill_uses(item_uid, skill);
247
+
248
+ -- Phase 32 A6.2: which session read which material through read_material,
249
+ -- and the file's hash when it did. item_uid is the task the read counts
250
+ -- for: the session's brief task, or the material's own task when the
251
+ -- session has none. path is the attachment's value (project-relative for
252
+ -- a recorded file), so two tasks' attachments of one file name the same
253
+ -- material.
254
+ CREATE TABLE IF NOT EXISTS material_reads (
255
+ item_uid TEXT NOT NULL,
256
+ session_id TEXT,
257
+ attachment_uid TEXT NOT NULL,
258
+ path TEXT NOT NULL,
259
+ sha256 TEXT,
260
+ locator TEXT,
261
+ at INTEGER NOT NULL
262
+ );
263
+ CREATE INDEX IF NOT EXISTS idx_material_reads_item ON material_reads(item_uid, at);
264
+ CREATE INDEX IF NOT EXISTS idx_material_reads_path ON material_reads(path);
265
+
266
+ -- Phase 32 C2.2a: a review host turned on for a project, on this device.
267
+ -- Kept here and not in .codetrellis/config.json, which is committed: a
268
+ -- cloned repository must never be able to turn on a request to a host.
269
+ -- slug is the repository it was turned on for; if the remote later names
270
+ -- another, the switch no longer applies. No token is ever stored here
271
+ -- (secret-store.ts).
272
+ CREATE TABLE IF NOT EXISTS review_hosts (
273
+ project_root TEXT PRIMARY KEY,
274
+ hostname TEXT NOT NULL,
275
+ slug TEXT NOT NULL,
276
+ enabled INTEGER NOT NULL DEFAULT 0,
277
+ changed_at INTEGER NOT NULL,
278
+ changed_by TEXT NOT NULL
279
+ );
280
+
281
+ -- Phase 32 B8.1: test reports an agent or a test criterion handed over,
282
+ -- and each test's last result from them. CodeTrellis never runs tests:
283
+ -- these are what the runs said, with when they ran (the report's mtime).
284
+ CREATE TABLE IF NOT EXISTS test_reports (
285
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
286
+ project_root TEXT NOT NULL,
287
+ path TEXT NOT NULL,
288
+ sha256 TEXT NOT NULL,
289
+ tests INTEGER NOT NULL,
290
+ passed INTEGER NOT NULL,
291
+ failed INTEGER NOT NULL,
292
+ errors INTEGER NOT NULL,
293
+ skipped INTEGER NOT NULL,
294
+ ran_at INTEGER NOT NULL,
295
+ reported_at INTEGER NOT NULL,
296
+ reported_by TEXT NOT NULL,
297
+ reported_by_type TEXT NOT NULL,
298
+ UNIQUE (project_root, sha256)
299
+ );
300
+ CREATE TABLE IF NOT EXISTS test_results (
301
+ project_root TEXT NOT NULL,
302
+ test_key TEXT NOT NULL,
303
+ suite TEXT,
304
+ classname TEXT,
305
+ name TEXT NOT NULL,
306
+ file TEXT,
307
+ result TEXT NOT NULL,
308
+ duration_ms INTEGER,
309
+ message TEXT,
310
+ report_id INTEGER NOT NULL,
311
+ ran_at INTEGER NOT NULL,
312
+ PRIMARY KEY (project_root, test_key)
313
+ );
314
+ -- Phase 32 B8.4b: every report's own cases, so replay can say what the
315
+ -- tests said at a past moment (test_results keeps only the latest). Kept
316
+ -- as long as replay frames are.
317
+ CREATE TABLE IF NOT EXISTS test_report_cases (
318
+ report_id INTEGER NOT NULL,
319
+ test_key TEXT NOT NULL,
320
+ suite TEXT,
321
+ classname TEXT,
322
+ name TEXT NOT NULL,
323
+ file TEXT,
324
+ result TEXT NOT NULL,
325
+ duration_ms INTEGER,
326
+ message TEXT,
327
+ PRIMARY KEY (report_id, test_key)
328
+ );
329
+
330
+ -- Phase 32 B9.3a: what a person did about a planned overlap (re-sequenced
331
+ -- the plans, told the agents, or left it), by its id (the subject and the
332
+ -- plans it is between), with who from the transport and when.
333
+ CREATE TABLE IF NOT EXISTS planned_overlap_decisions (
334
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
335
+ overlap_id TEXT NOT NULL,
336
+ project_root TEXT NOT NULL,
337
+ action TEXT NOT NULL,
338
+ words TEXT NOT NULL,
339
+ by_name TEXT NOT NULL,
340
+ by_type TEXT NOT NULL,
341
+ at INTEGER NOT NULL
342
+ );
343
+ -- Phase 32 B9.3b: a plan approved into planned overlaps, said once in the
344
+ -- inbox until a person marks it seen.
345
+ CREATE TABLE IF NOT EXISTS planned_overlap_notices (
346
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
347
+ project_root TEXT NOT NULL,
348
+ plan_uid TEXT NOT NULL,
349
+ plan_label TEXT NOT NULL,
350
+ words_json TEXT NOT NULL,
351
+ at INTEGER NOT NULL,
352
+ seen_at INTEGER,
353
+ seen_by TEXT
354
+ );
355
+ -- Phase 32 C4.1: a recurring playbook's run, as started here: its series,
356
+ -- period, the run before it and the tasks carried from it. A run started on
357
+ -- another machine is found by its id (derived from rule and period), not here.
358
+ CREATE TABLE IF NOT EXISTS recurring_runs (
359
+ plan_uid TEXT PRIMARY KEY,
360
+ project_root TEXT NOT NULL,
361
+ rule_id TEXT NOT NULL,
362
+ period TEXT NOT NULL,
363
+ label TEXT NOT NULL,
364
+ previous_uid TEXT,
365
+ carried_json TEXT NOT NULL DEFAULT '[]',
366
+ started_at INTEGER NOT NULL,
367
+ started_by TEXT NOT NULL
368
+ );
369
+ -- Phase 32 C4.2a: a due run the person chose not to start this time, on
370
+ -- this device. It stays due until its period ends, then reads missed.
371
+ CREATE TABLE IF NOT EXISTS recurring_dismissed (
372
+ project_root TEXT NOT NULL,
373
+ rule_id TEXT NOT NULL,
374
+ period TEXT NOT NULL,
375
+ by_name TEXT NOT NULL,
376
+ at INTEGER NOT NULL,
377
+ PRIMARY KEY (project_root, rule_id, period)
378
+ );
379
+ -- Phase 32 C4.3b: on this device, start an agent on each run of a rule.
380
+ -- Off unless the person turned it on here; never in the committed config.
381
+ CREATE TABLE IF NOT EXISTS recurring_agents (
382
+ project_root TEXT NOT NULL,
383
+ rule_id TEXT NOT NULL,
384
+ agent TEXT NOT NULL,
385
+ by_name TEXT NOT NULL,
386
+ at INTEGER NOT NULL,
387
+ PRIMARY KEY (project_root, rule_id)
388
+ );
389
+ -- Each session told of a planned overlap its task is in, read once.
390
+ CREATE TABLE IF NOT EXISTS planned_overlap_tells (
391
+ overlap_id TEXT NOT NULL,
392
+ session_id TEXT NOT NULL,
393
+ text TEXT NOT NULL,
394
+ created_at INTEGER NOT NULL,
395
+ read_at INTEGER,
396
+ PRIMARY KEY (overlap_id, session_id)
397
+ );
398
+
399
+ -- Phase 32 C3.1: task state shared as records in the project's files, per
400
+ -- project, on this device only (never the committed config). Off until
401
+ -- the person turns it on.
402
+ CREATE TABLE IF NOT EXISTS shared_task_state (
403
+ project_root TEXT PRIMARY KEY,
404
+ enabled INTEGER NOT NULL DEFAULT 0,
405
+ changed_at INTEGER NOT NULL,
406
+ changed_by TEXT NOT NULL
407
+ );
408
+
409
+ -- Phase 32 C3.1: this device's writer id for task-state records (one row),
410
+ -- and, per item, the record whose state this machine last took or wrote:
411
+ -- reading the same records again changes nothing.
412
+ CREATE TABLE IF NOT EXISTS task_record_writer (
413
+ id INTEGER PRIMARY KEY CHECK (id = 1),
414
+ writer TEXT NOT NULL
415
+ );
416
+ CREATE TABLE IF NOT EXISTS task_record_heads (
417
+ item_uid TEXT PRIMARY KEY,
418
+ writer TEXT NOT NULL,
419
+ counter INTEGER NOT NULL,
420
+ split TEXT,
421
+ verdict TEXT
422
+ );
423
+
424
+ -- Phase 32 C3.3: this device's own signing key for its records (one row),
425
+ -- used when git signing has no SSH key; the private half stays here. And
426
+ -- teammates' device keys, as introduced in a project's .codetrellis/keys:
427
+ -- 'new' until the person trusts or refuses one, in Settings.
428
+ -- Phase 32 C3.4a: this device's copy of a project's plans folder, as the
429
+ -- person confirmed it. The committed config only names the folder; a
430
+ -- cloned repository never points the app at one by itself.
431
+ CREATE TABLE IF NOT EXISTS linked_plans_folder (
432
+ project_root TEXT PRIMARY KEY,
433
+ local_path TEXT NOT NULL,
434
+ ref TEXT NOT NULL,
435
+ confirmed_at INTEGER NOT NULL,
436
+ confirmed_by TEXT NOT NULL
437
+ );
438
+
439
+ -- Phase 32 C3.5: teammates' material reads. The switch, per project on this
440
+ -- device: no row means on whenever task state is shared (the owner's
441
+ -- choice); a row says the person turned it off, or back on. And each
442
+ -- teammate's read record read here, with whether it verified (C3.3); none
443
+ -- of this device's own, which material_reads already has.
444
+ CREATE TABLE IF NOT EXISTS shared_material_reads (
445
+ project_root TEXT PRIMARY KEY,
446
+ enabled INTEGER NOT NULL,
447
+ changed_at INTEGER NOT NULL,
448
+ changed_by TEXT NOT NULL
449
+ );
450
+ CREATE TABLE IF NOT EXISTS teammate_material_reads (
451
+ writer TEXT NOT NULL,
452
+ item_uid TEXT NOT NULL,
453
+ counter INTEGER NOT NULL,
454
+ plan_uid TEXT NOT NULL,
455
+ name TEXT NOT NULL,
456
+ reader TEXT NOT NULL,
457
+ attachment_uid TEXT,
458
+ path TEXT NOT NULL,
459
+ sha256 TEXT,
460
+ at INTEGER NOT NULL,
461
+ verdict TEXT,
462
+ PRIMARY KEY (writer, item_uid, counter)
463
+ );
464
+ CREATE INDEX IF NOT EXISTS idx_teammate_material_reads_item ON teammate_material_reads(item_uid, at);
465
+
466
+ -- Phase 32 D1.5a: each teammate device's latest test run in a project, read
467
+ -- from its run record in the plans folder (.codetrellis/runs/). One row per
468
+ -- device: a newer run replaces it. Forgotten when sharing is turned off.
469
+ CREATE TABLE IF NOT EXISTS teammate_test_runs (
470
+ project_root TEXT NOT NULL,
471
+ writer TEXT NOT NULL,
472
+ counter INTEGER NOT NULL,
473
+ name TEXT NOT NULL,
474
+ by_author TEXT NOT NULL,
475
+ by_type TEXT NOT NULL,
476
+ commit_sha TEXT,
477
+ dirty TEXT NOT NULL,
478
+ at INTEGER NOT NULL,
479
+ report TEXT NOT NULL,
480
+ totals TEXT NOT NULL,
481
+ files TEXT NOT NULL,
482
+ verdict TEXT,
483
+ PRIMARY KEY (project_root, writer)
484
+ );
485
+
486
+ -- Phase 33 C7: every rule check is a run (not Phase 31's criterion check_runs). This device's runs (mine = 1) and
487
+ -- teammates' latest, read from their check-run records in the plans folder
488
+ -- (.codetrellis/runs/checks/). Teammates' are forgotten when sharing is off.
489
+ CREATE TABLE IF NOT EXISTS rule_check_runs (
490
+ project_root TEXT NOT NULL,
491
+ id TEXT NOT NULL,
492
+ mine INTEGER NOT NULL,
493
+ writer TEXT NOT NULL,
494
+ counter INTEGER NOT NULL,
495
+ name TEXT NOT NULL,
496
+ by_author TEXT NOT NULL,
497
+ by_type TEXT NOT NULL,
498
+ ran_in TEXT NOT NULL,
499
+ commit_sha TEXT,
500
+ dirty TEXT NOT NULL,
501
+ base TEXT,
502
+ rulebook TEXT,
503
+ scope TEXT,
504
+ strict INTEGER NOT NULL,
505
+ outcome TEXT NOT NULL,
506
+ says TEXT NOT NULL,
507
+ findings TEXT NOT NULL,
508
+ at INTEGER NOT NULL,
509
+ verdict TEXT,
510
+ -- Phase 33 C4b: an agent's review, when the run is one.
511
+ review TEXT,
512
+ PRIMARY KEY (project_root, id)
513
+ );
514
+ CREATE INDEX IF NOT EXISTS idx_rule_check_runs_at ON rule_check_runs(project_root, at);
515
+
516
+ CREATE TABLE IF NOT EXISTS task_record_device_key (
517
+ id INTEGER PRIMARY KEY CHECK (id = 1),
518
+ public_key TEXT NOT NULL,
519
+ private_key TEXT NOT NULL,
520
+ fingerprint TEXT NOT NULL,
521
+ created_at INTEGER NOT NULL
522
+ );
523
+ CREATE TABLE IF NOT EXISTS task_record_keys (
524
+ writer TEXT NOT NULL,
525
+ fingerprint TEXT NOT NULL,
526
+ public_key TEXT NOT NULL,
527
+ name TEXT NOT NULL,
528
+ project_root TEXT NOT NULL,
529
+ state TEXT NOT NULL DEFAULT 'new',
530
+ first_seen INTEGER NOT NULL,
531
+ decided_at INTEGER,
532
+ decided_by TEXT,
533
+ PRIMARY KEY (writer, fingerprint)
534
+ );
535
+
536
+ -- Phase 32 C2.6a: a plan that first reached this machine through its files
537
+ -- (a pull, a copy, an import), with who added it and in which commit, as
538
+ -- git says; nulls when it was not committed yet. A plan made here has none.
539
+ CREATE TABLE IF NOT EXISTS plan_arrivals (
540
+ plan_uid TEXT PRIMARY KEY,
541
+ added_by TEXT,
542
+ commit_sha TEXT,
543
+ arrived_at INTEGER NOT NULL
544
+ );
545
+
546
+ -- Phase 32 C2.5b: approvals as signed statements. One row per approval
547
+ -- this machine signed (or could not), and per signed record read from a
548
+ -- plan's approvals/ folder, with whether it verified and why not. A
549
+ -- verified record also adds the person's sign-off to criterion_signoffs.
550
+ CREATE TABLE IF NOT EXISTS signed_approvals (
551
+ uid TEXT PRIMARY KEY,
552
+ plan_uid TEXT NOT NULL,
553
+ item_uid TEXT NOT NULL,
554
+ criterion_uid TEXT NOT NULL,
555
+ signer TEXT,
556
+ origin TEXT NOT NULL,
557
+ state TEXT NOT NULL,
558
+ reason TEXT,
559
+ file TEXT,
560
+ at INTEGER NOT NULL
561
+ );
562
+ CREATE INDEX IF NOT EXISTS idx_signed_approvals_item ON signed_approvals(item_uid);
563
+
564
+ -- Phase 32 C1.4: a skill that arrived in a plan file (pulled through git,
565
+ -- or edited by hand) is held back from agents until a person accepts it.
566
+ -- One row per arrival: who added it and in which commit, as git says.
567
+ CREATE TABLE IF NOT EXISTS skill_arrivals (
568
+ item_uid TEXT NOT NULL,
569
+ skill TEXT NOT NULL,
570
+ added_by TEXT,
571
+ commit_sha TEXT,
572
+ arrived_at INTEGER NOT NULL,
573
+ accepted_at INTEGER,
574
+ accepted_by TEXT,
575
+ accepted_by_type TEXT
576
+ );
577
+ CREATE INDEX IF NOT EXISTS idx_skill_arrivals_item ON skill_arrivals(item_uid, skill);
578
+
579
+ -- Phase 32 B4: a place a person has said "stop and ask me". A task
580
+ -- breakpoint fires when an agent claims or finishes the task (or anything
581
+ -- under it); a spec breakpoint when an agent changes its description; a
582
+ -- code breakpoint (B4.2) when a workstream changes a file under it, its
583
+ -- target a repository-relative path (a folder ends in /, a function is
584
+ -- path#name) in project_root; a signal breakpoint (B4.2b) is a project
585
+ -- rule whose target is a signal kind. Kept after it is cleared, because
586
+ -- the hits it caused cite it.
587
+ CREATE TABLE IF NOT EXISTS breakpoints (
588
+ id TEXT PRIMARY KEY,
589
+ kind TEXT NOT NULL,
590
+ target TEXT NOT NULL,
591
+ plan_uid TEXT,
592
+ project_root TEXT,
593
+ note TEXT,
594
+ created_at INTEGER NOT NULL,
595
+ created_by TEXT NOT NULL,
596
+ created_by_type TEXT NOT NULL,
597
+ cleared_at INTEGER,
598
+ cleared_by TEXT,
599
+ cleared_by_type TEXT
600
+ );
601
+ CREATE INDEX IF NOT EXISTS idx_breakpoints_target ON breakpoints(target);
602
+
603
+ -- Phase 32 B4: one agent call held at a breakpoint, and the person's
604
+ -- answer. The agent waits on it by ref (await_decision), from the database,
605
+ -- so the wait survives timeouts and restarts. \`consumed_at\` is set when
606
+ -- the agent's next matching call spends the answer. A code hit (B4.2) names
607
+ -- the file in \`path\` (item_uid is empty); \`breach\` is 1 when the change was
608
+ -- only seen after it was made, never paused. A signal hit (B4.2b) names
609
+ -- the signal that held the call in \`signal_id\`.
610
+ CREATE TABLE IF NOT EXISTS breakpoint_hits (
611
+ ref TEXT PRIMARY KEY,
612
+ breakpoint_id TEXT NOT NULL,
613
+ tool TEXT NOT NULL,
614
+ action TEXT NOT NULL,
615
+ item_uid TEXT NOT NULL,
616
+ path TEXT,
617
+ breach INTEGER NOT NULL DEFAULT 0,
618
+ signal_id TEXT,
619
+ plan_uid TEXT,
620
+ agent TEXT,
621
+ session_id TEXT,
622
+ workstream_root TEXT,
623
+ hit_at INTEGER NOT NULL,
624
+ decision TEXT,
625
+ note TEXT,
626
+ answered_at INTEGER,
627
+ answered_by TEXT,
628
+ answered_by_type TEXT,
629
+ consumed_at INTEGER
630
+ );
631
+ CREATE INDEX IF NOT EXISTS idx_breakpoint_hits_waiting ON breakpoint_hits(answered_at, hit_at);
632
+
633
+ -- Phase 32 A1.6: one thing worth knowing about parallel work. Deduplicated
634
+ -- by id (kind, subject, workstreams); resolved when its cause goes away.
635
+ CREATE TABLE IF NOT EXISTS awareness_signals (
636
+ id TEXT PRIMARY KEY,
637
+ project_root TEXT NOT NULL,
638
+ kind TEXT NOT NULL,
639
+ severity TEXT NOT NULL,
640
+ subject TEXT NOT NULL,
641
+ workstreams TEXT NOT NULL,
642
+ summary TEXT NOT NULL,
643
+ first_seen INTEGER NOT NULL,
644
+ last_seen INTEGER NOT NULL,
645
+ state TEXT NOT NULL DEFAULT 'open',
646
+ resolved_at INTEGER,
647
+ -- A1.8: who set the state (JSON, from actorFrom) and when.
648
+ state_by TEXT,
649
+ state_at INTEGER,
650
+ -- A3.2: what it is about, fingerprinted; an answer holds while it does.
651
+ shape TEXT,
652
+ -- A3.2: it was acknowledged or intended, and opened again when its shape changed.
653
+ reopened_from TEXT,
654
+ reopened_at INTEGER
655
+ );
656
+ CREATE INDEX IF NOT EXISTS idx_awareness_project ON awareness_signals(project_root);
657
+
658
+ -- Phase 32 A2.6: which agent session was told about a signal (once), and
659
+ -- the note it left with acknowledge_signal. The agent's own words: shown
660
+ -- to the person, never to another agent.
661
+ CREATE TABLE IF NOT EXISTS awareness_signal_notes (
662
+ signal_id TEXT NOT NULL,
663
+ session_id TEXT NOT NULL,
664
+ agent_type TEXT NOT NULL,
665
+ told_at INTEGER,
666
+ note TEXT,
667
+ noted_at INTEGER,
668
+ PRIMARY KEY (signal_id, session_id)
669
+ );
670
+
671
+ -- Phase 32 B5.2: each time a signal was open, for replay. A signal keeps
672
+ -- one row in awareness_signals and is reopened in place, so its earlier
673
+ -- openings would be lost; here each opening is a row, closed when it
674
+ -- resolves. Kept 14 days after it closes, like the agent event log.
675
+ CREATE TABLE IF NOT EXISTS awareness_signal_spans (
676
+ signal_id TEXT NOT NULL,
677
+ project_root TEXT NOT NULL,
678
+ kind TEXT NOT NULL,
679
+ severity TEXT NOT NULL,
680
+ summary TEXT NOT NULL,
681
+ workstreams TEXT NOT NULL,
682
+ opened_at INTEGER NOT NULL,
683
+ closed_at INTEGER,
684
+ PRIMARY KEY (signal_id, opened_at)
685
+ );
686
+ CREATE INDEX IF NOT EXISTS idx_signal_spans_project ON awareness_signal_spans(project_root, opened_at);
687
+
688
+ -- Phase 32 A4.1: a person's message to the agents about a signal, and
689
+ -- which agent sessions have read it (once each, on their next tool call).
690
+ CREATE TABLE IF NOT EXISTS awareness_signal_replies (
691
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
692
+ signal_id TEXT NOT NULL,
693
+ project_root TEXT NOT NULL,
694
+ message TEXT NOT NULL,
695
+ actor TEXT NOT NULL,
696
+ actor_type TEXT NOT NULL,
697
+ channel TEXT NOT NULL,
698
+ created_at INTEGER NOT NULL
699
+ );
700
+ CREATE INDEX IF NOT EXISTS idx_signal_replies_signal ON awareness_signal_replies(signal_id, created_at);
701
+ CREATE TABLE IF NOT EXISTS awareness_signal_reply_reads (
702
+ reply_id INTEGER NOT NULL,
703
+ session_id TEXT NOT NULL,
704
+ agent_type TEXT NOT NULL,
705
+ read_at INTEGER NOT NULL,
706
+ PRIMARY KEY (reply_id, session_id)
707
+ );
708
+
709
+ -- Phase 32 B7.1: what a task relies on, a spec page or one section of it
710
+ -- (a heading, by slug; '' for the whole page). Who relies on a page is
711
+ -- read back across every plan of its project.
712
+ CREATE TABLE IF NOT EXISTS spec_links (
713
+ item_uid TEXT NOT NULL,
714
+ page_uid TEXT NOT NULL,
715
+ section TEXT NOT NULL DEFAULT '',
716
+ author TEXT NOT NULL,
717
+ author_type TEXT NOT NULL,
718
+ created_at INTEGER NOT NULL,
719
+ PRIMARY KEY (item_uid, page_uid, section)
720
+ );
721
+ CREATE INDEX IF NOT EXISTS idx_spec_links_page ON spec_links(page_uid);
722
+
723
+ -- Phase 32 B7.2: a proposed change to a spec page, made against a version
724
+ -- of it, with why and the evidence. The page is not touched until a person
725
+ -- accepts (B7.4). \`affected\` is who relied on it when it was made.
726
+ CREATE TABLE IF NOT EXISTS spec_proposals (
727
+ uid TEXT PRIMARY KEY,
728
+ page_uid TEXT NOT NULL,
729
+ plan_uid TEXT NOT NULL,
730
+ section TEXT NOT NULL DEFAULT '',
731
+ base_version INTEGER NOT NULL,
732
+ before_text TEXT NOT NULL,
733
+ proposed_text TEXT NOT NULL,
734
+ why TEXT NOT NULL,
735
+ evidence TEXT NOT NULL DEFAULT '{}',
736
+ affected TEXT NOT NULL DEFAULT '[]',
737
+ author TEXT NOT NULL,
738
+ author_type TEXT NOT NULL,
739
+ session_id TEXT,
740
+ status TEXT NOT NULL DEFAULT 'open',
741
+ created_at INTEGER NOT NULL,
742
+ decided_at INTEGER,
743
+ decided_by TEXT,
744
+ decided_by_type TEXT,
745
+ decision_note TEXT,
746
+ hit_ref TEXT,
747
+ decided_text TEXT
748
+ );
749
+ CREATE INDEX IF NOT EXISTS idx_spec_proposals_page ON spec_proposals(page_uid, status);
750
+
751
+ -- Phase 33 R3: an agent proposes a change to an architecture rule; a
752
+ -- person sees what it would do against the code and decides. The rule is
753
+ -- the body an agent proposed, by field; null for stopping the rule.
754
+ CREATE TABLE IF NOT EXISTS rule_proposals (
755
+ uid TEXT PRIMARY KEY,
756
+ project_root TEXT NOT NULL,
757
+ rule_id TEXT NOT NULL,
758
+ body TEXT,
759
+ why TEXT NOT NULL,
760
+ effect TEXT,
761
+ words TEXT NOT NULL,
762
+ author TEXT NOT NULL,
763
+ author_type TEXT NOT NULL,
764
+ session_id TEXT,
765
+ status TEXT NOT NULL DEFAULT 'open',
766
+ created_at INTEGER NOT NULL,
767
+ decided_at INTEGER,
768
+ decided_by TEXT,
769
+ decided_by_type TEXT,
770
+ decision_note TEXT
771
+ );
772
+ CREATE INDEX IF NOT EXISTS idx_rule_proposals_project ON rule_proposals(project_root, status);
773
+
774
+ -- Phase 33 V3: the commit each reviewer last looked at, per line of work,
775
+ -- with what the review said then, so a later look shows only what moved
776
+ -- and which findings the pushes since addressed.
777
+ CREATE TABLE IF NOT EXISTS review_marks (
778
+ project_root TEXT NOT NULL,
779
+ target TEXT NOT NULL,
780
+ reviewer TEXT NOT NULL,
781
+ reviewer_type TEXT NOT NULL,
782
+ base TEXT NOT NULL,
783
+ head_commit TEXT NOT NULL,
784
+ findings TEXT NOT NULL DEFAULT '[]',
785
+ at INTEGER NOT NULL,
786
+ PRIMARY KEY (project_root, target, reviewer)
787
+ );
788
+
789
+ -- Phase 32 B7.3: each session holding an affected task is told of an open
790
+ -- proposal once; this is who has been.
791
+ CREATE TABLE IF NOT EXISTS spec_proposal_reads (
792
+ proposal_uid TEXT NOT NULL,
793
+ session_id TEXT NOT NULL,
794
+ agent_type TEXT,
795
+ read_at INTEGER NOT NULL,
796
+ PRIMARY KEY (proposal_uid, session_id)
797
+ );
798
+
799
+ -- Phase 32 B7.3: what a proposal would mean for the work relying on it,
800
+ -- from the agent doing that work: none, or changes with a sentence.
801
+ CREATE TABLE IF NOT EXISTS spec_proposal_impacts (
802
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
803
+ proposal_uid TEXT NOT NULL,
804
+ impact TEXT NOT NULL,
805
+ words TEXT NOT NULL DEFAULT '',
806
+ tasks INTEGER,
807
+ item_uid TEXT,
808
+ plan_uid TEXT,
809
+ author TEXT NOT NULL,
810
+ author_type TEXT NOT NULL,
811
+ session_id TEXT,
812
+ created_at INTEGER NOT NULL
813
+ );
814
+ CREATE INDEX IF NOT EXISTS idx_spec_proposal_impacts ON spec_proposal_impacts(proposal_uid);
815
+
816
+ -- Phase 32 B7.4: a task whose spec changed under it, by an accepted
817
+ -- proposal. Flagged until the agent holding it has been told (read_at).
818
+ CREATE TABLE IF NOT EXISTS spec_change_flags (
819
+ item_uid TEXT NOT NULL,
820
+ proposal_uid TEXT NOT NULL,
821
+ created_at INTEGER NOT NULL,
822
+ read_at INTEGER,
823
+ read_by_session TEXT,
824
+ PRIMARY KEY (item_uid, proposal_uid)
825
+ );
826
+
827
+ -- Phase 32 B7.4: the proposing session told of the decision, once.
828
+ CREATE TABLE IF NOT EXISTS spec_proposal_outcome_reads (
829
+ proposal_uid TEXT NOT NULL,
830
+ session_id TEXT NOT NULL,
831
+ read_at INTEGER NOT NULL,
832
+ PRIMARY KEY (proposal_uid, session_id)
833
+ );
834
+
835
+ -- Phase 32 A1.7c: folders an agent reported that the person said "not now"
836
+ -- to. Asked once per folder, not once per connection.
837
+ CREATE TABLE IF NOT EXISTS folder_request_dismissals (
838
+ folder TEXT PRIMARY KEY,
839
+ dismissed_at INTEGER NOT NULL
840
+ );
841
+
842
+ CREATE TABLE IF NOT EXISTS deviations (
843
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
844
+ plan_uid TEXT NOT NULL REFERENCES plans(uid),
845
+ deviation_type TEXT NOT NULL,
846
+ severity TEXT NOT NULL DEFAULT 'warning',
847
+ description TEXT NOT NULL,
848
+ resolution TEXT NOT NULL DEFAULT 'pending',
849
+ detected_at INTEGER NOT NULL,
850
+ resolved_at INTEGER,
851
+ file_path TEXT,
852
+ -- Who resolved it, tagged as everything else is (Phase 32 \xA70.4h).
853
+ resolved_by TEXT,
854
+ resolved_by_type TEXT
855
+ );
856
+
857
+ CREATE INDEX IF NOT EXISTS idx_tasks_plan ON tasks(plan_uid);
858
+ CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
859
+ CREATE INDEX IF NOT EXISTS idx_comments_target ON comments(target_uid);
860
+ CREATE INDEX IF NOT EXISTS idx_plan_versions_plan ON plan_versions(plan_uid);
861
+ CREATE INDEX IF NOT EXISTS idx_sessions_plan ON agent_sessions(active_plan_uid);
862
+ CREATE INDEX IF NOT EXISTS idx_deviations_plan ON deviations(plan_uid);
863
+
864
+ CREATE TABLE IF NOT EXISTS trellis_snapshots (
865
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
866
+ name TEXT NOT NULL,
867
+ snapshot_type TEXT NOT NULL,
868
+ plan_uid TEXT REFERENCES plans(uid),
869
+ git_branch TEXT,
870
+ files_json TEXT NOT NULL,
871
+ edges_json TEXT NOT NULL,
872
+ created_at INTEGER NOT NULL,
873
+ -- Phase 32 B5.1: a replay frame (snapshot_type 'frame') says whose graph
874
+ -- it is, what caused it and at which commit. A frame whose graph matches
875
+ -- the one before points at it (same_as) and stores no copy. Indexed by
876
+ -- replay-frames.ts once these columns exist on an older database.
877
+ project_path TEXT,
878
+ reason TEXT,
879
+ ref TEXT,
880
+ session_id TEXT,
881
+ agent_type TEXT,
882
+ workstream_root TEXT,
883
+ commit_sha TEXT,
884
+ digest TEXT,
885
+ same_as INTEGER
886
+ );
887
+
888
+ CREATE INDEX IF NOT EXISTS idx_trellis_plan ON trellis_snapshots(plan_uid);
889
+ CREATE INDEX IF NOT EXISTS idx_trellis_type ON trellis_snapshots(snapshot_type);
890
+
891
+ CREATE TABLE IF NOT EXISTS plan_documents (
892
+ uid TEXT PRIMARY KEY,
893
+ plan_uid TEXT NOT NULL REFERENCES plans(uid),
894
+ doc_type TEXT NOT NULL,
895
+ title TEXT NOT NULL,
896
+ body TEXT NOT NULL DEFAULT '',
897
+ version INTEGER NOT NULL DEFAULT 1,
898
+ author TEXT NOT NULL,
899
+ author_type TEXT NOT NULL DEFAULT 'human',
900
+ order_hint TEXT,
901
+ parent_doc_uid TEXT,
902
+ created_at INTEGER NOT NULL,
903
+ updated_at INTEGER NOT NULL
904
+ );
905
+
906
+ CREATE INDEX IF NOT EXISTS idx_plan_docs_plan ON plan_documents(plan_uid);
907
+ CREATE INDEX IF NOT EXISTS idx_plan_docs_type ON plan_documents(doc_type);
908
+
909
+ CREATE TABLE IF NOT EXISTS plan_document_versions (
910
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
911
+ doc_uid TEXT NOT NULL REFERENCES plan_documents(uid),
912
+ version INTEGER NOT NULL,
913
+ body TEXT NOT NULL,
914
+ change_summary TEXT,
915
+ author TEXT NOT NULL,
916
+ -- How the edit arrived (carried 2b). Null on rows from before it was kept.
917
+ author_type TEXT,
918
+ created_at INTEGER NOT NULL,
919
+ UNIQUE(doc_uid, version)
920
+ );
921
+
922
+ CREATE INDEX IF NOT EXISTS idx_plan_doc_versions ON plan_document_versions(doc_uid);
923
+
924
+ -- A guarded plan document's file changed on disk (Phase 32 B7.5b): the
925
+ -- file's version, kept beside the breakpoint hit until a person decides.
926
+ -- The app's own version stays in plan_documents meanwhile.
927
+ CREATE TABLE IF NOT EXISTS plan_doc_disk_holds (
928
+ ref TEXT PRIMARY KEY,
929
+ doc_uid TEXT NOT NULL,
930
+ title TEXT NOT NULL,
931
+ body TEXT NOT NULL,
932
+ created_at INTEGER NOT NULL,
933
+ updated_at INTEGER NOT NULL
934
+ );
935
+
936
+ CREATE INDEX IF NOT EXISTS idx_plan_doc_disk_holds_doc ON plan_doc_disk_holds(doc_uid);
937
+
938
+ CREATE TABLE IF NOT EXISTS recent_projects (
939
+ path TEXT PRIMARY KEY,
940
+ display_name TEXT NOT NULL,
941
+ branch TEXT,
942
+ pinned INTEGER NOT NULL DEFAULT 0,
943
+ last_opened_at INTEGER NOT NULL,
944
+ first_opened_at INTEGER NOT NULL
945
+ );
946
+
947
+ CREATE INDEX IF NOT EXISTS idx_recent_projects_opened ON recent_projects(last_opened_at DESC);
948
+
949
+ -- Projects pushed off recent_projects by the unpinned cap. Read ONLY to
950
+ -- explain a refusal ("this was opened, then dropped off"); it is never a
951
+ -- source of trust. Cleared when the project is opened again.
952
+ CREATE TABLE IF NOT EXISTS evicted_projects (
953
+ path TEXT PRIMARY KEY,
954
+ evicted_at INTEGER NOT NULL
955
+ );
956
+ `;
957
+ const SCHEMA_ATTACHMENTS = `
958
+ CREATE TABLE IF NOT EXISTS attachments (
959
+ uid TEXT PRIMARY KEY,
960
+ target_type TEXT NOT NULL,
961
+ target_uid TEXT NOT NULL,
962
+ kind TEXT NOT NULL,
963
+ value TEXT NOT NULL,
964
+ label TEXT,
965
+ content_type TEXT,
966
+ author TEXT NOT NULL,
967
+ author_type TEXT NOT NULL DEFAULT 'human',
968
+ created_at INTEGER NOT NULL,
969
+ -- Phase 31 \xA74.2 \u2014 an artefact is an attachment with a role and a hash.
970
+ -- role: 'material' (input) \xB7 'output' (produced by the work) \xB7
971
+ -- 'evidence' (captured to prove something) \xB7 NULL for everything else.
972
+ -- sha256/size/mtime are taken when recorded and re-taken whenever the
973
+ -- file's size or mtime moves, so a decision can notice the file changed.
974
+ role TEXT,
975
+ sha256 TEXT,
976
+ size INTEGER,
977
+ mtime INTEGER,
978
+ recorded_by TEXT,
979
+ recorded_by_type TEXT
980
+ );
981
+ CREATE INDEX IF NOT EXISTS idx_attachments_target ON attachments(target_uid);
982
+ CREATE INDEX IF NOT EXISTS idx_attachments_target_type ON attachments(target_type, target_uid);
983
+ `;
984
+ const SCHEMA_PLAN_ITEMS = `
985
+ CREATE TABLE IF NOT EXISTS plan_items (
986
+ uid TEXT PRIMARY KEY,
987
+ plan_uid TEXT NOT NULL REFERENCES plans(uid),
988
+ parent_uid TEXT REFERENCES plan_items(uid),
989
+ sort_order INTEGER NOT NULL DEFAULT 0,
990
+ kind TEXT NOT NULL,
991
+ title TEXT NOT NULL,
992
+ body TEXT NOT NULL DEFAULT '',
993
+ template TEXT,
994
+ status TEXT,
995
+ assignee TEXT,
996
+ assignee_type TEXT,
997
+ assignee_model TEXT,
998
+ -- The MCP session that claimed it (Phase 32 bug 1): two agents of one
999
+ -- type are two claimants. Runtime only, never written to plan files.
1000
+ assignee_session TEXT,
1001
+ -- Phase 32 C5.1 \u2014 the branch this section is worked on, inherited by
1002
+ -- everything under it. A branch, not a folder: plan files are shared
1003
+ -- across checkouts and machines, and a folder means nothing on another.
1004
+ workstream TEXT,
1005
+ progress_percent INTEGER,
1006
+ blocked_reason TEXT,
1007
+ scope_path TEXT,
1008
+ file_specs TEXT NOT NULL DEFAULT '[]',
1009
+ symbol_specs TEXT NOT NULL DEFAULT '[]',
1010
+ new_connections TEXT NOT NULL DEFAULT '[]',
1011
+ removed_conns TEXT NOT NULL DEFAULT '[]',
1012
+ dependencies TEXT NOT NULL DEFAULT '[]',
1013
+ skills TEXT NOT NULL DEFAULT '[]',
1014
+ skills_mode TEXT DEFAULT 'inherit',
1015
+ claim_policy TEXT DEFAULT NULL,
1016
+ claim_policy_mode TEXT DEFAULT 'inherit',
1017
+ execution_config TEXT DEFAULT NULL,
1018
+ execution_config_mode TEXT DEFAULT 'inherit',
1019
+ constraints TEXT DEFAULT NULL,
1020
+ constraints_mode TEXT DEFAULT 'inherit',
1021
+ requires_approval INTEGER NOT NULL DEFAULT 0,
1022
+ author TEXT NOT NULL,
1023
+ author_type TEXT NOT NULL DEFAULT 'human',
1024
+ created_at INTEGER NOT NULL,
1025
+ updated_at INTEGER NOT NULL,
1026
+ migrated_from TEXT,
1027
+ estimate_minutes INTEGER,
1028
+ estimate_cost_usd REAL
1029
+ );
1030
+ CREATE INDEX IF NOT EXISTS idx_plan_items_plan ON plan_items(plan_uid);
1031
+ CREATE INDEX IF NOT EXISTS idx_plan_items_parent ON plan_items(parent_uid);
1032
+ CREATE INDEX IF NOT EXISTS idx_plan_items_kind ON plan_items(kind);
1033
+ CREATE INDEX IF NOT EXISTS idx_plan_items_status ON plan_items(status);
1034
+ CREATE INDEX IF NOT EXISTS idx_plan_items_sort ON plan_items(plan_uid, parent_uid, sort_order);
1035
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_plan_items_migrated ON plan_items(migrated_from);
1036
+
1037
+ -- Phase 31 \xA74.1 \u2014 acceptance criteria as rows. A line of prose has no
1038
+ -- state, no owner and no evidence; a row has all three. text is
1039
+ -- VERBATIM \u2014 the requester's wording is what they will check against.
1040
+ -- state is derived (see criteria-service) and never stored.
1041
+ CREATE TABLE IF NOT EXISTS item_criteria (
1042
+ uid TEXT PRIMARY KEY,
1043
+ item_uid TEXT NOT NULL,
1044
+ sort_order INTEGER NOT NULL DEFAULT 0,
1045
+ text TEXT NOT NULL,
1046
+ kind TEXT NOT NULL DEFAULT 'manual',
1047
+ policy TEXT NOT NULL DEFAULT 'propose',
1048
+ source TEXT,
1049
+ author TEXT NOT NULL,
1050
+ author_type TEXT NOT NULL,
1051
+ origin_uid TEXT,
1052
+ created_at INTEGER NOT NULL,
1053
+ updated_at INTEGER NOT NULL,
1054
+ -- When the wording last changed. Submissions and decisions older than
1055
+ -- this were about different words, so they no longer count.
1056
+ text_updated_at INTEGER
1057
+ );
1058
+ CREATE INDEX IF NOT EXISTS idx_item_criteria_item ON item_criteria(item_uid, sort_order);
1059
+
1060
+ -- One row per submission. attachment_uid is nullable: a submission can
1061
+ -- be a note alone ("done \u2014 see the body"), and that is still a claim
1062
+ -- someone has to judge.
1063
+ CREATE TABLE IF NOT EXISTS criterion_evidence (
1064
+ uid TEXT PRIMARY KEY,
1065
+ criterion_uid TEXT NOT NULL,
1066
+ submission_uid TEXT NOT NULL,
1067
+ attachment_uid TEXT,
1068
+ locator TEXT,
1069
+ note TEXT,
1070
+ sha256_at_submit TEXT,
1071
+ submitted_by TEXT NOT NULL,
1072
+ submitted_by_type TEXT NOT NULL,
1073
+ submitted_at INTEGER NOT NULL
1074
+ );
1075
+ CREATE INDEX IF NOT EXISTS idx_criterion_evidence_criterion ON criterion_evidence(criterion_uid, submitted_at);
1076
+
1077
+ -- Append-only. A decision is a record, never a flag that approving
1078
+ -- destroys. evidence_hashes is filled from 31.2 on, when artefacts
1079
+ -- carry a hash; until then it is '{}'.
1080
+ CREATE TABLE IF NOT EXISTS criterion_signoffs (
1081
+ uid TEXT PRIMARY KEY,
1082
+ criterion_uid TEXT NOT NULL,
1083
+ decision TEXT NOT NULL,
1084
+ actor TEXT NOT NULL,
1085
+ actor_type TEXT NOT NULL,
1086
+ channel TEXT NOT NULL,
1087
+ note TEXT,
1088
+ evidence_hashes TEXT NOT NULL DEFAULT '{}',
1089
+ created_at INTEGER NOT NULL,
1090
+ -- Phase 31 \xA78.2: a send-back taken from the exact place \u2014 the file and
1091
+ -- the locator (cell, lines, page) the note is about.
1092
+ anchor_attachment_uid TEXT,
1093
+ anchor_locator TEXT,
1094
+ -- Phase 31 \xA713: which device a person decided on \u2014 a paired phone's
1095
+ -- alias. NULL for the desktop and for anything decided before this.
1096
+ device TEXT
1097
+ );
1098
+ CREATE INDEX IF NOT EXISTS idx_criterion_signoffs_criterion ON criterion_signoffs(criterion_uid, created_at);
1099
+
1100
+ -- Items whose '## Acceptance criteria' body section has been read into
1101
+ -- rows. Kept apart from plan_items, whose reader maps columns by
1102
+ -- position, and so the pass can never run twice for an item.
1103
+ CREATE TABLE IF NOT EXISTS item_criteria_migrated (
1104
+ item_uid TEXT PRIMARY KEY,
1105
+ migrated_at INTEGER NOT NULL
1106
+ );
1107
+
1108
+ -- Phase 31 \xA78.3 \u2014 a check run: every criterion's mechanical checks
1109
+ -- re-run and recorded. Append-only; a run never approves anything, so a
1110
+ -- plan can say "passed its last three runs" and mean it.
1111
+ CREATE TABLE IF NOT EXISTS check_runs (
1112
+ uid TEXT PRIMARY KEY,
1113
+ plan_uid TEXT NOT NULL,
1114
+ trigger TEXT NOT NULL,
1115
+ by_actor TEXT NOT NULL,
1116
+ by_type TEXT NOT NULL,
1117
+ -- JSON array of item uids when the run covered only some items
1118
+ -- (a material changed); NULL for the whole plan.
1119
+ scope TEXT,
1120
+ outcomes TEXT NOT NULL,
1121
+ since_last TEXT NOT NULL DEFAULT '[]',
1122
+ started_at INTEGER NOT NULL,
1123
+ finished_at INTEGER NOT NULL
1124
+ );
1125
+ CREATE INDEX IF NOT EXISTS idx_check_runs_plan ON check_runs(plan_uid, started_at);
1126
+
1127
+ -- Phase 23 \u2014 time and cost. One row per closed TURN (see
1128
+ -- budget-service), not per tool call: an agent's wall-clock is mostly
1129
+ -- model thinking between calls, so summing tool durations would
1130
+ -- undercount it several-fold.
1131
+ --
1132
+ -- item_uid is nullable on purpose. Time an agent spends before
1133
+ -- claiming anything is real time and belongs to the plan; dropping it
1134
+ -- would make every plan look cheaper than it was.
1135
+ --
1136
+ -- cost_usd is nullable for the same reason costOf returns null:
1137
+ -- an agent that does not report its model has an unknown cost, and
1138
+ -- zero would read as free.
1139
+ CREATE TABLE IF NOT EXISTS item_time_entries (
1140
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
1141
+ plan_uid TEXT NOT NULL,
1142
+ item_uid TEXT,
1143
+ session_id TEXT,
1144
+ agent_type TEXT,
1145
+ agent_model TEXT,
1146
+ started_at INTEGER NOT NULL,
1147
+ ended_at INTEGER NOT NULL,
1148
+ input_tokens INTEGER NOT NULL DEFAULT 0,
1149
+ output_tokens INTEGER NOT NULL DEFAULT 0,
1150
+ cache_write_tokens INTEGER NOT NULL DEFAULT 0,
1151
+ cache_read_tokens INTEGER NOT NULL DEFAULT 0,
1152
+ cost_usd REAL,
1153
+ pricing_version TEXT
1154
+ );
1155
+ CREATE INDEX IF NOT EXISTS idx_time_entries_plan ON item_time_entries(plan_uid);
1156
+ CREATE INDEX IF NOT EXISTS idx_time_entries_item ON item_time_entries(item_uid);
1157
+
1158
+ -- A ceiling is advisory, the same posture as the stuck sensor: we have
1159
+ -- no mechanism to halt an agent, and pretending otherwise would be
1160
+ -- worse than honest advice. notified_at exists so the 80% warning
1161
+ -- fires once rather than on every tool call.
1162
+ CREATE TABLE IF NOT EXISTS plan_budgets (
1163
+ plan_uid TEXT PRIMARY KEY,
1164
+ minutes INTEGER,
1165
+ cost_usd REAL,
1166
+ exempt INTEGER NOT NULL DEFAULT 0,
1167
+ notified_at INTEGER,
1168
+ updated_at INTEGER NOT NULL
1169
+ );
1170
+
1171
+ -- Every change to a plan's ceiling, append-only: who made it, how it
1172
+ -- arrived, and what it was before. An agent may change a budget (it is
1173
+ -- advisory), and a change an agent made is flagged until a person has
1174
+ -- seen it (Phase 32 \xA70.4g, owner's decision).
1175
+ CREATE TABLE IF NOT EXISTS plan_budget_changes (
1176
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
1177
+ plan_uid TEXT NOT NULL,
1178
+ actor TEXT NOT NULL,
1179
+ actor_type TEXT NOT NULL,
1180
+ channel TEXT NOT NULL,
1181
+ before_json TEXT,
1182
+ after_json TEXT NOT NULL,
1183
+ created_at INTEGER NOT NULL,
1184
+ acknowledged_at INTEGER,
1185
+ acknowledged_by TEXT
1186
+ );
1187
+ CREATE INDEX IF NOT EXISTS idx_plan_budget_changes_plan ON plan_budget_changes(plan_uid, created_at);
1188
+
1189
+ -- Every change to a project's freeze, who made it and how it arrived
1190
+ -- (owner's decision, Phase 32 \xA70.4k). The freeze itself lives in the
1191
+ -- project's .codetrellis/config.json; this is the record of who changed it.
1192
+ CREATE TABLE IF NOT EXISTS project_freeze_changes (
1193
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
1194
+ project_path TEXT NOT NULL,
1195
+ actor TEXT NOT NULL,
1196
+ actor_type TEXT NOT NULL,
1197
+ channel TEXT NOT NULL,
1198
+ before_json TEXT,
1199
+ after_json TEXT NOT NULL,
1200
+ created_at INTEGER NOT NULL,
1201
+ acknowledged_at INTEGER,
1202
+ acknowledged_by TEXT
1203
+ );
1204
+ CREATE INDEX IF NOT EXISTS idx_project_freeze_changes_project ON project_freeze_changes(project_path, created_at);
1205
+
1206
+ -- The graph diff's baseline, per project, so a restart restores it
1207
+ -- instead of re-capturing the tree at launch (Phase 32 \xA70.6, bug 9).
1208
+ CREATE TABLE IF NOT EXISTS project_baselines (
1209
+ project_path TEXT PRIMARY KEY,
1210
+ data_json TEXT NOT NULL,
1211
+ updated_at INTEGER NOT NULL
1212
+ );
1213
+
1214
+ CREATE TABLE IF NOT EXISTS plan_item_versions (
1215
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
1216
+ item_uid TEXT NOT NULL REFERENCES plan_items(uid),
1217
+ version INTEGER NOT NULL,
1218
+ body_snapshot TEXT,
1219
+ meta_snapshot TEXT,
1220
+ change_summary TEXT,
1221
+ author TEXT NOT NULL,
1222
+ author_type TEXT NOT NULL DEFAULT 'human',
1223
+ created_at INTEGER NOT NULL,
1224
+ UNIQUE(item_uid, version)
1225
+ );
1226
+ CREATE INDEX IF NOT EXISTS idx_plan_item_versions_item ON plan_item_versions(item_uid);
1227
+
1228
+ CREATE TABLE IF NOT EXISTS plan_events (
1229
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
1230
+ plan_uid TEXT NOT NULL REFERENCES plans(uid),
1231
+ item_uid TEXT,
1232
+ event_type TEXT NOT NULL,
1233
+ before_state TEXT,
1234
+ after_state TEXT,
1235
+ summary TEXT NOT NULL,
1236
+ author TEXT NOT NULL,
1237
+ author_type TEXT NOT NULL DEFAULT 'human',
1238
+ created_at INTEGER NOT NULL
1239
+ );
1240
+ CREATE INDEX IF NOT EXISTS idx_plan_events_plan ON plan_events(plan_uid, created_at);
1241
+ CREATE INDEX IF NOT EXISTS idx_plan_events_item ON plan_events(item_uid, created_at);
1242
+ CREATE INDEX IF NOT EXISTS idx_plan_events_type ON plan_events(event_type);
1243
+
1244
+ CREATE TABLE IF NOT EXISTS channel_events (
1245
+ uid TEXT PRIMARY KEY,
1246
+ plan_uid TEXT NOT NULL REFERENCES plans(uid),
1247
+ item_uid TEXT,
1248
+ event_type TEXT NOT NULL,
1249
+ payload TEXT NOT NULL DEFAULT '{}',
1250
+ author TEXT NOT NULL,
1251
+ author_type TEXT NOT NULL DEFAULT 'human',
1252
+ agent_model TEXT,
1253
+ responds_to TEXT REFERENCES channel_events(uid),
1254
+ status TEXT NOT NULL DEFAULT 'open',
1255
+ created_at INTEGER NOT NULL,
1256
+ updated_at INTEGER NOT NULL
1257
+ );
1258
+ CREATE INDEX IF NOT EXISTS idx_channel_events_plan ON channel_events(plan_uid, created_at);
1259
+ CREATE INDEX IF NOT EXISTS idx_channel_events_item ON channel_events(item_uid, created_at);
1260
+ CREATE INDEX IF NOT EXISTS idx_channel_events_type ON channel_events(event_type);
1261
+ CREATE INDEX IF NOT EXISTS idx_channel_events_thread ON channel_events(responds_to);
1262
+ CREATE INDEX IF NOT EXISTS idx_channel_events_status ON channel_events(status, plan_uid);
1263
+ `;
1264
+ const SCHEMA_SYSTEM_DOCS = `
1265
+ CREATE TABLE IF NOT EXISTS system_docs (
1266
+ uid TEXT PRIMARY KEY,
1267
+ project_path TEXT NOT NULL,
1268
+ slug TEXT NOT NULL,
1269
+ title TEXT NOT NULL,
1270
+ body TEXT NOT NULL DEFAULT '',
1271
+ owner TEXT,
1272
+ tags TEXT NOT NULL DEFAULT '[]',
1273
+ "references" TEXT NOT NULL DEFAULT '{}',
1274
+ captured_against_commit TEXT,
1275
+ last_verified_at INTEGER,
1276
+ author TEXT NOT NULL DEFAULT 'human',
1277
+ author_type TEXT NOT NULL DEFAULT 'human',
1278
+ created_at INTEGER NOT NULL,
1279
+ updated_at INTEGER NOT NULL,
1280
+ UNIQUE(project_path, slug)
1281
+ );
1282
+ CREATE INDEX IF NOT EXISTS idx_system_docs_project ON system_docs(project_path);
1283
+ CREATE INDEX IF NOT EXISTS idx_system_docs_slug ON system_docs(slug);
1284
+ CREATE INDEX IF NOT EXISTS idx_system_docs_updated ON system_docs(updated_at DESC);
1285
+ `;
1286
+ const SCHEMA_EXTERNAL_REFS = `
1287
+ CREATE TABLE IF NOT EXISTS external_refs (
1288
+ uid TEXT PRIMARY KEY,
1289
+ item_uid TEXT NOT NULL,
1290
+ kind TEXT NOT NULL DEFAULT 'url',
1291
+ url TEXT NOT NULL,
1292
+ title TEXT NOT NULL DEFAULT '',
1293
+ metadata TEXT DEFAULT NULL,
1294
+ external_key TEXT,
1295
+ author TEXT NOT NULL DEFAULT 'human',
1296
+ author_type TEXT NOT NULL DEFAULT 'human',
1297
+ created_at INTEGER NOT NULL
1298
+ );
1299
+ CREATE INDEX IF NOT EXISTS idx_external_refs_item ON external_refs(item_uid);
1300
+ CREATE INDEX IF NOT EXISTS idx_external_refs_kind ON external_refs(kind);
1301
+
1302
+ -- Phase 24 \u2014 the ticket key (PROJ-412, ENG-88) as its own column.
1303
+ -- The URL already encodes it, but write-back needs to match on the key
1304
+ -- and re-import needs it to be idempotent, and re-parsing a URL at
1305
+ -- every comparison would make the key a derived value in two places.
1306
+ -- Nullable, so the reconciler adds it with no migration.
1307
+
1308
+ -- Plan-level external refs. An epic maps to a PLAN, not to an item,
1309
+ -- and external_refs.item_uid is NOT NULL \u2014 a constraint the reconciler
1310
+ -- cannot relax. A separate table is honest about that rather than
1311
+ -- storing a plan uid in a column named item_uid.
1312
+ CREATE TABLE IF NOT EXISTS plan_external_refs (
1313
+ uid TEXT PRIMARY KEY,
1314
+ plan_uid TEXT NOT NULL,
1315
+ kind TEXT NOT NULL DEFAULT 'url',
1316
+ url TEXT NOT NULL,
1317
+ title TEXT NOT NULL DEFAULT '',
1318
+ external_key TEXT,
1319
+ metadata TEXT DEFAULT NULL,
1320
+ author TEXT NOT NULL DEFAULT 'human',
1321
+ author_type TEXT NOT NULL DEFAULT 'human',
1322
+ created_at INTEGER NOT NULL
1323
+ );
1324
+ CREATE INDEX IF NOT EXISTS idx_plan_external_refs_plan ON plan_external_refs(plan_uid);
1325
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_plan_external_refs_key ON plan_external_refs(plan_uid, external_key);
1326
+
1327
+ -- The write-back watermark. CodeTrellis never talks to Jira: the
1328
+ -- agent holds that credential and does the writing. All we owe it is
1329
+ -- "what changed since you last synced", which is this one timestamp.
1330
+ CREATE TABLE IF NOT EXISTS external_sync_state (
1331
+ plan_uid TEXT PRIMARY KEY,
1332
+ last_synced_at INTEGER NOT NULL,
1333
+ synced_by TEXT,
1334
+ note TEXT
1335
+ );
1336
+ `;
1337
+ const RECONCILED_SCHEMA_SQL = [
1338
+ SCHEMA_AST,
1339
+ SCHEMA_PLANS_CORE,
1340
+ SCHEMA_ATTACHMENTS,
1341
+ SCHEMA_PLAN_ITEMS,
1342
+ SCHEMA_SYSTEM_DOCS,
1343
+ SCHEMA_EXTERNAL_REFS
1344
+ ].join("\n");
1345
+ const PERSISTENT_SCHEMA_SQL = RECONCILED_SCHEMA_SQL;
1346
+ const EPHEMERAL_TABLES = [];
1347
+ // Annotate the CommonJS export names for ESM import in node:
1348
+ 0 && (module.exports = {
1349
+ EPHEMERAL_TABLES,
1350
+ PERSISTENT_SCHEMA_SQL,
1351
+ RECONCILED_SCHEMA_SQL,
1352
+ SCHEMA_AST,
1353
+ SCHEMA_ATTACHMENTS,
1354
+ SCHEMA_EXTERNAL_REFS,
1355
+ SCHEMA_PLANS_CORE,
1356
+ SCHEMA_PLAN_ITEMS,
1357
+ SCHEMA_SYSTEM_DOCS
1358
+ });