@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,446 @@
1
+ // eval.mjs — `pa knowledge eval` retrieval-quality harness.
2
+ //
3
+ // Purpose (Deliverable B, w-2026-07-06-020): turn "the right doc at the
4
+ // right time" from an unmeasured quantity into a scored, trend-lined,
5
+ // scheduled signal. Every case runs through the SAME code path as
6
+ // interactive search (post-Deliverable-A cascade included), so the
7
+ // numbers describe what an operator or agent would actually see.
8
+ //
9
+ // Set: operator/knowledge/_meta/retrieval-evals.json
10
+ // Runs: operator/knowledge/_meta/retrieval-eval-runs/<isoUtc>.json
11
+ //
12
+ // Case shape:
13
+ // { id, query, expectedDocs: string[], matchMode: 'any'|'all', notes? }
14
+ //
15
+ // Scoring:
16
+ // hit@1 — matchMode 'any': ≥1 expected doc is at position 1 in results
17
+ // matchMode 'all': every expected doc is at position 1 (only
18
+ // valid for single-expected-doc cases; multi-doc always false)
19
+ // hit@5 — same rule, top-5 window
20
+ // miss — hit@5 false
21
+ //
22
+ // Determinism: the search cascade is deterministic (stable sort by score,
23
+ // edge count, id). Same eval set + same graph = same scores.
24
+ //
25
+ // Orphan gauge runs in the same pass — total + per-domain, delta vs last
26
+ // run, warnings when growth > 10 or any domain is 100% orphaned. The
27
+ // gauge is a load-bearing hygiene signal, but never fails the run — it
28
+ // tags the summary and boot-context renders the tag.
29
+ //
30
+ // Exit codes (tooling standard §6):
31
+ // 0 ok
32
+ // 1 usage error / eval set malformed / --strict-cases and any case missed
33
+ // 2 no eval set present (informational — set is authored operator-side)
34
+ // 3 IO failure (write run file)
35
+
36
+ import { readFile, readdir, writeFile, mkdir } from 'node:fs/promises';
37
+ import { existsSync } from 'node:fs';
38
+ import { join, resolve } from 'node:path';
39
+
40
+ import { getRepoRoot, loadGraph, searchCascade, orphans, uniqueDomains } from './graph.mjs';
41
+
42
+ const EVAL_SET_PATH = 'operator/knowledge/_meta/retrieval-evals.json';
43
+ const RUNS_DIR = 'operator/knowledge/_meta/retrieval-eval-runs';
44
+ const DEFAULT_ORPHAN_GROWTH_ALARM = 10;
45
+
46
+ const USAGE = `pa knowledge eval — retrieval-quality harness
47
+
48
+ Usage:
49
+ pa knowledge eval [--fixture <path>] [--out <dir>] [--full] [--format json|line|table]
50
+ [--strict-cases] [--no-write] [--limit N]
51
+ pa knowledge eval --help
52
+
53
+ Reads the eval set at operator/knowledge/_meta/retrieval-evals.json (or
54
+ --fixture for tests), runs each case through the SAME search cascade as
55
+ interactive callers, scores hit@1 / hit@5 / miss, computes the orphan
56
+ hygiene gauge, and writes a run file under
57
+ operator/knowledge/_meta/retrieval-eval-runs/.
58
+
59
+ Flags:
60
+ --fixture <path> Alternate eval-set path (used by tests)
61
+ --out <dir> Alternate runs directory (used by tests)
62
+ --full Run each search with --full (body scan)
63
+ --format json|line|table Output shape (default: line — the workState summary)
64
+ --strict-cases Exit 1 if any case misses hit@5
65
+ --no-write Skip persisting the run file
66
+ --limit N Only run the first N cases (dev convenience)
67
+ `;
68
+
69
+ export async function run(argv) {
70
+ const { flags, positional } = parseFlags(argv);
71
+ if (flags.help === true || flags.h === true) {
72
+ process.stdout.write(USAGE);
73
+ return 0;
74
+ }
75
+ if (positional.length > 0) {
76
+ process.stderr.write(`pa knowledge eval: unexpected arguments: ${positional.join(' ')}\n`);
77
+ process.stderr.write(USAGE);
78
+ return 1;
79
+ }
80
+ const format = resolveFormat(flags.format);
81
+
82
+ let repoRoot;
83
+ try {
84
+ repoRoot = await getRepoRoot();
85
+ } catch (err) {
86
+ process.stderr.write(`pa knowledge eval: ${err.message}\n`);
87
+ return err.exitCode ?? 2;
88
+ }
89
+
90
+ const evalSetPath = flags.fixture ? resolve(String(flags.fixture)) : join(repoRoot, EVAL_SET_PATH);
91
+ const runsDir = flags.out ? resolve(String(flags.out)) : join(repoRoot, RUNS_DIR);
92
+
93
+ const setLoad = await loadEvalSet(evalSetPath);
94
+ if (setLoad.status === 'missing') {
95
+ process.stderr.write(
96
+ `pa knowledge eval: no eval set at ${evalSetPath}\n` +
97
+ `\n` +
98
+ `Seed one by dropping a JSON file at that path with the shape:\n` +
99
+ ` { "version": "1.0",\n` +
100
+ ` "cases": [\n` +
101
+ ` { "id": "case-01", "query": "worktree isolation concurrent write workers",\n` +
102
+ ` "expectedDocs": ["operator/knowledge/…/worktree-isolation.md"],\n` +
103
+ ` "matchMode": "any", "notes": "audit case, 2026-07-06" }\n` +
104
+ ` ] }\n`,
105
+ );
106
+ return 2;
107
+ }
108
+ if (setLoad.status === 'malformed') {
109
+ process.stderr.write(`pa knowledge eval: eval set malformed at ${evalSetPath}: ${setLoad.error}\n`);
110
+ return 1;
111
+ }
112
+ const evalSet = setLoad.data;
113
+
114
+ let graph;
115
+ try {
116
+ graph = await loadGraph({ repoRoot });
117
+ } catch (err) {
118
+ process.stderr.write(`pa knowledge eval: ${err.message}\n`);
119
+ return err.exitCode ?? 3;
120
+ }
121
+
122
+ const nodeById = new Map(graph.nodes.map((n) => [n.id, n]));
123
+ const limit = Number.isInteger(Number(flags.limit)) ? Number(flags.limit) : evalSet.cases.length;
124
+ const full = flags.full === true;
125
+
126
+ const cases = [];
127
+ for (const c of evalSet.cases.slice(0, limit)) {
128
+ const validation = validateCase(c);
129
+ if (validation) {
130
+ process.stderr.write(`pa knowledge eval: invalid case: ${validation}\n`);
131
+ return 1;
132
+ }
133
+ const envelope = await searchCascade(graph, c.query, { full, repoRoot });
134
+ const topIds = envelope.results.map((r) => r.id);
135
+ const scored = scoreCase(c, topIds);
136
+ cases.push({
137
+ id: c.id,
138
+ query: c.query,
139
+ expectedDocs: c.expectedDocs.slice(),
140
+ matchMode: c.matchMode,
141
+ notes: c.notes ?? null,
142
+ mode: envelope.mode,
143
+ hit1: scored.hit1,
144
+ hit5: scored.hit5,
145
+ miss: scored.miss,
146
+ topResults: topIds.slice(0, 5),
147
+ expectedDocsPresent: expectedDocsPresent(c, topIds),
148
+ // Cases that reference a doc missing from the graph are the canonical
149
+ // regression signal (spec §Acceptance: "renamed doc caught on next
150
+ // run"). We flag it in each case so callers can distinguish a search
151
+ // miss from a stale eval reference.
152
+ expectedDocsMissingFromGraph: c.expectedDocs.filter((d) => !nodeById.has(d)),
153
+ });
154
+ }
155
+
156
+ const summary = summarise(cases);
157
+ const orphanGauge = computeOrphanGauge(graph);
158
+
159
+ const runId = new Date().toISOString().replace(/[:.]/g, '-').replace(/Z$/, '');
160
+ const generatedAt = new Date().toISOString();
161
+
162
+ let previousRun = null;
163
+ try {
164
+ previousRun = await readLatestRun(runsDir);
165
+ } catch { /* first-run friendly */ }
166
+
167
+ const delta = computeDelta(summary, orphanGauge, previousRun);
168
+ const alarms = buildAlarms(orphanGauge, delta);
169
+
170
+ const runFile = {
171
+ version: '1.0',
172
+ runId,
173
+ generatedAt,
174
+ graph: {
175
+ generatedAt: graph.generatedAt ?? null,
176
+ nodeCount: graph.nodes.length,
177
+ edgeCount: graph.edges.length,
178
+ },
179
+ cases,
180
+ summary,
181
+ orphans: orphanGauge,
182
+ delta,
183
+ alarms,
184
+ workStateLine: renderWorkStateLine(summary, orphanGauge, delta, alarms),
185
+ };
186
+
187
+ if (!(flags['no-write'] === true)) {
188
+ try {
189
+ await mkdir(runsDir, { recursive: true });
190
+ await writeFile(join(runsDir, runId + '.json'), JSON.stringify(runFile, null, 2) + '\n', 'utf8');
191
+ } catch (err) {
192
+ process.stderr.write(`pa knowledge eval: could not write run file: ${err.message}\n`);
193
+ return 3;
194
+ }
195
+ }
196
+
197
+ emit(runFile, format);
198
+
199
+ if (flags['strict-cases'] === true && summary.miss.count > 0) return 1;
200
+ return 0;
201
+ }
202
+
203
+ // --- eval-set loading -----------------------------------------------------
204
+
205
+ async function loadEvalSet(path) {
206
+ if (!existsSync(path)) return { status: 'missing' };
207
+ let raw;
208
+ try {
209
+ raw = await readFile(path, 'utf8');
210
+ } catch (e) {
211
+ return { status: 'malformed', error: e.message };
212
+ }
213
+ let json;
214
+ try {
215
+ json = JSON.parse(raw);
216
+ } catch (e) {
217
+ return { status: 'malformed', error: 'invalid JSON: ' + e.message };
218
+ }
219
+ if (!json || !Array.isArray(json.cases)) {
220
+ return { status: 'malformed', error: 'expected { cases: [...] }' };
221
+ }
222
+ return { status: 'ok', data: json };
223
+ }
224
+
225
+ function validateCase(c) {
226
+ if (!c || typeof c !== 'object') return 'case is not an object';
227
+ if (!c.id || typeof c.id !== 'string') return 'case.id missing or not a string';
228
+ if (!c.query || typeof c.query !== 'string') return `case ${c.id}: query missing or not a string`;
229
+ if (!Array.isArray(c.expectedDocs) || c.expectedDocs.length === 0) {
230
+ return `case ${c.id}: expectedDocs must be a non-empty array`;
231
+ }
232
+ if (c.expectedDocs.some((d) => typeof d !== 'string')) {
233
+ return `case ${c.id}: expectedDocs must be strings`;
234
+ }
235
+ if (c.matchMode !== 'any' && c.matchMode !== 'all') {
236
+ return `case ${c.id}: matchMode must be 'any' or 'all'`;
237
+ }
238
+ return null;
239
+ }
240
+
241
+ // --- scoring --------------------------------------------------------------
242
+
243
+ function scoreCase(c, topIds) {
244
+ const top1 = topIds.slice(0, 1);
245
+ const top5 = topIds.slice(0, 5);
246
+ const expected = new Set(c.expectedDocs);
247
+ if (c.matchMode === 'all') {
248
+ // All-mode is strict — every expected doc must sit inside the window.
249
+ const inTop1 = c.expectedDocs.every((d) => top1.includes(d));
250
+ const inTop5 = c.expectedDocs.every((d) => top5.includes(d));
251
+ return { hit1: inTop1, hit5: inTop5, miss: !inTop5 };
252
+ }
253
+ // matchMode 'any': at least one expected doc present.
254
+ const inTop1 = top1.some((d) => expected.has(d));
255
+ const inTop5 = top5.some((d) => expected.has(d));
256
+ return { hit1: inTop1, hit5: inTop5, miss: !inTop5 };
257
+ }
258
+
259
+ function expectedDocsPresent(c, topIds) {
260
+ const expected = new Set(c.expectedDocs);
261
+ return topIds.filter((d) => expected.has(d));
262
+ }
263
+
264
+ function summarise(cases) {
265
+ const total = cases.length;
266
+ const h1 = cases.filter((c) => c.hit1).length;
267
+ const h5 = cases.filter((c) => c.hit5).length;
268
+ const miss = cases.filter((c) => c.miss).length;
269
+ const byDomain = {};
270
+ for (const c of cases) {
271
+ const bucket = domainForCase(c);
272
+ if (!byDomain[bucket]) byDomain[bucket] = { total: 0, hit1: 0, hit5: 0, miss: 0 };
273
+ byDomain[bucket].total += 1;
274
+ if (c.hit1) byDomain[bucket].hit1 += 1;
275
+ if (c.hit5) byDomain[bucket].hit5 += 1;
276
+ if (c.miss) byDomain[bucket].miss += 1;
277
+ }
278
+ return {
279
+ total,
280
+ hit1: { count: h1, percentage: pct(h1, total) },
281
+ hit5: { count: h5, percentage: pct(h5, total) },
282
+ miss: { count: miss, percentage: pct(miss, total) },
283
+ byDomain,
284
+ };
285
+ }
286
+
287
+ function domainForCase(c) {
288
+ // Bucket a case by the domain of its FIRST expected doc's path — reads
289
+ // `operator/knowledge/<domain>/…`. Bare-slug expected docs bucket to
290
+ // `<none>`. This is a heuristic; it's fine because per-domain recall is
291
+ // an operator-facing eyeball metric, not a hard promotion gate.
292
+ const first = c.expectedDocs?.[0];
293
+ if (!first) return '<none>';
294
+ const m = /^operator\/knowledge\/([^/]+)/.exec(first);
295
+ return m ? m[1] : '<none>';
296
+ }
297
+
298
+ function pct(n, d) {
299
+ if (!d) return 0;
300
+ return Math.round((n / d) * 100);
301
+ }
302
+
303
+ // --- orphan gauge ---------------------------------------------------------
304
+
305
+ function computeOrphanGauge(graph) {
306
+ const results = orphans(graph, { includeStubs: true });
307
+ const total = results.length;
308
+ const byDomain = {};
309
+ for (const r of results) {
310
+ const d = r.domain ?? '<none>';
311
+ byDomain[d] = (byDomain[d] ?? 0) + 1;
312
+ }
313
+ // Include totals-per-domain so we can flag domains that are 100% orphaned.
314
+ const domainTotals = {};
315
+ for (const n of graph.nodes) {
316
+ const d = n.domain ?? '<none>';
317
+ domainTotals[d] = (domainTotals[d] ?? 0) + 1;
318
+ }
319
+ const perDomain = {};
320
+ for (const d of uniqueDomains(graph)) {
321
+ perDomain[d] = { orphans: byDomain[d] ?? 0, total: domainTotals[d] ?? 0 };
322
+ }
323
+ if (byDomain['<none>'] != null) {
324
+ perDomain['<none>'] = { orphans: byDomain['<none>'], total: domainTotals['<none>'] ?? 0 };
325
+ }
326
+ return { total, byDomain: perDomain };
327
+ }
328
+
329
+ // --- delta + alarms -------------------------------------------------------
330
+
331
+ async function readLatestRun(runsDir) {
332
+ if (!existsSync(runsDir)) return null;
333
+ const entries = await readdir(runsDir);
334
+ const files = entries.filter((n) => n.endsWith('.json')).sort();
335
+ if (!files.length) return null;
336
+ const raw = await readFile(join(runsDir, files[files.length - 1]), 'utf8');
337
+ try { return JSON.parse(raw); } catch { return null; }
338
+ }
339
+
340
+ function computeDelta(summary, orphanGauge, previous) {
341
+ if (!previous || !previous.summary || !previous.orphans) {
342
+ return { firstRun: true, hit5PercentagePointsDelta: 0, orphanCountDelta: 0 };
343
+ }
344
+ const prevH5 = previous.summary.hit5?.percentage ?? 0;
345
+ const prevOrphans = previous.orphans.total ?? 0;
346
+ return {
347
+ firstRun: false,
348
+ hit5PercentagePointsDelta: summary.hit5.percentage - prevH5,
349
+ orphanCountDelta: orphanGauge.total - prevOrphans,
350
+ };
351
+ }
352
+
353
+ function buildAlarms(orphanGauge, delta) {
354
+ const alarms = [];
355
+ if (!delta.firstRun && delta.orphanCountDelta > DEFAULT_ORPHAN_GROWTH_ALARM) {
356
+ alarms.push(`orphans grew by ${delta.orphanCountDelta} since last run (threshold ${DEFAULT_ORPHAN_GROWTH_ALARM})`);
357
+ }
358
+ for (const [domain, counts] of Object.entries(orphanGauge.byDomain)) {
359
+ if (counts.total > 0 && counts.orphans === counts.total) {
360
+ alarms.push(`${domain} domain is 100% orphaned (${counts.total} node${counts.total === 1 ? '' : 's'})`);
361
+ }
362
+ }
363
+ return alarms;
364
+ }
365
+
366
+ // --- render ---------------------------------------------------------------
367
+
368
+ function renderWorkStateLine(summary, orphanGauge, delta, alarms) {
369
+ const hit5 = summary.hit5.percentage;
370
+ const deltaTag = delta.firstRun
371
+ ? '(first run)'
372
+ : `(${delta.hit5PercentagePointsDelta > 0 ? '+' : ''}${delta.hit5PercentagePointsDelta})`;
373
+ const orphanTag = delta.firstRun
374
+ ? ''
375
+ : ` (${delta.orphanCountDelta > 0 ? '+' : ''}${delta.orphanCountDelta})`;
376
+ const alarmTag = alarms.length > 0 ? ` ⚠ ${alarms.length} alarm${alarms.length === 1 ? '' : 's'}` : '';
377
+ return `retrievalEval: hit@5 ${hit5}% ${deltaTag} | orphans ${orphanGauge.total}${orphanTag}${alarmTag}`;
378
+ }
379
+
380
+ function emit(runFile, format) {
381
+ if (format === 'json') {
382
+ process.stdout.write(JSON.stringify(runFile, null, 2) + '\n');
383
+ return;
384
+ }
385
+ if (format === 'line') {
386
+ process.stdout.write(runFile.workStateLine + '\n');
387
+ return;
388
+ }
389
+ // table
390
+ const s = runFile.summary;
391
+ const lines = [];
392
+ lines.push(`Retrieval eval — ${runFile.cases.length} case${runFile.cases.length === 1 ? '' : 's'} — run ${runFile.runId}`);
393
+ lines.push('');
394
+ lines.push(`hit@1: ${s.hit1.count}/${s.total} (${s.hit1.percentage}%)`);
395
+ lines.push(`hit@5: ${s.hit5.count}/${s.total} (${s.hit5.percentage}%)`);
396
+ lines.push(`miss : ${s.miss.count}/${s.total} (${s.miss.percentage}%)`);
397
+ if (runFile.delta && !runFile.delta.firstRun) {
398
+ const sign = runFile.delta.hit5PercentagePointsDelta > 0 ? '+' : '';
399
+ lines.push(`Δhit@5: ${sign}${runFile.delta.hit5PercentagePointsDelta}pp vs last run`);
400
+ }
401
+ lines.push('');
402
+ lines.push(`Orphans: ${runFile.orphans.total}`);
403
+ if (runFile.delta && !runFile.delta.firstRun) {
404
+ const sign = runFile.delta.orphanCountDelta > 0 ? '+' : '';
405
+ lines.push(`Δorphans: ${sign}${runFile.delta.orphanCountDelta} vs last run`);
406
+ }
407
+ if (runFile.alarms.length > 0) {
408
+ lines.push('');
409
+ lines.push('Alarms:');
410
+ for (const a of runFile.alarms) lines.push(` - ${a}`);
411
+ }
412
+ lines.push('');
413
+ lines.push(runFile.workStateLine);
414
+ process.stdout.write(lines.join('\n') + '\n');
415
+ }
416
+
417
+ // --- shared bits ----------------------------------------------------------
418
+
419
+ function parseFlags(args) {
420
+ const flags = {};
421
+ const positional = [];
422
+ for (let i = 0; i < args.length; i++) {
423
+ const a = args[i];
424
+ if (a === '-h' || a === '--help') { flags.help = true; continue; }
425
+ if (a.startsWith('--')) {
426
+ const key = a.slice(2);
427
+ const peek = args[i + 1];
428
+ if (peek == null || peek.startsWith('--')) { flags[key] = true; }
429
+ else { flags[key] = peek; i += 1; }
430
+ } else {
431
+ positional.push(a);
432
+ }
433
+ }
434
+ return { flags, positional };
435
+ }
436
+
437
+ function resolveFormat(raw) {
438
+ if (raw == null || raw === true) return 'line';
439
+ if (raw === 'json' || raw === 'line' || raw === 'table') return raw;
440
+ const err = new Error(`unknown --format: ${raw} (expected json | line | table)`);
441
+ err.exitCode = 1;
442
+ throw err;
443
+ }
444
+
445
+ // Test seams.
446
+ export const _internals = { scoreCase, summarise, computeOrphanGauge, buildAlarms, renderWorkStateLine, computeDelta };