create-egregore 0.19.33 → 0.20.1

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 (250) hide show
  1. package/assets/egregore-launcher.js +141 -14
  2. package/bin/cli.js +19 -3
  3. package/lib/connect-runtime.js +4 -2
  4. package/lib/local.js +15 -1
  5. package/lib/prime-runtime.js +208 -0
  6. package/lib/setup.js +66 -5
  7. package/package.json +4 -3
  8. package/runtime/codex/.codex/config.toml +3 -0
  9. package/runtime/codex/.codex/skills/archive/SKILL.md +1 -1
  10. package/runtime/codex/.codex/skills/branch/SKILL.md +1 -1
  11. package/runtime/codex/.codex/skills/checkup/SKILL.md +1 -1
  12. package/runtime/codex/.codex/skills/commit/SKILL.md +1 -1
  13. package/runtime/codex/.codex/skills/contribute/SKILL.md +1 -1
  14. package/runtime/codex/.codex/skills/delete-user/SKILL.md +1 -1
  15. package/runtime/codex/.codex/skills/ingest/SKILL.md +1 -1
  16. package/runtime/codex/.codex/skills/ingest-corpus/SKILL.md +29 -0
  17. package/runtime/codex/.codex/skills/ingest-notion/SKILL.md +29 -0
  18. package/runtime/codex/.codex/skills/ingest-user-interview/SKILL.md +1 -1
  19. package/runtime/codex/.codex/skills/issue/SKILL.md +1 -1
  20. package/runtime/codex/.codex/skills/me/SKILL.md +1 -1
  21. package/runtime/codex/.codex/skills/meeting/SKILL.md +1 -1
  22. package/runtime/codex/.codex/skills/note/SKILL.md +1 -1
  23. package/runtime/codex/.codex/skills/notion-connect/SKILL.md +29 -0
  24. package/runtime/codex/.codex/skills/onboarding/SKILL.md +1 -1
  25. package/runtime/codex/.codex/skills/pr/SKILL.md +1 -1
  26. package/runtime/codex/.codex/skills/pull/SKILL.md +1 -1
  27. package/runtime/codex/.codex/skills/push/SKILL.md +1 -1
  28. package/runtime/codex/.codex/skills/reflect/SKILL.md +1 -1
  29. package/runtime/codex/.codex/skills/review-pr/SKILL.md +1 -1
  30. package/runtime/codex/.codex/skills/save/SKILL.md +3 -1
  31. package/runtime/codex/.codex/skills/slack-connect/SKILL.md +1 -1
  32. package/runtime/codex/.codex/skills/summon/SKILL.md +1 -1
  33. package/runtime/codex/.codex/skills/sync-repos/SKILL.md +1 -1
  34. package/runtime/codex/.codex/skills/teams-connect/SKILL.md +29 -0
  35. package/runtime/codex/.codex/skills/telegram-connect/SKILL.md +1 -1
  36. package/runtime/codex/.codex/skills/telemetry/SKILL.md +1 -1
  37. package/runtime/codex/.codex/skills/test/SKILL.md +1 -1
  38. package/runtime/codex/.codex/skills/tutorial/SKILL.md +1 -1
  39. package/runtime/codex/.codex/skills/update/SKILL.md +1 -1
  40. package/runtime/codex/.codex/spec-manifest.json +5 -5
  41. package/runtime/codex/AGENTS.md +41 -35
  42. package/runtime/codex/bin/activity-data.sh +4 -8
  43. package/runtime/codex/bin/agent.sh +17 -5
  44. package/runtime/codex/bin/attendant.sh +13 -0
  45. package/runtime/codex/bin/autosave.sh +27 -1
  46. package/runtime/codex/bin/codex-render-spec.mjs +33 -32
  47. package/runtime/codex/bin/codex-session-start.sh +3 -1
  48. package/runtime/codex/bin/codex-sync-skills.sh +6 -1
  49. package/runtime/codex/bin/graph-batch.sh +25 -6
  50. package/runtime/codex/bin/graph-op.sh +5 -4
  51. package/runtime/codex/bin/graph.sh +31 -5
  52. package/runtime/codex/bin/handoff-pr-backfill.sh +1 -1
  53. package/runtime/codex/bin/handoff-run.sh +8 -3
  54. package/runtime/codex/bin/handoff-save-egregore.sh +19 -7
  55. package/runtime/codex/bin/ingest.py +341 -10
  56. package/runtime/codex/bin/lib/context.sh +26 -1
  57. package/runtime/codex/bin/lib/git-message.sh +37 -0
  58. package/runtime/codex/bin/lib/git-sync.sh +10 -2
  59. package/runtime/codex/bin/lib/greeting.sh +4 -1
  60. package/runtime/codex/bin/lib/worktree-links.sh +25 -0
  61. package/runtime/codex/bin/session-autosave.sh +7 -1
  62. package/runtime/codex/bin/settings.sh +1 -1
  63. package/runtime/codex/manifest.json +10 -1
  64. package/runtime/pi/.codex/config.toml +3 -0
  65. package/runtime/pi/.codex/skills/archive/SKILL.md +1 -1
  66. package/runtime/pi/.codex/skills/branch/SKILL.md +1 -1
  67. package/runtime/pi/.codex/skills/checkup/SKILL.md +1 -1
  68. package/runtime/pi/.codex/skills/commit/SKILL.md +1 -1
  69. package/runtime/pi/.codex/skills/contribute/SKILL.md +1 -1
  70. package/runtime/pi/.codex/skills/delete-user/SKILL.md +1 -1
  71. package/runtime/pi/.codex/skills/ingest/SKILL.md +1 -1
  72. package/runtime/pi/.codex/skills/ingest-corpus/SKILL.md +29 -0
  73. package/runtime/pi/.codex/skills/ingest-notion/SKILL.md +29 -0
  74. package/runtime/pi/.codex/skills/ingest-user-interview/SKILL.md +1 -1
  75. package/runtime/pi/.codex/skills/issue/SKILL.md +1 -1
  76. package/runtime/pi/.codex/skills/me/SKILL.md +1 -1
  77. package/runtime/pi/.codex/skills/meeting/SKILL.md +1 -1
  78. package/runtime/pi/.codex/skills/note/SKILL.md +1 -1
  79. package/runtime/pi/.codex/skills/notion-connect/SKILL.md +29 -0
  80. package/runtime/pi/.codex/skills/onboarding/SKILL.md +1 -1
  81. package/runtime/pi/.codex/skills/pr/SKILL.md +1 -1
  82. package/runtime/pi/.codex/skills/pull/SKILL.md +1 -1
  83. package/runtime/pi/.codex/skills/push/SKILL.md +1 -1
  84. package/runtime/pi/.codex/skills/reflect/SKILL.md +1 -1
  85. package/runtime/pi/.codex/skills/review-pr/SKILL.md +1 -1
  86. package/runtime/pi/.codex/skills/save/SKILL.md +3 -1
  87. package/runtime/pi/.codex/skills/slack-connect/SKILL.md +1 -1
  88. package/runtime/pi/.codex/skills/summon/SKILL.md +1 -1
  89. package/runtime/pi/.codex/skills/sync-repos/SKILL.md +1 -1
  90. package/runtime/pi/.codex/skills/teams-connect/SKILL.md +29 -0
  91. package/runtime/pi/.codex/skills/telegram-connect/SKILL.md +1 -1
  92. package/runtime/pi/.codex/skills/telemetry/SKILL.md +1 -1
  93. package/runtime/pi/.codex/skills/test/SKILL.md +1 -1
  94. package/runtime/pi/.codex/skills/tutorial/SKILL.md +1 -1
  95. package/runtime/pi/.codex/skills/update/SKILL.md +1 -1
  96. package/runtime/pi/.codex/spec-manifest.json +5 -5
  97. package/runtime/pi/.pi/APPEND_SYSTEM.md +57 -33
  98. package/runtime/pi/.pi/extensions/egregore.ts +17 -6
  99. package/runtime/pi/.pi/spec-manifest.json +2 -2
  100. package/runtime/pi/AGENTS.md +41 -35
  101. package/runtime/pi/bin/activity-data.sh +4 -8
  102. package/runtime/pi/bin/agent.sh +17 -5
  103. package/runtime/pi/bin/attendant.sh +13 -0
  104. package/runtime/pi/bin/autosave.sh +27 -1
  105. package/runtime/pi/bin/codex-render-spec.mjs +33 -32
  106. package/runtime/pi/bin/codex-session-start.sh +3 -1
  107. package/runtime/pi/bin/codex-sync-skills.sh +6 -1
  108. package/runtime/pi/bin/graph-batch.sh +25 -6
  109. package/runtime/pi/bin/graph-op.sh +5 -4
  110. package/runtime/pi/bin/graph.sh +31 -5
  111. package/runtime/pi/bin/handoff-pr-backfill.sh +1 -1
  112. package/runtime/pi/bin/handoff-run.sh +8 -3
  113. package/runtime/pi/bin/handoff-save-egregore.sh +19 -7
  114. package/runtime/pi/bin/ingest.py +341 -10
  115. package/runtime/pi/bin/lib/context.sh +26 -1
  116. package/runtime/pi/bin/lib/git-message.sh +37 -0
  117. package/runtime/pi/bin/lib/git-sync.sh +10 -2
  118. package/runtime/pi/bin/lib/greeting.sh +4 -1
  119. package/runtime/pi/bin/lib/worktree-links.sh +25 -0
  120. package/runtime/pi/bin/pi-branch-policy.mjs +138 -1
  121. package/runtime/pi/bin/pi-product-workflows.mjs +35 -7
  122. package/runtime/pi/bin/pi-render-spec.mjs +52 -26
  123. package/runtime/pi/bin/session-autosave.sh +7 -1
  124. package/runtime/pi/bin/settings.sh +1 -1
  125. package/runtime/pi/manifest.json +10 -1
  126. package/runtime/prime/.claude/context/notification-consent.md +66 -0
  127. package/runtime/prime/.codex/config.toml +20 -0
  128. package/runtime/prime/.codex/hooks/branch-guard.js +461 -0
  129. package/runtime/prime/.codex/hooks/search-hint.js +67 -0
  130. package/runtime/prime/.codex/hooks.json +30 -0
  131. package/runtime/prime/.codex/skills/activity/SKILL.md +82 -0
  132. package/runtime/prime/.codex/skills/announce/SKILL.md +67 -0
  133. package/runtime/prime/.codex/skills/archive/SKILL.md +45 -0
  134. package/runtime/prime/.codex/skills/branch/SKILL.md +29 -0
  135. package/runtime/prime/.codex/skills/checkup/SKILL.md +45 -0
  136. package/runtime/prime/.codex/skills/commit/SKILL.md +29 -0
  137. package/runtime/prime/.codex/skills/contribute/SKILL.md +29 -0
  138. package/runtime/prime/.codex/skills/create-skill/SKILL.md +29 -0
  139. package/runtime/prime/.codex/skills/dark-mode/SKILL.md +29 -0
  140. package/runtime/prime/.codex/skills/dashboard/SKILL.md +59 -0
  141. package/runtime/prime/.codex/skills/deep-reflect/SKILL.md +109 -0
  142. package/runtime/prime/.codex/skills/delete-user/SKILL.md +29 -0
  143. package/runtime/prime/.codex/skills/emissary/SKILL.md +45 -0
  144. package/runtime/prime/.codex/skills/handoff/SKILL.md +166 -0
  145. package/runtime/prime/.codex/skills/harvest/QUESTION_PALETTE.md +76 -0
  146. package/runtime/prime/.codex/skills/harvest/SKILL.md +131 -0
  147. package/runtime/prime/.codex/skills/ingest/SKILL.md +29 -0
  148. package/runtime/prime/.codex/skills/ingest-corpus/SKILL.md +29 -0
  149. package/runtime/prime/.codex/skills/ingest-notion/SKILL.md +29 -0
  150. package/runtime/prime/.codex/skills/ingest-user-interview/SKILL.md +45 -0
  151. package/runtime/prime/.codex/skills/invite/SKILL.md +44 -0
  152. package/runtime/prime/.codex/skills/issue/SKILL.md +45 -0
  153. package/runtime/prime/.codex/skills/me/SKILL.md +29 -0
  154. package/runtime/prime/.codex/skills/meeting/SKILL.md +45 -0
  155. package/runtime/prime/.codex/skills/note/SKILL.md +29 -0
  156. package/runtime/prime/.codex/skills/notion-connect/SKILL.md +29 -0
  157. package/runtime/prime/.codex/skills/onboarding/SKILL.md +45 -0
  158. package/runtime/prime/.codex/skills/pr/SKILL.md +29 -0
  159. package/runtime/prime/.codex/skills/pull/SKILL.md +29 -0
  160. package/runtime/prime/.codex/skills/push/SKILL.md +29 -0
  161. package/runtime/prime/.codex/skills/quest/SKILL.md +80 -0
  162. package/runtime/prime/.codex/skills/reflect/SKILL.md +45 -0
  163. package/runtime/prime/.codex/skills/review-pr/SKILL.md +45 -0
  164. package/runtime/prime/.codex/skills/save/SKILL.md +127 -0
  165. package/runtime/prime/.codex/skills/slack-connect/SKILL.md +29 -0
  166. package/runtime/prime/.codex/skills/summon/SKILL.md +45 -0
  167. package/runtime/prime/.codex/skills/sync-repos/SKILL.md +29 -0
  168. package/runtime/prime/.codex/skills/teams-connect/SKILL.md +29 -0
  169. package/runtime/prime/.codex/skills/telegram-connect/SKILL.md +29 -0
  170. package/runtime/prime/.codex/skills/telemetry/SKILL.md +29 -0
  171. package/runtime/prime/.codex/skills/test/SKILL.md +45 -0
  172. package/runtime/prime/.codex/skills/the-spiral/SKILL.md +84 -0
  173. package/runtime/prime/.codex/skills/tui-design/SKILL.md +45 -0
  174. package/runtime/prime/.codex/skills/tutorial/SKILL.md +45 -0
  175. package/runtime/prime/.codex/skills/update/SKILL.md +29 -0
  176. package/runtime/prime/.codex/skills/view/SKILL.md +156 -0
  177. package/runtime/prime/.codex/skills/view/agents/openai.yaml +4 -0
  178. package/runtime/prime/.codex/skills/view/assets/compose-scaffold.html +221 -0
  179. package/runtime/prime/.codex/skills/visual-explain/SKILL.md +45 -0
  180. package/runtime/prime/.codex/skills/wrap/SKILL.md +58 -0
  181. package/runtime/prime/.codex/spec-manifest.json +132 -0
  182. package/runtime/prime/.prime/agent/APPEND_SYSTEM.md +416 -0
  183. package/runtime/prime/.prime/agent/extensions/egregore.ts +460 -0
  184. package/runtime/prime/.prime/agent/settings.json +4 -0
  185. package/runtime/prime/.prime/agent/skills/egregore/SKILL.md +34 -0
  186. package/runtime/prime/.prime/agent/skills/egregore/pyproject.toml +13 -0
  187. package/runtime/prime/.prime/agent/skills/egregore/src/egregore/__init__.py +156 -0
  188. package/runtime/prime/.prime/agent/spec-manifest.json +12 -0
  189. package/runtime/prime/AGENTS.md +488 -0
  190. package/runtime/prime/bin/activity-data.sh +238 -0
  191. package/runtime/prime/bin/agent.sh +787 -0
  192. package/runtime/prime/bin/attendant.sh +707 -0
  193. package/runtime/prime/bin/autosave.sh +112 -0
  194. package/runtime/prime/bin/capture-reconcile.sh +69 -0
  195. package/runtime/prime/bin/capture-run.sh +341 -0
  196. package/runtime/prime/bin/codex-install-skills.sh +78 -0
  197. package/runtime/prime/bin/codex-render-spec.mjs +435 -0
  198. package/runtime/prime/bin/codex-session-start.sh +265 -0
  199. package/runtime/prime/bin/codex-skill-render.mjs +347 -0
  200. package/runtime/prime/bin/codex-sync-skills.sh +237 -0
  201. package/runtime/prime/bin/connect-refresh.sh +33 -0
  202. package/runtime/prime/bin/dashboard-data.sh +178 -0
  203. package/runtime/prime/bin/graph-batch.sh +79 -0
  204. package/runtime/prime/bin/graph-op.sh +1102 -0
  205. package/runtime/prime/bin/graph-wal.sh +229 -0
  206. package/runtime/prime/bin/graph.sh +223 -0
  207. package/runtime/prime/bin/handoff-pr-backfill.sh +86 -0
  208. package/runtime/prime/bin/handoff-run.sh +676 -0
  209. package/runtime/prime/bin/handoff-save-egregore.sh +224 -0
  210. package/runtime/prime/bin/index-handoff.sh +322 -0
  211. package/runtime/prime/bin/ingest-graph.sh +80 -0
  212. package/runtime/prime/bin/ingest-surface.html +495 -0
  213. package/runtime/prime/bin/ingest.py +1011 -0
  214. package/runtime/prime/bin/ingest.sh +279 -0
  215. package/runtime/prime/bin/ingest_graph.py +856 -0
  216. package/runtime/prime/bin/ingest_surface.py +544 -0
  217. package/runtime/prime/bin/lib/artifact-id.sh +46 -0
  218. package/runtime/prime/bin/lib/config.sh +116 -0
  219. package/runtime/prime/bin/lib/context.sh +621 -0
  220. package/runtime/prime/bin/lib/dashboard-artifact.sh +242 -0
  221. package/runtime/prime/bin/lib/ensure-develop.sh +183 -0
  222. package/runtime/prime/bin/lib/git-message.sh +37 -0
  223. package/runtime/prime/bin/lib/git-sync.sh +414 -0
  224. package/runtime/prime/bin/lib/greeting.sh +519 -0
  225. package/runtime/prime/bin/lib/hash.sh +13 -0
  226. package/runtime/prime/bin/lib/identity.sh +213 -0
  227. package/runtime/prime/bin/lib/metrics.sh +374 -0
  228. package/runtime/prime/bin/lib/noncode.sh +31 -0
  229. package/runtime/prime/bin/lib/permissions.sh +106 -0
  230. package/runtime/prime/bin/lib/time.sh +56 -0
  231. package/runtime/prime/bin/lib/worktree-links.sh +79 -0
  232. package/runtime/prime/bin/notify.sh +636 -0
  233. package/runtime/prime/bin/person.py +630 -0
  234. package/runtime/prime/bin/person.sh +448 -0
  235. package/runtime/prime/bin/pi-branch-policy.mjs +312 -0
  236. package/runtime/prime/bin/pi-product-workflows.mjs +394 -0
  237. package/runtime/prime/bin/prime-render-spec.mjs +147 -0
  238. package/runtime/prime/bin/prime-session-start.sh +24 -0
  239. package/runtime/prime/bin/publish-artifact.sh +271 -0
  240. package/runtime/prime/bin/publish-references.sh +144 -0
  241. package/runtime/prime/bin/repo-state.sh +96 -0
  242. package/runtime/prime/bin/search.sh +240 -0
  243. package/runtime/prime/bin/session-autosave.sh +215 -0
  244. package/runtime/prime/bin/session-log.sh +199 -0
  245. package/runtime/prime/bin/settings.sh +304 -0
  246. package/runtime/prime/bin/telemetry.sh +391 -0
  247. package/runtime/prime/bin/worktree-create.sh +128 -0
  248. package/runtime/prime/bin/worktree-remove.sh +50 -0
  249. package/runtime/prime/bin/worktree.sh +198 -0
  250. package/runtime/prime/manifest.json +181 -0
