brainclaw 1.9.0 → 1.10.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 (149) hide show
  1. package/README.md +631 -499
  2. package/dist/brainclaw-vscode.vsix +0 -0
  3. package/dist/cli.js +18 -1
  4. package/dist/commands/code-map.js +129 -0
  5. package/dist/commands/codev.js +7 -0
  6. package/dist/commands/harvest.js +1 -1
  7. package/dist/commands/hooks.js +73 -73
  8. package/dist/commands/init.js +1 -1
  9. package/dist/commands/install-hooks.js +78 -78
  10. package/dist/commands/mcp-read-handlers.js +57 -14
  11. package/dist/commands/mcp.js +200 -13
  12. package/dist/commands/run-profile.js +3 -2
  13. package/dist/commands/switch.js +125 -93
  14. package/dist/commands/version.js +1 -1
  15. package/dist/core/agent-capability.js +19 -4
  16. package/dist/core/agent-files.js +131 -119
  17. package/dist/core/code-map/backend.js +123 -0
  18. package/dist/core/code-map/core.js +81 -0
  19. package/dist/core/code-map/drafts.js +2 -0
  20. package/dist/core/code-map/extractor.js +29 -0
  21. package/dist/core/code-map/finalizer.js +191 -0
  22. package/dist/core/code-map/freshness.js +108 -0
  23. package/dist/core/code-map/ids.js +0 -0
  24. package/dist/core/code-map/importable.js +35 -0
  25. package/dist/core/code-map/indexes.js +197 -0
  26. package/dist/core/code-map/lang/java/imports.scm +17 -0
  27. package/dist/core/code-map/lang/java/index.js +254 -0
  28. package/dist/core/code-map/lang/java/tags.scm +48 -0
  29. package/dist/core/code-map/lang/php/imports.scm +21 -0
  30. package/dist/core/code-map/lang/php/index.js +251 -0
  31. package/dist/core/code-map/lang/php/tags.scm +44 -0
  32. package/dist/core/code-map/lang/provider.js +9 -0
  33. package/dist/core/code-map/lang/providers.js +24 -0
  34. package/dist/core/code-map/lang/python/imports.scm +90 -0
  35. package/dist/core/code-map/lang/python/index.js +364 -0
  36. package/dist/core/code-map/lang/python/tags.scm +81 -0
  37. package/dist/core/code-map/lang/query-runtime.js +374 -0
  38. package/dist/core/code-map/lang/registry.js +125 -0
  39. package/dist/core/code-map/lang/typescript/imports.scm +90 -0
  40. package/dist/core/code-map/lang/typescript/index.js +306 -0
  41. package/dist/core/code-map/lang/typescript/tags.js.scm +106 -0
  42. package/dist/core/code-map/lang/typescript/tags.scm +151 -0
  43. package/dist/core/code-map/lock.js +210 -0
  44. package/dist/core/code-map/materialized.js +51 -0
  45. package/dist/core/code-map/memory-reader.js +59 -0
  46. package/dist/core/code-map/paths.js +53 -0
  47. package/dist/core/code-map/query.js +568 -0
  48. package/dist/core/code-map/refresh.js +0 -0
  49. package/dist/core/code-map/resolve.js +177 -0
  50. package/dist/core/code-map/store.js +206 -0
  51. package/dist/core/code-map/types.js +288 -0
  52. package/dist/core/code-map/vocabulary.js +57 -0
  53. package/dist/core/code-map/wasm-loader.js +294 -0
  54. package/dist/core/code-map/work-section.js +206 -0
  55. package/dist/core/codev-prompts.js +38 -38
  56. package/dist/core/codev-rounds.js +4 -0
  57. package/dist/core/default-profiles/doctor.yaml +11 -11
  58. package/dist/core/default-profiles/janitor.yaml +11 -11
  59. package/dist/core/default-profiles/onboarder.yaml +11 -11
  60. package/dist/core/default-profiles/reviewer.yaml +13 -13
  61. package/dist/core/dispatcher.js +1 -1
  62. package/dist/core/entity-operations.js +29 -3
  63. package/dist/core/execution-adapters.js +11 -10
  64. package/dist/core/execution-profile.js +58 -0
  65. package/dist/core/execution.js +1 -1
  66. package/dist/core/facade-schema.js +9 -0
  67. package/dist/core/instruction-templates.js +2 -0
  68. package/dist/core/loops/verbs.js +0 -1
  69. package/dist/core/mcp-command-resolution.js +3 -1
  70. package/dist/core/messaging.js +2 -2
  71. package/dist/core/protocol-skills.js +164 -164
  72. package/dist/core/runtime-signals.js +1 -1
  73. package/dist/core/search.js +19 -2
  74. package/dist/core/security-guard.js +207 -207
  75. package/dist/core/spawn-check.js +16 -2
  76. package/dist/core/staleness.js +1 -1
  77. package/dist/core/store-resolution.js +67 -11
  78. package/dist/core/worktree.js +18 -18
  79. package/dist/facts.js +9 -5
  80. package/dist/facts.json +8 -4
  81. package/dist/vendor/web-tree-sitter/tree-sitter.js +3980 -0
  82. package/dist/vendor/web-tree-sitter/tree-sitter.wasm +0 -0
  83. package/dist/wasm/tree-sitter-java.wasm +0 -0
  84. package/dist/wasm/tree-sitter-javascript.wasm +0 -0
  85. package/dist/wasm/tree-sitter-php.wasm +0 -0
  86. package/dist/wasm/tree-sitter-python.wasm +0 -0
  87. package/dist/wasm/tree-sitter-tsx.wasm +0 -0
  88. package/dist/wasm/tree-sitter-typescript.wasm +0 -0
  89. package/dist/wasm/tree-sitter.wasm +0 -0
  90. package/docs/PROTOCOL.md +1 -1
  91. package/docs/adapters/openclaw.md +43 -43
  92. package/docs/architecture/project-refs.md +328 -328
  93. package/docs/cli.md +2131 -2093
  94. package/docs/code-map.md +198 -0
  95. package/docs/concepts/coordination.md +52 -52
  96. package/docs/concepts/coordinator-runbook.md +129 -129
  97. package/docs/concepts/dispatch-lifecycle.md +245 -245
  98. package/docs/concepts/event-log-store.md +928 -928
  99. package/docs/concepts/ideation-loop.md +317 -317
  100. package/docs/concepts/loop-engine.md +520 -511
  101. package/docs/concepts/mcp-governance.md +268 -268
  102. package/docs/concepts/memory.md +84 -84
  103. package/docs/concepts/multi-agent-workflows.md +167 -167
  104. package/docs/concepts/observer-protocol.md +361 -361
  105. package/docs/concepts/plans-and-claims.md +217 -217
  106. package/docs/concepts/project-md-convention.md +35 -35
  107. package/docs/concepts/runtime-notes.md +38 -38
  108. package/docs/concepts/troubleshooting.md +254 -254
  109. package/docs/concepts/workspace-bootstrapping.md +142 -142
  110. package/docs/context-format-changelog.md +35 -35
  111. package/docs/context-format.md +48 -48
  112. package/docs/index.md +65 -65
  113. package/docs/integrations/agents.md +158 -158
  114. package/docs/integrations/claude-code.md +23 -23
  115. package/docs/integrations/cline.md +77 -77
  116. package/docs/integrations/continue.md +55 -55
  117. package/docs/integrations/copilot.md +68 -68
  118. package/docs/integrations/cursor.md +23 -23
  119. package/docs/integrations/kilocode.md +72 -72
  120. package/docs/integrations/mcp.md +385 -378
  121. package/docs/integrations/mistral-vibe.md +122 -122
  122. package/docs/integrations/openclaw.md +92 -92
  123. package/docs/integrations/opencode.md +84 -84
  124. package/docs/integrations/overview.md +115 -115
  125. package/docs/integrations/roo.md +71 -71
  126. package/docs/integrations/windsurf.md +77 -77
  127. package/docs/mcp-schema-changelog.md +364 -356
  128. package/docs/playbooks/integration/index.md +121 -121
  129. package/docs/playbooks/orchestration.md +37 -0
  130. package/docs/playbooks/productivity/index.md +99 -99
  131. package/docs/playbooks/team/index.md +117 -117
  132. package/docs/product/agent-first-model.md +184 -184
  133. package/docs/product/entity-model-audit.md +462 -462
  134. package/docs/product/positioning.md +86 -86
  135. package/docs/quickstart-existing-project.md +107 -107
  136. package/docs/quickstart.md +183 -183
  137. package/docs/release-maintenance.md +79 -79
  138. package/docs/reputation.md +52 -52
  139. package/docs/review.md +45 -45
  140. package/docs/security.md +212 -212
  141. package/docs/server-operations.md +118 -118
  142. package/docs/storage.md +106 -106
  143. package/package.json +86 -66
  144. package/docs/concepts/event-log-store-critique-A.md +0 -333
  145. package/docs/concepts/event-log-store-critique-B.md +0 -353
  146. package/docs/concepts/event-log-store-phase0-measurements.md +0 -58
  147. package/docs/concepts/event-log-store-proposal-A.md +0 -365
  148. package/docs/concepts/event-log-store-proposal-B.md +0 -404
  149. package/docs/concepts/identity-model-proposal.md +0 -371
