@stravica-ai/digital-operator-pa 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +170 -0
  3. package/bin/desk +9 -0
  4. package/bin/distill +2 -0
  5. package/bin/estate-sync +2 -0
  6. package/bin/launch +2 -0
  7. package/bin/memory-sync +2 -0
  8. package/bin/migrate-inspect +2 -0
  9. package/bin/pa +2 -0
  10. package/bin/pa-coordinator-hook +2 -0
  11. package/bin/pa-init +2 -0
  12. package/bin/research +2 -0
  13. package/bin/scheduler +2 -0
  14. package/bin/secrets +2 -0
  15. package/bin/slice +2 -0
  16. package/bin/smoke +9 -0
  17. package/bin/sync +2 -0
  18. package/dist/engineering-pa-cli/README.md +205 -0
  19. package/dist/engineering-pa-cli/bin/estate-sync +2 -0
  20. package/dist/engineering-pa-cli/bin/launch +2 -0
  21. package/dist/engineering-pa-cli/bin/pa +2 -0
  22. package/dist/engineering-pa-cli/bin/pa-coordinator-hook +12 -0
  23. package/dist/engineering-pa-cli/bin/research +2 -0
  24. package/dist/engineering-pa-cli/bin/scheduler +2 -0
  25. package/dist/engineering-pa-cli/bin/secrets +2 -0
  26. package/dist/engineering-pa-cli/bin/smoke +9 -0
  27. package/dist/engineering-pa-cli/bin/sync +2 -0
  28. package/dist/engineering-pa-cli/config/coordinator-allowlist.json +118 -0
  29. package/dist/engineering-pa-cli/docs/coordinator-hook.md +211 -0
  30. package/dist/engineering-pa-cli/docs/estate-sync.md +412 -0
  31. package/dist/engineering-pa-cli/docs/gsc.md +175 -0
  32. package/dist/engineering-pa-cli/docs/lint-linkedin.md +139 -0
  33. package/dist/engineering-pa-cli/docs/secrets.md +221 -0
  34. package/dist/engineering-pa-cli/docs/smoke.md +113 -0
  35. package/dist/engineering-pa-cli/docs/staging-alias.md +114 -0
  36. package/dist/engineering-pa-cli/index.mjs +17 -0
  37. package/dist/engineering-pa-cli/package.json +37 -0
  38. package/dist/engineering-pa-cli/src/autonomy/cli.mjs +329 -0
  39. package/dist/engineering-pa-cli/src/autonomy/envelope.mjs +301 -0
  40. package/dist/engineering-pa-cli/src/coordinator-hook/cli.mjs +140 -0
  41. package/dist/engineering-pa-cli/src/coordinator-hook/config.mjs +134 -0
  42. package/dist/engineering-pa-cli/src/coordinator-hook/message.mjs +47 -0
  43. package/dist/engineering-pa-cli/src/coordinator-hook/policy.mjs +211 -0
  44. package/dist/engineering-pa-cli/src/coordinator-hook/repo-root.mjs +44 -0
  45. package/dist/engineering-pa-cli/src/coordinator-hook/self.mjs +30 -0
  46. package/dist/engineering-pa-cli/src/environment/cli.mjs +287 -0
  47. package/dist/engineering-pa-cli/src/environment/probes.mjs +302 -0
  48. package/dist/engineering-pa-cli/src/gsc/auth.mjs +148 -0
  49. package/dist/engineering-pa-cli/src/gsc/cli.mjs +93 -0
  50. package/dist/engineering-pa-cli/src/gsc/cloudflare.mjs +318 -0
  51. package/dist/engineering-pa-cli/src/gsc/commands/add-property.mjs +70 -0
  52. package/dist/engineering-pa-cli/src/gsc/commands/list-properties.mjs +33 -0
  53. package/dist/engineering-pa-cli/src/gsc/commands/pull-analytics.mjs +130 -0
  54. package/dist/engineering-pa-cli/src/gsc/commands/submit-sitemap.mjs +41 -0
  55. package/dist/engineering-pa-cli/src/gsc/commands/verify-via-cf-dns.mjs +189 -0
  56. package/dist/engineering-pa-cli/src/knowledge/call-log.mjs +59 -0
  57. package/dist/engineering-pa-cli/src/knowledge/cli.mjs +242 -0
  58. package/dist/engineering-pa-cli/src/knowledge/eval.mjs +446 -0
  59. package/dist/engineering-pa-cli/src/knowledge/formatters.mjs +331 -0
  60. package/dist/engineering-pa-cli/src/knowledge/graph.mjs +710 -0
  61. package/dist/engineering-pa-cli/src/launch/README.md +214 -0
  62. package/dist/engineering-pa-cli/src/launch/cli.mjs +51 -0
  63. package/dist/engineering-pa-cli/src/launch/commands/launch.mjs +106 -0
  64. package/dist/engineering-pa-cli/src/launch/identity.mjs +43 -0
  65. package/dist/engineering-pa-cli/src/launch/planner.mjs +44 -0
  66. package/dist/engineering-pa-cli/src/launch/repo-root.mjs +53 -0
  67. package/dist/engineering-pa-cli/src/launch/runner.mjs +147 -0
  68. package/dist/engineering-pa-cli/src/launch/task-loader.mjs +85 -0
  69. package/dist/engineering-pa-cli/src/lint/cli.mjs +61 -0
  70. package/dist/engineering-pa-cli/src/lint/commands/linkedin.mjs +133 -0
  71. package/dist/engineering-pa-cli/src/lint/detectors.mjs +90 -0
  72. package/dist/engineering-pa-cli/src/lint/linter.mjs +69 -0
  73. package/dist/engineering-pa-cli/src/lint/reporter.mjs +32 -0
  74. package/dist/engineering-pa-cli/src/lint/rules.mjs +132 -0
  75. package/dist/engineering-pa-cli/src/pa/cli.mjs +369 -0
  76. package/dist/engineering-pa-cli/src/pa/doc-groups.mjs +164 -0
  77. package/dist/engineering-pa-cli/src/pa/io.mjs +80 -0
  78. package/dist/engineering-pa-cli/src/pa/project-cli.mjs +385 -0
  79. package/dist/engineering-pa-cli/src/pa/projects.mjs +352 -0
  80. package/dist/engineering-pa-cli/src/pa/repo-root.mjs +64 -0
  81. package/dist/engineering-pa-cli/src/pa/session.mjs +254 -0
  82. package/dist/engineering-pa-cli/src/pa/work-cli.mjs +164 -0
  83. package/dist/engineering-pa-cli/src/pa/work.mjs +196 -0
  84. package/dist/engineering-pa-cli/src/pa/workstreams.mjs +201 -0
  85. package/dist/engineering-pa-cli/src/research/README.md +360 -0
  86. package/dist/engineering-pa-cli/src/research/briefs/extractor.md +103 -0
  87. package/dist/engineering-pa-cli/src/research/briefs/searcher.md +113 -0
  88. package/dist/engineering-pa-cli/src/research/briefs/synthesizer.md +124 -0
  89. package/dist/engineering-pa-cli/src/research/briefs/verifier.md +86 -0
  90. package/dist/engineering-pa-cli/src/research/cli.mjs +141 -0
  91. package/dist/engineering-pa-cli/src/research/commands/gates.mjs +176 -0
  92. package/dist/engineering-pa-cli/src/research/commands/list.mjs +56 -0
  93. package/dist/engineering-pa-cli/src/research/commands/mark.mjs +97 -0
  94. package/dist/engineering-pa-cli/src/research/commands/paths.mjs +69 -0
  95. package/dist/engineering-pa-cli/src/research/commands/prune.mjs +86 -0
  96. package/dist/engineering-pa-cli/src/research/commands/run.mjs +94 -0
  97. package/dist/engineering-pa-cli/src/research/commands/show.mjs +43 -0
  98. package/dist/engineering-pa-cli/src/research/docs/operator-present-flow.md +120 -0
  99. package/dist/engineering-pa-cli/src/research/format.mjs +59 -0
  100. package/dist/engineering-pa-cli/src/research/promote.mjs +260 -0
  101. package/dist/engineering-pa-cli/src/research/schema/finding.schema.json +55 -0
  102. package/dist/engineering-pa-cli/src/research/schema/gates.schema.json +34 -0
  103. package/dist/engineering-pa-cli/src/research/schema/manifest.schema.json +59 -0
  104. package/dist/engineering-pa-cli/src/research/schema/plan.schema.json +41 -0
  105. package/dist/engineering-pa-cli/src/research/schema/sources.schema.json +31 -0
  106. package/dist/engineering-pa-cli/src/research/store/findings.mjs +61 -0
  107. package/dist/engineering-pa-cli/src/research/store/gates.mjs +73 -0
  108. package/dist/engineering-pa-cli/src/research/store/index.mjs +312 -0
  109. package/dist/engineering-pa-cli/src/research/store/manifest.mjs +56 -0
  110. package/dist/engineering-pa-cli/src/research/store/plan.mjs +59 -0
  111. package/dist/engineering-pa-cli/src/research/store/sources.mjs +44 -0
  112. package/dist/engineering-pa-cli/src/research/store/validate.mjs +92 -0
  113. package/dist/engineering-pa-cli/src/research/workflows/research-normal.js +573 -0
  114. package/dist/engineering-pa-cli/src/scheduler/cli.mjs +197 -0
  115. package/dist/engineering-pa-cli/src/secrets/cli.mjs +254 -0
  116. package/dist/engineering-pa-cli/src/secrets/commands/backup-template.mjs +67 -0
  117. package/dist/engineering-pa-cli/src/secrets/commands/backup.mjs +85 -0
  118. package/dist/engineering-pa-cli/src/secrets/commands/delete.mjs +58 -0
  119. package/dist/engineering-pa-cli/src/secrets/commands/find.mjs +36 -0
  120. package/dist/engineering-pa-cli/src/secrets/commands/get.mjs +49 -0
  121. package/dist/engineering-pa-cli/src/secrets/commands/init.mjs +69 -0
  122. package/dist/engineering-pa-cli/src/secrets/commands/list.mjs +37 -0
  123. package/dist/engineering-pa-cli/src/secrets/commands/rotate.mjs +46 -0
  124. package/dist/engineering-pa-cli/src/secrets/commands/set.mjs +123 -0
  125. package/dist/engineering-pa-cli/src/secrets/commands/status.mjs +146 -0
  126. package/dist/engineering-pa-cli/src/secrets/commands/vaults.mjs +57 -0
  127. package/dist/engineering-pa-cli/src/secrets/commands/verify.mjs +143 -0
  128. package/dist/engineering-pa-cli/src/secrets/vault.mjs +766 -0
  129. package/dist/engineering-pa-cli/src/smoke/checks.mjs +199 -0
  130. package/dist/engineering-pa-cli/src/smoke/cli.mjs +108 -0
  131. package/dist/engineering-pa-cli/src/smoke/commands/run.mjs +237 -0
  132. package/dist/engineering-pa-cli/src/smoke/runner.mjs +191 -0
  133. package/dist/engineering-pa-cli/src/staging-alias/cli.mjs +91 -0
  134. package/dist/engineering-pa-cli/src/staging-alias/cloudflare.mjs +380 -0
  135. package/dist/engineering-pa-cli/src/staging-alias/commands/list.mjs +36 -0
  136. package/dist/engineering-pa-cli/src/staging-alias/commands/set.mjs +188 -0
  137. package/dist/engineering-pa-cli/src/staging-alias/commands/status.mjs +113 -0
  138. package/dist/engineering-pa-cli/src/staging-alias/commands/unset.mjs +95 -0
  139. package/dist/engineering-pa-cli/src/staging-alias/sites.mjs +105 -0
  140. package/dist/engineering-pa-cli/src/sync/cli.mjs +151 -0
  141. package/dist/engineering-pa-cli/src/sync/git.mjs +149 -0
  142. package/dist/engineering-pa-cli/src/sync/lock.mjs +30 -0
  143. package/dist/engineering-pa-cli/src/sync/regenerated-artifacts.mjs +114 -0
  144. package/dist/engineering-pa-cli/src/sync/registry-scope.mjs +260 -0
  145. package/dist/engineering-pa-cli/src/sync/run.mjs +531 -0
  146. package/dist/engineering-pa-cli/src/sync/runner.mjs +62 -0
  147. package/dist/engineering-pa-cli/src/sync/runs-digest.mjs +138 -0
  148. package/dist/engineering-pa-core/README.md +60 -0
  149. package/dist/engineering-pa-core/bin/desk +9 -0
  150. package/dist/engineering-pa-core/bin/distill +2 -0
  151. package/dist/engineering-pa-core/bin/memory-sync +2 -0
  152. package/dist/engineering-pa-core/bin/slice +2 -0
  153. package/dist/engineering-pa-core/docs/autonomy-envelope-tracker.md +111 -0
  154. package/dist/engineering-pa-core/docs/blueprints/README.md +45 -0
  155. package/dist/engineering-pa-core/docs/blueprints/docker-services/blueprint.md +168 -0
  156. package/dist/engineering-pa-core/docs/blueprints/git-identity/blueprint.md +116 -0
  157. package/dist/engineering-pa-core/docs/blueprints/ideas/custom-workspace-views.md +9 -0
  158. package/dist/engineering-pa-core/docs/blueprints/ideas/knowledge-domain-patterns.md +15 -0
  159. package/dist/engineering-pa-core/docs/blueprints/ideas/office-integration.md +11 -0
  160. package/dist/engineering-pa-core/docs/blueprints/ideas/team-scaling.md +9 -0
  161. package/dist/engineering-pa-core/docs/blueprints/ideas/work-personal-separation.md +9 -0
  162. package/dist/engineering-pa-core/docs/blueprints/scheduled-distillation/blueprint.md +129 -0
  163. package/dist/engineering-pa-core/docs/blueprints/tool-integration/blueprint.md +110 -0
  164. package/dist/engineering-pa-core/docs/commands/init.md +159 -0
  165. package/dist/engineering-pa-core/docs/commands/schedule.md +98 -0
  166. package/dist/engineering-pa-core/docs/commands/upgrade.md +67 -0
  167. package/dist/engineering-pa-core/docs/entity-location-map.md +93 -0
  168. package/dist/engineering-pa-core/docs/knowledge-scaffold.md +121 -0
  169. package/dist/engineering-pa-core/docs/lock.md +155 -0
  170. package/dist/engineering-pa-core/docs/memory-sync.md +28 -0
  171. package/dist/engineering-pa-core/docs/pa-operating-model.md +457 -0
  172. package/dist/engineering-pa-core/docs/scheduling.md +35 -0
  173. package/dist/engineering-pa-core/docs/standards/README.md +24 -0
  174. package/dist/engineering-pa-core/docs/standards/briefing-contract.md +161 -0
  175. package/dist/engineering-pa-core/docs/standards/tooling.md +240 -0
  176. package/dist/engineering-pa-core/docs/tools/distill.md +230 -0
  177. package/dist/engineering-pa-core/docs/tools/memory-sync.md +98 -0
  178. package/dist/engineering-pa-core/docs/tools/scheduler.md +243 -0
  179. package/dist/engineering-pa-core/docs/tools/slice.md +150 -0
  180. package/dist/engineering-pa-core/docs/upstream-issue-filing.md +88 -0
  181. package/dist/engineering-pa-core/docs/working-directory.md +29 -0
  182. package/dist/engineering-pa-core/docs/workspace-operations.md +46 -0
  183. package/dist/engineering-pa-core/index.mjs +21 -0
  184. package/dist/engineering-pa-core/knowledge/README.md +53 -0
  185. package/dist/engineering-pa-core/knowledge/canonical/.gitkeep +0 -0
  186. package/dist/engineering-pa-core/knowledge/content-voice/README.md +64 -0
  187. package/dist/engineering-pa-core/knowledge/content-voice/banned-ai-tells-baseline.md +133 -0
  188. package/dist/engineering-pa-core/knowledge/content-voice/banned-ai-tells-shape.md +58 -0
  189. package/dist/engineering-pa-core/knowledge/content-voice/banned-ai-tells-taxonomy.md +33 -0
  190. package/dist/engineering-pa-core/knowledge/content-voice/content-pipeline-routing.md +58 -0
  191. package/dist/engineering-pa-core/knowledge/content-voice/new-tell-capture-procedure.md +40 -0
  192. package/dist/engineering-pa-core/knowledge/content-voice/voice-guide-shape.md +43 -0
  193. package/dist/engineering-pa-core/knowledge/delegation-dispatch/README.md +34 -0
  194. package/dist/engineering-pa-core/knowledge/delegation-dispatch/briefing-contract.md +77 -0
  195. package/dist/engineering-pa-core/knowledge/delegation-dispatch/delegation-modes.md +84 -0
  196. package/dist/engineering-pa-core/knowledge/delegation-dispatch/dispatch-envelope.md +238 -0
  197. package/dist/engineering-pa-core/knowledge/delegation-dispatch/task-groups-and-orchestrators.md +62 -0
  198. package/dist/engineering-pa-core/knowledge/delegation-dispatch/team-improvement-loop.md +48 -0
  199. package/dist/engineering-pa-core/knowledge/delegation-dispatch/tool-development-policy.md +48 -0
  200. package/dist/engineering-pa-core/knowledge/engineering-discipline/README.md +33 -0
  201. package/dist/engineering-pa-core/knowledge/engineering-discipline/blast-radius-and-safety.md +50 -0
  202. package/dist/engineering-pa-core/knowledge/engineering-discipline/investigate-root-causes.md +48 -0
  203. package/dist/engineering-pa-core/knowledge/engineering-discipline/role-ladder.md +57 -0
  204. package/dist/engineering-pa-core/knowledge/engineering-discipline/verify-runtime-behaviour.md +53 -0
  205. package/dist/engineering-pa-core/knowledge/engineering-discipline/worktree-isolation.md +50 -0
  206. package/dist/engineering-pa-core/knowledge/knowledge-memory/README.md +33 -0
  207. package/dist/engineering-pa-core/knowledge/knowledge-memory/claude-md-hygiene.md +47 -0
  208. package/dist/engineering-pa-core/knowledge/knowledge-memory/journal-and-self-improvement.md +53 -0
  209. package/dist/engineering-pa-core/knowledge/knowledge-memory/knowledge-retrieval-discipline.md +62 -0
  210. package/dist/engineering-pa-core/knowledge/knowledge-memory/librarian-synthesis-mandate.md +56 -0
  211. package/dist/engineering-pa-core/knowledge/knowledge-memory/staging-and-observations.md +58 -0
  212. package/dist/engineering-pa-core/knowledge/operator-interface/README.md +32 -0
  213. package/dist/engineering-pa-core/knowledge/operator-interface/communication-style.md +33 -0
  214. package/dist/engineering-pa-core/knowledge/operator-interface/escalation-and-correction.md +45 -0
  215. package/dist/engineering-pa-core/knowledge/operator-interface/push-back-discipline.md +42 -0
  216. package/dist/engineering-pa-core/knowledge/operator-interface/session-boot-and-end.md +56 -0
  217. package/dist/engineering-pa-core/knowledge/platform-tooling/README.md +37 -0
  218. package/dist/engineering-pa-core/knowledge/platform-tooling/desk-cli-reference.md +52 -0
  219. package/dist/engineering-pa-core/knowledge/platform-tooling/environment-awareness.md +91 -0
  220. package/dist/engineering-pa-core/knowledge/platform-tooling/mcp-servers-catalogue.md +52 -0
  221. package/dist/engineering-pa-core/knowledge/platform-tooling/pa-cli-reference.md +55 -0
  222. package/dist/engineering-pa-core/knowledge/platform-tooling/scheduling-and-launchd.md +56 -0
  223. package/dist/engineering-pa-core/knowledge/platform-tooling/tool-discovery-discipline.md +49 -0
  224. package/dist/engineering-pa-core/knowledge/platform-tooling/working-directory-vs-project-root.md +43 -0
  225. package/dist/engineering-pa-core/knowledge/platform-tooling/workspace-server.md +51 -0
  226. package/dist/engineering-pa-core/knowledge/raw/.gitkeep +0 -0
  227. package/dist/engineering-pa-core/knowledge/scaffold/domains.json +5 -0
  228. package/dist/engineering-pa-core/knowledge/schema/.gitkeep +0 -0
  229. package/dist/engineering-pa-core/knowledge/work-management/README.md +33 -0
  230. package/dist/engineering-pa-core/knowledge/work-management/desk-cli.md +84 -0
  231. package/dist/engineering-pa-core/knowledge/work-management/progress-md.md +48 -0
  232. package/dist/engineering-pa-core/knowledge/work-management/projects.md +64 -0
  233. package/dist/engineering-pa-core/knowledge/work-management/spawn-log.md +48 -0
  234. package/dist/engineering-pa-core/knowledge/work-management/work-items.md +67 -0
  235. package/dist/engineering-pa-core/package.json +26 -0
  236. package/dist/engineering-pa-core/roles/agent-ops/definition.md +79 -0
  237. package/dist/engineering-pa-core/roles/dispatch-briefer/definition.md +195 -0
  238. package/dist/engineering-pa-core/roles/librarian/definition.md +176 -0
  239. package/dist/engineering-pa-core/roles/pa/definition.md +93 -0
  240. package/dist/engineering-pa-core/roles/system-admin/definition.md +106 -0
  241. package/dist/engineering-pa-core/roles/tool-developer/definition.md +116 -0
  242. package/dist/engineering-pa-core/roles/writer/definition.md +130 -0
  243. package/dist/engineering-pa-core/schema/autonomy-envelope.schema.json +61 -0
  244. package/dist/engineering-pa-core/schema/project.json +114 -0
  245. package/dist/engineering-pa-core/schema/schedule.json +63 -0
  246. package/dist/engineering-pa-core/schema/work-item.json +92 -0
  247. package/dist/engineering-pa-core/src/config/pa-package-name.mjs +30 -0
  248. package/dist/engineering-pa-core/src/desk/cli.mjs +95 -0
  249. package/dist/engineering-pa-core/src/desk/commands.mjs +398 -0
  250. package/dist/engineering-pa-core/src/desk/format.mjs +84 -0
  251. package/dist/engineering-pa-core/src/desk/repo.mjs +172 -0
  252. package/dist/engineering-pa-core/src/desk/team-scope.mjs +142 -0
  253. package/dist/engineering-pa-core/src/distill/cli.mjs +112 -0
  254. package/dist/engineering-pa-core/src/distill/prereqs.mjs +171 -0
  255. package/dist/engineering-pa-core/src/distill/prompt.mjs +74 -0
  256. package/dist/engineering-pa-core/src/distill/run.mjs +230 -0
  257. package/dist/engineering-pa-core/src/distill/runner.mjs +86 -0
  258. package/dist/engineering-pa-core/src/distill/staging.mjs +59 -0
  259. package/dist/engineering-pa-core/src/knowledge/retrieval/backlink-indexer.mjs +154 -0
  260. package/dist/engineering-pa-core/src/knowledge/retrieval/graph-builder.mjs +186 -0
  261. package/dist/engineering-pa-core/src/knowledge/retrieval/index-builder.mjs +225 -0
  262. package/dist/engineering-pa-core/src/knowledge/retrieval/query.mjs +263 -0
  263. package/dist/engineering-pa-core/src/lock/lock.mjs +202 -0
  264. package/dist/engineering-pa-core/src/memory-sync/cli-support.mjs +12 -0
  265. package/dist/engineering-pa-core/src/memory-sync/cli.mjs +56 -0
  266. package/dist/engineering-pa-core/src/memory-sync/commands/pull.mjs +44 -0
  267. package/dist/engineering-pa-core/src/memory-sync/commands/push.mjs +46 -0
  268. package/dist/engineering-pa-core/src/memory-sync/mirror.mjs +114 -0
  269. package/dist/engineering-pa-core/src/memory-sync/repo.mjs +65 -0
  270. package/dist/engineering-pa-core/src/scheduler/detect.mjs +111 -0
  271. package/dist/engineering-pa-core/src/scheduler/host.mjs +38 -0
  272. package/dist/engineering-pa-core/src/scheduler/index.mjs +13 -0
  273. package/dist/engineering-pa-core/src/scheduler/install.mjs +854 -0
  274. package/dist/engineering-pa-core/src/scheduler/list.mjs +168 -0
  275. package/dist/engineering-pa-core/src/scheduler/remove.mjs +176 -0
  276. package/dist/engineering-pa-core/src/scheduler/verify.mjs +435 -0
  277. package/dist/engineering-pa-core/src/session-boot/autonomy-injection.mjs +84 -0
  278. package/dist/engineering-pa-core/src/slice/cli.mjs +139 -0
  279. package/dist/engineering-pa-core/src/slice/inputs.mjs +174 -0
  280. package/dist/engineering-pa-core/src/slice/prompt.mjs +94 -0
  281. package/dist/engineering-pa-core/src/slice/prompts/dave-boot.md +91 -0
  282. package/dist/engineering-pa-core/src/slice/run.mjs +334 -0
  283. package/dist/engineering-pa-core-extensions-atlassian/README.md +31 -0
  284. package/dist/engineering-pa-core-extensions-atlassian/index.mjs +9 -0
  285. package/dist/engineering-pa-core-extensions-atlassian/package.json +19 -0
  286. package/dist/engineering-pa-core-extensions-n8n/README.md +29 -0
  287. package/dist/engineering-pa-core-extensions-n8n/index.mjs +8 -0
  288. package/dist/engineering-pa-core-extensions-n8n/package.json +19 -0
  289. package/dist/engineering-pa-librarian/README.md +38 -0
  290. package/dist/engineering-pa-librarian/index.mjs +12 -0
  291. package/dist/engineering-pa-librarian/package.json +19 -0
  292. package/dist/engineering-pa-migrate-inspect/README.md +131 -0
  293. package/dist/engineering-pa-migrate-inspect/bin/migrate-inspect +2 -0
  294. package/dist/engineering-pa-migrate-inspect/package.json +21 -0
  295. package/dist/engineering-pa-migrate-inspect/src/age-key-migrate.mjs +83 -0
  296. package/dist/engineering-pa-migrate-inspect/src/cli.mjs +97 -0
  297. package/dist/engineering-pa-migrate-inspect/src/inspector.mjs +237 -0
  298. package/dist/engineering-pa-migrate-inspect/src/platforms/linux.mjs +87 -0
  299. package/dist/engineering-pa-migrate-inspect/src/platforms/macos.mjs +105 -0
  300. package/dist/engineering-pa-migrate-inspect/src/runner.mjs +87 -0
  301. package/dist/engineering-pa-runbook/README.md +103 -0
  302. package/dist/engineering-pa-runbook/package.json +18 -0
  303. package/dist/engineering-pa-runbook/reference/dex-template.runbook.json +66 -0
  304. package/dist/engineering-pa-runbook/reference/hq-dave.runbook.json +69 -0
  305. package/dist/engineering-pa-runbook/reference/smarthome01.runbook.json +92 -0
  306. package/dist/engineering-pa-runbook/schema/inspection.schema.json +113 -0
  307. package/dist/engineering-pa-runbook/schema/runbook.schema.json +67 -0
  308. package/dist/engineering-pa-runbook/src/validator.mjs +167 -0
  309. package/dist/engineering-pa-scaffold/README.md +164 -0
  310. package/dist/engineering-pa-scaffold/bin/pa-init +2 -0
  311. package/dist/engineering-pa-scaffold/index.mjs +42 -0
  312. package/dist/engineering-pa-scaffold/package.json +22 -0
  313. package/dist/engineering-pa-scaffold/src/cli.mjs +115 -0
  314. package/dist/engineering-pa-scaffold/src/commands/init.mjs +169 -0
  315. package/dist/engineering-pa-scaffold/src/generator.mjs +354 -0
  316. package/dist/engineering-pa-scaffold/src/prompts.mjs +125 -0
  317. package/dist/engineering-pa-scaffold/src/runner.mjs +142 -0
  318. package/dist/engineering-pa-scaffold/templates/CLAUDE.md.template +196 -0
  319. package/dist/engineering-pa-scaffold/templates/operator-README.md.template +44 -0
  320. package/dist/engineering-pa-types-engineering/README.md +35 -0
  321. package/dist/engineering-pa-types-engineering/docs/commands/product-build.md +120 -0
  322. package/dist/engineering-pa-types-engineering/index.mjs +9 -0
  323. package/dist/engineering-pa-types-engineering/package.json +19 -0
  324. package/dist/engineering-pa-types-engineering/roles/product-engineer/definition.md +650 -0
  325. package/dist/engineering-pa-types-engineering/roles/product-engineer/templates/build-spec.md +82 -0
  326. package/dist/engineering-pa-types-engineering/roles/product-engineer/templates/preflight-checklist.md +158 -0
  327. package/dist/engineering-pa-types-engineering/roles/product-engineer/templates/worker-brief.md +130 -0
  328. package/dist/engineering-pa-workspace/README.md +197 -0
  329. package/dist/engineering-pa-workspace/app/assets/md.js +187 -0
  330. package/dist/engineering-pa-workspace/app/assets/modal.js +120 -0
  331. package/dist/engineering-pa-workspace/app/assets/theme.css +132 -0
  332. package/dist/engineering-pa-workspace/app/assets/theme.js +159 -0
  333. package/dist/engineering-pa-workspace/app/banner.js +320 -0
  334. package/dist/engineering-pa-workspace/app/delegations.html +345 -0
  335. package/dist/engineering-pa-workspace/app/home.html +1060 -0
  336. package/dist/engineering-pa-workspace/app/index.html +361 -0
  337. package/dist/engineering-pa-workspace/app/knowledge-map.html +163 -0
  338. package/dist/engineering-pa-workspace/app/knowledge.html +304 -0
  339. package/dist/engineering-pa-workspace/app/nav.json +75 -0
  340. package/dist/engineering-pa-workspace/app/notes.html +199 -0
  341. package/dist/engineering-pa-workspace/app/onboarding.html +592 -0
  342. package/dist/engineering-pa-workspace/app/profile.html +243 -0
  343. package/dist/engineering-pa-workspace/app/project-detail.html +432 -0
  344. package/dist/engineering-pa-workspace/app/projects.html +297 -0
  345. package/dist/engineering-pa-workspace/app/repos.html +598 -0
  346. package/dist/engineering-pa-workspace/app/schedules.html +486 -0
  347. package/dist/engineering-pa-workspace/app/secrets.html +164 -0
  348. package/dist/engineering-pa-workspace/app/staging.html +319 -0
  349. package/dist/engineering-pa-workspace/app/tasks.html +465 -0
  350. package/dist/engineering-pa-workspace/app/vendor/chart.umd.min.js +21 -0
  351. package/dist/engineering-pa-workspace/app/viewer.html +116 -0
  352. package/dist/engineering-pa-workspace/docs/DAEMON.md +104 -0
  353. package/dist/engineering-pa-workspace/docs/page-blueprint.md +286 -0
  354. package/dist/engineering-pa-workspace/docs/status-mon.md +168 -0
  355. package/dist/engineering-pa-workspace/index.mjs +12 -0
  356. package/dist/engineering-pa-workspace/nav.json.example +8 -0
  357. package/dist/engineering-pa-workspace/package.json +27 -0
  358. package/dist/engineering-pa-workspace/src/api.mjs +2086 -0
  359. package/dist/engineering-pa-workspace/src/install-daemon.mjs +573 -0
  360. package/dist/engineering-pa-workspace/src/nav.mjs +190 -0
  361. package/dist/engineering-pa-workspace/src/secrets-api.mjs +175 -0
  362. package/dist/engineering-pa-workspace/src/server.mjs +516 -0
  363. package/dist/engineering-pa-workspace/src/status-mon/poll.mjs +220 -0
  364. package/dist/engineering-pa-workspace/src/status-mon/poller.mjs +113 -0
  365. package/dist/engineering-pa-workspace/src/status-mon/run.mjs +133 -0
  366. package/dist/engineering-pa-workspace/src/supervisor.mjs +264 -0
  367. package/dist/engineering-pa-workspace/src/ws.mjs +633 -0
  368. package/index.mjs +60 -0
  369. package/package.json +58 -0
  370. package/templates/banned-ai-tells.md +102 -0
  371. package/templates/purpose.md +105 -0
  372. package/templates/voice-guide.md +98 -0
