create-egregore 0.21.6 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (719) hide show
  1. package/assets/egregore-launcher.js +58 -6
  2. package/assets/egregore-launcher.sh +15 -2
  3. package/lib/claude-runtime.js +2 -0
  4. package/lib/codex-runtime.js +2 -0
  5. package/lib/setup.js +20 -3
  6. package/package.json +2 -2
  7. package/runtime/claude/.claude/context/commit-format.md +7 -4
  8. package/runtime/claude/.claude/context/handoff-claiming.md +32 -0
  9. package/runtime/claude/.claude/context/notification-consent.md +12 -9
  10. package/runtime/claude/.claude/hooks/boundary-check.sh +14 -331
  11. package/runtime/claude/.claude/hooks/memory-read-guard.sh +9 -1
  12. package/runtime/claude/.claude/rules/voice-bedrock.md +6 -2
  13. package/runtime/claude/.claude/settings.json +1 -1
  14. package/runtime/claude/.claude/skills/commit/SKILL.md +5 -3
  15. package/runtime/claude/.claude/skills/dark-mode/SKILL.md +48 -369
  16. package/runtime/claude/.claude/skills/records/SKILL.md +158 -0
  17. package/runtime/claude/.claude/skills/reflect/SKILL.md +50 -21
  18. package/runtime/claude/.claude/skills/review-pr/SKILL.md +4 -2
  19. package/runtime/claude/.claude/skills/save/SKILL.md +9 -3
  20. package/runtime/claude/.claude/skills/summon/SKILL.md +138 -207
  21. package/runtime/claude/.claude/skills/tui-design/SKILL.md +1 -1
  22. package/runtime/claude/.claude/skills/update/SKILL.md +1 -1
  23. package/runtime/claude/.claude/skills/view/SKILL.md +52 -16
  24. package/runtime/claude/.claude/skills/view/compose-scaffold.html +19 -13
  25. package/runtime/claude/CLAUDE.md +59 -95
  26. package/runtime/claude/bin/agent.sh +231 -7
  27. package/runtime/claude/bin/api-call.sh +44 -23
  28. package/runtime/claude/bin/artifact-register.sh +7 -1
  29. package/runtime/claude/bin/artifact-writeback.sh +1 -1
  30. package/runtime/claude/bin/artifacts.sh +66 -265
  31. package/runtime/claude/bin/attendant.sh +4 -1
  32. package/runtime/claude/bin/boundary-guard.cjs +1848 -0
  33. package/runtime/claude/bin/boundary-hook.sh +41 -0
  34. package/runtime/claude/bin/boundary.sh +15 -155
  35. package/runtime/claude/bin/capture-run.sh +32 -2
  36. package/runtime/claude/bin/codex-render-spec.mjs +24 -46
  37. package/runtime/claude/bin/codex-session-start.sh +19 -0
  38. package/runtime/claude/bin/codex-skill-render.mjs +18 -0
  39. package/runtime/claude/bin/config-get.sh +10 -1
  40. package/runtime/claude/bin/connect-refresh.sh +16 -0
  41. package/runtime/claude/bin/corpus_map.py +5 -0
  42. package/runtime/claude/bin/data/capabilities/claude.json +1480 -0
  43. package/runtime/claude/bin/genui.sh +19 -0
  44. package/runtime/claude/bin/graph-batch.sh +1 -1
  45. package/runtime/claude/bin/graph-op.sh +14 -0
  46. package/runtime/claude/bin/graph.sh +1 -1
  47. package/runtime/claude/bin/handoff-pr-backfill.sh +1 -1
  48. package/runtime/claude/bin/handoff-run.sh +11 -6
  49. package/runtime/claude/bin/ingest-item.sh +1 -1
  50. package/runtime/claude/bin/ingest-surface.html +22 -4
  51. package/runtime/claude/bin/issue.sh +1 -1
  52. package/runtime/claude/bin/knowledge.sh +1 -1
  53. package/runtime/claude/bin/lib/card-delivery.sh +329 -0
  54. package/runtime/claude/bin/lib/config.sh +148 -3
  55. package/runtime/claude/bin/lib/context.sh +38 -67
  56. package/runtime/claude/bin/lib/genui-entry.py +36 -0
  57. package/runtime/claude/bin/lib/git-message.sh +25 -6
  58. package/runtime/claude/bin/lib/git-sync.sh +12 -4
  59. package/runtime/claude/bin/lib/greeting.sh +255 -28
  60. package/runtime/claude/bin/lib/handoff_meta.py +294 -0
  61. package/runtime/claude/bin/lib/health-footer.sh +83 -2
  62. package/runtime/claude/bin/lib/identity.sh +31 -10
  63. package/runtime/claude/bin/lib/instance-registry.sh +71 -0
  64. package/runtime/claude/bin/lib/local_ci_receipt.py +249 -0
  65. package/runtime/claude/bin/lib/metrics.sh +121 -8
  66. package/runtime/claude/bin/lib/notices.sh +36 -0
  67. package/runtime/claude/bin/lib/record_outcomes.py +729 -0
  68. package/runtime/claude/bin/lib/reflexes.py +267 -0
  69. package/runtime/claude/bin/lib/retrieval_scorecard.py +624 -0
  70. package/runtime/claude/bin/lib/session-record-prompt.txt +18 -0
  71. package/runtime/claude/bin/lib/session_record.py +3747 -0
  72. package/runtime/claude/bin/lib/session_trail.py +1983 -0
  73. package/runtime/claude/bin/lib/settings-drift.sh +8 -5
  74. package/runtime/claude/bin/lib/startup-restart.sh +41 -0
  75. package/runtime/claude/bin/lib/worktree-links.sh +92 -0
  76. package/runtime/claude/bin/memory-push.sh +6 -0
  77. package/runtime/claude/bin/merge-gate.sh +498 -0
  78. package/runtime/claude/bin/notify.sh +5 -2
  79. package/runtime/claude/bin/page-access.sh +103 -0
  80. package/runtime/claude/bin/person.sh +13 -2
  81. package/runtime/claude/bin/pi-render-spec.mjs +0 -1
  82. package/runtime/claude/bin/pi-spirit-discovery.mjs +34 -0
  83. package/runtime/claude/bin/post-update.sh +181 -0
  84. package/runtime/claude/bin/prime-render-spec.mjs +0 -1
  85. package/runtime/claude/bin/publish-artifact.sh +89 -42
  86. package/runtime/claude/bin/qa-inventory.sh +2 -2
  87. package/runtime/claude/bin/quest.sh +1 -1
  88. package/runtime/claude/bin/records.sh +11 -0
  89. package/runtime/claude/bin/reflexes/05-vitals.sh +9 -0
  90. package/runtime/claude/bin/reflexes/10-open-items.sh +12 -0
  91. package/runtime/claude/bin/reflexes/15-retrieval.sh +8 -0
  92. package/runtime/claude/bin/reflexes/20-nightly.sh +100 -0
  93. package/runtime/claude/bin/reflexes/20-sandbox.sh +85 -0
  94. package/runtime/claude/bin/reflexes/30-cost.py +116 -0
  95. package/runtime/claude/bin/reflexes/40-shells.py +51 -0
  96. package/runtime/claude/bin/reflexes/README.md +61 -0
  97. package/runtime/claude/bin/reflexes.sh +7 -0
  98. package/runtime/claude/bin/runtime-identity.sh +140 -42
  99. package/runtime/claude/bin/screenshot.sh +77 -0
  100. package/runtime/claude/bin/scroll.sh +1 -1
  101. package/runtime/claude/bin/search.sh +31 -5
  102. package/runtime/claude/bin/session-autosave.sh +6 -3
  103. package/runtime/claude/bin/session-id.sh +147 -0
  104. package/runtime/claude/bin/session-log.sh +19 -0
  105. package/runtime/claude/bin/session-record.sh +26 -0
  106. package/runtime/claude/bin/session-start.sh +121 -151
  107. package/runtime/claude/bin/settings.sh +13 -8
  108. package/runtime/claude/bin/spirit-discovery-claude.sh +4 -0
  109. package/runtime/claude/bin/spirit-discovery-codex.sh +4 -0
  110. package/runtime/claude/bin/spirit-discovery-pi.sh +4 -0
  111. package/runtime/claude/bin/spirit-discovery-prime.sh +4 -0
  112. package/runtime/claude/bin/spirit-discovery.sh +4 -0
  113. package/runtime/claude/bin/startup-check.sh +1 -1
  114. package/runtime/claude/bin/telemetry.sh +11 -4
  115. package/runtime/claude/bin/test-baseline.sh +33 -5
  116. package/runtime/claude/bin/todo.sh +1 -1
  117. package/runtime/claude/bin/worktree-create.sh +15 -45
  118. package/runtime/claude/bin/worktree.sh +6 -0
  119. package/runtime/claude/docs/spirit-discovery.md +96 -0
  120. package/runtime/claude/egregore_runtime/__init__.py +18 -12
  121. package/runtime/claude/egregore_runtime/access.py +608 -0
  122. package/runtime/claude/egregore_runtime/access_cli.py +190 -0
  123. package/runtime/claude/egregore_runtime/adapters/invitation.py +5 -3
  124. package/runtime/claude/egregore_runtime/adapters/qmd.py +521 -47
  125. package/runtime/claude/egregore_runtime/admin_entry.py +56 -0
  126. package/runtime/claude/egregore_runtime/artifacts.py +222 -16
  127. package/runtime/claude/egregore_runtime/contracts.py +27 -0
  128. package/runtime/claude/egregore_runtime/eligibility.py +5 -12
  129. package/runtime/claude/egregore_runtime/episode_binding.py +16 -5
  130. package/runtime/claude/egregore_runtime/github_issues.py +2 -2
  131. package/runtime/claude/egregore_runtime/handoff_lookup.py +9 -20
  132. package/runtime/claude/egregore_runtime/harness_cli.py +674 -149
  133. package/runtime/claude/egregore_runtime/held.py +2436 -0
  134. package/runtime/claude/egregore_runtime/hosted_api.py +137 -0
  135. package/runtime/claude/egregore_runtime/identity.py +196 -65
  136. package/runtime/claude/egregore_runtime/identity_transfer.py +6 -2
  137. package/runtime/claude/egregore_runtime/ingest_cli.py +2 -2
  138. package/runtime/claude/egregore_runtime/ingest_index_cli.py +4 -16
  139. package/runtime/claude/egregore_runtime/installation.py +119 -0
  140. package/runtime/claude/egregore_runtime/investigation.py +64 -41
  141. package/runtime/claude/egregore_runtime/investigation_guidance.py +16 -11
  142. package/runtime/claude/egregore_runtime/issue_cli.py +51 -32
  143. package/runtime/claude/egregore_runtime/issue_reporting.py +4 -3
  144. package/runtime/claude/egregore_runtime/issue_triage_service.py +2 -2
  145. package/runtime/claude/egregore_runtime/issues.py +12 -6
  146. package/runtime/claude/egregore_runtime/knowledge.py +331 -5
  147. package/runtime/claude/egregore_runtime/knowledge_cli.py +57 -17
  148. package/runtime/claude/egregore_runtime/lifecycle.py +88 -22
  149. package/runtime/claude/egregore_runtime/lifecycle_cli.py +21 -13
  150. package/runtime/claude/egregore_runtime/line_ids.py +10 -0
  151. package/runtime/claude/egregore_runtime/memory_push.py +349 -0
  152. package/runtime/claude/egregore_runtime/observe.py +64 -25
  153. package/runtime/claude/egregore_runtime/observers.py +19 -0
  154. package/runtime/claude/egregore_runtime/optional_modules.py +13 -0
  155. package/runtime/claude/egregore_runtime/outputs_cli.py +321 -0
  156. package/runtime/claude/egregore_runtime/policy.py +651 -24
  157. package/runtime/claude/egregore_runtime/private_result.py +2 -1
  158. package/runtime/claude/egregore_runtime/projection.py +946 -0
  159. package/runtime/claude/egregore_runtime/quest_cli.py +20 -23
  160. package/runtime/claude/egregore_runtime/question_cli.py +15 -11
  161. package/runtime/claude/egregore_runtime/questions.py +10 -10
  162. package/runtime/claude/egregore_runtime/quests.py +10 -10
  163. package/runtime/claude/egregore_runtime/record_publish.py +548 -0
  164. package/runtime/claude/egregore_runtime/record_subject.py +564 -0
  165. package/runtime/claude/egregore_runtime/research_ingest.py +2 -4
  166. package/runtime/claude/egregore_runtime/runtime.py +169 -60
  167. package/runtime/claude/egregore_runtime/sandbox.py +194 -0
  168. package/runtime/claude/egregore_runtime/scroll_cli.py +22 -32
  169. package/runtime/claude/egregore_runtime/scrolls.py +23 -15
  170. package/runtime/claude/egregore_runtime/shadow.py +262 -0
  171. package/runtime/claude/egregore_runtime/spirit_discovery.py +487 -0
  172. package/runtime/claude/egregore_runtime/spirit_discovery_cli.py +25 -0
  173. package/runtime/claude/egregore_runtime/spirit_discovery_transport.py +18 -0
  174. package/runtime/claude/egregore_runtime/status.py +101 -44
  175. package/runtime/claude/egregore_runtime/status_cli.py +13 -5
  176. package/runtime/claude/egregore_runtime/sync.py +39 -21
  177. package/runtime/claude/egregore_runtime/taste.py +934 -0
  178. package/runtime/claude/egregore_runtime/taste_cli.py +242 -0
  179. package/runtime/claude/egregore_runtime/taste_rules.py +91 -0
  180. package/runtime/claude/egregore_runtime/telemetry.py +26 -3
  181. package/runtime/claude/egregore_runtime/todo_cli.py +15 -12
  182. package/runtime/claude/egregore_runtime/todos.py +3 -2
  183. package/runtime/claude/egregore_runtime/upgrade.py +85 -58
  184. package/runtime/claude/egregore_runtime/writeback.py +330 -24
  185. package/runtime/claude/manifest.json +65 -5
  186. package/runtime/codex/.claude/context/handoff-claiming.md +32 -0
  187. package/runtime/codex/.claude/context/notification-consent.md +12 -9
  188. package/runtime/codex/.claude/skills/view/SKILL.md +438 -0
  189. package/runtime/codex/.codex/hooks.json +11 -0
  190. package/runtime/codex/.codex/skills/dark-mode/SKILL.md +1 -1
  191. package/runtime/codex/.codex/skills/records/SKILL.md +29 -0
  192. package/runtime/codex/.codex/skills/summon/SKILL.md +1 -1
  193. package/runtime/codex/.codex/skills/view/assets/compose-scaffold.html +19 -13
  194. package/runtime/codex/.codex/spec-manifest.json +13 -19
  195. package/runtime/codex/AGENTS.md +54 -105
  196. package/runtime/codex/bin/agent.sh +231 -7
  197. package/runtime/codex/bin/api-call.sh +44 -23
  198. package/runtime/codex/bin/artifact-register.sh +7 -1
  199. package/runtime/codex/bin/artifact-writeback.sh +1 -1
  200. package/runtime/codex/bin/artifacts.sh +66 -265
  201. package/runtime/codex/bin/attendant.sh +4 -1
  202. package/runtime/codex/bin/boundary-guard.cjs +1848 -0
  203. package/runtime/codex/bin/boundary-hook.sh +41 -0
  204. package/runtime/codex/bin/capture-run.sh +32 -2
  205. package/runtime/codex/bin/codex-render-spec.mjs +24 -46
  206. package/runtime/codex/bin/codex-session-start.sh +19 -0
  207. package/runtime/codex/bin/codex-skill-render.mjs +18 -0
  208. package/runtime/codex/bin/config-get.sh +10 -1
  209. package/runtime/codex/bin/connect-refresh.sh +16 -0
  210. package/runtime/codex/bin/corpus_map.py +5 -0
  211. package/runtime/codex/bin/data/capabilities/codex.json +1458 -0
  212. package/runtime/codex/bin/genui.sh +19 -0
  213. package/runtime/codex/bin/graph-batch.sh +1 -1
  214. package/runtime/codex/bin/graph-op.sh +14 -0
  215. package/runtime/codex/bin/graph.sh +1 -1
  216. package/runtime/codex/bin/handoff-pr-backfill.sh +1 -1
  217. package/runtime/codex/bin/handoff-run.sh +11 -6
  218. package/runtime/codex/bin/ingest-item.sh +1 -1
  219. package/runtime/codex/bin/ingest-surface.html +22 -4
  220. package/runtime/codex/bin/issue.sh +1 -1
  221. package/runtime/codex/bin/knowledge.sh +1 -1
  222. package/runtime/codex/bin/lib/card-delivery.sh +329 -0
  223. package/runtime/codex/bin/lib/config.sh +148 -3
  224. package/runtime/codex/bin/lib/context.sh +38 -67
  225. package/runtime/codex/bin/lib/genui-entry.py +36 -0
  226. package/runtime/codex/bin/lib/git-message.sh +25 -6
  227. package/runtime/codex/bin/lib/git-sync.sh +12 -4
  228. package/runtime/codex/bin/lib/greeting.sh +255 -28
  229. package/runtime/codex/bin/lib/handoff_meta.py +294 -0
  230. package/runtime/codex/bin/lib/health-footer.sh +83 -2
  231. package/runtime/codex/bin/lib/identity.sh +31 -10
  232. package/runtime/codex/bin/lib/instance-registry.sh +71 -0
  233. package/runtime/codex/bin/lib/local_ci_receipt.py +249 -0
  234. package/runtime/codex/bin/lib/metrics.sh +121 -8
  235. package/runtime/codex/bin/lib/notices.sh +36 -0
  236. package/runtime/codex/bin/lib/record_outcomes.py +729 -0
  237. package/runtime/codex/bin/lib/reflexes.py +267 -0
  238. package/runtime/codex/bin/lib/retrieval_scorecard.py +624 -0
  239. package/runtime/codex/bin/lib/session-record-prompt.txt +18 -0
  240. package/runtime/codex/bin/lib/session_record.py +3747 -0
  241. package/runtime/codex/bin/lib/session_trail.py +1983 -0
  242. package/runtime/codex/bin/lib/settings-drift.sh +8 -5
  243. package/runtime/codex/bin/lib/startup-restart.sh +41 -0
  244. package/runtime/codex/bin/lib/worktree-links.sh +92 -0
  245. package/runtime/codex/bin/memory-push.sh +6 -0
  246. package/runtime/codex/bin/merge-gate.sh +498 -0
  247. package/runtime/codex/bin/notify.sh +5 -2
  248. package/runtime/codex/bin/page-access.sh +103 -0
  249. package/runtime/codex/bin/person.sh +13 -2
  250. package/runtime/codex/bin/pi-render-spec.mjs +0 -1
  251. package/runtime/codex/bin/pi-spirit-discovery.mjs +34 -0
  252. package/runtime/codex/bin/post-update.sh +181 -0
  253. package/runtime/codex/bin/prime-render-spec.mjs +0 -1
  254. package/runtime/codex/bin/publish-artifact.sh +89 -42
  255. package/runtime/codex/bin/qa-inventory.sh +2 -2
  256. package/runtime/codex/bin/quest.sh +1 -1
  257. package/runtime/codex/bin/records.sh +11 -0
  258. package/runtime/codex/bin/reflexes/05-vitals.sh +9 -0
  259. package/runtime/codex/bin/reflexes/10-open-items.sh +12 -0
  260. package/runtime/codex/bin/reflexes/15-retrieval.sh +8 -0
  261. package/runtime/codex/bin/reflexes/20-nightly.sh +100 -0
  262. package/runtime/codex/bin/reflexes/20-sandbox.sh +85 -0
  263. package/runtime/codex/bin/reflexes/30-cost.py +116 -0
  264. package/runtime/codex/bin/reflexes/40-shells.py +51 -0
  265. package/runtime/codex/bin/reflexes/README.md +61 -0
  266. package/runtime/codex/bin/reflexes.sh +7 -0
  267. package/runtime/codex/bin/runtime-identity.sh +140 -42
  268. package/runtime/codex/bin/screenshot.sh +77 -0
  269. package/runtime/codex/bin/scroll.sh +1 -1
  270. package/runtime/codex/bin/search.sh +31 -5
  271. package/runtime/codex/bin/session-autosave.sh +6 -3
  272. package/runtime/codex/bin/session-id.sh +147 -0
  273. package/runtime/codex/bin/session-log.sh +19 -0
  274. package/runtime/codex/bin/session-record.sh +26 -0
  275. package/runtime/codex/bin/settings.sh +13 -8
  276. package/runtime/codex/bin/spirit-discovery-claude.sh +4 -0
  277. package/runtime/codex/bin/spirit-discovery-codex.sh +4 -0
  278. package/runtime/codex/bin/spirit-discovery-pi.sh +4 -0
  279. package/runtime/codex/bin/spirit-discovery-prime.sh +4 -0
  280. package/runtime/codex/bin/spirit-discovery.sh +4 -0
  281. package/runtime/codex/bin/startup-check.sh +1 -1
  282. package/runtime/codex/bin/telemetry.sh +11 -4
  283. package/runtime/codex/bin/test-baseline.sh +33 -5
  284. package/runtime/codex/bin/todo.sh +1 -1
  285. package/runtime/codex/bin/worktree-create.sh +15 -45
  286. package/runtime/codex/bin/worktree.sh +6 -0
  287. package/runtime/codex/docs/spirit-discovery.md +96 -0
  288. package/runtime/codex/egregore_runtime/__init__.py +18 -12
  289. package/runtime/codex/egregore_runtime/access.py +608 -0
  290. package/runtime/codex/egregore_runtime/access_cli.py +190 -0
  291. package/runtime/codex/egregore_runtime/adapters/invitation.py +5 -3
  292. package/runtime/codex/egregore_runtime/adapters/qmd.py +521 -47
  293. package/runtime/codex/egregore_runtime/admin_entry.py +56 -0
  294. package/runtime/codex/egregore_runtime/artifacts.py +222 -16
  295. package/runtime/codex/egregore_runtime/contracts.py +27 -0
  296. package/runtime/codex/egregore_runtime/eligibility.py +5 -12
  297. package/runtime/codex/egregore_runtime/episode_binding.py +16 -5
  298. package/runtime/codex/egregore_runtime/github_issues.py +2 -2
  299. package/runtime/codex/egregore_runtime/handoff_lookup.py +9 -20
  300. package/runtime/codex/egregore_runtime/harness_cli.py +674 -149
  301. package/runtime/codex/egregore_runtime/held.py +2436 -0
  302. package/runtime/codex/egregore_runtime/hosted_api.py +137 -0
  303. package/runtime/codex/egregore_runtime/identity.py +196 -65
  304. package/runtime/codex/egregore_runtime/identity_transfer.py +6 -2
  305. package/runtime/codex/egregore_runtime/ingest_cli.py +2 -2
  306. package/runtime/codex/egregore_runtime/ingest_index_cli.py +4 -16
  307. package/runtime/codex/egregore_runtime/installation.py +119 -0
  308. package/runtime/codex/egregore_runtime/investigation.py +64 -41
  309. package/runtime/codex/egregore_runtime/investigation_guidance.py +16 -11
  310. package/runtime/codex/egregore_runtime/issue_cli.py +51 -32
  311. package/runtime/codex/egregore_runtime/issue_reporting.py +4 -3
  312. package/runtime/codex/egregore_runtime/issue_triage_service.py +2 -2
  313. package/runtime/codex/egregore_runtime/issues.py +12 -6
  314. package/runtime/codex/egregore_runtime/knowledge.py +331 -5
  315. package/runtime/codex/egregore_runtime/knowledge_cli.py +57 -17
  316. package/runtime/codex/egregore_runtime/lifecycle.py +88 -22
  317. package/runtime/codex/egregore_runtime/lifecycle_cli.py +21 -13
  318. package/runtime/codex/egregore_runtime/line_ids.py +10 -0
  319. package/runtime/codex/egregore_runtime/memory_push.py +349 -0
  320. package/runtime/codex/egregore_runtime/observe.py +64 -25
  321. package/runtime/codex/egregore_runtime/observers.py +19 -0
  322. package/runtime/codex/egregore_runtime/optional_modules.py +13 -0
  323. package/runtime/codex/egregore_runtime/outputs_cli.py +321 -0
  324. package/runtime/codex/egregore_runtime/policy.py +651 -24
  325. package/runtime/codex/egregore_runtime/private_result.py +2 -1
  326. package/runtime/codex/egregore_runtime/projection.py +946 -0
  327. package/runtime/codex/egregore_runtime/quest_cli.py +20 -23
  328. package/runtime/codex/egregore_runtime/question_cli.py +15 -11
  329. package/runtime/codex/egregore_runtime/questions.py +10 -10
  330. package/runtime/codex/egregore_runtime/quests.py +10 -10
  331. package/runtime/codex/egregore_runtime/record_publish.py +548 -0
  332. package/runtime/codex/egregore_runtime/record_subject.py +564 -0
  333. package/runtime/codex/egregore_runtime/research_ingest.py +2 -4
  334. package/runtime/codex/egregore_runtime/runtime.py +169 -60
  335. package/runtime/codex/egregore_runtime/sandbox.py +194 -0
  336. package/runtime/codex/egregore_runtime/scroll_cli.py +22 -32
  337. package/runtime/codex/egregore_runtime/scrolls.py +23 -15
  338. package/runtime/codex/egregore_runtime/shadow.py +262 -0
  339. package/runtime/codex/egregore_runtime/spirit_discovery.py +487 -0
  340. package/runtime/codex/egregore_runtime/spirit_discovery_cli.py +25 -0
  341. package/runtime/codex/egregore_runtime/spirit_discovery_transport.py +18 -0
  342. package/runtime/codex/egregore_runtime/status.py +101 -44
  343. package/runtime/codex/egregore_runtime/status_cli.py +13 -5
  344. package/runtime/codex/egregore_runtime/sync.py +39 -21
  345. package/runtime/codex/egregore_runtime/taste.py +934 -0
  346. package/runtime/codex/egregore_runtime/taste_cli.py +242 -0
  347. package/runtime/codex/egregore_runtime/taste_rules.py +91 -0
  348. package/runtime/codex/egregore_runtime/telemetry.py +26 -3
  349. package/runtime/codex/egregore_runtime/todo_cli.py +15 -12
  350. package/runtime/codex/egregore_runtime/todos.py +3 -2
  351. package/runtime/codex/egregore_runtime/upgrade.py +85 -58
  352. package/runtime/codex/egregore_runtime/writeback.py +330 -24
  353. package/runtime/codex/manifest.json +66 -5
  354. package/runtime/pi/.claude/context/handoff-claiming.md +32 -0
  355. package/runtime/pi/.claude/context/notification-consent.md +12 -9
  356. package/runtime/pi/.claude/skills/view/SKILL.md +438 -0
  357. package/runtime/pi/.codex/hooks.json +11 -0
  358. package/runtime/pi/.codex/skills/dark-mode/SKILL.md +1 -1
  359. package/runtime/pi/.codex/skills/records/SKILL.md +29 -0
  360. package/runtime/pi/.codex/skills/summon/SKILL.md +1 -1
  361. package/runtime/pi/.codex/skills/view/assets/compose-scaffold.html +19 -13
  362. package/runtime/pi/.codex/spec-manifest.json +13 -19
  363. package/runtime/pi/.pi/APPEND_SYSTEM.md +53 -99
  364. package/runtime/pi/.pi/extensions/egregore.ts +13 -1
  365. package/runtime/pi/.pi/spec-manifest.json +2 -2
  366. package/runtime/pi/AGENTS.md +54 -105
  367. package/runtime/pi/bin/agent.sh +231 -7
  368. package/runtime/pi/bin/api-call.sh +44 -23
  369. package/runtime/pi/bin/artifact-register.sh +7 -1
  370. package/runtime/pi/bin/artifact-writeback.sh +1 -1
  371. package/runtime/pi/bin/artifacts.sh +66 -265
  372. package/runtime/pi/bin/attendant.sh +4 -1
  373. package/runtime/pi/bin/boundary-guard.cjs +1848 -0
  374. package/runtime/pi/bin/boundary-hook.sh +41 -0
  375. package/runtime/pi/bin/capture-run.sh +32 -2
  376. package/runtime/pi/bin/codex-render-spec.mjs +24 -46
  377. package/runtime/pi/bin/codex-session-start.sh +19 -0
  378. package/runtime/pi/bin/codex-skill-render.mjs +18 -0
  379. package/runtime/pi/bin/config-get.sh +10 -1
  380. package/runtime/pi/bin/connect-refresh.sh +16 -0
  381. package/runtime/pi/bin/corpus_map.py +5 -0
  382. package/runtime/pi/bin/data/capabilities/pi.json +1458 -0
  383. package/runtime/pi/bin/genui.sh +19 -0
  384. package/runtime/pi/bin/graph-batch.sh +1 -1
  385. package/runtime/pi/bin/graph-op.sh +14 -0
  386. package/runtime/pi/bin/graph.sh +1 -1
  387. package/runtime/pi/bin/handoff-pr-backfill.sh +1 -1
  388. package/runtime/pi/bin/handoff-run.sh +11 -6
  389. package/runtime/pi/bin/ingest-item.sh +1 -1
  390. package/runtime/pi/bin/ingest-surface.html +22 -4
  391. package/runtime/pi/bin/issue.sh +1 -1
  392. package/runtime/pi/bin/knowledge.sh +1 -1
  393. package/runtime/pi/bin/lib/card-delivery.sh +329 -0
  394. package/runtime/pi/bin/lib/config.sh +148 -3
  395. package/runtime/pi/bin/lib/context.sh +38 -67
  396. package/runtime/pi/bin/lib/genui-entry.py +36 -0
  397. package/runtime/pi/bin/lib/git-message.sh +25 -6
  398. package/runtime/pi/bin/lib/git-sync.sh +12 -4
  399. package/runtime/pi/bin/lib/greeting.sh +255 -28
  400. package/runtime/pi/bin/lib/handoff_meta.py +294 -0
  401. package/runtime/pi/bin/lib/health-footer.sh +83 -2
  402. package/runtime/pi/bin/lib/identity.sh +31 -10
  403. package/runtime/pi/bin/lib/instance-registry.sh +71 -0
  404. package/runtime/pi/bin/lib/local_ci_receipt.py +249 -0
  405. package/runtime/pi/bin/lib/metrics.sh +121 -8
  406. package/runtime/pi/bin/lib/notices.sh +36 -0
  407. package/runtime/pi/bin/lib/record_outcomes.py +729 -0
  408. package/runtime/pi/bin/lib/reflexes.py +267 -0
  409. package/runtime/pi/bin/lib/retrieval_scorecard.py +624 -0
  410. package/runtime/pi/bin/lib/session-record-prompt.txt +18 -0
  411. package/runtime/pi/bin/lib/session_record.py +3747 -0
  412. package/runtime/pi/bin/lib/session_trail.py +1983 -0
  413. package/runtime/pi/bin/lib/settings-drift.sh +8 -5
  414. package/runtime/pi/bin/lib/startup-restart.sh +41 -0
  415. package/runtime/pi/bin/lib/worktree-links.sh +92 -0
  416. package/runtime/pi/bin/memory-push.sh +6 -0
  417. package/runtime/pi/bin/merge-gate.sh +498 -0
  418. package/runtime/pi/bin/notify.sh +5 -2
  419. package/runtime/pi/bin/page-access.sh +103 -0
  420. package/runtime/pi/bin/person.sh +13 -2
  421. package/runtime/pi/bin/pi-branch-policy.mjs +37 -0
  422. package/runtime/pi/bin/pi-observe-context.mjs +97 -4
  423. package/runtime/pi/bin/pi-render-spec.mjs +0 -1
  424. package/runtime/pi/bin/pi-session-start.sh +4 -1
  425. package/runtime/pi/bin/pi-spirit-discovery.mjs +34 -0
  426. package/runtime/pi/bin/post-update.sh +181 -0
  427. package/runtime/pi/bin/prime-render-spec.mjs +0 -1
  428. package/runtime/pi/bin/publish-artifact.sh +89 -42
  429. package/runtime/pi/bin/qa-inventory.sh +2 -2
  430. package/runtime/pi/bin/quest.sh +1 -1
  431. package/runtime/pi/bin/records.sh +11 -0
  432. package/runtime/pi/bin/reflexes/05-vitals.sh +9 -0
  433. package/runtime/pi/bin/reflexes/10-open-items.sh +12 -0
  434. package/runtime/pi/bin/reflexes/15-retrieval.sh +8 -0
  435. package/runtime/pi/bin/reflexes/20-nightly.sh +100 -0
  436. package/runtime/pi/bin/reflexes/20-sandbox.sh +85 -0
  437. package/runtime/pi/bin/reflexes/30-cost.py +116 -0
  438. package/runtime/pi/bin/reflexes/40-shells.py +51 -0
  439. package/runtime/pi/bin/reflexes/README.md +61 -0
  440. package/runtime/pi/bin/reflexes.sh +7 -0
  441. package/runtime/pi/bin/runtime-identity.sh +140 -42
  442. package/runtime/pi/bin/screenshot.sh +77 -0
  443. package/runtime/pi/bin/scroll.sh +1 -1
  444. package/runtime/pi/bin/search.sh +31 -5
  445. package/runtime/pi/bin/session-autosave.sh +6 -3
  446. package/runtime/pi/bin/session-id.sh +147 -0
  447. package/runtime/pi/bin/session-log.sh +19 -0
  448. package/runtime/pi/bin/session-record.sh +26 -0
  449. package/runtime/pi/bin/settings.sh +13 -8
  450. package/runtime/pi/bin/spirit-discovery-claude.sh +4 -0
  451. package/runtime/pi/bin/spirit-discovery-codex.sh +4 -0
  452. package/runtime/pi/bin/spirit-discovery-pi.sh +4 -0
  453. package/runtime/pi/bin/spirit-discovery-prime.sh +4 -0
  454. package/runtime/pi/bin/spirit-discovery.sh +4 -0
  455. package/runtime/pi/bin/startup-check.sh +1 -1
  456. package/runtime/pi/bin/telemetry.sh +11 -4
  457. package/runtime/pi/bin/test-baseline.sh +33 -5
  458. package/runtime/pi/bin/todo.sh +1 -1
  459. package/runtime/pi/bin/worktree-create.sh +15 -45
  460. package/runtime/pi/bin/worktree.sh +6 -0
  461. package/runtime/pi/docs/spirit-discovery.md +96 -0
  462. package/runtime/pi/egregore_runtime/__init__.py +18 -12
  463. package/runtime/pi/egregore_runtime/access.py +608 -0
  464. package/runtime/pi/egregore_runtime/access_cli.py +190 -0
  465. package/runtime/pi/egregore_runtime/adapters/invitation.py +5 -3
  466. package/runtime/pi/egregore_runtime/adapters/qmd.py +521 -47
  467. package/runtime/pi/egregore_runtime/admin_entry.py +56 -0
  468. package/runtime/pi/egregore_runtime/artifacts.py +222 -16
  469. package/runtime/pi/egregore_runtime/contracts.py +27 -0
  470. package/runtime/pi/egregore_runtime/eligibility.py +5 -12
  471. package/runtime/pi/egregore_runtime/episode_binding.py +16 -5
  472. package/runtime/pi/egregore_runtime/github_issues.py +2 -2
  473. package/runtime/pi/egregore_runtime/handoff_lookup.py +9 -20
  474. package/runtime/pi/egregore_runtime/harness_cli.py +674 -149
  475. package/runtime/pi/egregore_runtime/held.py +2436 -0
  476. package/runtime/pi/egregore_runtime/hosted_api.py +137 -0
  477. package/runtime/pi/egregore_runtime/identity.py +196 -65
  478. package/runtime/pi/egregore_runtime/identity_transfer.py +6 -2
  479. package/runtime/pi/egregore_runtime/ingest_cli.py +2 -2
  480. package/runtime/pi/egregore_runtime/ingest_index_cli.py +4 -16
  481. package/runtime/pi/egregore_runtime/installation.py +119 -0
  482. package/runtime/pi/egregore_runtime/investigation.py +64 -41
  483. package/runtime/pi/egregore_runtime/investigation_guidance.py +16 -11
  484. package/runtime/pi/egregore_runtime/issue_cli.py +51 -32
  485. package/runtime/pi/egregore_runtime/issue_reporting.py +4 -3
  486. package/runtime/pi/egregore_runtime/issue_triage_service.py +2 -2
  487. package/runtime/pi/egregore_runtime/issues.py +12 -6
  488. package/runtime/pi/egregore_runtime/knowledge.py +331 -5
  489. package/runtime/pi/egregore_runtime/knowledge_cli.py +57 -17
  490. package/runtime/pi/egregore_runtime/lifecycle.py +88 -22
  491. package/runtime/pi/egregore_runtime/lifecycle_cli.py +21 -13
  492. package/runtime/pi/egregore_runtime/line_ids.py +10 -0
  493. package/runtime/pi/egregore_runtime/memory_push.py +349 -0
  494. package/runtime/pi/egregore_runtime/observe.py +64 -25
  495. package/runtime/pi/egregore_runtime/observers.py +19 -0
  496. package/runtime/pi/egregore_runtime/optional_modules.py +13 -0
  497. package/runtime/pi/egregore_runtime/outputs_cli.py +321 -0
  498. package/runtime/pi/egregore_runtime/policy.py +651 -24
  499. package/runtime/pi/egregore_runtime/private_result.py +2 -1
  500. package/runtime/pi/egregore_runtime/projection.py +946 -0
  501. package/runtime/pi/egregore_runtime/quest_cli.py +20 -23
  502. package/runtime/pi/egregore_runtime/question_cli.py +15 -11
  503. package/runtime/pi/egregore_runtime/questions.py +10 -10
  504. package/runtime/pi/egregore_runtime/quests.py +10 -10
  505. package/runtime/pi/egregore_runtime/record_publish.py +548 -0
  506. package/runtime/pi/egregore_runtime/record_subject.py +564 -0
  507. package/runtime/pi/egregore_runtime/research_ingest.py +2 -4
  508. package/runtime/pi/egregore_runtime/runtime.py +169 -60
  509. package/runtime/pi/egregore_runtime/sandbox.py +194 -0
  510. package/runtime/pi/egregore_runtime/scroll_cli.py +22 -32
  511. package/runtime/pi/egregore_runtime/scrolls.py +23 -15
  512. package/runtime/pi/egregore_runtime/shadow.py +262 -0
  513. package/runtime/pi/egregore_runtime/spirit_discovery.py +487 -0
  514. package/runtime/pi/egregore_runtime/spirit_discovery_cli.py +25 -0
  515. package/runtime/pi/egregore_runtime/spirit_discovery_transport.py +18 -0
  516. package/runtime/pi/egregore_runtime/status.py +101 -44
  517. package/runtime/pi/egregore_runtime/status_cli.py +13 -5
  518. package/runtime/pi/egregore_runtime/sync.py +39 -21
  519. package/runtime/pi/egregore_runtime/taste.py +934 -0
  520. package/runtime/pi/egregore_runtime/taste_cli.py +242 -0
  521. package/runtime/pi/egregore_runtime/taste_rules.py +91 -0
  522. package/runtime/pi/egregore_runtime/telemetry.py +26 -3
  523. package/runtime/pi/egregore_runtime/todo_cli.py +15 -12
  524. package/runtime/pi/egregore_runtime/todos.py +3 -2
  525. package/runtime/pi/egregore_runtime/upgrade.py +85 -58
  526. package/runtime/pi/egregore_runtime/writeback.py +330 -24
  527. package/runtime/pi/manifest.json +66 -5
  528. package/runtime/prime/.claude/context/handoff-claiming.md +32 -0
  529. package/runtime/prime/.claude/context/notification-consent.md +12 -9
  530. package/runtime/prime/.claude/skills/view/SKILL.md +438 -0
  531. package/runtime/prime/.codex/hooks.json +11 -0
  532. package/runtime/prime/.codex/skills/dark-mode/SKILL.md +1 -1
  533. package/runtime/prime/.codex/skills/records/SKILL.md +29 -0
  534. package/runtime/prime/.codex/skills/summon/SKILL.md +1 -1
  535. package/runtime/prime/.codex/skills/view/assets/compose-scaffold.html +19 -13
  536. package/runtime/prime/.codex/spec-manifest.json +13 -19
  537. package/runtime/prime/.prime/agent/APPEND_SYSTEM.md +53 -99
  538. package/runtime/prime/.prime/agent/extensions/egregore.ts +14 -1
  539. package/runtime/prime/.prime/agent/skills/egregore/SKILL.md +14 -6
  540. package/runtime/prime/.prime/agent/skills/egregore/src/egregore/__init__.py +66 -1
  541. package/runtime/prime/.prime/agent/spec-manifest.json +2 -2
  542. package/runtime/prime/AGENTS.md +54 -105
  543. package/runtime/prime/bin/agent.sh +231 -7
  544. package/runtime/prime/bin/api-call.sh +44 -23
  545. package/runtime/prime/bin/artifact-register.sh +7 -1
  546. package/runtime/prime/bin/artifact-writeback.sh +1 -1
  547. package/runtime/prime/bin/artifacts.sh +66 -265
  548. package/runtime/prime/bin/attendant.sh +4 -1
  549. package/runtime/prime/bin/boundary-guard.cjs +1848 -0
  550. package/runtime/prime/bin/boundary-hook.sh +41 -0
  551. package/runtime/prime/bin/capture-run.sh +32 -2
  552. package/runtime/prime/bin/codex-render-spec.mjs +24 -46
  553. package/runtime/prime/bin/codex-session-start.sh +19 -0
  554. package/runtime/prime/bin/codex-skill-render.mjs +18 -0
  555. package/runtime/prime/bin/config-get.sh +10 -1
  556. package/runtime/prime/bin/connect-refresh.sh +16 -0
  557. package/runtime/prime/bin/corpus_map.py +5 -0
  558. package/runtime/prime/bin/data/capabilities/prime.json +1458 -0
  559. package/runtime/prime/bin/genui.sh +19 -0
  560. package/runtime/prime/bin/graph-batch.sh +1 -1
  561. package/runtime/prime/bin/graph-op.sh +14 -0
  562. package/runtime/prime/bin/graph.sh +1 -1
  563. package/runtime/prime/bin/handoff-pr-backfill.sh +1 -1
  564. package/runtime/prime/bin/handoff-run.sh +11 -6
  565. package/runtime/prime/bin/ingest-item.sh +1 -1
  566. package/runtime/prime/bin/ingest-surface.html +22 -4
  567. package/runtime/prime/bin/issue.sh +1 -1
  568. package/runtime/prime/bin/knowledge.sh +1 -1
  569. package/runtime/prime/bin/lib/card-delivery.sh +329 -0
  570. package/runtime/prime/bin/lib/config.sh +148 -3
  571. package/runtime/prime/bin/lib/context.sh +38 -67
  572. package/runtime/prime/bin/lib/genui-entry.py +36 -0
  573. package/runtime/prime/bin/lib/git-message.sh +25 -6
  574. package/runtime/prime/bin/lib/git-sync.sh +12 -4
  575. package/runtime/prime/bin/lib/greeting.sh +255 -28
  576. package/runtime/prime/bin/lib/handoff_meta.py +294 -0
  577. package/runtime/prime/bin/lib/health-footer.sh +83 -2
  578. package/runtime/prime/bin/lib/identity.sh +31 -10
  579. package/runtime/prime/bin/lib/instance-registry.sh +71 -0
  580. package/runtime/prime/bin/lib/local_ci_receipt.py +249 -0
  581. package/runtime/prime/bin/lib/metrics.sh +121 -8
  582. package/runtime/prime/bin/lib/notices.sh +36 -0
  583. package/runtime/prime/bin/lib/record_outcomes.py +729 -0
  584. package/runtime/prime/bin/lib/reflexes.py +267 -0
  585. package/runtime/prime/bin/lib/retrieval_scorecard.py +624 -0
  586. package/runtime/prime/bin/lib/session-record-prompt.txt +18 -0
  587. package/runtime/prime/bin/lib/session_record.py +3747 -0
  588. package/runtime/prime/bin/lib/session_trail.py +1983 -0
  589. package/runtime/prime/bin/lib/settings-drift.sh +8 -5
  590. package/runtime/prime/bin/lib/startup-restart.sh +41 -0
  591. package/runtime/prime/bin/lib/worktree-links.sh +92 -0
  592. package/runtime/prime/bin/memory-push.sh +6 -0
  593. package/runtime/prime/bin/merge-gate.sh +498 -0
  594. package/runtime/prime/bin/notify.sh +5 -2
  595. package/runtime/prime/bin/page-access.sh +103 -0
  596. package/runtime/prime/bin/person.sh +13 -2
  597. package/runtime/prime/bin/pi-branch-policy.mjs +37 -0
  598. package/runtime/prime/bin/pi-observe-context.mjs +97 -4
  599. package/runtime/prime/bin/pi-render-spec.mjs +0 -1
  600. package/runtime/prime/bin/pi-spirit-discovery.mjs +34 -0
  601. package/runtime/prime/bin/post-update.sh +181 -0
  602. package/runtime/prime/bin/prime-render-spec.mjs +0 -1
  603. package/runtime/prime/bin/prime-session-start.sh +3 -1
  604. package/runtime/prime/bin/publish-artifact.sh +89 -42
  605. package/runtime/prime/bin/qa-inventory.sh +2 -2
  606. package/runtime/prime/bin/quest.sh +1 -1
  607. package/runtime/prime/bin/records.sh +11 -0
  608. package/runtime/prime/bin/reflexes/05-vitals.sh +9 -0
  609. package/runtime/prime/bin/reflexes/10-open-items.sh +12 -0
  610. package/runtime/prime/bin/reflexes/15-retrieval.sh +8 -0
  611. package/runtime/prime/bin/reflexes/20-nightly.sh +100 -0
  612. package/runtime/prime/bin/reflexes/20-sandbox.sh +85 -0
  613. package/runtime/prime/bin/reflexes/30-cost.py +116 -0
  614. package/runtime/prime/bin/reflexes/40-shells.py +51 -0
  615. package/runtime/prime/bin/reflexes/README.md +61 -0
  616. package/runtime/prime/bin/reflexes.sh +7 -0
  617. package/runtime/prime/bin/runtime-identity.sh +140 -42
  618. package/runtime/prime/bin/screenshot.sh +77 -0
  619. package/runtime/prime/bin/scroll.sh +1 -1
  620. package/runtime/prime/bin/search.sh +31 -5
  621. package/runtime/prime/bin/session-autosave.sh +6 -3
  622. package/runtime/prime/bin/session-id.sh +147 -0
  623. package/runtime/prime/bin/session-log.sh +19 -0
  624. package/runtime/prime/bin/session-record.sh +26 -0
  625. package/runtime/prime/bin/settings.sh +13 -8
  626. package/runtime/prime/bin/spirit-discovery-claude.sh +4 -0
  627. package/runtime/prime/bin/spirit-discovery-codex.sh +4 -0
  628. package/runtime/prime/bin/spirit-discovery-pi.sh +4 -0
  629. package/runtime/prime/bin/spirit-discovery-prime.sh +4 -0
  630. package/runtime/prime/bin/spirit-discovery.sh +4 -0
  631. package/runtime/prime/bin/startup-check.sh +1 -1
  632. package/runtime/prime/bin/telemetry.sh +11 -4
  633. package/runtime/prime/bin/test-baseline.sh +33 -5
  634. package/runtime/prime/bin/todo.sh +1 -1
  635. package/runtime/prime/bin/worktree-create.sh +15 -45
  636. package/runtime/prime/bin/worktree.sh +6 -0
  637. package/runtime/prime/docs/spirit-discovery.md +96 -0
  638. package/runtime/prime/egregore_runtime/__init__.py +18 -12
  639. package/runtime/prime/egregore_runtime/access.py +608 -0
  640. package/runtime/prime/egregore_runtime/access_cli.py +190 -0
  641. package/runtime/prime/egregore_runtime/adapters/invitation.py +5 -3
  642. package/runtime/prime/egregore_runtime/adapters/qmd.py +521 -47
  643. package/runtime/prime/egregore_runtime/admin_entry.py +56 -0
  644. package/runtime/prime/egregore_runtime/artifacts.py +222 -16
  645. package/runtime/prime/egregore_runtime/contracts.py +27 -0
  646. package/runtime/prime/egregore_runtime/eligibility.py +5 -12
  647. package/runtime/prime/egregore_runtime/episode_binding.py +16 -5
  648. package/runtime/prime/egregore_runtime/github_issues.py +2 -2
  649. package/runtime/prime/egregore_runtime/handoff_lookup.py +9 -20
  650. package/runtime/prime/egregore_runtime/harness_cli.py +674 -149
  651. package/runtime/prime/egregore_runtime/held.py +2436 -0
  652. package/runtime/prime/egregore_runtime/hosted_api.py +137 -0
  653. package/runtime/prime/egregore_runtime/identity.py +196 -65
  654. package/runtime/prime/egregore_runtime/identity_transfer.py +6 -2
  655. package/runtime/prime/egregore_runtime/ingest_cli.py +2 -2
  656. package/runtime/prime/egregore_runtime/ingest_index_cli.py +4 -16
  657. package/runtime/prime/egregore_runtime/installation.py +119 -0
  658. package/runtime/prime/egregore_runtime/investigation.py +64 -41
  659. package/runtime/prime/egregore_runtime/investigation_guidance.py +16 -11
  660. package/runtime/prime/egregore_runtime/issue_cli.py +51 -32
  661. package/runtime/prime/egregore_runtime/issue_reporting.py +4 -3
  662. package/runtime/prime/egregore_runtime/issue_triage_service.py +2 -2
  663. package/runtime/prime/egregore_runtime/issues.py +12 -6
  664. package/runtime/prime/egregore_runtime/knowledge.py +331 -5
  665. package/runtime/prime/egregore_runtime/knowledge_cli.py +57 -17
  666. package/runtime/prime/egregore_runtime/lifecycle.py +88 -22
  667. package/runtime/prime/egregore_runtime/lifecycle_cli.py +21 -13
  668. package/runtime/prime/egregore_runtime/line_ids.py +10 -0
  669. package/runtime/prime/egregore_runtime/memory_push.py +349 -0
  670. package/runtime/prime/egregore_runtime/observe.py +64 -25
  671. package/runtime/prime/egregore_runtime/observers.py +19 -0
  672. package/runtime/prime/egregore_runtime/optional_modules.py +13 -0
  673. package/runtime/prime/egregore_runtime/outputs_cli.py +321 -0
  674. package/runtime/prime/egregore_runtime/policy.py +651 -24
  675. package/runtime/prime/egregore_runtime/private_result.py +2 -1
  676. package/runtime/prime/egregore_runtime/projection.py +946 -0
  677. package/runtime/prime/egregore_runtime/quest_cli.py +20 -23
  678. package/runtime/prime/egregore_runtime/question_cli.py +15 -11
  679. package/runtime/prime/egregore_runtime/questions.py +10 -10
  680. package/runtime/prime/egregore_runtime/quests.py +10 -10
  681. package/runtime/prime/egregore_runtime/record_publish.py +548 -0
  682. package/runtime/prime/egregore_runtime/record_subject.py +564 -0
  683. package/runtime/prime/egregore_runtime/research_ingest.py +2 -4
  684. package/runtime/prime/egregore_runtime/runtime.py +169 -60
  685. package/runtime/prime/egregore_runtime/sandbox.py +194 -0
  686. package/runtime/prime/egregore_runtime/scroll_cli.py +22 -32
  687. package/runtime/prime/egregore_runtime/scrolls.py +23 -15
  688. package/runtime/prime/egregore_runtime/shadow.py +262 -0
  689. package/runtime/prime/egregore_runtime/spirit_discovery.py +487 -0
  690. package/runtime/prime/egregore_runtime/spirit_discovery_cli.py +25 -0
  691. package/runtime/prime/egregore_runtime/spirit_discovery_transport.py +18 -0
  692. package/runtime/prime/egregore_runtime/status.py +101 -44
  693. package/runtime/prime/egregore_runtime/status_cli.py +13 -5
  694. package/runtime/prime/egregore_runtime/sync.py +39 -21
  695. package/runtime/prime/egregore_runtime/taste.py +934 -0
  696. package/runtime/prime/egregore_runtime/taste_cli.py +242 -0
  697. package/runtime/prime/egregore_runtime/taste_rules.py +91 -0
  698. package/runtime/prime/egregore_runtime/telemetry.py +26 -3
  699. package/runtime/prime/egregore_runtime/todo_cli.py +15 -12
  700. package/runtime/prime/egregore_runtime/todos.py +3 -2
  701. package/runtime/prime/egregore_runtime/upgrade.py +85 -58
  702. package/runtime/prime/egregore_runtime/writeback.py +330 -24
  703. package/runtime/prime/manifest.json +66 -5
  704. package/runtime/claude/bin/thread.sh +0 -9
  705. package/runtime/claude/egregore_runtime/admin_gate.py +0 -102
  706. package/runtime/claude/egregore_runtime/thread_cli.py +0 -173
  707. package/runtime/claude/egregore_runtime/threads.py +0 -521
  708. package/runtime/codex/bin/thread.sh +0 -9
  709. package/runtime/codex/egregore_runtime/admin_gate.py +0 -102
  710. package/runtime/codex/egregore_runtime/thread_cli.py +0 -173
  711. package/runtime/codex/egregore_runtime/threads.py +0 -521
  712. package/runtime/pi/bin/thread.sh +0 -9
  713. package/runtime/pi/egregore_runtime/admin_gate.py +0 -102
  714. package/runtime/pi/egregore_runtime/thread_cli.py +0 -173
  715. package/runtime/pi/egregore_runtime/threads.py +0 -521
  716. package/runtime/prime/bin/thread.sh +0 -9
  717. package/runtime/prime/egregore_runtime/admin_gate.py +0 -102
  718. package/runtime/prime/egregore_runtime/thread_cli.py +0 -173
  719. package/runtime/prime/egregore_runtime/threads.py +0 -521
