27 KiB
U3 r0.6 Transport Completion Evidence Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: 在当前 MiniMax-M3 工具流上留下可重放、无内容的 HTTP 响应体与 SSE 业务终态分层证据,同时保持缺 [DONE] 时工具零执行。
Architecture: Agent-Native 在现有 Client.Stream → ParseSSE 链路里流式计数响应体并归类最后的 SSE 结构,合成一条只含有限枚举、布尔和饱和计数的 TerminalObservation。Backend 受控评测白名单归一化该观察,与实际 run ID、调用号和 Usage 一起落到受限记录;普通用户界面仍只展示任务卡的真实状态与有来源成果。此版不把 HTTP EOF 变成工具放行条件,也不修改模型路由或加请求。
Tech Stack: Go 1.27、net/http/httptest、Agent-Native OpenAI 兼容 SSE、Backend 受控评测与 SQLite、任务自有 Playwright 机制实例、Dev 组合测试和 Gitea CI。
Spec: 已获阶段 4 人工批准的 r0.6 书面设计。批准对象 Documents 54d39ef13034b2ce84cb84681566ea21311f79a0、Dev 89125b8dda5f8f988a8a760ed64bf00827e1de5c;用户答复“批准设计,继续实施计划”。本计划本身待阶段 5 人工评审;该答复只授权编写计划,不授权以下代码步骤、付费探针、A01、合入或部署。
Global Constraints
- 范围固定为已核验的 MiniMax-M3、
api.minimaxi.com/v1、无 fallback 的路由身份(保护文件 SHA-2562a92569d2416d74e8d07029219af88474cb6f860c2aa897a5ffdd10fcbe9b495)。代码观察可以复用在 OpenAI 兼容客户端,但解释与未来兼容决策只针对该路由;路由字节或模型改变须重新评审。不得把 API key、路由文件原文或供应商数据写进仓库与收据。 - 保持
toolFinishExecutable原有判据:缺[DONE]、读错、取消、半帧、工具身份或 JSON 对象参数不完整时,不释放或执行工具;不新增自动重试、补参数、模型回退、摘要模型调用或额外 provider 回合。文本缺标记的既有容忍路径不得扩给工具。 - 新观察只保存有限枚举、布尔和饱和计数。不得保存原始 SSE/尾部字节及其内容哈希、正文、思考、prompt、工具名/参数、HTTP header/trailer 名称或值、URL 查询、IP、请求 ID、证书细节、API key、原始错误句。诊断不进入普通用户 UI,异步状态仍由原所有者按 seq 处理。
- Agent-Native 的终态事件是唯一诊断来源;Backend 只白名单消费并保留已返回 Usage、实际 run ID、停止边界。既有公开 Core/HTTP/TaskSnapshot 合同、数据库表、前端状态 owner、r0.5 宿主确认及来源判定不改。若证明必须改公开契约、权限、持久模式或 UI,停止受影响单元,返回设计评审;UI 修改前先读 Dev
DESIGN.md并使用@ui令牌/原语。 - r0.5 唯一付费探针已消耗授权,结果
incomplete_terminal、返回 Usage 513、工具 0;r0.4 A01 仍 FAIL,r0.5 真实 A01 仍NOT_RUN。本计划实施阶段只跑假流、真实本地 HTTP/浏览器与隔离 PG/CI,不运行TestWorkCheckpoints、不使用WORK_CHECKPOINT_SERVER_MODE=model、不读取保护路由 key。新的供应商试验和 A01 均须候选固定后另交资源提案并获明确批准。 - 每个源代码单元先 RED、再最小 GREEN、再组件测试与提交;证据经 Dev
make evidence保存,例如RECEIPT=/tmp/fast-slow-u3-r06-task1-red.json CMD='GOWORK=off go -C deps/agent-native test ./runtime/llm -run TestClientBodyBoundary -count=1' make evidence,来源为 SELF。每次换一个未使用的收据路径。独立审阅重跑为 REPLAY;准确 HEAD CI 为 GATE。正式用户验收与所有 PR 合入仍在后续阶段,八个 PR 维持草稿。
Review Focus
以下五类容易被“有 EOF/有 Usage”掩盖的输入必须由相应任务的测试直接覆盖:
- 声明长度大于实际响应体:
TestClientBodyBoundaryShortRead(Task 1)应记读取错误或长度不符,仍零工具。 - 自动 gzip 解压使线上长度不可直接比:
TestClientBodyBoundaryUncompressed(Task 1)应记长度关系unknown,不能伪造匹配。 - 合法
[DONE]在客户端未读到 HTTP EOF 前出现:TestClientDoneDoesNotNeedBodyEOF(Task 1)应维持原有合法工具终态,不把新观测变成额外放行门槛。 - Usage 后出现注释、空
data:、未知非 JSON 或半帧:TestSSETailStructure(Task 2)只记结构类别,不泄漏原文;缺[DONE]的工具仍零释放。 - 上游或测试注入未知枚举、负数、超上限计数:
TestEvaluationTransportObservationSanitized(Task 3)应归unknown/钳制计数,不让供应商可控文字入评测记录。
File Ownership Map
| 文件/组件 | 单一职责 |
|---|---|
Agent-Native runtime/llm/body_observation.go、client.go |
只观察 HTTP 响应体读取与有限传输类别,不碰 SSE 内容或工具准入 |
Agent-Native runtime/llm/sse.go、types.go |
SSE 尾部结构、现有 [DONE] 门禁及一个终态观察合同 |
Backend internal/server/work_checkpoint_eval_test.go |
在既有受控评测记录边界深拷贝并白名单化 Agent-Native 标量 |
| Agent-Squad/Backend/Dev gitlinks | 使各消费方固定同一已提交 Native SHA;Dev 验证真实组合 |
| Frontend 既有 Playwright 文件 | 只重放用户可见状态;本计划不修改前端生产代码 |
Task 1: Agent-Native 流式 HTTP 响应体观察
Files:
- Create:
deps/agent-native/runtime/llm/body_observation.go(只计数和归类,不缓冲响应内容) - Modify:
deps/agent-native/runtime/llm/types.go(TerminalObservation.BodyBoundary加法字段) - Modify:
deps/agent-native/runtime/llm/client.go(在既有响应上附观察,不改请求体/重定向/重试) - Test:
deps/agent-native/runtime/llm/client_test.go
Interfaces: TerminalObservation.BodyBoundary *BodyBoundaryObservation;BodyBoundaryObservation 只包含 ProtocolClass(http1|http2|other)、FramingClass(known_length|chunked|http2_stream|close_delimited|unknown)、DeclaredLengthKnown、饱和的 BytesRead、BytesSaturated、EOFSeen、LengthRelation(match|mismatch|unknown)及 Uncompressed。ParseSSE(ctx, io.Reader) 的签名、Event.StreamComplete 和工具门禁不变;独立调用 ParseSSE 时 BodyBoundary=nil。
- Step 1: 写 RED。 在
client_test.go增加上述三个 Review Focus 测试与TestClientBodyBoundaryChunkedAndHTTP2。用httptest.NewServer显式设置正确/过长Content-Length,用Flush生成 chunked,httptest.NewUnstartedServer+EnableHTTP2+StartTLS生成 HTTP/2;gzip 用gzip.NewWriter返回压缩体。TestClientDoneDoesNotNeedBodyEOF复用本文件已有的terminalRoundTripFunc,返回含[DONE]、但不要求随后读取到io.EOF的本地http.Response,避免依赖真实网络调度。工具帧为本地固定 JSON;无[DONE]的用例必须同时断言len(end.Message.ToolCalls)==0、返回 Usage 不丢、HTTPStatus 200。合法[DONE]用例必须保留当前可释放的 ToolCalls。测试只用本地假响应,不使用保护路由。
// 关键断言形状;同一表驱动覆盖已知长度、chunked、HTTP/2、gzip、短读。
if end.TerminalObservation == nil || end.TerminalObservation.BodyBoundary == nil {
t.Fatal("missing body boundary observation")
}
body := end.TerminalObservation.BodyBoundary
if body.FramingClass != wantFraming ||
body.LengthRelation != wantLengthRelation || body.EOFSeen != wantEOF {
t.Fatalf("wrong body boundary: %+v", body)
}
if !wantDone && (end.StreamComplete || len(end.Message.ToolCalls) != 0) {
t.Fatalf("unfinished tool stream was released: %+v", end)
}
- Step 2: 记录 RED。 在 Dev 工作树运行
GOWORK=off go -C deps/agent-native test ./runtime/llm -run '^(TestClientBodyBoundary.*|TestClientDoneDoesNotNeedBodyEOF)$' -count=1,由 Devmake evidence保存原始 SELF 失败;预期因BodyBoundary字段/分类尚不存在而编译失败,不改测试绕过。 - Step 3: 最小 GREEN。 在
types.go定义上面的导出结构;body_observation.go用io.Reader包装resp.Body,仅对Read返回的n累加,饱和上限32*1024*1024+1,记录io.EOF,绝不复制p[:n]。以resp.ProtoMajor、ContentLength、TransferEncoding、Close和Uncompressed归类;已知长度只在未自动解压、未饱和且读到 EOF 时比较,其他情况记unknown。client.run对一次http.Client.Do的成功响应把计数器传给ParseSSE,只在终态事件附上快照;HTTP 错误/请求前错误仍保留原错误分类。
type BodyBoundaryObservation struct {
ProtocolClass, FramingClass string
DeclaredLengthKnown bool
BytesRead int64
BytesSaturated, EOFSeen bool
LengthRelation string
Uncompressed bool
}
// 现有 TerminalObservation 追加:BodyBoundary *BodyBoundaryObservation `json:"bodyBoundary,omitempty"`
- Step 4: 跑 GREEN 与边界。 重跑 Step 2;再从 Dev 运行
GOWORK=off go -C deps/agent-native vet ./runtime/llm与GOWORK=off go -C deps/agent-native test ./runtime/llm -count=1。补一例关闭分隔/无法可靠判断的响应,必须为unknown;检查取消、HTTP 4xx、重定向和读取失败都不产生虚假的EOFSeen=true。resp.Body.Close的结果不得被解释成业务流已完成。 - Step 5: 提交 Agent-Native Task 1。 仅提交列出的结构、读取包装和测试,英文祈使句主题及 Why/Evidence/Impact/Refs 正文;推送现有 Agent-Native 草稿 PR #46,核对准确组件 HEAD 的 CI。此时
BodyBoundary仍不影响工具执行。
Task 2: Agent-Native SSE 尾部结构分类
Files:
- Modify:
deps/agent-native/runtime/llm/types.go(TailEventKind、TailEventCount) - Modify:
deps/agent-native/runtime/llm/sse.go(在现有 reader/解析器内部统计结构,不存 data 内容) - Test:
deps/agent-native/runtime/llm/sse_test.go
Interfaces: TerminalObservation.TailEventKind 为 done_literal|json_frame|empty_data|comment|unknown_non_json|partial_frame|unknown,TailEventCount 饱和到 10000。它们与 Task 1 的 BodyBoundary 并列,不能设置 StreamComplete 或绕过 toolFinishExecutable。sseEventReader.next() 可在内部增观察状态,但不改公开 ParseSSE 签名。
- Step 1: 写 RED。 新增
TestSSETailStructure表驱动假流:合法 JSON+Usage 后分别接注释、空data:、data: NOT_DONE、截断data: {;另加[DONE]与纯文本无[DONE]正常对照。每例断言精确尾部枚举、计数范围、ReadOutcome、StreamComplete和已返回 Usage;缺[DONE]或坏帧时工具调用零释放,合法[DONE]工具对照仍释放一条但本测试不执行工具。序列化观察不得含PRIVATE_TAIL_R06哨兵。TestSSETailCountSaturates连续发超过 10000 个无内容注释并检查计数不溢出。
| 两个 JSON 帧后的尾部(纯文本例只有一个 JSON 帧) | TailEventKind |
TailEventCount |
ReadOutcome |
|---|---|---|---|
[DONE] |
done_literal |
3 | done_marker |
| 直接 EOF | json_frame |
2 | clean_eof |
| 单独注释后 EOF | comment |
3 | clean_eof |
空 data: |
empty_data |
3 | invalid_frame |
data: NOT_DONE |
unknown_non_json |
3 | invalid_frame |
截断 data: { |
partial_frame |
3 | invalid_frame |
| 单个纯文本 JSON 后 EOF | json_frame |
1 | clean_eof |
got := end.TerminalObservation
if got == nil || got.TailEventKind != wantKind || got.TailEventCount != wantCount {
t.Fatalf("wrong tail observation: %+v", got)
}
raw, err := json.Marshal(got)
if err != nil || strings.Contains(string(raw), "PRIVATE_TAIL_R06") {
t.Fatalf("unsafe tail observation: %s err=%v", raw, err)
}
if wantToolRejection && len(end.Message.ToolCalls) != 0 {
t.Fatal("tail evidence released an incomplete tool")
}
- Step 2: 记录 RED。 从 Dev 运行
GOWORK=off go -C deps/agent-native test ./runtime/llm -run '^(TestSSETailStructure|TestSSETailCountSaturates)$' -count=1;用 Dev evidence 收据保存失败,预期新字段缺失。 - Step 3: 最小 GREEN。
sseEventReader在完成一个结构事件时更新有限tailKind和饱和tailCount;emitParsed在成功 JSON、字面[DONE]、空 data、非 JSON 与 JSON 末尾截断时归类。仅以json.SyntaxError的类别/结束位置区分partial_frame与其他unknown_non_json,不能记录错误原句或帧字节。注释在 reader 中计数但继续保持原忽略行为;超出计数上限只饱和。observation()把标量送到原终态事件,绝不修改sawDone的唯一设置点。
const maxObservedTailEvents = 10000
func noteTail(kind string, count *int, last *string) {
if *count < maxObservedTailEvents { *count = *count + 1 }
*last = kind
}
// sawDone 仍仅在 data == "[DONE]" 分支设为 true。
- Step 4: 跑 GREEN 与全量组件回归。 重跑 Step 2,另外从 Dev 运行
GOWORK=off go -C deps/agent-native vet ./...与GOWORK=off go -C deps/agent-native test -count=1 ./...,保留现有多片工具参数、缺[DONE]、读错、取消、纯文本与合法[DONE]正反例。检查单次流只发一个终态,且新增字段不带未知文本。 - Step 5: 提交并推送 Agent-Native Task 2。 只提交本单元差异;当前 Agent-Native HEAD 成为 Backend/Agent-Squad 的唯一嵌套 pin,等待其准确 HEAD CI。若本地假流暴露解析器确实漏认合法结束形式,仅记录发现并回到方案评审,不能顺手放宽工具门禁。
Task 3: Backend 无内容归一化与失败后停止
Files:
- Modify:
modules/backend/deps/agent-native(固定 Task 2 Agent-Native SHA) - Modify:
deps/agent-squad/deps/agent-native、modules/backend/deps/agent-squad(先固定 Agent-Squad 的相同 Native SHA,再由 Backend 消费) - Modify:
modules/backend/internal/server/work_checkpoint_eval_test.go(evalTerminalObservation白名单复制) - Test:
modules/backend/internal/server/work_checkpoint_eval_budget_test.go(现有livetag、本地 fake provider)
Interfaces: 消费 Task 1/2 的 TerminalObservation.BodyBoundary、TailEventKind、TailEventCount,只写入既有 evalCallRecord.TerminalObservation;evalCallRecord 的 run ID/调用号/Usage/failureClass 及 Backend 预算停止逻辑不变。必须深拷贝嵌套观察并将所有字符串缩至已定义枚举、负数钳为 0、过大计数钳至 Agent-Native 上限。没有公开 API、数据库或生产模型路由改动。
- Step 1: 固定消费依赖。 在 Agent-Squad 草稿分支将
deps/agent-native固定到 Task 2 的提交,从 Dev 运行GOWORK=off go -C deps/agent-squad vet ./...、GOWORK=off go -C deps/agent-squad test -count=1 ./...,提交并推送 PR #53。随后在 Backend 草稿分支将嵌套deps/agent-native与deps/agent-squad固定到这两个已提交的 SHA;用git rev-parse HEAD分别核对组件及嵌套指针,不以游离工作树代码作为依赖。Dev 的完整make test-pins留到 Task 4 暂存最新三条主 gitlink 后再运行。 - Step 2: 写 RED。 在
work_checkpoint_eval_budget_test.go新增TestEvaluationTransportObservationSanitized:fake provider 传入TailEventKind="PRIVATE_TAIL_R06"、ProtocolClass="PRIVATE_HEADER_R06"、负数/超上限计数和含正文的终态,同时给出 Usage 17;断言新provider-records.json只有归一后的unknown、0/上限、run ID 和 Usage,不含哨兵、原始messages/terminal。再加TestEvaluationTransportEvidenceStopsAfterUnmarkedToolEOF:fake provider 仿照当前 Agent-Native 的失败终态发KindMessageEnd、StopReason=StopError、非 nilErr、FinishReason=tool_calls、Usage17、ReadOutcome=clean_eof、StreamComplete=false、空 ToolCalls;第二次请求被拒,provider 调用数仍 1、落盘 Usage17、工具 0。沿用现有TestEvaluationStopsAfterMalformedToolTerminal的停止构造。
clean := evalTerminalObservation(terminal.TerminalObservation)
if clean.TailEventKind != "unknown" || clean.BodyBoundary.ProtocolClass != "other" ||
clean.TailEventCount < 0 || clean.BodyBoundary.BytesRead < 0 {
t.Fatalf("unbounded observation: %+v", clean)
}
if strings.Contains(string(recordJSON), "PRIVATE_TAIL_R06") || providerCalls.Load() != 1 {
t.Fatal("content leaked or a failed terminal caused another request")
}
- Step 3: 记录 RED。 只运行本地假 provider:从 Dev 执行
GOWORK=off go -C modules/backend test -tags live ./internal/server -run '^(TestEvaluationTransportObservationSanitized|TestEvaluationTransportEvidenceStopsAfterUnmarkedToolEOF)$' -count=1,用 Dev evidence 保存原始失败。不得运行宽泛go test -tags live ./...、TestServeWorkCheckpointEval的model模式或任何受保护路由。 - Step 4: 最小 GREEN。
evalTerminalObservation从输入构造新TerminalObservation,分别白名单ReadOutcome/TailEventKind、BodyBoundary 的ProtocolClass/FramingClass/LengthRelation,再复制布尔与钳制计数;未知协议类归other,未知其他枚举归unknown。不给evalCallRecord加原始 Event、header/trailer 或错误消息。先持久化 Usage 与失败记录,再按现有 gate 放行终态;记录失败仍阻止后继调用。
func clampCount(value, limit int64) int64 {
if value < 0 { return 0 }
if value > limit { return limit }
return value
}
// 对 *observation.BodyBoundary 深拷贝后逐字段白名单,不保留输入指针。
- Step 5: 跑 GREEN 与控制组。 重跑 Step 3,并从 Dev 运行
GOWORK=off go -C modules/backend test -tags live ./internal/server -run '^(TestEvaluationRecordsContentFreeTerminal|TestEvaluationRedactsProviderControlledTerminalLabels|TestEvaluationStopsAfterMalformedToolTerminal|TestEvaluationKeepsUsageOnTerminalFailure|TestEvaluationStopsWhenProviderRecordUnavailable)$' -count=1;再运行 BackendGOWORK=off go -C modules/backend vet ./...、GOWORK=off go -C modules/backend test -count=1 ./...。go test -tags live的每条命令都必须有上述精确锚定的-run,不触发真实模型样本。 - Step 6: 提交 Backend。 将已固定的 Agent-Native/Squad gitlink 与归一化代码、测试一起提交到现有 Backend 草稿 PR #193;核对 Backend 真实 HEAD、Agent-Native/Squad 嵌套 pin 和组件 CI,保持两个消费方使用同一 Native SHA。
Task 4: 组合重放、独立审阅与阶段 6 候选
Files:
- Modify: Dev
deps/agent-native、deps/agent-squad、modules/backendgitlinks - Modify: Dev
.task/feature-fast-slow-u2-u3-plan.md、PROJECT.md和 Documentsdocs/reports/2026-10-13-fast-slow-u2-u3-validation.md(只记录实际结果) - Test without product edits:
modules/frontend/e2e/work-checkpoints.playwright.ts的现有宿主确认、失败和来源场景
Interfaces: 固定 Task 1–3 的精确 Agent-Native/Agent-Squad/Backend SHA;不变更 Frontend/UI/Core 的公开契约或代码。Dev、Backend 和 Squad 的嵌套 Agent-Native gitlink 必须同值,Backend 嵌套 Squad 指针与 Dev 同值;平台 PR 都保持草稿。任务自有 HTTP 机制实例必须 WORK_CHECKPOINT_SERVER_MODE=mechanism,不得接入业务实例或真实模型。
- Step 1: 固定 pin 并跑组合。 Agent-Native → Agent-Squad/Backend → Dev 按依赖顺序提交并推送;Dev 暂存实际 gitlink 后用 evidence 分别运行
make test-pins、make test、make build。文档记录准确 SHA、原始退出码及来源,任何子仓未提交的工作树差异不能冒充 pin。若上游主干推进,按 Devmake task-sync解决冲突并据影响重跑。 - Step 2: 建立任务自有机制实例。
modules/frontend/e2e/work-checkpoints.playwright.ts与TestServeWorkCheckpointEval都要求数据目录名含fast-slow-u2-u3-。先验证/tmp/fast-slow-u2-u3-r06-20261014不存在,创建 0700 目录;在 Dev 工作树执行下面的命令。mode=mechanism使用代码内 fake stream;env -u确保旧模型路由和 A01 标签不被继承。将启动命令与 PID 写入 SELF 收据,不把 server 日志中的模拟内容当成供应商证据。
R06_RUN_ROOT=/tmp/fast-slow-u2-u3-r06-20261014
mkdir -m 0700 "$R06_RUN_ROOT"
GOWORK=off go -C modules/backend test -tags live -c -o "$R06_RUN_ROOT/server.test" ./internal/server
R06_DEV_SHA=$(git rev-parse HEAD)
R06_BACKEND_SHA=$(git -C modules/backend rev-parse HEAD)
env -u WORK_CHECKPOINT_ROUTE_FILE -u WORK_CHECKPOINT_EXTRA_A01 \
WORK_CHECKPOINT_SERVER_MODE=mechanism \
WORK_CHECKPOINT_SERVER_DATA="$R06_RUN_ROOT/mechanism-data" \
WORK_CHECKPOINT_SERVER_MANIFEST="$R06_RUN_ROOT/manifest.json" \
WORK_CHECKPOINT_MECHANISM_NOTICES=1 \
WORK_CHECKPOINT_DEV_SHA="$R06_DEV_SHA" WORK_CHECKPOINT_BACKEND_SHA="$R06_BACKEND_SHA" \
"$R06_RUN_ROOT/server.test" -test.run '^TestServeWorkCheckpointEval$' \
>"$R06_RUN_ROOT/server.log" 2>&1 &
R06_SERVER_PID=$!
printf '%s\n' "$R06_SERVER_PID" >"$R06_RUN_ROOT/server.pid"
chmod 0600 "$R06_RUN_ROOT/server.pid"
- Step 3: 验证实例身份并启动预览。 从任务自有
server.pid读取R06_SERVER_PID;用python3 -c 'import json; print(json.load(open("/tmp/fast-slow-u2-u3-r06-20261014/manifest.json"))["base"])'取本地 API;核对 manifest PID、binary与/proc/$R06_SERVER_PID/exe、binarySHA256与sha256sum、Dev/Backend SHA 与当前 HEAD。另分别用git -C deps/agent-native rev-parse HEAD、git -C deps/agent-squad rev-parse HEAD及 Backend 嵌套 gitlink 对照 Dev pin;当前 manifest 不包含 Native/Squad 字段,不能声称它自己已核对这两个 SHA。确认127.0.0.1:4186未被占用后运行下面的 preview;若端口被占,停在本步骤并选一个新的任务自有端口,记录实际值,不连接已有服务。
R06_RUN_ROOT=/tmp/fast-slow-u2-u3-r06-20261014
R06_SERVER_PID=$(cat "$R06_RUN_ROOT/server.pid")
for R06_WAIT in $(seq 1 80); do
test -s "$R06_RUN_ROOT/manifest.json" && break
sleep 0.25
done
test -s "$R06_RUN_ROOT/manifest.json"
R06_API_BASE=$(python3 -c 'import json; print(json.load(open("/tmp/fast-slow-u2-u3-r06-20261014/manifest.json"))["base"])')
python3 -c 'import socket; s=socket.socket(); s.bind(("127.0.0.1",4186)); s.close()'
PLAYWRIGHT_API_TARGET="$R06_API_BASE" npm --prefix modules/frontend run preview -- --host 127.0.0.1 --port 4186 --strictPort \
>"$R06_RUN_ROOT/preview.log" 2>&1 &
R06_PREVIEW_PID=$!
printf '%s\n' "$R06_PREVIEW_PID" >"$R06_RUN_ROOT/preview.pid"
chmod 0600 "$R06_RUN_ROOT/preview.pid"
for R06_WAIT in $(seq 1 80); do
curl -fsS -o /dev/null http://127.0.0.1:4186/ && break
sleep 0.25
done
curl -fsS -o /dev/null http://127.0.0.1:4186/
- Step 4: 跑浏览器并清理任务实例。 在 Frontend 工作树运行下面的命令,核对可信首回合、零/部分失败、来源、刷新和 390px 窄屏;不改变现有 UI 文案、焦点或 seq 投影。使用 Dev
make evidence的源码外收据捕获完整输出,保存 trace;核对server.pid、preview.pid和/proc身份后,只停止这两个任务自有进程。
PLAYWRIGHT_BASE_URL=http://127.0.0.1:4186 \
WORK_CHECKPOINT_HTTP_MANIFEST=/tmp/fast-slow-u2-u3-r06-20261014/manifest.json \
npx playwright test e2e/work-checkpoints.playwright.ts --reporter=list
- Step 5: 隔离 PG 与 CI。 Dev 必需
test-pg作业在新容器中启动真实 PostgreSQL/Redis,执行make test-backend-pg和双进程生命周期;不得把 SQLite 或 SKIP 当成 PG。先核对 Agent-Native #46、Agent-Squad #53、Backend #193 以及 Dev #512 的准确 HEAD CI,再核对 Dev 的test、test-pg、svc-realcombo三项作业和全部步骤在同一最新 Dev HEAD 成功,记录 GATE 运行链接、runner 和 SHA。若本地另起隔离 PG,先查数据根/实例 PID 与 DSN 身份,不能连接现有 8788 实例。 - Step 6: 独立复审。 未参与实现的审阅者对固定候选重跑 Task 1 的已知长度/gzip/DONE 对照、Task 2 的尾部结构、Task 3 的脱敏/停止最小集,先读命令×SHA×输出再读作者解释;审阅重点是正常 HTTP 结束不被写成 SSE 完成、未知类别不落原文、JSON 对象不被说成 schema 有效、缺
[DONE]零工具且 Usage 保留。Critical/Important 闭合并在实际新 HEAD 补测之前,不提交阶段 6 结论。 - Step 7: 提交阶段 6 人工评审材料。 任务卡与 Documents 核验报告映射 r0.6 设计条款 → 文件/测试 → SELF/REPLAY/GATE 证据,写明真实 MiniMax 再测和 r0.5 A01
NOT_RUN、r0.4 FAIL、当前路由原因仍可能unknown。给用户审阅零付费机制候选;即使阶段 6 通过,仍须单独资源提案才可进行新的真实请求,再经阶段 7 人工验收。安全/质量失败时八个 PR 继续草稿,不合入或部署。
Plan Self-Review And Stop Conditions
| r0.6 设计条款 | 实施/验证归属 |
|---|---|
| HTTP 响应体协议、定界、读数、EOF 与未知处理 | Task 1 的 BodyBoundary、已知长度/gzip/chunked/HTTP2/DONE 对照 |
SSE 尾部结构、不泄漏未知帧、缺 [DONE] 继续拒绝 |
Task 2 的 TailEventKind、饱和计数和无标记反例 |
| 实际 run ID/Usage、有限白名单、失败后零后继请求 | Task 3 的归一化与 fake provider 拒绝测试 |
| 普通用户界面、来源、失败状态和 seq 不回退 | Task 4 的任务自有 HTTP/Playwright 与准确 HEAD 组合 |
| 供应商契约不足时不放宽、真实 A01 另审 | Global Constraints、Task 4 阶段 6 材料与以下停止条件 |
Task 1 拥有 HTTP 读取边界,Task 2 拥有 SSE 结构,Task 3 拥有持久评测白名单,Task 4 只固定真实组合和用户链回归;没有第二个异步状态 owner、公开 schema 变更或额外模型回合。五项 Review Focus 都指向各任务的命名测试。
- 发现 Go
net/http无法可靠暴露某种原始传输分隔方式时,记录unknown与零付费证据,不读取原始网络字节“补齐”;发现供应商另有终止形式时仅记录事实,不在本计划中放宽工具门禁。需要新的路由、公开字段、数据库迁移、权限、模型预算或 UI 变更时,停止受影响单元并返回设计/计划人工重审。 - 本计划的交付终点是零付费、可审阅的阶段 6 候选。当前用户只批准写计划,Task 1–4 的代码、浏览器/PG 重放、真实模型对照和合入均
NOT_RUN。书面计划获阶段 5 人工批准后,按既有任务 worktree 同会话实施;任何真实 provider 请求仍须候选固定和单独资源批准。