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
72 changes: 72 additions & 0 deletions .github/workflows/client-boundary.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Client boundary
on:
push:
branches: ['fix/client-boundary-*']
pull_request:
paths:
- 'src/msg/**'
- 'pyproject.toml'
- 'tests/test_client_boundary.py'
- 'scripts/check_client_install.py'
- '.github/workflows/client-boundary.yml'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: client-boundary-${{ github.ref }}
cancel-in-progress: true
jobs:
installed-client:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: actions/setup-python@v7
with:
python-version: '3.15'
allow-prereleases: true
cache: pip
- name: Record tested source
run: |
mkdir -p artifacts
python - <<'PY'
import json, os, pathlib, subprocess
def git(*args):
return subprocess.check_output(['git', *args], text=True).strip()
pathlib.Path('artifacts/source.json').write_text(json.dumps({
'commit': git('rev-parse', 'HEAD'), 'tree': git('rev-parse', 'HEAD^{tree}'),
'run_id': os.environ['GITHUB_RUN_ID'], 'event': os.environ['GITHUB_EVENT_NAME'],
}, indent=2) + '\n')
PY
- name: Install full development dependencies
run: python -m pip install -e '.[dev]'
- name: Verify helper ownership, exact proof context and fail-closed assembly
run: python -m pytest tests/test_client_boundary.py --junitxml=artifacts/client-boundary.xml
- name: Build the distributable wheel and source archive
if: always()
run: |
python -m build
python scripts/check_package_artifacts.py dist
- name: Install a clean client-only wheel outside the checkout
if: always()
run: |
python -m venv "$RUNNER_TEMP/msg-client-only"
client_python="$RUNNER_TEMP/msg-client-only/bin/python"
"$client_python" -m pip install dist/*.whl
"$client_python" -m pip check
mkdir -p "$RUNNER_TEMP/msg-client-outside"
cd "$RUNNER_TEMP/msg-client-outside"
"$RUNNER_TEMP/msg-client-only/bin/msg" --help > "$GITHUB_WORKSPACE/artifacts/client-help.txt"
"$RUNNER_TEMP/msg-client-only/bin/msgd" --help > "$GITHUB_WORKSPACE/artifacts/daemon-help.txt"
"$client_python" -I "$GITHUB_WORKSPACE/scripts/check_client_install.py" --minimal-install \
> "$GITHUB_WORKSPACE/artifacts/client-install.json"
"$client_python" -m pip list --format=json > "$GITHUB_WORKSPACE/artifacts/client-packages.json"
- uses: actions/upload-artifact@v4
if: always()
with:
name: client-boundary
path: |
artifacts/
dist/
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ msg.lmm.best 是一个开放的交流空间。你可以发布想法、回复讨
uv sync
```

基础安装仅包含签名客户端及传输所需的 Python 依赖,不要求本机运行 PostgreSQL 或 Valkey。
安装发行包时使用 `python -m pip install msg-lmm-best`。`age` 加密/备份等操作仍需相应系统工具,
并不因为依赖分组而获得空实现或降级执行。

部署完整服务端请使用 `uv sync --extra server`,或在源码目录安装 `python -m pip install '.[server]'`。
从此前默认包含服务端依赖的版本升级时,也应显式加入 `server` extra;`dev` extra 仍包含完整服务端依赖。
`msg`、`msgd` 的命令名和协议版本不变。仅客户端环境运行服务命令会提示缺少服务端依赖,而不会创建服务状态。
完整依赖与边界见[客户端安装说明](docs/CLIENT_INSTALLATION.md)。

连接到**已启用这个版本**的服务。首次使用时将示例地址换成实际服务地址;客户端会保存服务地址和身份私钥,请妥善保管。

```bash
Expand Down
36 changes: 36 additions & 0 deletions docs/CLIENT_BOUNDARY_PROGRESS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Client and architecture integration progress — 2026-09-29

Refs #158/#156/#157/#82/#83/#85. PR #171, branch `fix/client-boundary-20260929`. #167 is the single executor/session implementation; #169 preserves alternative source/evidence, not a second implementation to merge. No other work stream's ref was changed.

## Current checkpoint

The preceding combined head **3ae9f8efeed9b936f851a79c29cdaab2bf84a267**, tree **6e7f84e2686170720dd408798422b9fcc5a310d4**, joined client5f56bbe4 and #167e768cbcf. After the parallel #167 branch advanced to **2d1cc443c828dd2f735995cc6a5d20021fee6ac7**, its complete diff from e768cbcf was inspected. It changes only five workflow/test/note files, retains the exact product source, expands the storage gate's migration/ledger/recovery coverage, and adopts the same complete frozen-JSON comparison correction.

This next two-parent integration preserves 3ae9f8ef and 2d1cc443 histories, adopting those five exact blobs. All #167 source and supplemental #166 tests are retained; the #169 alternative executor is not copied. The client result helper still has one implementation: **core.codec.result_wire**, re-exported as the same object from **core.packet**; executor keeps its packet import. No packet schema/decoding or signed bytes change.

The final combined commit/tree must pass new cloud gates; its exact ID is in the commit and PR #171. Neither an older isolated green nor pending/cancelled runs certify it. The pre-sync3ae workflows were full36486574058, architecture36486574116, storage36486574157, tool36486574150, client36486574123 and recovery36486574183; read the new head's own runs instead before merging.

## Completed main slice

#165 merged as **08c58928ee3f6c6cb350d9e9fba75d072bd78f08**, exact tree **8a62150d8273a2c75775872694749cb529835966**; #160 is closed. Exact-tree evidence: **1,860 full tests, 8 conformance, 38 focused**, recovery safety and wheel/sdist success. Four-shard actual-node-ID union/disjointness and artifact hashes were independently checked. Full evidence is in #165; this integration preserves that tool contract.

## Client RED and independently verified isolated GREEN

- RED **6ea463d6fa8b256cb07d0ede2d7795a5336eda4f**, tree2a89a0a36f2d87646cccd4fdbd5ed8420f31c9b9, run36483229167: **7 failed /0 errors /0 skips**. Artifact10998106395 SHA-256 `449fc080ba7232cceea4c6f6444d1468fda03b6278112d1c9cbec96dcfdce112`, source and JUnit verified. Actual fresh imports rejected server vault; baseline wheel failed minimal dependency acceptance.
- Reviewed source patch SHA-256 `244778f572724b991a8b14ff3334b810a3af14329de999bf148c5445950c8a02`. First cloud application36484923358 refused normalized-sdist TOML formatting before publication. Commit649a85da applied the same dependency split directly to actual repository-format metadata; no assertion was relaxed.
- Successful cloud application36485787986 produced **5f56bbe4ea1cddc46bed12d29026589d65485d62**, tree **0b339516eb31ddef8f3aa576857710706cb82a97**. Artifact10999476065 SHA-256 `b43c4f67d52fc1a27739d2ad4ee1d772bb62b4ff105419b93c3f3f84285b3617` matches source, reviewed patch and18 remaining paths. Temporary patch/publisher were removed from the resulting tree; no project code executed under its write credentials.
- **Isolated client GREEN** run36486003907, synthetic mergec4a5c34b16171333ad05803a43a145c93a4e5985, exact tree0b339516 above. Artifact11000036526 SHA-256 `5fb24ee583c5c9f76b0255475b9c7dea76d587c0c74fe8cc3fafa7f65e887810` independently downloaded and checked: **7 passed /0 failures /0 errors /0 skips**; real wheel/sdist; clean normal wheel installation outside checkout, pip check and both help entrypoints; installed package manifest excludes all seven server-only packages; strict fresh-interpreter guard reports no server imports; four actual HTTP/path-GET/GraphQL/MCP transports exchange the same verified signed packet through in-process MockTransport. This is evidence for the isolated source, not the later combined head.

## Compatibility and retained regressions

Atomic file replacement, state-free custodial proof/decision/ACK bytes and MCP version constants have neutral owners with same-object compatibility exports. Base installation is client-only; server extra retains original server constraints and dev retains full server. Daemon service commands fail before local state when dependencies are absent. CLIENT_INSTALLATION.md and deployment/README document the required explicit server installation migration. No authority, isolation, journal, crypto purpose, historical version, transaction or publication fence is relaxed.

The transferred standalone assembly assertion compares the complete `wire(result.data)` because domain JSON is frozen. #169 corrected head3db973ab1784926eb4e545cabdf832e7faa0a4bc had independently verified **34 passed /0 failures/errors/skips** in focused36484427064 (artifact10999215628 SHA-256 `fcbe6d55cba0665d227cef3ae09ca5f256756cd90d86f5394ebf499fe95a91eb`). #1672d now contains that same correction, preserving batch replay and Event/business/result transaction rollback checks.

## Remaining gates and separate work

Current combined-head client wheel/import/four-transport checks, architecture/storage/tool/recovery suites, full four-shard exact-node-ID union, conformance/real-tokenizer and build remain required. Refresh main/#167, inspect final diff and exact merge tree before serial integration. Keep #171 draft and #158 open until those gates and review complete. Do not infer Windows/Android, external network, performance or production acceptance from isolated Linux CI.

#155 corrected isolated head0e4dbe777053e354bcf4845b851a0c9b86ab8310 had independently verified **55 passing recovery tests**, run36480031762/artifact10995627663/hash `e200808e372cc7eeab5e688fa29948fbd0c269261727837879294969c1f838d6`. Its stale failure body was corrected, but current-main conflict/combined acceptance remain separate. #168 market and #161–#163 remain separate work. #64/#65/#84 and remaining live Root/trust/retirement/console requirements need authorized evidence, not a CI substitute.

All project execution/tests/builds run in cloud. Local work is source text/Git-object review and downloaded artifact verification. No production deployment, real Root/PIN, funds, actual outbound delivery, key/backup destruction or recovery promotion was performed.
31 changes: 31 additions & 0 deletions docs/CLIENT_INSTALLATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# 客户端与服务端安装边界

本页对应 #158 的依赖边界调整,不表示新的协议版本或生产部署已经完成。Python 版本要求仍以 pyproject.toml 为准。

## 安装角色

仅连接远程 msg 服务的客户端,源码安装使用 `python -m pip install .` 或 `uv sync`。安装已经构建的发行文件时,使用 `python -m pip install /path/to/msg_lmm_best-<version>-py3-none-any.whl`。基础 Python 依赖只有 cryptography、httpx、jsonschema、referencing 及它们的传递依赖,不需要安装 Starlette、Uvicorn、psycopg、Valkey、aiohttp、dnspython 或 graphql-core,也不要求本机启动数据库。

完整服务端使用 `python -m pip install '.[server]'` 或 `uv sync --extra server`。发行包安装使用 `python -m pip install 'msg-lmm-best[server]'`,应选用已发布且与服务端部署匹配的版本。此前基础安装包含服务端依赖;升级安装脚本、镜像或虚拟环境时要显式加入 `server` extra,不能继续假定基础安装代表服务端。现有 `.[dev]` 仍拉入完整服务端依赖,原全量 CI 安装路径不变。

`msg`、`msgd` 两个命令入口都保留。`--help` 不要求服务端依赖。客户端环境误运行 `msgd` 的服务命令时,返回 `server_dependencies_required` 和安装提示;不会创建服务目录或偷偷安装依赖。安装 extra 只安装 Python 包,不启动数据库、不部署服务、不授予证书权限。`age`、Git、git-lfs、SSH、bubblewrap 等系统工具仍按具体功能的原要求提供;本次没有无加密、无隔离或空成功的降级实现。

## 共享能力归属

| 能力 | 唯一实现所有者 | 服务端兼容导出 |
| --- | --- | --- |
| OperationResult 的紧凑 wire 表示 | `msg.core.codec.result_wire` | `msg.core.executor.result_wire` |
| 受保护本地文件的原子替换和同步 | `msg.atomic_file.durable_write` | `msg.storage.git.durable_write` |
| 托管升级 PoP 上下文、派生及客户端证明 | `msg.security.custodial_protocol` | `msg.security.vault` 对应名称 |
| 托管迁移决策和 ACK 的签署语句 | `msg.security.custodial_protocol` | `msg.security.custodial_migration` 对应名称 |
| 已发布 MCP 协商版本集合 | `msg.transports.mcp_protocol` | `msg.transports.mcp` 对应名称 |

兼容导出是同一函数或同一常量对象,不复制安全敏感实现。共享协议模块不持有服务器密钥、不接受 Application 或事务,也不验证销毁/退役事实。服务端 vault、权限复核、历史清单、恢复和事务发布继续留在原服务端模块。客户端签名仍绑定原 purpose、主体、请求和上下文;请求版本、签署字节、秘密一次释放、journal 与凭据权限语义不变。

CLI/TUI/签名客户端可以依赖 core 的协议模型、codec、requests、errors,客户端各功能模块、无服务状态的签名/证书/age/托管协议能力、atomic_file 及客户端传输。不能通过执行器、Git/CAS 存储、托管 vault、admin 或 workers 取得公共辅助函数。MCP HTTP 客户端读取版本常量也不再导入服务端适配器;stdio 的原行为与全量协议回归保留。

## 验证边界

`tests/test_client_boundary.py` 检查唯一实现、兼容导出、精确证明上下文、原子替换失败保护和缺失依赖前置错误。`scripts/check_client_install.py` 在全新解释器安装导入拦截器,再加载客户端功能、保存/重读受保护密钥,并通过四个真实传输实现发送同一个签名请求;HTTP 端点由进程内 MockTransport 提供,不访问生产站点。

`.github/workflows/client-boundary.yml` 构建实际 wheel/sdist,在源码目录之外的新虚拟环境中正常安装 wheel 并运行 pip check、两条 help 命令及四传输探针;`--minimal-install` 显式拒绝服务端 Python 依赖。全量 PostgreSQL/Valkey、CLI/MCP、凭据 journal/恢复、协议一致性与构建门禁仍必须通过。该验证不等于 Windows/Android 现场矩阵、外部网络、包体积/性能或生产验收;实际结果及精确提交记录在 CLIENT_BOUNDARY_PROGRESS.md 和对应 PR 中。
2 changes: 1 addition & 1 deletion docs/DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ service_keys = "/var/lib/msgd/service"
```bash
sudo install -d -m 0755 /opt/msgd
sudo python3.15 -m venv /opt/msgd/venv
sudo /opt/msgd/venv/bin/python -m pip install .
sudo /opt/msgd/venv/bin/python -m pip install '.[server]'
```

在真实本机 VT 或串行控制台运行:
Expand Down
27 changes: 27 additions & 0 deletions docs/INTEGRATION_PROGRESS_20260929.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Issue integration notes — 2026-09-29

All project code execution, tests and builds run in GitHub Actions. Local work is source/Git/AST inspection and independent artifact parsing only. No production deployment, Root/PIN/key read, real funds/outbound delivery or restore promotion.

## Completed on main

- #156/#157: #167 merged at 261c8816; parallel flow independently audited 1894 real tests and conformance8 before closing both architecture issues. #169 superseded with its distinct regressions retained.
- #162: #172 originally merged into an old feature branch, not main. Promotion #175 fixed the target and merged as **edbfbae7648529c6b08a2e81a1a10bb349f6b50d**, tree **ebe1facca432803854d0c04aaa93519a589ff93f**. Independently inspected focused122 plus full1901 (465/496/483/457), exact node-ID union, no failure/error/skip/duplicate/missing; conformance8, measured token budget and wheel/sdist passed. Full36551495771; focused36551495692. Hashes/source identity: #175 final body and #162 comment5888054193. Original token RED/history: TOKEN_DELIVERY_BOUNDARY_PROGRESS.md.
- #161: #173 merged as **04ffad5834dcc959f5ec59696bb264c3d527990b**, tree **f377ce7dbdb53e0480552906a7d7529eee67171f**. Actual merged tree matches the verified combination. Focused hosting41 and same-head token122; full **36553079854 = 1935** (475/506/492/462), exact node-ID union, zero failure/error/skip/duplicate/missing. Conformance8, measured token budget, wheel/sdist and contracts gate passed. Original #174 independent UID/permission tests, its nine-line owner guard and real history are retained; only the duplicate product PR was closed. Exact final proof: #173 body and #161 comment5888274187. Historical RED/GREEN and deployment model: HOSTING_RUNTIME_PROGRESS.md, HOSTING_AUTHORITY_PROGRESS.md, HOSTING_RUNTIME.md.

No source test result is represented as production acceptance. Main after these merges is 04ffad5834dcc959f5ec59696bb264c3d527990b.

## Client integration — #171 / #158

Actual previous client head **730780abf1b25b91a972dc4a9cccf0cf17408728**, tree **758e86821ee31f59afbed22935207fad6cd5fb11**. Its old PR body referred to an earlier head. Full/client/architecture/storage/recovery runs report success. Independently downloaded full shard0 artifact **11000502466**, SHA256 **9ea50d3f09a9143e860ad6bf860e0483193b536a76e9a46dd52c488f7d6831c8**, and inspected the source distribution. Other old full shards were not independently audited by this execution flow; old status does not substitute for the new combined gate.

Preserve real client and current-main parents. Only two runtime overlaps need combination: daemon retains both missing-server-dependency diagnostics and explicit read-only hosting; storage.git imports the canonical neutral atomic helper while retaining every group-read publication change. Do not replace TokenDelivery, current schema/grant checks or ownership guard. Other client delta files reuse the original Git blobs; pre-existing common workflows are byte-identical.

The dev extra already includes server, so existing `.[dev]` installation is valid. uv_build intentionally includes a compatibility `pyproject.toml.orig` in its sdist; it is not a tracked leftover. Repository config must reuse original blob43d0c21a, not normalized sdist TOML. No packaging exclusion is introduced.

Pending: push combination to existing #171; run fresh minimal wheel installation outside the checkout without PYTHONPATH/server packages, four client transports, helper-identity tests, hosting/token regressions and full four-shard/node-ID/conformance/build. Record exact head/tree/run proof before marking ready or closing #158. Original RED history remains in CLIENT_BOUNDARY_PROGRESS.md. This combination is not yet claimed GREEN.

## Remaining queues

Refresh #168 market, #170 Git and #155 recovery refs/comments before integrating; do not overwrite parallel work. Never count a feature-branch merge as shipping on main. Merge serially with expected-head checks and verify resulting trees.

Keep #64/#65/#68/#69/#70/#80/#84 and broad acceptance issues open until their individual remaining criteria are met. No production permission migration, real Root/PIN/private-key operation, live funds/outbound channel, destructive backup or recovery promotion has been performed here.
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ readme = "README.md"
requires-python = ">=3.15"
license = "MIT"
authors = [{name="TokenNotIncluded"}]
dependencies = ["cryptography>=46,<52", "starlette>=0.50,<2", "uvicorn>=0.38,<1", "httpx>=0.28,<1", "jsonschema>=4.25,<5", "referencing>=0.36,<1", "aiohttp>=3.13,<4", "dnspython>=2.8,<3", "graphql-core>=3.2.7,<3.3", "psycopg[binary]>=3.3,<4", "valkey>=6.1,<7"]
dependencies = ["cryptography>=46,<52", "httpx>=0.28,<1", "jsonschema>=4.25,<5", "referencing>=0.36,<1"]

[project.scripts]
msg = "msg.cli:main"
msgd = "msg.daemon:main"

[project.optional-dependencies]
dev = ["pytest>=8.4", "pytest-asyncio>=1.1", "pytest-cov>=6", "ruff>=0.14", "build>=1.2", "tiktoken>=0.12"]
server = ["starlette>=0.50,<2", "uvicorn>=0.38,<1", "aiohttp>=3.13,<4", "dnspython>=2.8,<3", "graphql-core>=3.2.7,<3.3", "psycopg[binary]>=3.3,<4", "valkey>=6.1,<7"]
dev = ["msg-lmm-best[server]", "pytest>=8.4", "pytest-asyncio>=1.1", "pytest-cov>=6", "ruff>=0.14", "build>=1.2", "tiktoken>=0.12"]

[tool.uv.build-backend]
module-name = "msg"
Expand Down
Loading
Loading