@bookedsolid/rea 0.1.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 (90) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +339 -0
  3. package/SECURITY.md +104 -0
  4. package/THREAT_MODEL.md +245 -0
  5. package/agents/accessibility-engineer.md +101 -0
  6. package/agents/backend-engineer.md +126 -0
  7. package/agents/code-reviewer.md +144 -0
  8. package/agents/codex-adversarial.md +107 -0
  9. package/agents/frontend-specialist.md +84 -0
  10. package/agents/qa-engineer.md +138 -0
  11. package/agents/rea-orchestrator.md +101 -0
  12. package/agents/security-engineer.md +108 -0
  13. package/agents/technical-writer.md +140 -0
  14. package/agents/typescript-specialist.md +111 -0
  15. package/commands/codex-review.md +104 -0
  16. package/commands/freeze.md +81 -0
  17. package/commands/halt-check.md +120 -0
  18. package/commands/rea.md +52 -0
  19. package/commands/review.md +79 -0
  20. package/dist/cli/check.d.ts +1 -0
  21. package/dist/cli/check.js +66 -0
  22. package/dist/cli/doctor.d.ts +1 -0
  23. package/dist/cli/doctor.js +93 -0
  24. package/dist/cli/freeze.d.ts +8 -0
  25. package/dist/cli/freeze.js +61 -0
  26. package/dist/cli/index.d.ts +2 -0
  27. package/dist/cli/index.js +65 -0
  28. package/dist/cli/init.d.ts +6 -0
  29. package/dist/cli/init.js +237 -0
  30. package/dist/cli/serve.d.ts +1 -0
  31. package/dist/cli/serve.js +19 -0
  32. package/dist/cli/utils.d.ts +23 -0
  33. package/dist/cli/utils.js +51 -0
  34. package/dist/config/tier-map.d.ts +11 -0
  35. package/dist/config/tier-map.js +108 -0
  36. package/dist/config/types.d.ts +24 -0
  37. package/dist/config/types.js +1 -0
  38. package/dist/gateway/circuit-breaker.d.ts +43 -0
  39. package/dist/gateway/circuit-breaker.js +86 -0
  40. package/dist/gateway/middleware/audit-types.d.ts +16 -0
  41. package/dist/gateway/middleware/audit-types.js +1 -0
  42. package/dist/gateway/middleware/audit.d.ts +12 -0
  43. package/dist/gateway/middleware/audit.js +98 -0
  44. package/dist/gateway/middleware/blocked-paths.d.ts +12 -0
  45. package/dist/gateway/middleware/blocked-paths.js +117 -0
  46. package/dist/gateway/middleware/chain.d.ts +28 -0
  47. package/dist/gateway/middleware/chain.js +40 -0
  48. package/dist/gateway/middleware/circuit-breaker.d.ts +11 -0
  49. package/dist/gateway/middleware/circuit-breaker.js +43 -0
  50. package/dist/gateway/middleware/injection.d.ts +22 -0
  51. package/dist/gateway/middleware/injection.js +128 -0
  52. package/dist/gateway/middleware/kill-switch.d.ts +10 -0
  53. package/dist/gateway/middleware/kill-switch.js +58 -0
  54. package/dist/gateway/middleware/policy.d.ts +12 -0
  55. package/dist/gateway/middleware/policy.js +70 -0
  56. package/dist/gateway/middleware/rate-limit.d.ts +12 -0
  57. package/dist/gateway/middleware/rate-limit.js +31 -0
  58. package/dist/gateway/middleware/redact.d.ts +16 -0
  59. package/dist/gateway/middleware/redact.js +128 -0
  60. package/dist/gateway/middleware/result-size-cap.d.ts +13 -0
  61. package/dist/gateway/middleware/result-size-cap.js +48 -0
  62. package/dist/gateway/middleware/session.d.ts +10 -0
  63. package/dist/gateway/middleware/session.js +18 -0
  64. package/dist/gateway/middleware/tier.d.ts +6 -0
  65. package/dist/gateway/middleware/tier.js +10 -0
  66. package/dist/gateway/rate-limiter.d.ts +36 -0
  67. package/dist/gateway/rate-limiter.js +75 -0
  68. package/dist/index.d.ts +3 -0
  69. package/dist/index.js +2 -0
  70. package/dist/policy/loader.d.ts +80 -0
  71. package/dist/policy/loader.js +146 -0
  72. package/dist/policy/types.d.ts +34 -0
  73. package/dist/policy/types.js +19 -0
  74. package/hooks/_lib/common.sh +105 -0
  75. package/hooks/_lib/halt-check.sh +39 -0
  76. package/hooks/_lib/policy-read.sh +79 -0
  77. package/hooks/architecture-review-gate.sh +84 -0
  78. package/hooks/attribution-advisory.sh +126 -0
  79. package/hooks/blocked-paths-enforcer.sh +176 -0
  80. package/hooks/changeset-security-gate.sh +143 -0
  81. package/hooks/commit-review-gate.sh +166 -0
  82. package/hooks/dangerous-bash-interceptor.sh +362 -0
  83. package/hooks/dependency-audit-gate.sh +118 -0
  84. package/hooks/env-file-protection.sh +110 -0
  85. package/hooks/pr-issue-link-gate.sh +65 -0
  86. package/hooks/push-review-gate.sh +120 -0
  87. package/hooks/secret-scanner.sh +229 -0
  88. package/hooks/security-disclosure-gate.sh +146 -0
  89. package/hooks/settings-protection.sh +147 -0
  90. package/package.json +93 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Booked Solid Technology (Clarity House LLC)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,339 @@
