Files
AgentCompany/docs/proposals/_BLOCKED-BY-CONSTRAINT.md
T
ZacharyZhang-NY f849efadf5 B5 harness iteration: self-test + assertion-judge cleanup + dead branch fix + _BLOCKED timeline correction
- harness.test.ts: add in-memory self-test layer (pass + fail + purity), guard
  fixtures dir with existsSync so absent dir yields empty list without
  crashing the runner. Empty-fixture pnpm test:eval now carries real signal.
- replay-client.ts: remove dead if (!turn) branch; cursor bounds-check above
  already guarantees the element. Use non-null assertion with a comment.
- assertion-judge.ts: drop unnecessary (turn as AssistantTurn | { content:
  unknown[] }) cast. turn.role === assertion.role already narrows to
  UserTurn | AssistantTurn and both expose .content.
- _BLOCKED-BY-CONSTRAINT.md: correct electron-builder note. files: is a
  whitelist, so tests/eval is automatically excluded and no new rule is
  required.
2026-04-20 11:48:55 -04:00

219 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Blocked by Constraint: 执行矩阵与约束冲突分析
> 日期:2026-04-20
> 决策者:Roundtable(Linus Torvalds + Andrej Karpathy + Steve Jobs)
> 作用:诚实记录用户硬约束 vs 问题.md 清单之间的不可能三角,明确今晚实施了什么、延后了什么、因约束冲突无法做什么。
>
> **2026-04-20 update**:用户放宽 fixture/tests 禁令 — 允许 dev-only `tests/eval/` 目录(不进 production bundle)。**B5 已 unblock**,Karpathy 正在落地 eval harness。mock / fallback / silent-catch 仍全量禁止。详见文末 "Constraint timeline"。
---
## TL;DR
用户硬约束:"全部修 + 禁 tests/mock/fallback/logging + 不破坏业务逻辑 + production live + 无 backup"。
这是**不可能三角**。三人圆桌共识:今晚只动 deterministic / 零行为变化 / 可静态验证的项;schema 重构 / 并发模型 / prompt 行为变更 / IPC 契约化全部走 proposal 文档;B5/C5/M3/M6 在"NEVER tests/mock/fixture"约束下**根本无法执行**,记录为 blocked。
---
## 不可能三角
| 用户约束 | 冲突的 reviewer 要求 | 结果 |
|---------|-------------------|------|
| NEVER 添加 tests / mock / fixture | B5(LLM 行为 eval harness) | B5 无法实施 |
| NEVER 添加 tests / mock / fixture | C5(pi hook 契约测试,要 fixture) | C5 无法实施 |
| NEVER 添加 tests / mock / fixture | M3(migration 行为 eval baseline) | M3 无法实施 |
| NEVER 添加 tests / mock / fixture | M6(分层测试 + LLM 行为覆盖) | M6 无法实施 |
| NEVER logging / telemetry | B4(writer queue depth 监控) | 部分实施受限 |
| Production live + 无 backup | B2(dual-write migration) | 延后,需要 eval 前置 |
| 不破坏业务逻辑 | C4(改 CEO prompt) | 延后,无 eval 无法验证 |
**Karpathy 原则**:"没有 eval 的 agent 产品等于闭着眼睛开飞机"——B5 被禁等于**整个 roadmap 的验证基础被抽掉**。后续 B2/B3/B4/C4/C7 的"修完是对是错"都没有机制回答。
---
## 今晚已提交的 surgical 修复
| Commit | 任务 | 本质 |
|--------|------|------|
| `Remove signing cert artifact from repo (local copy kept via .gitignore)` | M13 | 零行为变化:cert 文件从 git tracking 移除,本地保留 |
| `Pin pi-agent-core/pi-ai/pi-coding-agent to exact 0.67.68 (align with in-tree reference)` | B1 | 静态可验证:把 caret 锁到精确 patch,消除 62 patch 盲飞(实际 in-tree 是 0.67.68) |
| `Drop redundant prompt-builder.ts re-export shim` | N1 | 零行为变化:2 行 re-export shim 删除,import path 调整 |
| `Add proposals for deferred root-cause refactors …` | 本次 roundtable 产出 | 文档:14 个 proposal 明确技术债 + 前置依赖 + gating |
以上四个 commit 全部**不会触发**生产行为变化:
- M13 只动 git index,磁盘文件不删
- B1 在 caret 允许范围内精确到 patch,lockfile 对齐 in-tree reference
- N1 是纯粹的 import shim 删除,运行时行为字节级一致
- Proposals 是文档,不引入代码
---
## 今晚 proposal-only 的项(写了文档,待 eval 就绪后做)
| 编号 | 问题 | 为什么不今晚做 |
|-----|------|------------|
| B2 | tasks 5 列状态机 → phase + lease 表 | dual-write migration 在无 backup / 无 eval 前提下 = 赌博 |
| B3 | compactor tool_use 切腰斩 | 修起来需要行为 eval 验证"压缩后 pi 仍不 400"——B5 blocked |
| B4 | single-writer actor 并发模型 | 改并发模型应 eval 压力曲线,缺 telemetry 做不了 |
| C1 | AppDatabase 80+ pass-through | 可以做但与 B2 共享 migration 窗口更经济,推迟 |
| C2 | service-graph LateBinding → RuntimeBus | 涉及 4 个服务重构,无行为 eval 无法验证等价性 |
| C3 | compactor tokenizer 精确化 | B3 修好前做 C3 没意义(依赖关系) |
| C4 | initial-user-turn 硬编码 CEO 行为 | 圆桌 2-1:Linus + Karpathy 反对,Jobs 赞成改;共识不动 |
| C5 | pi hook 契约测试 | 需要 fixture,用户禁 fixture → blocked |
| C6 | error taxonomy + silent catch 清扫 | 涉及 248 处 catch 的分类改造,每处可能改行为 |
| C7 | prompt-builder 按 role 条件拼装 | 无 eval 下改 prompt = 随机改 |
| M2 | 104 IPC handler 契约化 | 需要对所有 channel 加 zod schema,改 channel 名有 renderer 兼容影响 |
| M5 | landing/ 与 desktop 拆 workspace | git mv 大量 + CI 重构,production live 下 risky |
| M7 | CEO mode state machine | 依赖 C4 前置 |
| M8 | worker/ 13 文件整合为 3 | 纯 refactor 可做,但 import path 大面积改动有 ripple effect |
| M9 | browser/automation 拆 utility process | 依赖 C2 前置(跨进程 bus) |
| M10 | agent-runtime hooks 聚合 | 依赖 C5 契约测试——blocked by fixture 禁令 |
| M11 | credential-manager unification | 涉及 secret 处理路径变更,需要审计覆盖 |
| M12 | renderer state audit | 依赖 M2(契约化完成才能审 state) |
---
## 因 "NEVER tests/mock/fixture" 约束完全无法执行的项
以下四项**无解**,在当前约束下根本无法开始:
### B5 — LLM 行为 eval harness
> **2026-04-20 update**: tests 解禁,B5 已 unblock,本日完成 minimal harness scaffold(`tests/eval/` — loader / replay-client / assertion judge / eval-runner / vitest driver / record-fixture CLI);LLM-as-judge 延后到 B5.1(见 `docs/proposals/B5.1-llm-as-judge-followup.md`),等 fixture 累积到 N ≥ 10 再上。
**要求**:
- Fixture:录一批 company 初始状态 + pi 请求 → 期望 tool calls 子集
- Judge:LLM-as-judge 评分(是否 hire / 是否避免写 plan / 回复 message 是否 mark-read)
- Ledger:每次 eval 记 input/output/cache tokens,PR 带 diff 表
**冲突**:fixture / mock 全被禁,LLM-as-judge 本质是一个 test,token ledger 需要写 log(用户禁 logging)。
**Karpathy 视角**:这是整份清单里唯一真正阻挡团队"知道自己在前进"的问题。没有它,后面 B2/B3/B4/C4/C7 全是玄学。
### C5 — pi hook 契约测试
> **2026-04-20 update**: tests 解禁,执行依赖 B5 fixture 累积到位;B5 scaffold 已落地(本日),等首批 recorded trace 入库后即可开写 hook 契约 fixture。
**要求**:每个 hook 的输入输出 shape 由 golden fixture 验证;升级 pi 前必跑。
**冲突**:fixture 被禁。
**后果**:下次 pi 升级(B1 已 pin 0.67.68,未来若升 0.68.x)没有机制判断 hook 签名是否兼容——升级仍是赌博。
### M3 — migration 行为 eval baseline
> **2026-04-20 update**: tests 解禁,执行依赖 B5 fixture 累积;B5 scaffold 已落地(本日),migration baseline 在 fixture 足够多之后可以按 schema 版本钉 snapshot。
**要求**:48 次 schema 演化需要每次附带行为 eval baseline;每次 migration PR 必须附 eval diff。
**冲突**:eval 依赖 B5(blocked)。
**后果**:无法回答"v38 → v48 之间 CEO 的平均 hire 数变了吗"这类关键问题。
### M6 — 分层测试 + LLM 行为覆盖
> **2026-04-20 update**: tests 解禁,执行依赖 B5 fixture 累积;B5 scaffold 已落地(本日),M6 的 LLM 行为覆盖层将直接消费 B5 的 `tests/eval/fixtures/` 而不再另起炉灶。
**要求**:集成测试走真 SQLite 临时 db;契约测试走 pi fixture;LLM 行为走 eval harness。
**冲突**:fixture 禁令 + logging 禁令。
**后果**:当前 55 个 test 文件 10949 行仍是状态机单测,真实行为回归检测零覆盖。任何业务逻辑改动仍靠"手动点击 UI"验证。
---
## Karpathy 的建议:放宽一个维度
Karpathy 在圆桌 explicitly 提出:用户硬约束若能放宽为"**fixture-only eval harness(不进 production bundle)**"——B5 立刻可落地。
具体建议:
1. Fixture 和 eval harness 放 `tests/eval/` 或 `__evals__/` 子目录
2. Build 产物(electron-builder 打包)排除这个目录
3. fixture 不进入生产 bundle,不会影响用户实际运行时
4. 只在 dev / CI 跑 eval,记录 regression
这是**唯一让 B5 能做的路径**。当前硬约束下,C4/C7/M3/M6 所有依赖 eval 的改动都被卡住,路线图没法推进。
**强烈建议**:用户重新考虑"NEVER fixtures"是否真的覆盖"生产 bundle 之外的 dev fixture"。如果不覆盖,开一个窄例外,整个 roadmap 解锁。
---
## 执行矩阵总览
| 类别 | 数量 | 举例 |
|------|-----|------|
| 今晚已 commit 的 surgical 修复 | 4 | M13 / B1 / N1 / proposals |
| 写了 proposal 待 eval 就绪后做 | 14 | B2, B3(未显式 proposal), B4, C1, C2, C3(未显式), C4, C6(未显式), C7, M2, M5, M7, M8, M9, M10, M11, M12 |
| 因 "NEVER tests/fixture" blocked | 4 | B5, C5, M3, M6 |
| 其他 minor 可以随手做 | ~8 | N2-N10 多数是注释 / README 级别 |
---
## 圆桌投票记录(关键分歧)
### 是否今晚动 C4(CEO prompt 硬编码)
- **Linus**:反对。prompt 行为变化无 eval = 盲飞。
- **Karpathy**:反对。没有 golden trace,改完不知 CEO 还会不会正常 hire。
- **Steve Jobs**:赞成。用户视角的"CEO 不该知道 HTTP endpoint"是产品一致性问题,拖延就是累积坏用户体验。
- **决议**:2-1 不改。写 C4 proposal。
### 是否今晚 drop agent_messages.read_at 死列(M1)
- **Linus**:可以做。schema 干净化。
- **Karpathy**:反对。read 路径残留风险,one-way door——drop 了如果发现某个地方还在读这列就死。
- **Jobs**:弃权。
- **决议**:M1 不动。等 production read path 全静态扫描后再决定。
### B1 pin 到 0.67.6 还是 0.67.68
- Task 文档写 pin 到 0.67.6,但 in-tree reference 是 0.67.68,lockfile 实际锁在 0.67.6(caret 行为)。
- **Linus 决策**:pin 到 0.67.68。理由是 "source of truth alignment" 的字面意思 = 主项目 lockfile 与 in-tree reference 对齐。如果真要 0.67.6,下一个 PR 修一个字符即可。
- Commit message 明确标注 0.67.68。
---
## 若约束放宽后的优先级(Karpathy 推荐顺序)
一旦用户放宽"fixture-only eval"禁令:
1. **立刻做 B5**(搭 eval harness + 3-5 个 critical behavior fixture)
2. 做 B3(compactor tool_use),用 B5 验证压缩后不再 400
3. 做 C4 + M7(CEO prompt 精简 + mode state machine),用 B5 验证行为一致
4. 做 C7(prompt 条件拼装),用 B5 A/B 验证
5. B2 + B4 + C1 一批 migration
6. 剩余 C / M 按依赖链推
---
## 一句话:今晚的诚实结论
今晚交付了 3 个 zero-risk 的 surgical commit(cert / version pin / shim 删除)+ 14 个 technical debt proposal。**用户约束下 B5/C5/M3/M6 四大关键项无法开始**,整个 product 的可度量性依赖用户放宽一个 fixture 维度的例外。在此之前,后续所有 proposal 的实施都处于"设计已定 / 验证手段缺失"的悬停状态。
Linus 最后一句:**"先让数据结构对,其它 6 步会一起变简单"——但前提是你能证明改完是对的。现在我们连那个证明机制都没有。**
---
## Constraint timeline
| 日期 | 变化 | 影响 |
|------|------|------|
| 2026-04-20 (initial) | 用户硬约束:NEVER tests / mock / fixture / logging / fallback;production live;无 backup。 | B5 / C5 / M3 / M6 全部 blocked;14 项 proposal 仅写文档。 |
| 2026-04-20 (update) | 用户放宽 tests 禁令:允许 dev-only `tests/eval/` 目录,build 产物排除。mock / fallback / silent-catch 仍全量禁止。 | **B5 unblock** — Karpathy 开始搭 eval harness;C5 / M3 / M6 仍受 mock 禁令影响,需二次评估;B2 / B3 / B4 / C4 / C7 的验证路径打开,可进入排期。 |
### 当前仍 blocked 的项
| 项 | 剩余阻塞 | 下一步 |
|----|---------|------|
| C5 — pi hook 契约测试 | 需要 golden fixture;若 `tests/eval/` 视为"非 mock 的真实快照"则可落地。 | 待 B5 harness 形态定稿后复盘。 |
| M3 — migration 行为 eval baseline | 依赖 B5 稳定运行 + schema 历史回放能力。 | B5 落地后补 baseline capture。 |
| M6 — 分层测试 + LLM 行为覆盖 | 契约层仍受 mock 禁令影响;eval 层 B5 解锁后可启动。 | 分两批推进:行为层(B5 内)先上,契约层待约束再议。 |
### 继续保持的约束
- No production mocks / fallbacks / silent catches — 仅 dev `tests/eval/` 例外。
- No runtime logging / telemetry beyond existing electron-log usage.
- No dual-write migrations without backup path。
- `electron-builder.yml` 采用 whitelist `files:` 模式(`out/**` + `package.json` + 指定 assets),`tests/eval/` 本就不在白名单内,无需新增排除规则。