package/docs/review.md CHANGED
@@ -1,45 +1,45 @@
1
- # Review and Reflection
2
-
3
- brainclaw includes a reflective layer so not every observation has to become canonical memory immediately.
4
-
5
- ## Why this exists
6
-
7
- Some facts are:
8
-
9
- - durable and worth keeping
10
- - useful but still uncertain
11
- - too local or too temporary to promote immediately
12
-
13
- A review layer helps filter and promote the right items.
14
-
15
- ## Typical flow
16
-
17
- ```
18
- runtime-note → reflect-runtime-note → review candidate → accept / reject
19
- ```
20
-
21
- 1. capture a runtime note (`brainclaw runtime-note`)
22
- 2. reflect it into a candidate when useful (`brainclaw reflect-runtime-note`)
23
- 3. review the candidate (`brainclaw review`)
24
- 4. accept or reject it (`brainclaw accept` / `brainclaw reject`)
25
-
26
- For MCP-capable agents, `brainclaw runtime-note` maps to `bclaw_write_note`.
27
-
28
- ## Star and use signals
29
-
30
- Before formal review, candidates can accumulate signals:
31
-
32
- ```bash
33
- brainclaw star-candidate cnd_001 --by copilot # passive interest
34
- brainclaw use-candidate cnd_001 --by copilot --context "auth rollout" # active reuse
35
- ```
36
-
37
- `review --prioritized` uses these signals (along with freshness and semantic relevance) to surface the most important candidates.
38
-
39
- ## curator role
40
-
41
- The `curator` trust level has direct promote access. Other roles create candidates for review.
42
-
43
- ## Why this is valuable
44
-
45
- This keeps canonical memory cleaner while still preserving useful observations long enough to evaluate them.
1
+ # Review and Reflection
2
+
3
+ brainclaw includes a reflective layer so not every observation has to become canonical memory immediately.
4
+
5
+ ## Why this exists
6
+
7
+ Some facts are:
8
+
9
+ - durable and worth keeping
10
+ - useful but still uncertain
11
+ - too local or too temporary to promote immediately
12
+
13
+ A review layer helps filter and promote the right items.
14
+
15
+ ## Typical flow
16
+
17
+ ```
18
+ runtime-note → reflect-runtime-note → review candidate → accept / reject
19
+ ```
20
+
21
+ 1. capture a runtime note (`brainclaw runtime-note`)
22
+ 2. reflect it into a candidate when useful (`brainclaw reflect-runtime-note`)
23
+ 3. review the candidate (`brainclaw review`)
24
+ 4. accept or reject it (`brainclaw accept` / `brainclaw reject`)
25
+
26
+ For MCP-capable agents, `brainclaw runtime-note` maps to `bclaw_write_note`.
27
+
28
+ ## Star and use signals
29
+
30
+ Before formal review, candidates can accumulate signals:
31
+
32
+ ```bash
33
+ brainclaw star-candidate cnd_001 --by copilot # passive interest
34
+ brainclaw use-candidate cnd_001 --by copilot --context "auth rollout" # active reuse
35
+ ```
36
+
37
+ `review --prioritized` uses these signals (along with freshness and semantic relevance) to surface the most important candidates.
38
+
39
+ ## curator role
40
+
41
+ The `curator` trust level has direct promote access. Other roles create candidates for review.
42
+
43
+ ## Why this is valuable
44
+
45
+ This keeps canonical memory cleaner while still preserving useful observations long enough to evaluate them.
package/docs/security.md CHANGED
@@ -1,212 +1,212 @@
1
- # Security
2
-
3
- brainclaw is designed to be safe by default.
4
-
5
- ## Security model
6
-
7
- ### No network access by default
8
- The CLI does not need to call external services to function. The optional
9
- supply-chain gate (see below) is the one feature that talks to a remote
10
- service, and it is off until explicitly enabled.
11
-
12
- ### No telemetry
13
- brainclaw does not collect or send usage data.
14
-
15
- ### No secret management
16
- brainclaw is not a vault and should not be treated like one.
17
-
18
- ### Plain-text visibility
19
- The storage model is intentionally inspectable.
20
- That makes review easier, but it also means users must be careful about what they write and commit.
21
-
22
- ## Built-in safety behaviors
23
-
24
- ### Content scanning (scanText)
25
-
26
- Whenever content is added to `.brainclaw/` brainclaw scans the text in three
27
- layers:
28
-
29
- 1. **User-configured regex patterns** from `redaction.patterns`. The
30
- defaults catch words like `api_key`, `secret`, `token`, `password`.
31
- 2. **Structural detectors** for well-known token shapes — GitHub PATs
32
- (`ghp_`, `gho_`, `github_pat_…`), AWS access keys (`AKIA…`/`ASIA…`),
33
- Google API keys (`AIza…`), Slack tokens and webhooks, Stripe
34
- `sk_live_/sk_test_` keys, JWTs, PEM-encoded private keys, and URLs
35
- with embedded `user:password@host` credentials.
36
- 3. **Entropy detector** that flags high-Shannon-entropy substrings near
37
- a secret keyword (api_key/token/secret/password/auth/...). This
38
- catches custom-shaped keys the structural list does not enumerate.
39
-
40
- In `security.mode: warn` matches surface as warnings; in
41
- `security.strict_redaction: true` (or `security.mode: strict`) the same
42
- matches block the write.
43
-
44
- ### Sensitive paths
45
-
46
- When `security.block_sensitive_paths: true` (default), content that
47
- references paths like `.env`, `secrets/`, `.git/`, or `node_modules/`
48
- emits a warning.
49
-
50
- ### Configuration
51
-
52
- ```yaml
53
- security:
54
- mode: warn # 'warn' or 'strict' — affects redaction scanning
55
- strict_redaction: false # if true, blocks entries with sensitive content
56
- block_sensitive_paths: true
57
- token_detection:
58
- enabled: true # turn off all structural + entropy detection
59
- entropy:
60
- enabled: true
61
- min_length: 32 # minimum substring length to consider
62
- min_entropy: 4.0 # minimum Shannon entropy (bits/char)
63
- detectors: # per-detector override map; explicit false disables a detector
64
- aws_access_key: true
65
- jwt: true
66
-
67
- redaction:
68
- enabled: true
69
- patterns:
70
- - '(?i)api[_-]?key'
71
- - '(?i)secret'
72
- - '(?i)token'
73
- - '(?i)password'
74
- ```
75
-
76
- ## Supply-chain pre-install gate
77
-
78
- `brainclaw setup-security` enables a preinstall gate that intercepts
79
- `npm`/`pnpm`/`yarn`/`pip`/`pip3` install commands and asks Socket.dev's
80
- scoring service whether the requested packages are risky.
81
-
82
- ```
83
- brainclaw setup-security --mode advisory # default — warn-only
84
- brainclaw setup-security --mode enforced # block risky installs
85
- ```
86
-
87
- ### Advisory vs enforced
88
-
89
- The mode determines what happens when the gate decides a package is
90
- risky:
91
-
92
- - **advisory** — verdicts are surfaced (printed warning, security trap
93
- created) but the install is *not* aborted.
94
- - **enforced** — a `block` verdict aborts the install with a non-zero
95
- exit code.
96
-
97
- The mode is read from `security.preinstall.mode` and can be overridden
98
- per call with `brainclaw check-security --mode <advisory|enforced>`.
99
-
100
- ### Exit codes
101
-
102
- `brainclaw check-security` emits exit codes that already encode the mode
103
- decision, so wrapper scripts are mode-agnostic:
104
-
105
- | Exit | Meaning |
106
- |------|------------------------------------------------------------|
107
- | 0 | pass — no risky packages |
108
- | 1 | warn — advisory-mode block, or warn-threshold verdict |
109
- | 2 | block — enforced-mode block; the wrapper aborts the install|
110
-
111
- The wrapper scripts (`<.brainclaw/security/bin>/npm`, `pnpm`, `yarn`,
112
- `pip`, `pip3` and their `.ps1` counterparts) call the CLI and react
113
- purely to the exit code, so flipping advisory↔enforced is a config
114
- change — no regeneration required.
115
-
116
- ### Composite scoring
117
-
118
- Each package gets five sub-scores from Socket (supply-chain,
119
- vulnerability, quality, maintenance, license) on a 0–100 scale. The
120
- gate combines them into a single composite using configurable weights:
121
-
122
- ```yaml
123
- security:
124
- preinstall:
125
- weights:
126
- supply_chain: 0.35
127
- vulnerability: 0.30
128
- quality: 0.15
129
- maintenance: 0.15
130
- license: 0.05
131
- thresholds:
132
- composite_pass: 70 # composite >= 70 → pass
133
- composite_warn: 50 # composite >= 50 but < 70 → warn; below → block
134
- supply_chain_block: 30 # hard block when supply_chain < 30
135
- vulnerability_block: 20 # hard block when vulnerability < 20
136
- ```
137
-
138
- Weights are normalized to sum to 1.0 automatically — a config like
139
- `{ supply_chain: 1, vulnerability: 1 }` is rescaled rather than
140
- producing composites above 100. Thresholds are clamped to `[0,100]`
141
- and `composite_warn` is capped at `composite_pass` so the verdict
142
- function stays monotonic.
143
-
144
- ### Allowlist / denylist
145
-
146
- ```yaml
147
- security:
148
- preinstall:
149
- allowlist:
150
- - npm:internal-pkg # ecosystem-scoped
151
- - npm:axios@1.14.0 # exact version pin
152
- - lodash # bare name — any ecosystem, any version
153
- denylist:
154
- - npm:axios@1.14.1 # known-compromised version
155
- - pypi:bad-pkg
156
- ```
157
-
158
- Matching is exact on each component. Bare names match by package name
159
- only; an `ecosystem:` prefix scopes the match to that ecosystem;
160
- appending `@version` (or `==version` for pip-style) requires an exact
161
- version. The wildcard `@*` matches any version (useful for explicit
162
- "any version" entries).
163
-
164
- This is a hard tightening from the MVP: previously `denylist: ['lodash']`
165
- matched any package whose purl contained the substring `lodash`, so
166
- `react-lodash` was silently blocked. The new matcher requires exact
167
- package-name equality.
168
-
169
- ### Package extraction sources
170
-
171
- `check-security` can pull the list of packages from three places, which
172
- may be combined:
173
-
174
- - `--packages axios,express@1.2.3` — comma-separated specs
175
- - `--requirements requirements.txt` — pip-style requirements file;
176
- recursive `-r` includes, env markers, and extras are handled
177
- - `--lockfile package-lock.json` — npm package-lock (v1, v2, v3);
178
- scans top-level direct deps and devDeps
179
-
180
- The wrappers auto-translate `npm install -r foo.txt` → `--requirements`,
181
- skip filesystem paths and URL specs that aren't registry packages
182
- (`./local-pkg`, `git+https://…`, `*.tgz`, `*.whl`), and handle the
183
- common npm/pip flag conventions.
184
-
185
- ### Offline / fetch-error fallback
186
-
187
- When the Socket call fails (network down, service unreachable), the
188
- gate uses `security.preinstall.fallback_on_error`:
189
-
190
- - `block` — fail closed regardless of mode
191
- - `warn` — surface a warning, continue with whatever cached scores
192
- exist; if no cache exists the gate exits with code 1
193
- - `pass` — silent fall-through (the install proceeds)
194
-
195
- Cached scores have a TTL of `cache_ttl_hours` (default 24) and live
196
- in `.brainclaw/security/cache.json`.
197
-
198
- ## Recommended stance
199
-
200
- - do not store secrets — even with detection, the safer move is to never
201
- write them
202
- - review what gets committed
203
- - keep machine-local observations machine-local when appropriate
204
- - use stricter redaction settings in sensitive environments
205
- - run `setup-security --mode advisory` first; flip to `enforced` once
206
- the team has gotten used to the verdicts
207
-
208
- ## Important nuance
209
-
210
- brainclaw reduces hidden behavior, but it does not remove the need for
211
- operational discipline. It warns; the team still decides what belongs
212
- in shared memory.
1
+ # Security
2
+
3
+ brainclaw is designed to be safe by default.
4
+
5
+ ## Security model
6
+
7
+ ### No network access by default
8
+ The CLI does not need to call external services to function. The optional
9
+ supply-chain gate (see below) is the one feature that talks to a remote
10
+ service, and it is off until explicitly enabled.
11
+
12
+ ### No telemetry
13
+ brainclaw does not collect or send usage data.
14
+
15
+ ### No secret management
16
+ brainclaw is not a vault and should not be treated like one.
17
+
18
+ ### Plain-text visibility
19
+ The storage model is intentionally inspectable.
20
+ That makes review easier, but it also means users must be careful about what they write and commit.
21
+
22
+ ## Built-in safety behaviors
23
+
24
+ ### Content scanning (scanText)
25
+
26
+ Whenever content is added to `.brainclaw/` brainclaw scans the text in three
27
+ layers:
28
+
29
+ 1. **User-configured regex patterns** from `redaction.patterns`. The
30
+ defaults catch words like `api_key`, `secret`, `token`, `password`.
31
+ 2. **Structural detectors** for well-known token shapes — GitHub PATs
32
+ (`ghp_`, `gho_`, `github_pat_…`), AWS access keys (`AKIA…`/`ASIA…`),
33
+ Google API keys (`AIza…`), Slack tokens and webhooks, Stripe
34
+ `sk_live_/sk_test_` keys, JWTs, PEM-encoded private keys, and URLs
35
+ with embedded `user:password@host` credentials.
36
+ 3. **Entropy detector** that flags high-Shannon-entropy substrings near
37
+ a secret keyword (api_key/token/secret/password/auth/...). This
38
+ catches custom-shaped keys the structural list does not enumerate.
39
+
40
+ In `security.mode: warn` matches surface as warnings; in
41
+ `security.strict_redaction: true` (or `security.mode: strict`) the same
42
+ matches block the write.
43
+
44
+ ### Sensitive paths
45
+
46
+ When `security.block_sensitive_paths: true` (default), content that
47
+ references paths like `.env`, `secrets/`, `.git/`, or `node_modules/`
48
+ emits a warning.
49
+
50
+ ### Configuration
51
+
52
+ ```yaml
53
+ security:
54
+ mode: warn # 'warn' or 'strict' — affects redaction scanning
55
+ strict_redaction: false # if true, blocks entries with sensitive content
56
+ block_sensitive_paths: true
57
+ token_detection:
58
+ enabled: true # turn off all structural + entropy detection
59
+ entropy:
60
+ enabled: true
61
+ min_length: 32 # minimum substring length to consider
62
+ min_entropy: 4.0 # minimum Shannon entropy (bits/char)
63
+ detectors: # per-detector override map; explicit false disables a detector
64
+ aws_access_key: true
65
+ jwt: true
66
+
67
+ redaction:
68
+ enabled: true
69
+ patterns:
70
+ - '(?i)api[_-]?key'
71
+ - '(?i)secret'
72
+ - '(?i)token'
73
+ - '(?i)password'
74
+ ```
75
+
76
+ ## Supply-chain pre-install gate
77
+
78
+ `brainclaw setup-security` enables a preinstall gate that intercepts
79
+ `npm`/`pnpm`/`yarn`/`pip`/`pip3` install commands and asks Socket.dev's
80
+ scoring service whether the requested packages are risky.
81
+
82
+ ```
83
+ brainclaw setup-security --mode advisory # default — warn-only
84
+ brainclaw setup-security --mode enforced # block risky installs
85
+ ```
86
+
87
+ ### Advisory vs enforced
88
+
89
+ The mode determines what happens when the gate decides a package is
90
+ risky:
91
+
92
+ - **advisory** — verdicts are surfaced (printed warning, security trap
93
+ created) but the install is *not* aborted.
94
+ - **enforced** — a `block` verdict aborts the install with a non-zero
95
+ exit code.
96
+
97
+ The mode is read from `security.preinstall.mode` and can be overridden
98
+ per call with `brainclaw check-security --mode <advisory|enforced>`.
99
+
100
+ ### Exit codes
101
+
102
+ `brainclaw check-security` emits exit codes that already encode the mode
103
+ decision, so wrapper scripts are mode-agnostic:
104
+
105
+ | Exit | Meaning |
106
+ |------|------------------------------------------------------------|
107
+ | 0 | pass — no risky packages |
108
+ | 1 | warn — advisory-mode block, or warn-threshold verdict |
109
+ | 2 | block — enforced-mode block; the wrapper aborts the install|
110
+
111
+ The wrapper scripts (`<.brainclaw/security/bin>/npm`, `pnpm`, `yarn`,
112
+ `pip`, `pip3` and their `.ps1` counterparts) call the CLI and react
113
+ purely to the exit code, so flipping advisory↔enforced is a config
114
+ change — no regeneration required.
115
+
116
+ ### Composite scoring
117
+
118
+ Each package gets five sub-scores from Socket (supply-chain,
119
+ vulnerability, quality, maintenance, license) on a 0–100 scale. The
120
+ gate combines them into a single composite using configurable weights:
121
+
122
+ ```yaml
123
+ security:
124
+ preinstall:
125
+ weights:
126
+ supply_chain: 0.35
127
+ vulnerability: 0.30
128
+ quality: 0.15
129
+ maintenance: 0.15
130
+ license: 0.05
131
+ thresholds:
132
+ composite_pass: 70 # composite >= 70 → pass
133
+ composite_warn: 50 # composite >= 50 but < 70 → warn; below → block
134
+ supply_chain_block: 30 # hard block when supply_chain < 30
135
+ vulnerability_block: 20 # hard block when vulnerability < 20
136
+ ```
137
+
138
+ Weights are normalized to sum to 1.0 automatically — a config like
139
+ `{ supply_chain: 1, vulnerability: 1 }` is rescaled rather than
140
+ producing composites above 100. Thresholds are clamped to `[0,100]`
141
+ and `composite_warn` is capped at `composite_pass` so the verdict
142
+ function stays monotonic.
143
+
144
+ ### Allowlist / denylist
145
+
146
+ ```yaml
147
+ security:
148
+ preinstall:
149
+ allowlist:
150
+ - npm:internal-pkg # ecosystem-scoped
151
+ - npm:axios@1.14.0 # exact version pin
152
+ - lodash # bare name — any ecosystem, any version
153
+ denylist:
154
+ - npm:axios@1.14.1 # known-compromised version
155
+ - pypi:bad-pkg
156
+ ```
157
+
158
+ Matching is exact on each component. Bare names match by package name
159
+ only; an `ecosystem:` prefix scopes the match to that ecosystem;
160
+ appending `@version` (or `==version` for pip-style) requires an exact
161
+ version. The wildcard `@*` matches any version (useful for explicit
162
+ "any version" entries).
163
+
164
+ This is a hard tightening from the MVP: previously `denylist: ['lodash']`
165
+ matched any package whose purl contained the substring `lodash`, so
166
+ `react-lodash` was silently blocked. The new matcher requires exact
167
+ package-name equality.
168
+
169
+ ### Package extraction sources
170
+
171
+ `check-security` can pull the list of packages from three places, which
172
+ may be combined:
173
+
174
+ - `--packages axios,express@1.2.3` — comma-separated specs
175
+ - `--requirements requirements.txt` — pip-style requirements file;
176
+ recursive `-r` includes, env markers, and extras are handled
177
+ - `--lockfile package-lock.json` — npm package-lock (v1, v2, v3);
178
+ scans top-level direct deps and devDeps
179
+
180
+ The wrappers auto-translate `npm install -r foo.txt` → `--requirements`,
181
+ skip filesystem paths and URL specs that aren't registry packages
182
+ (`./local-pkg`, `git+https://…`, `*.tgz`, `*.whl`), and handle the
183
+ common npm/pip flag conventions.
184
+
185
+ ### Offline / fetch-error fallback
186
+
187
+ When the Socket call fails (network down, service unreachable), the
188
+ gate uses `security.preinstall.fallback_on_error`:
189
+
190
+ - `block` — fail closed regardless of mode
191
+ - `warn` — surface a warning, continue with whatever cached scores
192
+ exist; if no cache exists the gate exits with code 1
193
+ - `pass` — silent fall-through (the install proceeds)
194
+
195
+ Cached scores have a TTL of `cache_ttl_hours` (default 24) and live
196
+ in `.brainclaw/security/cache.json`.
197
+
198
+ ## Recommended stance
199
+
200
+ - do not store secrets — even with detection, the safer move is to never
201
+ write them
202
+ - review what gets committed
203
+ - keep machine-local observations machine-local when appropriate
204
+ - use stricter redaction settings in sensitive environments
205
+ - run `setup-security --mode advisory` first; flip to `enforced` once
206
+ the team has gotten used to the verdicts
207
+
208
+ ## Important nuance
209
+
210
+ brainclaw reduces hidden behavior, but it does not remove the need for
211
+ operational discipline. It warns; the team still decides what belongs
212
+ in shared memory.