create-egregore 0.20.2 → 0.21.0-runtime-mvp.2

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 (706) hide show
  1. package/assets/egregore-launcher.js +1013 -16
  2. package/bin/cli.js +11 -0
  3. package/lib/claude-runtime.js +192 -0
  4. package/lib/local.js +38 -31
  5. package/lib/pi-runtime.js +1 -0
  6. package/lib/prime-runtime.js +1 -0
  7. package/lib/runtime-identity.js +146 -0
  8. package/lib/setup.js +116 -17
  9. package/package.json +10 -6
  10. package/runtime/claude/.claude/context/commit-format.md +110 -0
  11. package/runtime/claude/.claude/context/git-language.md +46 -0
  12. package/runtime/claude/.claude/context/notification-consent.md +66 -0
  13. package/runtime/claude/.claude/context/pr-format.md +67 -0
  14. package/runtime/claude/.claude/context/telemetry.md +133 -0
  15. package/runtime/claude/.claude/hooks/boundary-check.sh +333 -0
  16. package/runtime/claude/.claude/hooks/branch-guard.sh +231 -0
  17. package/runtime/claude/.claude/hooks/card-context.sh +38 -0
  18. package/runtime/claude/.claude/hooks/emissary-detect.sh +53 -0
  19. package/runtime/claude/.claude/hooks/memory-refresh.sh +67 -0
  20. package/runtime/claude/.claude/hooks/onboarding-guard.sh +86 -0
  21. package/runtime/claude/.claude/hooks/retrieval-context.sh +43 -0
  22. package/runtime/claude/.claude/rules/voice-bedrock.md +73 -0
  23. package/runtime/claude/.claude/settings.json +131 -0
  24. package/runtime/claude/.claude/skills/activity/SKILL.md +68 -0
  25. package/runtime/claude/.claude/skills/announce/SKILL.md +54 -0
  26. package/runtime/claude/.claude/skills/archive/SKILL.md +71 -0
  27. package/runtime/claude/.claude/skills/branch/SKILL.md +147 -0
  28. package/runtime/claude/.claude/skills/checkup/SKILL.md +159 -0
  29. package/runtime/claude/.claude/skills/commit/SKILL.md +103 -0
  30. package/runtime/claude/.claude/skills/contribute/SKILL.md +343 -0
  31. package/runtime/claude/.claude/skills/create-skill/SKILL.md +135 -0
  32. package/runtime/claude/.claude/skills/dark-mode/SKILL.md +410 -0
  33. package/runtime/claude/.claude/skills/dashboard/SKILL.md +43 -0
  34. package/runtime/claude/.claude/skills/deep-reflect/REPORT.md +140 -0
  35. package/runtime/claude/.claude/skills/deep-reflect/RESEARCH.md +132 -0
  36. package/runtime/claude/.claude/skills/deep-reflect/ROLES.md +104 -0
  37. package/runtime/claude/.claude/skills/deep-reflect/SKILL.md +170 -0
  38. package/runtime/claude/.claude/skills/delete-user/SKILL.md +150 -0
  39. package/runtime/claude/.claude/skills/emissary/SKILL.md +220 -0
  40. package/runtime/claude/.claude/skills/handoff/SKILL.md +124 -0
  41. package/runtime/claude/.claude/skills/harvest/AUDIT.md +546 -0
  42. package/runtime/claude/.claude/skills/harvest/FORMAT.md +436 -0
  43. package/runtime/claude/.claude/skills/harvest/PROCESS.md +395 -0
  44. package/runtime/claude/.claude/skills/harvest/QUESTION_PALETTE.md +76 -0
  45. package/runtime/claude/.claude/skills/harvest/SKILL.md +100 -0
  46. package/runtime/claude/.claude/skills/ingest/SKILL.md +112 -0
  47. package/runtime/claude/.claude/skills/ingest-corpus/SKILL.md +187 -0
  48. package/runtime/claude/.claude/skills/ingest-notion/SKILL.md +214 -0
  49. package/runtime/claude/.claude/skills/ingest-user-interview/SKILL.md +65 -0
  50. package/runtime/claude/.claude/skills/ingest-user-interview/references/analysis-contract.md +125 -0
  51. package/runtime/claude/.claude/skills/invite/SKILL.md +111 -0
  52. package/runtime/claude/.claude/skills/issue/SKILL.md +104 -0
  53. package/runtime/claude/.claude/skills/me/SKILL.md +81 -0
  54. package/runtime/claude/.claude/skills/meeting/SKILL.md +76 -0
  55. package/runtime/claude/.claude/skills/meeting/references/analysis-contract.md +102 -0
  56. package/runtime/claude/.claude/skills/note/SKILL.md +71 -0
  57. package/runtime/claude/.claude/skills/notion-connect/SKILL.md +124 -0
  58. package/runtime/claude/.claude/skills/onboarding/SKILL.md +159 -0
  59. package/runtime/claude/.claude/skills/pr/SKILL.md +85 -0
  60. package/runtime/claude/.claude/skills/pull/SKILL.md +79 -0
  61. package/runtime/claude/.claude/skills/push/SKILL.md +47 -0
  62. package/runtime/claude/.claude/skills/quest/SKILL.md +121 -0
  63. package/runtime/claude/.claude/skills/reflect/SKILL.md +69 -0
  64. package/runtime/claude/.claude/skills/review-pr/SKILL.md +276 -0
  65. package/runtime/claude/.claude/skills/save/SKILL.md +92 -0
  66. package/runtime/claude/.claude/skills/slack-connect/SKILL.md +148 -0
  67. package/runtime/claude/.claude/skills/summon/SKILL.md +240 -0
  68. package/runtime/claude/.claude/skills/sync-repos/SKILL.md +82 -0
  69. package/runtime/claude/.claude/skills/teams-connect/SKILL.md +216 -0
  70. package/runtime/claude/.claude/skills/telegram-connect/SKILL.md +110 -0
  71. package/runtime/claude/.claude/skills/telemetry/SKILL.md +117 -0
  72. package/runtime/claude/.claude/skills/test/SKILL.md +87 -0
  73. package/runtime/claude/.claude/skills/the-spiral/SKILL.md +492 -0
  74. package/runtime/claude/.claude/skills/tui-design/SKILL.md +188 -0
  75. package/runtime/claude/.claude/skills/tutorial/SKILL.md +100 -0
  76. package/runtime/claude/.claude/skills/update/SKILL.md +265 -0
  77. package/runtime/claude/.claude/skills/view/SKILL.md +393 -0
  78. package/runtime/claude/.claude/skills/view/compose-scaffold.html +221 -0
  79. package/runtime/claude/.claude/skills/visual-explain/SKILL.md +132 -0
  80. package/runtime/claude/.claude/skills/wrap/SKILL.md +98 -0
  81. package/runtime/claude/CLAUDE.md +447 -0
  82. package/runtime/claude/bin/activity-action.sh +92 -0
  83. package/runtime/claude/bin/activity-data.sh +17 -0
  84. package/runtime/claude/bin/agent.sh +783 -0
  85. package/runtime/claude/bin/artifact-register.sh +164 -0
  86. package/runtime/claude/bin/artifact-writeback.sh +53 -0
  87. package/runtime/claude/bin/artifacts.sh +288 -0
  88. package/runtime/claude/bin/attendant.sh +707 -0
  89. package/runtime/claude/bin/autosave.sh +112 -0
  90. package/runtime/claude/bin/boundary.sh +253 -0
  91. package/runtime/claude/bin/build-sealed-dataroom.mjs +722 -0
  92. package/runtime/claude/bin/capture-reconcile.sh +69 -0
  93. package/runtime/claude/bin/capture-run.sh +357 -0
  94. package/runtime/claude/bin/codex-install-skills.sh +78 -0
  95. package/runtime/claude/bin/codex-render-spec.mjs +462 -0
  96. package/runtime/claude/bin/codex-session-start.sh +275 -0
  97. package/runtime/claude/bin/codex-skill-render.mjs +349 -0
  98. package/runtime/claude/bin/codex-sync-skills.sh +237 -0
  99. package/runtime/claude/bin/connect-refresh.sh +33 -0
  100. package/runtime/claude/bin/contribute-guard.sh +79 -0
  101. package/runtime/claude/bin/corpus_map.py +806 -0
  102. package/runtime/claude/bin/corpus_survey.py +304 -0
  103. package/runtime/claude/bin/dashboard-data.sh +18 -0
  104. package/runtime/claude/bin/github-auth.sh +121 -0
  105. package/runtime/claude/bin/graph-batch.sh +86 -0
  106. package/runtime/claude/bin/graph-op.sh +1106 -0
  107. package/runtime/claude/bin/graph-projection.sh +54 -0
  108. package/runtime/claude/bin/graph-wal.sh +242 -0
  109. package/runtime/claude/bin/graph.sh +267 -0
  110. package/runtime/claude/bin/handoff-lifecycle-job.sh +146 -0
  111. package/runtime/claude/bin/handoff-lifecycle.sh +280 -0
  112. package/runtime/claude/bin/handoff-pr-backfill.sh +86 -0
  113. package/runtime/claude/bin/handoff-preview.sh +169 -0
  114. package/runtime/claude/bin/handoff-run.sh +692 -0
  115. package/runtime/claude/bin/handoff-save-egregore.sh +224 -0
  116. package/runtime/claude/bin/index-handoff.sh +322 -0
  117. package/runtime/claude/bin/ingest-graph.sh +86 -0
  118. package/runtime/claude/bin/ingest-item.sh +10 -0
  119. package/runtime/claude/bin/ingest-surface.html +495 -0
  120. package/runtime/claude/bin/ingest.py +1011 -0
  121. package/runtime/claude/bin/ingest.sh +308 -0
  122. package/runtime/claude/bin/ingest_graph.py +856 -0
  123. package/runtime/claude/bin/ingest_surface.py +544 -0
  124. package/runtime/claude/bin/invite.sh +6 -0
  125. package/runtime/claude/bin/issue.sh +10 -0
  126. package/runtime/claude/bin/knowledge.sh +10 -0
  127. package/runtime/claude/bin/lib/artifact-id.sh +46 -0
  128. package/runtime/claude/bin/lib/config.sh +136 -0
  129. package/runtime/claude/bin/lib/context.sh +642 -0
  130. package/runtime/claude/bin/lib/dashboard-artifact.sh +242 -0
  131. package/runtime/claude/bin/lib/ensure-develop.sh +183 -0
  132. package/runtime/claude/bin/lib/git-message.sh +37 -0
  133. package/runtime/claude/bin/lib/git-sync.sh +494 -0
  134. package/runtime/claude/bin/lib/greeting.sh +548 -0
  135. package/runtime/claude/bin/lib/handoff-meta.sh +97 -0
  136. package/runtime/claude/bin/lib/hash.sh +13 -0
  137. package/runtime/claude/bin/lib/identity.sh +213 -0
  138. package/runtime/claude/bin/lib/metrics.sh +374 -0
  139. package/runtime/claude/bin/lib/noncode.sh +31 -0
  140. package/runtime/claude/bin/lib/permissions.sh +106 -0
  141. package/runtime/claude/bin/lib/time.sh +56 -0
  142. package/runtime/claude/bin/lib/worktree-links.sh +85 -0
  143. package/runtime/claude/bin/node-run.sh +42 -0
  144. package/runtime/claude/bin/notification.sh +6 -0
  145. package/runtime/claude/bin/notify.sh +636 -0
  146. package/runtime/claude/bin/observe-context.sh +14 -0
  147. package/runtime/claude/bin/onboarding.sh +6 -0
  148. package/runtime/claude/bin/person.py +634 -0
  149. package/runtime/claude/bin/person.sh +481 -0
  150. package/runtime/claude/bin/pi-render-spec.mjs +140 -0
  151. package/runtime/claude/bin/post-update.sh +37 -0
  152. package/runtime/claude/bin/prime-render-spec.mjs +147 -0
  153. package/runtime/claude/bin/publish-artifact.sh +324 -0
  154. package/runtime/claude/bin/publish-references.sh +144 -0
  155. package/runtime/claude/bin/quest.sh +9 -0
  156. package/runtime/claude/bin/question.sh +8 -0
  157. package/runtime/claude/bin/repo-state.sh +96 -0
  158. package/runtime/claude/bin/research-ingest.sh +7 -0
  159. package/runtime/claude/bin/restore-owned-skills.sh +67 -0
  160. package/runtime/claude/bin/retrieval_eval.py +385 -0
  161. package/runtime/claude/bin/runtime-identity.sh +70 -0
  162. package/runtime/claude/bin/runtime-upgrade.sh +43 -0
  163. package/runtime/claude/bin/scroll.sh +9 -0
  164. package/runtime/claude/bin/search.sh +318 -0
  165. package/runtime/claude/bin/session-autosave.sh +220 -0
  166. package/runtime/claude/bin/session-log.sh +199 -0
  167. package/runtime/claude/bin/session-start.sh +696 -0
  168. package/runtime/claude/bin/settings.sh +532 -0
  169. package/runtime/claude/bin/startup-check.sh +136 -0
  170. package/runtime/claude/bin/statusline.sh +41 -0
  171. package/runtime/claude/bin/telemetry.sh +666 -0
  172. package/runtime/claude/bin/test-changes.sh +344 -0
  173. package/runtime/claude/bin/thread.sh +9 -0
  174. package/runtime/claude/bin/todo.sh +9 -0
  175. package/runtime/claude/bin/view-render.sh +126 -0
  176. package/runtime/claude/bin/worktree-create.sh +145 -0
  177. package/runtime/claude/bin/worktree-remove.sh +50 -0
  178. package/runtime/claude/bin/worktree.sh +198 -0
  179. package/runtime/claude/egregore_runtime/__init__.py +228 -0
  180. package/runtime/claude/egregore_runtime/adapters/__init__.py +5 -0
  181. package/runtime/claude/egregore_runtime/adapters/invitation.py +237 -0
  182. package/runtime/claude/egregore_runtime/adapters/notification.py +59 -0
  183. package/runtime/claude/egregore_runtime/adapters/qmd.py +1701 -0
  184. package/runtime/claude/egregore_runtime/adapters/qmd_cli.py +210 -0
  185. package/runtime/claude/egregore_runtime/adapters/qmd_embed_worker.py +59 -0
  186. package/runtime/claude/egregore_runtime/admin_gate.py +102 -0
  187. package/runtime/claude/egregore_runtime/artifacts.py +523 -0
  188. package/runtime/claude/egregore_runtime/contracts.py +499 -0
  189. package/runtime/claude/egregore_runtime/entitlements.py +85 -0
  190. package/runtime/claude/egregore_runtime/errors.py +10 -0
  191. package/runtime/claude/egregore_runtime/graph.py +356 -0
  192. package/runtime/claude/egregore_runtime/handoff_lookup.py +196 -0
  193. package/runtime/claude/egregore_runtime/harness_cli.py +1221 -0
  194. package/runtime/claude/egregore_runtime/identity.py +734 -0
  195. package/runtime/claude/egregore_runtime/identity_cli.py +91 -0
  196. package/runtime/claude/egregore_runtime/ingest.py +575 -0
  197. package/runtime/claude/egregore_runtime/ingest_cli.py +254 -0
  198. package/runtime/claude/egregore_runtime/ingest_index_cli.py +147 -0
  199. package/runtime/claude/egregore_runtime/invitation_cli.py +51 -0
  200. package/runtime/claude/egregore_runtime/invitations.py +116 -0
  201. package/runtime/claude/egregore_runtime/issue_cli.py +305 -0
  202. package/runtime/claude/egregore_runtime/issues.py +359 -0
  203. package/runtime/claude/egregore_runtime/knowledge.py +376 -0
  204. package/runtime/claude/egregore_runtime/knowledge_cli.py +173 -0
  205. package/runtime/claude/egregore_runtime/lifecycle.py +888 -0
  206. package/runtime/claude/egregore_runtime/lifecycle_cli.py +269 -0
  207. package/runtime/claude/egregore_runtime/notification_cli.py +125 -0
  208. package/runtime/claude/egregore_runtime/notifications.py +230 -0
  209. package/runtime/claude/egregore_runtime/observe.py +342 -0
  210. package/runtime/claude/egregore_runtime/onboarding.py +290 -0
  211. package/runtime/claude/egregore_runtime/onboarding_cli.py +110 -0
  212. package/runtime/claude/egregore_runtime/policy.py +144 -0
  213. package/runtime/claude/egregore_runtime/profile.py +193 -0
  214. package/runtime/claude/egregore_runtime/quest_cli.py +216 -0
  215. package/runtime/claude/egregore_runtime/question_cli.py +180 -0
  216. package/runtime/claude/egregore_runtime/questions.py +304 -0
  217. package/runtime/claude/egregore_runtime/quests.py +419 -0
  218. package/runtime/claude/egregore_runtime/readiness.py +379 -0
  219. package/runtime/claude/egregore_runtime/research_ingest.py +256 -0
  220. package/runtime/claude/egregore_runtime/research_ingest_cli.py +44 -0
  221. package/runtime/claude/egregore_runtime/runtime.py +464 -0
  222. package/runtime/claude/egregore_runtime/scroll_cli.py +185 -0
  223. package/runtime/claude/egregore_runtime/scrolls.py +726 -0
  224. package/runtime/claude/egregore_runtime/status.py +412 -0
  225. package/runtime/claude/egregore_runtime/status_cli.py +174 -0
  226. package/runtime/claude/egregore_runtime/sync.py +218 -0
  227. package/runtime/claude/egregore_runtime/teamsync.py +139 -0
  228. package/runtime/claude/egregore_runtime/telemetry.py +640 -0
  229. package/runtime/claude/egregore_runtime/thread_cli.py +173 -0
  230. package/runtime/claude/egregore_runtime/threads.py +517 -0
  231. package/runtime/claude/egregore_runtime/todo_cli.py +142 -0
  232. package/runtime/claude/egregore_runtime/todos.py +244 -0
  233. package/runtime/claude/egregore_runtime/upgrade.py +770 -0
  234. package/runtime/claude/egregore_runtime/upgrade_worker.py +53 -0
  235. package/runtime/claude/egregore_runtime/writeback.py +391 -0
  236. package/runtime/claude/egregore_runtime/writeback_cli.py +114 -0
  237. package/runtime/claude/manifest.json +284 -0
  238. package/runtime/codex/.codex/hooks/search-hint.js +21 -52
  239. package/runtime/codex/.codex/hooks.json +3 -3
  240. package/runtime/codex/.codex/skills/activity/SKILL.md +23 -66
  241. package/runtime/codex/.codex/skills/announce/SKILL.md +27 -50
  242. package/runtime/codex/.codex/skills/archive/SKILL.md +21 -36
  243. package/runtime/codex/.codex/skills/checkup/SKILL.md +77 -36
  244. package/runtime/codex/.codex/skills/dark-mode/SKILL.md +1 -1
  245. package/runtime/codex/.codex/skills/dashboard/SKILL.md +17 -47
  246. package/runtime/codex/.codex/skills/handoff/SKILL.md +84 -133
  247. package/runtime/codex/.codex/skills/harvest/SKILL.md +32 -117
  248. package/runtime/codex/.codex/skills/ingest/SKILL.md +47 -25
  249. package/runtime/codex/.codex/skills/ingest-user-interview/SKILL.md +18 -36
  250. package/runtime/codex/.codex/skills/ingest-user-interview/references/analysis-contract.md +42 -0
  251. package/runtime/codex/.codex/skills/invite/SKILL.md +21 -35
  252. package/runtime/codex/.codex/skills/issue/SKILL.md +60 -41
  253. package/runtime/codex/.codex/skills/me/SKILL.md +1 -1
  254. package/runtime/codex/.codex/skills/meeting/SKILL.md +16 -36
  255. package/runtime/codex/.codex/skills/meeting/references/analysis-contract.md +48 -0
  256. package/runtime/codex/.codex/skills/note/SKILL.md +30 -25
  257. package/runtime/codex/.codex/skills/onboarding/SKILL.md +36 -41
  258. package/runtime/codex/.codex/skills/pull/SKILL.md +1 -1
  259. package/runtime/codex/.codex/skills/quest/SKILL.md +27 -66
  260. package/runtime/codex/.codex/skills/reflect/SKILL.md +22 -36
  261. package/runtime/codex/.codex/skills/save/SKILL.md +2 -2
  262. package/runtime/codex/.codex/skills/telemetry/SKILL.md +1 -1
  263. package/runtime/codex/.codex/skills/test/SKILL.md +1 -1
  264. package/runtime/codex/.codex/skills/tutorial/SKILL.md +40 -41
  265. package/runtime/codex/.codex/skills/view/SKILL.md +115 -111
  266. package/runtime/codex/.codex/skills/wrap/SKILL.md +45 -41
  267. package/runtime/codex/.codex/spec-manifest.json +9 -9
  268. package/runtime/codex/AGENTS.md +62 -58
  269. package/runtime/codex/bin/activity-action.sh +92 -0
  270. package/runtime/codex/bin/activity-data.sh +12 -233
  271. package/runtime/codex/bin/agent.sh +84 -100
  272. package/runtime/codex/bin/artifact-register.sh +164 -0
  273. package/runtime/codex/bin/artifact-writeback.sh +53 -0
  274. package/runtime/codex/bin/artifacts.sh +288 -0
  275. package/runtime/codex/bin/build-sealed-dataroom.mjs +722 -0
  276. package/runtime/codex/bin/capture-run.sh +18 -2
  277. package/runtime/codex/bin/codex-render-spec.mjs +41 -16
  278. package/runtime/codex/bin/codex-session-start.sh +14 -4
  279. package/runtime/codex/bin/codex-skill-render.mjs +9 -7
  280. package/runtime/codex/bin/corpus_map.py +806 -0
  281. package/runtime/codex/bin/corpus_survey.py +304 -0
  282. package/runtime/codex/bin/dashboard-data.sh +11 -171
  283. package/runtime/codex/bin/github-auth.sh +121 -0
  284. package/runtime/codex/bin/graph-batch.sh +7 -0
  285. package/runtime/codex/bin/graph-op.sh +4 -0
  286. package/runtime/codex/bin/graph-projection.sh +54 -0
  287. package/runtime/codex/bin/graph-wal.sh +13 -0
  288. package/runtime/codex/bin/graph.sh +44 -0
  289. package/runtime/codex/bin/handoff-lifecycle-job.sh +146 -0
  290. package/runtime/codex/bin/handoff-lifecycle.sh +280 -0
  291. package/runtime/codex/bin/handoff-preview.sh +169 -0
  292. package/runtime/codex/bin/handoff-run.sh +42 -26
  293. package/runtime/codex/bin/ingest-graph.sh +6 -0
  294. package/runtime/codex/bin/ingest-item.sh +10 -0
  295. package/runtime/codex/bin/ingest.sh +59 -30
  296. package/runtime/codex/bin/invite.sh +6 -0
  297. package/runtime/codex/bin/issue.sh +10 -0
  298. package/runtime/codex/bin/knowledge.sh +10 -0
  299. package/runtime/codex/bin/lib/config.sh +20 -0
  300. package/runtime/codex/bin/lib/context.sh +46 -25
  301. package/runtime/codex/bin/lib/git-sync.sh +70 -6
  302. package/runtime/codex/bin/lib/greeting.sh +34 -5
  303. package/runtime/codex/bin/lib/handoff-meta.sh +97 -0
  304. package/runtime/codex/bin/lib/worktree-links.sh +6 -0
  305. package/runtime/codex/bin/node-run.sh +42 -0
  306. package/runtime/codex/bin/notification.sh +6 -0
  307. package/runtime/codex/bin/observe-context.sh +14 -0
  308. package/runtime/codex/bin/onboarding.sh +6 -0
  309. package/runtime/codex/bin/person.py +4 -0
  310. package/runtime/codex/bin/person.sh +43 -10
  311. package/runtime/codex/bin/pi-render-spec.mjs +140 -0
  312. package/runtime/codex/bin/post-update.sh +37 -0
  313. package/runtime/codex/bin/prime-render-spec.mjs +147 -0
  314. package/runtime/codex/bin/publish-artifact.sh +55 -2
  315. package/runtime/codex/bin/quest.sh +9 -0
  316. package/runtime/codex/bin/question.sh +8 -0
  317. package/runtime/codex/bin/research-ingest.sh +7 -0
  318. package/runtime/codex/bin/restore-owned-skills.sh +67 -0
  319. package/runtime/codex/bin/retrieval_eval.py +385 -0
  320. package/runtime/codex/bin/runtime-identity.sh +70 -0
  321. package/runtime/codex/bin/runtime-upgrade.sh +43 -0
  322. package/runtime/codex/bin/scroll.sh +9 -0
  323. package/runtime/codex/bin/search.sh +231 -195
  324. package/runtime/codex/bin/settings.sh +174 -5
  325. package/runtime/codex/bin/startup-check.sh +136 -0
  326. package/runtime/codex/bin/telemetry.sh +522 -247
  327. package/runtime/codex/bin/test-changes.sh +344 -0
  328. package/runtime/codex/bin/thread.sh +9 -0
  329. package/runtime/codex/bin/todo.sh +9 -0
  330. package/runtime/codex/bin/view-render.sh +126 -0
  331. package/runtime/codex/bin/worktree-create.sh +19 -5
  332. package/runtime/codex/egregore_runtime/__init__.py +228 -0
  333. package/runtime/codex/egregore_runtime/adapters/__init__.py +5 -0
  334. package/runtime/codex/egregore_runtime/adapters/invitation.py +237 -0
  335. package/runtime/codex/egregore_runtime/adapters/notification.py +59 -0
  336. package/runtime/codex/egregore_runtime/adapters/qmd.py +1701 -0
  337. package/runtime/codex/egregore_runtime/adapters/qmd_cli.py +210 -0
  338. package/runtime/codex/egregore_runtime/adapters/qmd_embed_worker.py +59 -0
  339. package/runtime/codex/egregore_runtime/admin_gate.py +102 -0
  340. package/runtime/codex/egregore_runtime/artifacts.py +523 -0
  341. package/runtime/codex/egregore_runtime/contracts.py +499 -0
  342. package/runtime/codex/egregore_runtime/entitlements.py +85 -0
  343. package/runtime/codex/egregore_runtime/errors.py +10 -0
  344. package/runtime/codex/egregore_runtime/graph.py +356 -0
  345. package/runtime/codex/egregore_runtime/handoff_lookup.py +196 -0
  346. package/runtime/codex/egregore_runtime/harness_cli.py +1221 -0
  347. package/runtime/codex/egregore_runtime/identity.py +734 -0
  348. package/runtime/codex/egregore_runtime/identity_cli.py +91 -0
  349. package/runtime/codex/egregore_runtime/ingest.py +575 -0
  350. package/runtime/codex/egregore_runtime/ingest_cli.py +254 -0
  351. package/runtime/codex/egregore_runtime/ingest_index_cli.py +147 -0
  352. package/runtime/codex/egregore_runtime/invitation_cli.py +51 -0
  353. package/runtime/codex/egregore_runtime/invitations.py +116 -0
  354. package/runtime/codex/egregore_runtime/issue_cli.py +305 -0
  355. package/runtime/codex/egregore_runtime/issues.py +359 -0
  356. package/runtime/codex/egregore_runtime/knowledge.py +376 -0
  357. package/runtime/codex/egregore_runtime/knowledge_cli.py +173 -0
  358. package/runtime/codex/egregore_runtime/lifecycle.py +888 -0
  359. package/runtime/codex/egregore_runtime/lifecycle_cli.py +269 -0
  360. package/runtime/codex/egregore_runtime/notification_cli.py +125 -0
  361. package/runtime/codex/egregore_runtime/notifications.py +230 -0
  362. package/runtime/codex/egregore_runtime/observe.py +342 -0
  363. package/runtime/codex/egregore_runtime/onboarding.py +290 -0
  364. package/runtime/codex/egregore_runtime/onboarding_cli.py +110 -0
  365. package/runtime/codex/egregore_runtime/policy.py +144 -0
  366. package/runtime/codex/egregore_runtime/profile.py +193 -0
  367. package/runtime/codex/egregore_runtime/quest_cli.py +216 -0
  368. package/runtime/codex/egregore_runtime/question_cli.py +180 -0
  369. package/runtime/codex/egregore_runtime/questions.py +304 -0
  370. package/runtime/codex/egregore_runtime/quests.py +419 -0
  371. package/runtime/codex/egregore_runtime/readiness.py +379 -0
  372. package/runtime/codex/egregore_runtime/research_ingest.py +256 -0
  373. package/runtime/codex/egregore_runtime/research_ingest_cli.py +44 -0
  374. package/runtime/codex/egregore_runtime/runtime.py +464 -0
  375. package/runtime/codex/egregore_runtime/scroll_cli.py +185 -0
  376. package/runtime/codex/egregore_runtime/scrolls.py +726 -0
  377. package/runtime/codex/egregore_runtime/status.py +412 -0
  378. package/runtime/codex/egregore_runtime/status_cli.py +174 -0
  379. package/runtime/codex/egregore_runtime/sync.py +218 -0
  380. package/runtime/codex/egregore_runtime/teamsync.py +139 -0
  381. package/runtime/codex/egregore_runtime/telemetry.py +640 -0
  382. package/runtime/codex/egregore_runtime/thread_cli.py +173 -0
  383. package/runtime/codex/egregore_runtime/threads.py +517 -0
  384. package/runtime/codex/egregore_runtime/todo_cli.py +142 -0
  385. package/runtime/codex/egregore_runtime/todos.py +244 -0
  386. package/runtime/codex/egregore_runtime/upgrade.py +770 -0
  387. package/runtime/codex/egregore_runtime/upgrade_worker.py +53 -0
  388. package/runtime/codex/egregore_runtime/writeback.py +391 -0
  389. package/runtime/codex/egregore_runtime/writeback_cli.py +114 -0
  390. package/runtime/codex/manifest.json +98 -1
  391. package/runtime/pi/.codex/hooks/search-hint.js +21 -52
  392. package/runtime/pi/.codex/hooks.json +3 -3
  393. package/runtime/pi/.codex/skills/activity/SKILL.md +23 -66
  394. package/runtime/pi/.codex/skills/announce/SKILL.md +27 -50
  395. package/runtime/pi/.codex/skills/archive/SKILL.md +21 -36
  396. package/runtime/pi/.codex/skills/checkup/SKILL.md +77 -36
  397. package/runtime/pi/.codex/skills/dark-mode/SKILL.md +1 -1
  398. package/runtime/pi/.codex/skills/dashboard/SKILL.md +17 -47
  399. package/runtime/pi/.codex/skills/handoff/SKILL.md +84 -133
  400. package/runtime/pi/.codex/skills/harvest/SKILL.md +32 -117
  401. package/runtime/pi/.codex/skills/ingest/SKILL.md +47 -25
  402. package/runtime/pi/.codex/skills/ingest-user-interview/SKILL.md +18 -36
  403. package/runtime/pi/.codex/skills/ingest-user-interview/references/analysis-contract.md +42 -0
  404. package/runtime/pi/.codex/skills/invite/SKILL.md +21 -35
  405. package/runtime/pi/.codex/skills/issue/SKILL.md +60 -41
  406. package/runtime/pi/.codex/skills/me/SKILL.md +1 -1
  407. package/runtime/pi/.codex/skills/meeting/SKILL.md +16 -36
  408. package/runtime/pi/.codex/skills/meeting/references/analysis-contract.md +48 -0
  409. package/runtime/pi/.codex/skills/note/SKILL.md +30 -25
  410. package/runtime/pi/.codex/skills/onboarding/SKILL.md +36 -41
  411. package/runtime/pi/.codex/skills/pull/SKILL.md +1 -1
  412. package/runtime/pi/.codex/skills/quest/SKILL.md +27 -66
  413. package/runtime/pi/.codex/skills/reflect/SKILL.md +22 -36
  414. package/runtime/pi/.codex/skills/save/SKILL.md +2 -2
  415. package/runtime/pi/.codex/skills/telemetry/SKILL.md +1 -1
  416. package/runtime/pi/.codex/skills/test/SKILL.md +1 -1
  417. package/runtime/pi/.codex/skills/tutorial/SKILL.md +40 -41
  418. package/runtime/pi/.codex/skills/view/SKILL.md +115 -111
  419. package/runtime/pi/.codex/skills/wrap/SKILL.md +45 -41
  420. package/runtime/pi/.codex/spec-manifest.json +9 -9
  421. package/runtime/pi/.pi/APPEND_SYSTEM.md +57 -48
  422. package/runtime/pi/.pi/extensions/egregore.ts +7 -0
  423. package/runtime/pi/.pi/spec-manifest.json +2 -2
  424. package/runtime/pi/AGENTS.md +62 -58
  425. package/runtime/pi/bin/activity-action.sh +92 -0
  426. package/runtime/pi/bin/activity-data.sh +12 -233
  427. package/runtime/pi/bin/agent.sh +84 -100
  428. package/runtime/pi/bin/artifact-register.sh +164 -0
  429. package/runtime/pi/bin/artifact-writeback.sh +53 -0
  430. package/runtime/pi/bin/artifacts.sh +288 -0
  431. package/runtime/pi/bin/build-sealed-dataroom.mjs +722 -0
  432. package/runtime/pi/bin/capture-run.sh +18 -2
  433. package/runtime/pi/bin/codex-render-spec.mjs +41 -16
  434. package/runtime/pi/bin/codex-session-start.sh +14 -4
  435. package/runtime/pi/bin/codex-skill-render.mjs +9 -7
  436. package/runtime/pi/bin/corpus_map.py +806 -0
  437. package/runtime/pi/bin/corpus_survey.py +304 -0
  438. package/runtime/pi/bin/dashboard-data.sh +11 -171
  439. package/runtime/pi/bin/github-auth.sh +121 -0
  440. package/runtime/pi/bin/graph-batch.sh +7 -0
  441. package/runtime/pi/bin/graph-op.sh +4 -0
  442. package/runtime/pi/bin/graph-projection.sh +54 -0
  443. package/runtime/pi/bin/graph-wal.sh +13 -0
  444. package/runtime/pi/bin/graph.sh +44 -0
  445. package/runtime/pi/bin/handoff-lifecycle-job.sh +146 -0
  446. package/runtime/pi/bin/handoff-lifecycle.sh +280 -0
  447. package/runtime/pi/bin/handoff-preview.sh +169 -0
  448. package/runtime/pi/bin/handoff-run.sh +42 -26
  449. package/runtime/pi/bin/ingest-graph.sh +6 -0
  450. package/runtime/pi/bin/ingest-item.sh +10 -0
  451. package/runtime/pi/bin/ingest.sh +59 -30
  452. package/runtime/pi/bin/invite.sh +6 -0
  453. package/runtime/pi/bin/issue.sh +10 -0
  454. package/runtime/pi/bin/knowledge.sh +10 -0
  455. package/runtime/pi/bin/lib/config.sh +20 -0
  456. package/runtime/pi/bin/lib/context.sh +46 -25
  457. package/runtime/pi/bin/lib/git-sync.sh +70 -6
  458. package/runtime/pi/bin/lib/greeting.sh +34 -5
  459. package/runtime/pi/bin/lib/handoff-meta.sh +97 -0
  460. package/runtime/pi/bin/lib/worktree-links.sh +6 -0
  461. package/runtime/pi/bin/node-run.sh +42 -0
  462. package/runtime/pi/bin/notification.sh +6 -0
  463. package/runtime/pi/bin/observe-context.sh +14 -0
  464. package/runtime/pi/bin/onboarding.sh +6 -0
  465. package/runtime/pi/bin/person.py +4 -0
  466. package/runtime/pi/bin/person.sh +43 -10
  467. package/runtime/pi/bin/pi-observe-context.mjs +93 -0
  468. package/runtime/pi/bin/pi-product-workflows.mjs +1 -1
  469. package/runtime/pi/bin/pi-render-spec.mjs +1 -1
  470. package/runtime/pi/bin/post-update.sh +37 -0
  471. package/runtime/pi/bin/prime-render-spec.mjs +147 -0
  472. package/runtime/pi/bin/publish-artifact.sh +55 -2
  473. package/runtime/pi/bin/quest.sh +9 -0
  474. package/runtime/pi/bin/question.sh +8 -0
  475. package/runtime/pi/bin/research-ingest.sh +7 -0
  476. package/runtime/pi/bin/restore-owned-skills.sh +67 -0
  477. package/runtime/pi/bin/retrieval_eval.py +385 -0
  478. package/runtime/pi/bin/runtime-identity.sh +70 -0
  479. package/runtime/pi/bin/runtime-upgrade.sh +43 -0
  480. package/runtime/pi/bin/scroll.sh +9 -0
  481. package/runtime/pi/bin/search.sh +231 -195
  482. package/runtime/pi/bin/settings.sh +174 -5
  483. package/runtime/pi/bin/startup-check.sh +136 -0
  484. package/runtime/pi/bin/telemetry.sh +522 -247
  485. package/runtime/pi/bin/test-changes.sh +344 -0
  486. package/runtime/pi/bin/thread.sh +9 -0
  487. package/runtime/pi/bin/todo.sh +9 -0
  488. package/runtime/pi/bin/view-render.sh +126 -0
  489. package/runtime/pi/bin/worktree-create.sh +19 -5
  490. package/runtime/pi/egregore_runtime/__init__.py +228 -0
  491. package/runtime/pi/egregore_runtime/adapters/__init__.py +5 -0
  492. package/runtime/pi/egregore_runtime/adapters/invitation.py +237 -0
  493. package/runtime/pi/egregore_runtime/adapters/notification.py +59 -0
  494. package/runtime/pi/egregore_runtime/adapters/qmd.py +1701 -0
  495. package/runtime/pi/egregore_runtime/adapters/qmd_cli.py +210 -0
  496. package/runtime/pi/egregore_runtime/adapters/qmd_embed_worker.py +59 -0
  497. package/runtime/pi/egregore_runtime/admin_gate.py +102 -0
  498. package/runtime/pi/egregore_runtime/artifacts.py +523 -0
  499. package/runtime/pi/egregore_runtime/contracts.py +499 -0
  500. package/runtime/pi/egregore_runtime/entitlements.py +85 -0
  501. package/runtime/pi/egregore_runtime/errors.py +10 -0
  502. package/runtime/pi/egregore_runtime/graph.py +356 -0
  503. package/runtime/pi/egregore_runtime/handoff_lookup.py +196 -0
  504. package/runtime/pi/egregore_runtime/harness_cli.py +1221 -0
  505. package/runtime/pi/egregore_runtime/identity.py +734 -0
  506. package/runtime/pi/egregore_runtime/identity_cli.py +91 -0
  507. package/runtime/pi/egregore_runtime/ingest.py +575 -0
  508. package/runtime/pi/egregore_runtime/ingest_cli.py +254 -0
  509. package/runtime/pi/egregore_runtime/ingest_index_cli.py +147 -0
  510. package/runtime/pi/egregore_runtime/invitation_cli.py +51 -0
  511. package/runtime/pi/egregore_runtime/invitations.py +116 -0
  512. package/runtime/pi/egregore_runtime/issue_cli.py +305 -0
  513. package/runtime/pi/egregore_runtime/issues.py +359 -0
  514. package/runtime/pi/egregore_runtime/knowledge.py +376 -0
  515. package/runtime/pi/egregore_runtime/knowledge_cli.py +173 -0
  516. package/runtime/pi/egregore_runtime/lifecycle.py +888 -0
  517. package/runtime/pi/egregore_runtime/lifecycle_cli.py +269 -0
  518. package/runtime/pi/egregore_runtime/notification_cli.py +125 -0
  519. package/runtime/pi/egregore_runtime/notifications.py +230 -0
  520. package/runtime/pi/egregore_runtime/observe.py +342 -0
  521. package/runtime/pi/egregore_runtime/onboarding.py +290 -0
  522. package/runtime/pi/egregore_runtime/onboarding_cli.py +110 -0
  523. package/runtime/pi/egregore_runtime/policy.py +144 -0
  524. package/runtime/pi/egregore_runtime/profile.py +193 -0
  525. package/runtime/pi/egregore_runtime/quest_cli.py +216 -0
  526. package/runtime/pi/egregore_runtime/question_cli.py +180 -0
  527. package/runtime/pi/egregore_runtime/questions.py +304 -0
  528. package/runtime/pi/egregore_runtime/quests.py +419 -0
  529. package/runtime/pi/egregore_runtime/readiness.py +379 -0
  530. package/runtime/pi/egregore_runtime/research_ingest.py +256 -0
  531. package/runtime/pi/egregore_runtime/research_ingest_cli.py +44 -0
  532. package/runtime/pi/egregore_runtime/runtime.py +464 -0
  533. package/runtime/pi/egregore_runtime/scroll_cli.py +185 -0
  534. package/runtime/pi/egregore_runtime/scrolls.py +726 -0
  535. package/runtime/pi/egregore_runtime/status.py +412 -0
  536. package/runtime/pi/egregore_runtime/status_cli.py +174 -0
  537. package/runtime/pi/egregore_runtime/sync.py +218 -0
  538. package/runtime/pi/egregore_runtime/teamsync.py +139 -0
  539. package/runtime/pi/egregore_runtime/telemetry.py +640 -0
  540. package/runtime/pi/egregore_runtime/thread_cli.py +173 -0
  541. package/runtime/pi/egregore_runtime/threads.py +517 -0
  542. package/runtime/pi/egregore_runtime/todo_cli.py +142 -0
  543. package/runtime/pi/egregore_runtime/todos.py +244 -0
  544. package/runtime/pi/egregore_runtime/upgrade.py +770 -0
  545. package/runtime/pi/egregore_runtime/upgrade_worker.py +53 -0
  546. package/runtime/pi/egregore_runtime/writeback.py +391 -0
  547. package/runtime/pi/egregore_runtime/writeback_cli.py +114 -0
  548. package/runtime/pi/manifest.json +98 -1
  549. package/runtime/prime/.codex/hooks/search-hint.js +21 -52
  550. package/runtime/prime/.codex/hooks.json +3 -3
  551. package/runtime/prime/.codex/skills/activity/SKILL.md +23 -66
  552. package/runtime/prime/.codex/skills/announce/SKILL.md +27 -50
  553. package/runtime/prime/.codex/skills/archive/SKILL.md +21 -36
  554. package/runtime/prime/.codex/skills/checkup/SKILL.md +77 -36
  555. package/runtime/prime/.codex/skills/dark-mode/SKILL.md +1 -1
  556. package/runtime/prime/.codex/skills/dashboard/SKILL.md +17 -47
  557. package/runtime/prime/.codex/skills/handoff/SKILL.md +84 -133
  558. package/runtime/prime/.codex/skills/harvest/SKILL.md +32 -117
  559. package/runtime/prime/.codex/skills/ingest/SKILL.md +47 -25
  560. package/runtime/prime/.codex/skills/ingest-user-interview/SKILL.md +18 -36
  561. package/runtime/prime/.codex/skills/ingest-user-interview/references/analysis-contract.md +42 -0
  562. package/runtime/prime/.codex/skills/invite/SKILL.md +21 -35
  563. package/runtime/prime/.codex/skills/issue/SKILL.md +60 -41
  564. package/runtime/prime/.codex/skills/me/SKILL.md +1 -1
  565. package/runtime/prime/.codex/skills/meeting/SKILL.md +16 -36
  566. package/runtime/prime/.codex/skills/meeting/references/analysis-contract.md +48 -0
  567. package/runtime/prime/.codex/skills/note/SKILL.md +30 -25
  568. package/runtime/prime/.codex/skills/onboarding/SKILL.md +36 -41
  569. package/runtime/prime/.codex/skills/pull/SKILL.md +1 -1
  570. package/runtime/prime/.codex/skills/quest/SKILL.md +27 -66
  571. package/runtime/prime/.codex/skills/reflect/SKILL.md +22 -36
  572. package/runtime/prime/.codex/skills/save/SKILL.md +2 -2
  573. package/runtime/prime/.codex/skills/telemetry/SKILL.md +1 -1
  574. package/runtime/prime/.codex/skills/test/SKILL.md +1 -1
  575. package/runtime/prime/.codex/skills/tutorial/SKILL.md +40 -41
  576. package/runtime/prime/.codex/skills/view/SKILL.md +115 -111
  577. package/runtime/prime/.codex/skills/wrap/SKILL.md +45 -41
  578. package/runtime/prime/.codex/spec-manifest.json +9 -9
  579. package/runtime/prime/.prime/agent/APPEND_SYSTEM.md +57 -48
  580. package/runtime/prime/.prime/agent/extensions/egregore.ts +7 -0
  581. package/runtime/prime/.prime/agent/spec-manifest.json +2 -2
  582. package/runtime/prime/AGENTS.md +62 -58
  583. package/runtime/prime/bin/activity-action.sh +92 -0
  584. package/runtime/prime/bin/activity-data.sh +12 -233
  585. package/runtime/prime/bin/agent.sh +84 -100
  586. package/runtime/prime/bin/artifact-register.sh +164 -0
  587. package/runtime/prime/bin/artifact-writeback.sh +53 -0
  588. package/runtime/prime/bin/artifacts.sh +288 -0
  589. package/runtime/prime/bin/build-sealed-dataroom.mjs +722 -0
  590. package/runtime/prime/bin/capture-run.sh +18 -2
  591. package/runtime/prime/bin/codex-render-spec.mjs +41 -16
  592. package/runtime/prime/bin/codex-session-start.sh +14 -4
  593. package/runtime/prime/bin/codex-skill-render.mjs +9 -7
  594. package/runtime/prime/bin/corpus_map.py +806 -0
  595. package/runtime/prime/bin/corpus_survey.py +304 -0
  596. package/runtime/prime/bin/dashboard-data.sh +11 -171
  597. package/runtime/prime/bin/github-auth.sh +121 -0
  598. package/runtime/prime/bin/graph-batch.sh +7 -0
  599. package/runtime/prime/bin/graph-op.sh +4 -0
  600. package/runtime/prime/bin/graph-projection.sh +54 -0
  601. package/runtime/prime/bin/graph-wal.sh +13 -0
  602. package/runtime/prime/bin/graph.sh +44 -0
  603. package/runtime/prime/bin/handoff-lifecycle-job.sh +146 -0
  604. package/runtime/prime/bin/handoff-lifecycle.sh +280 -0
  605. package/runtime/prime/bin/handoff-preview.sh +169 -0
  606. package/runtime/prime/bin/handoff-run.sh +42 -26
  607. package/runtime/prime/bin/ingest-graph.sh +6 -0
  608. package/runtime/prime/bin/ingest-item.sh +10 -0
  609. package/runtime/prime/bin/ingest.sh +59 -30
  610. package/runtime/prime/bin/invite.sh +6 -0
  611. package/runtime/prime/bin/issue.sh +10 -0
  612. package/runtime/prime/bin/knowledge.sh +10 -0
  613. package/runtime/prime/bin/lib/config.sh +20 -0
  614. package/runtime/prime/bin/lib/context.sh +46 -25
  615. package/runtime/prime/bin/lib/git-sync.sh +70 -6
  616. package/runtime/prime/bin/lib/greeting.sh +34 -5
  617. package/runtime/prime/bin/lib/handoff-meta.sh +97 -0
  618. package/runtime/prime/bin/lib/worktree-links.sh +6 -0
  619. package/runtime/prime/bin/node-run.sh +42 -0
  620. package/runtime/prime/bin/notification.sh +6 -0
  621. package/runtime/prime/bin/observe-context.sh +14 -0
  622. package/runtime/prime/bin/onboarding.sh +6 -0
  623. package/runtime/prime/bin/person.py +4 -0
  624. package/runtime/prime/bin/person.sh +43 -10
  625. package/runtime/prime/bin/pi-observe-context.mjs +93 -0
  626. package/runtime/prime/bin/pi-product-workflows.mjs +1 -1
  627. package/runtime/prime/bin/pi-render-spec.mjs +140 -0
  628. package/runtime/prime/bin/post-update.sh +37 -0
  629. package/runtime/prime/bin/prime-render-spec.mjs +1 -1
  630. package/runtime/prime/bin/publish-artifact.sh +55 -2
  631. package/runtime/prime/bin/quest.sh +9 -0
  632. package/runtime/prime/bin/question.sh +8 -0
  633. package/runtime/prime/bin/research-ingest.sh +7 -0
  634. package/runtime/prime/bin/restore-owned-skills.sh +67 -0
  635. package/runtime/prime/bin/retrieval_eval.py +385 -0
  636. package/runtime/prime/bin/runtime-identity.sh +70 -0
  637. package/runtime/prime/bin/runtime-upgrade.sh +43 -0
  638. package/runtime/prime/bin/scroll.sh +9 -0
  639. package/runtime/prime/bin/search.sh +231 -195
  640. package/runtime/prime/bin/settings.sh +174 -5
  641. package/runtime/prime/bin/startup-check.sh +136 -0
  642. package/runtime/prime/bin/telemetry.sh +522 -247
  643. package/runtime/prime/bin/test-changes.sh +344 -0
  644. package/runtime/prime/bin/thread.sh +9 -0
  645. package/runtime/prime/bin/todo.sh +9 -0
  646. package/runtime/prime/bin/view-render.sh +126 -0
  647. package/runtime/prime/bin/worktree-create.sh +19 -5
  648. package/runtime/prime/egregore_runtime/__init__.py +228 -0
  649. package/runtime/prime/egregore_runtime/adapters/__init__.py +5 -0
  650. package/runtime/prime/egregore_runtime/adapters/invitation.py +237 -0
  651. package/runtime/prime/egregore_runtime/adapters/notification.py +59 -0
  652. package/runtime/prime/egregore_runtime/adapters/qmd.py +1701 -0
  653. package/runtime/prime/egregore_runtime/adapters/qmd_cli.py +210 -0
  654. package/runtime/prime/egregore_runtime/adapters/qmd_embed_worker.py +59 -0
  655. package/runtime/prime/egregore_runtime/admin_gate.py +102 -0
  656. package/runtime/prime/egregore_runtime/artifacts.py +523 -0
  657. package/runtime/prime/egregore_runtime/contracts.py +499 -0
  658. package/runtime/prime/egregore_runtime/entitlements.py +85 -0
  659. package/runtime/prime/egregore_runtime/errors.py +10 -0
  660. package/runtime/prime/egregore_runtime/graph.py +356 -0
  661. package/runtime/prime/egregore_runtime/handoff_lookup.py +196 -0
  662. package/runtime/prime/egregore_runtime/harness_cli.py +1221 -0
  663. package/runtime/prime/egregore_runtime/identity.py +734 -0
  664. package/runtime/prime/egregore_runtime/identity_cli.py +91 -0
  665. package/runtime/prime/egregore_runtime/ingest.py +575 -0
  666. package/runtime/prime/egregore_runtime/ingest_cli.py +254 -0
  667. package/runtime/prime/egregore_runtime/ingest_index_cli.py +147 -0
  668. package/runtime/prime/egregore_runtime/invitation_cli.py +51 -0
  669. package/runtime/prime/egregore_runtime/invitations.py +116 -0
  670. package/runtime/prime/egregore_runtime/issue_cli.py +305 -0
  671. package/runtime/prime/egregore_runtime/issues.py +359 -0
  672. package/runtime/prime/egregore_runtime/knowledge.py +376 -0
  673. package/runtime/prime/egregore_runtime/knowledge_cli.py +173 -0
  674. package/runtime/prime/egregore_runtime/lifecycle.py +888 -0
  675. package/runtime/prime/egregore_runtime/lifecycle_cli.py +269 -0
  676. package/runtime/prime/egregore_runtime/notification_cli.py +125 -0
  677. package/runtime/prime/egregore_runtime/notifications.py +230 -0
  678. package/runtime/prime/egregore_runtime/observe.py +342 -0
  679. package/runtime/prime/egregore_runtime/onboarding.py +290 -0
  680. package/runtime/prime/egregore_runtime/onboarding_cli.py +110 -0
  681. package/runtime/prime/egregore_runtime/policy.py +144 -0
  682. package/runtime/prime/egregore_runtime/profile.py +193 -0
  683. package/runtime/prime/egregore_runtime/quest_cli.py +216 -0
  684. package/runtime/prime/egregore_runtime/question_cli.py +180 -0
  685. package/runtime/prime/egregore_runtime/questions.py +304 -0
  686. package/runtime/prime/egregore_runtime/quests.py +419 -0
  687. package/runtime/prime/egregore_runtime/readiness.py +379 -0
  688. package/runtime/prime/egregore_runtime/research_ingest.py +256 -0
  689. package/runtime/prime/egregore_runtime/research_ingest_cli.py +44 -0
  690. package/runtime/prime/egregore_runtime/runtime.py +464 -0
  691. package/runtime/prime/egregore_runtime/scroll_cli.py +185 -0
  692. package/runtime/prime/egregore_runtime/scrolls.py +726 -0
  693. package/runtime/prime/egregore_runtime/status.py +412 -0
  694. package/runtime/prime/egregore_runtime/status_cli.py +174 -0
  695. package/runtime/prime/egregore_runtime/sync.py +218 -0
  696. package/runtime/prime/egregore_runtime/teamsync.py +139 -0
  697. package/runtime/prime/egregore_runtime/telemetry.py +640 -0
  698. package/runtime/prime/egregore_runtime/thread_cli.py +173 -0
  699. package/runtime/prime/egregore_runtime/threads.py +517 -0
  700. package/runtime/prime/egregore_runtime/todo_cli.py +142 -0
  701. package/runtime/prime/egregore_runtime/todos.py +244 -0
  702. package/runtime/prime/egregore_runtime/upgrade.py +770 -0
  703. package/runtime/prime/egregore_runtime/upgrade_worker.py +53 -0
  704. package/runtime/prime/egregore_runtime/writeback.py +391 -0
  705. package/runtime/prime/egregore_runtime/writeback_cli.py +114 -0
  706. package/runtime/prime/manifest.json +98 -1
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env bash
2
+ # repo-state.sh — Capture current branch state across all repos.
3
+ # Outputs a markdown table (## Repo State) for handoff files.
4
+ # Only includes repos on non-base branches or with uncommitted changes.
5
+ #
6
+ # Usage: bash bin/repo-state.sh [--no-pr]
7
+ # --no-pr Skip the `gh pr list` lookup per repo (~400–600ms each).
8
+ # PR column will be `—`. Useful on the hot path where a detached
9
+ # backfill will fill PR numbers in later.
10
+ # Outputs the markdown section to stdout. Empty output = nothing to report.
11
+ set -euo pipefail
12
+
13
+ NO_PR=0
14
+ while [ $# -gt 0 ]; do
15
+ case "$1" in
16
+ --no-pr) NO_PR=1; shift ;;
17
+ *) shift ;;
18
+ esac
19
+ done
20
+
21
+ SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
22
+ CONFIG="$SCRIPT_DIR/egregore.json"
23
+ PARENT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
24
+
25
+ # Source config helpers for _get_base_branch
26
+ source "$SCRIPT_DIR/bin/lib/config.sh" 2>/dev/null || true
27
+
28
+ CORE_REPO=$(jq -r '.repo_name // "egregore"' "$CONFIG" 2>/dev/null)
29
+ GITHUB_ORG=$(jq -r '.github_org // empty' "$CONFIG" 2>/dev/null)
30
+ MANAGED_REPOS=$(jq -r '(.repos[]? // empty) | if type == "object" then .name else . end' "$CONFIG" 2>/dev/null)
31
+
32
+ ROWS=""
33
+
34
+ check_repo() {
35
+ local repo_name="$1"
36
+ local repo_dir="$2"
37
+ local base_branch="$3"
38
+
39
+ [ -d "$repo_dir/.git" ] || [ -f "$repo_dir/.git" ] || return 0
40
+
41
+ local branch
42
+ branch=$(git -C "$repo_dir" branch --show-current 2>/dev/null || echo "")
43
+ [ -z "$branch" ] && return 0
44
+
45
+ local dirty=""
46
+ [ -n "$(git -C "$repo_dir" status --porcelain 2>/dev/null | head -1)" ] && dirty="yes"
47
+
48
+ # Skip if on base branch with no changes
49
+ if [ "$branch" = "$base_branch" ] && [ -z "$dirty" ]; then
50
+ return 0
51
+ fi
52
+
53
+ # Count commits ahead of base
54
+ local ahead=0
55
+ ahead=$(git -C "$repo_dir" rev-list "origin/${base_branch}..HEAD" --count 2>/dev/null || echo "0")
56
+
57
+ # Skip if on base branch, no dirty files, no commits ahead
58
+ if [ "$branch" = "$base_branch" ] && [ -z "$dirty" ] && [ "$ahead" = "0" ]; then
59
+ return 0
60
+ fi
61
+
62
+ # Check for open PR (skipped with --no-pr; a detached backfill fills it in)
63
+ local pr="—"
64
+ if [ "$NO_PR" = "0" ] && command -v gh &>/dev/null && [ -n "$GITHUB_ORG" ]; then
65
+ local pr_num
66
+ pr_num=$(gh pr list --repo "$GITHUB_ORG/$repo_name" --head "$branch" --json number -q '.[0].number' 2>/dev/null || true)
67
+ [ -n "$pr_num" ] && pr="#$pr_num"
68
+ fi
69
+
70
+ ROWS="${ROWS}| ${repo_name} | ${branch} | ${pr} | ${base_branch} |\n"
71
+ }
72
+
73
+ # Check core repo
74
+ if ! CORE_BASE=$(_get_base_branch); then
75
+ echo "repo-state: could not resolve the configured base branch" >&2
76
+ exit 1
77
+ fi
78
+ check_repo "$CORE_REPO" "$SCRIPT_DIR" "$CORE_BASE"
79
+
80
+ # Check managed repos
81
+ for REPO in $MANAGED_REPOS; do
82
+ REPO_DIR="$PARENT_DIR/$REPO"
83
+ if ! BASE=$(_get_base_branch "$REPO"); then
84
+ continue
85
+ fi
86
+ check_repo "$REPO" "$REPO_DIR" "$BASE"
87
+ done
88
+
89
+ # Output
90
+ if [ -n "$ROWS" ]; then
91
+ echo "## Repo State"
92
+ echo ""
93
+ echo "| Repo | Branch | PR | Base |"
94
+ echo "|------|--------|----|------|"
95
+ printf '%b' "$ROWS"
96
+ fi
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bash
2
+ # Typed Runtime boundary for approved meeting/interview analysis packages.
3
+ set -euo pipefail
4
+
5
+ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
6
+ EGREGORE_ROOT="$ROOT" PYTHONPATH="$ROOT${PYTHONPATH:+:$PYTHONPATH}" \
7
+ exec python3 -m egregore_runtime.research_ingest_cli "$@"
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env bash
2
+ # restore-owned-skills.sh — keep org-owned skills intact through a framework update.
3
+ #
4
+ # Org-owned skills are declared in egregore.json → owned_skills[]. The /update
5
+ # overlay stamps upstream framework paths (including .claude/skills/) over the
6
+ # working tree. This script runs AFTER the overlay and BEFORE the update
7
+ # commit. For every owned skill name:
8
+ #
9
+ # - upstream does NOT ship that name → nothing to do (the overlay never
10
+ # touched it; local edits, committed or not, are left alone)
11
+ # - upstream DOES ship that name → the org's committed version wins:
12
+ # the skill directory is reset to HEAD and the collision is reported so
13
+ # the org can rename theirs or explicitly adopt upstream's
14
+ # - collision but no committed org version → upstream's copy stays (there is
15
+ # nothing to restore); the report says to commit and re-run /update
16
+ #
17
+ # Runtime-neutral: called from every harness's update flow. Idempotent; exits
18
+ # 0 silently when owned_skills is absent or empty.
19
+ #
20
+ # Usage: restore-owned-skills.sh [--upstream-ref <ref>] (default upstream/main)
21
+
22
+ set -uo pipefail
23
+
24
+ UPSTREAM_REF="upstream/main"
25
+ if [ "${1:-}" = "--upstream-ref" ] && [ -n "${2:-}" ]; then
26
+ UPSTREAM_REF="$2"
27
+ fi
28
+
29
+ command -v jq >/dev/null 2>&1 || exit 0
30
+ [ -f egregore.json ] || exit 0
31
+ git rev-parse --git-dir >/dev/null 2>&1 || exit 0
32
+
33
+ OWNED=$(jq -r '.owned_skills // [] | .[]' egregore.json 2>/dev/null)
34
+ [ -n "$OWNED" ] || exit 0
35
+
36
+ while IFS= read -r name; do
37
+ [ -n "$name" ] || continue
38
+ case "$name" in
39
+ */*|.*|*..*|*' '*)
40
+ echo " ⚠ owned_skills: invalid name '$name' — skipped" >&2
41
+ continue
42
+ ;;
43
+ esac
44
+ SKILL_PATH=".claude/skills/$name"
45
+
46
+ # Only a name collision needs work — an org-only skill is never touched by
47
+ # the overlay, and resetting it here would destroy uncommitted local edits.
48
+ if ! git ls-tree -d "$UPSTREAM_REF" -- "$SKILL_PATH" 2>/dev/null | grep -q .; then
49
+ continue
50
+ fi
51
+
52
+ if git cat-file -e "HEAD:$SKILL_PATH" 2>/dev/null; then
53
+ # Wipe the overlay's copy (index + tree), then restore the org's committed
54
+ # version. rm+checkout also drops upstream-only files inside the dir.
55
+ git rm -r --cached --quiet -- "$SKILL_PATH" 2>/dev/null || true
56
+ rm -rf "$SKILL_PATH"
57
+ git checkout HEAD -- "$SKILL_PATH" 2>/dev/null || true
58
+ echo " ◐ owned skill '$name': upstream ships a skill with this name — kept yours."
59
+ echo " Review upstream's version: git diff HEAD $UPSTREAM_REF -- $SKILL_PATH"
60
+ else
61
+ echo " ⚠ owned skill '$name': upstream ships this name and you have no committed version — upstream's copy is in the tree. Commit yours and re-run /update to keep it."
62
+ fi
63
+ done <<EOF
64
+ $OWNED
65
+ EOF
66
+
67
+ exit 0
@@ -0,0 +1,385 @@
1
+ """Measure retrieval against questions whose answers are known.
2
+
3
+ A system that answers questions phrases a wrong answer exactly as well as a
4
+ right one. Nothing about the output distinguishes them, so the only instrument
5
+ that can is a set of questions someone has already answered — asked of the
6
+ system, and compared.
7
+
8
+ This runs such a fixture and reports what the plan requires: whether the hard
9
+ boundary ever leaked, how often the expected source was retrieved, how often
10
+ nothing was found, and how long it took. A boundary violation is a failure
11
+ regardless of how good the answer looked.
12
+
13
+ Expected answers are marked verified or not. An unverified expectation is a
14
+ guess written down, and counting it as evidence would make the measurement
15
+ agree with whoever wrote the fixture rather than with the domain.
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import json
21
+ import math
22
+ import re
23
+ import time
24
+ from collections import Counter
25
+ from dataclasses import dataclass, field
26
+ from pathlib import Path
27
+
28
+ TOKEN = re.compile(r"\w{3,}", re.UNICODE)
29
+
30
+ # Turkish is agglutinative: budama, budaması and budamada are one word wearing
31
+ # three suffixes, and exact token matching treats them as three. Retrieval
32
+ # therefore under-returns on inflected forms. Stemming is a known gap, recorded
33
+ # here rather than silently tolerated — measuring it needs the fixture.
34
+ STEMMING = False
35
+
36
+
37
+ @dataclass
38
+ class Passage:
39
+ id: str
40
+ text: str
41
+ document: str
42
+ zone: str
43
+ tier: str
44
+ topic: str
45
+
46
+
47
+ @dataclass
48
+ class QueryResult:
49
+ id: str
50
+ question: str
51
+ found: int
52
+ top: list = field(default_factory=list)
53
+ expected_hit: bool | None = None
54
+ boundary_violation: list = field(default_factory=list)
55
+ elapsed_ms: float = 0.0
56
+ verified_expectation: bool = False
57
+
58
+
59
+ def tokenize(text: str) -> list[str]:
60
+ return TOKEN.findall((text or "").lower())
61
+
62
+
63
+ def zones_in_scope(zone: str, hierarchy: dict) -> set[str]:
64
+ """A zone plus everything it inherits from.
65
+
66
+ Inheritance runs one way. A grower's own zone and the wider zones containing
67
+ it are in scope; a sibling zone never is, which is the direction where a
68
+ violation does harm.
69
+ """
70
+ scope = {zone}
71
+ current = zone
72
+ seen = {zone}
73
+ while True:
74
+ parent = hierarchy.get(current)
75
+ if not parent or parent in seen:
76
+ break
77
+ scope.add(parent)
78
+ seen.add(parent)
79
+ current = parent
80
+ return scope
81
+
82
+
83
+ # BM25 parameters at their standard values. k1 bounds how much repeating a term
84
+ # can raise a score; b sets how strongly length is normalised away.
85
+ K1 = 1.2
86
+ B = 0.75
87
+
88
+ # How many passages one document may contribute. Without a cap a single long
89
+ # document fills the whole list, and a grower reading five results sees one
90
+ # source five times instead of five sources.
91
+ PER_DOCUMENT = 2
92
+
93
+
94
+ class Index:
95
+ """A lexical index over passages, filtered before ranking.
96
+
97
+ Ranking is BM25 rather than plain term frequency. The difference is length:
98
+ a longer passage contains more of every word, so under raw counts the
99
+ longest passages in a corpus rise to the top of questions they have no
100
+ particular claim to. Measured here, the two documents topping unrelated
101
+ queries were the two longest chunks in the archive.
102
+ """
103
+
104
+ def __init__(self, passages: list[Passage]):
105
+ self.passages = passages
106
+ self.df: Counter = Counter()
107
+ self.tf: list[Counter] = []
108
+ self.lengths: list[int] = []
109
+ for p in passages:
110
+ counts = Counter(tokenize(p.text))
111
+ self.tf.append(counts)
112
+ self.lengths.append(sum(counts.values()))
113
+ self.df.update(set(counts))
114
+ self.n = max(1, len(passages))
115
+ self.avg_length = (sum(self.lengths) / self.n) if self.lengths else 0.0
116
+
117
+ def idf(self, term: str) -> float:
118
+ """Inverse document frequency, in the form that stays positive.
119
+
120
+ The textbook ratio goes to zero — and can go negative — for a term
121
+ present in most of the corpus, which silently drops passages that do
122
+ match. The +1 keeps every genuine match above zero.
123
+ """
124
+ df = self.df.get(term, 0)
125
+ return math.log(1 + (self.n - df + 0.5) / (df + 0.5))
126
+
127
+ def search(
128
+ self,
129
+ question: str,
130
+ allowed_zones: set[str],
131
+ limit: int = 5,
132
+ per_document: int = PER_DOCUMENT,
133
+ vocabulary=None,
134
+ ) -> list[tuple[float, Passage]]:
135
+ terms = tokenize(question)
136
+ weights = {t: 1.0 for t in terms}
137
+ if vocabulary is not None:
138
+ import term_expand
139
+
140
+ _, added = term_expand.expand(question, vocabulary)
141
+ for t in added:
142
+ # Only where the asker did not already use the word. An inferred
143
+ # word never raises the weight of one they chose themselves.
144
+ if len(t) >= 3 and t not in weights:
145
+ weights[t] = term_expand.EXPANSION_WEIGHT
146
+
147
+ scored = []
148
+ for i, p in enumerate(self.passages):
149
+ # The zone filter runs before ranking, not after. Filtering a ranked
150
+ # list would let a better-scoring out-of-zone passage displace an
151
+ # in-zone one and shorten the result rather than replace it.
152
+ if p.zone not in allowed_zones:
153
+ continue
154
+ counts = self.tf[i]
155
+ norm = K1 * (1 - B + B * (self.lengths[i] / self.avg_length)) if self.avg_length else K1
156
+ score = 0.0
157
+ for t, weight in weights.items():
158
+ tf = counts.get(t, 0)
159
+ if tf:
160
+ score += weight * self.idf(t) * (tf * (K1 + 1)) / (tf + norm)
161
+ if score > 0:
162
+ scored.append((score, p))
163
+ scored.sort(key=lambda x: -x[0])
164
+
165
+ if per_document <= 0:
166
+ return scored[:limit]
167
+ seen: Counter = Counter()
168
+ capped = []
169
+ for score, p in scored:
170
+ if seen[p.document] >= per_document:
171
+ continue
172
+ seen[p.document] += 1
173
+ capped.append((score, p))
174
+ if len(capped) >= limit:
175
+ break
176
+ return capped
177
+
178
+
179
+ def load_passages(manifest_path: Path, data_root: Path) -> list[Passage]:
180
+ manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
181
+ chunk_re = re.compile(r"<!-- ingest-chunk: (\S+) -->\n\n(.*?)(?=\n## Chunk |\Z)", re.S)
182
+ passages: list[Passage] = []
183
+ for doc in manifest.get("documents", []):
184
+ body = (data_root / doc["file_path"]).read_text(encoding="utf-8", errors="replace")
185
+ provenance = doc.get("provenance") or {}
186
+ catalogued = provenance.get("from_catalogue") or {}
187
+ excluded = {
188
+ c["id"] for c in doc.get("chunks", []) if (c.get("segment") or {}).get("kind") == "bibliography"
189
+ }
190
+ for match in chunk_re.finditer(body):
191
+ cid = match.group(1)
192
+ if cid in excluded:
193
+ continue
194
+ passages.append(
195
+ Passage(
196
+ id=cid,
197
+ text=match.group(2),
198
+ document=doc.get("title", ""),
199
+ zone=(doc.get("boundaries") or {}).get("zone", ""),
200
+ tier=provenance.get("tier", ""),
201
+ topic=catalogued.get("topic", ""),
202
+ )
203
+ )
204
+ return passages
205
+
206
+
207
+ def run(fixture: dict, index: Index, vocabulary=None) -> list[QueryResult]:
208
+ hierarchy = fixture.get("zone_hierarchy") or {}
209
+ results: list[QueryResult] = []
210
+
211
+ for query in fixture.get("queries", []):
212
+ zone = query.get("zone") or fixture.get("default_zone") or ""
213
+ scope = zones_in_scope(zone, hierarchy) if zone else set()
214
+
215
+ started = time.perf_counter()
216
+ hits = (
217
+ index.search(query["text"], scope, limit=query.get("limit", 5), vocabulary=vocabulary)
218
+ if scope
219
+ else []
220
+ )
221
+ elapsed = (time.perf_counter() - started) * 1000
222
+
223
+ expected = (query.get("expect") or {}).get("documents") or []
224
+ verified = bool((query.get("expect") or {}).get("verified"))
225
+ expected_hit = None
226
+ if expected:
227
+ retrieved = {p.document for _, p in hits}
228
+ expected_hit = any(e in retrieved for e in expected)
229
+
230
+ # Anything returned from outside the permitted scope is a failure of the
231
+ # only guarantee the system makes about where advice applies.
232
+ violations = [p.document for _, p in hits if p.zone not in scope]
233
+
234
+ results.append(
235
+ QueryResult(
236
+ id=query.get("id", "?"),
237
+ question=query["text"],
238
+ found=len(hits),
239
+ top=[{"document": p.document, "zone": p.zone, "tier": p.tier, "chunk": p.id} for _, p in hits[:3]],
240
+ expected_hit=expected_hit,
241
+ boundary_violation=violations,
242
+ elapsed_ms=round(elapsed, 1),
243
+ verified_expectation=verified,
244
+ )
245
+ )
246
+ return results
247
+
248
+
249
+ def diagnose(passages: list[Passage]) -> list[str]:
250
+ """Reasons a corpus will answer nothing, stated before the run does.
251
+
252
+ Zone is a hard retrieval boundary, so a corpus ingested without a publisher
253
+ profile carries no zone and every query is refused. That is the boundary
254
+ working — advice that cannot be placed is not served — but the report it
255
+ produces reads as `0 answered, 0 boundary violations`, which looks closer to
256
+ success than to the misconfiguration it is.
257
+ """
258
+ notes = []
259
+ if not passages:
260
+ return ["the corpus is empty: no passages were loaded from the manifest"]
261
+
262
+ zoneless = sum(1 for p in passages if not p.zone)
263
+ if zoneless == len(passages):
264
+ notes.append(
265
+ f"every one of {len(passages):,} passages has no zone, so every query will be "
266
+ "refused. The corpus was probably ingested without EGREGORE_PUBLISHER_PROFILE set."
267
+ )
268
+ elif zoneless:
269
+ notes.append(f"{zoneless:,} of {len(passages):,} passages have no zone and can never be served")
270
+
271
+ tierless = sum(1 for p in passages if not p.tier)
272
+ if tierless == len(passages):
273
+ notes.append("no passage carries a trust tier, so results cannot be ranked by source reliability")
274
+ return notes
275
+
276
+
277
+ def report(results: list[QueryResult]) -> dict:
278
+ answered = [r for r in results if r.found]
279
+ checked = [r for r in results if r.expected_hit is not None and r.verified_expectation]
280
+ hits = [r for r in checked if r.expected_hit]
281
+ latencies = sorted(r.elapsed_ms for r in results) or [0.0]
282
+ violations = [r for r in results if r.boundary_violation]
283
+
284
+ def pct(n, d):
285
+ return round(100 * n / d, 1) if d else None
286
+
287
+ return {
288
+ "queries": len(results),
289
+ "answered": len(answered),
290
+ "unanswered": len(results) - len(answered),
291
+ "unanswered_rate_pct": pct(len(results) - len(answered), len(results)),
292
+ "boundary_violations": len(violations),
293
+ "citation_hit_rate_pct": pct(len(hits), len(checked)),
294
+ "expectations_verified": len(checked),
295
+ "expectations_unverified": sum(
296
+ 1 for r in results if r.expected_hit is not None and not r.verified_expectation
297
+ ),
298
+ "p50_ms": latencies[len(latencies) // 2],
299
+ "p95_ms": latencies[min(len(latencies) - 1, int(len(latencies) * 0.95))],
300
+ }
301
+
302
+
303
+ def format_report(report: dict, results: list[QueryResult], verbose: bool = False) -> str:
304
+ lines = [
305
+ f"queries {report['queries']} · answered {report['answered']} · unanswered {report['unanswered']}",
306
+ "",
307
+ f"boundary_violations {report['boundary_violations']}",
308
+ f"citation_hit_rate_pct {report['citation_hit_rate_pct']}",
309
+ f"expectations_verified {report['expectations_verified']}",
310
+ f"expectations_unverified {report['expectations_unverified']}",
311
+ f"p50_ms {report['p50_ms']} · p95_ms {report['p95_ms']}",
312
+ ]
313
+ if report["citation_hit_rate_pct"] is None:
314
+ lines += [
315
+ "",
316
+ "The hit rate is unavailable because no expectation has been confirmed by",
317
+ "someone who knows the domain. It is withheld rather than computed from",
318
+ "guesses, which would only measure agreement with whoever wrote the fixture.",
319
+ ]
320
+ if verbose:
321
+ lines.append("")
322
+ for r in results:
323
+ lines.append(f"[{r.id}] {r.question}")
324
+ lines.append(f" {r.found} found · {r.elapsed_ms} ms")
325
+ for hit in r.top:
326
+ lines.append(f" · {hit['document'][:70]} ({hit['zone']}, {hit['tier']})")
327
+ if r.boundary_violation:
328
+ lines.append(f" VIOLATION: {r.boundary_violation}")
329
+ return "\n".join(lines)
330
+
331
+
332
+ def main(argv: list[str] | None = None) -> int:
333
+ import argparse
334
+
335
+ parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
336
+ parser.add_argument("--fixture", required=True, type=Path)
337
+ parser.add_argument("--manifest", required=True, type=Path)
338
+ parser.add_argument("--data-root", required=True, type=Path)
339
+ parser.add_argument("--vocabulary", type=Path, nargs="*", default=[],
340
+ help="term files used to expand a question into the archive's wording")
341
+ parser.add_argument("--verbose", action="store_true", help="show retrieved sources per query")
342
+ parser.add_argument("--json", action="store_true", help="emit the report as JSON")
343
+ args = parser.parse_args(argv)
344
+
345
+ fixture = json.loads(args.fixture.read_text(encoding="utf-8"))
346
+ started = time.perf_counter()
347
+ passages = load_passages(args.manifest, args.data_root)
348
+ index = Index(passages)
349
+ if not args.json:
350
+ print(f"loaded {len(passages):,} passages in {time.perf_counter() - started:.1f}s "
351
+ "(bibliographies excluded)\n")
352
+
353
+ vocabulary = None
354
+ if args.vocabulary:
355
+ import term_expand
356
+
357
+ vocabulary = term_expand.load_vocabulary(args.vocabulary)
358
+ if not args.json:
359
+ print(f"vocabulary: {len(vocabulary)} term groups")
360
+ for skipped in vocabulary.skipped:
361
+ print(f" skipped {skipped}")
362
+
363
+ problems = diagnose(passages)
364
+ if problems and not args.json:
365
+ for note in problems:
366
+ print(f"!! {note}")
367
+ print()
368
+
369
+ results = run(fixture, index, vocabulary=vocabulary)
370
+ summary = report(results)
371
+
372
+ if args.json:
373
+ print(json.dumps({"report": summary, "diagnostics": problems,
374
+ "results": [vars(r) for r in results]},
375
+ ensure_ascii=False, indent=2))
376
+ else:
377
+ print(format_report(summary, results, verbose=args.verbose))
378
+
379
+ # A boundary violation is the one failure that must be actionable from a
380
+ # script; everything else is a measurement, not a fault.
381
+ return 1 if (summary["boundary_violations"] or problems) else 0
382
+
383
+
384
+ if __name__ == "__main__":
385
+ raise SystemExit(main())
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # Resolve the stable Runtime identity before Observe can emit attributed
5
+ # context. Connected instances adopt IDs from the authenticated control plane;
6
+ # legacy Local instances create opaque local IDs once. Network failure remains
7
+ # non-fatal to startup and is retried next session.
8
+
9
+ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
10
+ CONFIG="$ROOT/egregore.json"
11
+ STATE="$ROOT/.egregore-state.json"
12
+
13
+ resolved() {
14
+ [ -f "$CONFIG" ] && [ -f "$STATE" ] || return 1
15
+ jq -e '
16
+ (.org_id | type == "string" and length > 0 and (startswith("legacy-org:") | not))
17
+ ' "$CONFIG" >/dev/null 2>&1 || return 1
18
+ jq -e '
19
+ [ .account_id, .actor_id, .membership_id ]
20
+ | all(type == "string" and length > 0)
21
+ ' "$STATE" >/dev/null 2>&1
22
+ }
23
+
24
+ case "${1:-ensure}" in
25
+ status)
26
+ if resolved; then
27
+ printf '{"status":"resolved"}\n'
28
+ exit 0
29
+ fi
30
+ printf '{"status":"unresolved"}\n'
31
+ exit 1
32
+ ;;
33
+ ensure)
34
+ resolved && exit 0
35
+ mode="$(jq -r 'if (.mode // "local") == "connected" or (.api_url // "") != "" then "connected" else "local" end' "$CONFIG" 2>/dev/null || echo local)"
36
+ if [ "$mode" = "local" ]; then
37
+ EGREGORE_ROOT="$ROOT" python3 -m egregore_runtime.identity_cli initialize-local >/dev/null
38
+ else
39
+ api_url="$(jq -r '.api_url // empty' "$CONFIG" 2>/dev/null)"
40
+ api_key="$(grep '^EGREGORE_API_KEY=' "$ROOT/.env" 2>/dev/null | cut -d= -f2-)"
41
+ [ -n "$api_url" ] && [ -n "$api_key" ] || exit 1
42
+ # Identity repair is read-only: select the already-existing account and
43
+ # membership records, then adopt their opaque IDs locally. If migration
44
+ # 038 has not reached the control plane, the next session retries.
45
+ control_plane="$(curl -sf "$api_url/api/org/status" \
46
+ -H "Authorization: Bearer $api_key" --connect-timeout 2 --max-time 4 \
47
+ 2>/dev/null || true)"
48
+ printf '%s' "$control_plane" | jq -e \
49
+ '.org_id | type == "string" and length > 0' >/dev/null 2>&1 || exit 1
50
+ slug="$(jq -r '.slug // empty' "$CONFIG" 2>/dev/null)"
51
+ [ -n "$slug" ] || exit 1
52
+ roster="$(curl -sf "$api_url/api/org/$slug/members?include_removed=true" \
53
+ -H "Authorization: Bearer $api_key" --connect-timeout 2 --max-time 4 \
54
+ 2>/dev/null || true)"
55
+ printf '%s' "$roster" | jq -e \
56
+ '.members | type == "array"' >/dev/null 2>&1 || exit 1
57
+ jq -cn \
58
+ --argjson organization "$control_plane" \
59
+ --argjson roster "$roster" \
60
+ '{organization:$organization,roster:$roster}' | \
61
+ EGREGORE_ROOT="$ROOT" python3 -m egregore_runtime.identity_cli \
62
+ reconcile-records >/dev/null
63
+ fi
64
+ resolved
65
+ ;;
66
+ *)
67
+ echo 'usage: bash bin/runtime-identity.sh {ensure|status}' >&2
68
+ exit 2
69
+ ;;
70
+ esac
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env bash
2
+ # runtime-upgrade.sh — deterministic bridge for the per-instance Runtime
3
+ # upgrade. The launcher's Settings surface and advanced callers drive the
4
+ # transactional engine through these verbs; the Python Runtime owns all
5
+ # state, staging, gates, activation, and rollback. Output is JSON for
6
+ # renderers — this script is an internal surface, not the user experience.
7
+ #
8
+ # Verbs:
9
+ # status [--fetch] durable upgrade + team-sync state
10
+ # init --candidate <ver> stage a candidate (X.Y.Z-runtime-mvp.N only)
11
+ # prepare start/resume the detached preparation worker
12
+ # activate atomic activation; refuses unless every gate passed
13
+ # cancel request cancellation; previous Runtime untouched
14
+ # rollback restore the recorded previous Runtime version
15
+ # team-sync [--fetch] canonical memory sync state only
16
+ set -uo pipefail
17
+
18
+ SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
19
+
20
+ # EGREGORE_INSTANCE_ROOT lets the packaged launcher bridge drive an instance
21
+ # that predates this script: engine code always comes from this script's own
22
+ # tree, while the target instance is set explicitly — never inferred.
23
+ INSTANCE_ROOT="${EGREGORE_INSTANCE_ROOT:-$SCRIPT_DIR}"
24
+
25
+ _runtime() {
26
+ EGREGORE_ROOT="$INSTANCE_ROOT" \
27
+ PYTHONPATH="$SCRIPT_DIR${PYTHONPATH:+:$PYTHONPATH}" \
28
+ python3 -m egregore_runtime.harness_cli "$@"
29
+ }
30
+
31
+ case "${1:-}" in
32
+ status) shift; _runtime upgrade status "$@" ;;
33
+ init) shift; _runtime upgrade init "$@" ;;
34
+ prepare) shift; _runtime upgrade prepare "$@" ;;
35
+ activate) shift; _runtime upgrade activate "$@" ;;
36
+ cancel) shift; _runtime upgrade cancel "$@" ;;
37
+ rollback) shift; _runtime upgrade rollback "$@" ;;
38
+ team-sync) shift; _runtime team-sync "$@" ;;
39
+ *)
40
+ echo "usage: bash bin/runtime-upgrade.sh {status|init --candidate <version>|prepare|activate|cancel|rollback|team-sync}" >&2
41
+ exit 2
42
+ ;;
43
+ esac
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
5
+ export EGREGORE_ROOT="$ROOT"
6
+ export EGREGORE_SESSION_ID="${EGREGORE_SESSION_ID:-$(cat "$ROOT/.egregore-session-id" 2>/dev/null || true)}"
7
+ export PYTHONPATH="$ROOT${PYTHONPATH:+:$PYTHONPATH}"
8
+
9
+ exec python3 -m egregore_runtime.scroll_cli "$@"