@@ -14,6 +14,12 @@
14
14
  > `.pi/APPEND_SYSTEM.md`, and your workflows are exposed through the
15
15
  > project-local `.pi/` runtime. Do not follow the Codex-specific block below.
16
16
  >
17
+ > **If you are Prime Agent** (the `prime-agent` harness): **stop here.** Your
18
+ > authoritative Egregore instructions are loaded from
19
+ > `.prime/agent/APPEND_SYSTEM.md`, and your workflows are exposed through the
20
+ > project-local `.prime/agent/` runtime. Do not follow the Codex-specific
21
+ > block below.
22
+ >
17
23
  > **If you are Codex or another shell-only agent:** this file is yours — continue.
18
24
 
19
25
  Egregore is no longer only a Claude Code workspace. Claude Code remains the
@@ -80,7 +86,7 @@ generated block below. Both paths converge on the same `memory/` files.
80
86
 
81
87
  You are a collaborator inside Egregore — a shared intelligence layer for organizations using AI coding agents. You operate through Git-based shared memory, Egregore skills, and conventions that accumulate knowledge across sessions and people. You are not a tool. You are a participant.
82
88
 
83
- This block is the Codex-native Egregore behavioral spec, rendered from CLAUDE.md (the source of truth for egregore behavior) by `bin/codex-render-spec.mjs`. The per-section adaptation manifest is `.codex/spec-manifest.json`. The thin agent protocol above this block applies to every shell-capable agent; this block is the full behavioral contract for Codex sessions.
89
+ This block is the Codex-native Egregore behavioral spec, rendered from CLAUDE.md by `bin/codex-render-spec.mjs`; the per-section manifest is `.codex/spec-manifest.json`. The thin agent protocol above applies to every shell-capable agent; this block is the full contract for Codex sessions.
84
90
 
