feihong-code 0.2.3 → 0.6.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 (180) hide show
  1. package/.github/FUNDING.yml +4 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +37 -37
  3. package/.github/ISSUE_TEMPLATE/config.yml +14 -14
  4. package/.github/ISSUE_TEMPLATE/feature_request.md +28 -28
  5. package/.github/PULL_REQUEST_TEMPLATE.md +46 -46
  6. package/.github/SECURITY.md +67 -67
  7. package/.github/dependabot.yml +16 -0
  8. package/.github/workflows/ci.yml +1 -1
  9. package/AGENT-GUIDE.md +382 -237
  10. package/CHANGELOG.md +392 -0
  11. package/CODE_OF_CONDUCT.md +56 -56
  12. package/CONTRIBUTING.md +68 -68
  13. package/LICENSE +22 -22
  14. package/README.md +586 -522
  15. package/README.self-evolve.md +274 -0
  16. package/dist/agent/code-review.js +2 -0
  17. package/dist/agent/code-review.js.map +1 -1
  18. package/dist/agent/code-writer.js +74 -18
  19. package/dist/agent/code-writer.js.map +1 -1
  20. package/dist/agent/context-compactor.js +13 -4
  21. package/dist/agent/context-compactor.js.map +1 -1
  22. package/dist/agent/experience.js +319 -84
  23. package/dist/agent/experience.js.map +1 -1
  24. package/dist/agent/orchestrator.js +233 -71
  25. package/dist/agent/orchestrator.js.map +1 -1
  26. package/dist/agent/planner.js +30 -7
  27. package/dist/agent/planner.js.map +1 -1
  28. package/dist/agent/prompts.js +9 -0
  29. package/dist/agent/prompts.js.map +1 -1
  30. package/dist/agent/quality-gate.js +10 -4
  31. package/dist/agent/quality-gate.js.map +1 -1
  32. package/dist/agent/repo-context.js +181 -0
  33. package/dist/agent/repo-context.js.map +1 -0
  34. package/dist/agent/repo-reader.js +92 -99
  35. package/dist/agent/repo-reader.js.map +1 -1
  36. package/dist/agent/self-heal.js +80 -60
  37. package/dist/agent/self-heal.js.map +1 -1
  38. package/dist/agent/self-improver.js +65 -61
  39. package/dist/agent/self-improver.js.map +1 -1
  40. package/dist/agent/subagent-summary.js +31 -0
  41. package/dist/agent/subagent-summary.js.map +1 -0
  42. package/dist/agent/subagent.js +52 -2
  43. package/dist/agent/subagent.js.map +1 -1
  44. package/dist/agent/symbol-index.js +160 -0
  45. package/dist/agent/symbol-index.js.map +1 -0
  46. package/dist/agent/team.js +193 -0
  47. package/dist/agent/team.js.map +1 -0
  48. package/dist/cli/commands.js +124 -143
  49. package/dist/cli/commands.js.map +1 -1
  50. package/dist/cli/index.js +113 -106
  51. package/dist/cli/index.js.map +1 -1
  52. package/dist/cli/repl.js +82 -7
  53. package/dist/cli/repl.js.map +1 -1
  54. package/dist/cli/run.js +600 -95
  55. package/dist/cli/run.js.map +1 -1
  56. package/dist/cli/tui.js +145 -0
  57. package/dist/cli/tui.js.map +1 -0
  58. package/dist/cli/version.js +1 -1
  59. package/dist/enterprise/audit.js +145 -23
  60. package/dist/enterprise/audit.js.map +1 -1
  61. package/dist/enterprise/index.js +14 -11
  62. package/dist/enterprise/index.js.map +1 -1
  63. package/dist/enterprise/policy.js +22 -10
  64. package/dist/enterprise/policy.js.map +1 -1
  65. package/dist/harness/executor.js +127 -0
  66. package/dist/harness/executor.js.map +1 -0
  67. package/dist/harness/harness.js +87 -0
  68. package/dist/harness/harness.js.map +1 -0
  69. package/dist/harness/index.js +31 -0
  70. package/dist/harness/index.js.map +1 -0
  71. package/dist/harness/loader.js +138 -0
  72. package/dist/harness/loader.js.map +1 -0
  73. package/dist/harness/reporter.js +34 -0
  74. package/dist/harness/reporter.js.map +1 -0
  75. package/dist/harness/types.js +10 -0
  76. package/dist/harness/types.js.map +1 -0
  77. package/dist/harness/verifier.js +48 -0
  78. package/dist/harness/verifier.js.map +1 -0
  79. package/dist/hello.js +14 -0
  80. package/dist/hello.js.map +1 -0
  81. package/dist/memory/auto-summarize.js +208 -0
  82. package/dist/memory/auto-summarize.js.map +1 -0
  83. package/dist/memory/index.js +228 -0
  84. package/dist/memory/index.js.map +1 -0
  85. package/dist/models/model-router.js +100 -27
  86. package/dist/models/model-router.js.map +1 -1
  87. package/dist/models/model.dto.js +25 -3
  88. package/dist/models/model.dto.js.map +1 -1
  89. package/dist/models/providers/ollama.provider.js +12 -0
  90. package/dist/models/providers/ollama.provider.js.map +1 -1
  91. package/dist/models/providers/openai-compatible.provider.js +14 -1
  92. package/dist/models/providers/openai-compatible.provider.js.map +1 -1
  93. package/dist/plugins/plugin-loader.js +179 -0
  94. package/dist/plugins/plugin-loader.js.map +1 -0
  95. package/dist/runtime/event-log.js.map +1 -1
  96. package/dist/runtime/hooks.js +80 -0
  97. package/dist/runtime/hooks.js.map +1 -0
  98. package/dist/self-evolve/hook.js +60 -0
  99. package/dist/self-evolve/hook.js.map +1 -0
  100. package/dist/self-evolve/hook.ts +80 -0
  101. package/dist/self-evolve/manager.d.ts +8 -0
  102. package/dist/self-evolve/manager.js +401 -0
  103. package/dist/shared/config.js +35 -3
  104. package/dist/shared/config.js.map +1 -1
  105. package/dist/shared/errors.js +6 -2
  106. package/dist/shared/errors.js.map +1 -1
  107. package/dist/shared/i18n.js +535 -0
  108. package/dist/shared/i18n.js.map +1 -0
  109. package/dist/shared/secure-store.js +117 -0
  110. package/dist/shared/secure-store.js.map +1 -0
  111. package/dist/skills/grill.js +2 -1
  112. package/dist/skills/grill.js.map +1 -1
  113. package/dist/skills/self-heal.js +73 -0
  114. package/dist/skills/self-heal.js.map +1 -0
  115. package/dist/skills/skill-loader.js +131 -0
  116. package/dist/skills/skill-loader.js.map +1 -0
  117. package/dist/skills/skill-market.js +195 -0
  118. package/dist/skills/skill-market.js.map +1 -0
  119. package/dist/tools/analysis/code-analyzer.js +45 -18
  120. package/dist/tools/analysis/code-analyzer.js.map +1 -1
  121. package/dist/tools/index.js +5 -0
  122. package/dist/tools/index.js.map +1 -1
  123. package/dist/tools/mcp/index.js +84 -0
  124. package/dist/tools/mcp/index.js.map +1 -0
  125. package/dist/tools/mcp/mcp-client.js +194 -0
  126. package/dist/tools/mcp/mcp-client.js.map +1 -0
  127. package/dist/tools/sandbox.js +126 -0
  128. package/dist/tools/sandbox.js.map +1 -0
  129. package/dist/tools/shell/exec.js +72 -3
  130. package/dist/tools/shell/exec.js.map +1 -1
  131. package/dist/tools/shell/run-shell.tool.js +37 -7
  132. package/dist/tools/shell/run-shell.tool.js.map +1 -1
  133. package/dist/tools/skills/load-skill.tool.js +36 -0
  134. package/dist/tools/skills/load-skill.tool.js.map +1 -0
  135. package/dist/tools/tool.interface.js.map +1 -1
  136. package/dist/tools/tool.registry.js +69 -1
  137. package/dist/tools/tool.registry.js.map +1 -1
  138. package/dist/tools/web/web.tool.js +139 -0
  139. package/dist/tools/web/web.tool.js.map +1 -0
  140. package/dist/web/auth.js +178 -3
  141. package/dist/web/auth.js.map +1 -1
  142. package/dist/web/channels.js +171 -0
  143. package/dist/web/channels.js.map +1 -0
  144. package/dist/web/public/css/style.css +1546 -0
  145. package/dist/web/public/index.html +804 -37
  146. package/dist/web/public/js/api.js +309 -0
  147. package/dist/web/public/js/app.js +1472 -0
  148. package/dist/web/public/js/ui.js +832 -0
  149. package/dist/web/public/js/utils.js +170 -0
  150. package/dist/web/server.js +937 -11
  151. package/dist/web/server.js.map +1 -1
  152. package/dist/web/task-queue.js +470 -0
  153. package/dist/web/task-queue.js.map +1 -0
  154. package/dist/web/web-config.js +143 -0
  155. package/dist/web/web-config.js.map +1 -0
  156. package/docs/App/344/275/277/347/224/250/350/257/264/346/230/216/344/271/246.md +299 -0
  157. package/docs/App/346/212/200/346/234/257/350/257/264/346/230/216/344/271/246.md +554 -0
  158. package/docs/Deployment_Guide_EN.md +288 -0
  159. package/docs/SELF-EVOLVE-GUIDE.md +313 -0
  160. package/docs/Technical_Manual_EN.md +216 -0
  161. package/docs/User_Manual_EN.md +314 -0
  162. package/docs/error-codes.md +198 -0
  163. package/docs/screenshots/cli-demo.png +0 -0
  164. package/docs/screenshots/feature-comparison.png +0 -0
  165. package/docs/screenshots/web-console.png +0 -0
  166. package/docs/self-evolve-implementation.md +165 -0
  167. package/docs/self-evolve.md +166 -0
  168. package/docs//344/272/247/345/223/201/345/274/200/345/217/221/346/226/207/346/241/243.md +614 -614
  169. package/docs//344/274/201/344/270/232/351/203/250/347/275/262/344/270/216/345/220/210/350/247/204.md +267 -267
  170. package/docs//344/275/277/347/224/250/350/257/264/346/230/216/344/271/246.md +318 -358
  171. package/docs//345/270/270/350/247/201/351/227/256/351/242/230/344/270/216/346/225/205/351/232/234/346/216/222/346/237/245.md +130 -130
  172. package/docs//346/212/200/346/234/257/350/257/264/346/230/216/344/271/246.md +216 -303
  173. package/docs//346/236/266/346/236/204/344/270/216API.md +238 -238
  174. package/docs//347/224/250/346/210/267/346/211/213/345/206/214.md +196 -196
  175. package/docs//351/203/250/347/275/262/346/214/207/345/215/227.md +165 -165
  176. package/docs//351/203/250/347/275/262/350/257/264/346/230/216/344/271/246.md +288 -0
  177. package/docs//351/205/215/347/275/256/345/217/202/350/200/203.md +127 -127
  178. package/docs//351/241/265/351/235/242/345/212/237/350/203/275/345/244/215/347/233/230/344/270/216/345/206/222/347/203/237/346/265/213/350/257/225/346/212/245/345/221/212.html +117 -0
  179. package/package.json +108 -109
  180. package/tool-schema.json +117 -46
