briefops 1.0.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 (255) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/CODE_OF_CONDUCT.md +13 -0
  3. package/CONTRIBUTING.md +53 -0
  4. package/LICENSE +21 -0
  5. package/README.md +801 -0
  6. package/SECURITY.md +59 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.js +54 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/commands/approve.d.ts +2 -0
  11. package/dist/commands/approve.js +38 -0
  12. package/dist/commands/approve.js.map +1 -0
  13. package/dist/commands/brief.d.ts +2 -0
  14. package/dist/commands/brief.js +81 -0
  15. package/dist/commands/brief.js.map +1 -0
  16. package/dist/commands/codex.d.ts +2 -0
  17. package/dist/commands/codex.js +163 -0
  18. package/dist/commands/codex.js.map +1 -0
  19. package/dist/commands/compare.d.ts +2 -0
  20. package/dist/commands/compare.js +48 -0
  21. package/dist/commands/compare.js.map +1 -0
  22. package/dist/commands/continue.d.ts +2 -0
  23. package/dist/commands/continue.js +66 -0
  24. package/dist/commands/continue.js.map +1 -0
  25. package/dist/commands/doctor.d.ts +2 -0
  26. package/dist/commands/doctor.js +90 -0
  27. package/dist/commands/doctor.js.map +1 -0
  28. package/dist/commands/eval.d.ts +2 -0
  29. package/dist/commands/eval.js +89 -0
  30. package/dist/commands/eval.js.map +1 -0
  31. package/dist/commands/export.d.ts +2 -0
  32. package/dist/commands/export.js +105 -0
  33. package/dist/commands/export.js.map +1 -0
  34. package/dist/commands/finish.d.ts +2 -0
  35. package/dist/commands/finish.js +71 -0
  36. package/dist/commands/finish.js.map +1 -0
  37. package/dist/commands/handoff.d.ts +2 -0
  38. package/dist/commands/handoff.js +77 -0
  39. package/dist/commands/handoff.js.map +1 -0
  40. package/dist/commands/inbox.d.ts +2 -0
  41. package/dist/commands/inbox.js +36 -0
  42. package/dist/commands/inbox.js.map +1 -0
  43. package/dist/commands/init.d.ts +2 -0
  44. package/dist/commands/init.js +13 -0
  45. package/dist/commands/init.js.map +1 -0
  46. package/dist/commands/inspect.d.ts +2 -0
  47. package/dist/commands/inspect.js +226 -0
  48. package/dist/commands/inspect.js.map +1 -0
  49. package/dist/commands/log.d.ts +2 -0
  50. package/dist/commands/log.js +96 -0
  51. package/dist/commands/log.js.map +1 -0
  52. package/dist/commands/memory.d.ts +2 -0
  53. package/dist/commands/memory.js +236 -0
  54. package/dist/commands/memory.js.map +1 -0
  55. package/dist/commands/pack.d.ts +2 -0
  56. package/dist/commands/pack.js +42 -0
  57. package/dist/commands/pack.js.map +1 -0
  58. package/dist/commands/prime.d.ts +4 -0
  59. package/dist/commands/prime.js +44 -0
  60. package/dist/commands/prime.js.map +1 -0
  61. package/dist/commands/project.d.ts +2 -0
  62. package/dist/commands/project.js +50 -0
  63. package/dist/commands/project.js.map +1 -0
  64. package/dist/commands/shared.d.ts +3 -0
  65. package/dist/commands/shared.js +24 -0
  66. package/dist/commands/shared.js.map +1 -0
  67. package/dist/commands/skill.d.ts +2 -0
  68. package/dist/commands/skill.js +146 -0
  69. package/dist/commands/skill.js.map +1 -0
  70. package/dist/commands/worker.d.ts +2 -0
  71. package/dist/commands/worker.js +128 -0
  72. package/dist/commands/worker.js.map +1 -0
  73. package/dist/core/adapter.d.ts +22 -0
  74. package/dist/core/adapter.js +167 -0
  75. package/dist/core/adapter.js.map +1 -0
  76. package/dist/core/approval.d.ts +26 -0
  77. package/dist/core/approval.js +86 -0
  78. package/dist/core/approval.js.map +1 -0
  79. package/dist/core/brief.d.ts +47 -0
  80. package/dist/core/brief.js +411 -0
  81. package/dist/core/brief.js.map +1 -0
  82. package/dist/core/codex.d.ts +53 -0
  83. package/dist/core/codex.js +286 -0
  84. package/dist/core/codex.js.map +1 -0
  85. package/dist/core/codexPlugin.d.ts +51 -0
  86. package/dist/core/codexPlugin.js +228 -0
  87. package/dist/core/codexPlugin.js.map +1 -0
  88. package/dist/core/compatibility.d.ts +2 -0
  89. package/dist/core/compatibility.js +16 -0
  90. package/dist/core/compatibility.js.map +1 -0
  91. package/dist/core/config.d.ts +19 -0
  92. package/dist/core/config.js +77 -0
  93. package/dist/core/config.js.map +1 -0
  94. package/dist/core/contextBudget.d.ts +12 -0
  95. package/dist/core/contextBudget.js +22 -0
  96. package/dist/core/contextBudget.js.map +1 -0
  97. package/dist/core/contextCompare.d.ts +27 -0
  98. package/dist/core/contextCompare.js +97 -0
  99. package/dist/core/contextCompare.js.map +1 -0
  100. package/dist/core/continuity.d.ts +25 -0
  101. package/dist/core/continuity.js +73 -0
  102. package/dist/core/continuity.js.map +1 -0
  103. package/dist/core/errors.d.ts +4 -0
  104. package/dist/core/errors.js +12 -0
  105. package/dist/core/errors.js.map +1 -0
  106. package/dist/core/eval.d.ts +38 -0
  107. package/dist/core/eval.js +180 -0
  108. package/dist/core/eval.js.map +1 -0
  109. package/dist/core/exportPolicy.d.ts +7 -0
  110. package/dist/core/exportPolicy.js +17 -0
  111. package/dist/core/exportPolicy.js.map +1 -0
  112. package/dist/core/exportTargets.d.ts +25 -0
  113. package/dist/core/exportTargets.js +292 -0
  114. package/dist/core/exportTargets.js.map +1 -0
  115. package/dist/core/handoff.d.ts +48 -0
  116. package/dist/core/handoff.js +611 -0
  117. package/dist/core/handoff.js.map +1 -0
  118. package/dist/core/inbox.d.ts +15 -0
  119. package/dist/core/inbox.js +56 -0
  120. package/dist/core/inbox.js.map +1 -0
  121. package/dist/core/lock.d.ts +11 -0
  122. package/dist/core/lock.js +99 -0
  123. package/dist/core/lock.js.map +1 -0
  124. package/dist/core/log.d.ts +38 -0
  125. package/dist/core/log.js +93 -0
  126. package/dist/core/log.js.map +1 -0
  127. package/dist/core/memory.d.ts +86 -0
  128. package/dist/core/memory.js +353 -0
  129. package/dist/core/memory.js.map +1 -0
  130. package/dist/core/memoryHygiene.d.ts +25 -0
  131. package/dist/core/memoryHygiene.js +95 -0
  132. package/dist/core/memoryHygiene.js.map +1 -0
  133. package/dist/core/memoryProposal.d.ts +40 -0
  134. package/dist/core/memoryProposal.js +279 -0
  135. package/dist/core/memoryProposal.js.map +1 -0
  136. package/dist/core/output.d.ts +7 -0
  137. package/dist/core/output.js +18 -0
  138. package/dist/core/output.js.map +1 -0
  139. package/dist/core/patch.d.ts +37 -0
  140. package/dist/core/patch.js +220 -0
  141. package/dist/core/patch.js.map +1 -0
  142. package/dist/core/paths.d.ts +33 -0
  143. package/dist/core/paths.js +84 -0
  144. package/dist/core/paths.js.map +1 -0
  145. package/dist/core/prime.d.ts +17 -0
  146. package/dist/core/prime.js +298 -0
  147. package/dist/core/prime.js.map +1 -0
  148. package/dist/core/privacyDoctor.d.ts +14 -0
  149. package/dist/core/privacyDoctor.js +59 -0
  150. package/dist/core/privacyDoctor.js.map +1 -0
  151. package/dist/core/project.d.ts +16 -0
  152. package/dist/core/project.js +73 -0
  153. package/dist/core/project.js.map +1 -0
  154. package/dist/core/securityDoctor.d.ts +14 -0
  155. package/dist/core/securityDoctor.js +96 -0
  156. package/dist/core/securityDoctor.js.map +1 -0
  157. package/dist/core/skill.d.ts +16 -0
  158. package/dist/core/skill.js +81 -0
  159. package/dist/core/skill.js.map +1 -0
  160. package/dist/core/storage.d.ts +20 -0
  161. package/dist/core/storage.js +112 -0
  162. package/dist/core/storage.js.map +1 -0
  163. package/dist/core/tokens.d.ts +5 -0
  164. package/dist/core/tokens.js +24 -0
  165. package/dist/core/tokens.js.map +1 -0
  166. package/dist/core/worker.d.ts +51 -0
  167. package/dist/core/worker.js +312 -0
  168. package/dist/core/worker.js.map +1 -0
  169. package/dist/core/workflow.d.ts +61 -0
  170. package/dist/core/workflow.js +308 -0
  171. package/dist/core/workflow.js.map +1 -0
  172. package/dist/core/workspace.d.ts +7 -0
  173. package/dist/core/workspace.js +214 -0
  174. package/dist/core/workspace.js.map +1 -0
  175. package/dist/index.d.ts +2 -0
  176. package/dist/index.js +16 -0
  177. package/dist/index.js.map +1 -0
  178. package/dist/schemas/brief.d.ts +12 -0
  179. package/dist/schemas/brief.js +2 -0
  180. package/dist/schemas/brief.js.map +1 -0
  181. package/dist/schemas/eval.d.ts +96 -0
  182. package/dist/schemas/eval.js +30 -0
  183. package/dist/schemas/eval.js.map +1 -0
  184. package/dist/schemas/handoff.d.ts +33 -0
  185. package/dist/schemas/handoff.js +13 -0
  186. package/dist/schemas/handoff.js.map +1 -0
  187. package/dist/schemas/log.d.ts +51 -0
  188. package/dist/schemas/log.js +19 -0
  189. package/dist/schemas/log.js.map +1 -0
  190. package/dist/schemas/memory.d.ts +112 -0
  191. package/dist/schemas/memory.js +21 -0
  192. package/dist/schemas/memory.js.map +1 -0
  193. package/dist/schemas/memoryProposal.d.ts +181 -0
  194. package/dist/schemas/memoryProposal.js +46 -0
  195. package/dist/schemas/memoryProposal.js.map +1 -0
  196. package/dist/schemas/patch.d.ts +38 -0
  197. package/dist/schemas/patch.js +15 -0
  198. package/dist/schemas/patch.js.map +1 -0
  199. package/dist/schemas/project.d.ts +23 -0
  200. package/dist/schemas/project.js +8 -0
  201. package/dist/schemas/project.js.map +1 -0
  202. package/dist/schemas/skill.d.ts +26 -0
  203. package/dist/schemas/skill.js +9 -0
  204. package/dist/schemas/skill.js.map +1 -0
  205. package/dist/schemas/worker.d.ts +29 -0
  206. package/dist/schemas/worker.js +12 -0
  207. package/dist/schemas/worker.js.map +1 -0
  208. package/dist/version.d.ts +1 -0
  209. package/dist/version.js +3 -0
  210. package/dist/version.js.map +1 -0
  211. package/docs/codex-resume.md +13 -0
  212. package/docs/compatibility.md +49 -0
  213. package/docs/concept.md +13 -0
  214. package/docs/evals.md +18 -0
  215. package/docs/file-format.md +67 -0
  216. package/docs/handoff-briefs.md +9 -0
  217. package/docs/integrations/harnesses.md +74 -0
  218. package/docs/memory-lifecycle.md +23 -0
  219. package/docs/persistent-worker.md +15 -0
  220. package/docs/privacy-model.md +40 -0
  221. package/docs/quickstart.md +74 -0
  222. package/docs/release-checklist.md +68 -0
  223. package/docs/roadmap.md +33 -0
  224. package/docs/superpowers/plans/2026-06-08-briefops-oss-readiness.md +1272 -0
  225. package/docs/superpowers/plans/2026-06-08-codex-first-context-optimization.md +1176 -0
  226. package/docs/token-budget.md +63 -0
  227. package/examples/atlas-q/README.md +15 -0
  228. package/examples/codex-first-context/README.md +48 -0
  229. package/examples/codex-first-context/after-briefops-prime.md +40 -0
  230. package/examples/codex-first-context/before-manual-history-dump.md +18 -0
  231. package/examples/persistent-worker-demo/README.md +15 -0
  232. package/examples/persistent-worker-demo/after-codex-resume.md +17 -0
  233. package/examples/persistent-worker-demo/before-context-dump.md +5 -0
  234. package/examples/persistent-worker-demo/briefops-workspace/codex/prompts/resume_demo.md +29 -0
  235. package/examples/persistent-worker-demo/briefops-workspace/handoffs/handoff_demo.md +50 -0
  236. package/examples/persistent-worker-demo/briefops-workspace/logs/log_20260604_001.yaml +14 -0
  237. package/examples/persistent-worker-demo/briefops-workspace/logs/log_20260604_002.yaml +12 -0
  238. package/examples/persistent-worker-demo/briefops-workspace/memory/decisions.yaml +12 -0
  239. package/examples/persistent-worker-demo/briefops-workspace/memory/deprecated.yaml +1 -0
  240. package/examples/persistent-worker-demo/briefops-workspace/memory/facts.yaml +12 -0
  241. package/examples/persistent-worker-demo/briefops-workspace/memory/incidents.yaml +12 -0
  242. package/examples/persistent-worker-demo/briefops-workspace/memory/lessons.yaml +12 -0
  243. package/examples/persistent-worker-demo/briefops-workspace/memory-proposals/memprop_demo_001.memory-proposal.yaml +23 -0
  244. package/examples/persistent-worker-demo/briefops-workspace/projects/atlas-q.project.md +18 -0
  245. package/examples/persistent-worker-demo/briefops-workspace/skills/backtest-validation.skill.md +13 -0
  246. package/examples/persistent-worker-demo/briefops-workspace/skills/risk-review.skill.md +15 -0
  247. package/examples/persistent-worker-demo/briefops-workspace/workers/quant-reviewer.worker.yaml +12 -0
  248. package/examples/persistent-worker-demo/briefops-workspace/workers/summaries/quant-reviewer.summary.md +44 -0
  249. package/package.json +59 -0
  250. package/plugins/briefops-codex/.codex-plugin/plugin.json +39 -0
  251. package/plugins/briefops-codex/README.md +44 -0
  252. package/plugins/briefops-codex/skills/briefops-continue-worker/SKILL.md +22 -0
  253. package/plugins/briefops-codex/skills/briefops-finish-task/SKILL.md +22 -0
  254. package/plugins/briefops-codex/skills/briefops-prime-context/SKILL.md +24 -0
  255. package/plugins/briefops-codex/skills/briefops-review-memory/SKILL.md +27 -0
