Skip to content
Open
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
44 changes: 44 additions & 0 deletions docs/architecture/rfcs/monorepo-distribution-split-v0.md
Original file line number Diff line number Diff line change
Expand Up @@ -2567,6 +2567,50 @@ R0/V10/R1, D2/D5/D6/D3, context/model/split-install, PostgreSQL host/wheel and
full-cost/adoption requirements remain open. No main merge or host upgrade is
included.

### 2026-11-08 — Synthetic Host UTF-8 recovery qualification

The Windows CPython 3.11 CI arm of #8360 fails six existing original-task
revalidation cases. Its synthetic Python Host inherits a locale decoder for a
pipe, while the existing generic Host transport sends UTF-8 JSON. A disposable
File-provider counterprobe changes only that Host decoder: CP1252 produces
`host_failure` without `task_failure`; UTF-8 reaches the independent artifact
validator and produces `validation_failed` at `task_postcondition`, with
`revalidate_cached_result`. The source macOS arm independently passes all 12
existing revalidation cases. These observations locate a fixture mismatch;
they do not justify widening production failure classification.

Fixture commit `a4ce613585fdb329ba3600f0ede768864214ed84`, over main
`4e949f405528fd8087f0623526c62f890c1ce982`, explicitly configures its stdin as
UTF-8 before reading the request. One new File/SQLite regression first sets
only the generated Host's decoder to CP1252, sends a Unicode brief and requires
the rejected artifact to reach task validation. After repairing the artifact,
revalidation must accept it with the original turn key and exactly one Host
invocation. The same regression fails with the immutable baseline Host on the
same CPython 3.13.5/Node 22.22.3 environment, and passes with the correction.
No transport, production owner, persisted state or protocol vocabulary changes.

On macOS arm64 with Node 22.22.3, CPython 3.11.15 source and a newly installed,
isolated monolithic wheel each pass the new two provider cases plus all 12
existing original-task recovery cases. Wheel imports are verified outside the
checkout before loading the source-owned fixtures; all 1,920 present packaged
tracked runtime entries match the source bytes. The same 17 source-only
exclusions remain: canary baseline, host plugin/config, fault-test helper and
documentation/media. This qualifies the existing File/SQLite
synthetic Host recovery path, including retained MCP disconnection and lock
timeout recovery cases, not model adoption, split installation or native
Windows. The failed original Windows arm remains historical evidence until a
new exact-head Windows run passes. The independent Frontstage manifest request
still returns HTTP 504 after its bounded retry.

The original task stays open. Preserve I3 for at least one minor release,
M1/#8011, full R0/V10/R1, D2/D5/D6/D3, context/model/split-install,
PostgreSQL host/wheel, whole-path/full marginal-cost/adoption requirements and
all historical and frozen failures. No cost campaign is repeated or relabeled,
and this fixture qualification establishes no performance benefit. The report
loading proposal #8360 retains its independent review and CI gates; the next
step is exact-head review of this correction and native Windows readback. No
main merge or installed-host upgrade is included.

## Appendix B: Decision log

| Date | Decision | Owner / approval | Alternatives | Normative sections changed |
Expand Down
35 changes: 35 additions & 0 deletions docs/architecture/rfcs/monorepo-distribution-split-v0.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -1993,6 +1993,41 @@ caller 的必需依赖闭包,再选一个完整可回退的加载改动并验
context/model/split-install、PostgreSQL host/wheel、full-cost/adoption 要求
继续开放;本轮不合入 main、不升级 host。

### 2026-11-08 — 合成 Host 的 UTF-8 恢复资格

#8360 的 Windows CPython 3.11 CI arm 在六个既有原任务重验证用例中失败。
合成 Python Host 对 pipe 继承 locale decoder,而原 generic Host transport
发送 UTF-8 JSON。Disposable File-provider counterprobe 只改变该 Host decoder:
CP1252 产生 `host_failure`,没有 `task_failure`;UTF-8 到达独立产物 validator,
在 `task_postcondition` 产生 `validation_failed`,并提供
`revalidate_cached_result`。源码 macOS arm 独立通过全部12个既有重验证用例。
这些观察定位了 fixture mismatch,不支持扩大生产 failure classification。

