phocinae-guard 0.1.0__tar.gz

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.
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2026 phocinae-guard authors (Nous Research)
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
@@ -0,0 +1,260 @@
1
+ Metadata-Version: 2.4
2
+ Name: phocinae-guard
3
+ Version: 0.1.0
4
+ Summary: Phocinae command approval gate for AI harnesses (L0 whitelist/blacklist)
5
+ License: Apache-2.0
6
+ Requires-Python: >=3.9
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Dynamic: license-file
10
+
11
+ # phocinae-guard · L0 内核
12
+
13
+ **斑海豹(phocinae)命令行审批门 L0 内核**:一条 shell 命令进来,判定出去
14
+ (`allow` / `deny` / `ask` + exit code)。面向 Claude Code / Cline / Codex CLI /
15
+ Crush / dsh / Gemini CLI / Qwen Code / Kimi Code / OpenHands / Hermes 的 hook /
16
+ 包装通用形态;本次交付为通用 CLI 形态(stdin 或 `--command`)。
17
+
18
+ ## 定位
19
+
20
+ - 审批门而非沙箱:只做「放行 / 拒绝 / 需人工确认」判定,不承诺隔离执行环境。
21
+ - 单文件 `guard.py`,Python ≥ 3.8,**零第三方依赖**(纯标准库),可直接塞进任何 hook 管道。
22
+ - L0 确定性表独立存活:服务器挂了也能守住黑白名单底线。
23
+
24
+ ## 架构(三层)
25
+
26
+ ```
27
+ 命令 → 归一化
28
+ ├─ L0 确定性表(纯离线):白名单精确/前缀 → allow
29
+ │ 黑名单危险正则 → deny(先于白名单判定)
30
+ ├─ L1 /v1/systemone 两问:noul「是否放行」+ score「风险层 2–10」(默认关闭,见下)
31
+ │ 阈值映射(通道合成取最严格):
32
+ │ risk≥7 或 noul=false(≤0.35) → deny
33
+ │ risk 4–6 或 noul 摇摆 → ask(hook 阻塞态,可 --confirm)
34
+ │ 其余(risk<4 且 noul=true) → allow
35
+ └─ 服务器不可用 → fail-closed:除白名单外一律 deny/ask(默认 deny,可配 ask)
36
+
37
+ 不变式:只有 allow 类能过门(exit 0);deny/ask 均非零退出;
38
+ --confirm 只能把 ask 升级为 allow,永远不能覆盖 deny。
39
+ ```
40
+
41
+ 判定矩阵(noul 阈值 0.65 / ask≥4 / deny≥7,均可配):
42
+
43
+ | risk | noul=false | noul 摇摆 | noul=true |
44
+ |------|-----------|----------|-----------|
45
+ | ≥7 | deny | deny | deny |
46
+ | 4–6 | deny | ask | ask |
47
+ | <4 | deny | ask | allow |
48
+
49
+ ## L0 表内容概要(`l0_table.json`,24 条黑名单正则)
50
+
51
+ | 类 | 覆盖 |
52
+ |----|------|
53
+ | 危险删除 | `rm -rf /`、`/*`、`~`、`$HOME`、`/etc` `/usr` `/var` `/boot` `/bin` `/sbin` `/lib` `/opt` `/root`、`rm -rf .`/`..` |
54
+ | sudo 破坏 | `sudo rm/dd/mkfs/fdisk/sfdisk/parted/wipefs/shutdown/reboot/poweroff/halt` |
55
+ | 下载即执行 | `curl\|sh`、`wget\|bash`、任意管道喂 shell、`sh -c 'curl…'`、`eval $(curl)`、`source <(curl)` |
56
+ | git 破坏 | `push --force`/`-f`、`push --delete`(`--force-with-lease` 有意放行到 L1 由模型裁决) |
57
+ | find/xargs 删除 | `find / -delete`、`find /usr… -delete`、`find -exec rm`、`xargs rm` |
58
+ | 块设备 | `dd of=/dev/sd*/hd*/vd*/nvme*/mmcblk*/dm-*/md*/loop*/disk`、`mkfs.*` |
59
+ | 权限/属主 | `chmod [-R] 777`、`chown … /系统路径` |
60
+ | 其他 | fork bomb(`:(){ :\|:& };:`、`%0\|%0`)、`shutdown/reboot/poweroff/halt`、`crontab -r`、`> /etc…` 重定向覆写、`mv` 进系统路径 |
61
+
62
+ 白名单:`ls`/`pwd`/`git status|diff|log|show|fetch|branch|tag` 等只读命令(精确+前缀两档),
63
+ 服务器不可用时这些命令仍可离线放行。
64
+
65
+ ## 目录结构
66
+
67
+ ```
68
+ phocinae-guard/
69
+ ├── guard.py # 单文件审批门(纯标准库)
70
+ ├── l0_table.json # L0 确定性表(白名单+黑名单正则)
71
+ ├── guard.conf.example.json# 配置文件示例
72
+ ├── mock_server.py # 本地测试 mock(POST /v1/systemone 固定 noul/score)
73
+ ├── mock_rules.json # mock 按命令区分的规则(灰带命令用)
74
+ ├── test_guard.py # 验收测试(replay battery + 全链路)
75
+ ├── .claude-plugin/ # Claude Code 插件(本地成品;市场提交为后续迭代)
76
+ │ ├── plugin.json # 插件 manifest(name/version/description/author/hooks 声明)
77
+ │ ├── hooks/
78
+ │ │ ├── hooks.json # PreToolUse(Bash) command 型 hook 配置
79
+ │ │ └── guard_hook.py # hook 本体:Claude Code JSON 协议 ↔ guard.py 裁决
80
+ │ ├── skills/
81
+ │ │ └── phocinae-guard/SKILL.md # 「审批门」技能说明(应对守则+自查清单)
82
+ │ └── scripts/
83
+ │ └── self_test.sh # 插件自测(hook 链路 + exit code 断言)
84
+ ├── README.md
85
+ └── LICENSE # Apache-2.0
86
+ ```
87
+
88
+ ## 安装
89
+
90
+ ```bash
91
+ mkdir -p /opt/phocinae-guard
92
+ cp guard.py l0_table.json /opt/phocinae-guard/
93
+ # 可选:全局配置文件(路径、阈值、L0 表路径都在这里改)
94
+ cp guard.conf.example.json /etc/phocinae-guard.conf.json
95
+ ```
96
+
97
+ 依赖:仅 Python ≥ 3.8。L1 判定需要一个 `/v1/systemone` 服务(phocinae-server P0
98
+ 扁平协议,或测试用 mock_server.py)。**P0 口径:L1 默认关闭(`l1_enabled=false`)**——
99
+ 当前 150M 权重未经命令审批域校准(2026-10-08 联合实测:对灰区命令的 noul/score
100
+ 信号≈噪声),灰区命令走 fail-closed(deny/ask)。领域微调 + 标定电池完成后(P1)
101
+ 再开 `PHOCINAE_GUARD_L1_ENABLED=1`。不装服务也可用——L1 关闭时灰区自动进入
102
+ fail-closed。
103
+
104
+ ## 用法
105
+
106
+ ```bash
107
+ # stdin 收命令
108
+ echo "rm -rf /" | guard.py # exit 1,deny
109
+ # 或显式传
110
+ guard.py --command "git status" # exit 0,allow
111
+ guard.py --command "npm install -g x" # exit 2,ask(需人工确认)
112
+ guard.py --command "npm install -g x" --confirm # 人工确认后 exit 0
113
+ ```
114
+
115
+ exit code:`0`=allow(可执行)· `1`=deny(拒绝)· `2`=ask(阻塞待人工,hook 输出阻塞态)·
116
+ `3`=用法/配置错误。stdout 默认一行 JSON(含 `decision`/`layer`/`reason`/`noul`/`score`/
117
+ `thresholds`/`exit`),`--text` 换人读格式。审计 JSONL(ts+command+cwd+decision+依据层+原因)
118
+ 默认追加到 `./phocinae-guard.audit.jsonl`,`--audit off` 或 env 置 `off` 可禁用。
119
+
120
+ ## 集成示例
121
+
122
+ **通用 bash 包装**(Claude Code / Cline / Crush / dsh 等都可用):
123
+
124
+ ```bash
125
+ #!/usr/bin/env bash
126
+ # guard-wrap.sh:先过门再执行
127
+ out=$(/opt/phocinae-guard/guard.py --command "$1")
128
+ case $? in
129
+ 0) shift; exec "$@" ;; # allow → 执行
130
+ 1) echo "[guard] DENY: $out" >&2; exit 1 ;; # deny → 拦截
131
+ 2) echo "[guard] ASK: $out" >&2; exit 2 ;; # ask → 阻塞待人工
132
+ *) echo "[guard] ERROR" >&2; exit 3 ;;
133
+ esac
134
+ ```
135
+
136
+ **Claude Code PreToolUse hook**(`settings.json`):
137
+
138
+ ```json
139
+ {"hooks": {"PreToolUse": [{"matcher": "Bash", "hooks": [
140
+ {"type": "command",
141
+ "command": "jq -r .tool_input.command | /opt/phocinae-guard/guard.py"}]}]}}
142
+ ```
143
+
144
+ hook 收到的 stdin JSON 里取命令后喂给 guard:exit 0 放行;exit 2 输出
145
+ `decision=ask` 给前端做人工确认(确认后带 `--confirm` 重跑);exit 1 直接阻断。
146
+ 其余工具同理:Codex CLI / Gemini CLI 用 `sandbox_command_wrapper`/`command wrapper`,
147
+ OpenHands / Hermes 用 PreToolUse 类 hook——凡是能「拦命令、看 exit code」的位置都能挂。
148
+
149
+ ## Claude Code 插件(.claude-plugin/)
150
+
151
+ 本地成品形态:一个 Claude Code 插件目录——`PreToolUse(Bash)` 拦截每一次 shell
152
+ 命令,交给 guard.py 裁决,再把结果翻译成 Claude Code hook JSON 协议
153
+ (`permissionDecision: allow/deny/ask` + 可执行理由)。**本次仅本地成品,不发布;
154
+ claude-community 市场提交为后续迭代。**
155
+
156
+ ### 插件结构
157
+
158
+ - `.claude-plugin/plugin.json`:manifest(name/version/description/author +
159
+ `hooks`/`skills` 组件声明,Apache-2.0);
160
+ - `.claude-plugin/hooks/hooks.json`:`PreToolUse` → matcher `Bash` → command 型
161
+ hook `python3 "${CLAUDE_PLUGIN_ROOT}/.claude-plugin/hooks/guard_hook.py"`
162
+ (timeout 30s,远低于默认 60s 上限);
163
+ - `.claude-plugin/hooks/guard_hook.py`:协议适配器(纯标准库)——stdin 收
164
+ PreToolUse 事件 JSON,取 `tool_input.command` 调 guard.py,按 exit code 映射:
165
+ `0/allow → hook exit 0 + allow`(跳过权限弹窗)、`1/deny → hook exit 2 + deny`、
166
+ `2/ask → hook exit 2 + ask`(auto 模式下 ask 也强制弹窗);guard.py 出错/超时 →
167
+ 无输出、exit 0,落入正常权限流(fail-closed,**绝不自动 allow**)。
168
+ **传参逐项对齐**:只显式传 `--command` / `--cwd`,不覆盖服务地址参数,沿用
169
+ guard.py 内置默认 `http://127.0.0.1:8155`;阈值/fail-closed/L1 开关/审计路径
170
+ 等经环境变量透传(见「配置」节)。审计默认落 `~/.phocinae-guard/audit.jsonl`
171
+ (避免散落到各项目目录),`PHOCINAE_GUARD_AUDIT=off` 禁用;
172
+ - `.claude-plugin/skills/phocinae-guard/SKILL.md`:教 Claude 理解裁决、被 deny 后
173
+ 改方案而非原样重试、危险命令自查清单。
174
+
175
+ ### 安装
176
+
177
+ ```bash
178
+ # 本地开发/验证:claude --plugin-dir 直接挂本仓(团队分发走插件市场,后续迭代)
179
+ claude --plugin-dir /home/hermes/dev/phocinae-guard
180
+ ```
181
+
182
+ 依赖:`python3` ≥ 3.8 在 PATH(hook 与 guard.py 均零第三方包)。不装插件时,可把
183
+ 上文「集成示例」里的 settings.json hook 片段直接贴进 `.claude/settings.json`,
184
+ 效果等同(插件只是把这个片段打包成一键安装)。
185
+
186
+ ### 自测
187
+
188
+ ```bash
189
+ bash .claude-plugin/scripts/self_test.sh
190
+ ```
191
+
192
+ 纯本地、纯 CPU(不起真实模型服务):两份 JSON 可解析+结构断言 → 服务地址对齐
193
+ 断言(guard 内置默认 127.0.0.1:8155、hook 不覆盖)→ guard 直连(良性 exit 0 /
194
+ 危险 exit 1 / 灰区 fail-closed)→ hook 链路(良性 exit 0+allow、危险 exit 2+deny、
195
+ 灰区 exit 2+deny)→ L1 端到端(本地 mock 起在 8155 验证默认 server 对齐与阈值
196
+ 映射,8155 被占则 SKIP)→ 审计 JSONL 校验。退出码 0 = 全绿。
197
+
198
+ ### 行为要点
199
+
200
+ - 默认只有 L0 表在跑(`l1_enabled=false`):白名单放行、黑名单 deny、其余灰区
201
+ fail-closed=deny——**装上即最严格**。体验过严时设 `PHOCINAE_GUARD_FAIL_CLOSED=ask`
202
+ 放宽为人工确认档;L1 模型经命令审批域校准后再开 `PHOCINAE_GUARD_L1_ENABLED=1`。
203
+ - deny 在任何权限模式下都生效(含 bypass/yolo 模式),`--confirm` 也无法覆盖;
204
+ 被 deny 后 Claude 应依据理由改方案而不是重试同款。
205
+ - 门只管 Bash 工具调用;Write/Edit/MCP 工具不受此 hook 约束(后续迭代可扩 matcher)。
206
+
207
+ ## 配置
208
+
209
+ 优先级:命令行 > 环境变量 > 配置文件 > 内置默认。
210
+
211
+ | env | 默认 | 说明 |
212
+ |-----|------|------|
213
+ | `PHOCINAE_GUARD_SERVER` | `http://127.0.0.1:8155` | L1 服务基地址(自动拼 `/v1/systemone`) |
214
+ | `PHOCINAE_GUARD_TIMEOUT` | `2.0` | L1 请求超时(秒) |
215
+ | `PHOCINAE_GUARD_NOUL_THRESHOLD` | `0.65` | noul 放行阈值 |
216
+ | `PHOCINAE_GUARD_DENY_AT` | `7.0` | score ≥ 此值 → deny |
217
+ | `PHOCINAE_GUARD_ASK_AT` | `4.0` | score ≥ 此值且 < deny → ask |
218
+ | `PHOCINAE_GUARD_TABLE` | 同目录 `l0_table.json` | L0 表路径 |
219
+ | `PHOCINAE_GUARD_AUDIT` | `./phocinae-guard.audit.jsonl` | 审计路径(`off` 禁用) |
220
+ | `PHOCINAE_GUARD_FAIL_CLOSED` | `deny` | 服务器不可用兜底:`deny`/`ask` |
221
+ | `PHOCINAE_GUARD_CONFIG` | 无 | 配置文件路径(JSON,见 `guard.conf.example.json`) |
222
+
223
+ 对应命令行参数:`--server/--timeout/--noul-threshold/--deny-at/--ask-at/--table/--audit/--fail-closed/--config`。
224
+ L0 表自定义:JSON 的 `whitelist`/`whitelist_prefix`/`blacklist` 三节各自覆盖内置默认节;
225
+ `blacklist` 条目形如 `[名称, 正则, 说明]`。
226
+
227
+ ## 测试与验收
228
+
229
+ ```bash
230
+ python3 mock_server.py --port 8155 --rules mock_rules.json & # 本地 mock
231
+ python3 test_guard.py -v # 验收套件
232
+ ```
233
+
234
+ replay battery:**15 条良性**(ls/git status/pytest/npm test/echo/…)、**24 条危险**
235
+ (rm -rf /、curl|sh、sudo rm、git push --force、find -delete、dd、mkfs、fork bomb、
236
+ chmod -R 777、shutdown、crontab -r、重定向覆写 /etc 等)、**4 条灰带**
237
+ (npm install -g→ask、pip install→allow、curl 仅下载→allow、push --force-with-lease→ask)。
238
+
239
+ 验收实测(2026-10-08):危险误放行 **0/24**,良性误拒 **0/15**(门槛 ≤1),
240
+ L1 阈值映射 8 档全过(含边界 noul=0.65、score=4.0),服务器不可用 → fail-closed
241
+ 行为正确(白名单离线放行、黑名单离线 deny、灰区 deny/ask 可配),审计 JSONL 落盘齐全,
242
+ 自定义 L0 表与阈值 env 覆盖生效。测试全程只用本地 mock,不触碰任何真实服务。
243
+
244
+ ## 安全声明
245
+
246
+ - **L0 正则表是确定性启发式,不是完备防护**:换行/字符串拼接/多阶段下载再执行/base64
247
+ 混淆等手法可绕过正则;它负责「宁严勿松」的第一道确定性拦截,不是安全的全部。
248
+ - **L1 判定依赖服务与模型质量**:noul/score 是模型输出,阈值映射只是把模型意见翻译成
249
+ 门禁动作;服务不可用默认 fail-closed=deny(最严),可用 `PHOCINAE_GUARD_FAIL_CLOSED=ask`
250
+ 放宽为人工确认档。
251
+ - **不变式**:只有 allow 类能过门;`--confirm` 只升级 ask,deny 永不可覆盖。
252
+ - **审计是事后追责材料**:JSONL 记录了时间戳+命令+cwd+判定+依据层,请定期复核;
253
+ 审计写失败不阻断判定(宁可漏记不误杀),但会向 stderr 报错。
254
+ - **生产建议**:关键路径配容器/权限/网络隔离;guard 是审批门,不是沙箱。
255
+ - 已知局限:多行脚本整体喂入时判定按整段文本归一匹配;`--force-with-lease`、
256
+ 普通 `find -delete`(非根/系统路径)等有意留给 L1 裁决,L0 不覆盖所有变体。
257
+
258
+ ## License
259
+
260
+ Apache License 2.0 —— 见 `LICENSE`。版权 2026 phocinae-guard 作者(Nous Research)。