@@ -1,267 +1,267 @@
1
- # 飞虹 Code — 企业部署与合规指南(M4)
2
-
3
- > 晋江市飞虹智科技企业管理有限公司 · 飞扬企源研发中心 · 负责人:吴赐虹
4
-
5
- 本文面向**企业管理员 / 平台工程 / 安全合规**角色,说明如何把飞虹 Code 以受控方式部署到团队、部门乃至多客户(多租户)环境中。
6
-
7
- ---
8
-
9
- ## 一、能力总览
10
-
11
- | 维度 | 能力 | 关键命令 |
12
- | --- | --- | --- |
13
- | 身份 | 租户 / 用户 / 角色由环境注入,容器与网关友好 | `fhcode whoami` |
14
- | 权限 | RBAC 角色矩阵 + deny 优先黑名单 + 沙箱越界拦截 | `fhcode policy` |
15
- | 审计 | sha256 哈希链、脱敏、按月切分、可验证 | `fhcode audit` / `fhcode audit verify` |
16
- | 隔离 | 会话 / 审计 / 目标物理分目录 | `fhcode tenants` |
17
- | 成本 | 单任务熔断 + 租户日预算 fail-fast | `FH_TENANT_BUDGET_USD` |
18
- | 交付 | 三条全离线 CI 流水线 + 发布包白名单 | `npm run verify` |
19
-
20
- 企业模式默认开启。若需退回社区版行为(无租户、无审计链、无 RBAC):`FH_ENTERPRISE=false`。
21
-
22
- ---
23
-
24
- ## 二、身份模型
25
-
26
- ```bash
27
- export FH_TENANT=acme # 租户 ID:^[A-Za-z0-9._-]{1,64}$
28
- export FH_USER=wuchihong # 用户标识,写入审计 actor
29
- export FH_ROLE=developer # viewer | developer | operator | admin
30
- ```
31
-
32
- - 三者均可由**容器编排 / SSO 网关 / CI Runner** 注入,CLI 自身不做认证——认证是上游职责,飞虹 Code 只负责**授权与留痕**。
33
- - `FH_TENANT` 非法(含 `../`、超长、特殊字符)时启动即报 `TENANT_ID_INVALID`,杜绝路径穿越。
34
- - `FH_ROLE` 非法值直接报 `ROLE_INVALID`,不做"降级容错"——权限问题不允许猜。
35
-
36
- ### 推荐角色分配
37
-
38
- | 场景 | 角色 | 理由 |
39
- | --- | --- | --- |
40
- | 代码审查 / 只读排障 | `viewer` | 仅能读取与检索,任何写入都被拒 |
41
- | 日常研发 | `developer` | 可写代码与跑测试,shell 需审批 |
42
- | 值班 / 运维处置 | `operator` | 全工具可用,shell 仍需审批,成本上限 $5 |
43
- | 平台管理员 | `admin` | 无成本上限,但**危险命令与敏感路径依旧拒绝** |
44
-
45
- ---
46
-
47
- ## 三、权限策略
48
-
49
- ### 3.1 判定顺序(deny 优先)
50
-
51
- ```
52
- 1) 危险 shell 命令黑名单 → deny(admin 也拦)
53
- 2) 敏感路径黑名单 → deny
54
- 3) 沙箱越界(逃出 cwd) → deny
55
- 4) 角色-工具矩阵 → deny / approval / allow
56
- 5) shell 白名单 → allow(否则 approval)
57
- ```
58
-
59
- 前三条是**硬底线**,不受角色影响,也不能被人工审批放行——批准了也不执行。
60
-
61
- ### 3.2 内置黑名单
62
-
63
- - **危险命令(23 条)**:`rm -rf /`、`rm -rf ~`、`mkfs`、`dd if=`、fork 炸弹 `:(){`、`shutdown`、`reboot`、`format `、`del /s`、`rd /s`、`chown -R root`、`curl | sh`、`wget | sh`、`iptables -F`、`reg delete`、`history -c`、`shred ` 等。
64
- - **敏感路径(11 类)**:`.env`、`.git/config`、`.git/hooks`、`.npmrc`、`.ssh`、`id_rsa`、`id_ed25519`、`credentials`、`.aws`、`.kube/config`、`shadow`。
65
-
66
- ### 3.3 策略覆盖(只能加严)
67
-
68
- 优先级从低到高:
69
-
70
- ```
71
- DEFAULT_POLICY
72
- → <FH_HOME>/policy.json 全局策略
73
- → <FH_HOME>/tenants/<租户>/policy.json 租户策略
74
- → FH_POLICY 内联 JSON 临时覆盖(CI / 调试)
75
- ```
76
-
77
- **黑名单取并集**——下级配置只能新增禁止项,无法删除上级的禁止项。这条设计确保"租户自定义策略"永远不能成为提权通道。
78
-
79
- `policy.json` 示例:
80
-
81
- ```json
82
- {
83
- "roles": {
84
- "developer": { "maxCostUsd": 0.25, "approvalTools": ["run_shell", "write_file"] }
85
- },
86
- "denyShell": ["npm publish", "docker push", "kubectl delete"],
87
- "denyPaths": ["config/secrets", "deploy/prod"],
88
- "tenantDailyBudgetUsd": 20
89
- }
90
- ```
91
-
92
- ### 3.4 审批通道
93
-
94
- | 环境 | 行为 |
95
- | --- | --- |
96
- | TTY 交互终端 | 逐条弹出 `y/n`,用户显式批准才执行 |
97
- | 非交互(CI / 管道 / 守护进程) | 回退白名单审批器:命中 `FH_SHELL_ALLOW` 自动通过,其余拒绝并留痕 |
98
-
99
- > **守卫是唯一权威闸门**:策略判定、审批、审计在工具执行前一次性完成,工具层不会二次弹审批,杜绝重复询问与决策打架。
100
-
101
- ---
102
-
103
- ## 四、审计与取证
104
-
105
- ### 4.1 存储
106
-
107
- ```
108
- <FH_HOME>/tenants/<租户>/audit/audit-YYYY-MM.jsonl
109
- ```
110
-
111
- append-only、按月切分、同步写入(不缓冲,进程崩溃不丢记录)。
112
-
113
- ### 4.2 记录结构
114
-
115
- ```json
116
- {
117
- "seq": 2,
118
- "ts": "2026-08-10T06:41:43.118Z",
119
- "tenantId": "acme",
120
- "userId": "wuchihong",
121
- "role": "developer",
122
- "runId": "2d1e3188-...",
123
- "action": "tool:write_file",
124
- "resource": "demo-output.txt",
125
- "decision": "allow",
126
- "reason": "rbac.allow — 角色 developer 允许调用 write_file",
127
- "prevHash": "…",
128
- "hash": "…"
129
- }
130
- ```
131
-
132
- `decision` 取值:`allow` / `deny` / `approved`(人工批准)/ `rejected`(人工拒绝或无审批通道)/ `info`(会话起止等)。
133
-
134
- 覆盖动作:`session:start`、`session:end`、`session:rollback`、`skill:goal`、`quota:block`、`tool:<工具名>`。
135
-
136
- ### 4.3 防篡改验证
137
-
138
- ```bash
139
- fhcode audit verify
140
- ```
141
-
142
- 链式校验三件事:**seq 连续**(防删除/插入)、**prevHash 衔接**(防重排)、**hash 自洽**(防内容改写)。任一失败会定位到具体条目:
143
-
144
- ```
145
- ❌ 审计链校验失败:共 5 条,断点在第 3 条
146
- 记录内容被篡改:hash 不自洽(期望 8b3a6990664e…)
147
- ```
148
-
149
- 退出码为 `2`,可直接接入监控告警:
150
-
151
- ```bash
152
- fhcode audit verify || alertmanager-cli fire --name fhcode-audit-tampered
153
- ```
154
-
155
- ### 4.4 脱敏
156
-
157
- `resource` / `reason` 写入前统一脱敏:`apiKey=` / `secret=` / `token=` / `password=` / `Authorization: Bearer` 的值替换为 `***`,`sk-xxxxx` 形态密钥替换为 `sk-***`。**审计日志本身不会成为泄密源**。
158
-
159
- > 合规提示:审计目录建议单独挂载只读快照卷或定期归档至 WORM 存储;哈希链只能证明"是否被改",不能阻止有权限者删除整个文件,物理保全仍需存储层配合。
160
-
161
- ---
162
-
163
- ## 五、多租户
164
-
165
- ### 5.1 目录布局
166
-
167
- ```
168
- <FH_HOME>/
169
- ├── policy.json 全局策略(可选)
170
- └── tenants/
171
- ├── acme/
172
- │ ├── sessions/ 会话检查点 + 事件日志
173
- │ ├── audit/ 审计链
174
- │ ├── goals/ /goal 产物
175
- │ └── policy.json 租户策略(可选)
176
- └── beta/
177
- └── …
178
- ```
179
-
180
- `sessions` / `resume` / `diff` / `rollback` / `audit` / `goal` 全部在当前租户目录内操作,**跨租户不可见**。
181
-
182
- ### 5.2 用量汇总
183
-
184
- ```bash
185
- $ fhcode tenants
186
- 租户用量汇总:
187
- 租户ID 会话数 累计成本 审计条数 最近活跃
188
- beta 1 $ 0.000000 3 2026-08-10T06:42:00.496Z
189
- acme 2 $ 0.420000 6 2026-08-10T06:41:59.599Z
190
- ```
191
-
192
- 统计不反序列化整份对话(仅正则提取 `costUsd` / `updatedAt`),万级会话下依然秒回。
193
-
194
- ### 5.3 升级兼容
195
-
196
- 默认租户(`default`)在 `tenants/default` 尚未创建、而旧版 `<FH_HOME>/sessions` 存在时,会自动继续使用旧目录——**从 M3 升级到 M4 不丢历史会话**。
197
-
198
- ### 5.4 部署形态建议
199
-
200
- | 形态 | 做法 | 适用 |
201
- | --- | --- | --- |
202
- | 单机多租户 | 同一 `FH_HOME`,靠 `FH_TENANT` 分目录 | 内部多团队 |
203
- | 容器一租户一实例 | 每租户独立容器 + 独立卷,`FH_TENANT` 与卷同名 | 对隔离要求高 / 对外服务 |
204
- | CI 每次任务一租户 | `FH_TENANT=ci-${{ github.run_id }}` | 流水线可追溯,任务间零串扰 |
205
-
206
- ---
207
-
208
- ## 六、成本治理
209
-
210
- | 层级 | 配置 | 行为 |
211
- | --- | --- | --- |
212
- | 单任务 | 角色 `maxCostUsd` | 达到上限立即中止本次任务,检查点保留,可调高后 `resume` 续跑 |
213
- | 租户日预算 | `FH_TENANT_BUDGET_USD` 或策略 `tenantDailyBudgetUsd` | 任务**启动前** fail-fast(`QUOTA_EXCEEDED`),不产生任何模型调用费用 |
214
-
215
- 统计口径:该租户 `sessions` 目录下 `updatedAt` 为当天(UTC)的检查点 `costUsd` 之和。拒绝时同步写入 `quota:block` 审计记录。
216
-
217
- ```bash
218
- $ FH_TENANT_BUDGET_USD=0.30 fhcode "超预算任务"
219
- [飞虹 Code] 运行失败 (QUOTA_EXCEEDED): 租户 acme 今日成本 $0.420000 已达上限 $0.3,任务被拒绝。
220
- ```
221
-
222
- ---
223
-
224
- ## 七、CI 集成
225
-
226
- `.github/workflows/ci.yml` 三条流水线,**全程离线、零 Secrets**,fork PR 也能安全跑完:
227
-
228
- | Job | 内容 |
229
- | --- | --- |
230
- | `build` | Node 18 / 20 / 22 矩阵 → typecheck → 编译 → 离线端到端 → `/plan` `/grill` |
231
- | `enterprise` | `scripts/verify-m4.mjs` 41 项断言 + CLI 企业命令冒烟 + **租户隔离断言**(beta 租户读不到其它租户会话即通过) |
232
- | `security` | `npm pack --dry-run` 白名单校验(`.env`/`src`/`policy.json` 出现即失败)+ 仓库明文密钥扫描 + `npm audit` |
233
-
234
- 本地一条命令跑齐:
235
-
236
- ```bash
237
- npm run verify # typecheck + build + M4 断言套件
238
- ```
239
-
240
- ### 断言覆盖(41 项)
241
-
242
- 1. RBAC 角色矩阵(5 项)
243
- 2. deny 优先危险动作(4 项)
244
- 3. 策略文件覆盖与"只能加严"(4 项)
245
- 4. 审计哈希链:写入 / 校验 / 脱敏 / 篡改定位 / 删除检测(7 项)
246
- 5. 守卫接入工具链:拦截、放行、审批一次、危险命令批准也拒(11 项)
247
- 6. 多租户:非法 ID、目录隔离、用量统计、不串台(7 项)
248
- 7. 配额:当日统计、超限、充足(3 项)
249
-
250
- ---
251
-
252
- ## 八、上线检查清单
253
-
254
- - [ ] `FH_HOME` 指向持久卷,`tenants/` 已纳入备份策略
255
- - [ ] `FH_TENANT` / `FH_USER` / `FH_ROLE` 由上游身份系统注入,不由用户自填
256
- - [ ] 生产角色最小化:默认 `developer`,`admin` 仅限平台管理员
257
- - [ ] `policy.json` 已按业务补充禁止项(如 `kubectl delete`、生产配置目录)
258
- - [ ] `FH_TENANT_BUDGET_USD` 已设置,避免失控消耗
259
- - [ ] `FH_SHELL_ALLOW` 仅包含确需免审批的命令(建议 `git,npm,node,ls,cat`)
260
- - [ ] 定时任务执行 `fhcode audit verify`,失败即告警
261
- - [ ] 审计目录已归档至只读 / WORM 存储
262
- - [ ] `.env` 未入库(`git check-ignore .env` 应有输出)
263
- - [ ] 发布前执行 `npm pack --dry-run` 确认无密钥与源码泄漏
264
-
265
- ---
266
-
267
- © 2026 晋江市飞虹智科技企业管理有限公司 · 飞扬企源研发中心 · 负责人:吴赐虹
1
+ # 飞虹 Code — 企业部署与合规指南(M4)
2
+
3
+ > 晋江市飞虹智科技企业管理有限公司 · 飞扬企源研发中心 · 负责人:吴赐虹
4
+
5
+ 本文面向**企业管理员 / 平台工程 / 安全合规**角色,说明如何把飞虹 Code 以受控方式部署到团队、部门乃至多客户(多租户)环境中。
6
+
7
+ ---
8
+
9
+ ## 一、能力总览
10
+
11
+ | 维度 | 能力 | 关键命令 |
12
+ | --- | --- | --- |
13
+ | 身份 | 租户 / 用户 / 角色由环境注入,容器与网关友好 | `fhcode whoami` |
14
+ | 权限 | RBAC 角色矩阵 + deny 优先黑名单 + 沙箱越界拦截 | `fhcode policy` |
15
+ | 审计 | sha256 哈希链、脱敏、按月切分、可验证 | `fhcode audit` / `fhcode audit verify` |
16
+ | 隔离 | 会话 / 审计 / 目标物理分目录 | `fhcode tenants` |
17
+ | 成本 | 单任务熔断 + 租户日预算 fail-fast | `FH_TENANT_BUDGET_USD` |
18
+ | 交付 | 三条全离线 CI 流水线 + 发布包白名单 | `npm run verify` |
19
+
20
+ 企业模式默认开启。若需退回社区版行为(无租户、无审计链、无 RBAC):`FH_ENTERPRISE=false`。
21
+
22
+ ---
23
+
24
+ ## 二、身份模型
25
+
26
+ ```bash
27
+ export FH_TENANT=acme # 租户 ID:^[A-Za-z0-9._-]{1,64}$
28
+ export FH_USER=wuchihong # 用户标识,写入审计 actor
29
+ export FH_ROLE=developer # viewer | developer | operator | admin
30
+ ```
31
+
32
+ - 三者均可由**容器编排 / SSO 网关 / CI Runner** 注入,CLI 自身不做认证——认证是上游职责,飞虹 Code 只负责**授权与留痕**。
33
+ - `FH_TENANT` 非法(含 `../`、超长、特殊字符)时启动即报 `TENANT_ID_INVALID`,杜绝路径穿越。
34
+ - `FH_ROLE` 非法值直接报 `ROLE_INVALID`,不做"降级容错"——权限问题不允许猜。
35
+
36
+ ### 推荐角色分配
37
+
38
+ | 场景 | 角色 | 理由 |
39
+ | --- | --- | --- |
40
+ | 代码审查 / 只读排障 | `viewer` | 仅能读取与检索,任何写入都被拒 |
41
+ | 日常研发 | `developer` | 可写代码与跑测试,shell 需审批 |
42
+ | 值班 / 运维处置 | `operator` | 全工具可用,shell 仍需审批,成本上限 $5 |
43
+ | 平台管理员 | `admin` | 无成本上限,但**危险命令与敏感路径依旧拒绝** |
44
+
45
+ ---
46
+
47
+ ## 三、权限策略
48
+
49
+ ### 3.1 判定顺序(deny 优先)
50
+
51
+ ```
52
+ 1) 危险 shell 命令黑名单 → deny(admin 也拦)
53
+ 2) 敏感路径黑名单 → deny
54
+ 3) 沙箱越界(逃出 cwd) → deny
55
+ 4) 角色-工具矩阵 → deny / approval / allow
56
+ 5) shell 白名单 → allow(否则 approval)
57
+ ```
58
+
59
+ 前三条是**硬底线**,不受角色影响,也不能被人工审批放行——批准了也不执行。
60
+
61
+ ### 3.2 内置黑名单
62
+
63
+ - **危险命令(23 条)**:`rm -rf /`、`rm -rf ~`、`mkfs`、`dd if=`、fork 炸弹 `:(){`、`shutdown`、`reboot`、`format `、`del /s`、`rd /s`、`chown -R root`、`curl | sh`、`wget | sh`、`iptables -F`、`reg delete`、`history -c`、`shred ` 等。
64
+ - **敏感路径(11 类)**:`.env`、`.git/config`、`.git/hooks`、`.npmrc`、`.ssh`、`id_rsa`、`id_ed25519`、`credentials`、`.aws`、`.kube/config`、`shadow`。
65
+
66
+ ### 3.3 策略覆盖(只能加严)
67
+
68
+ 优先级从低到高:
69
+
70
+ ```
71
+ DEFAULT_POLICY
72
+ → <FH_HOME>/policy.json 全局策略
73
+ → <FH_HOME>/tenants/<租户>/policy.json 租户策略
74
+ → FH_POLICY 内联 JSON 临时覆盖(CI / 调试)
75
+ ```
76
+
77
+ **黑名单取并集**——下级配置只能新增禁止项,无法删除上级的禁止项。这条设计确保"租户自定义策略"永远不能成为提权通道。
78
+
79
+ `policy.json` 示例:
80
+
81
+ ```json
82
+ {
83
+ "roles": {
84
+ "developer": { "maxCostUsd": 0.25, "approvalTools": ["run_shell", "write_file"] }
85
+ },
86
+ "denyShell": ["npm publish", "docker push", "kubectl delete"],
87
+ "denyPaths": ["config/secrets", "deploy/prod"],
88
+ "tenantDailyBudgetUsd": 20
89
+ }
90
+ ```
91
+
92
+ ### 3.4 审批通道
93
+
94
+ | 环境 | 行为 |
95
+ | --- | --- |
96
+ | TTY 交互终端 | 逐条弹出 `y/n`,用户显式批准才执行 |
97
+ | 非交互(CI / 管道 / 守护进程) | 回退白名单审批器:命中 `FH_SHELL_ALLOW` 自动通过,其余拒绝并留痕 |
98
+
99
+ > **守卫是唯一权威闸门**:策略判定、审批、审计在工具执行前一次性完成,工具层不会二次弹审批,杜绝重复询问与决策打架。
100
+
101
+ ---
102
+
103
+ ## 四、审计与取证
104
+
105
+ ### 4.1 存储
106
+
107
+ ```
108
+ <FH_HOME>/tenants/<租户>/audit/audit-YYYY-MM.jsonl
109
+ ```
110
+
111
+ append-only、按月切分、同步写入(不缓冲,进程崩溃不丢记录)。
112
+
113
+ ### 4.2 记录结构
114
+
115
+ ```json
116
+ {
117
+ "seq": 2,
118
+ "ts": "2026-08-10T06:41:43.118Z",
119
+ "tenantId": "acme",
120
+ "userId": "wuchihong",
121
+ "role": "developer",
122
+ "runId": "2d1e3188-...",
123
+ "action": "tool:write_file",
124
+ "resource": "demo-output.txt",
125
+ "decision": "allow",
126
+ "reason": "rbac.allow — 角色 developer 允许调用 write_file",
127
+ "prevHash": "…",
128
+ "hash": "…"
129
+ }
130
+ ```
131
+
132
+ `decision` 取值:`allow` / `deny` / `approved`(人工批准)/ `rejected`(人工拒绝或无审批通道)/ `info`(会话起止等)。
133
+
134
+ 覆盖动作:`session:start`、`session:end`、`session:rollback`、`skill:goal`、`quota:block`、`tool:<工具名>`。
135
+
136
+ ### 4.3 防篡改验证
137
+
138
+ ```bash
139
+ fhcode audit verify
140
+ ```
141
+
142
+ 链式校验三件事:**seq 连续**(防删除/插入)、**prevHash 衔接**(防重排)、**hash 自洽**(防内容改写)。任一失败会定位到具体条目:
143
+
144
+ ```
145
+ ❌ 审计链校验失败:共 5 条,断点在第 3 条
146
+ 记录内容被篡改:hash 不自洽(期望 8b3a6990664e…)
147
+ ```
148
+
149
+ 退出码为 `2`,可直接接入监控告警:
150
+
151
+ ```bash
152
+ fhcode audit verify || alertmanager-cli fire --name fhcode-audit-tampered
153
+ ```
154
+
155
+ ### 4.4 脱敏
156
+
157
+ `resource` / `reason` 写入前统一脱敏:`apiKey=` / `secret=` / `token=` / `password=` / `Authorization: Bearer` 的值替换为 `***`,`sk-xxxxx` 形态密钥替换为 `sk-***`。**审计日志本身不会成为泄密源**。
158
+
159
+ > 合规提示:审计目录建议单独挂载只读快照卷或定期归档至 WORM 存储;哈希链只能证明"是否被改",不能阻止有权限者删除整个文件,物理保全仍需存储层配合。
160
+
161
+ ---
162
+
163
+ ## 五、多租户
164
+
165
+ ### 5.1 目录布局
166
+
167
+ ```
168
+ <FH_HOME>/
169
+ ├── policy.json 全局策略(可选)
170
+ └── tenants/
171
+ ├── acme/
172
+ │ ├── sessions/ 会话检查点 + 事件日志
173
+ │ ├── audit/ 审计链
174
+ │ ├── goals/ /goal 产物
175
+ │ └── policy.json 租户策略(可选)
176
+ └── beta/
177
+ └── …
178
+ ```
179
+
180
+ `sessions` / `resume` / `diff` / `rollback` / `audit` / `goal` 全部在当前租户目录内操作,**跨租户不可见**。
181
+
182
+ ### 5.2 用量汇总
183
+
184
+ ```bash
185
+ $ fhcode tenants
186
+ 租户用量汇总:
187
+ 租户ID 会话数 累计成本 审计条数 最近活跃
188
+ beta 1 $ 0.000000 3 2026-08-10T06:42:00.496Z
189
+ acme 2 $ 0.420000 6 2026-08-10T06:41:59.599Z
190
+ ```
191
+
192
+ 统计不反序列化整份对话(仅正则提取 `costUsd` / `updatedAt`),万级会话下依然秒回。
193
+
194
+ ### 5.3 升级兼容
195
+
196
+ 默认租户(`default`)在 `tenants/default` 尚未创建、而旧版 `<FH_HOME>/sessions` 存在时,会自动继续使用旧目录——**从 M3 升级到 M4 不丢历史会话**。
197
+
198
+ ### 5.4 部署形态建议
199
+
200
+ | 形态 | 做法 | 适用 |
201
+ | --- | --- | --- |
202
+ | 单机多租户 | 同一 `FH_HOME`,靠 `FH_TENANT` 分目录 | 内部多团队 |
203
+ | 容器一租户一实例 | 每租户独立容器 + 独立卷,`FH_TENANT` 与卷同名 | 对隔离要求高 / 对外服务 |
204
+ | CI 每次任务一租户 | `FH_TENANT=ci-${{ github.run_id }}` | 流水线可追溯,任务间零串扰 |
205
+
206
+ ---
207
+
208
+ ## 六、成本治理
209
+
210
+ | 层级 | 配置 | 行为 |
211
+ | --- | --- | --- |
212
+ | 单任务 | 角色 `maxCostUsd` | 达到上限立即中止本次任务,检查点保留,可调高后 `resume` 续跑 |
213
+ | 租户日预算 | `FH_TENANT_BUDGET_USD` 或策略 `tenantDailyBudgetUsd` | 任务**启动前** fail-fast(`QUOTA_EXCEEDED`),不产生任何模型调用费用 |
214
+
215
+ 统计口径:该租户 `sessions` 目录下 `updatedAt` 为当天(UTC)的检查点 `costUsd` 之和。拒绝时同步写入 `quota:block` 审计记录。
216
+
217
+ ```bash
218
+ $ FH_TENANT_BUDGET_USD=0.30 fhcode "超预算任务"
219
+ [飞虹 Code] 运行失败 (QUOTA_EXCEEDED): 租户 acme 今日成本 $0.420000 已达上限 $0.3,任务被拒绝。
220
+ ```
221
+
222
+ ---
223
+
224
+ ## 七、CI 集成
225
+
226
+ `.github/workflows/ci.yml` 三条流水线,**全程离线、零 Secrets**,fork PR 也能安全跑完:
227
+
228
+ | Job | 内容 |
229
+ | --- | --- |
230
+ | `build` | Node 18 / 20 / 22 矩阵 → typecheck → 编译 → 离线端到端 → `/plan` `/grill` |
231
+ | `enterprise` | `scripts/verify-m4.mjs` 41 项断言 + CLI 企业命令冒烟 + **租户隔离断言**(beta 租户读不到其它租户会话即通过) |
232
+ | `security` | `npm pack --dry-run` 白名单校验(`.env`/`src`/`policy.json` 出现即失败)+ 仓库明文密钥扫描 + `npm audit` |
233
+
234
+ 本地一条命令跑齐:
235
+
236
+ ```bash
237
+ npm run verify # typecheck + build + M4 断言套件
238
+ ```
239
+
240
+ ### 断言覆盖(41 项)
241
+
242
+ 1. RBAC 角色矩阵(5 项)
243
+ 2. deny 优先危险动作(4 项)
244
+ 3. 策略文件覆盖与"只能加严"(4 项)
245
+ 4. 审计哈希链:写入 / 校验 / 脱敏 / 篡改定位 / 删除检测(7 项)
246
+ 5. 守卫接入工具链:拦截、放行、审批一次、危险命令批准也拒(11 项)
247
+ 6. 多租户:非法 ID、目录隔离、用量统计、不串台(7 项)
248
+ 7. 配额:当日统计、超限、充足(3 项)
249
+
250
+ ---
251
+
252
+ ## 八、上线检查清单
253
+
254
+ - [ ] `FH_HOME` 指向持久卷,`tenants/` 已纳入备份策略
255
+ - [ ] `FH_TENANT` / `FH_USER` / `FH_ROLE` 由上游身份系统注入,不由用户自填
256
+ - [ ] 生产角色最小化:默认 `developer`,`admin` 仅限平台管理员
257
+ - [ ] `policy.json` 已按业务补充禁止项(如 `kubectl delete`、生产配置目录)
258
+ - [ ] `FH_TENANT_BUDGET_USD` 已设置,避免失控消耗
259
+ - [ ] `FH_SHELL_ALLOW` 仅包含确需免审批的命令(建议 `git,npm,node,ls,cat`)
260
+ - [ ] 定时任务执行 `fhcode audit verify`,失败即告警
261
+ - [ ] 审计目录已归档至只读 / WORM 存储
262
+ - [ ] `.env` 未入库(`git check-ignore .env` 应有输出)
263
+ - [ ] 发布前执行 `npm pack --dry-run` 确认无密钥与源码泄漏
264
+
265
+ ---
266
+
267
+ © 2026 晋江市飞虹智科技企业管理有限公司 · 飞扬企源研发中心 · 负责人:吴赐虹