Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,13 @@ jobs:
"dist/templates/trellis/scripts/hermes/experiment.py",
"dist/templates/trellis/scripts/hermes/runner.py",
"dist/templates/trellis/scripts/hermes/report.py",
"dist/templates/trellis/scripts/common/closure.py",
"dist/templates/trellis/scripts/common/dispatch.py",
"dist/templates/trellis/hermes/schemas/result-envelope.schema.json",
"dist/templates/shared-hooks/hermes-runtime-guard.py",
"dist/templates/shared-hooks/inject-workflow-state.py",
"dist/templates/common/commands/status.md",
"dist/templates/common/commands/handoff.md",
];
const missingCliFiles = requiredCliFiles.filter(
(file) => !fs.existsSync(path.join(cliRoot, file)),
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ node /path/to/research-trellis/packages/cli/bin/trellis.js update

### 7. Agent Context Firewall

每次正式角色派发先生成绑定 `hermes_revision`(Hermes 修订号)的结构化文件,正文最多 2000 字符、引用最多 3 个。`Claude Code`(Claude 代码工具)钩子只接收 `job_id`(工作编号)并替换长提示;`Codex native`(Codex 原生)仅为建议性,`Codex strict`(Codex 严格模式)使用结构化输出参数执行。
每次正式角色派发先生成绑定 `hermes_revision`(Hermes 修订号)的结构化文件,正文最多 2000 字符、引用最多 3 个。`Claude Code`(Claude 代码工具)钩子只接收 `job_id`(工作编号)并替换长提示;`Codex`(代码代理平台)使用同一份紧凑派发和结果契约,在当前项目工作区协作。

返回必须包含 `uncertainties`(不确定项),长日志、完整差异和搜索过程不会进入主上下文。原始跟踪保存在 `.trellis/.runtime/`(本地运行目录),成功或失败都会机械更新下一动作,但不会仅凭聊天关闭任务。

Expand Down
47 changes: 12 additions & 35 deletions docs/hermes_deployment_preflight.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,25 @@
# Hermes Deployment Candidate Hardening Preflight
# Hermes 本地工作流预检

这版是 `deployment candidate hardening`(部署候选加固),不是完整
`production ready`(生产就绪)平台。
Hermes 面向真实科研项目工作区,不提供容器、沙箱或隔离运行环境。它使用任务状态、最小派发、运行记录和关闭审计协助科研迭代。

## 紧急部署步骤

1. 先运行 quick gate:
## 发布前检查

```bash
pnpm --filter research-trellis hermes:preflight -- --quick
```

2. 发布前补跑完整验证:

```bash
pnpm --filter research-trellis exec vitest run test/scripts/agent-context-firewall.integration.test.ts test/scripts/closure.integration.test.ts test/templates/hermes-runtime.test.ts test/templates/hermes-roles.test.ts test/templates/trellis.test.ts test/templates/claude.test.ts test/templates/codex.test.ts test/templates/shared-hooks.test.ts
PYTHONPYCACHEPREFIX=/tmp/research-trellis-pycache python3 -m py_compile packages/cli/src/templates/trellis/scripts/common/*.py packages/cli/src/templates/trellis/scripts/hermes/*.py packages/cli/src/templates/shared-hooks/*.py
pnpm --filter research-trellis typecheck
pnpm --filter research-trellis build
```

3. 若 Python 编译后出现 `__pycache__` 或 `.pyc` 在模板目录内,不能发布;用 `gio trash` 或 `trash` 清理后重跑 preflight。

## 安全 Gate

- 正式上下文防火墙只支持 `Claude Code`(Claude 代码工具)和 `Codex`(代码代理平台)。Claude 的 `Agent`(代理)工具必须启用项目钩子;Codex 原生代理仅是建议性入口,需要强制控制时必须使用 `dispatch.py run --platform codex --mode strict`(Codex 严格派发)。
- `TRELLIS_HOOKS=0`(关闭钩子)或 `TRELLIS_DISABLE_HOOKS=1`(禁用钩子)会覆盖心跳判断。`lean`(轻量)模式会显示强警告;`standard`(标准)模式要求新鲜钩子或严格执行心跳;`publication`(发表)模式缺少该硬门禁时必须拒绝派发和关闭。
- Claude Agent 调用只传 `job_id`(工作编号),不允许异步调用。Codex 严格包装使用 `codex exec --output-schema --json -o`(结构化执行)并把原始跟踪保存在 `.trellis/.runtime/hermes-traces/`(本地跟踪目录);发布包和聊天只使用校验后的净化结果。
- `Bash` 写入守卫是最佳努力,不是完整 shell 沙箱。hook 会解析常见重定向和 `tee` 写入;遇到写入语义但无法明确解析目标时必须 `fail closed`。
- `runner.py` 必须按任务 `experiment.yaml` 的 `allowed_commands` 执行命令白名单;未匹配命令直接失败。`allowed_commands` is not a strong command sandbox(不是强命令沙箱);如果允许 `python3`,仍能执行任意 Python 行为。需要更强控制时,应使用更严格 exact match(精确匹配)或外部 OS 级隔离。
- `sandbox.required=true` 且 `mode=none` 必须拒绝运行;`mode=none` 只是本地执行,不是隔离环境。`container` 当前只提供 `Docker`(容器运行时)薄切片:通过 `docker run --rm`(一次性容器执行命令)挂载仓库,并在容器工作目录执行已通过白名单的命令;这仍是 `not an OS sandbox`(不是操作系统沙箱),也不是 `production ready`(生产就绪)的强隔离。`external` 当前仍只做可用性检查,不能声称已经提供 `OS sandbox`(操作系统沙箱)。
- `runner.py --cwd`、`--input`、`--output` 必须留在仓库内;`report.py --output` 必须留在当前任务 Hermes 目录内。
- runner 默认使用最小环境变量白名单,`run_manifest` 不记录完整环境,避免 secret env 泄露。
- `approval_records` 必须依赖 `external human/root approval`(外部人工/根权限批准)流程写入。当前实现只能校验字段、claim/evidence 关联和决策值;它不是 OS 级不可写权限隔离。
- `JSONL` 记录是 append-only(追加写)约定,不是 `not tamper-proof`(不可篡改)存储。需要防篡改审计时,应使用外部日志、权限或签名机制。

## 失败处理
## 当前约定

- 缺关键模板文件:补齐模板后重跑 `hermes:preflight`。
- Bash gate 失败:改用受 Hermes runner 管理的命令,或把写入文件纳入任务卡 `allowed_files`。
- 命令不在 `allowed_commands`:更新任务级 `experiment.yaml`,不要绕过 runner。
- approval 失败:由外部 human/root 流程补写完整 approval 记录,agent 不能自行生成批准。
- 防火墙状态异常:运行 `python3 ./.trellis/scripts/hermes/dispatch.py status --task <task>`(派发状态),确认平台、环境变量和最新心跳;不能用手工改写心跳文件绕过 `standard`(标准)或 `publication`(发表)门禁。
- `runner.py`(运行器)直接在当前项目环境执行。`allowed_commands`(允许命令)用于记录实验可复现的命令边界,不是安全隔离。
- `Claude Code`(Claude 代码工具)和 `Codex`(代码代理平台)都使用紧凑派发和结果摘要;完整日志、差异和搜索过程保留在文件中。
- `task.json`(任务状态)是事实源。`HANDOFF.md`(交接摘要)只用于暂停、阶段切换和恢复上下文,不阻止结束任务或关闭任务。
- `close`(关闭)仍需满足工作包、证据和审计条件;人工科研决策仍由项目负责人确认。

## 已知边界
## 常见问题

这版是部署候选加固薄切片:它阻断已知高风险绕过,并为 `container`(容器)模式提供可验证的 `Docker`(容器运行时)最小执行路径,但不提供用户权限、文件系统 `ACL`(访问控制列表)或系统调用级隔离;也就是 `not an OS sandbox`(不是操作系统沙箱),更不是生产级强隔离。需要强隔离时,应在后续版本把 `Hermes runner`(Hermes 运行器)放入独立受限执行环境。
- 命令不在 `allowed_commands`(允许命令)中:更新当前任务的 `experiment.yaml`(实验配置),并保持命令尽可能具体。
- 任务暂停:生成 `HANDOFF.md`(交接摘要);恢复时先读取 `task.json`(任务状态),再按需读取交接摘要。
- 模板目录出现 `__pycache__` 或 `.pyc`:使用 `trash`(回收站命令)清理后重跑预检。
4 changes: 2 additions & 2 deletions docs/hermes_role_profile_migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

## 派发上下文

`v0.7.1`(当前版本)开始,主代理先生成 validated dispatch(已验证派发),其中只保留:
`v0.7.1-beta.0`(当前测试版)开始,主代理先生成 validated dispatch(已验证派发),其中只保留:

1. `job_id`(工作编号)和 `hermes_revision`(Hermes 修订号);
2. 当前角色与模式;
Expand All @@ -45,7 +45,7 @@
| 两平台正式 Hermes 模板合计 | 7 个 / 9873 字符 | 10 个 / 8904 字符 | 新增 Codex 支持后仍减少 9.8% |
| 单个正式模板平均长度 | 1410 字符 | 890 字符 | 减少 36.9% |

派发正文测试限制在 2000 字符内。`Claude Code`(Claude 代码工具)只向 `Agent`(代理)传 `job_id`(工作编号),`Codex native`(Codex 原生)仅为建议性,`Codex strict`(Codex 严格模式)由统一 CLI 包装器执行。
派发正文测试限制在 2000 字符内。`Claude Code`(Claude 代码工具)只向 `Agent`(代理)传 `job_id`(工作编号),`Codex`(代码代理平台)使用同一份紧凑派发和结果契约,直接在当前项目工作区协作。

## 兼容边界

Expand Down
14 changes: 7 additions & 7 deletions docs/hermes_trellis_research_transformation_plan.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Hermes on Trellis 科研化改造总计划

> **For agentic workers:** REQUIRED SUB-SKILL: Use `superpowers:subagent-driven-development`(子代理驱动开发) or `superpowers:executing-plans`(执行计划) to implement this plan task-by-task. Steps should be tracked with checkbox syntax in later implementation issues.
> **状态:历史设计记录。** 本文保留早期讨论,不是当前运行规范;其中关于容器、沙箱、严格隔离和额外安全门禁的内容已不再采用。当前行为以中文手册、任务胶囊、Lean Closure 和本地工作流预检为准。

**Goal:** 把 Trellis 从任务协作脚手架,改造成可审计、可复现、可评估的科研实验框架。

Expand Down Expand Up @@ -62,13 +62,13 @@

### P7-P11:deployment candidate hardening(部署候选加固)

当前 P7-P11 只做可验证薄切片:sandbox 配置 fail-closed、provenance
ledger、local service queue、audit ledger、evaluation quality gate。这里不能
声称完整 `production ready`(生产就绪)或 OS 级生产平台。
以下 P7-P11 是历史方案,不再作为当前路线。当前版本保留 provenance
ledger、audit ledger 和 evaluation quality gate 等轻量记录能力,不继续实现
sandbox、容器、远程服务或复杂本地队列。

边界约定:

- `not an OS sandbox`(不是操作系统级沙箱)。`container` 模式已有 `Docker`(容器运行时)薄切片,会通过 `docker run --rm`(一次性容器执行命令)挂载仓库并运行白名单命令;它仍不是生产级强隔离。`external` 模式当前只做可用性检查。
- `container`(容器)和 `external sandbox`(外部沙箱)方案已放弃;运行器直接在真实项目环境执行登记命令。
- `approval_records` 依赖 `external human/root approval`(外部人工/根权限批准)。
- `JSONL` 不是不可篡改存储,只是 append-only(追加写)约定。
- `allowed_commands` 不是 strong command sandbox(强命令沙箱);允许 `python3` 时仍可执行任意 Python 行为。
Expand Down Expand Up @@ -330,9 +330,9 @@ P7 Agent Context Firewall:
- [x] 新增统一 `dispatch.py`(派发命令),支持创建、校验、显示、运行、列表、应用和状态查询。
- [x] 派发绑定单调 `hermes_revision`(Hermes 修订号)、当前工作包、五角色模式和最多 3 个引用。
- [x] Claude Agent 钩子只接受 `job_id`(工作编号),拒绝异步,并在结束时校验和净化结果。
- [x] Codex native(Codex 原生)明确为建议性;strict(严格)复用结构化执行参数,不增加 SDK、数据库或服务。
- [x] Codex native(Codex 原生)明确为建议性;旧 strict(严格)参数只保留兼容提示,不再提供独立执行模式。
- [x] 原始跟踪只写入忽略发布的 `.trellis/.runtime/`(本地运行目录);主上下文只接收净化摘要。
- [x] `lean`(轻量)、`standard`(标准)和 `publication`(发表)按钩子或严格模式心跳执行不同门禁。
- [x] `lean`(轻量)、`standard`(标准)和 `publication`(发表)共享钩子状态提示;模式差异由运行、证据、统计、主张和审批审计决定。

最终验证记录:

Expand Down
13 changes: 13 additions & 0 deletions docs/manual/06-tasks-and-planning.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

## 操作步骤

每个新的可执行任务都先由主代理分析 intent(意图)、scope(范围)、definition of done(完成定义)、科研协议影响、风险和最小工作包拆分。已有任务的后续请求先分成三类:范围内续接继续当前工作包;低风险计划变化使用 `amend`(修改计划);新假设、模型功能架构、数据、指标、基线或主张范围变化进入 exploration(探索)并重新校验。范围内补充不能重新生成整套工作包。

协作判断固定为三档:普通可逆任务直接执行,不增加讨论或记录步骤;存在有限不确定性时,明确关键假设后继续;只有高风险研究变化才暂停讨论并由用户批准科研取舍。判断以事实和证据为先,应保留不确定性和有依据的异议。证据冲突或关键假设失效时,把任务标记为 `blocked`(阻塞),再通过批准的 `amend`(修改计划)更新研究协议。提示词不能替代结构化记录,也不能让每个任务都进入 `grill`(方案讨论)。

1. 创建任务:

```bash
Expand Down Expand Up @@ -77,6 +81,15 @@ python3 ./.trellis/scripts/closure.py amend --task "$TASK" \

数据集、研究假设、数据切分、指标定义、基线、主张范围和任务范围属于高风险字段,必须增加 `--approved-by human/root`(人工批准)。变更直接写入 `task.json`(任务状态),同时向 `task-events.jsonl`(任务事件)追加 `plan_amended`(计划已修改)记录;变更后重新运行 closure 校验。正式研究仍可额外使用 Hermes `plan_change`(研究计划变更记录)保存更完整的提案和审阅链。

新完成的高风险 exploration(探索)讨论还需要引用已有决策记录:

```bash
python3 ./.trellis/scripts/closure.py grill --task "$TASK" --complete \
--decision-ref design.md
```

引用必须位于仓库或当前任务内。记录至少包含 `Decision`(决定)、`Rationale`(理由)、`Evidence`(证据)、`Alternatives`(备选方案)和 `Failure Conditions`(失效条件)。事件和 Task Capsule(任务胶囊)只显示引用,不加载正文。旧任务已有 `grill_completed=true`(已完成讨论)但没有引用时继续运行并给出警告;研究协议再次修改后必须重新记录。普通 delivery(确定性交付)和 execution(冻结协议执行)没有这一门禁。

## 预期结果

任务创建时状态为 `planning`(规划中);启动后变为 `in_progress`(进行中);只有 close gate(关闭门禁)通过后才变为 `completed`(已完成),随后可移动到 `.trellis/tasks/archive/<year-month>/`(月度归档目录)。
Expand Down
35 changes: 19 additions & 16 deletions docs/manual/09-experiments.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

## 目标

为每个科研任务固定问题、假设、数据、被测对象、指标、环境、允许命令和产物目录。
为每个科研任务固定问题、假设、数据、被测对象、指标、环境、允许命令和产物目录。运行器直接在当前项目环境执行命令,不提供容器或沙箱运行模式。

## 适用范围

适用于本地脚本、测试、基准、数据处理和模型评估。纯文档任务仍会生成实验骨架,但启动前也必须把占位字段改成非空内容。

数据预检不是通用步骤。只有 Hermes closure(科研闭环)任务属于 exploration(探索),且 `research_change_fields`(研究变化字段)包含 `dataset`(数据集)、`split`(数据切分)或 `preprocessing`(预处理)时才启用;旧版非 closure 任务、普通任务、冻结协议执行和不涉及这三个字段的探索任务都不增加预检。

## 前置条件

- 已创建任务并设置 `TASK`(任务目录名)变量。
Expand Down Expand Up @@ -39,21 +41,23 @@ environment:
shell: "bash"
allowed_commands:
- "python3 scripts/evaluate.py"
sandbox:
mode: "none"
required: false
artifact_dir: ".trellis/tasks/任务名/hermes/runs"
```

3. 尽量把 `allowed_commands`(允许命令)写成完整命令前缀,而不是只写 `python3`(Python 3 命令)。当前匹配支持可执行文件名、完整命令或命令前缀,但它不是强安全边界。
4. 选择运行隔离方式:
3. 对需要数据预检的任务,增加 `data_preflight`(数据预检):

```yaml
data_preflight:
source: "公开评估集"
version: "2026-07"
input_manifest: "data/eval-manifest.json"
hash: "sha256:实际文件的64位小写哈希"
checks_ref: "data/eval-checks.yaml"
```

| 模式 | 当前状态 |
| --- | --- |
| `none`(无隔离) | 已实现且为默认值;直接在本机运行 |
| `container`(容器) | 实验性;需要 `docker`(容器命令)和有效镜像,运行器会挂载仓库 |
| `external`(外部) | 配置可解析,但当前运行器不提供外部沙箱执行,实际运行会失败 |
`input_manifest`(输入清单)与 `data_path`(数据路径)二选一,`hash`(哈希值)必须与所指文件一致。`checks_ref`(检查记录)必须位于仓库内,并把 `schema`(结构)、`missing`(缺失值)、`duplicates`(重复项)和 `split_leakage`(切分泄漏)分别记为 `checked`(已检查)或 `not_applicable`(不适用)。运行时还要用 `runner.py run --input`(声明运行输入)同时传入数据文件和检查记录,二者会带哈希写入运行清单。

4. 尽量把 `allowed_commands`(允许命令)写成完整命令前缀,而不是只写 `python3`(Python 3 命令)。它用于实验复现和任务边界,不是安全隔离。
5. 校验配置:

```bash
Expand All @@ -67,18 +71,17 @@ python3 ./.trellis/scripts/hermes/experiment.py validate --task "$TASK"
## 失败恢复

- 字段为空或类型错误:按报错修正;指标和允许命令必须是非空列表,随机种子必须是整数。
- `sandbox.required=true`(必须隔离)却使用 `mode: none`(无隔离):改用可用容器,或停止运行。
- 容器命令不可用:安装并验证 `docker`(容器命令),或在明确接受风险后改回无隔离模式。
- 命令被拒绝:不要扩大到笼统的可执行文件;把确实需要的完整命令前缀加入配置并重新审阅。
- 数据预检失败:修正仓库内路径、实际文件哈希或四项检查状态。校验通过前运行器不会执行命令,也不会写入成功运行状态。
- 旧配置中的 `sandbox`(沙箱)字段可以保留,但运行器会忽略它并直接在项目环境执行。

## 验证记录

- 日期:2026-07-15。
- 版本:`0.7.1-beta.0`(测试版)。
- 更名前基准提交:`9f7dc8497b4782878d6fa7ac3b63eba5bde507df`。
- 命令:`rg -n -m 1 "allowed_commands|sandbox" packages/cli/src/templates/trellis/scripts/hermes packages/cli/test/templates/hermes-runtime.test.ts`(实现与测试核对)。
- 结果:命令允许列表、隔离模式和对应测试均可定位。
- 未验证项:本轮未启动真实容器或外部隔离环境。
- 命令:`rg -n -m 1 "allowed_commands" packages/cli/src/templates/trellis/scripts/hermes packages/cli/test/templates/hermes-runtime.test.ts`(实现与测试核对)。
- 结果:命令允许列表和本地运行记录均可定位。

## 来源

Expand Down
Loading