@@ -0,0 +1,1272 @@
1
+ # BriefOps OSS Readiness Implementation Plan
2
+
3
+ > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
+
5
+ **Goal:** Move BriefOps from internal dogfood alpha to a public open-source release candidate with safe defaults, clear trust boundaries, release hygiene, and harness-friendly adoption guidance.
6
+
7
+ **Architecture:** Keep BriefOps as a local-first file-backed CLI, not an agent harness. Strengthen the product edge: deterministic context priming, human-approved memory, safe shared exports, auditable local work history, and compatibility with stronger harnesses such as LazyCodex/OmO without adopting their global-hook runtime model.
8
+
9
+ **Tech Stack:** TypeScript, Node.js >=20, Commander, YAML, Zod, Vitest, GitHub Actions, npm package distribution.
10
+
11
+ ---
12
+
13
+ ## File Structure
14
+
15
+ Create:
16
+ - `SECURITY.md` - vulnerability reporting, supported versions, local data handling policy.
17
+ - `CONTRIBUTING.md` - development setup, test matrix, branch/commit expectations.
18
+ - `CODE_OF_CONDUCT.md` - concise community conduct policy.
19
+ - `CHANGELOG.md` - release notes beginning with `0.2.0-alpha.0` and next release section.
20
+ - `docs/integrations/harnesses.md` - how to use BriefOps with LazyCodex, OmO, Codex, Claude Code, Cursor, and other harnesses.
21
+ - `docs/release-checklist.md` - human release gate checklist.
22
+ - `src/core/output.ts` - safe explicit-output write helper.
23
+ - `src/core/privacyDoctor.ts` - privacy-oriented local workspace checks.
24
+ - `tests/output-safety.test.ts` - no-overwrite behavior for explicit output paths.
25
+ - `tests/privacy-doctor.test.ts` - privacy doctor behavior.
26
+ - `.github/dependabot.yml` - dependency update signal.
27
+
28
+ Modify:
29
+ - `package.json` - add repository, bugs, homepage, keywords, and release verification script.
30
+ - `README.md` - add OSS readiness, trust boundary, harness integration, and release status sections.
31
+ - `.github/workflows/ci.yml` - add audit/release-check steps.
32
+ - `src/commands/brief.ts` - add `--force` for explicit output overwrite.
33
+ - `src/commands/codex.ts` - add `--force` to prompt output commands and tighten plugin install messaging.
34
+ - `src/commands/continue.ts` - add `--force` for explicit output overwrite.
35
+ - `src/commands/doctor.ts` - add `--privacy` and optional `--fix-gitignore`.
36
+ - `src/commands/handoff.ts` - add `--force`.
37
+ - `src/commands/pack.ts` - add `--force`.
38
+ - `src/core/brief.ts` - use output helper for explicit output paths.
39
+ - `src/core/codex.ts` - use output helper for explicit output paths.
40
+ - `src/core/codexPlugin.ts` - plugin install should be idempotent but not silently overwrite changed generated files unless `--force`.
41
+ - `src/core/handoff.ts` - use output helper for explicit output paths and add missing lock around `saveCodexResumeFromHandoff`.
42
+ - `src/core/workflow.ts` - use output helper for explicit pack paths.
43
+ - `tests/cli-workflow.test.ts` - CLI coverage for `--force`, `doctor --privacy`, and plugin changed-file behavior.
44
+ - `tests/codex-plugin.test.ts` - plugin idempotency and changed-file safety.
45
+
46
+ ---
47
+
48
+ ## Task 1: OSS Trust Documents And Package Metadata
49
+
50
+ **Files:**
51
+ - Create: `SECURITY.md`
52
+ - Create: `CONTRIBUTING.md`
53
+ - Create: `CODE_OF_CONDUCT.md`
54
+ - Create: `CHANGELOG.md`
55
+ - Modify: `package.json`
56
+ - Modify: `README.md`
57
+
58
+ - [x] **Step 1: Add `SECURITY.md`**
59
+
60
+ Create `SECURITY.md`:
61
+
62
+ ```markdown
63
+ # Security Policy
64
+
65
+ BriefOps is a local-first CLI. It stores project memory, work logs, generated prompts, and plugin assets under `.briefops/` in the current repository.
66
+
67
+ ## Supported Versions
68
+
69
+ | Version | Supported |
70
+ | --- | --- |
71
+ | 0.2.x alpha | Security fixes accepted |
72
+
73
+ ## Reporting A Vulnerability
74
+
75
+ Please report suspected vulnerabilities through GitHub Security Advisories when available. If advisories are not enabled, open a GitHub issue with a minimal description and avoid posting secrets, private logs, or exploit payloads.
76
+
77
+ Include:
78
+
79
+ - BriefOps version
80
+ - Operating system
81
+ - Command used
82
+ - Whether `.briefops/` contains private project data
83
+ - Expected behavior
84
+ - Observed behavior
85
+
86
+ ## Local Data Policy
87
+
88
+ BriefOps does not require a hosted service, MCP server, vector database, or network access.
89
+
90
+ Do not commit `.briefops/` unless you intentionally curated the contents for sharing. Use:
91
+
92
+ ```bash
93
+ briefops doctor --privacy
94
+ briefops prime --export-policy shared-only
95
+ briefops pack resume --export-policy shared-only
96
+ ```
97
+
98
+ before sharing generated context outside your local machine.
99
+ ```
100
+
101
+ - [x] **Step 2: Add `CONTRIBUTING.md`**
102
+
103
+ Create `CONTRIBUTING.md`:
104
+
105
+ ```markdown
106
+ # Contributing
107
+
108
+ Thanks for improving BriefOps.
109
+
110
+ BriefOps is intentionally small:
111
+
112
+ - local-first
113
+ - file-backed
114
+ - deterministic
115
+ - human-approved
116
+ - token-aware
117
+ - no hosted service required
118
+ - no MCP server required
119
+
120
+ ## Development Setup
121
+
122
+ ```bash
123
+ npm install
124
+ npm run build
125
+ npm test
126
+ ```
127
+
128
+ Run the CLI during development:
129
+
130
+ ```bash
131
+ npm run dev -- --help
132
+ ```
133
+
134
+ ## Required Checks
135
+
136
+ Before opening a pull request:
137
+
138
+ ```bash
139
+ npm run build
140
+ npm test
141
+ npm pack --dry-run
142
+ ```
143
+
144
+ ## Safety Rules
145
+
146
+ - Never auto-approve memory proposals or skill patches.
147
+ - Do not introduce hosted services, cloud sync, vector databases, or MCP as required runtime dependencies.
148
+ - Keep private local memory out of shared exports unless it is explicitly marked `visibility: shared` and `exportable: true`.
149
+ - Prefer small deterministic file-backed changes over agent runtime behavior.
150
+
151
+ ## Pull Request Style
152
+
153
+ Include:
154
+
155
+ - What changed
156
+ - Why it matters for local-first continuity
157
+ - Tests run
158
+ - Any privacy or export-policy impact
159
+ ```
160
+
161
+ - [x] **Step 3: Add `CODE_OF_CONDUCT.md`**
162
+
163
+ Create `CODE_OF_CONDUCT.md`:
164
+
165
+ ```markdown
166
+ # Code Of Conduct
167
+
168
+ BriefOps aims to be a practical, respectful open-source project.
169
+
170
+ We expect contributors to:
171
+
172
+ - be kind and direct
173
+ - critique code and ideas, not people
174
+ - respect privacy and local data boundaries
175
+ - avoid posting secrets, private logs, or sensitive project memory
176
+ - keep discussions focused on making BriefOps safer and more useful
177
+
178
+ Maintainers may remove comments, issues, or contributions that are abusive, harassing, spammy, or unsafe.
179
+ ```
180
+
181
+ - [x] **Step 4: Add `CHANGELOG.md`**
182
+
183
+ Create `CHANGELOG.md`:
184
+
185
+ ```markdown
186
+ # Changelog
187
+
188
+ ## Unreleased
189
+
190
+ - Add OSS readiness hardening.
191
+
192
+ ## 0.2.0-alpha.0
193
+
194
+ - Add Codex first-context workflow.
195
+ - Add local Codex plugin bundle generation.
196
+ - Add `briefops prime` and `briefops codex prime`.
197
+ - Add default worker selection with `briefops worker use`.
198
+ - Add persistent worker finish/continue flow.
199
+ - Add human-approved memory proposal flow.
200
+ - Add shared-only export policy.
201
+ - Add `doctor --security` and stale lock cleanup.
202
+ ```
203
+
204
+ - [x] **Step 5: Update `package.json` metadata**
205
+
206
+ Modify `package.json`:
207
+
208
+ ```json
209
+ {
210
+ "repository": {
211
+ "type": "git",
212
+ "url": "git+https://github.com/simony-816/briefops.git"
213
+ },
214
+ "bugs": {
215
+ "url": "https://github.com/simony-816/briefops/issues"
216
+ },
217
+ "homepage": "https://github.com/simony-816/briefops#readme",
218
+ "keywords": [
219
+ "codex",
220
+ "ai-agents",
221
+ "local-first",
222
+ "memory",
223
+ "context",
224
+ "handoff",
225
+ "developer-tools"
226
+ ],
227
+ "scripts": {
228
+ "build": "tsc -p tsconfig.json",
229
+ "test": "vitest run",
230
+ "dev": "tsx src/index.ts",
231
+ "verify:release": "npm run build && npm test && npm pack --dry-run"
232
+ }
233
+ }
234
+ ```
235
+
236
+ Preserve existing fields and ordering where practical.
237
+
238
+ - [x] **Step 6: Run package metadata check**
239
+
240
+ Run:
241
+
242
+ ```bash
243
+ npm run build
244
+ npm test
245
+ npm pack --dry-run
246
+ ```
247
+
248
+ Expected: all pass and tarball includes `README.md`, `LICENSE`, `SECURITY.md`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `CHANGELOG.md`, `docs`, `plugins`, `examples`, and `dist`.
249
+
250
+ - [x] **Step 7: Commit**
251
+
252
+ ```bash
253
+ git add SECURITY.md CONTRIBUTING.md CODE_OF_CONDUCT.md CHANGELOG.md package.json README.md
254
+ git commit -m "docs: add open-source trust documents"
255
+ ```
256
+
257
+ ---
258
+
259
+ ## Task 2: Safe Explicit Output Writes
260
+
261
+ **Files:**
262
+ - Create: `src/core/output.ts`
263
+ - Create: `tests/output-safety.test.ts`
264
+ - Modify: `src/commands/brief.ts`
265
+ - Modify: `src/commands/codex.ts`
266
+ - Modify: `src/commands/continue.ts`
267
+ - Modify: `src/commands/handoff.ts`
268
+ - Modify: `src/commands/pack.ts`
269
+ - Modify: `src/core/brief.ts`
270
+ - Modify: `src/core/codex.ts`
271
+ - Modify: `src/core/handoff.ts`
272
+ - Modify: `src/core/workflow.ts`
273
+ - Modify: `tests/cli-workflow.test.ts`
274
+
275
+ - [x] **Step 1: Write failing tests for explicit output no-overwrite**
276
+
277
+ Create `tests/output-safety.test.ts`:
278
+
279
+ ```ts
280
+ import path from "node:path";
281
+ import { describe, expect, it } from "vitest";
282
+ import { generateCodexResume } from "../src/core/codex.js";
283
+ import { generateHandoff } from "../src/core/handoff.js";
284
+ import { createProject } from "../src/core/project.js";
285
+ import { createSkill } from "../src/core/skill.js";
286
+ import { readTextFile, writeTextFile } from "../src/core/storage.js";
287
+ import { createWorker } from "../src/core/worker.js";
288
+ import { packResume } from "../src/core/workflow.js";
289
+ import { initWorkspace } from "../src/core/workspace.js";
290
+ import { withTempDir } from "./helpers.js";
291
+
292
+ async function seed(dir: string): Promise<void> {
293
+ await initWorkspace(dir);
294
+ await createSkill({ cwd: dir, name: "risk-review" });
295
+ await createProject({ cwd: dir, name: "atlas-q" });
296
+ await createWorker({
297
+ cwd: dir,
298
+ name: "quant-reviewer",
299
+ project: "atlas-q",
300
+ skills: ["risk-review"]
301
+ });
302
+ }
303
+
304
+ describe("explicit output safety", () => {
305
+ it("does not overwrite explicit Codex resume output without force", async () => {
306
+ await withTempDir(async (dir) => {
307
+ await seed(dir);
308
+ const outputPath = path.join(dir, "resume.md");
309
+ await writeTextFile(outputPath, "keep me\n");
310
+
311
+ await expect(generateCodexResume({
312
+ cwd: dir,
313
+ worker: "quant-reviewer",
314
+ task: "Continue review.",
315
+ save: true,
316
+ outputPath
317
+ })).rejects.toThrow("Output file already exists");
318
+
319
+ expect(await readTextFile(outputPath)).toBe("keep me\n");
320
+ });
321
+ });
322
+
323
+ it("overwrites explicit Codex resume output when force is true", async () => {
324
+ await withTempDir(async (dir) => {
325
+ await seed(dir);
326
+ const outputPath = path.join(dir, "resume.md");
327
+ await writeTextFile(outputPath, "replace me\n");
328
+
329
+ await generateCodexResume({
330
+ cwd: dir,
331
+ worker: "quant-reviewer",
332
+ task: "Continue review.",
333
+ save: true,
334
+ outputPath,
335
+ force: true
336
+ });
337
+
338
+ expect(await readTextFile(outputPath)).toContain("BriefOps Codex Resume");
339
+ });
340
+ });
341
+
342
+ it("does not overwrite explicit handoff output without force", async () => {
343
+ await withTempDir(async (dir) => {
344
+ await seed(dir);
345
+ const outputPath = path.join(dir, "handoff.md");
346
+ await writeTextFile(outputPath, "keep me\n");
347
+
348
+ await expect(generateHandoff({
349
+ cwd: dir,
350
+ worker: "quant-reviewer",
351
+ task: "Continue review.",
352
+ save: true,
353
+ outputPath
354
+ })).rejects.toThrow("Output file already exists");
355
+
356
+ expect(await readTextFile(outputPath)).toBe("keep me\n");
357
+ });
358
+ });
359
+
360
+ it("does not overwrite explicit pack output without force", async () => {
361
+ await withTempDir(async (dir) => {
362
+ await seed(dir);
363
+ const outputPath = path.join(dir, "pack.md");
364
+ await writeTextFile(outputPath, "keep me\n");
365
+
366
+ await expect(packResume({
367
+ cwd: dir,
368
+ worker: "quant-reviewer",
369
+ task: "Continue review.",
370
+ outputPath
371
+ })).rejects.toThrow("Output file already exists");
372
+
373
+ expect(await readTextFile(outputPath)).toBe("keep me\n");
374
+ });
375
+ });
376
+ });
377
+ ```
378
+
379
+ - [x] **Step 2: Run failing output safety tests**
380
+
381
+ Run:
382
+
383
+ ```bash
384
+ npm test -- tests/output-safety.test.ts
385
+ ```
386
+
387
+ Expected: FAIL because `force` is not yet supported and explicit outputs currently overwrite.
388
+
389
+ - [x] **Step 3: Add output helper**
390
+
391
+ Create `src/core/output.ts`:
392
+
393
+ ```ts
394
+ import path from "node:path";
395
+ import { BriefOpsError } from "./errors.js";
396
+ import { pathExists, writeTextFile } from "./storage.js";
397
+
398
+ export async function writeGeneratedOutput(options: {
399
+ defaultPath: string;
400
+ outputPath?: string;
401
+ content: string;
402
+ force?: boolean;
403
+ }): Promise<string> {
404
+ const targetPath = options.outputPath ?? options.defaultPath;
405
+ const isExplicit = Boolean(options.outputPath);
406
+
407
+ if (isExplicit && !options.force && await pathExists(targetPath)) {
408
+ throw new BriefOpsError(
409
+ `Output file already exists: ${targetPath}. Re-run with --force to overwrite.`
410
+ );
411
+ }
412
+
413
+ await writeTextFile(targetPath, options.content, {
414
+ force: !isExplicit || Boolean(options.force)
415
+ });
416
+ return targetPath;
417
+ }
418
+
419
+ export function resolveCliOutputPath(cwd: string, value?: string): string | undefined {
420
+ return value ? path.resolve(cwd, value) : undefined;
421
+ }
422
+ ```
423
+
424
+ - [x] **Step 4: Thread `force?: boolean` through core option types**
425
+
426
+ Add `force?: boolean` to:
427
+
428
+ ```ts
429
+ // src/core/brief.ts
430
+ export type SaveGeneratedBriefOptions = {
431
+ cwd: string;
432
+ generated: GeneratedBrief;
433
+ outputPath?: string;
434
+ force?: boolean;
435
+ };
436
+
437
+ // src/core/codex.ts
438
+ export type CodexMissionOptions = { /* existing fields */ force?: boolean };
439
+ export type CodexPlanOptions = { /* existing fields */ force?: boolean };
440
+ export type CodexResumeOptions = { /* existing fields */ force?: boolean };
441
+
442
+ // src/core/handoff.ts
443
+ export type GenerateHandoffOptions = { /* existing fields */ force?: boolean };
444
+
445
+ // src/core/workflow.ts
446
+ export type ContinueWorkOptions = { /* existing fields */ force?: boolean };
447
+ export type PackResumeOptions = { /* existing fields */ force?: boolean };
448
+ ```
449
+
450
+ - [x] **Step 5: Use output helper in save functions**
451
+
452
+ In `src/core/codex.ts`, replace `writeTextFile(targetPath, ..., { force: true })` inside `saveCodexPrompt()` with:
453
+
454
+ ```ts
455
+ return writeGeneratedOutput({
456
+ defaultPath: path.join(
457
+ workspacePaths(options.cwd).codexPrompts,
458
+ `${formatDateStamp()}-${options.kind}-${slugForFilename(options.name)}.md`
459
+ ),
460
+ outputPath: options.outputPath,
461
+ content: options.content,
462
+ force: options.force
463
+ });
464
+ ```
465
+
466
+ In `src/core/handoff.ts`, use the same pattern for `saveGeneratedHandoff()` and `saveCodexResumeFromHandoff()`.
467
+
468
+ In `src/core/workflow.ts`, use the same pattern for `packResume()`.
469
+
470
+ - [x] **Step 6: Add CLI `--force` flags**
471
+
472
+ For each command with `--output`, add:
473
+
474
+ ```ts
475
+ .option("--force", "Overwrite an existing explicit output file.")
476
+ ```
477
+
478
+ Pass:
479
+
480
+ ```ts
481
+ force: Boolean(options.force)
482
+ ```
483
+
484
+ to the corresponding core call.
485
+
486
+ - [x] **Step 7: Run output tests**
487
+
488
+ Run:
489
+
490
+ ```bash
491
+ npm test -- tests/output-safety.test.ts
492
+ ```
493
+
494
+ Expected: PASS.
495
+
496
+ - [x] **Step 8: Run regression tests**
497
+
498
+ Run:
499
+
500
+ ```bash
501
+ npm test -- tests/cli-workflow.test.ts tests/persistent-worker.test.ts
502
+ ```
503
+
504
+ Expected: PASS.
505
+
506
+ - [x] **Step 9: Commit**
507
+
508
+ ```bash
509
+ git add src/core/output.ts src/core src/commands tests/output-safety.test.ts tests/cli-workflow.test.ts
510
+ git commit -m "fix: protect explicit output files"
511
+ ```
512
+
513
+ ---
514
+
515
+ ## Task 3: Privacy Doctor And Gitignore Guard
516
+
517
+ **Files:**
518
+ - Create: `src/core/privacyDoctor.ts`
519
+ - Create: `tests/privacy-doctor.test.ts`
520
+ - Modify: `src/commands/doctor.ts`
521
+ - Modify: `README.md`
522
+ - Modify: `docs/quickstart.md`
523
+
524
+ - [x] **Step 1: Write failing privacy doctor tests**
525
+
526
+ Create `tests/privacy-doctor.test.ts`:
527
+
528
+ ```ts
529
+ import { describe, expect, it } from "vitest";
530
+ import { addMemory } from "../src/core/memory.js";
531
+ import { runPrivacyDoctor } from "../src/core/privacyDoctor.js";
532
+ import { createProject } from "../src/core/project.js";
533
+ import { createSkill } from "../src/core/skill.js";
534
+ import { writeTextFile } from "../src/core/storage.js";
535
+ import { initWorkspace } from "../src/core/workspace.js";
536
+ import { withTempDir } from "./helpers.js";
537
+
538
+ async function seed(dir: string): Promise<void> {
539
+ await initWorkspace(dir);
540
+ await createSkill({ cwd: dir, name: "risk-review" });
541
+ await createProject({ cwd: dir, name: "atlas-q" });
542
+ }
543
+
544
+ describe("privacy doctor", () => {
545
+ it("warns when .briefops is not ignored", async () => {
546
+ await withTempDir(async (dir) => {
547
+ await seed(dir);
548
+
549
+ const result = await runPrivacyDoctor({ cwd: dir });
550
+
551
+ expect(result.ok).toBe(true);
552
+ expect(result.checks.find((check) => check.name === "Gitignore")?.status).toBe("warn");
553
+ });
554
+ });
555
+
556
+ it("passes gitignore check when .briefops is ignored", async () => {
557
+ await withTempDir(async (dir) => {
558
+ await seed(dir);
559
+ await writeTextFile(`${dir}/.gitignore`, ".briefops/\n");
560
+
561
+ const result = await runPrivacyDoctor({ cwd: dir });
562
+
563
+ expect(result.checks.find((check) => check.name === "Gitignore")?.status).toBe("ok");
564
+ });
565
+ });
566
+
567
+ it("warns on private memory marked exportable", async () => {
568
+ await withTempDir(async (dir) => {
569
+ await seed(dir);
570
+ await writeTextFile(`${dir}/.gitignore`, ".briefops/\n");
571
+ await addMemory({
572
+ cwd: dir,
573
+ type: "lessons",
574
+ project: "atlas-q",
575
+ skill: "risk-review",
576
+ content: "Private lesson should not be exportable.",
577
+ visibility: "private",
578
+ exportable: true
579
+ });
580
+
581
+ const result = await runPrivacyDoctor({ cwd: dir });
582
+
583
+ expect(result.checks.find((check) => check.name === "Private exportable memory")?.status)
584
+ .toBe("warn");
585
+ });
586
+ });
587
+
588
+ it("warns on secret-like strings in local memory", async () => {
589
+ await withTempDir(async (dir) => {
590
+ await seed(dir);
591
+ await writeTextFile(`${dir}/.gitignore`, ".briefops/\n");
592
+ await addMemory({
593
+ cwd: dir,
594
+ type: "facts",
595
+ project: "atlas-q",
596
+ skill: "risk-review",
597
+ content: "Use API key sk-test-12345678901234567890 for local sandbox.",
598
+ visibility: "private",
599
+ exportable: false
600
+ });
601
+
602
+ const result = await runPrivacyDoctor({ cwd: dir });
603
+
604
+ expect(result.checks.find((check) => check.name === "Secret-like local memory")?.status)
605
+ .toBe("warn");
606
+ });
607
+ });
608
+ });
609
+ ```
610
+
611
+ - [x] **Step 2: Run failing tests**
612
+
613
+ Run:
614
+
615
+ ```bash
616
+ npm test -- tests/privacy-doctor.test.ts
617
+ ```
618
+
619
+ Expected: FAIL because `runPrivacyDoctor` does not exist.
620
+
621
+ - [x] **Step 3: Implement privacy doctor**
622
+
623
+ Create `src/core/privacyDoctor.ts`:
624
+
625
+ ```ts
626
+ import { promises as fs } from "node:fs";
627
+ import path from "node:path";
628
+ import { listMemory } from "./memory.js";
629
+ import { pathExists, readTextFile, writeTextFile } from "./storage.js";
630
+ import { requireWorkspace } from "./workspace.js";
631
+
632
+ export type PrivacyDoctorStatus = "ok" | "warn" | "fail";
633
+
634
+ export type PrivacyDoctorCheck = {
635
+ name: string;
636
+ status: PrivacyDoctorStatus;
637
+ detail: string;
638
+ };
639
+
640
+ export type PrivacyDoctorResult = {
641
+ ok: boolean;
642
+ checks: PrivacyDoctorCheck[];
643
+ };
644
+
645
+ function check(name: string, status: PrivacyDoctorStatus, detail: string): PrivacyDoctorCheck {
646
+ return { name, status, detail };
647
+ }
648
+
649
+ const secretPatterns = [
650
+ /\bsk-[A-Za-z0-9_-]{16,}\b/,
651
+ /\bghp_[A-Za-z0-9_]{20,}\b/,
652
+ /\bgithub_pat_[A-Za-z0-9_]{20,}\b/,
653
+ /\bAKIA[0-9A-Z]{16}\b/,
654
+ /\b(password|passwd|secret|token|api[_-]?key)\s*[:=]\s*\S+/i
655
+ ];
656
+
657
+ async function gitignoreStatus(cwd: string): Promise<PrivacyDoctorCheck> {
658
+ const gitignorePath = path.join(cwd, ".gitignore");
659
+ if (!(await pathExists(gitignorePath))) {
660
+ return check("Gitignore", "warn", ".gitignore not found; add `.briefops/` before public use.");
661
+ }
662
+
663
+ const raw = await readTextFile(gitignorePath);
664
+ const ignoresBriefOps = raw
665
+ .split(/\r?\n/)
666
+ .map((line) => line.trim())
667
+ .some((line) => line === ".briefops" || line === ".briefops/" || line === "/.briefops/");
668
+
669
+ return ignoresBriefOps
670
+ ? check("Gitignore", "ok", ".briefops is ignored.")
671
+ : check("Gitignore", "warn", ".briefops is not ignored.");
672
+ }
673
+
674
+ export async function fixBriefOpsGitignore(cwd = process.cwd()): Promise<string> {
675
+ const gitignorePath = path.join(cwd, ".gitignore");
676
+ const existing = await pathExists(gitignorePath) ? await readTextFile(gitignorePath) : "";
677
+ const lines = existing.split(/\r?\n/).map((line) => line.trim());
678
+ if (!lines.includes(".briefops/") && !lines.includes(".briefops") && !lines.includes("/.briefops/")) {
679
+ const next = `${existing.trimEnd()}${existing.trim() ? "\n" : ""}.briefops/\n`;
680
+ await writeTextFile(gitignorePath, next, { force: true });
681
+ }
682
+ return gitignorePath;
683
+ }
684
+
685
+ export async function runPrivacyDoctor(options: {
686
+ cwd?: string;
687
+ } = {}): Promise<PrivacyDoctorResult> {
688
+ const cwd = options.cwd ?? process.cwd();
689
+ await requireWorkspace(cwd);
690
+
691
+ const memory = await listMemory({ cwd });
692
+ const privateExportable = memory.filter((item) => item.visibility === "private" && item.exportable);
693
+ const secretLike = memory.filter((item) =>
694
+ secretPatterns.some((pattern) => pattern.test(item.content))
695
+ );
696
+
697
+ const checks: PrivacyDoctorCheck[] = [
698
+ await gitignoreStatus(cwd),
699
+ privateExportable.length > 0
700
+ ? check("Private exportable memory", "warn", `${privateExportable.length} private item(s) are exportable.`)
701
+ : check("Private exportable memory", "ok", "No private exportable memory."),
702
+ secretLike.length > 0
703
+ ? check("Secret-like local memory", "warn", `${secretLike.length} memory item(s) look like secrets.`)
704
+ : check("Secret-like local memory", "ok", "No secret-like memory found.")
705
+ ];
706
+
707
+ return {
708
+ ok: checks.every((item) => item.status !== "fail"),
709
+ checks
710
+ };
711
+ }
712
+ ```
713
+
714
+ Remove the unused `fs` import if TypeScript reports it.
715
+
716
+ - [x] **Step 4: Add CLI flags**
717
+
718
+ Modify `src/commands/doctor.ts`:
719
+
720
+ ```ts
721
+ .option("--privacy", "Run privacy checks for local memory and share safety.")
722
+ .option("--fix-gitignore", "Add `.briefops/` to .gitignore when running --privacy.")
723
+ ```
724
+
725
+ Behavior:
726
+
727
+ ```ts
728
+ if (options.privacy) {
729
+ if (options.fixGitignore) {
730
+ const path = await fixBriefOpsGitignore();
731
+ console.log(`Updated gitignore: ${path}`);
732
+ console.log("");
733
+ }
734
+ const result = await runPrivacyDoctor();
735
+ printTable([
736
+ ["Check", "Status", "Detail"],
737
+ ...result.checks.map((item) => [item.name, item.status, item.detail])
738
+ ]);
739
+ if (!result.ok) {
740
+ process.exitCode = 1;
741
+ }
742
+ return;
743
+ }
744
+ ```
745
+
746
+ - [x] **Step 5: Run privacy tests**
747
+
748
+ Run:
749
+
750
+ ```bash
751
+ npm test -- tests/privacy-doctor.test.ts tests/cli-workflow.test.ts
752
+ ```
753
+
754
+ Expected: PASS.
755
+
756
+ - [x] **Step 6: Document privacy workflow**
757
+
758
+ Add to `README.md`:
759
+
760
+ ```markdown
761
+ ## Privacy Check
762
+
763
+ Run this before publishing a repository, sharing a pack, or attaching BriefOps context outside your machine:
764
+
765
+ ```bash
766
+ briefops doctor --privacy
767
+ briefops doctor --privacy --fix-gitignore
768
+ ```
769
+
770
+ BriefOps is local-first, but `.briefops/` may contain private logs and memory. Keep `.briefops/` out of source control unless you intentionally curated the contents.
771
+ ```
772
+
773
+ - [x] **Step 7: Commit**
774
+
775
+ ```bash
776
+ git add src/core/privacyDoctor.ts src/commands/doctor.ts tests/privacy-doctor.test.ts tests/cli-workflow.test.ts README.md docs/quickstart.md
777
+ git commit -m "feat: add privacy doctor"
778
+ ```
779
+
780
+ ---
781
+
782
+ ## Task 4: Plugin Trust Boundary And Idempotent Install Safety
783
+
784
+ **Files:**
785
+ - Modify: `src/core/codexPlugin.ts`
786
+ - Modify: `src/commands/codex.ts`
787
+ - Modify: `plugins/briefops-codex/README.md`
788
+ - Modify: `tests/codex-plugin.test.ts`
789
+
790
+ - [x] **Step 1: Write failing plugin changed-file test**
791
+
792
+ Add to `tests/codex-plugin.test.ts`:
793
+
794
+ ```ts
795
+ it("does not overwrite changed local plugin files without force", async () => {
796
+ await withTempDir(async (dir) => {
797
+ await initWorkspace(dir);
798
+ await installCodexPlugin({ cwd: dir });
799
+ const skillPath = path.join(
800
+ dir,
801
+ ".briefops/codex/plugin/briefops/skills/briefops-prime-context/SKILL.md"
802
+ );
803
+ await writeTextFile(skillPath, "custom local edit\n", { force: true });
804
+
805
+ await expect(installCodexPlugin({ cwd: dir })).rejects.toThrow(
806
+ "Generated plugin file has local changes"
807
+ );
808
+
809
+ expect(await readTextFile(skillPath)).toBe("custom local edit\n");
810
+ });
811
+ });
812
+
813
+ it("overwrites changed local plugin files with force", async () => {
814
+ await withTempDir(async (dir) => {
815
+ await initWorkspace(dir);
816
+ await installCodexPlugin({ cwd: dir });
817
+ const skillPath = path.join(
818
+ dir,
819
+ ".briefops/codex/plugin/briefops/skills/briefops-prime-context/SKILL.md"
820
+ );
821
+ await writeTextFile(skillPath, "custom local edit\n", { force: true });
822
+
823
+ await installCodexPlugin({ cwd: dir, force: true });
824
+
825
+ expect(await readTextFile(skillPath)).toContain("BriefOps Prime Context");
826
+ });
827
+ });
828
+ ```
829
+
830
+ - [x] **Step 2: Run failing plugin tests**
831
+
832
+ Run:
833
+
834
+ ```bash
835
+ npm test -- tests/codex-plugin.test.ts
836
+ ```
837
+
838
+ Expected: FAIL because plugin install currently overwrites generated files.
839
+
840
+ - [x] **Step 3: Make plugin install idempotent but changed-file safe**
841
+
842
+ In `src/core/codexPlugin.ts`, add:
843
+
844
+ ```ts
845
+ async function writeGeneratedPluginFile(options: {
846
+ target: string;
847
+ content: string;
848
+ force: boolean;
849
+ }): Promise<void> {
850
+ if (await pathExists(options.target)) {
851
+ const existing = await readTextFile(options.target);
852
+ if (existing === options.content) {
853
+ return;
854
+ }
855
+ if (!options.force) {
856
+ throw new BriefOpsError(
857
+ `Generated plugin file has local changes: ${options.target}. Re-run with --force to overwrite.`
858
+ );
859
+ }
860
+ }
861
+
862
+ await writeTextFile(options.target, options.content, { force: true });
863
+ }
864
+ ```
865
+
866
+ Import `BriefOpsError`.
867
+
868
+ Replace the install loop write with:
869
+
870
+ ```ts
871
+ await writeGeneratedPluginFile({
872
+ target,
873
+ content: file.content,
874
+ force: Boolean(options.force)
875
+ });
876
+ ```
877
+
878
+ - [x] **Step 4: Narrow plugin trust messaging**
879
+
880
+ Update generated skill text and `plugins/briefops-codex/README.md` to include:
881
+
882
+ ```markdown
883
+ The BriefOps plugin is a local CLI helper. It does not require network access, does not publish to a marketplace, and should not auto-approve memory or skill patches. Use `--export-policy shared-only` before copying context outside the local workspace.
884
+ ```
885
+
886
+ - [x] **Step 5: Run plugin tests**
887
+
888
+ Run:
889
+
890
+ ```bash
891
+ npm test -- tests/codex-plugin.test.ts tests/cli-workflow.test.ts
892
+ ```
893
+
894
+ Expected: PASS.
895
+
896
+ - [x] **Step 6: Commit**
897
+
898
+ ```bash
899
+ git add src/core/codexPlugin.ts src/commands/codex.ts plugins/briefops-codex/README.md tests/codex-plugin.test.ts
900
+ git commit -m "fix: protect generated plugin files"
901
+ ```
902
+
903
+ ---
904
+
905
+ ## Task 5: Harness Integration Documentation
906
+
907
+ **Files:**
908
+ - Create: `docs/integrations/harnesses.md`
909
+ - Modify: `README.md`
910
+ - Modify: `examples/codex-first-context/README.md`
911
+
912
+ - [x] **Step 1: Create harness integration doc**
913
+
914
+ Create `docs/integrations/harnesses.md`:
915
+
916
+ ```markdown
917
+ # Harness Integrations
918
+
919
+ BriefOps is not an agent harness. It does not run models, manage subscriptions, install hooks, expose MCP tools, or route work across agents.
920
+
921
+ BriefOps is a local memory and context ledger that a harness can read before work and update after work.
922
+
923
+ ## Recommended Pattern
924
+
925
+ Before a task:
926
+
927
+ ```bash
928
+ briefops prime --task "<task>" --format codex --max-tokens 800
929
+ ```
930
+
931
+ After meaningful work:
932
+
933
+ ```bash
934
+ briefops finish --worker <worker> --task "<task>" --result "<result>"
935
+ briefops memory proposal-show latest
936
+ briefops approve latest
937
+ ```
938
+
939
+ For a fresh thread:
940
+
941
+ ```bash
942
+ briefops continue --worker <worker> --task "<next task>" --pack
943
+ ```
944
+
945
+ For portable or shared context:
946
+
947
+ ```bash
948
+ briefops prime --task "<task>" --format codex --export-policy shared-only
949
+ briefops pack resume --worker <worker> --task "<task>" --export-policy shared-only
950
+ ```
951
+
952
+ ## LazyCodex / OmO
953
+
954
+ Use LazyCodex or OmO for orchestration, hooks, LSP/MCP, and autonomous execution. Use BriefOps for durable local continuity.
955
+
956
+ Suggested human workflow:
957
+
958
+ ```bash
959
+ briefops prime --task "Implement the next scoped change." --format codex --max-tokens 800
960
+ codex "Use the BriefOps prime context, then run ultrawork for this task."
961
+ briefops finish --worker <worker> --task "Implement the next scoped change." --result "<verified result>"
962
+ briefops memory proposal-show latest
963
+ ```
964
+
965
+ Do not let a harness auto-run `briefops approve latest`. Approval should remain human-confirmed.
966
+
967
+ ## Codex App And Codex CLI
968
+
969
+ Use `briefops codex plugin install` to generate local plugin assets under `.briefops/codex/plugin/briefops`.
970
+
971
+ This command does not write to global Codex folders by default.
972
+
973
+ ## Claude Code
974
+
975
+ BriefOps can coexist with `CLAUDE.md`. Keep `CLAUDE.md` for always-loaded project instructions and use BriefOps for task history, approved memory, handoffs, and shared-only packs.
976
+
977
+ ## Cursor
978
+
979
+ BriefOps can coexist with Cursor rules and memories. Keep Cursor rules for editor behavior and use BriefOps for auditable cross-thread work history.
980
+ ```
981
+
982
+ - [x] **Step 2: Link integration doc from README**
983
+
984
+ Add to `README.md`:
985
+
986
+ ```markdown
987
+ ## Harness Integrations
988
+
989
+ BriefOps works best as a local memory ledger beside stronger harnesses such as Codex, LazyCodex, OmO, Claude Code, Cursor, and OpenCode. See `docs/integrations/harnesses.md`.
990
+ ```
991
+
992
+ - [x] **Step 3: Run docs packaging check**
993
+
994
+ Run:
995
+
996
+ ```bash
997
+ npm pack --dry-run
998
+ ```
999
+
1000
+ Expected: tarball includes `docs/integrations/harnesses.md`.
1001
+
1002
+ - [x] **Step 4: Commit**
1003
+
1004
+ ```bash
1005
+ git add docs/integrations/harnesses.md README.md examples/codex-first-context/README.md
1006
+ git commit -m "docs: explain harness integrations"
1007
+ ```
1008
+
1009
+ ---
1010
+
1011
+ ## Task 6: Release Readiness Automation
1012
+
1013
+ **Files:**
1014
+ - Create: `docs/release-checklist.md`
1015
+ - Create: `.github/dependabot.yml`
1016
+ - Modify: `.github/workflows/ci.yml`
1017
+ - Modify: `package.json`
1018
+
1019
+ - [x] **Step 1: Add release checklist**
1020
+
1021
+ Create `docs/release-checklist.md`:
1022
+
1023
+ ```markdown
1024
+ # Release Checklist
1025
+
1026
+ Before publishing BriefOps:
1027
+
1028
+ ```bash
1029
+ npm run build
1030
+ npm test
1031
+ npm audit --audit-level=moderate
1032
+ npm pack --dry-run
1033
+ briefops --help
1034
+ ```
1035
+
1036
+ Manual smoke test:
1037
+
1038
+ ```bash
1039
+ tmpdir="$(mktemp -d)"
1040
+ cd "$tmpdir"
1041
+ briefops init
1042
+ briefops codex install
1043
+ briefops codex plugin install
1044
+ briefops skill create risk-review
1045
+ briefops project create atlas-q
1046
+ briefops worker create quant-reviewer --project atlas-q --skills risk-review
1047
+ briefops worker use quant-reviewer
1048
+ briefops prime --task "Start this task." --format codex --max-tokens 800
1049
+ briefops doctor --security
1050
+ briefops doctor --privacy
1051
+ ```
1052
+
1053
+ Confirm:
1054
+
1055
+ - `shared-only` exports omit private local memory.
1056
+ - Memory and skill patches require human approval.
1057
+ - Explicit output paths do not overwrite without `--force`.
1058
+ - `.briefops/` is ignored or intentionally curated.
1059
+ - `npm pack --dry-run` includes docs, examples, plugins, dist, README, LICENSE, SECURITY, CONTRIBUTING, CODE_OF_CONDUCT, CHANGELOG.
1060
+ ```
1061
+
1062
+ - [x] **Step 2: Add Dependabot**
1063
+
1064
+ Create `.github/dependabot.yml`:
1065
+
1066
+ ```yaml
1067
+ version: 2
1068
+ updates:
1069
+ - package-ecosystem: "npm"
1070
+ directory: "/"
1071
+ schedule:
1072
+ interval: "weekly"
1073
+ open-pull-requests-limit: 5
1074
+ ```
1075
+
1076
+ - [x] **Step 3: Add CI audit**
1077
+
1078
+ Modify `.github/workflows/ci.yml`:
1079
+
1080
+ ```yaml
1081
+ - name: Audit dependencies
1082
+ run: npm audit --audit-level=moderate
1083
+ ```
1084
+
1085
+ Place after `npm ci` and before build.
1086
+
1087
+ - [x] **Step 4: Add release verify script if not already present**
1088
+
1089
+ Ensure `package.json` has:
1090
+
1091
+ ```json
1092
+ "verify:release": "npm run build && npm test && npm audit --audit-level=moderate && npm pack --dry-run"
1093
+ ```
1094
+
1095
+ - [x] **Step 5: Run release verification**
1096
+
1097
+ Run:
1098
+
1099
+ ```bash
1100
+ npm run verify:release
1101
+ ```
1102
+
1103
+ Expected: PASS.
1104
+
1105
+ - [x] **Step 6: Commit**
1106
+
1107
+ ```bash
1108
+ git add docs/release-checklist.md .github/dependabot.yml .github/workflows/ci.yml package.json
1109
+ git commit -m "chore: add release readiness checks"
1110
+ ```
1111
+
1112
+ ---
1113
+
1114
+ ## Task 7: Final Product Gate
1115
+
1116
+ **Files:**
1117
+ - Modify: `README.md`
1118
+ - Modify: `docs/roadmap.md`
1119
+ - Modify: `CHANGELOG.md`
1120
+ - Modify: `package.json`
1121
+ - Modify: `package-lock.json`
1122
+
1123
+ - [x] **Step 1: Add release status to README**
1124
+
1125
+ Add:
1126
+
1127
+ ```markdown
1128
+ ## Release Status
1129
+
1130
+ BriefOps is pre-1.0. The current release is intended for developers who want a local-first memory and context ledger for AI coding agents. The public API and file formats may change before 1.0, but the core safety principles are stable:
1131
+
1132
+ - local files first
1133
+ - no hosted service required
1134
+ - no required MCP server
1135
+ - human-approved memory
1136
+ - shared-only export controls
1137
+ - deterministic CLI behavior
1138
+ ```
1139
+
1140
+ - [x] **Step 2: Update roadmap**
1141
+
1142
+ In `docs/roadmap.md`, make the next milestones:
1143
+
1144
+ ```markdown
1145
+ ## Near Term
1146
+
1147
+ - privacy doctor
1148
+ - explicit output overwrite protection
1149
+ - OSS trust docs
1150
+ - harness integration guide
1151
+ - release readiness CI
1152
+
1153
+ ## Later
1154
+
1155
+ - optional cross-harness projection
1156
+ - richer eval fixtures for token savings
1157
+ - curated shared-memory export bundles
1158
+ - signed release artifacts
1159
+ ```
1160
+
1161
+ - [x] **Step 3: Update changelog**
1162
+
1163
+ Move completed items into `CHANGELOG.md`:
1164
+
1165
+ ```markdown
1166
+ ## 0.2.1-alpha.0
1167
+
1168
+ - Add OSS trust documents.
1169
+ - Add privacy doctor.
1170
+ - Protect explicit output paths from accidental overwrite.
1171
+ - Protect generated Codex plugin files from silent local-change overwrite.
1172
+ - Add harness integration guidance.
1173
+ - Add release readiness checks.
1174
+ ```
1175
+
1176
+ - [x] **Step 4: Run complete verification**
1177
+
1178
+ Run:
1179
+
1180
+ ```bash
1181
+ npm run verify:release
1182
+ npm test -- tests/output-safety.test.ts tests/privacy-doctor.test.ts tests/codex-plugin.test.ts tests/cli-workflow.test.ts tests/safety.test.ts
1183
+ git diff --check
1184
+ ```
1185
+
1186
+ Expected:
1187
+
1188
+ - build passes
1189
+ - all tests pass
1190
+ - audit passes or reports only accepted non-production dev warnings that are documented before release
1191
+ - package dry-run includes expected files
1192
+ - diff check has no whitespace errors
1193
+
1194
+ - [x] **Step 5: Manual smoke test**
1195
+
1196
+ Run:
1197
+
1198
+ ```bash
1199
+ tmpdir="$(mktemp -d)"
1200
+ cd "$tmpdir"
1201
+ node /Users/simon/Documents/briefops/dist/index.js init
1202
+ node /Users/simon/Documents/briefops/dist/index.js codex install
1203
+ node /Users/simon/Documents/briefops/dist/index.js codex plugin install
1204
+ node /Users/simon/Documents/briefops/dist/index.js skill create risk-review
1205
+ node /Users/simon/Documents/briefops/dist/index.js project create atlas-q
1206
+ node /Users/simon/Documents/briefops/dist/index.js worker create quant-reviewer --project atlas-q --skills risk-review
1207
+ node /Users/simon/Documents/briefops/dist/index.js worker use quant-reviewer
1208
+ node /Users/simon/Documents/briefops/dist/index.js prime --task "Start this task." --format codex --max-tokens 800
1209
+ node /Users/simon/Documents/briefops/dist/index.js doctor --security
1210
+ node /Users/simon/Documents/briefops/dist/index.js doctor --privacy
1211
+ ```
1212
+
1213
+ Expected:
1214
+
1215
+ - plugin bundle path is printed
1216
+ - prime output includes `Codex Operating Note`
1217
+ - security doctor passes or gives actionable warnings
1218
+ - privacy doctor warns if `.briefops/` is not ignored
1219
+
1220
+ - [x] **Step 6: Commit**
1221
+
1222
+ ```bash
1223
+ git add README.md docs/roadmap.md CHANGELOG.md package.json package-lock.json
1224
+ git commit -m "docs: mark release candidate readiness"
1225
+ ```
1226
+
1227
+ ---
1228
+
1229
+ ## Completion Criteria
1230
+
1231
+ This plan is complete only when:
1232
+
1233
+ 1. Explicit user output paths never overwrite existing files unless `--force` is passed.
1234
+ 2. Generated plugin files are idempotent and do not silently erase local edits.
1235
+ 3. `briefops doctor --privacy` exists and checks gitignore, private exportable memory, and secret-like memory strings.
1236
+ 4. OSS trust files exist: `SECURITY.md`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `CHANGELOG.md`.
1237
+ 5. CI runs build, tests, audit, and npm package dry-run.
1238
+ 6. Package metadata includes repository, bugs, homepage, and keywords.
1239
+ 7. Harness integration docs clearly position BriefOps beside LazyCodex/OmO rather than as a competing harness.
1240
+ 8. README clearly says BriefOps is pre-1.0 but ready for public alpha use.
1241
+ 9. `npm run verify:release` passes.
1242
+ 10. Manual smoke test passes.
1243
+
1244
+ ---
1245
+
1246
+ ## Self-Review
1247
+
1248
+ Spec coverage:
1249
+ - Open-source readiness: Tasks 1, 6, 7.
1250
+ - P2 overwrite issue: Task 2.
1251
+ - P2 plugin trust/permission surface: Task 4.
1252
+ - P3 stale/privacy local data edge: Task 3.
1253
+ - BriefOps edge versus harness agents: Task 5.
1254
+ - Product completion direction: Tasks 6 and 7.
1255
+
1256
+ Placeholder scan:
1257
+ - No `TBD`, `TODO`, or “implement later” placeholders.
1258
+ - Every code-changing task includes exact file paths, commands, and expected outcomes.
1259
+
1260
+ Type consistency:
1261
+ - `force?: boolean` is consistently threaded through explicit output paths.
1262
+ - `runPrivacyDoctor` returns `PrivacyDoctorResult`, matching CLI rendering.
1263
+ - Plugin changed-file behavior uses existing `pathExists`, `readTextFile`, and `writeTextFile`.
1264
+
1265
+ ---
1266
+
1267
+ ## Execution Options
1268
+
1269
+ Plan complete and saved to `docs/superpowers/plans/2026-06-08-briefops-oss-readiness.md`.
1270
+
1271
+ 1. **Subagent-Driven (recommended)** - dispatch a fresh subagent per task, review between tasks, fast iteration.
1272
+ 2. **Inline Execution** - execute tasks in this session using executing-plans, with checkpoints after each task.