@@ -14,7 +14,7 @@ source "$SCRIPT_DIR/bin/lib/config.sh"
14
14
  source "$SCRIPT_DIR/bin/lib/scratch.sh"
15
15
 
16
16
  usage() {
17
- echo 'Usage: bash bin/api-call.sh <METHOD> <path-or-url> [--auth github|egregore|resend] [--json-file <file>] [--out <file>] [--error-out <file>]' >&2
17
+ echo 'Usage: bash bin/api-call.sh <METHOD> <path-or-url> [--auth github|egregore|resend|egregore+github] [--json-file <file>] [--out <file>] [--error-out <file>]' >&2
18
18
  echo 'Failed responses are discarded unless --error-out requests a private HTTP error body.' >&2
19
19
  exit 2
20
20
  }
@@ -34,7 +34,7 @@ while [ "$#" -gt 0 ]; do
34
34
  case "$1" in
35
35
  --auth)
36
36
  [ -z "$auth" ] || usage
37
- case "$2" in github|egregore|resend) auth="$2" ;; *) usage ;; esac
37
+ case "$2" in github|egregore|resend|egregore+github) auth="$2" ;; *) usage ;; esac
38
38
  ;;
39
39
  --json-file) [ -z "$json_file" ] || usage; json_file="$2" ;;
