内容
# HarnessScope
<!-- mcp-name: io.github.moongioh/hscope -->

*每张图片都是`hscope demo`:一个合成的语料库,在本地生成。实际的转录文本包含完整的提示文本,绝不会作为演示材料。*
HarnessScope 提供**逐轮**的 **治理可观测性**,适用于 Claude Code 会话。HarnessScope 将本地的转录 JSONL 文件解析为 SQLite,评估每个回合是否符合工作区自身的运营规则(代码前规划、完成前验证、上下文预算、路径边界等),并提供一个本地的 Web 查看器,展示每个会话如何遍历该治理结构 — 包括通过和违规。
界面:**会话重放**(带有上下文芯片和规则判决的回合时间线)· **Harness Circuit**(一个回合的上下文源 → 代理 → 动作表面 → 治理输出的固定拓扑图,带有往返/离机边缘)· **规则健康**(每个规则的合规性 × 覆盖率)· **Token/循环**(每回合 Token 消耗 + 丢失标记)· **设置**(您注册的每个钩子、MCP 服务器、技能和子代理,旁边是转录文本显示实际调用的内容 — `active` / `unused` / `unregistered-call`)· 计划层次结构(会话上方的工作项 — 后端已发货,UI 进行中)。
所有内容都是**本地优先**:不会有转录数据离开您的机器(一个例外是选择加入的 Tier B LLM 评估器,默认关闭,仅在明确的每个会话点击时触发)。该工具永远不会写入您的项目、`.mcp.json` 或您的 Harness 设置:一个观察治理的工具不应该改变它所观察的表面。唯一的例外是 hscope 自身的 `~/.hscope/<workspace>/workspace-model.json`,设置页面和 MCP 服务器可以编辑 — 具有模式检查、路径限制和门控(URL 中打开的会话令牌;`hscope --no-edit` 完全关闭它)。
## 要求
- **Python 3.11+**(3.10 适用;基于 3.13 开发)
- `pip install -r requirements.txt` — PyYAML、FastAPI、uvicorn。除此之外不需要任何依赖。
- **不需要 Node.js**。React UI 已预编译在 `web/dist` 中(故意提交);如果您想自行开发 UI,则仅需要 Node 20+(`cd web && npm install && npm run build`)。
- 一台具有 Claude Code 转录文本的机器,位于 `~/.claude/projects/` 下(默认扫描根目录)。
可选,仅适用于 Tier B 意图评估器:`anthropic`(默认后端,需要 `ANTHROPIC_API_KEY`)或 `google-genai`(`HSCOPE_TIER_B_BACKEND=gemini`,Vertex ADC)。
## 无需提供转录文本即可查看
```bash
hscope demo --serve # 构建合成语料库,评估后打开查看器
```
三个虚拟会话:一个合规的,一个浪费的(重复读取,上下文丢失,边界读取,声明完成但无验证),一个扇出(两个子代理 — 一个引用它读取的内容,一个不引用;一个在后台生成 — 以及一个离机 MCP 往返)。
它遵循与真实数据相同的标准:语料库必须满足 `hscope doctor`,因此生成器编写的格式不会被解析器期望的结构破坏。它已经经过两次验证 — 一个 `requestId` 跨会话重复使用(hscope 正确读取为一个 API 调用被 fork 重放),以及一个填充的 `agentId:` 被解析器的正则表达式整个吞噬。
## 零配置首运行
```bash
pip install hscope # 或:pipx install hscope · npx -y hscope(仍需要 Python 3.10+)
hscope # 扫描 ~/.claude/projects → 导入 → 评估 → 检查 → 打开查看器
```
无需标志,无需配置文件。两件事情它不会做错:
- **端口被找到,而不是被假设**。8000 是一个合理的默认值,但在某些 Windows 机器上,它是一个保留范围(WinError 10013)。第一次印象不应该是堆栈跟踪。
- **它会显示转录文本已过期**。Harness 删除它们后大约 30 天,**导入使它们永久化**。导入频率低于此,您将无声地丢失会话 — 一个从未导入的会话与从未发生的会话无法区分。首次运行会打印您的最旧转录文本的年龄,并规定一个节奏。
它还会宣布它即将评估哪些规则 — 中立的预设,或它在磁盘上找到的工作区模型(s)。声称“预设”同时悄悄应用模型与撒谎一样 — 即在没有通知的情况下使用模型。
## 设置,委托给您已有的 LLM
没有人应该手动编写规则来尝试一个工具。当首次运行发现没有工作区模型时,它会从此目录结构中生成一个,并留下一个页面供您的模型完成:
```bash
hscope # ...如果没有您自己的规则,则写入 ~/.hscope/<id>/HSCOPE-SETUP.md
hscope mcp --install # 打印一个 MCP 代码段;将其粘贴到 .mcp.json 中
hscope setup # 重新生成页面,每当您的规范发生变化时
```
`HSCOPE-SETUP.md` 是一个带有两个阅读者的 Markdown 页面。对于您:规范、钩子、MCP 服务器、技能和子代理,hscope 找到并显示的内容,以及规范条款中没有引用任何规则的内容。对于您的 LLM:调用 `get_setup_guide` → `suggest_rules` → `set_rule` 并编写这些规则。您审批;它起草。
整个过程是**三个手动操作** — 运行 `hscope`,粘贴代码段,交出页面。代码段带有 `HSCOPE_MCP_WRITE=1`,因此粘贴它**是**写入同意;没有第二个步骤。而且 hscope 从不编辑 `.mcp.json` 本身:一个观察治理的工具不应该改变它所观察的表面。
## 快速开始
```bash
pip install -r requirements.txt
# 1. 将转录文本解析为 SQLite(默认扫描:~/.claude/projects)
python -m hscope.cli ingest --db harness_scope.db
# 2. 运行规则引擎(添加 --model 以覆盖工作区模型)
python -m hscope.cli rules --db harness_scope.db \
--model ~/.hscope/<workspace>/workspace-model.json
# 3. 提供查看器(API + 内置 UI)
HSCOPE_DB=harness_scope.db \
HSCOPE_WORKSPACE_MODEL=~/.hscope/<workspace>/workspace-model.json \
python -m hscope.server
# → http://127.0.0.1:8000
```
步骤 1-2 是幂等的 — 随时重新运行它们以刷新;步骤 2 会擦除并重新生成所有派生判断(规则评估,工作项链接)。
### 环境变量
| 变量 | 默认值 | 含义 |
|---|---|---|
| `HSCOPE_DB` | `./harness_scope.db` | 服务器读取的 SQLite 路径 |
| `HSCOPE_WORKSPACE_MODEL` | *(未设置)* | `workspace-model.json` 的路径;未设置 ⇒ 中立的内置预设 |
| `HSCOPE_HOST` / `HSCOPE_PORT` | `127.0.0.1` / `8000` | 服务器绑定。某些 Windows 机器保留 8000/8085–8184(WinError 10013)— 选择例如 `9137` |
| `HSCOPE_WORKSPACE_ROOT` | 仓库父目录 | 工作项惯例的相对路径解析根目录 |
| `HSCOPE_TIER_B_BACKEND` / `HSCOPE_TIER_B_MODEL` | `anthropic` / 默认后端 | Tier B 评估器提供商/模型(选择加入功能) |
| `HSCOPE_MCP_WRITE` | *(未设置)* | `1` 允许 MCP 服务器编辑**其自身**的工作区模型。未设置 ⇒ 只读 |
## 会话不是一个模型与自身对话
一个会话会生成子代理,它们在模型上运行,而父模型不运行。HarnessScope 收集此结构而不是将其展平:
- **子代理属于生成它的回合** — 以及恢复它的回合。Harness 在每个提示记录上都带有 `promptId`;子代理的头部记录带有其父回合的 `promptId`,而 `SendMessage` 继续带有后来的回合。所以链接是读取的,而不是从时间戳推断的。这个工作区中 15% 的子代理至少被恢复一次;它们的工作被计费到请求的回合。
- **一个回合是一个用户**。不是“任何带有文本的用户记录”:中断通知、`<command-name>` 回声和 `<bash-input>` 块也是用户记录,计算它们会使此工作区的回合总数膨胀 28%。
- **每个上下文窗口单独计数**。子代理读取父代理已经读取的文件时,它没有重新读取任何内容 — 它从未拥有过这些令牌。`tool_uses.agent_id` 保持边界,因此重新读取浪费(R3/R8)被计费到实际支付的上下文。
- **模型维度存活**。`session_report` 返回哪些模型运行,哪些仅在子代理中运行,以及每个模型的花费。
- **电路绘制往返**。子代理是一个带有生成边(谁运行,在哪个模型上)和返回边的节点 — 标记为返回的内容,这不是子代理**花费**的内容。一个真正的回合:三个 `general-purpose` 代理在 Opus 上花费 16.5k / 6.3k / 5.3k 输出令牌,并向父代理提供 1.5k / 2.2k / 2.0k。一个后台生成的工具结果仅是一个启动确认,因此其返回大小被报告为未测量而不是发明。子代理执行的工作被标记为 `sub`,永远不会折叠到父代理中。
- **每个请求一个使用记录 — 最后一个**。流式响应为一个 `requestId` 编写多个记录,早期记录带有部分 `output_tokens`(2,其中完成响应为 31,979)。仅按第一个出现次数 deduplicating 会使此工作区的输出减少 3.6%,而在子代理中更多。(两个独立键同意答案:max-per-`message.id` 和 last-per-`requestId` 均给出 32,348,242,而每个记录的朴素总和给出 90,957,147。)
- **共享请求被披露,而不是静默减去**。一个 fork、resume 或 compact 将 assistant 回合重播到第二个转录文本中。每个会话自己的总数都是正确的;汇总会话会将 API 调用计一次每次会话。`/api/summary` 报告 `shared_requests` 和 `shared_request_tokens`(此处:28 个调用,27,059 输出令牌,0.08% 总量)因此工作区数字从不假装成干净的总和。
## 工作区模型(可选但推荐)
没有模型,HarnessScope 运行在**中立预设**:具有空域值的通用规则,路径标签默认为文件名,会话渲染为扁平列表。在任何仓库中都不会崩溃 — 这是去域化合同。
使用模型(`~/.hscope/<workspace>/workspace-model.json`),您在一个 JSON 文档中声明您的仓库如何治理:
- `rules[]` — 具有您参数的 archetype 实例(关键词,阈值,标记)
- `roles[]` — 每个路径 / MCP 服务器 / 子代理的含义(标签,电路节点,主机边界)
- `gates[]` — 您的治理管道(例如 context-load → plan-approval → implement → verify → ledger)
- `unmeasurable[]` — 规范条款无法检查的内容(诚实显示而不是伪造)
- `work_items` — 会话的可选上级分组(此工作区:`plans/**` 文件带有状态 frontmatter;其他仓库可以将问题/PR 映射到同一个槽)。不存在 ⇒ 扁平会话。
模式和中立示例位于 `hscope/schema/` 中。使用以下命令验证您的模式:
```bash
python -m hscope.schema.validate_model ~/.hscope/<workspace>/workspace-model.json
```
## MCP 表面
任何 MCP 客户端都可以读取 HarnessScope 观察到的内容 — 然后循环关闭:一个代理通过读取上一个会话的评分来打开一个会话,而不是重新赚取该评分。
```jsonc
// .mcp.json
{ "mcpServers": { "harness-scope": {
"command": "python", "args": ["-m", "hscope.cli", "mcp", "--db", "/path/to/harness_scope.db"] } } }
```
| 工具 | |
|---|---|
| `list_sessions` · `session_report` · `token_hotspots` · `rule_health` | 查看器的数字 |
| `get_workspace_model` | 此仓库的治理方式,作为一个文档 |
| `get_setup_guide` · `suggest_roles` · `suggest_rules` | 编写规则的证据 |
| `set_role` · `set_rule` | 将它们写回 |
**此服务器中没有运行模型**。客户端**是**模型:`get_setup_guide` 将封闭的 archetype 库和每个 archetype 的参数模式交给它,`suggest_rules` 将交给它没有引用的规范条款,然后通过 `set_rule` 返回判断 — 参数根据 archetype 的模式进行验证后写入。所以 MCP 路径不需要提供者,不需要凭证,也不需要离机同意。`hscope compile` 以一个批量 LLM 调用完成相同的工作;这是它的对话式、增量对应方。
写入**默认关闭** (`HSCOPE_MCP_WRITE=1`),并且只能触及 `~/.hscope/<workspace>/workspace-model.json`。没有工具会写入项目文件或控制另一个代理 — HarnessScope 观察和评估;它不驱动。
## 验证 harnesses(完成定义)
合成转录文本测试套件,无需夹具。运行它们:
```bash
python -m hscope.verify_all # 发现所有 hscope/verify_*.py;CI 在 3 个 OS 上运行此命令
```
单独运行,适用于想要一个 harness 报告时(此列表是说明性的 — 上面的运行器是真相来源,因此永远不会运行不完的 harness):
```bash
python -m hscope.verify # P1 解析器(接受转录文本路径;不在 verify_all 中)
python -m hscope.verify_rules # 规则引擎(archetypes,评估,去域化)
python -m hscope.verify_circuit # 电路 API(节点,往返,门控通道)
python -m hscope.verify_work_items # 计划层次结构(推理,生命周期,守卫)
python -m hscope.verify_context_tiers # 声明的上下文注入层
python -m hscope.verify_workspace # 工作区 -> 会话模型解析
python -m hscope.verify_compile # `hscope compile`(离线;存根提供者)
python -m hscope.verify_defense # 解析器防御 / 宽容降级
python -m hscope.verify_mcp # MCP 表面(协议,写入门控,限制)
python -m hscope.verify_agents # 多代理 / 多模型收集(生成回合,上下文)
python -m hscope.verify_doctor # 每个不变式在其自身中断时触发,并且仅触发一次
python -m hscope.verify_firstrun # 零配置运行(端口发现,保留通知)
python -m hscope.verify_demo # demo 语料库:合成,ASCII,通过医生
python -m hscope.verify_ingest # 增量导入:什么**不**跳过
python -m hscope.verify_setup # 移交页面 + 一个 LLM 在 MCP 上闭环
python -m hscope.verify_i18n # 查看器字符串是英语规范的
python -m hscope.verify_scrub # 发布内容不携带域值
```
## `hscope doctor` — 检测漂移,而不是调漂
转录文本格式未公开且会变动:此语料库在 1 个月内声明了 **27 个 harness 版本**。hscope 读取它,因为它是唯一知道**含义**的接口 — 哪个回合,哪个代理,哪个文件。指标知道数量;账单知道钱;两者都不知道“子代理”一词。
所以漂移的答案不是无尽的调漂。而是一个失败时大声报错的名称,指出打破它的 harness 版本,而不是悄悄发出错误的数字:
```bash
python -m hscope.cli doctor --db harness_scope.db # 如果任何不变式被违反,则退出 1
```
九个不变式,每个在发货前都经过验证:一个回合开始记录带有 `promptId`;一个子代理行带有 `agentId`;计数的使用行是请求的**最终**使用;一个请求永远不会跨主文件和子代理文件;一个子代理位于一个回合,其父代理实际拥有;等等。
两样东西它拒绝做:
- **评估旧的 hscope 写入的行**。之后,“harness 省略了字段”和“我们从未存储它”是相同的缺失。会话由读取它们的模式戳记(`ingest_schema`)标记,旧的不被排除 **并且被计数**,永远不会混入。
- **报告空的通过**。零个违规行为超过零个可验证的行不是绿色勾选。
## 故障行为(优雅降级)
一个治理工具悄悄地检查出什么都没有,比一个工具停止运行更糟糕。所以:
| 情况 | 会发生什么 |
|---|---|
| 一行转录无法解析 | 被计数并报告为 `无法解析的行:N`。永远不会在沉默中丢弃。 |
| 构建不认识的记录类型 | 按类型计数并打印(`未知记录类型`)。继续摄入。 |
| 由 **较新** 的 hscope 编写的数据库 | 带有升级消息被拒绝。一个此构建忽略的列是一条规则,它会默默地停止检查。 |
| 架构版本之前的数据库 | 被迁移并标记。 |
| `--model` 指向一个不存在的文件 | 硬错误。输入错误类型不应静默地给出中性预设的数字,假装它们是您的。 |
| 工作区模型不可读、非对象或来自未来的 `schema_version` | 被拒绝并显示名称。在自动解析期间,其他模型仍会加载,每个跳过的模型都会打印原因。 |
| `$HSCOPE_WORKSPACE_MODEL` 不正确 | 查看器继续提供服务,没有角色,并且只说一次。(否则,空电路看起来与合规电路完全一样。) |
| 没有 `hscope compile` 的 LLM 提供程序 | 确定性结构 + 中性预设规则,提供程序的缺失被报告。 |
| MCP 工具调用被拒绝(未知工具、错误参数、关闭) | 作为 `isError` **内容** 返回,而不是协议故障。客户端读取原因并保持会话。 |
| MCP `set_rule` / `set_role` 将产生无效模型 | 不会写入。破坏其自身配置的治理工具会根据垃圾评估每个后续会话。 |
| 转录没有 `promptId`(早于该字段) | 回退到文本启发式,并且运行报告有多少次通过这种方式检测到。 |
| 子代理文件命名了一个主文件从未具有的 spawn 转 | 停在转 0 **并列出** 为 `未链接的子代理`。默默停放它会多算一个 spawn 出来的转。 |
| 数据库中存在会话,但其转录消失(约 30 天保留) | 重新摄入无法重建它。它被计数并报告为 `未重建`,因此两个版本的数据库永远不会看起来像一个。 |
| 子代理在后台启动 | 其返回的有效载荷大小未知(tool_result 是一个启动确认)。电路显示“后台”,永远不会是伪造的 token 计数。 |
| 子代理在主转录中未记录的提示下恢复 | 其行保持它们所在的转,并运行报告 `未链接的恢复:N`。 |
## 数据与隐私
- SQLite 数据库包含来自您的转录的**完整提示文本**。它被 gitignore (`*.db`) 并且必须保持本地 — 永远不要提交或上传它。
- 服务器默认绑定 `127.0.0.1` 并且对数据库只读。
- B 级(LLM 评判器)仅在您为该会话点击评判按钮时才会发送每个会话的摘要**到主机**;规则(`B1`)默认禁用。
## 许可证与开放核心边界
HarnessScope 是 **Apache-2.0 开放核心**。个人用户接触的一切都是永久免费的,没有功能限制 — 付费层级(如果/当它们存在时)只会为**组织**添加功能,永远不会为个人用户删除功能:
| 层级 | 免费(Apache-2.0 核心) | 企业(`ee/`,未来) |
|---|---|---|
| 捕获 | 转录摄入 + 钩子 | MCP 网关(跨平台捕获) |
| 分析 | 规则引擎 · 电路 · token 损失 · 覆盖率 — 所有这些 | 多用户聚合,组织仪表盘 |
| 安全 | 本地安全流规则(自我审计) | 组织合规报告,审计日志 |
| 账户 | 本地,单用户 | 单点登录 / 基于角色的访问控制 |
参见 `LICENSE`(Apache-2.0),`ee/README.md`(边界)和 `CONTRIBUTING.md`(DCO)。
## 仓库布局
```
hscope/ # Python 包:cli,parse(JSONL→SQLite),db,规则引擎,
# 工作项(计划层次结构),服务器(FastAPI),mcp(stdio),
# compile(规范→模型),tier_b,verify_*
hscope/schema/ # 工作区模型 JSON 模式 + 中性示例 + 验证器
web/ # React 查看器源(Vite);web/dist = 提交的构建
docs/ # 每个工作包的设计笔记
ee/ # 企业版边界(空占位符 — 参见 ee/README.md)
```
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器