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,379 @@
1
+ """Runtime MVP readiness surface.
2
+
3
+ One staged, truthful view of what the local Runtime can do right now:
4
+ trust boundary, authorization policy, pinned QMD, reranking posture, BM25,
5
+ embeddings, the semantic build revision versus the canonical source
6
+ revision, and whether search stays usable while vectors rebuild.
7
+
8
+ Truth sources are Runtime state — ``RetrieverHealth``, a ``PolicyDecision``
9
+ from the actor's authorizer, and the session boundary state computed at
10
+ session start. Nothing is inferred from filenames, process names, or
11
+ hardcoded organizations, no percentage progress is invented (QMD does not
12
+ provide one), and building this report performs no network call.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import hashlib
18
+ import json
19
+ import time
20
+ from dataclasses import dataclass
21
+ from pathlib import Path
22
+ from typing import Any, Mapping
23
+
24
+ from .contracts import Permission, PolicyDecision, RetrieverHealth
25
+ from .adapters.qmd import RERANKING_ENABLED
26
+
27
+ STAGE_READY = "ready"
28
+ STAGE_BUILDING = "building"
29
+ STAGE_UNAVAILABLE = "unavailable"
30
+ STAGE_DISABLED = "disabled"
31
+
32
+ _GLYPHS = {
33
+ STAGE_READY: "●",
34
+ STAGE_BUILDING: "◐",
35
+ STAGE_UNAVAILABLE: "○",
36
+ STAGE_DISABLED: "–",
37
+ }
38
+
39
+
40
+ @dataclass(frozen=True, slots=True)
41
+ class ReadinessItem:
42
+ key: str
43
+ label: str
44
+ stage: str
45
+ detail: str
46
+
47
+ def to_dict(self) -> dict[str, str]:
48
+ return {
49
+ "key": self.key,
50
+ "label": self.label,
51
+ "stage": self.stage,
52
+ "detail": self.detail,
53
+ }
54
+
55
+
56
+ @dataclass(frozen=True, slots=True)
57
+ class ReadinessReport:
58
+ items: tuple[ReadinessItem, ...]
59
+ generated_in_ms: int
60
+
61
+ def to_dict(self) -> dict[str, Any]:
62
+ return {
63
+ "schema_version": "egregore-readiness/v1",
64
+ "items": [item.to_dict() for item in self.items],
65
+ "generated_in_ms": self.generated_in_ms,
66
+ }
67
+
68
+
69
+ def _short_revision(revision: str | None) -> str:
70
+ """Compress a canonical revision to an honest, comparable short form."""
71
+ if not revision:
72
+ return "none"
73
+ dirty = "+dirty" if "+dirty" in revision else ""
74
+ head = revision.split("+", 1)[0]
75
+ if ":" in head:
76
+ scheme, value = head.split(":", 1)
77
+ return f"{scheme}:{value[:12]}{dirty}"
78
+ return f"{head[:12]}{dirty}"
79
+
80
+
81
+ def session_boundary_state(root: Path) -> Mapping[str, Any] | None:
82
+ """The session boundary computed at session start, if any.
83
+
84
+ The cache key mirrors the shell tooling: the hex MD5 of the project
85
+ path. Reading state written by the boundary machinery is the runtime
86
+ truth for isolation readiness; absence means no session start has
87
+ computed a boundary here yet.
88
+ """
89
+ digest = hashlib.md5(str(root).encode("utf-8")).hexdigest()
90
+ cache = Path("/tmp") / f"egregore-boundary-{digest}.json"
91
+ try:
92
+ value = json.loads(cache.read_text(encoding="utf-8"))
93
+ except (OSError, ValueError):
94
+ return None
95
+ return value if isinstance(value, dict) else None
96
+
97
+
98
+ def _boundary_item(root: Path, boundary: Mapping[str, Any] | None) -> ReadinessItem:
99
+ label = "Trust boundary"
100
+ if boundary is None:
101
+ return ReadinessItem(
102
+ key="boundary",
103
+ label=label,
104
+ stage=STAGE_UNAVAILABLE,
105
+ detail="session boundary not computed yet — run a session start",
106
+ )
107
+ project_dir = str(boundary.get("project_dir") or "")
108
+ if Path(project_dir) != root:
109
+ return ReadinessItem(
110
+ key="boundary",
111
+ label=label,
112
+ stage=STAGE_UNAVAILABLE,
113
+ detail="boundary belongs to another checkout — run a session start here",
114
+ )
115
+ denied = boundary.get("denied_paths")
116
+ if not isinstance(denied, list):
117
+ return ReadinessItem(
118
+ key="boundary",
119
+ label=label,
120
+ stage=STAGE_UNAVAILABLE,
121
+ detail="boundary state is unreadable — run a session start",
122
+ )
123
+ posture = str(boundary.get("posture") or "standard")
124
+ return ReadinessItem(
125
+ key="boundary",
126
+ label=label,
127
+ stage=STAGE_READY,
128
+ detail=(
129
+ f"posture {posture} · {len(denied)} foreign instance"
130
+ f"{'s' if len(denied) != 1 else ''} isolated"
131
+ ),
132
+ )
133
+
134
+
135
+ def _authorization_item(probe: PolicyDecision | Exception | None) -> ReadinessItem:
136
+ label = "Authorization"
137
+ if probe is None:
138
+ return ReadinessItem(
139
+ key="authorization",
140
+ label=label,
141
+ stage=STAGE_UNAVAILABLE,
142
+ detail="no policy answered the authorization probe",
143
+ )
144
+ if isinstance(probe, Exception):
145
+ return ReadinessItem(
146
+ key="authorization",
147
+ label=label,
148
+ stage=STAGE_UNAVAILABLE,
149
+ detail=f"policy probe failed: {str(probe)[:120]}",
150
+ )
151
+ if not probe.allowed:
152
+ reasons = "; ".join(probe.reasons) or "no reason given"
153
+ return ReadinessItem(
154
+ key="authorization",
155
+ label=label,
156
+ stage=STAGE_UNAVAILABLE,
157
+ detail=f"read denied by policy {probe.policy_epoch}: {reasons[:120]}",
158
+ )
159
+ return ReadinessItem(
160
+ key="authorization",
161
+ label=label,
162
+ stage=STAGE_READY,
163
+ detail=f"actor authorized · policy {probe.policy_epoch}",
164
+ )
165
+
166
+
167
+ def _qmd_item(health: RetrieverHealth) -> ReadinessItem:
168
+ label = "QMD"
169
+ if health.available:
170
+ return ReadinessItem(
171
+ key="qmd",
172
+ label=label,
173
+ stage=STAGE_READY,
174
+ detail=f"{health.adapter} {health.adapter_version} pinned",
175
+ )
176
+ reason = health.warnings[0] if health.warnings else "retrieval adapter unavailable"
177
+ return ReadinessItem(
178
+ key="qmd", label=label, stage=STAGE_UNAVAILABLE, detail=str(reason)[:140]
179
+ )
180
+
181
+
182
+ def _reranker_item() -> ReadinessItem:
183
+ if RERANKING_ENABLED:
184
+ return ReadinessItem(
185
+ key="reranker",
186
+ label="Reranker",
187
+ stage=STAGE_READY,
188
+ detail="model reranking enabled",
189
+ )
190
+ return ReadinessItem(
191
+ key="reranker",
192
+ label="Reranker",
193
+ stage=STAGE_DISABLED,
194
+ detail="disabled for the MVP — typed rank fusion only",
195
+ )
196
+
197
+
198
+ def _bm25_item(health: RetrieverHealth) -> ReadinessItem:
199
+ label = "BM25"
200
+ if health.bm25_ready:
201
+ return ReadinessItem(
202
+ key="bm25",
203
+ label=label,
204
+ stage=STAGE_READY,
205
+ detail=f"lexical index usable · {_short_revision(health.index_source_revision)}",
206
+ )
207
+ if health.available and health.canonical_state_ready:
208
+ return ReadinessItem(
209
+ key="bm25",
210
+ label=label,
211
+ stage=STAGE_BUILDING,
212
+ detail="lexical index registering — first update pending",
213
+ )
214
+ return ReadinessItem(
215
+ key="bm25",
216
+ label=label,
217
+ stage=STAGE_UNAVAILABLE,
218
+ detail="no lexical index — retrieval adapter is not available",
219
+ )
220
+
221
+
222
+ def _embeddings_item(health: RetrieverHealth) -> ReadinessItem:
223
+ label = "Embeddings"
224
+ state = health.embedding_state
225
+ if state == "ready":
226
+ return ReadinessItem(
227
+ key="embeddings", label=label, stage=STAGE_READY, detail="vector build complete"
228
+ )
229
+ if state in ("running", "pending"):
230
+ detail = (
231
+ "background embed running — search does not wait for it"
232
+ if state == "running"
233
+ else "documents pending embedding — background embed scheduled"
234
+ )
235
+ return ReadinessItem(
236
+ key="embeddings", label=label, stage=STAGE_BUILDING, detail=detail
237
+ )
238
+ if state == "missing_model":
239
+ return ReadinessItem(
240
+ key="embeddings",
241
+ label=label,
242
+ stage=STAGE_UNAVAILABLE,
243
+ detail="embedding model not installed — lexical retrieval only",
244
+ )
245
+ return ReadinessItem(
246
+ key="embeddings",
247
+ label=label,
248
+ stage=STAGE_UNAVAILABLE,
249
+ detail="no vector build yet",
250
+ )
251
+
252
+
253
+ def _semantic_item(health: RetrieverHealth) -> ReadinessItem:
254
+ label = "Semantic build"
255
+ source = _short_revision(health.source_revision)
256
+ build = _short_revision(health.semantic_source_revision)
257
+ if health.semantic_ready:
258
+ return ReadinessItem(
259
+ key="semantic",
260
+ label=label,
261
+ stage=STAGE_READY,
262
+ detail=f"vectors current at {build}",
263
+ )
264
+ if health.semantic_source_revision:
265
+ return ReadinessItem(
266
+ key="semantic",
267
+ label=label,
268
+ stage=STAGE_BUILDING,
269
+ detail=f"serving {build} while {source} builds",
270
+ )
271
+ return ReadinessItem(
272
+ key="semantic",
273
+ label=label,
274
+ stage=STAGE_UNAVAILABLE,
275
+ detail=f"no complete vector build yet · source {source}",
276
+ )
277
+
278
+
279
+ def _search_item(health: RetrieverHealth) -> ReadinessItem:
280
+ label = "Search"
281
+ if health.bm25_ready and health.semantic_ready:
282
+ return ReadinessItem(
283
+ key="search", label=label, stage=STAGE_READY, detail="hybrid current"
284
+ )
285
+ if health.bm25_ready and health.semantic_source_revision:
286
+ return ReadinessItem(
287
+ key="search",
288
+ label=label,
289
+ stage=STAGE_READY,
290
+ detail="hybrid stays available while embeddings rebuild",
291
+ )
292
+ if health.bm25_ready:
293
+ return ReadinessItem(
294
+ key="search",
295
+ label=label,
296
+ stage=STAGE_READY,
297
+ detail="lexical available until the first vector build completes",
298
+ )
299
+ reason = health.warnings[0] if health.warnings else "retrieval is not available"
300
+ return ReadinessItem(
301
+ key="search", label=label, stage=STAGE_UNAVAILABLE, detail=str(reason)[:140]
302
+ )
303
+
304
+
305
+ def build_report(
306
+ *,
307
+ root: Path,
308
+ health: RetrieverHealth,
309
+ boundary: Mapping[str, Any] | None,
310
+ authorization: PolicyDecision | Exception | None,
311
+ started_monotonic: float | None = None,
312
+ ) -> ReadinessReport:
313
+ """Assemble the staged report from injected Runtime state (deterministic)."""
314
+ started = started_monotonic if started_monotonic is not None else time.monotonic()
315
+ items = (
316
+ _boundary_item(root, boundary),
317
+ _authorization_item(authorization),
318
+ _qmd_item(health),
319
+ _reranker_item(),
320
+ _bm25_item(health),
321
+ _embeddings_item(health),
322
+ _semantic_item(health),
323
+ _search_item(health),
324
+ )
325
+ elapsed_ms = max(0, round((time.monotonic() - started) * 1000))
326
+ return ReadinessReport(items=items, generated_in_ms=elapsed_ms)
327
+
328
+
329
+ def collect_report(root: Path, runtime, *, harness: str, session_id: str) -> ReadinessReport:
330
+ """Gather live Runtime state and assemble the report. Local I/O only."""
331
+ started = time.monotonic()
332
+ health = runtime.retrieval_health()
333
+ boundary = session_boundary_state(root)
334
+ authorization: PolicyDecision | Exception | None
335
+ try:
336
+ actor = runtime.resolve_actor(session_id=session_id, harness=harness)
337
+ authorization = runtime.authorize(actor, Permission.READ)
338
+ except Exception as exc: # readiness must report failures, not raise them
339
+ authorization = exc
340
+ return build_report(
341
+ root=root,
342
+ health=health,
343
+ boundary=boundary,
344
+ authorization=authorization,
345
+ started_monotonic=started,
346
+ )
347
+
348
+
349
+ def render(report: ReadinessReport, *, tty: bool) -> str:
350
+ """Render the staged report for humans. No raw JSON, no command traces."""
351
+ lines: list[str] = []
352
+ if tty:
353
+ lines.append("Egregore Runtime readiness")
354
+ lines.append("┄" * 40)
355
+ else:
356
+ lines.append("egregore runtime readiness")
357
+ width = max(len(item.label) for item in report.items)
358
+ for item in report.items:
359
+ if tty:
360
+ glyph = _GLYPHS.get(item.stage, "○")
361
+ lines.append(f" {glyph} {item.label:<{width}} {item.stage:<11} {item.detail}")
362
+ else:
363
+ lines.append(f"{item.key}: {item.stage} — {item.detail}")
364
+ lines.append(f"rendered in {report.generated_in_ms} ms · local state only, no network")
365
+ return "\n".join(lines)
366
+
367
+
368
+ __all__ = [
369
+ "STAGE_BUILDING",
370
+ "STAGE_DISABLED",
371
+ "STAGE_READY",
372
+ "STAGE_UNAVAILABLE",
373
+ "ReadinessItem",
374
+ "ReadinessReport",
375
+ "build_report",
376
+ "collect_report",
377
+ "render",
378
+ "session_boundary_state",
379
+ ]
@@ -0,0 +1,256 @@
1
+ """Typed canonical write boundary for meetings and user interviews."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from datetime import UTC, datetime
7
+ from pathlib import Path, PurePosixPath
8
+ from typing import Any, Mapping, Sequence
9
+
10
+ from .artifacts import ARTIFACT_SCHEMA_VERSION, CanonicalDocument, artifact_id_from_path, content_digest
11
+ from .contracts import (
12
+ ActorContext,
13
+ ArtifactRelationship,
14
+ CanonicalArtifact,
15
+ Permission,
16
+ SourceProvenance,
17
+ WritebackStatus,
18
+ )
19
+ from .runtime import EgregoreRuntime
20
+ from .policy import scope_allows_path
21
+
22
+
23
+ RESEARCH_INGEST_SCHEMA_VERSION = "egregore-research-ingest/v1"
24
+ KINDS = frozenset({"meeting", "interview"})
25
+ ARTIFACT_TYPES = frozenset(
26
+ {"meeting", "interview", "participant", "decision", "finding", "pattern"}
27
+ )
28
+ MAX_DOCUMENTS = 40
29
+ MAX_BODY_BYTES = 250_000
30
+
31
+
32
+ class ResearchIngestError(ValueError):
33
+ """An analysis package violates the canonical research contract."""
34
+
35
+
36
+ @dataclass(frozen=True, slots=True)
37
+ class ResearchIngestReceipt:
38
+ kind: str
39
+ source_id: str
40
+ status: str
41
+ artifacts: tuple[dict[str, Any], ...]
42
+ warnings: tuple[str, ...]
43
+
44
+ def to_dict(self) -> dict[str, Any]:
45
+ return {
46
+ "schema_version": RESEARCH_INGEST_SCHEMA_VERSION,
47
+ "kind": self.kind,
48
+ "source_id": self.source_id,
49
+ "status": self.status,
50
+ "artifacts": list(self.artifacts),
51
+ "warnings": list(self.warnings),
52
+ }
53
+
54
+
55
+ def _required(mapping: Mapping[str, Any], key: str) -> str:
56
+ value = str(mapping.get(key) or "").strip()
57
+ if not value:
58
+ raise ResearchIngestError(f"{key} is required")
59
+ return value
60
+
61
+
62
+ def _canonical_path(kind: str, value: str, artifact_type: str) -> str:
63
+ raw = value.strip().replace("\\", "/").removeprefix("memory/")
64
+ path = PurePosixPath(raw)
65
+ if path.is_absolute() or ".." in path.parts or path.suffix != ".md":
66
+ raise ResearchIngestError("canonical_path must be a relative Markdown path")
67
+ allowed = (
68
+ ("meetings/", "knowledge/decisions/", "knowledge/findings/", "knowledge/patterns/")
69
+ if kind == "meeting"
70
+ else (
71
+ "research/interviews/",
72
+ "research/participants/",
73
+ "knowledge/findings/",
74
+ "knowledge/patterns/",
75
+ "knowledge/decisions/",
76
+ )
77
+ )
78
+ if not raw.startswith(allowed):
79
+ raise ResearchIngestError(f"canonical_path is outside the {kind} research boundary")
80
+ if artifact_type == "meeting" and not raw.startswith("meetings/"):
81
+ raise ResearchIngestError("meeting briefing must be stored under meetings/")
82
+ if artifact_type == "interview" and not raw.startswith("research/interviews/"):
83
+ raise ResearchIngestError("interview briefing must be stored under research/interviews/")
84
+ if artifact_type == "participant" and not raw.startswith("research/participants/"):
85
+ raise ResearchIngestError("participant record must be stored under research/participants/")
86
+ return raw
87
+
88
+
89
+ def _relationships(values: Any) -> tuple[ArtifactRelationship, ...]:
90
+ if values is None:
91
+ return ()
92
+ if not isinstance(values, Sequence) or isinstance(values, (str, bytes)):
93
+ raise ResearchIngestError("relationships must be a list")
94
+ rows = []
95
+ for item in values:
96
+ if not isinstance(item, Mapping):
97
+ raise ResearchIngestError("relationship entries must be objects")
98
+ rows.append(
99
+ ArtifactRelationship(
100
+ relation=_required(item, "relation"),
101
+ target_id=_required(item, "target_id"),
102
+ )
103
+ )
104
+ return tuple(rows)
105
+
106
+
107
+ class CanonicalResearchIngestService:
108
+ """Validate metadata, authorize, then inspect and persist analysis content."""
109
+
110
+ def __init__(self, runtime: EgregoreRuntime, *, clock=None, content_loader=None) -> None:
111
+ self.runtime = runtime
112
+ self.clock = clock or (lambda: datetime.now(UTC))
113
+ self.content_loader = content_loader or (
114
+ lambda body_path: Path(body_path).read_text(encoding="utf-8")
115
+ )
116
+
117
+ def ingest(
118
+ self,
119
+ actor: ActorContext,
120
+ package: Mapping[str, Any],
121
+ *,
122
+ expected_kind: str | None = None,
123
+ ) -> ResearchIngestReceipt:
124
+ schema = _required(package, "schema_version")
125
+ if schema != RESEARCH_INGEST_SCHEMA_VERSION:
126
+ raise ResearchIngestError(f"unsupported schema_version: {schema}")
127
+ kind = _required(package, "kind").casefold()
128
+ if kind not in KINDS or (expected_kind and kind != expected_kind):
129
+ raise ResearchIngestError("research package kind does not match the requested adapter")
130
+ source = package.get("source")
131
+ if not isinstance(source, Mapping):
132
+ raise ResearchIngestError("source must be an object")
133
+ source_type = _required(source, "type")
134
+ source_id = _required(source, "id")
135
+ source_revision = _required(source, "revision")
136
+ source_content_hash = _required(source, "content_hash")
137
+ documents = package.get("documents")
138
+ if not isinstance(documents, Sequence) or isinstance(documents, (str, bytes)):
139
+ raise ResearchIngestError("documents must be a list")
140
+ if not documents or len(documents) > MAX_DOCUMENTS:
141
+ raise ResearchIngestError(f"documents must contain 1-{MAX_DOCUMENTS} entries")
142
+
143
+ # Metadata is intentionally validated before any body is accessed.
144
+ metadata: list[tuple[Mapping[str, Any], str, str, str, str, str]] = []
145
+ resources = []
146
+ for raw in documents:
147
+ if not isinstance(raw, Mapping):
148
+ raise ResearchIngestError("document entries must be objects")
149
+ artifact_type = _required(raw, "artifact_type").casefold()
150
+ if artifact_type not in ARTIFACT_TYPES:
151
+ raise ResearchIngestError(f"unsupported research artifact_type: {artifact_type}")
152
+ title = _required(raw, "title")
153
+ status = str(raw.get("status") or "active").strip()
154
+ body_path = _required(raw, "body_path")
155
+ canonical_path = _canonical_path(
156
+ kind, _required(raw, "canonical_path"), artifact_type
157
+ )
158
+ artifact_id = str(raw.get("id") or artifact_id_from_path(canonical_path)).strip()
159
+ metadata.append((raw, artifact_type, title, status, canonical_path, body_path))
160
+ resources.append(artifact_id)
161
+
162
+ decision = self.runtime.authorize(actor, Permission.WRITE, tuple(resources))
163
+ if not decision.allowed:
164
+ raise PermissionError("; ".join(decision.reasons) or "research ingest denied")
165
+
166
+ for _, _, _, _, canonical_path, _ in metadata:
167
+ if decision.scopes and not scope_allows_path(
168
+ f"memory/{canonical_path}", decision.scopes
169
+ ):
170
+ raise PermissionError(
171
+ "research artifact path is outside the actor's authorized scope"
172
+ )
173
+
174
+ now = self.clock().astimezone(UTC)
175
+ provenance = SourceProvenance(
176
+ source_type=source_type,
177
+ source_id=source_id,
178
+ revision=source_revision,
179
+ content_hash=source_content_hash,
180
+ observed_at=now,
181
+ source_uri=str(source.get("uri")) if source.get("uri") else None,
182
+ imported_by=actor.actor.actor_id,
183
+ )
184
+ prepared_documents: list[CanonicalDocument] = []
185
+ for raw, artifact_type, title, status, canonical_path, body_path in metadata:
186
+ body = self.content_loader(body_path)
187
+ if not isinstance(body, str) or not body.strip():
188
+ raise ResearchIngestError("document body is required")
189
+ if len(body.encode("utf-8")) > MAX_BODY_BYTES:
190
+ raise ResearchIngestError("document body exceeds the research ingest limit")
191
+ digest = content_digest(body)
192
+ artifact_id = str(raw.get("id") or artifact_id_from_path(canonical_path)).strip()
193
+ artifact = CanonicalArtifact(
194
+ schema_version=ARTIFACT_SCHEMA_VERSION,
195
+ artifact_id=artifact_id,
196
+ org_id=actor.profile.org_id,
197
+ artifact_type=artifact_type,
198
+ title=title,
199
+ created_at=now,
200
+ created_by=actor.actor.actor_id,
201
+ status=status,
202
+ canonical_path=canonical_path,
203
+ revision=f"sha256:{digest[:16]}",
204
+ content_hash=digest,
205
+ workstream=str(raw.get("workstream")) if raw.get("workstream") else None,
206
+ visibility=tuple(str(item) for item in (raw.get("visibility") or ())),
207
+ relationships=_relationships(raw.get("relationships")),
208
+ supersedes=tuple(str(item) for item in (raw.get("supersedes") or ())),
209
+ provenance=(provenance,),
210
+ )
211
+ legacy_fields = dict(raw.get("metadata") or {})
212
+ legacy_fields.update(
213
+ {
214
+ "research_ingest_schema": RESEARCH_INGEST_SCHEMA_VERSION,
215
+ "research_kind": kind,
216
+ "source_type": source_type,
217
+ "source_id": source_id,
218
+ "source_revision": source_revision,
219
+ }
220
+ )
221
+ prepared_documents.append(
222
+ CanonicalDocument(
223
+ artifact=artifact,
224
+ body=body,
225
+ policy_hints=dict(raw.get("policy_hints") or {}),
226
+ legacy_fields=legacy_fields,
227
+ )
228
+ )
229
+
230
+ receipts = self.runtime.write_documents(actor, tuple(prepared_documents))
231
+ rows = []
232
+ warnings: list[str] = []
233
+ for receipt in receipts:
234
+ rows.append(
235
+ {
236
+ "artifact_id": receipt.artifact.artifact_id,
237
+ "canonical_path": f"memory/{receipt.artifact.canonical_path}",
238
+ "status": receipt.status.value,
239
+ "git_revision": receipt.git_revision,
240
+ "index_revision": receipt.index_revision,
241
+ "embedding_state": receipt.embedding_state,
242
+ }
243
+ )
244
+ warnings.extend(
245
+ warning for warning in receipt.warnings if warning not in warnings
246
+ )
247
+
248
+ statuses = {row["status"] for row in rows}
249
+ overall = (
250
+ WritebackStatus.REJECTED.value
251
+ if statuses == {WritebackStatus.REJECTED.value}
252
+ else WritebackStatus.PARTIAL.value
253
+ if warnings or WritebackStatus.REJECTED.value in statuses or WritebackStatus.PARTIAL.value in statuses
254
+ else WritebackStatus.ACCEPTED.value
255
+ )
256
+ return ResearchIngestReceipt(kind, source_id, overall, tuple(rows), tuple(warnings))
@@ -0,0 +1,44 @@
1
+ """Shell adapter for canonical meeting and interview writeback."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ import os
8
+ from pathlib import Path
9
+ import sys
10
+
11
+ from .research_ingest import CanonicalResearchIngestService, ResearchIngestError
12
+ from .runtime import local_runtime
13
+
14
+
15
+ def main() -> int:
16
+ parser = argparse.ArgumentParser(prog="egregore-research-ingest")
17
+ parser.add_argument("kind", choices=("meeting", "interview"))
18
+ parser.add_argument("--input", required=True, help="analysis package JSON")
19
+ parser.add_argument("--no-push", action="store_true")
20
+ args = parser.parse_args()
21
+ root = Path(os.environ.get("EGREGORE_ROOT") or Path.cwd()).resolve()
22
+ runtime = local_runtime(root, push_remote=not args.no_push)
23
+ session_path = root / ".egregore-session-id"
24
+ session_id = os.environ.get("EGREGORE_SESSION_ID")
25
+ if not session_id and session_path.is_file():
26
+ session_id = session_path.read_text(encoding="utf-8").splitlines()[0].strip()
27
+ actor = runtime.resolve_actor(
28
+ session_id=session_id or "research-ingest-shell",
29
+ harness=os.environ.get("EGREGORE_RUNTIME", "shell"),
30
+ )
31
+ package = json.loads(Path(args.input).read_text(encoding="utf-8"))
32
+ receipt = CanonicalResearchIngestService(runtime).ingest(
33
+ actor, package, expected_kind=args.kind
34
+ )
35
+ print(json.dumps(receipt.to_dict(), ensure_ascii=False, separators=(",", ":")))
36
+ return 0 if receipt.status in {"accepted", "partial"} else 1
37
+
38
+
39
+ if __name__ == "__main__":
40
+ try:
41
+ raise SystemExit(main())
42
+ except (json.JSONDecodeError, OSError, PermissionError, ResearchIngestError) as exc:
43
+ print(f"research-ingest: {exc}", file=sys.stderr)
44
+ raise SystemExit(1) from exc