40
40
  --out) [ -z "$out" ] || usage; out="$2" ;;
@@ -99,41 +99,59 @@ fi
99
99
 
100
100
  url="$target"
101
101
  if [[ "$target" == /* ]]; then
102
- api_url=$(bash "$SCRIPT_DIR/bin/config-get.sh" api_url)
102
+ # config-get.sh refuses an address that is not plain, and says why.
103
+ api_url=$(bash "$SCRIPT_DIR/bin/config-get.sh" api_url) || exit 2
103
104
  if [ -z "$api_url" ]; then
104
105
  echo 'api-call: api_url is not set' >&2
105
106
  exit 2
106
107
  fi
107
108
  url="${api_url%/}$target"
108
109
  fi
110
+ # The retired hosted origin (October 2026 reset) never receives a credential,
111
+ # whether it came from egregore.json or an absolute target, and neither does an
112
+ # origin that is not plain. Resolve the final address before any key is
113
+ # loaded; curl runs with --globoff, so the path and query stay literal.
114
+ url="$(_hosted_api_target "$url")" || exit 2
109
115
 
110
- token=''
111
- if [ -n "$auth" ]; then
112
- case "$auth" in
113
- github) key_name=GITHUB_TOKEN ;;
114
- egregore) key_name=EGREGORE_API_KEY ;;
115
- resend) key_name=RESEND_API_KEY ;;
116
- esac
117
- token=$(_load_env_var "$key_name")
116
+ # load_key KEY_NAME: the key from .env, edges trimmed; GITHUB_TOKEN falls
117
+ # back to `gh auth token`. Sets `loaded`; exits 2 when the key is missing.
118
+ loaded=''
119
+ load_key() {
120
+ loaded=$(_load_env_var "$1")
118
121
  # Strip surrounding whitespace, including CRLF, without evaluating .env.
119
- token="${token#"${token%%[![:space:]]*}"}"
120
- token="${token%"${token##*[![:space:]]}"}"
121
- if [ "$auth" = resend ]; then
122
+ loaded="${loaded#"${loaded%%[![:space:]]*}"}"
123
+ loaded="${loaded%"${loaded##*[![:space:]]}"}"
124
+ if [ "$1" = RESEND_API_KEY ]; then
122
125
  # The email skill historically removes all whitespace from Resend keys.
123
- token=$(printf '%s' "$token" | tr -d '[:space:]')
124
- elif [ "$auth" = github ] && [ -z "$token" ]; then
125
- token=$(gh auth token 2>/dev/null) || token=''
126
- token="${token#"${token%%[![:space:]]*}"}"
127
- token="${token%"${token##*[![:space:]]}"}"
126
+ loaded=$(printf '%s' "$loaded" | tr -d '[:space:]')
127
+ elif [ "$1" = GITHUB_TOKEN ] && [ -z "$loaded" ]; then
128
+ loaded=$(gh auth token 2>/dev/null) || loaded=''
129
+ loaded="${loaded#"${loaded%%[![:space:]]*}"}"
130
+ loaded="${loaded%"${loaded##*[![:space:]]}"}"
128
131
  fi
129
- if [ -z "$token" ]; then
130
- printf 'api-call: %s is not set in .env\n' "$key_name" >&2
132
+ if [ -z "$loaded" ]; then
133
+ printf 'api-call: %s is not set in .env\n' "$1" >&2
131
134
  exit 2
132
135
  fi
133
- fi
136
+ }
137
+
138
+ # egregore+github: the org key names the organisation (Authorization) and the
139
+ # caller's own GitHub token proves the person (X-GitHub-Token).
140
+ token=''
141
+ person_token=''
142
+ case "$auth" in
143
+ github) load_key GITHUB_TOKEN; token="$loaded" ;;
144
+ egregore) load_key EGREGORE_API_KEY; token="$loaded" ;;
145
+ resend) load_key RESEND_API_KEY; token="$loaded" ;;
146
+ egregore+github)
147
+ load_key EGREGORE_API_KEY; token="$loaded"
148
+ load_key GITHUB_TOKEN; person_token="$loaded"
149
+ ;;
150
+ esac
151
+ loaded=''
134
152
 
135
153
  response_file=$(mktemp "$SCRIPT_DIR/tmp/api-call.XXXXXX")
136
- args=(-q -sS --max-time 60 --request "$method" --url "$url"
154
+ args=(-q -sS --globoff --max-time 60 --request "$method" --url "$url"
137
155
  --output "$response_file" --write-out '%{http_code}' -H @-)
138
156
  if [ -n "$json_file" ]; then
139
157
  args+=(--data-binary "@$json_file")
@@ -143,6 +161,9 @@ headers() {
143
161
  if [ -n "$token" ]; then
144
162
  printf 'Authorization: Bearer %s\n' "$token"
145
163
  fi
164
+ if [ -n "$person_token" ]; then
165
+ printf 'X-GitHub-Token: %s\n' "$person_token"
166
+ fi
146
167
  # Preserve delete-user's JSON header even on its bodyless DELETE request.
147
168
  if [ -n "$json_file" ] || [ "$method" = DELETE ]; then
148
169
  printf '%s\n' 'Content-Type: application/json'
@@ -184,7 +184,13 @@ REL="artifacts/$(basename "$FILE")"
184
184
  git commit -m "chore(artifacts): register ${TITLE}" -- "$REL" >/dev/null 2>&1 || exit 0
185
185
  for _ in 1 2 3; do
186
186
  before="$(git rev-parse HEAD 2>/dev/null)" || break
187
- git pull --rebase --no-edit >/dev/null 2>&1 && git push >/dev/null 2>&1 && break
187
+ if git pull --rebase --no-edit >/dev/null 2>&1; then
188
+ if bash "$SCRIPT_DIR/bin/memory-push.sh" --repository "$SCRIPT_DIR/memory" --branch main >/dev/null 2>&1; then
189
+ break
190
+ else
191
+ case "$?" in 75) ;; *) break ;; esac
192
+ fi
193
+ fi
188
194
  if [ "$(rebase_start)" = "$before" ]; then
189
195
  if [ "$(git diff --name-only --diff-filter=U 2>/dev/null)" = "$REL" ] \
190
196
  && git checkout --ours -- "$REL" 2>/dev/null && git add -- "$REL" 2>/dev/null; then
@@ -7,7 +7,7 @@ set -euo pipefail
7
7
  ROOT="$(cd "$(dirname "$0")/.." && pwd)"
8
8
  export EGREGORE_ROOT="$ROOT"
9
9
  export PYTHONSAFEPATH=1 PYTHONPATH="$ROOT${PYTHONPATH:+:$PYTHONPATH}"
10
- export EGREGORE_SESSION_ID="${EGREGORE_SESSION_ID:-$(cat "$ROOT/.egregore-session-id" 2>/dev/null || true)}"
10
+ export EGREGORE_SESSION_ID="${EGREGORE_SESSION_ID:-$(bash "$ROOT/bin/session-id.sh" --root "$ROOT" 2>/dev/null || cat "$ROOT/.egregore-session-id" 2>/dev/null || true)}"
11
11
 
12
12
  case "${1:-}" in
13
13
  capture)
@@ -1,288 +1,89 @@
1
1
  #!/usr/bin/env bash
2
- # Intentionally NOT `set -euo pipefail`: this is a grep-heavy find tool where
3
- # no-match (grep exit 1) and empty arrays are normal control flow, not errors.
2
+ # The link commands read the org API key: never trace it.
3
+ set +vx
4
4
 
5
5
  # artifacts.sh — find something you generated, by NAME or CONTENT, and get its URL.
6
6
  #
7
- # Every generative surface already records into memory, each in its own home:
8
- # • hosted artifacts (scroll, /view, /reflect, decision surfaces) → artifacts/
9
- # • handoffs → handoffs/
10
- # • emissaries (outbound pointers) → handoffs/outbound/
11
- # • decisions / findings / patterns (/reflect, /add) → knowledge/
12
- # The finder searches ALL of them, so anything you made is retrievable by what's
13
- # IN it, not just the name you gave it. Grep-first, so it works with nothing but
14
- # Claude Code / Codex file ops (OSS):
7
+ # artifacts find [--since D|--until D|--on D] <query...> rank matches
8
+ # artifacts list [N] most recently recorded
15
9
  #
16
- # artifacts find <query...> rank matches (title/topic beat a body mention)
17
- # artifacts list [N] most recently recorded artifacts
18
- #
19
- # In paid mode (search available) `find` also folds in qmd semantic recall, so
20
- # "the artifact where I laid out our GTM plan" resolves even without the words.
21
- # The graph is the third layer — query it via bin/graph.sh for relationships.
10
+ # Both run in the Runtime (`harness_cli artifacts`), which ranks hosted
11
+ # artifacts, handoffs, emissaries and knowledge as this script once did and
12
+ # prints only what the reader may see. The hosted link controls stay here.
22
13
 
23
14
  SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
24
- MEM="$SCRIPT_DIR/memory"
25
-
26
- # All artifact-bearing memory dirs. index.md files are navigation, not artifacts.
27
- _corpus() {
28
- find \
29
- "$MEM/artifacts" \
30
- "$MEM/handoffs" \
31
- "$MEM/knowledge/decisions" "$MEM/knowledge/findings" "$MEM/knowledge/patterns" \
32
- -type f -name '*.md' 2>/dev/null | grep -vE '/index\.md$'
33
- }
34
-
35
- _field() { # <file> <key> → frontmatter value
36
- sed -n "/^---$/,/^---$/p" "$1" 2>/dev/null | grep -i "^$2:" | head -1 | cut -d: -f2- | sed 's/^ *//'
37
- }
38
-
39
- _title() { # frontmatter title → first "# " heading → filename
40
- local t; t="$(_field "$1" title)"
41
- [ -n "$t" ] || t="$(grep -m1 '^# ' "$1" 2>/dev/null | sed 's/^#* *//')"
42
- [ -n "$t" ] || t="$(basename "$1" .md)"
43
- printf '%s' "$t"
44
- }
45
-
46
- _url() { # frontmatter url → first hosted link in the body
47
- local u; u="$(_field "$1" url)"
48
- [ -n "$u" ] || u="$(grep -oE 'https://egregore\.xyz/[^ )>"]+' "$1" 2>/dev/null | head -1)"
49
- printf '%s' "$u"
50
- }
51
-
52
- _tag() { # short source label from path (falls back to frontmatter type)
53
- case "$1" in
54
- */handoffs/outbound/*) printf 'emissary' ;;
55
- */handoffs/*) printf 'handoff' ;;
56
- */knowledge/decisions/*) printf 'decision' ;;
57
- */knowledge/findings/*) printf 'finding' ;;
58
- */knowledge/patterns/*) printf 'pattern' ;;
59
- *) local ty; ty="$(_field "$1" type)"; printf '%s' "${ty:-artifact}" ;;
60
- esac
61
- }
62
-
63
- _rel() { printf 'memory/%s' "${1#"$MEM"/}"; }
15
+ # shellcheck source=bin/lib/config.sh
16
+ source "$SCRIPT_DIR/bin/lib/config.sh"
64
17
 
65
- # Tokenize a query into significant lowercase words (drop tiny/stopwords).
66
- _words() {
67
- local stop=" the a an is for and or in of to on with our we my me i where " w
68
- local -a out=()
69
- for w in $(printf '%s' "$1" | LC_ALL=C tr '[:upper:]' '[:lower:]' | LC_ALL=C tr -c 'a-z0-9' ' '); do
70
- [ ${#w} -ge 3 ] || continue
71
- case "$stop" in *" $w "*) continue ;; esac
72
- out+=("$w")
73
- done
74
- [ ${#out[@]} -gt 0 ] || out=("$(printf '%s' "$1" | LC_ALL=C tr '[:upper:]' '[:lower:]')")
75
- printf '%s\n' "${out[@]}"
18
+ _runtime_artifacts() {
19
+ EGREGORE_ROOT="$SCRIPT_DIR" PYTHONSAFEPATH=1 PYTHONPATH="$SCRIPT_DIR${PYTHONPATH:+:$PYTHONPATH}" \
20
+ python3 -m egregore_runtime.harness_cli artifacts "$1" -- "${@:2}"
76
21
  }
77
22
 
78
- # Date N days before today — portable across BSD (date -v) and GNU (date -d).
79
- _days_ago() { date -v-"${1}"d +%Y-%m-%d 2>/dev/null || date -d "${1} days ago" +%Y-%m-%d 2>/dev/null; }
80
-
81
- # Parse a relative-time expression out of a query. Echoes "SINCE|UNTIL|CLEANED":
82
- # SINCE/UNTIL are YYYY-MM-DD bounds (empty = unbounded); CLEANED is the query
83
- # with the temporal phrase removed so "yesterday" can't be matched as a keyword.
84
- # Operates on the lowercased query — the finder lowercases anyway.
85
- _time_window() {
86
- local lc since="" until="" cleaned n
87
- lc="$(printf '%s' "$1" | LC_ALL=C tr '[:upper:]' '[:lower:]')"; cleaned="$lc"
88
- if [[ "$lc" =~ ([0-9]+)[[:space:]]+(day|days|week|weeks)[[:space:]]+ago ]]; then
89
- n="${BASH_REMATCH[1]}"; case "${BASH_REMATCH[2]}" in week*) n=$((n * 7)) ;; esac
90
- since="$(_days_ago "$n")"; cleaned="$(printf '%s' "$lc" | sed -E 's/[0-9]+ +(day|days|week|weeks) +ago//')"
91
- elif [[ "$lc" =~ (last|past)[[:space:]]+([0-9]+)[[:space:]]+(day|days|week|weeks) ]]; then
92
- n="${BASH_REMATCH[2]}"; case "${BASH_REMATCH[3]}" in week*) n=$((n * 7)) ;; esac
93
- since="$(_days_ago "$n")"; cleaned="$(printf '%s' "$lc" | sed -E 's/(last|past) +[0-9]+ +(day|days|week|weeks)//')"
94
- elif [[ "$lc" == *yesterday* ]]; then
95
- since="$(_days_ago 1)"; until="$since"; cleaned="${lc//yesterday/}"
96
- elif [[ "$lc" == *today* ]]; then
97
- since="$(date +%Y-%m-%d)"; until="$since"; cleaned="${lc//today/}"
98
- elif [[ "$lc" =~ (this|last|past)[[:space:]]+week ]]; then
99
- since="$(_days_ago 7)"; cleaned="$(printf '%s' "$lc" | sed -E 's/(this|last|past) +week//')"
100
- elif [[ "$lc" =~ (this|last|past)[[:space:]]+month ]]; then
101
- since="$(_days_ago 31)"; cleaned="$(printf '%s' "$lc" | sed -E 's/(this|last|past) +month//')"
102
- elif [[ "$lc" =~ recent|recently|lately ]]; then
103
- since="$(_days_ago 14)"; cleaned="$(printf '%s' "$lc" | sed -E 's/recently|recent|lately//')"
104
- elif [[ "$lc" =~ ([0-9]{4}-[0-9]{2}-[0-9]{2}) ]]; then
105
- since="${BASH_REMATCH[1]}"; until="$since"; cleaned="${lc//${BASH_REMATCH[1]}/}"
23
+ # --- Hosted link controls (Connected: the page lives on egregore.xyz) --------
24
+ # artifacts close <id> close the link now; it opens a "link closed" notice
25
+ # artifacts reopen <id> open it again, with no closing date
26
+ # artifacts opens <id> when the page was opened (people; previews apart)
27
+ _link_call() { # <method> <id> <action> → JSON on stdout; plain reason on failure
28
+ local method="$1" id="$2" action="$3" api_url api_key body status
29
+ api_url="${EGREGORE_API_URL:-$(grep '^EGREGORE_API_URL=' "$SCRIPT_DIR/.env" 2>/dev/null | cut -d'=' -f2-)}"
30
+ api_url="$(_hosted_api_url "${api_url:-$(jq -r '.api_url // empty' "$SCRIPT_DIR/egregore.json" 2>/dev/null)}")" || return 4
31
+ api_key="${EGREGORE_API_KEY:-$(grep '^EGREGORE_API_KEY=' "$SCRIPT_DIR/.env" 2>/dev/null | cut -d'=' -f2-)}"
32
+ if [ -z "$api_url" ] || [ -z "$api_key" ]; then
33
+ echo "Hosted links are part of Egregore Connect; this configuration has none." >&2
34
+ return 4
106
35
  fi
107
- printf '%s|%s|%s' "$since" "$until" "$cleaned"
108
- }
109
-
110
- # Best-effort YYYY-MM-DD for a memory file: filename prefix, handoff dir/day, or
111
- # frontmatter date:. Lets the grep path honor temporal windows too.
112
- _file_date() {
113
- local f="$1" d dir base
114
- d="$(basename "$f" | grep -oE '^[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -1)"
115
- [ -n "$d" ] && { printf '%s' "$d"; return; }
116
- dir="$(basename "$(dirname "$f")")"; base="$(basename "$f")"
117
- if [[ "$dir" =~ ^[0-9]{4}-[0-9]{2}$ && "$base" =~ ^([0-9]{2})- ]]; then
118
- printf '%s-%s' "$dir" "${BASH_REMATCH[1]}"; return
36
+ if ! [[ "$id" =~ ^[A-Za-z0-9_-]{1,50}$ ]]; then
37
+ echo "usage: artifacts $action <id> (the id in egregore.xyz/view/<org>/<id>)" >&2
38
+ return 1
119
39
  fi
120
- sed -n '/^---$/,/^---$/p' "$f" 2>/dev/null | grep -i '^date:' | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -1
121
- }
122
-
123
- # Human label for the active window, appended to the result header.
124
- _window_label() {
125
- if [ -n "$1" ] && [ "$1" = "$2" ]; then printf ' · on %s' "$1"
126
- elif [ -n "$1" ] && [ -n "$2" ]; then printf ' · %s..%s' "$1" "$2"
127
- elif [ -n "$1" ]; then printf ' · since %s' "$1"
128
- elif [ -n "$2" ]; then printf ' · until %s' "$2"; fi
129
- }
130
-
131
- # ── grep path — OSS/local, and the connected-mode fallback ──
132
- _grep_find() {
133
- local query="$1" since="${2:-}" until="${3:-}"
134
- [ -d "$MEM" ] || { echo "(no memory linked)"; return 0; }
135
- local words=(); while IFS= read -r w; do words+=("$w"); done < <(_words "$query")
136
-
137
- echo "⌕ artifacts · grep-rank · \"$query\"$(_window_label "$since" "$until")"
138
- echo
139
-
140
- # Fast path: ONE grep pass narrows 1000s of files to the handful that match
141
- # any word — scoring the whole corpus per-word in bash is death by subprocess.
142
- local pat; pat="$(IFS='|'; printf '%s' "${words[*]}")"
143
- local -a cands=()
144
- while IFS= read -r f; do [ -n "$f" ] && cands+=("$f"); done \
145
- < <(_corpus | tr '\n' '\0' | xargs -0 grep -ilE -- "$pat" 2>/dev/null)
146
-
147
- # Score only the candidates. A word in the title/topics/filename outweighs a
148
- # passing body mention (8 vs 1), so the doc that's ABOUT the query beats one
149
- # that merely name-drops it. Header check is a bash builtin (no subprocess);
150
- # only fall back to a full-file grep for words not in the header.
151
- local hdr base score matched w fd
152
- local -a scored=()
153
- for f in "${cands[@]}"; do
154
- fd="$(_file_date "$f")"
155
- # Temporal window: when set, drop out-of-range (and undated) files.
156
- if [ -n "$since" ] || [ -n "$until" ]; then
157
- [ -n "$fd" ] || continue
158
- [ -n "$since" ] && [[ "$fd" < "$since" ]] && continue
159
- [ -n "$until" ] && [[ "$fd" > "$until" ]] && continue
160
- fi
161
- base="${f##*/}"
162
- hdr="$(sed -n '1,25p' "$f" 2>/dev/null | grep -iE '^title:|^topics:|^# ' ; printf '%s' "$base")"
163
- hdr="$(printf '%s' "$hdr" | LC_ALL=C tr '[:upper:]' '[:lower:]')"
164
- score=0; matched=0
165
- for w in "${words[@]}"; do
166
- if [[ "$hdr" == *"$w"* ]]; then
167
- score=$((score + 8)); matched=$((matched + 1))
168
- elif grep -qiF -- "$w" "$f" 2>/dev/null; then
169
- score=$((score + 1)); matched=$((matched + 1))
170
- fi
171
- done
172
- [ "$matched" -gt 0 ] && scored+=("$matched $score ${fd:-0000-00-00} $f")
173
- done
174
-
175
- if [ ${#scored[@]} -eq 0 ]; then
176
- echo " no matches across artifacts / handoffs / knowledge."
177
- else
178
- # Rank: words matched, then weighted score, then recency (newest first).
179
- printf '%s\n' "${scored[@]}" | sort -t" " -k1,1nr -k2,2nr -k3,3r | head -8 | while IFS=" " read -r matched score fd f; do
180
- local title url rel tag
181
- title="$(_title "$f")"; url="$(_url "$f")"; rel="$(_rel "$f")"; tag="$(_tag "$f")"
182
- printf ' ● [%s] %s\n' "$tag" "$title"
183
- [ -n "$url" ] && printf ' %s\n' "$url"
184
- printf ' %s (%d/%d matched · %s)\n\n' "$rel" "$matched" "${#words[@]}" "$fd"
185
- done
40
+ body="$(mktemp)"
41
+ # The key goes in on standard input, never in curl's arguments, which any
42
+ # local process can read.
43
+ status="$(curl -q -s -o "$body" -w '%{http_code}' -X "$method" -H @- \
44
+ "${api_url}/api/artifact-links/${id}/${action}" <<< "Authorization: Bearer ${api_key}")" || status=000
45
+ if [ "$status" != "200" ]; then
46
+ case "$status" in
47
+ 404) echo "This organization has no hosted page with the id '$id'." >&2 ;;
48
+ 401|403) echo "The API key was refused; run /env to check it." >&2 ;;
49
+ 000) echo "Could not reach the Egregore API; check the connection and try again." >&2 ;;
50
+ *) echo "The API answered $status: $(jq -r '.detail // empty' "$body" 2>/dev/null)" >&2 ;;
51
+ esac
52
+ rm -f "$body"
53
+ return 1
186
54
  fi