@@ -0,0 +1,260 @@
1
+ // Knowledge-library promotion (w-021).
2
+ //
3
+ // On `research mark done <id>` for a NORMAL or DEEP session, promote the
4
+ // session's verbatim `answer.md` into the operator knowledge library as a
5
+ // first-class queryable doc under `operator/knowledge/research/`, so
6
+ // `pa knowledge` surfaces it alongside every other operator doc.
7
+ //
8
+ // Operator directive (2026-07-07):
9
+ // - normal + deep → auto-promote.
10
+ // - light → NEVER promote (hard rule; `--promote` on light is a
11
+ // usage error, enforced in mark.mjs before we get here).
12
+ // - `--no-promote` → normal/deep skip with a one-line note (status still done).
13
+ // - aborted → never promoted (mark aborted never calls this).
14
+ //
15
+ // This module is the ONE place that writes to `operator/knowledge/`. Session
16
+ // reads fan out through the store (tooling standard §7: reads may scatter,
17
+ // writes may not). `knowledgeDir` is injectable so tests bind a temp dir —
18
+ // same posture as the store's `makeStore(dir)`.
19
+ //
20
+ // Graph shape the promoted doc must satisfy (discovered from
21
+ // @stravica-ai/engineering-pa-core .../knowledge/retrieval/graph-builder.mjs +
22
+ // the `pa knowledge` CLI graph.mjs — NEITHER reads front-matter):
23
+ // - node `title` = the first `# ` heading in the file → we prepend `# <question>`.
24
+ // - node `domain` = path segment under operator/knowledge → `research/` gives it.
25
+ // - edges = `[[wiki]]` + `[md](rel.md)` links + .backlinks.json → we add
26
+ // a provenance footer linking `./README.md` so `related` is non-empty.
27
+ // The rich front-matter block below is honoured by no builder today; it is
28
+ // human/Librarian metadata and forward-compat for a schema-aware builder.
29
+
30
+ import { mkdir, writeFile, readFile } from 'node:fs/promises';
31
+ import { existsSync } from 'node:fs';
32
+ import { join } from 'node:path';
33
+
34
+ import { getRepoRoot } from '../pa/repo-root.mjs';
35
+
36
+ // Where promoted answers land inside the operator repo. Historical shape: when
37
+ // the tool lived at `operator/extensions/tools/research/`, this constant was
38
+ // computed with `fileURLToPath(new URL('../../../../../', import.meta.url))` —
39
+ // a fixed five-`../` walk that only worked at that anchor. Under
40
+ // `@stravica-ai/digital-operator-pa`, the source lives inside `node_modules/`, so the
41
+ // walk lands in the wrong tree. Instead we resolve the operator repo root the
42
+ // same way `pa knowledge` / `pa work` do (env-var override, else walk up for
43
+ // `.git`) and join `operator/knowledge/` under it. Async because getRepoRoot is.
44
+ export const KNOWLEDGE_SUBPATH = 'operator/knowledge';
45
+ export const RESEARCH_DOMAIN = 'research';
46
+
47
+ export async function defaultKnowledgeDir() {
48
+ return join(await getRepoRoot(), KNOWLEDGE_SUBPATH);
49
+ }
50
+
51
+ // ── pure helpers ──────────────────────────────────────────────────────────────
52
+
53
+ // Kebab-case slug from the question. Deterministic (same question → same slug →
54
+ // same filename → idempotent promotion). Bounded length keeps filenames sane.
55
+ export function slugify(text, maxLen = 60) {
56
+ const slug = String(text ?? '')
57
+ .toLowerCase()
58
+ .normalize('NFKD').replace(/[\u0300-\u036f]/g, '') // strip accents
59
+ .replace(/[^a-z0-9]+/g, '-')
60
+ .replace(/^-+|-+$/g, '')
61
+ .slice(0, maxLen)
62
+ .replace(/-+$/g, '');
63
+ return slug || 'session';
64
+ }
65
+
66
+ // The promoted doc's filename: `<sessionId>-<slug>.md`. sessionId is unique and
67
+ // stable, so the target path is deterministic — the basis for idempotency.
68
+ export function promotedFileName(sessionId, question) {
69
+ return `${sessionId}-${slugify(question)}.md`;
70
+ }
71
+
72
+ // Derive counts the frontmatter records. manifest.json is FROZEN and carries
73
+ // none of these — everything is derived from the session's other artifacts
74
+ // (brief §5). A finding is the unit of "claim":
75
+ // refuted — any verification vote refuted it.
76
+ // verified — else, any vote confirmed it.
77
+ // unverified — else (only unverified-infra votes, or none, e.g. light mode).
78
+ // gatedCount counts UNRESOLVED gates (pending/retrying) — the ones still owed a
79
+ // human sweep; resolved/failed are closed out.
80
+ export function deriveCounts({ sources, findings, gates }) {
81
+ const sourceCount = sources?.items?.length ?? 0;
82
+ let verifiedCount = 0;
83
+ let refutedCount = 0;
84
+ let unverifiedCount = 0;
85
+ for (const f of findings ?? []) {
86
+ const outcomes = (f.verificationVotes ?? []).map((v) => v.outcome);
87
+ if (outcomes.includes('refuted')) refutedCount++;
88
+ else if (outcomes.includes('confirmed')) verifiedCount++;
89
+ else unverifiedCount++;
90
+ }
91
+ const gatedCount = (gates?.queue ?? []).filter(
92
+ (g) => g.status === 'pending' || g.status === 'retrying',
93
+ ).length;
94
+ return { sourceCount, verifiedCount, refutedCount, unverifiedCount, gatedCount };
95
+ }
96
+
97
+ // First substantive paragraph of the answer body → doc description. Skips
98
+ // front-matter, headings, blank lines, block markers and horizontal rules;
99
+ // collapses whitespace; truncates. Falls back to the question when the answer
100
+ // has no prose (e.g. a `structured` answer that is one JSON block).
101
+ export function firstParagraph(answer, fallback, maxLen = 240) {
102
+ const body = stripFrontMatter(String(answer ?? ''));
103
+ const para = [];
104
+ let inFence = false;
105
+ for (const raw of body.split(/\r?\n/)) {
106
+ const line = raw.trim();
107
+ if (line.startsWith('```')) {
108
+ // A fence before any prose → skip the whole block; after prose → stop.
109
+ if (para.length) break;
110
+ inFence = !inFence;
111
+ continue;
112
+ }
113
+ if (inFence) continue; // skip fenced content entirely
114
+ if (line === '') { if (para.length) break; else continue; }
115
+ if (line.startsWith('#')) { if (para.length) break; else continue; }
116
+ if (line === '---' || line.startsWith('|')) { if (para.length) break; else continue; }
117
+ para.push(line);
118
+ }
119
+ const text = para.join(' ').replace(/\s+/g, ' ').trim();
120
+ const chosen = text || String(fallback ?? '').replace(/\s+/g, ' ').trim();
121
+ return chosen.length > maxLen ? chosen.slice(0, maxLen - 1).trimEnd() + '…' : chosen;
122
+ }
123
+
124
+ function stripFrontMatter(content) {
125
+ if (!content.startsWith('---')) return content;
126
+ const lines = content.split(/\r?\n/);
127
+ if (lines[0].trim() !== '---') return content;
128
+ for (let i = 1; i < lines.length; i++) {
129
+ if (lines[i].trim() === '---') return lines.slice(i + 1).join('\n');
130
+ }
131
+ return content;
132
+ }
133
+
134
+ // YAML-ish scalar escaping for the flat `key: value` front-matter we emit.
135
+ // Double-quote and escape when the value could be misread (colons, leading
136
+ // specials, quotes). Numbers pass through bare.
137
+ function yamlScalar(value) {
138
+ if (typeof value === 'number') return String(value);
139
+ const s = String(value ?? '');
140
+ if (s === '') return '""';
141
+ if (/^[A-Za-z0-9][\w .\-/]*$/.test(s) && !/^\d/.test(s)) return s;
142
+ return `"${s.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
143
+ }
144
+
145
+ // Assemble the promoted document: front-matter + `# <question>` H1 (so the
146
+ // graph builder titles the node with the question) + the VERBATIM answer body
147
+ // + a provenance footer that links `./README.md` (a real graph edge, so
148
+ // `pa knowledge related` is non-empty). The answer body itself is untouched.
149
+ export function buildDocument({ manifest, counts, slug, date, description, answer }) {
150
+ const fm = [
151
+ '---',
152
+ `name: ${yamlScalar(slug)}`,
153
+ `title: ${yamlScalar(manifest.question)}`,
154
+ `description: ${yamlScalar(description)}`,
155
+ `domain: ${yamlScalar(RESEARCH_DOMAIN)}`,
156
+ `type: ${yamlScalar('research-session')}`,
157
+ `mode: ${yamlScalar(manifest.mode)}`,
158
+ `sessionId: ${yamlScalar(manifest.sessionId)}`,
159
+ `date: ${yamlScalar(date)}`,
160
+ `sourceCount: ${yamlScalar(counts.sourceCount)}`,
161
+ `verifiedCount: ${yamlScalar(counts.verifiedCount)}`,
162
+ `refutedCount: ${yamlScalar(counts.refutedCount)}`,
163
+ `unverifiedCount: ${yamlScalar(counts.unverifiedCount)}`,
164
+ `gatedCount: ${yamlScalar(counts.gatedCount)}`,
165
+ `question: ${yamlScalar(manifest.question)}`,
166
+ '---',
167
+ ].join('\n');
168
+
169
+ const footer = `*Promoted from research session \`${manifest.sessionId}\` (\`${manifest.mode}\` mode, ${date}). ` +
170
+ `Part of the [research knowledge library](./README.md).*`;
171
+
172
+ const body = String(answer ?? '').replace(/\s+$/, '');
173
+ return `${fm}\n\n# ${manifest.question}\n\n${body}\n\n---\n\n${footer}\n`;
174
+ }
175
+
176
+ // ── the write chokepoint ────────────────────────────────────────────────────────
177
+
178
+ // Promote a session's answer.md into the knowledge library. Reads via the
179
+ // injected `store`; writes exactly one file under `knowledgeDir/research/`.
180
+ //
181
+ // Returns a result object; NEVER throws for expected skips (missing answer,
182
+ // already promoted) so `mark done` still succeeds. `date` defaults to the
183
+ // manifest's updatedAt date (the mark-done timestamp).
184
+ //
185
+ // Callers guarantee: only invoked for status===done, mode in {normal,deep},
186
+ // and not when --no-promote / light (those decisions live in decidePromotion).
187
+ export async function promoteSession(id, { store, knowledgeDir } = {}) {
188
+ // Resolve the write target lazily: if the caller didn't inject one, walk
189
+ // to the operator repo root and land under operator/knowledge/. The same
190
+ // resolver `pa knowledge` uses — `$DAVE_REPO_ROOT` / `$PA_REPO_ROOT` /
191
+ // walk-up-for-`.git`.
192
+ if (!knowledgeDir) knowledgeDir = await defaultKnowledgeDir();
193
+ const manifest = await store.readManifest(id);
194
+
195
+ const answer = await store.readAnswer(id);
196
+ if (answer == null) {
197
+ return { status: 'skipped-no-answer', reason: `session ${id} has no answer.md — nothing to promote` };
198
+ }
199
+
200
+ const domainDir = join(knowledgeDir, RESEARCH_DOMAIN);
201
+ const fileName = promotedFileName(id, manifest.question);
202
+ const relPath = `operator/knowledge/${RESEARCH_DOMAIN}/${fileName}`;
203
+ const absPath = join(domainDir, fileName);
204
+
205
+ // Idempotency, derived from filesystem state (no manifest field — schema is
206
+ // frozen). Same session → same deterministic filename; if it already exists
207
+ // we do not re-write, so a re-promotion is a no-op.
208
+ if (existsSync(absPath)) {
209
+ return { status: 'already-promoted', path: relPath };
210
+ }
211
+
212
+ const sources = await store.readSources(id);
213
+ const gates = await store.readGates(id);
214
+ const findings = await store.listFindings(id);
215
+ const counts = deriveCounts({ sources, findings, gates });
216
+
217
+ const date = (manifest.updatedAt || manifest.createdAt || '').slice(0, 10);
218
+ const slug = slugify(manifest.question);
219
+ const description = firstParagraph(answer, manifest.question);
220
+ const doc = buildDocument({ manifest, counts, slug, date, description, answer });
221
+
222
+ await mkdir(domainDir, { recursive: true });
223
+ await writeFile(absPath, doc, 'utf8');
224
+
225
+ return { status: 'promoted', path: relPath, counts };
226
+ }
227
+
228
+ // ── promotion decision (pure) ───────────────────────────────────────────────────
229
+
230
+ // Decide what to do given the terminal transition + flags. Kept pure so the
231
+ // mark command is thin glue and the rules are unit-testable in isolation.
232
+ // light + promote → throw usage error (exit 1): light is NEVER promoted.
233
+ // light → skip-silent (the point of light is quiet lookups).
234
+ // normal/deep + noPromote → skip-note (log one line, still success).
235
+ // normal/deep → promote.
236
+ // status !== done → skip-silent (aborted et al. never promote).
237
+ export function decidePromotion({ mode, status, noPromote = false, promote = false }) {
238
+ if (mode === 'light') {
239
+ if (promote) {
240
+ throw Object.assign(
241
+ new Error('light-mode sessions are never promoted to the knowledge library (operator directive); --promote is not allowed on light mode'),
242
+ { exitCode: 1 },
243
+ );
244
+ }
245
+ return { action: 'skip-silent' };
246
+ }
247
+ if (status !== 'done') return { action: 'skip-silent' };
248
+ if (noPromote) return { action: 'skip-note' };
249
+ return { action: 'promote' };
250
+ }
251
+
252
+ // The one-line hint printed after a successful promotion. The knowledge graph
253
+ // is rebuilt by a 6-hourly reindex job (see the `Knowledge reindex` cron); it
254
+ // re-reads every doc in operator/knowledge/, so we do NOT shell into the
255
+ // version-pinned builder from here (brief §5: global side effects → hint, don't
256
+ // auto-run). There is no stable `pa knowledge rebuild` verb to call.
257
+ export function refreshHint(relPath) {
258
+ return `promoted to ${relPath} — rebuild the knowledge graph (knowledge-reindex cron, ` +
259
+ `or run the graph/index builders) so \`pa knowledge search\`/\`related\` surface it`;
260
+ }
@@ -0,0 +1,55 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "ai.stravica.knowledge.research/finding.schema.json",
4
+ "title": "Research finding",
5
+ "description": "One finding per sub-question, written by workers at sessions/<sessionId>/findings/sq-<id>.json. We read/validate them, workers write them. Validator: src/store/findings.mjs.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["subQuestionId", "summary", "quotes", "sources", "confidence", "verificationVotes", "unsourced"],
9
+ "properties": {
10
+ "subQuestionId": { "type": "string", "minLength": 1 },
11
+ "summary": { "type": "string", "description": "Synthesised answer to the sub-question." },
12
+ "quotes": {
13
+ "type": "array",
14
+ "description": "Direct supporting quotes, each tied to a source ref (build-spec §5 quote-grounded extraction).",
15
+ "items": {
16
+ "type": "object",
17
+ "additionalProperties": false,
18
+ "required": ["text", "sourceId"],
19
+ "properties": {
20
+ "text": { "type": "string", "minLength": 1 },
21
+ "sourceId": { "type": "string", "minLength": 1, "description": "References sources.json items[].id." },
22
+ "importance": { "type": "string", "enum": ["central", "supporting", "incidental"] }
23
+ }
24
+ }
25
+ },
26
+ "sources": {
27
+ "type": "array",
28
+ "items": { "type": "string" },
29
+ "description": "Source ids (sources.json items[].id) this finding draws on."
30
+ },
31
+ "confidence": {
32
+ "type": "string",
33
+ "enum": ["low", "medium", "high"],
34
+ "description": "Bucketed confidence. Buckets chosen over a 0..1 float — LLM self-scored floats are false precision."
35
+ },
36
+ "verificationVotes": {
37
+ "type": "array",
38
+ "description": "Verify outcomes (build-spec §4/§5). Empty in light mode. Three outcomes per vote.",
39
+ "items": {
40
+ "type": "object",
41
+ "additionalProperties": false,
42
+ "required": ["outcome"],
43
+ "properties": {
44
+ "outcome": { "type": "string", "enum": ["confirmed", "refuted", "unverified-infra"] },
45
+ "lens": { "type": "string", "description": "Verifier lens (deep diverse-lens: quote-support | contradiction-search | recency-source-fit)." },
46
+ "note": { "type": "string" }
47
+ }
48
+ }
49
+ },
50
+ "unsourced": {
51
+ "type": "boolean",
52
+ "description": "True if the finding carries claims without a supporting quote (build-spec §8 unsourced-claim counter)."
53
+ }
54
+ }
55
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "ai.stravica.knowledge.research/gates.schema.json",
4
+ "title": "Research human-gate queue",
5
+ "description": "gates.json at sessions/<sessionId>/gates.json — the retry queue for human-gated fetches (build-spec §6). Merges brief §3 status-tracking fields with spec §6 descriptive fields. Validator: src/store/gates.mjs.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["queue"],
9
+ "properties": {
10
+ "queue": {
11
+ "type": "array",
12
+ "items": {
13
+ "type": "object",
14
+ "additionalProperties": false,
15
+ "required": ["id", "url", "gateType", "whatIsNeeded", "status", "blockedAt"],
16
+ "properties": {
17
+ "id": { "type": "string", "minLength": 1, "description": "Gate record id (unique within the session)." },
18
+ "url": { "type": "string", "minLength": 1, "description": "The gated URL." },
19
+ "gateType": { "type": "string", "description": "e.g. cloudflare, captcha, auth, paywall." },
20
+ "subQuestionId": { "type": "string", "description": "Which sub-question was blocked, if known." },
21
+ "whatIsNeeded": { "type": "string", "description": "Human-readable what-is-needed-to-clear (spec §6). Also the brief's `reason`." },
22
+ "status": {
23
+ "type": "string",
24
+ "enum": ["pending", "retrying", "resolved", "failed"],
25
+ "description": "pending → retrying (marked eligible by `gates --retry`) → resolved/failed."
26
+ },
27
+ "blockedAt": { "type": "string", "description": "ISO 8601 UTC when the gate was hit (spec's loggedAt)." },
28
+ "resolution": { "type": "string", "description": "Note or outcome once resolved/failed." },
29
+ "artifactPath": { "type": "string", "description": "Path to the saved page content (sessions/<id>/gated/<hash>.md, spec §6.4)." }
30
+ }
31
+ }
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,59 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "ai.stravica.knowledge.research/manifest.schema.json",
4
+ "title": "Research session manifest",
5
+ "description": "Root manifest.json for a research session, at sessions/<sessionId>/manifest.json. Hand-rolled validator: src/store/manifest.mjs. camelCase throughout.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "sessionId",
10
+ "mode",
11
+ "question",
12
+ "gatePolicy",
13
+ "status",
14
+ "outputMode",
15
+ "budget",
16
+ "assumptions",
17
+ "createdAt",
18
+ "updatedAt"
19
+ ],
20
+ "properties": {
21
+ "sessionId": {
22
+ "type": "string",
23
+ "description": "ULID-like 26-char Crockford base32 id: 10-char ms timestamp + 16-char entropy. Lexicographically sortable by creation time.",
24
+ "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
25
+ },
26
+ "mode": { "type": "string", "enum": ["light", "normal", "deep"] },
27
+ "question": { "type": "string", "minLength": 1, "description": "Raw operator question." },
28
+ "intent": { "type": "string", "description": "Clarified intent, if the caller passed one." },
29
+ "gatePolicy": {
30
+ "type": "string",
31
+ "enum": ["operatorPresent", "background", "worker"],
32
+ "description": "Human-gate execution posture (build-spec §6)."
33
+ },
34
+ "status": { "type": "string", "enum": ["draft", "in-progress", "done", "aborted"] },
35
+ "outputMode": {
36
+ "type": "string",
37
+ "enum": ["shortAnswer", "article", "structured"],
38
+ "description": "Synthesis render target. Defaults to shortAnswer."
39
+ },
40
+ "budget": {
41
+ "type": "object",
42
+ "description": "Records what the run was scoped to. Not enforced by the CLI.",
43
+ "additionalProperties": false,
44
+ "required": ["maxSubQuestions", "maxDeepeningRounds", "wallClockMinutes"],
45
+ "properties": {
46
+ "maxSubQuestions": { "type": "integer", "minimum": 0 },
47
+ "maxDeepeningRounds": { "type": "integer", "minimum": 0 },
48
+ "wallClockMinutes": { "type": "integer", "minimum": 0 }
49
+ }
50
+ },
51
+ "assumptions": {
52
+ "type": "array",
53
+ "items": { "type": "string" },
54
+ "description": "Scope-narrowing assumptions recorded when a background run cannot clarify (build-spec §4)."
55
+ },
56
+ "createdAt": { "type": "string", "description": "ISO 8601 UTC." },
57
+ "updatedAt": { "type": "string", "description": "ISO 8601 UTC." }
58
+ }
59
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "ai.stravica.knowledge.research/plan.schema.json",
4
+ "title": "Research plan",
5
+ "description": "plan.json at sessions/<sessionId>/plan.json. `run` writes a skeleton (empty subQuestions, mode-derived rounds/tier); the workflow (w-017) fills subQuestions. Validator: src/store/plan.mjs.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["subQuestions", "deepeningRounds", "verificationTier"],
9
+ "properties": {
10
+ "subQuestions": {
11
+ "type": "array",
12
+ "description": "Dependency-classified decomposition (build-spec §4). Empty until the planner fills it.",
13
+ "items": {
14
+ "type": "object",
15
+ "additionalProperties": false,
16
+ "required": ["id", "text", "kind", "dependsOn"],
17
+ "properties": {
18
+ "id": { "type": "string", "minLength": 1 },
19
+ "text": { "type": "string", "minLength": 1 },
20
+ "kind": { "type": "string", "enum": ["independent", "dependent"] },
21
+ "dependsOn": {
22
+ "type": "array",
23
+ "items": { "type": "string" },
24
+ "description": "Sub-question ids this one depends on. Empty for independent facets."
25
+ }
26
+ }
27
+ }
28
+ },
29
+ "deepeningRounds": {
30
+ "type": "integer",
31
+ "minimum": 0,
32
+ "maximum": 3,
33
+ "description": "0 for light, 1 for normal, up to 3 for deep."
34
+ },
35
+ "verificationTier": {
36
+ "type": "string",
37
+ "enum": ["none", "central-3vote", "diverse-lens-3vote"],
38
+ "description": "none (light), central-3vote (normal), diverse-lens-3vote (deep)."
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "ai.stravica.knowledge.research/sources.schema.json",
4
+ "title": "Research sources",
5
+ "description": "Aggregated source registry at sessions/<sessionId>/sources.json. One entry per fetched source; finding.sources[] and quote.sourceId reference items[].id. Validator: src/store/sources.mjs.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["items"],
9
+ "properties": {
10
+ "items": {
11
+ "type": "array",
12
+ "items": {
13
+ "type": "object",
14
+ "additionalProperties": false,
15
+ "required": ["id", "kind"],
16
+ "properties": {
17
+ "id": { "type": "string", "minLength": 1, "description": "Stable id referenced by findings." },
18
+ "kind": {
19
+ "type": "string",
20
+ "enum": ["web", "playwright", "kb", "codebase", "prior-session"],
21
+ "description": "Source capability (build-spec §2/§3)."
22
+ },
23
+ "url": { "type": "string" },
24
+ "title": { "type": "string" },
25
+ "fetchedAt": { "type": "string", "description": "ISO 8601 UTC." },
26
+ "checksum": { "type": "string", "description": "Optional content hash for dedup/change-detection." }
27
+ }
28
+ }
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,61 @@
1
+ // finding.json schema + validator (build-spec §5). Zero-dep, hand-rolled.
2
+ // Workers write findings/sq-<id>.json; we read + validate them. We never write findings.
3
+ // Schema doc: src/schema/finding.schema.json.
4
+ import {
5
+ parseJson, requireObject, requireFields, noExtraFields,
6
+ requireString, optionalString, requireEnum, optionalEnum, requireArray, requireBoolean, fail,
7
+ } from './validate.mjs';
8
+
9
+ export const CONFIDENCE = ['low', 'medium', 'high'];
10
+ export const IMPORTANCE = ['central', 'supporting', 'incidental'];
11
+ export const VOTE_OUTCOMES = ['confirmed', 'refuted', 'unverified-infra'];
12
+
13
+ const TOP = ['subQuestionId', 'summary', 'quotes', 'sources', 'confidence', 'verificationVotes', 'unsourced'];
14
+ const QUOTE_FIELDS = ['text', 'sourceId', 'importance'];
15
+ const QUOTE_REQUIRED = ['text', 'sourceId'];
16
+ const VOTE_FIELDS = ['outcome', 'lens', 'note'];
17
+
18
+ export function loadFinding(text, where = 'finding') {
19
+ return validateFinding(parseJson(text, where), where);
20
+ }
21
+
22
+ export function validateFinding(f, where = 'finding') {
23
+ requireObject(f, where);
24
+ requireFields(f, TOP, where);
25
+ noExtraFields(f, TOP, where);
26
+
27
+ requireString(f, 'subQuestionId', where);
28
+ requireString(f, 'summary', where, { nonEmpty: false });
29
+
30
+ const quotes = requireArray(f, 'quotes', where);
31
+ quotes.forEach((q, i) => {
32
+ const w = `${where}.quotes[${i}]`;
33
+ requireObject(q, w);
34
+ requireFields(q, QUOTE_REQUIRED, w);
35
+ noExtraFields(q, QUOTE_FIELDS, w);
36
+ requireString(q, 'text', w);
37
+ requireString(q, 'sourceId', w);
38
+ optionalEnum(q, 'importance', IMPORTANCE, w);
39
+ });
40
+
41
+ const sources = requireArray(f, 'sources', where);
42
+ sources.forEach((s, i) => {
43
+ if (typeof s !== 'string') fail(`sources[${i}] must be a string (source id)`, where);
44
+ });
45
+
46
+ requireEnum(f, 'confidence', CONFIDENCE, where);
47
+
48
+ const votes = requireArray(f, 'verificationVotes', where);
49
+ votes.forEach((v, i) => {
50
+ const w = `${where}.verificationVotes[${i}]`;
51
+ requireObject(v, w);
52
+ requireFields(v, ['outcome'], w);
53
+ noExtraFields(v, VOTE_FIELDS, w);
54
+ requireEnum(v, 'outcome', VOTE_OUTCOMES, w);
55
+ optionalString(v, 'lens', w);
56
+ optionalString(v, 'note', w);
57
+ });
58
+
59
+ requireBoolean(f, 'unsourced', where);
60
+ return f;
61
+ }
@@ -0,0 +1,73 @@
1
+ // gates.json schema + validator + pure queue transforms (build-spec §6). Zero-dep.
2
+ // Schema doc: src/schema/gates.schema.json.
3
+ //
4
+ // Disk persistence for gates lives in store/index.mjs (the write chokepoint).
5
+ // This module owns the schema, validation, and PURE transforms only — nothing
6
+ // here touches the filesystem, so `gates --retry` composes read (index) →
7
+ // transform (here) → write (index).
8
+ import {
9
+ parseJson, requireObject, requireFields, noExtraFields,
10
+ requireString, optionalString, requireEnum, requireArray, fail,
11
+ } from './validate.mjs';
12
+
13
+ export const GATE_STATUSES = ['pending', 'retrying', 'resolved', 'failed'];
14
+
15
+ const TOP = ['queue'];
16
+ const ITEM_FIELDS = ['id', 'url', 'gateType', 'subQuestionId', 'whatIsNeeded', 'status', 'blockedAt', 'resolution', 'artifactPath'];
17
+ const ITEM_REQUIRED = ['id', 'url', 'gateType', 'whatIsNeeded', 'status', 'blockedAt'];
18
+
19
+ export function emptyGates() {
20
+ return { queue: [] };
21
+ }
22
+
23
+ export function loadGates(text, where = 'gates') {
24
+ return validateGates(parseJson(text, where), where);
25
+ }
26
+
27
+ export function validateGates(g, where = 'gates') {
28
+ requireObject(g, where);
29
+ requireFields(g, TOP, where);
30
+ noExtraFields(g, TOP, where);
31
+
32
+ const queue = requireArray(g, 'queue', where);
33
+ const seen = new Set();
34
+ queue.forEach((it, i) => {
35
+ const w = `${where}.queue[${i}]`;
36
+ requireObject(it, w);
37
+ requireFields(it, ITEM_REQUIRED, w);
38
+ noExtraFields(it, ITEM_FIELDS, w);
39
+ const id = requireString(it, 'id', w);
40
+ if (seen.has(id)) fail(`duplicate gate id "${id}"`, w);
41
+ seen.add(id);
42
+ requireString(it, 'url', w);
43
+ requireString(it, 'gateType', w);
44
+ optionalString(it, 'subQuestionId', w);
45
+ requireString(it, 'whatIsNeeded', w);
46
+ requireEnum(it, 'status', GATE_STATUSES, w);
47
+ requireString(it, 'blockedAt', w);
48
+ optionalString(it, 'resolution', w);
49
+ optionalString(it, 'artifactPath', w);
50
+ });
51
+ return g;
52
+ }
53
+
54
+ // A gate item is eligible for retry when it is still pending or already retrying
55
+ // (idempotent re-mark). Resolved/failed items are terminal and left untouched.
56
+ export function isRetryEligible(item) {
57
+ return item.status === 'pending' || item.status === 'retrying';
58
+ }
59
+
60
+ // PURE: return a new gates object with all eligible items marked `retrying`,
61
+ // plus the list of items that were (re)marked. Does not mutate the input.
62
+ export function markEligibleForRetry(gates) {
63
+ const marked = [];
64
+ const queue = gates.queue.map((it) => {
65
+ if (isRetryEligible(it)) {
66
+ const next = { ...it, status: 'retrying' };
67
+ marked.push(next);
68
+ return next;
69
+ }
70
+ return it;
71
+ });
72
+ return { gates: { ...gates, queue }, marked };
73
+ }