1
+ # REA
2
+
3
+ **Agentic governance layer for Claude Code — policy enforcement, hook-based safety gates, audit logging, and Codex-integrated adversarial review.**
4
+
5
+ [![npm version](https://img.shields.io/badge/npm-pending-lightgrey)](https://www.npmjs.com/package/@bookedsolid/rea)
6
+ [![CI](https://img.shields.io/badge/ci-pending-lightgrey)](https://github.com/bookedsolidtech/rea/actions)
7
+ [![provenance](https://img.shields.io/badge/npm%20provenance-pending-lightgrey)](https://docs.npmjs.com/generating-provenance-statements)
8
+ [![license](https://img.shields.io/badge/license-MIT-blue)](./LICENSE)
9
+ [![DCO](https://img.shields.io/badge/DCO-required-green)](https://developercertificate.org/)
10
+ [![Node](https://img.shields.io/badge/node-%3E%3D22-brightgreen)](https://nodejs.org/)
11
+
12
+ > Status: 0.0.x, pre-release. Badges are placeholders until the first publish.
13
+
14
+ ---
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npx @bookedsolid/rea init
20
+ ```
21
+
22
+ The `init` command is an interactive wizard. It detects your project, writes
23
+ `.rea/policy.yaml`, copies hooks and slash commands into `.claude/`, wires
24
+ `.mcp.json` to run `rea serve` as a governance gateway, installs a
25
+ `.husky/commit-msg` hook, and appends a managed fragment to `CLAUDE.md`.
26
+
27
+ Node 22+ and pnpm 9+ required.
28
+
29
+ ## What REA is
30
+
31
+ REA is a governance layer for Claude Code. It is a single npm package that
32
+ ships four things:
33
+
34
+ 1. A **hook layer** — 11 shell scripts wired into Claude Code's `PreToolUse`
35
+ and `PostToolUse` events. Hooks enforce secret scanning, dangerous-command
36
+ interception, blocked-path protection, settings protection, attribution
37
+ rejection, and commit/push review gates.
38
+ 2. A **gateway layer** — an MCP server (`rea serve`) that proxies downstream
39
+ MCP servers through a middleware chain. Every tool call — native or
40
+ proxied — is classified, policy-checked, redacted, audited, and
41
+ size-capped before it executes.
42
+ 3. A **policy runtime** — `.rea/policy.yaml` with strict zod-validated
43
+ schema. Defines autonomy level, a hard ceiling (`max_autonomy_level`),
44
+ blocked paths, attribution rules, context protection, and optional
45
+ Discord notification webhook.
46
+ 4. A **kill switch** — `.rea/HALT` is a single file. If it exists, every
47
+ tool call is denied at the middleware and hook layers. Use
48
+ `rea freeze --reason "..."` to create it and `rea unfreeze --reason "..."`
49
+ to remove it.
50
+
51
+ REA is one tool that does one thing: gate and audit agentic tool calls
52
+ against operator-defined policy. That is the whole product.
53
+
54
+ ## What REA is NOT
55
+
56
+ These are non-goals. PRs adding any of these will be closed with a pointer
57
+ to build a separate package that composes with REA.
58
+
59
+ - **Not a project manager.** No task CRUD, no GitHub issue sync, no board
60
+ scaffolding. No `task_create`, `task_update`, `repo_scaffold`.
61
+ - **Not an Obsidian integration.** No vault journaling, no note creation,
62
+ no precompact summaries, no pre/post-compact Obsidian hooks.
63
+ - **Not an account manager.** No `rea account add/list/env/rotate/remove`.
64
+ No Keychain, no OAuth, no multi-tenant token vault. Env vars only.
65
+ - **Not a Discord bot.** No Discord MCP tools. A Discord webhook URL in
66
+ `policy.yaml` is the maximum surface area — one outbound POST, opt-in.
67
+ - **Not a daemon supervisor.** `rea serve` is started by Claude Code via
68
+ `.mcp.json`. Claude Code owns the lifecycle. There is no `rea start`,
69
+ no `rea stop`, no pid file, no systemd unit.
70
+ - **Not a hosted service.** There is no REA Cloud, no SaaS tier, no
71
+ multi-token workstreams, no workload isolation platform.
72
+ - **Not a 70-agent roster.** 10 curated agents ship in the package. Four
73
+ profiles layer additional specialists on top. No kitchen sink.
74
+
75
+ The non-goals are the product. Every "but what if we just added X" belongs
76
+ in a separate package.
77
+
78
+ ## Quick start
79
+
80
+ ### 1. Write a policy
81
+
82
+ `.rea/policy.yaml`:
83
+
84
+ ```yaml
85
+ version: "1"
86
+ profile: "bst-internal"
87
+ autonomy_level: L1
88
+ max_autonomy_level: L2
89
+ promotion_requires_human_approval: true
90
+ blocked_paths:
91
+ - ".env"
92
+ - ".env.*"
93
+ - "secrets/**"
94
+ block_ai_attribution: true
95
+ context_protection:
96
+ delegate_to_subagent:
97
+ - "pnpm run preflight"
98
+ - "pnpm run test"
99
+ - "pnpm run build"
100
+ max_bash_output_lines: 100
101
+ notification_channel: "" # optional Discord webhook
102
+ ```
103
+
104
+ `autonomy_level` can be raised up to `max_autonomy_level` and no further.
105
+ The loader rejects the file at parse time if `autonomy_level` exceeds the
106
+ ceiling. The ceiling is set by the human operator and never by an agent.
107
+
108
+ ### 2. Freeze when you need to stop everything
109
+
110
+ ```bash
111
+ rea freeze --reason "incident triage; investigate unexpected .env write"
112
+ ```
113
+
114
+ `rea freeze` writes `.rea/HALT`. Every subsequent tool call is denied
115
+ until an operator runs:
116
+
117
+ ```bash
118
+ rea unfreeze --reason "false alarm — resolved"
119
+ ```
120
+
121
+ Both calls produce audit entries. The middleware never clears HALT on
122
+ its own.
123
+
124
+ ### 3. Verify the install
125
+
126
+ ```bash
127
+ rea doctor
128
+ ```
129
+
130
+ `rea doctor` checks hook coverage, policy parse, husky commit-msg hook
131
+ install, `.mcp.json` gateway wiring, Codex plugin availability, and the
132
+ integrity of the audit hash chain. It returns a pass/fail summary with
133
+ specific remediation hints.
134
+
135
+ ## Architecture
136
+
137
+ ### Middleware chain
138
+
139
+ Every native MCP tool call AND every proxied downstream call flows through
140
+ one chain. The order matters — each layer fails closed.
141
+
142
+ ```
143
+ tool call
144
+
145
+
146
+ ┌───────────────────────────────────────────────────┐
147
+ │ audit.enter — hash-chained record start │
148
+ │ kill-switch — deny if .rea/HALT exists │
149
+ │ tier — read/write/destructive class │
150
+ │ policy — autonomy gate (L0–L3) │
151
+ │ blocked-paths — .rea/ + operator paths │
152
+ │ rate-limit — token bucket per server │
153
+ │ circuit-breaker — trip on downstream failure │
154
+ │ redact (args) — secrets in arguments │
155
+ │ injection — prompt-injection heuristics │
156
+ │ │
157
+ │ ==== EXECUTE ==== │
158
+ │ │
159
+ │ redact (result) — secrets in result │
160
+ │ result-size-cap — bounded response │
161
+ │ audit.exit — hash-chained record close │
162
+ └───────────────────────────────────────────────────┘
163
+
164
+
165
+ result
166
+ ```
167
+
168
+ `.rea/` is hardcoded as an always-blocked path. It cannot be unblocked
169
+ from policy. Policy is re-read on every invocation — any edit to
170
+ `policy.yaml` takes effect on the next tool call.
171
+
172
+ ### Hook layer
173
+
174
+ Hooks are shell scripts wired into `.claude/settings.json`. They run at
175
+ Claude Code tool-invocation time, independently of the gateway. Both
176
+ layers fail closed. Bypassing one does not disable the other.
177
+
178
+ Every hook sources `hooks/_lib/halt-check.sh` and `hooks/_lib/policy-read.sh`
179
+ at the top of the script. Every hook uses `set -euo pipefail`.
180
+
181
+ ### Slash commands
182
+
183
+ Five commands ship in the package and are copied into `.claude/commands/`
184
+ during `rea init`.
185
+
186
+ ### Agent roster
187
+
188
+ Ten curated agents ship in the package: `rea-orchestrator`, `code-reviewer`,
189
+ `codex-adversarial`, `security-engineer`, `accessibility-engineer`,
190
+ `typescript-specialist`, `frontend-specialist`, `backend-engineer`,
191
+ `qa-engineer`, `technical-writer`. Four profiles
192
+ (`client-engagement`, `bst-internal`, `lit-wc`, `open-source`) layer
193
+ additional specialists on top.
194
+
195
+ The orchestrator is the single entry point for non-trivial tasks. The
196
+ CLAUDE.md template installed by `rea init` instructs the host agent:
197
+ _"For any non-trivial task, delegate to the `rea-orchestrator` agent
198
+ FIRST."_
199
+
200
+ ## The Plan / Build / Review loop
201
+
202
+ Codex is a first-class part of REA. It is not a bolt-on. The BST
203
+ engineering process bakes adversarial review into the default flow, and
204
+ REA ships it out of the box.
205
+
206
+ | Phase | Primary model | Codex role | Governance |
207
+ | --- | --- | --- | --- |
208
+ | Plan | Claude Opus | — | Full middleware chain |
209
+ | Pre-implementation review | — | `/codex review` — review the PLAN before code | Audited |
210
+ | Build | Claude Opus | — | Full middleware chain |
211
+ | Adversarial review | — | `/codex adversarial-review` on the diff (independent perspective) | Audited, redacted, kill-switched |
212
+ | Pre-merge gate | — | `/codex adversarial-review` re-run; recorded in audit.jsonl | Required status check (recommended) |
213
+
214
+ Three things make this work:
215
+
216
+ 1. The **`codex-adversarial` agent** in the curated roster wraps
217
+ `/codex adversarial-review`. The orchestrator delegates to it after
218
+ any non-trivial change.
219
+ 2. The **`/codex-review` slash command** is one of the five shipped
220
+ commands. It produces an audit entry including the request summary,
221
+ response summary, and pass/fail signal.
222
+ 3. The **`push-review-gate.sh` hook** checks for a recent `/codex-review`
223
+ audit entry on the current branch and warns (does not block) if none
224
+ is present.
225
+
226
+ Codex responses are treated as untrusted input. They flow through the
227
+ `redact` and `injection` middleware on return — same treatment as any
228
+ other downstream tool result. Codex never receives `.rea/policy.yaml`
229
+ content in its prompts; Codex reviews diffs, not policy.
230
+
231
+ If Codex is not installed, `rea doctor` warns with a one-line install
232
+ hint. REA does not require Codex to function, but the default workflow
233
+ assumes it.
234
+
235
+ ## Hooks
236
+
237
+ Eleven hooks, down from reagent's 26. Each does one thing.
238
+
239
+ | Hook | Event | One-line purpose |
240
+ | --- | --- | --- |
241
+ | `dangerous-bash-interceptor` | PreToolUse: Bash | Block categories of destructive shell commands |
242
+ | `env-file-protection` | PreToolUse: Bash | Block reads of `.env*` files |
243
+ | `dependency-audit-gate` | PreToolUse: Bash | Run `npm audit`; block on high/critical |
244
+ | `commit-review-gate` | PreToolUse: Bash | Intercept `git commit`; require review on non-trivial diffs |
245
+ | `push-review-gate` | PreToolUse: Bash | Intercept `git push`; warn if no recent `/codex-review` |
246
+ | `attribution-advisory` | PreToolUse: Bash | Block commits containing AI attribution markers |
247
+ | `secret-scanner` | PreToolUse: Write\|Edit | Scan file writes for credential patterns |
248
+ | `settings-protection` | PreToolUse: Write\|Edit | Block agent writes to `.claude/settings.json` |
249
+ | `blocked-paths-enforcer` | PreToolUse: Write\|Edit | Enforce `blocked_paths` from policy |
250
+ | `changeset-security-gate` | PreToolUse: Write\|Edit | Require changeset entry on security-relevant changes |
251
+ | `architecture-review-gate` | PostToolUse: Write\|Edit | Flag edits crossing architectural boundaries |
252
+
253
+ A twelfth hook, `security-disclosure-gate`, intercepts `gh issue create`
254
+ commands containing security-sensitive keywords and redirects to private
255
+ disclosure. It is installed as part of the Bash PreToolUse set.
256
+
257
+ ## Slash commands
258
+
259
+ | Command | Purpose |
260
+ | --- | --- |
261
+ | `/rea` | Session status — autonomy level, HALT state, last audit entries, next action |
262
+ | `/review` | Invoke the `code-reviewer` agent on current changes |
263
+ | `/codex-review` | Invoke the `codex-adversarial` agent → `/codex adversarial-review` |
264
+ | `/freeze` | Prompt for a reason and write `.rea/HALT` |
265
+ | `/halt-check` | Verify every middleware and hook respects HALT |
266
+
267
+ ## Policy file reference
268
+
269
+ `.rea/policy.yaml` fields. The schema is zod-strict — unknown fields are
270
+ rejected, not ignored.
271
+
272
+ | Field | Type | Purpose |
273
+ | --- | --- | --- |
274
+ | `version` | string, `"1"` | Schema version; only `"1"` accepted in 0.1.x |
275
+ | `profile` | string | Profile name from `profiles/` (e.g. `bst-internal`) |
276
+ | `autonomy_level` | `L0`\|`L1`\|`L2`\|`L3` | Current autonomy. `L0` = read-only; `L3` = full tool access |
277
+ | `max_autonomy_level` | `L0`\|`L1`\|`L2`\|`L3` | Hard ceiling. `autonomy_level` cannot exceed this |
278
+ | `promotion_requires_human_approval` | boolean | Require operator confirmation to raise autonomy. Default `true` |
279
+ | `blocked_paths` | string[] | Glob patterns. `.rea/` is always blocked regardless of this list |
280
+ | `block_ai_attribution` | boolean | Enforce no-AI-attribution in commits and PR bodies |
281
+ | `context_protection.delegate_to_subagent` | string[] | Commands that must run in a subagent context to preserve the parent's context window |
282
+ | `context_protection.max_bash_output_lines` | number | Truncate long bash output at this line count |
283
+ | `notification_channel` | string | Optional Discord webhook URL. Empty string = no notifications |
284
+
285
+ `autonomy_level > max_autonomy_level` is rejected at parse time. Setting
286
+ `promotion_requires_human_approval: false` requires the CLI flag
287
+ `--i-understand-the-risks`.
288
+
289
+ ## Migration from `@bookedsolid/reagent`
290
+
291
+ ```bash
292
+ npx @bookedsolid/rea init --from-reagent
293
+ ```
294
+
295
+ `--from-reagent`:
296
+
297
+ - Reads `.reagent/policy.yaml` and translates field-for-field into
298
+ `.rea/policy.yaml`. Field names are identical, so the translation is a
299
+ rename.
300
+ - Moves `.reagent/audit.jsonl` to `.rea/audit.jsonl` and verifies the
301
+ hash chain.
302
+ - Un-wires dropped hooks (Obsidian, PM-layer, account) from
303
+ `.claude/settings.json`.
304
+ - Replaces `reagent` slash commands and agents with the REA equivalents.
305
+ - Leaves `.reagent/` in place; you delete it manually after verifying
306
+ `rea doctor` passes and a dogfood run completes.
307
+
308
+ Reagent will be deprecated via `npm deprecate` within seven days of
309
+ REA 0.1.0. The deprecation notice points users here.
310
+
311
+ ## Security
312
+
313
+ - [SECURITY.md](./SECURITY.md) — disclosure policy, supported versions,
314
+ and scope. Do not report vulnerabilities via public GitHub issues.
315
+ - [THREAT_MODEL.md](./THREAT_MODEL.md) — attack surface, mitigations,
316
+ residual risks. This is the contract REA holds itself to.
317
+
318
+ Short version: gateway and hook layers operate independently. Both fail
319
+ closed. `.rea/` is always blocked. Audit is hash-chained. Policy is
320
+ re-read on every invocation. npm publish uses OIDC provenance, not
321
+ long-lived tokens.
322
+
323
+ ## Contributing
324
+
325
+ See [CONTRIBUTING.md](./CONTRIBUTING.md). Short version:
326
+
327
+ - DCO sign-off required on every commit (`git commit -s`). CI rejects
328
+ unsigned commits.
329
+ - No AI attribution in commit messages, PR bodies, or code. The
330
+ commit-msg hook enforces this.
331
+ - Conventional commits, TypeScript strict, ESLint zero-warnings,
332
+ Prettier, vitest.
333
+ - Security-sensitive paths (`src/gateway/middleware/**`, `src/policy/**`,
334
+ `hooks/**`, `.github/workflows/**`) require explicit maintainer
335
+ review and a threat-model update in the same PR.
336
+
337
+ ## License
338
+
339
+ [MIT](./LICENSE)
package/SECURITY.md ADDED
@@ -0,0 +1,104 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ | Version | Supported |
6
+ | ------- | --------- |
7
+ | 0.1.x | Yes |
8
+ | < 0.1 | No (pre-release) |
9
+
10
+ ## Reporting a Vulnerability
11
+
12
+ **Do not open a public GitHub issue for security vulnerabilities.**
13
+
14
+ Public issues expose vulnerabilities to attackers before users can patch. We follow coordinated disclosure — vulnerabilities are disclosed publicly only after a patch is released.
15
+
16
+ > Note: REA enforces this policy automatically. The `security-disclosure-gate` hook intercepts `gh issue create` commands containing security-sensitive keywords and blocks them with instructions to use private disclosure instead.
17
+
18
+ ### Private Disclosure (preferred)
19
+
20
+ Email **security@bookedsolid.tech** with the details below. This is monitored and treated as confidential.
21
+
22
+ Alternatively, use [GitHub Security Advisories](https://github.com/bookedsolidtech/rea/security/advisories/new) to report privately. This creates a private discussion thread visible only to maintainers.
23
+
24
+ ### What to include
25
+
26
+ - Description of the vulnerability and affected component
27
+ - Steps to reproduce (minimal PoC if possible)
28
+ - Potential impact and attack scenario
29
+ - Your suggested fix (optional but appreciated)
30
+
31
+ ### Response timeline
32
+
33
+ | Step | Target |
34
+ | ------------------------- | ------------------------------------- |
35
+ | Acknowledgement | Within 72 hours |
36
+ | Patch for critical issues | Within 7 days of confirmed report |
37
+ | Public disclosure | Within 90 days, or sooner if patched |
38
+
39
+ ## Scope
40
+
41
+ The following components are **in scope**:
42
+
43
+ - **Hook scripts** — all `.sh` files in `hooks/` and consumer-installed `.claude/hooks/`. REA ships shell scripts that execute on every Claude Code tool call with the full permissions of the user running Claude Code. Vulnerabilities in these scripts are treated as critical, equivalent to arbitrary code execution in the developer's environment.
44
+ - **CLI commands** — `rea init`, `rea freeze`, `rea unfreeze`, `rea serve`, `rea check`, `rea doctor`, and related entry points in `src/cli/`
45
+ - **MCP server and middleware chain** — policy enforcement, tier classification, blocked-path enforcement, secret redaction, audit logging, kill-switch, and injection detection layers
46
+ - **Policy loader** — `.rea/policy.yaml` parsing and schema validation; autonomy-ceiling enforcement
47
+ - **Prompt injection** — via proxied tool descriptions, tool names, or tool results
48
+ - **Tool name collision / shadowing** — native tool override via malicious downstream server config
49
+ - **Secret redaction gaps** — credential patterns not caught, encoding-based bypasses
50
+ - **Audit chain tampering** — hash chain bypass, log suppression techniques
51
+ - **Shell hook injection** — techniques to inject arbitrary commands through hook input parsing
52
+ - **HALT kill-switch bypass** — race conditions, symlink attacks, TOCTOU on `.rea/HALT`
53
+ - **Codex plugin integration** — review-gate bypass, audit entry suppression on Codex invocations
54
+
55
+ **Out of scope:**
56
+
57
+ - Vulnerabilities in Claude Code itself — report those to Anthropic
58
+ - Vulnerabilities in the Codex plugin itself — report those to OpenAI
59
+ - Bugs in the MCP protocol implementation — report those to the MCP maintainers or Anthropic
60
+ - Vulnerabilities in downstream MCP servers proxied through `.rea/registry.yaml` — report those to the respective project maintainers
61
+ - Social engineering
62
+ - Denial of service via resource exhaustion (unless it bypasses a security control)
63
+ - Issues requiring physical access to the machine
64
+
65
+ ## Coordinated Disclosure
66
+
67
+ Once a patch is ready:
68
+
69
+ 1. We release the patched version to npm
70
+ 2. We publish a GitHub Security Advisory with full technical details
71
+ 3. We credit the reporter (unless they prefer anonymity)
72
+
73
+ We ask reporters to wait for our patch before publishing their own writeup. Critical issues are patched within 7 days; other issues within a reasonable timeline based on complexity.
74
+
75
+ ## Security Architecture
76
+
77
+ REA's security model is defense-in-depth across two independent layers:
78
+
79
+ **Gateway layer** (runtime, `rea serve`):
80
+
81
+ - Governance middleware chain — every tool call is audited, classified, and policy-checked
82
+ - Secret redaction on arguments (pre-execution) and results (post-execution)
83
+ - HALT kill switch — a single `.rea/HALT` file immediately blocks all tool calls
84
+ - Blocked path enforcement — `.rea/` and operator-defined paths are always protected
85
+
86
+ **Hook layer** (development-time, Claude Code hooks):
87
+
88
+ - 11 Claude Code hooks enforce security at the point of tool invocation
89
+ - `security-disclosure-gate` blocks public issue creation for security topics
90
+ - `settings-protection` prevents agents from modifying their own safety rails
91
+ - `dangerous-bash-interceptor` blocks categories of destructive shell commands
92
+
93
+ Both layers operate independently — compromising one does not disable the other.
94
+
95
+ ## Security Design Notes
96
+
97
+ - No telemetry or network calls from the CLI or gateway (gateway only connects to operator-configured downstream servers)
98
+ - No `eval`, `Function()`, or dynamic `require` on policy-driven input
99
+ - Policy parsing is strict zod schema — unknown fields rejected, not ignored
100
+ - Path traversal protection on profile loading (regex + path containment check)
101
+ - CI publish pipeline includes gitleaks secret scanning, npm provenance attestation via OIDC, SBOM generation, and payload validation
102
+ - All shell hooks use `set -euo pipefail` with explicit variable quoting
103
+ - Commits are signed and DCO-signed-off; `main` branch protection requires passing checks and review
104
+ - npm publish uses OIDC provenance; no long-lived NPM tokens in CI