55
+ cat "$body"
56
+ rm -f "$body"
187
57
  }
188
58
 
189
- # ── graph path — paid/connected: relevance + relationships, indexed ──
190
- # Returns 0 only when it surfaced results; a miss or an offline graph returns 1
191
- # so cmd_find falls back to grep (which also covers handoffs/emissaries that live
192
- # as Session nodes, not Artifact nodes).
193
- _graph_find() {
194
- local query="$1" since="${2:-}" until="${3:-}"
195
- local words=(); while IFS= read -r w; do words+=("$w"); done < <(_words "$query")
196
- local words_json; words_json="$(jq -nc '$ARGS.positional' --args "${words[@]}")"
197
-
198
- # A word in the title outweighs topics outweighs a passing excerpt mention —
199
- # same weighting as the grep path, but scored server-side over indexed nodes.
200
- # The temporal window filters on a.created; ties break by recency (newest first).
201
- local cypher='MATCH (a:Artifact)
202
- WHERE any(w IN $words WHERE toLower(a.title) CONTAINS w
203
- OR toLower(coalesce(a.excerpt,"")) CONTAINS w
204
- OR any(t IN coalesce(a.topics,[]) WHERE toLower(t) CONTAINS w))
205
- AND ($since = "" OR (a.created IS NOT NULL AND a.created >= datetime($since)))
206
- AND ($until = "" OR (a.created IS NOT NULL AND a.created <= datetime($until + "T23:59:59")))
207
- WITH a, reduce(s=0, w IN $words | s
208
- + (CASE WHEN toLower(a.title) CONTAINS w THEN 8 ELSE 0 END)
209
- + (CASE WHEN any(t IN coalesce(a.topics,[]) WHERE toLower(t) CONTAINS w) THEN 5 ELSE 0 END)
210
- + (CASE WHEN toLower(coalesce(a.excerpt,"")) CONTAINS w THEN 1 ELSE 0 END)) AS score
211
- OPTIONAL MATCH (a)-[:CONTRIBUTED_BY]->(p:Person)
212
- OPTIONAL MATCH (a)-[:PART_OF]->(q:Quest)
213
- RETURN a.title AS title, a.url AS url, a.type AS type, score,
214
- collect(DISTINCT p.name)[0] AS author, collect(DISTINCT q.title)[0] AS quest,
215
- CASE WHEN a.created IS NOT NULL THEN toString(date(a.created)) ELSE "" END AS created
216
- ORDER BY score DESC, created DESC LIMIT 8'
217
-
218
- local resp; resp="$(bash "$SCRIPT_DIR/bin/graph.sh" query "$cypher" "$(jq -n --argjson words "$words_json" --arg since "$since" --arg until "$until" '{words: $words, since: $since, until: $until}')" 2>/dev/null)"
219
- local nrows; nrows="$(printf '%s' "$resp" | jq -r '(.values // []) | length' 2>/dev/null || echo 0)"
220
- [ "${nrows:-0}" -gt 0 ] || return 1
221
-
222
- echo "⌕ artifacts · relationships · \"$query\"$(_window_label "$since" "$until")"
223
- echo
224
- # Render each row with jq (null-safe): @tsv + bash read collapses null columns
225
- # because tab is IFS-whitespace. Cols: 0 title,1 url,2 type,3 score,4 author,5 quest,6 created.
226
- printf '%s' "$resp" | jq -r '
227
- .values[] |
228
- " ● [" + (.[2] // "artifact") + "] " + (.[0] // "(untitled)")
229
- + (if (.[1] // "") != "" then "\n " + .[1] else "" end)
230
- + "\n graph · score " + (.[3] | tostring)
231
- + (if (.[6] // "") != "" then " · " + .[6] else "" end)
232
- + (if (.[4] // "") != "" then " · by " + .[4] else "" end)
233
- + (if (.[5] // "") != "" then " · " + .[5] else "" end)
234
- + "\n"'
235
- return 0
59
+ cmd_close() {
60
+ local out; out="$(_link_call POST "${1:-}" close)" || return $?
61
+ printf 'Closed: egregore.xyz/view/…/%s now opens a "link closed" notice.\n' "$1"
62
+ jq -r '.note // empty' <<< "$out"
63
+ echo "Reopen with: bash bin/artifacts.sh reopen $1"
236
64
  }
237
65
 
238
- cmd_find() {
239
- # Explicit date bounds (the agent translates arbitrary phrasing into these).
240
- local since="" until=""
241
- local -a rest=()
242
- while [ $# -gt 0 ]; do
243
- case "$1" in
244
- --since) since="${2:-}"; shift 2 ;;
245
- --until) until="${2:-}"; shift 2 ;;
246
- --on) since="${2:-}"; until="${2:-}"; shift 2 ;;
247
- *) rest+=("$1"); shift ;;
248
- esac
249
- done
250
- local query="${rest[*]}"
251
- [ -n "$query" ] || { echo "usage: artifacts find [--since D|--until D|--on D] <query>" >&2; exit 1; }
252
-
253
- # No explicit flags → parse a relative-time expression from the query itself
254
- # ("… from yesterday", "last week", "on 2026-07-10"), stripping it from the
255
- # keyword match so it doesn't become dead search noise.
256
- if [ -z "$since" ] && [ -z "$until" ]; then
257
- local win cleaned; win="$(_time_window "$query")"
258
- since="${win%%|*}"; win="${win#*|}"; until="${win%%|*}"; cleaned="${win#*|}"
259
- cleaned="$(printf '%s' "$cleaned" | sed 's/^ *//; s/ *$//')"
260
- [ -n "$cleaned" ] && query="$cleaned"
261
- fi
262
-
263
- # Paid/connected → graph first (relevance + relationships + created, indexed).
264
- # If the graph is offline or has no match, fall through to grep, which also
265
- # covers handoffs/emissaries (Session nodes) and is the whole OSS story.
266
- # EGREGORE_MODE overrides the egregore.json mode (test/OSS-simulation hook).
267
- local mode; mode="${EGREGORE_MODE:-$(jq -r '.mode // "connected"' "$SCRIPT_DIR/egregore.json" 2>/dev/null)}"
268
- if [ "$mode" != "local" ]; then
269
- _graph_find "$query" "$since" "$until" && return 0
270
- fi
271
- _grep_find "$query" "$since" "$until"
66
+ cmd_reopen() {
67
+ _link_call POST "${1:-}" reopen >/dev/null || return $?
68
+ printf 'Reopened: %s has no closing date.\n' "$1"
272
69
  }
273
70
 
274
- cmd_list() {
275
- local n="${1:-10}"
276
- [ -d "$MEM" ] || { echo "(no memory linked)"; return 0; }
277
- _corpus | xargs ls -t 2>/dev/null | head -"$n" | while read -r f; do
278
- local title url tag
279
- title="$(_title "$f")"; url="$(_url "$f")"; tag="$(_tag "$f")"
280
- printf ' ● [%-8s] %-52s %s\n' "$tag" "${title:0:52}" "$url"
281
- done
71
+ cmd_opens() {
72
+ local out; out="$(_link_call GET "${1:-}" opens)" || return $?
73
+ jq -r '
74
+ (if .opens == 0 then "Not opened by anyone yet."
75
+ else "Opened \(.opens) time\(if .opens == 1 then "" else "s" end) by people · first \(.first) · last \(.last) (UTC)" end),
76
+ (if .automated > 0 then "\(.automated) more fetch\(if .automated == 1 then "" else "es" end) by link previews and bots." else empty end),
77
+ (if .complete then empty else "Counts cover the newest 500 opens." end),
78
+ "Counted at most once a minute; opens the edge cache answers (within 5 minutes) go uncounted."
79
+ ' <<< "$out"
282
80
  }
283
81
 
284
82
  case "${1:-find}" in
285
- find) shift; cmd_find "$@" ;;
286
- list) shift; cmd_list "$@" ;;
287
- *) cmd_find "$@" ;;
83
+ find) shift; _runtime_artifacts find "$@" ;;
84
+ list) shift; _runtime_artifacts list "$@" ;;
85
+ close) shift; cmd_close "$@" ;;
86
+ reopen) shift; cmd_reopen "$@" ;;
87
+ opens) shift; cmd_opens "$@" ;;
88
+ *) _runtime_artifacts find "$@" ;;
288
89
  esac