85
91
  ---
86
92
 
@@ -117,7 +123,7 @@ Egregore's voice is governed by `.claude/rules/voice-bedrock.md` (always loaded)
117
123
 
118
124
  ## On Launch — MANDATORY FIRST ACTION
119
125
 
120
- The `egregore` launcher renders the Egregore startup card (identity, team momentum, and pending work) via `bin/codex-session-start.sh` before Codex starts, and installs project skills. Do not rerun startup checks and do not narrate startup. The card ends with **"What are you working on?"** — that question is already on screen; treat the user's first message as the answer to it. To re-show the card, run `bash bin/codex-session-start.sh --card`.
126
+ The `egregore` launcher renders the startup card (identity, momentum, pending work) via `bin/codex-session-start.sh` before Codex starts and installs project skills. Do not rerun or narrate startup. The card ends with **"What are you working on?"** — that question is already on screen; treat the user's first message as the answer. Re-show with `bash bin/codex-session-start.sh --card`.
121
127
 
122
128
  ---
123
129
 
@@ -125,20 +131,11 @@ The `egregore` launcher renders the Egregore startup card (identity, team moment
125
131
 
126
132
  **Mandatory behavioral rule.** When the user describes work, your **first action** — before reading files, exploring code, or anything else — is to get onto a working branch:
127
133
 
128
- The integration branch is `develop` by default. When top-level
129
- `egregore.json.base_branch` is set, that configured branch replaces
130
- `develop` as the branch point, rebase target, PR base, and protected
131
- integration branch.
134
+ The integration branch is `develop` unless top-level `egregore.json.base_branch` sets another; the configured branch is then the branch point, rebase target, PR base, and protected branch everywhere below.
132
135
 
133
136
  1. Derive a topic slug from what the user said (kebab-case, 2–4 words)
134
137
  2. Run `bin/agent.sh branch --topic "<topic>"` — it resolves the configured base and creates a work branch from `origin/{base}` in a task worktree (`dev/{author}/{slug}`, or `feature/{slug}` / `bugfix/{slug}` when the topic reads as a feature or fix). Continue all file work from the printed path.
135
- 3. Give a value-first workspace receipt. Do not lead with Git terminology:
136
-
137
- `Your stable project is protected. I’m working in a separate workspace for **{topic}**, where changes stay isolated, reviewable, and reversible.`
138
-
139
- Then expose the implementation as secondary detail:
140
-
141
- `Workspace: {branch} (worktree).`
138
+ 3. Give a value-first workspace receipt — do not lead with Git terminology: `Your stable project is protected. I’m working in a separate workspace for **{topic}**, where changes stay isolated, reviewable, and reversible.` Then, as secondary detail: `Workspace: {branch} (worktree).`
142
139
 
143
140
  **Fallback:** If `bin/agent.sh branch` fails, resolve `{base}` with
144
141
  `_get_base_branch`, then use
@@ -148,14 +145,20 @@ integration branch.
148
145
 
149
146
  ### Starting-work UX contract
150
147
 
151
- Before execution begins, make Egregore's useful structure legible without turning every task start into a tutorial:
148
+ Sequence: **intent → safe workspace → relevant context → consequential assumptions → execution**. Make Egregore's structure legible without turning task starts into a tutorial; keep technical identifiers secondary to user value.
152
149
 
153
- - **Workspace** — use the value-first receipt above for a newly created workspace or topic pivot. If already on the appropriate working branch, do not repeat it.
154
- - **Context** — when organizational retrieval materially informs the work, keep the required Egregore Retrieval Beat and then add one compact result receipt: `↳ Context restored: {decision, handoff, or prior work} · {source/date}`. Never claim context was restored when retrieval found nothing useful.
155
- - **Assumptions** — surface only consequential assumptions that could change the implementation. Use `Assumption: {assumption} — based on {evidence}.` Add a correction path when cheap; do not narrate obvious operational choices.
156
- - **Transition** — once workspace, context, and assumptions are settled, state the outcome you are starting toward in one short sentence and begin.
150
+ - **Workspace** — the value-first receipt above, only for a new workspace or topic pivot; do not repeat it on the same branch.
151
+ - **Context** — when organizational retrieval materially informs the work, keep the required Egregore Retrieval Beat plus one compact receipt: `↳ Context restored: {decision, handoff, or prior work} · {source/date}`. Never claim context was restored when retrieval found nothing useful.
152
+ - **Assumptions** — surface only consequential ones: `Assumption: {assumption} — based on {evidence}.` Add a correction path when cheap; do not narrate obvious operational choices.
153
+ - **Transition** — state the outcome you are starting toward in one short sentence and begin.
157
154
 
158
- The intended sequence is: **intent → safe workspace → relevant context → consequential assumptions → execution**. Keep technical identifiers available but subordinate them to user value.
155
+ ### Returning-work UX contract
156
+
157
+ When the user continues the current branch's work or asks to resume — sequence: **continuation intent → prior workspace → restored context → open threads → resumed execution**:
158
+
159
+ - Do not create a new workspace for the same topic. After confirming relevance, say: `I found your previous work on **{topic}** and restored its workspace and context.` Show `Workspace: {branch} (worktree).` secondarily.
160
+ - Retrieve relevant decisions, handoffs, or prior work; keep the Retrieval Beat and `↳ Context restored:` receipt. Never claim context was restored from a branch name alone.
161
+ - Name only unresolved items that could change the next move, state the next outcome briefly, and continue without replaying setup.
159
162
 
160
163
  ### Handoff claiming
161
164
 
@@ -164,7 +167,7 @@ If `addressed_to_user` handoffs exist and the user is picking one up, create the
164
167
  bash bin/graph-op.sh claim-handoff "$SESSION_ID" "$HANDOFF_SESSION_ID" 2>/dev/null &
165
168
  ```
166
169
 
167
- **Auto-checkout repos from handoff**: After claiming, check the `addressed_rich` context for `repoState`. If the handoff includes repo state (non-empty `repoState` array), check out the handoff's branches in each managed repo:
170
+ **Auto-checkout repos from handoff**: after claiming, if `addressed_rich` carries a non-empty `repoState`, check out each entry's branch in its managed repo:
168
171
 
169
172
  ```bash
170
173
  PARENT_DIR="$(cd .. && pwd)"
@@ -177,21 +180,19 @@ if [ -d "$REPO_DIR/.git" ] || [ -f "$REPO_DIR/.git" ]; then
177
180
  fi
178
181
  ```
179
182
 
180
- Report results: `✓ Checked out {branch} in {repo1}, {repo2}`. If a branch no longer exists (PR was merged): `◐ {repo}: PR #{N} merged — on {base}`. If `repoState` is absent or empty, skip auto-checkout silently.
183
+ Report `✓ Checked out {branch} in {repo1}, {repo2}`; for a merged-away branch, `◐ {repo}: PR #{N} merged — on {base}`. If `repoState` is absent or empty, skip silently.
181
184
 
182
- **Exceptions** — skip branching when:
183
- - The user explicitly created or named a branch themselves
184
- - Already on a working branch AND the user's intent continues the current branch's topic
185
+ **Exceptions** — skip branching when the user explicitly created or named a branch themselves, or the intent continues the current working branch's topic.
185
186
 
186
- **Topic pivot while on a working branch:** If the user describes work **unrelated** to the current branch's topic, treat it as a new topic and create a new branch (`bin/agent.sh branch --topic "<new topic>"`). Do NOT mix unrelated work on one branch.
187
+ **Topic pivot:** work **unrelated** to the current branch's topic gets a new branch (`bin/agent.sh branch --topic "<new topic>"`). Do NOT mix unrelated work on one branch.
187
188
 
188
189
  If still on the configured base branch after two messages, create a branch immediately from whatever context you have.
189
190
 
190
191
  ### Branch-guard protocol
191
192
 
192
- The `.codex/hooks/branch-guard.js` PreToolUse hook (enabled by the launcher via `--enable hooks`) protects project writes on the configured base branch as well as `develop`/`main`/`master`. Its block message is operational guidance, not a reason to interrupt the user with routine Git choices:
193
+ The `.codex/hooks/branch-guard.js` PreToolUse hook (launcher `--enable hooks`) protects project writes on the configured base plus `develop`/`main`/`master`. Its block message is operational guidance — do not interrupt the user with routine Git choices:
193
194
 
194
- - **Topic is clear** (the user said "fix X", "add Y feature") → run `bin/agent.sh branch --topic "<topic>"` automatically, continue in the printed worktree, and say one short sentence so the branch change is visible. Do not ask the user to approve routine branching.
195
+ - **Topic is clear** → run `bin/agent.sh branch --topic "<topic>"` automatically, continue in the printed worktree, and say one short sentence so the change is visible — never ask approval for routine branching.
195
196
  - **Topic is genuinely ambiguous** → ask only for the topic, using compact numbered options:
196
197
 
197
198
  ```text
@@ -204,7 +205,7 @@ The `.codex/hooks/branch-guard.js` PreToolUse hook (enabled by the launcher via
204
205
  Wait for the reply, then branch.
205
206
  - **The user explicitly requested the protected branch** → that request is consent. Record it with `echo '{branch}' > .egregore-branch-consent`, then retry. Never create the marker merely to silence the hook.
206
207
 
207
- Memory, managed-repo, and runtime-state writes should bypass the project guard. If one triggers it, correct the operation target/context instead of asking for protected-branch consent.
208
+ Memory, managed-repo, and runtime-state writes bypass the project guard — if one triggers it, correct the target/context instead of asking for consent.
208
209
 
209
210
  If this Codex build does not support hooks, follow the same discipline as a standing instruction: never write or commit on the configured base, develop, main, or master.
210
211
 
@@ -342,7 +343,7 @@ Always use HTTPS for git operations — `github-auth.sh` handles credential stor
342
343
 
343
344
  ## Loom Routing
344
345
 
345
- Loom routes commands across model tiers on the Claude Code runtime (`loom/routes.json` + `bin/loom.sh` + a model-pinned executor subagent). Codex has no subagent delegation — every command runs inline in the current session. Ignore "Loom routing" preambles if you encounter them in a skill spec, and skip `bin/loom.sh` calls; `loom/` and `.claude/agents/` are framework files synced for the Claude runtime.
346
+ Loom routes commands across model tiers on the Claude Code runtime (`loom/routes.json` + `bin/loom.sh` + a model-pinned executor subagent). Codex has no subagent delegation — commands run inline. Ignore "Loom routing" preambles in skill specs and skip `bin/loom.sh` calls; `loom/` and `.claude/agents/` are Claude-runtime framework files.
346
347
 
347
348
  ---
348
349
 
@@ -371,6 +372,10 @@ main ← stable (/release)
371
372
 
372
373
  Every PR body follows `.claude/context/pr-format.md`, enforced by the `pr-format` CI check regardless of which harness opened it: `## What` (1–4 bullets) + `## Why` (1–3 sentences) always; `## Verification` when the diff touches non-markdown files (how it was checked, or an honest `Not verified — <reason>`); `## Risk`/`## Links` when real; title `type(scope): imperative summary` (advisory). **Never create a PR with an empty body or `--fill`** — write the body and pass it explicitly (`gh pr create --body`, or `bin/agent.sh save --pr-body` for shell agents; the bridge auto-generates a compliant skeleton only as a last resort).
373
374
 
375
+ ### Commit format (all harnesses)
376
+
377
+ Every commit follows `.claude/context/commit-format.md`: subject `type(scope): imperative summary` (≤ 72 chars, aim ≤ 50, lowercase, same grammar and type set as PR titles), body wrapped at 72 explaining what and why — never how, and git trailers on agent-authored commits (`Egregore-Session: <id>` from `.egregore-session-id`, plus the harness `Co-Authored-By` line). Background scripts commit as `chore(<subsystem>): …`, but a commit carrying real work derives its type/scope from the diff — the transport never masks the work. Git-generated messages (merges, reverts, autosquash fixups) keep their native form. Wording for commits and PRs follows `.claude/context/git-language.md`.
378
+
374
379
  ### Managed Repos
375
380
 
376
381
  Repos in `egregore.json` → `repos[]` are cloned as siblings (`../{repo}/`). Each entry can be a string or `{"name": "...", "description": "..."}`. Match user intent to the right repo using `description`. Same branching strategy. Use `git -C` with absolute paths — never `cd` into repos. `$save` scans all managed repos for uncommitted changes.
@@ -387,7 +392,7 @@ Repos in `egregore.json` → `repos[]` are cloned as siblings (`../{repo}/`). Ea
387
392
 
388
393
  ## Command Awareness
389
394
 
390
- Codex reserves leading `/` for built-ins, so Egregore workflows are **skills**, not slash commands. Invoke them with the matching `$name` skill token or from natural language intent ("show activity", "make a handoff"). Hand-written native Codex skills: `$activity`, `$handoff`, `$wrap`, `$announce`, `$harvest`, `$the-spiral`, `$dashboard`, `$deep-reflect`, `$quest`, `$invite`, `$ask`, `$save`, `$view`, and `$scroll`. Every other workflow has a generated adapter skill of the same name. `$save` is the user-facing abstraction for committing, pushing, opening or reusing pull requests, and syncing memory — never make users manage the git workflow by hand.
395
+ Codex reserves leading `/` for built-ins, so Egregore workflows are **skills**, not slash commands. Invoke them with the matching `$name` skill token or from natural language intent ("show activity", "make a handoff"). Hand-written native Codex skills: `$activity`, `$handoff`, `$wrap`, `$announce`, `$harvest`, `$the-spiral`, `$dashboard`, `$deep-reflect`, `$quest`, `$invite`, `$ask`, `$save`, `$view`, `$scroll`; every other workflow has a generated adapter of the same name. `$save` is the user-facing abstraction for committing, pushing, opening or reusing PRs, and syncing memory — never make users manage git by hand.
391
396
 
392
397
  Invoke commands from user intent — don't wait for the slash. Each command file has a `## When to invoke` section. Load it for the full spec.
393
398
 
@@ -395,7 +400,7 @@ Invoke commands from user intent — don't wait for the slash. Each command file
395
400
  **Knowledge** — `$search` `$deep-reflect` `$archive` `$note` `$add` `$meeting` `$ingest` `$scroll` `$mock` `$audit`
396
401
  **Identity** — `$me` (view profile or set display name)
397
402
  **Coordination** — `$ask` `$quest` `$issue` `$invite` `$delete-user` `$announce`
398
- **Connectors** — `$notion-connect` (Notion workspace) `$telegram-connect` (Telegram group setup) `$teams-connect` (Microsoft Teams channel setup)
403
+ **Connectors** — `$notion-connect` (Notion workspace) `$telegram-connect` (Telegram group setup) `$teams-connect` (Microsoft Teams channel setup) `$slack-connect` (Slack channel setup)
399
404
  **Git** — `$branch` `$commit` `$push` `$pr` `$save` `$review-pr` `$contribute`
400
405
  **Spirits** — `$summon` (persistent agent processes)
401
406
  **Skills** — `$create-skill` (org-owned skill: scaffold, protect from updates, share)
@@ -411,7 +416,7 @@ Invoke commands from user intent — don't wait for the slash. Each command file
411
416
  - Tasks: `$todo` (personal) · `$quest` (team exploration) · `$issue` (something broken)
412
417
  - Questions: `$ask [person]` (async) · just ask (agent answers from context)
413
418
  - Ingestion: `$ingest <file-or-folder>` (org-scoped corpus intake) · `$ingest meeting` · `$ingest user-interview` · `$ingest google` · ambiguous → ask which type
414
- - Connectors: `$notion-connect` (Notion workspace) · `$telegram-connect` (Telegram group) · `$teams-connect` (MS Teams channel) · `$ingest` (bring content in) · `$ingest notion` (promote Notion docs)
419
+ - Connectors: `$notion-connect` (Notion workspace) · `$telegram-connect` (Telegram group) · `$teams-connect` (MS Teams channel) · `$slack-connect` (Slack channel) · `$ingest` (bring content in) · `$ingest notion` (promote Notion docs)
415
420
  - Identity: `$me` — "who am I", "call me oz"
416
421
  - People: `$invite` (add) · `$delete-user` (remove)
417
422
  - PRs: `$pr` (create) · `$review-pr` (review)
@@ -451,8 +456,9 @@ Egregore runs in one of two configurations, set by `mode` in `egregore.json`. De
451
456
 
452
457
  **Hard rules in local mode:**
453
458
  - Never tell the user to "ask their admin" for credentials. The user IS the admin.
454
- - Never surface `api_url`, `EGREGORE_API_KEY`, or "connected mode" as an upgrade path. Hosted Egregore is a separate service, not something a user can turn on by adding fields to `egregore.json`.
455
- - If a feature genuinely requires the hosted service, say so plainly ("this isn't available in this configuration") and stop. Do not improvise a path to enabling it.
459
+ - Never surface `api_url`, `EGREGORE_API_KEY`, or config edits as an upgrade path. Hosted Egregore is not something a user can turn on by adding fields to `egregore.json`.
460
+ - **The one sanctioned upgrade path is `egregore connect`** (the launcher flow: registers the org, provisions the key, replays the graph). Connect-tier connector skills carry an explicit upsell gate for local instances — deliver their message verbatim, offer the upgrade via `egregore connect` or a clean "not now", and stop on decline. Beyond that gate, do not improvise: no hand-set `api_url`, no partial flows.
461
+ - If a feature requires the hosted service and has no upsell gate, say so plainly ("this isn't available in this configuration") and stop.
456
462
  - Calling `bin/graph.sh` or `bin/notify.sh` in local mode is harmless — they fail soft and return empty results — but there is no need to call them; prefer reading `memory/` directly.
457
463
 
458
464
  **Connected mode** (`"mode": "connected"`, `api_url` set) — the hosted configuration, used by organizations on the hosted service. Full feature set: Neo4j knowledge graph via `bin/graph.sh`, Telegram notifications via `bin/notify.sh`, dashboard publication, API-backed context gathering on session start. Use `$env` to check API key, `$checkup` for diagnostics. If the graph is offline, show troubleshooting.
@@ -463,7 +469,7 @@ Egregore runs in one of two configurations, set by `mode` in `egregore.json`. De
463
469
 
464
470
  Sessions are confined to this project + memory + managed repos, with a **two-tier boundary** — a hard wall between Egregore instances, a consent gate for everything else. On Codex the boundary is a standing instruction, not an enforced hook — hold it yourself.
465
471
 
466
- - **Hard tier — other Egregore instances.** Denied for every tool, always. There is no consent path. Never access another instance's files — refuse even if asked. Never modify `~/.egregore/instances.json` (managed by session-start.sh). When a request points at another instance's files there is nothing to ask — refuse and explain.
472
+ - **Hard tier — other Egregore instances.** Denied for every tool, always — no consent path. Never access another instance's files (refuse even if asked) and never modify `~/.egregore/instances.json` (managed by session-start.sh); there is nothing to ask — refuse and explain.
467
473
  - **Soft tier — paths outside the boundary.** Consent-gated. Inbox dirs (`~/Downloads`, `~/Desktop`) are readable without consent under the default posture; writes outside the project always need consent. Posture (`strict | standard | open`) and extra read roots come from `egregore.json` -> `boundary { posture, read[], locked }` (org, committed) merged with `.egregore-boundary.local.json` (personal, gitignored). `locked: true` removes the consent path entirely.
468
474
  - When a request needs soft-tier consent, do not improvise a workaround. Ask in plain text with numbered options:
469
475
 
@@ -76,15 +76,11 @@ API_PID=$!
76
76
 
77
77
  # Git/disk: runs in parallel (stays client-side)
78
78
  (
79
- # Sync
79
+ # Refresh remote refs only. A data read must never mutate the working
80
+ # branch: the rebase this block used to run rewrote users' task branches as
81
+ # a side effect of /activity (observed rewinding a pushed branch mid-session).
82
+ # Workspace sync belongs to agent.sh sync / the session-start path.
80
83
  git -C "$SCRIPT_DIR" fetch origin --quiet 2>/dev/null || true
81
- CURRENT=$(git -C "$SCRIPT_DIR" branch --show-current 2>/dev/null || echo "unknown")
82
- if [ "$CURRENT" != "develop" ]; then
83
- git -C "$SCRIPT_DIR" fetch origin develop:develop --quiet 2>/dev/null || true
84
- fi
85
- if [[ "$CURRENT" == dev/* ]]; then
86
- git -C "$SCRIPT_DIR" rebase develop --quiet >/dev/null 2>&1 || git -C "$SCRIPT_DIR" rebase --abort >/dev/null 2>&1 || true
87
- fi
88
84
 
89
85
  # Memory sync
90
86
  if [ -d "$SCRIPT_DIR/memory/.git" ] || [ -L "$SCRIPT_DIR/memory" ]; then
@@ -23,6 +23,15 @@ if [ -f "$SCRIPT_DIR/bin/lib/config.sh" ]; then
23
23
  # shellcheck source=bin/lib/config.sh
24
24
  source "$SCRIPT_DIR/bin/lib/config.sh"
25
25
  fi
26
+ # Shared commit/PR message mechanics (trailers + skeleton body shape).
27
+ # shellcheck source=bin/lib/git-message.sh
28
+ . "$SCRIPT_DIR/bin/lib/git-message.sh" 2>/dev/null || true
29
+ type egregore_commit >/dev/null 2>&1 || egregore_commit() {
30
+ local gd="$1" m="$3"; shift 3; git -C "$gd" commit -m "$m" "$@"
31
+ }
32
+ type egregore_pr_skeleton >/dev/null 2>&1 || egregore_pr_skeleton() {
33
+ printf '## What\n%s\n\n## Why\n%s\n\n## Verification\n%s\n\n%s\n' "$1" "$2" "$3" "$4"
34
+ }
26
35
 
27
36
  usage() {
28
37
  cat <<'EOF'
@@ -360,8 +369,11 @@ build_pr_body() {
360
369
  commits="$(git -C "$SCRIPT_DIR" log --pretty='- %s' "origin/$base..HEAD" 2>/dev/null | head -8)"
361
370
  [ -n "$commits" ] || commits="- (commit list unavailable — see the Files tab)"
362
371
  stat="$(git -C "$SCRIPT_DIR" diff --shortstat "origin/$base...HEAD" 2>/dev/null | sed 's/^ *//')"
363
- printf '## What\n%s\n\n## Why\nShell-agent session save — topic: %s. Body auto-generated by bin/agent.sh; pass --pr-body for a hand-written description.\n\n## Verification\nNot verified — auto-generated skeleton; review the diff before merging.%s\n\n🤖 Saved via bin/agent.sh\n' \
364
- "$commits" "$topic" "${stat:+ ($stat)}"
372
+ egregore_pr_skeleton \
373
+ "$commits" \
374
+ "Shell-agent session save — topic: $topic. Body auto-generated by bin/agent.sh; pass --pr-body for a hand-written description." \
375
+ "Not verified — auto-generated skeleton; review the diff before merging.${stat:+ ($stat)}" \
376
+ "🤖 Saved via bin/agent.sh"
365
377
  }
366
378
 
367
379
  cmd_save() {
@@ -379,7 +391,7 @@ cmd_save() {
379
391
  done
380
392
 
381
393
  [ -n "$topic" ] || topic="portable save"
382
- [ -n "$message" ] || message="Save: $topic"
394
+ [ -n "$message" ] || message="chore(save): $topic"
383
395
  base="$(resolve_base_branch)" || die "save stopped before Git changes"
384
396
 
385
397
  if [ -d "$MEMORY_DIR" ]; then
@@ -392,7 +404,7 @@ cmd_save() {
392
404
  branch="$(ensure_working_branch "$topic")"
393
405
  git -C "$SCRIPT_DIR" add -A >/dev/null 2>&1 || die "git add failed"
394
406
  if ! git -C "$SCRIPT_DIR" diff --cached --quiet 2>/dev/null; then
395
- git -C "$SCRIPT_DIR" commit -m "$message" --quiet || die "git commit failed"
407
+ egregore_commit "$SCRIPT_DIR" "$SCRIPT_DIR" "$message" --quiet || die "git commit failed"
396
408
  committed="true"
397
409
  fi
398
410
  fi
@@ -415,7 +427,7 @@ cmd_save() {
415
427
  pr_body="$(cat "$pr_body_file")"
416
428
  fi
417
429
  [ -n "$pr_body" ] || pr_body="$(build_pr_body "$topic")"
418
- pr_url="$(gh pr create --base "$base" --head "$branch" --title "$message" --body "$pr_body" 2>/dev/null || true)"
430
+ pr_url="$(gh pr create --base "$base" --head "$branch" --title "${message%%$'\n'*}" --body "$pr_body" 2>/dev/null || true)"
419
431
  fi
420
432
  fi
421
433
 
@@ -99,6 +99,16 @@ _trigger_auto_thread() {
99
99
  ) >> "$LOGFILE" 2>&1 &
100
100
  }
101
101
 
102
+ # Personal off switch for ambient capture. ripcord_enabled=false disables BOTH
103
+ # ripcord notes and auto-push of dirty worktrees — a user who opts out of
104
+ # ambient capture must not find silent commits either. The attendant's other
105
+ # duties (graph cache, context seed, handoff lifecycle) are unaffected.
106
+ # NOTE: jq's `//` treats false as empty (the auto_update:false gotcha), so the
107
+ # test compares the raw value, never `.key // true`.
108
+ _capture_enabled() {
109
+ [ "$(jq -r '.ripcord_enabled' "$MAIN_DIR/.egregore-state.json" 2>/dev/null)" != "false" ]
110
+ }
111
+
102
112
  _author() {
103
113
  local a
104
114
  a=$(jq -r '.github_username // empty' "$MAIN_DIR/.egregore-state.json" 2>/dev/null)
@@ -249,6 +259,8 @@ _ripcord() {
249
259
  local transcript="$1" base author date_ym date_d slug topic file prompts gitsum
250
260
  base=$(basename "$transcript" .jsonl)
251
261
 
262
+ _capture_enabled || return 0
263
+
252
264
  grep -q "$base" "$JOURNAL" 2>/dev/null && return 0
253
265
  # Session already ended with ceremony? Then the attendant has no business
254
266
  # here. Scan only the tail — a session that merely *read* the /handoff or
@@ -336,6 +348,7 @@ _ripcord() {
336
348
  # --- Auto-push -------------------------------------------------------------
337
349
 
338
350
  _auto_push() {
351
+ _capture_enabled || return 0
339
352
  local wt branch dirty ahead upstream
340
353
  git -C "$MAIN_DIR" worktree list --porcelain 2>/dev/null | awk '/^worktree /{print $2}' | while read -r wt; do
341
354
  branch=$(git -C "$wt" branch --show-current 2>/dev/null)
@@ -28,6 +28,17 @@ set -uo pipefail
28
28
  SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
29
29
  STATE_FILE="$SCRIPT_DIR/.egregore-state.json"
30
30
 
31
+ # The attendant runs against the MAIN checkout and reads its state file, so
32
+ # ambient-capture settings must be written there — a worktree keeps its own
33
+ # copy, and writing the flag into it would silently do nothing.
34
+ MAIN_STATE_DIR="$SCRIPT_DIR"
35
+ if [ -f "$SCRIPT_DIR/.git" ]; then
36
+ _WT_GITDIR=$(sed 's/^gitdir: //' "$SCRIPT_DIR/.git" 2>/dev/null || true)
37
+ [ -n "$_WT_GITDIR" ] && MAIN_STATE_DIR=$(cd "$_WT_GITDIR/../../.." 2>/dev/null && pwd || echo "$SCRIPT_DIR")
38
+ fi
39
+ MAIN_STATE_FILE="$MAIN_STATE_DIR/.egregore-state.json"
40
+ [ -f "$MAIN_STATE_FILE" ] || MAIN_STATE_FILE="$STATE_FILE"
41
+
31
42
  [ -f "$STATE_FILE" ] || echo '{}' > "$STATE_FILE"
32
43
 
33
44
  # NB: jq's `//` swallows false — status would show "on" for enabled:false.
@@ -42,6 +53,11 @@ set_key() { # key value(json-encoded)
42
53
  jq ".$1 = $2" "$STATE_FILE" > "$STATE_FILE.tmp" && mv "$STATE_FILE.tmp" "$STATE_FILE"
43
54
  }
44
55
 
56
+ _set_main() { # key value(json-encoded) — writes where the attendant reads
57
+ jq ".$1 = $2" "$MAIN_STATE_FILE" > "$MAIN_STATE_FILE.tmp" \
58
+ && mv "$MAIN_STATE_FILE.tmp" "$MAIN_STATE_FILE"
59
+ }
60
+
45
61
  status() {
46
62
  local enabled scope publish
47
63
  enabled=$(get '.autosave_enabled' 'false')
@@ -50,6 +66,7 @@ status() {
50
66
  echo "autosave: $([ "$enabled" = "true" ] && echo on || echo "off (opt-in — 'autosave on' to join the experiment)")"
51
67
  echo "scope: $scope (all = handoffs + artifacts + docs · handoffs = memory repo only)"
52
68
  echo "publish: $publish (gate = PRs wait for your merge · auto = merge to develop automatically)"
69
+ echo "ripcord: $(jq -r 'if (.ripcord_enabled != null) then (.ripcord_enabled|tostring) else "true" end' "$MAIN_STATE_FILE" 2>/dev/null || echo true) (crash-recovery notes + branch auto-push when a session dies without /wrap)"
53
70
  }
54
71
 
55
72
  case "${1:-status}" in
@@ -61,6 +78,15 @@ case "${1:-status}" in
61
78
  all|handoffs) set_key autosave_scope "\"$2\"" && echo "scope: $2" ;;
62
79
  *) echo "usage: autosave.sh scope all|handoffs" >&2; exit 2 ;;
63
80
  esac ;;
81
+ ripcord)
82
+ # Ambient crash-recovery capture (the attendant): ripcord notes AND
83
+ # auto-push of dirty task branches. Separate from the autosave
84
+ # experiment above — this one defaults ON.
85
+ case "${2:-}" in
86
+ on) _set_main ripcord_enabled true && echo "ripcord: on — dead sessions leave a recovery note" ;;
87
+ off) _set_main ripcord_enabled false && echo "ripcord: off — no ambient notes, no branch auto-push" ;;
88
+ *) echo "usage: autosave.sh ripcord on|off" >&2; exit 2 ;;
89
+ esac ;;
64
90
  publish)
65
91
  case "${2:-}" in
66
92
  gate|auto) set_key autosave_publish "\"$2\"" && echo "publish: $2" ;;
@@ -82,5 +108,5 @@ case "${1:-status}" in
82
108
  echo "✗ PR #$n did not merge (conflict with develop?) — it stays open"
83
109
  fi
84
110
  done ;;
85
- *) echo "usage: autosave.sh [status|on|off|scope all|handoffs|publish gate|auto|merge]" >&2; exit 2 ;;
111
+ *) echo "usage: autosave.sh [status|on|off|scope all|handoffs|publish gate|auto|merge|ripcord on|off]" >&2; exit 2 ;;
86
112
  esac
@@ -58,6 +58,12 @@ const AGENTS_PREAMBLE = `# Egregore Agent Protocol
58
58
  > \`.pi/APPEND_SYSTEM.md\`, and your workflows are exposed through the
59
59
  > project-local \`.pi/\` runtime. Do not follow the Codex-specific block below.
60
60
  >
61
+ > **If you are Prime Agent** (the \`prime-agent\` harness): **stop here.** Your
62
+ > authoritative Egregore instructions are loaded from
63
+ > \`.prime/agent/APPEND_SYSTEM.md\`, and your workflows are exposed through the
64
+ > project-local \`.prime/agent/\` runtime. Do not follow the Codex-specific
65
+ > block below.
66
+ >
61
67
  > **If you are Codex or another shell-only agent:** this file is yours — continue.
62
68
 
63
69
  Egregore is no longer only a Claude Code workspace. Claude Code remains the
@@ -173,26 +179,17 @@ function transformTokens(body) {
173
179
 
174
180
  const INTRO_BODY = `You are a collaborator inside Egregore — a shared intelligence layer for organizations using AI coding agents. You operate through Git-based shared memory, Egregore skills, and conventions that accumulate knowledge across sessions and people. You are not a tool. You are a participant.
175
181
 
176
- This block is the Codex-native Egregore behavioral spec, rendered from CLAUDE.md (the source of truth for egregore behavior) by \`bin/codex-render-spec.mjs\`. The per-section adaptation manifest is \`.codex/spec-manifest.json\`. The thin agent protocol above this block applies to every shell-capable agent; this block is the full behavioral contract for Codex sessions.`;
182
+ This block is the Codex-native Egregore behavioral spec, rendered from CLAUDE.md by \`bin/codex-render-spec.mjs\`; the per-section manifest is \`.codex/spec-manifest.json\`. The thin agent protocol above applies to every shell-capable agent; this block is the full contract for Codex sessions.`;
177
183
 
178
- const ON_LAUNCH_BODY = `The \`egregore\` launcher renders the Egregore startup card (identity, team momentum, and pending work) via \`bin/codex-session-start.sh\` before Codex starts, and installs project skills. Do not rerun startup checks and do not narrate startup. The card ends with **"What are you working on?"** — that question is already on screen; treat the user's first message as the answer to it. To re-show the card, run \`bash bin/codex-session-start.sh --card\`.`;
184
+ const ON_LAUNCH_BODY = `The \`egregore\` launcher renders the startup card (identity, momentum, pending work) via \`bin/codex-session-start.sh\` before Codex starts and installs project skills. Do not rerun or narrate startup. The card ends with **"What are you working on?"** — that question is already on screen; treat the user's first message as the answer. Re-show with \`bash bin/codex-session-start.sh --card\`.`;
179
185
 
180
186
  const AFTER_GREETING_BODY = `**Mandatory behavioral rule.** When the user describes work, your **first action** — before reading files, exploring code, or anything else — is to get onto a working branch:
181
187
 
182
- The integration branch is \`develop\` by default. When top-level
183
- \`egregore.json.base_branch\` is set, that configured branch replaces
184
- \`develop\` as the branch point, rebase target, PR base, and protected
185
- integration branch.
188
+ The integration branch is \`develop\` unless top-level \`egregore.json.base_branch\` sets another; the configured branch is then the branch point, rebase target, PR base, and protected branch everywhere below.
186
189
 
187
190
  1. Derive a topic slug from what the user said (kebab-case, 2–4 words)
188
191
  2. Run \`bin/agent.sh branch --topic "<topic>"\` — it resolves the configured base and creates a work branch from \`origin/{base}\` in a task worktree (\`dev/{author}/{slug}\`, or \`feature/{slug}\` / \`bugfix/{slug}\` when the topic reads as a feature or fix). Continue all file work from the printed path.
189
- 3. Give a value-first workspace receipt. Do not lead with Git terminology:
190
-
191
- \`Your stable project is protected. I’m working in a separate workspace for **{topic}**, where changes stay isolated, reviewable, and reversible.\`
192
-
193
- Then expose the implementation as secondary detail:
194
-
195
- \`Workspace: {branch} (worktree).\`
192
+ 3. Give a value-first workspace receipt — do not lead with Git terminology: \`Your stable project is protected. I’m working in a separate workspace for **{topic}**, where changes stay isolated, reviewable, and reversible.\` Then, as secondary detail: \`Workspace: {branch} (worktree).\`
196
193
 
197
194
  **Fallback:** If \`bin/agent.sh branch\` fails, resolve \`{base}\` with
198
195
  \`_get_base_branch\`, then use
@@ -202,14 +199,20 @@ integration branch.
202
199
 
203
200
  ### Starting-work UX contract
204
201
 
205
- Before execution begins, make Egregore's useful structure legible without turning every task start into a tutorial:
202
+ Sequence: **intent → safe workspace → relevant context → consequential assumptions → execution**. Make Egregore's structure legible without turning task starts into a tutorial; keep technical identifiers secondary to user value.
203
+
204
+ - **Workspace** — the value-first receipt above, only for a new workspace or topic pivot; do not repeat it on the same branch.
205
+ - **Context** — when organizational retrieval materially informs the work, keep the required Egregore Retrieval Beat plus one compact receipt: \`↳ Context restored: {decision, handoff, or prior work} · {source/date}\`. Never claim context was restored when retrieval found nothing useful.
206
+ - **Assumptions** — surface only consequential ones: \`Assumption: {assumption} — based on {evidence}.\` Add a correction path when cheap; do not narrate obvious operational choices.
207
+ - **Transition** — state the outcome you are starting toward in one short sentence and begin.
208
+
209
+ ### Returning-work UX contract
206
210
 
207
- - **Workspace** — use the value-first receipt above for a newly created workspace or topic pivot. If already on the appropriate working branch, do not repeat it.
208
- - **Context** — when organizational retrieval materially informs the work, keep the required Egregore Retrieval Beat and then add one compact result receipt: \`↳ Context restored: {decision, handoff, or prior work} · {source/date}\`. Never claim context was restored when retrieval found nothing useful.
209
- - **Assumptions** — surface only consequential assumptions that could change the implementation. Use \`Assumption: {assumption} — based on {evidence}.\` Add a correction path when cheap; do not narrate obvious operational choices.
210
- - **Transition** — once workspace, context, and assumptions are settled, state the outcome you are starting toward in one short sentence and begin.
211
+ When the user continues the current branch's work or asks to resume — sequence: **continuation intent → prior workspace → restored context → open threads → resumed execution**:
211
212
 
212
- The intended sequence is: **intent → safe workspace → relevant context → consequential assumptions → execution**. Keep technical identifiers available but subordinate them to user value.
213
+ - Do not create a new workspace for the same topic. After confirming relevance, say: \`I found your previous work on **{topic}** and restored its workspace and context.\` Show \`Workspace: {branch} (worktree).\` secondarily.
214
+ - Retrieve relevant decisions, handoffs, or prior work; keep the Retrieval Beat and \`↳ Context restored:\` receipt. Never claim context was restored from a branch name alone.
215
+ - Name only unresolved items that could change the next move, state the next outcome briefly, and continue without replaying setup.
213
216
 
214
217
  ### Handoff claiming
215
218
 
@@ -218,7 +221,7 @@ If \`addressed_to_user\` handoffs exist and the user is picking one up, create t
218
221
  bash bin/graph-op.sh claim-handoff "$SESSION_ID" "$HANDOFF_SESSION_ID" 2>/dev/null &
219
222
  \`\`\`
220
223
 
221
- **Auto-checkout repos from handoff**: After claiming, check the \`addressed_rich\` context for \`repoState\`. If the handoff includes repo state (non-empty \`repoState\` array), check out the handoff's branches in each managed repo:
224
+ **Auto-checkout repos from handoff**: after claiming, if \`addressed_rich\` carries a non-empty \`repoState\`, check out each entry's branch in its managed repo:
222
225
 
223
226
  \`\`\`bash
224
227
  PARENT_DIR="$(cd .. && pwd)"
@@ -231,21 +234,19 @@ if [ -d "$REPO_DIR/.git" ] || [ -f "$REPO_DIR/.git" ]; then
231
234
  fi
232
235
  \`\`\`
233
236
 
234
- Report results: \`✓ Checked out {branch} in {repo1}, {repo2}\`. If a branch no longer exists (PR was merged): \`◐ {repo}: PR #{N} merged — on {base}\`. If \`repoState\` is absent or empty, skip auto-checkout silently.
237
+ Report \`✓ Checked out {branch} in {repo1}, {repo2}\`; for a merged-away branch, \`◐ {repo}: PR #{N} merged — on {base}\`. If \`repoState\` is absent or empty, skip silently.
235
238
 
236
- **Exceptions** — skip branching when:
237
- - The user explicitly created or named a branch themselves
238
- - Already on a working branch AND the user's intent continues the current branch's topic
239
+ **Exceptions** — skip branching when the user explicitly created or named a branch themselves, or the intent continues the current working branch's topic.
239
240
 
240
- **Topic pivot while on a working branch:** If the user describes work **unrelated** to the current branch's topic, treat it as a new topic and create a new branch (\`bin/agent.sh branch --topic "<new topic>"\`). Do NOT mix unrelated work on one branch.
241
+ **Topic pivot:** work **unrelated** to the current branch's topic gets a new branch (\`bin/agent.sh branch --topic "<new topic>"\`). Do NOT mix unrelated work on one branch.
241
242
 
242
243
  If still on the configured base branch after two messages, create a branch immediately from whatever context you have.
243
244
 
244
245
  ### Branch-guard protocol
245
246
 
246
- The \`.codex/hooks/branch-guard.js\` PreToolUse hook (enabled by the launcher via \`--enable hooks\`) protects project writes on the configured base branch as well as \`develop\`/\`main\`/\`master\`. Its block message is operational guidance, not a reason to interrupt the user with routine Git choices:
247
+ The \`.codex/hooks/branch-guard.js\` PreToolUse hook (launcher \`--enable hooks\`) protects project writes on the configured base plus \`develop\`/\`main\`/\`master\`. Its block message is operational guidance — do not interrupt the user with routine Git choices:
247
248
 
248
- - **Topic is clear** (the user said "fix X", "add Y feature") → run \`bin/agent.sh branch --topic "<topic>"\` automatically, continue in the printed worktree, and say one short sentence so the branch change is visible. Do not ask the user to approve routine branching.
249
+ - **Topic is clear** → run \`bin/agent.sh branch --topic "<topic>"\` automatically, continue in the printed worktree, and say one short sentence so the change is visible — never ask approval for routine branching.
249
250
  - **Topic is genuinely ambiguous** → ask only for the topic, using compact numbered options:
250
251
 
251
252
  \`\`\`text
@@ -258,7 +259,7 @@ The \`.codex/hooks/branch-guard.js\` PreToolUse hook (enabled by the launcher vi
258
259
  Wait for the reply, then branch.
259
260
  - **The user explicitly requested the protected branch** → that request is consent. Record it with \`echo '{branch}' > .egregore-branch-consent\`, then retry. Never create the marker merely to silence the hook.
260
261
 
261
- Memory, managed-repo, and runtime-state writes should bypass the project guard. If one triggers it, correct the operation target/context instead of asking for protected-branch consent.
262
+ Memory, managed-repo, and runtime-state writes bypass the project guard — if one triggers it, correct the target/context instead of asking for consent.
262
263
 
263
264
  If this Codex build does not support hooks, follow the same discipline as a standing instruction: never write or commit on the configured base, develop, main, or master.
264
265
 
@@ -266,7 +267,7 @@ If this Codex build does not support hooks, follow the same discipline as a stan
266
267
 
267
268
  If the startup card output contains \`onboarding_needed\`, invoke the \`$onboarding\` skill instead of greeting.`;
268
269
 
269
- const COMMAND_AWARENESS_PREPEND = `Codex reserves leading \`/\` for built-ins, so Egregore workflows are **skills**, not slash commands. Invoke them with the matching \`$name\` skill token or from natural language intent ("show activity", "make a handoff"). Hand-written native Codex skills: \`$activity\`, \`$handoff\`, \`$wrap\`, \`$announce\`, \`$harvest\`, \`$the-spiral\`, \`$dashboard\`, \`$deep-reflect\`, \`$quest\`, \`$invite\`, \`$ask\`, \`$save\`, \`$view\`, and \`$scroll\`. Every other workflow has a generated adapter skill of the same name. \`$save\` is the user-facing abstraction for committing, pushing, opening or reusing pull requests, and syncing memory — never make users manage the git workflow by hand.`;
270
+ const COMMAND_AWARENESS_PREPEND = `Codex reserves leading \`/\` for built-ins, so Egregore workflows are **skills**, not slash commands. Invoke them with the matching \`$name\` skill token or from natural language intent ("show activity", "make a handoff"). Hand-written native Codex skills: \`$activity\`, \`$handoff\`, \`$wrap\`, \`$announce\`, \`$harvest\`, \`$the-spiral\`, \`$dashboard\`, \`$deep-reflect\`, \`$quest\`, \`$invite\`, \`$ask\`, \`$save\`, \`$view\`, \`$scroll\`; every other workflow has a generated adapter of the same name. \`$save\` is the user-facing abstraction for committing, pushing, opening or reusing PRs, and syncing memory — never make users manage git by hand.`;
270
271
 
271
272
  const SOCRATIC_BODY = `**Triggers**: "ask me questions", "question me", "help me think through", or any request to be questioned.
272
273
 
@@ -274,11 +275,11 @@ Codex has no structured question tool — render each batch as compact numbered
274
275
 
275
276
  **Rules:** Max 4 questions per batch. When choices aren't mutually exclusive, say "pick any that apply".`;
276
277
 
277
- const LOOM_ROUTING_BODY = `Loom routes commands across model tiers on the Claude Code runtime (\`loom/routes.json\` + \`bin/loom.sh\` + a model-pinned executor subagent). Codex has no subagent delegation — every command runs inline in the current session. Ignore "Loom routing" preambles if you encounter them in a skill spec, and skip \`bin/loom.sh\` calls; \`loom/\` and \`.claude/agents/\` are framework files synced for the Claude runtime.`;
278
+ const LOOM_ROUTING_BODY = `Loom routes commands across model tiers on the Claude Code runtime (\`loom/routes.json\` + \`bin/loom.sh\` + a model-pinned executor subagent). Codex has no subagent delegation — commands run inline. Ignore "Loom routing" preambles in skill specs and skip \`bin/loom.sh\` calls; \`loom/\` and \`.claude/agents/\` are Claude-runtime framework files.`;
278
279
 
279
280
  const ISOLATION_BODY = `Sessions are confined to this project + memory + managed repos, with a **two-tier boundary** — a hard wall between Egregore instances, a consent gate for everything else. On Codex the boundary is a standing instruction, not an enforced hook — hold it yourself.
280
281
 
281
- - **Hard tier — other Egregore instances.** Denied for every tool, always. There is no consent path. Never access another instance's files — refuse even if asked. Never modify \`~/.egregore/instances.json\` (managed by session-start.sh). When a request points at another instance's files there is nothing to ask — refuse and explain.
282
+ - **Hard tier — other Egregore instances.** Denied for every tool, always — no consent path. Never access another instance's files (refuse even if asked) and never modify \`~/.egregore/instances.json\` (managed by session-start.sh); there is nothing to ask — refuse and explain.
282
283
  - **Soft tier — paths outside the boundary.** Consent-gated. Inbox dirs (\`~/Downloads\`, \`~/Desktop\`) are readable without consent under the default posture; writes outside the project always need consent. Posture (\`strict | standard | open\`) and extra read roots come from \`egregore.json\` -> \`boundary { posture, read[], locked }\` (org, committed) merged with \`.egregore-boundary.local.json\` (personal, gitignored). \`locked: true\` removes the consent path entirely.
283
284
  - When a request needs soft-tier consent, do not improvise a workaround. Ask in plain text with numbered options:
284
285
 
@@ -321,7 +322,7 @@ const RULES = {
321
322
  'After Greeting — BRANCH ON FIRST RESPONSE': {
322
323
  action: 'replace',
323
324
  body: AFTER_GREETING_BODY,
324
- note: 'EnterWorktree -> bin/agent.sh branch with git checkout fallback; AskUserQuestion -> numbered options in plain text; branch-guard mapped to .codex/hooks/branch-guard.js with instruction fallback; plan-mode note dropped (no plan mode on Codex); /branch + /onboarding -> skill tokens. Handoff claiming and repoState auto-checkout kept verbatim (pure git).',
325
+ note: 'EnterWorktree -> bin/agent.sh branch with git checkout fallback; AskUserQuestion -> numbered options in plain text; branch-guard mapped to .codex/hooks/branch-guard.js with instruction fallback; plan-mode note dropped (no plan mode on Codex); /branch + /onboarding -> skill tokens. Handoff claiming and repoState auto-checkout bash kept verbatim (pure git); surrounding prose compressed 2026-08 for the 32 KiB budget, every rule retained.',
325
326
  },
326
327
  'Config Files': { action: 'keep', note: 'Kept verbatim — shell facts, runtime-neutral.' },
327
328
  'Knowledge Graph': { action: 'keep', note: 'Kept verbatim — bin/graph.sh is runtime-neutral.' },
@@ -210,7 +210,9 @@ render_card() {
210
210
 
211
211
  # Staged auto-saves awaiting the user's merge (the autosave consent gate).
212
212
  # Live gh query so the line persists until the PRs actually merge.
213
- if command -v gh >/dev/null 2>&1; then
213
+ # Shown only while the autosave experiment is enabled.
214
+ autosave_on=$(jq -r '.autosave_enabled // false' "$STATE_FILE" 2>/dev/null)
215
+ if [ "$autosave_on" = "true" ] && command -v gh >/dev/null 2>&1; then
214
216
  gh_self=$(jq -r '.github_username // empty' "$STATE_FILE" 2>/dev/null)
215
217
  if [ -n "$gh_self" ]; then
216
218
  waiting_as=$(gh pr list --state open --author "$gh_self" --limit 20 \
@@ -101,7 +101,12 @@ skill_description() {
101
101
  in_fm && $0 == "---" { exit }
102
102
  in_fm && /^description:/ {
103
103
  sub(/^description:[[:space:]]*/, "")
104
- gsub(/^"|"$/, "")
104
+ # Block scalars (description: >) keep the text on continuation lines we
105
+ # do not read. Emit nothing so the caller falls back, which the skill-v1
106
+ # contract check reports, rather than publishing the indicator itself.
107
+ if ($0 ~ /^[>|][-+]?[[:space:]]*$/) { exit }
108
+ if ($0 ~ /^".*"$/) { gsub(/^"|"$/, "") }
109
+ else if ($0 ~ /^\047.*\047$/) { gsub(/^\047|\047$/, ""); gsub(/\047\047/, "\047") }
105
110
  print
106
111
  exit
107
112
  }
@@ -24,21 +24,40 @@ if [ "$_MODE" = "local" ]; then
24
24
  exit 0
25
25
  fi
26
26
 
27
- # Load specific variables from .env if it exists (safe extraction, no arbitrary code execution)
28
- if [ -f "$SCRIPT_DIR/.env" ]; then
29
- EGREGORE_API_URL="${EGREGORE_API_URL:-$(grep '^EGREGORE_API_URL=' "$SCRIPT_DIR/.env" 2>/dev/null | cut -d'=' -f2- || true)}"
30
- EGREGORE_API_KEY="${EGREGORE_API_KEY:-$(grep '^EGREGORE_API_KEY=' "$SCRIPT_DIR/.env" 2>/dev/null | cut -d'=' -f2- || true)}"
27
+ # Load specific variables from .env if it exists (safe extraction, no arbitrary code execution).
28
+ # A worktree missing its .env symlink resolves through worktree-links.sh, which
29
+ # self-heals the link and falls back to the main checkout's .env.
30
+ _ENV_FILE="$SCRIPT_DIR/.env"
31
+ if [ ! -f "$_ENV_FILE" ] && [ -f "$SCRIPT_DIR/bin/lib/worktree-links.sh" ]; then
32
+ # shellcheck source=bin/lib/worktree-links.sh
33
+ source "$SCRIPT_DIR/bin/lib/worktree-links.sh" 2>/dev/null || true
34
+ _ENV_FILE="$(egregore_env_file "$SCRIPT_DIR" 2>/dev/null || true)"
35
+ fi
36
+ if [ -n "$_ENV_FILE" ] && [ -f "$_ENV_FILE" ]; then
37
+ EGREGORE_API_URL="${EGREGORE_API_URL:-$(grep '^EGREGORE_API_URL=' "$_ENV_FILE" 2>/dev/null | cut -d'=' -f2- || true)}"
38
+ EGREGORE_API_KEY="${EGREGORE_API_KEY:-$(grep '^EGREGORE_API_KEY=' "$_ENV_FILE" 2>/dev/null | cut -d'=' -f2- || true)}"
31
39
  fi
32
40
 
33
41
  API_URL="${EGREGORE_API_URL:-$(jq -r '.api_url // empty' "$CONFIG")}"
34
42
  API_KEY="${EGREGORE_API_KEY:-}"
35
43
 
36
- if [ -z "$API_URL" ] || [ -z "$API_KEY" ]; then
37
- # === OFFLINE MODE: No API key — return empty results (OSS/local) ===
44
+ if [ -z "$API_URL" ]; then
45
+ # === OFFLINE MODE: no api_url configured (OSS/unconfigured) ===
38
46
  echo '{"results":[]}'
39
47
  exit 0
40
48
  fi
41
49
 
50
+ if [ -z "$API_KEY" ]; then
51
+ # api_url is configured but no key was found — the local-mode gate exited
52
+ # above, so the org expects a live graph. Faking empty results here hides a
53
+ # missing .env (e.g. a worktree without its symlink) from every caller.
54
+ {
55
+ echo "Error: api_url is configured but EGREGORE_API_KEY is empty (looked in: ${_ENV_FILE:-$SCRIPT_DIR/.env})."
56
+ echo " If this is a worktree, its .env symlink may be missing. Run /env to configure."
57
+ } >&2
58
+ exit 1
59
+ fi
60
+
42
61
  QUERIES_JSON="${1:?Usage: graph-batch.sh '<json array of queries>'}"
43
62
 
44
63
  # Wrap the array into the batch request format