Fixture commit `a4ce613585fdb329ba3600f0ede768864214ed84` 基于 main
`4e949f405528fd8087f0623526c62f890c1ce982`,在读取请求前显式将 stdin 配为
UTF-8。新增 File/SQLite regression 先只把生成 Host 的 decoder 设为 CP1252,
发送 Unicode brief,要求被拒绝的产物到达 task validation。修复产物后,重验证
必须沿用原 turn key 并接受结果,Host invocation 始终为一次。同一 regression
在相同 CPython3.13.5/Node22.22.3 环境中对不可变 baseline Host 失败,修正后
通过。不改变 transport、生产 owner、持久状态或协议词汇。

macOS arm64/Node22.22.3 下,CPython3.11.15 source 与新安装的隔离单体 wheel
各通过新增两个 provider 用例及全部12个既有原任务恢复用例。先在 checkout 外
验证 wheel import 归属,再加载 source-owned fixture;1920个实际 packaged
tracked runtime entry 均与源码字节相同。原17个 source-only exclusion 保留:
canary baseline、host plugin/config、fault-test helper 和 documentation/media。
这验收既有 File/SQLite 合成 Host 恢复路径,包括保留的 MCP
断连及 lock-timeout 恢复用例,不验收模型采纳、split installation 或原生 Windows。
原失败 Windows arm 保留为历史证据,直到新 exact-head Windows run 通过。
独立 Frontstage manifest 请求在有界重试后仍为 HTTP504。

原任务保持开放。保留 I3 至少一个 minor release、M1/#8011、完整 R0/V10/R1、
D2/D5/D6/D3、context/model/split-install、PostgreSQL host/wheel、whole-path/
full marginal-cost/adoption 验收及全部历史/冻结失败。不重跑或重标签成本
campaign,本 fixture 资格不证明性能收益。报告按需加载提案 #8360 保留独立
review/CI gate;下一步为本修正的 exact-head 评审与原生 Windows 读回。不包含
合入 main 或 installed-host 升级。

## 附录 B:决策日志

| 日期 | 决策 | 负责人 / 批准 | 备选 | 变更的规范章节 |
Expand Down
32 changes: 32 additions & 0 deletions tests/test_local_delegation.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
from loopx.control_plane.quota.turn_envelope import turn_host_lineage
from loopx.control_plane.collaboration.inbox import acknowledge
from loopx.control_plane.collaboration.peers import return_result
# The generic Host protocol sends UTF-8 over a pipe, whose Python 3.11
# Windows default is a locale codec rather than the console's UTF-8 mode.
sys.stdin.reconfigure(encoding='utf-8')
request = json.load(sys.stdin)
workspace = Path.cwd()
root = Path(sys.argv[1])
Expand Down Expand Up @@ -98,6 +101,35 @@ def brief():
"return_requirement": "Return the independently checked artifact"}


def test_fixture_host_revalidates_utf8_input_under_a_non_utf8_pipe(service):
"""The fixture must reach task validation with the original UTF-8 identity."""
root, runner = service
host = root / "fixture-host.py"
# Model the Windows Python 3.11 pipe default without changing the parent
# transport or requiring a platform-dependent locale on the test runner.
host.write_text("import sys; sys.stdin.reconfigure(encoding='cp1252')\n"
+ host.read_text(encoding="utf-8"), encoding="utf-8")
output = root / "analyst/initial/output.json"
saved = output.read_bytes()
output.write_text("{}", encoding="utf-8")
request = {**brief(), "context": "Read the synthetic résumé: 报告 € → evidence."}
runner.start("analysis", "analysis-1", request)
rejected = wait(runner)
assert rejected["status"] == "rejected", rejected
assert "task_failure" in rejected, rejected
assert rejected["task_failure"]["resume_mode"] == "revalidate_cached_result"
turn_key = rejected["task_failure"]["turn_key"]
assert (root / "analyst/initial/host-invocations").read_text() == "1"

output.write_bytes(saved)
runner.revalidate("analysis-1")
accepted = wait(runner)
assert accepted["status"] == "accepted", accepted
assert "task_failure" not in accepted
assert json.loads(runner.path("analysis-1").read_text())["turn_key"] == turn_key
assert (root / "analyst/initial/host-invocations").read_text() == "1"


@pytest.mark.parametrize("provider", ["file", "sqlite"])
def test_delegation_fixture_isolates_cached_and_child_runtime_routes(tmp_path, monkeypatch, provider):
"""A warmed parent must use the same private Effect server as its CLI."""
Expand Down
Loading