@@ -36,6 +36,8 @@ if [ -f "$SCRIPT_DIR/.git" ]; then
36
36
  fi
37
37
 
38
38
  CONFIG="$MAIN_DIR/egregore.json"
39
+ # shellcheck source=bin/lib/config.sh
40
+ source "$MAIN_DIR/bin/lib/config.sh"
39
41
  MEMORY_DIR="${EGREGORE_MEMORY_DIR:-$MAIN_DIR/memory}"
40
42
  STALE_MIN="${ATTENDANT_STALE_MIN:-12}"
41
43
  DRY_RUN="${ATTENDANT_DRY_RUN:-0}"
@@ -126,7 +128,8 @@ _effective_scope() {
126
128
  local url key
127
129
  url="${EGREGORE_API_URL:-$(grep '^EGREGORE_API_URL=' "$MAIN_DIR/.env" 2>/dev/null | cut -d'=' -f2- || true)}"
128
130
  key="${EGREGORE_API_KEY:-$(grep '^EGREGORE_API_KEY=' "$MAIN_DIR/.env" 2>/dev/null | cut -d'=' -f2- || true)}"
129
- [ -n "$url" ] || url=$(jq -r '.api_url // empty' "$CONFIG" 2>/dev/null)
131
+ # A fingerprint only: a refused address counts as none, quietly.
132
+ url="$(_hosted_api_url "${url:-$(jq -r '.api_url // empty' "$CONFIG" 2>/dev/null)}" 2>/dev/null)" || url=""
130
133
  echo -n "${url}|${key}" | cksum | cut -d' ' -f1
131
134
  }
132
135