Skip to content

Build frontend delivery artifacts outside Git with verified upgrade retention - #4977

Merged
huangruiteng merged 6 commits into
mainfrom
codex/frontend-artifact-delivery-0924
Sep 24, 2026
Merged

huangruiteng merged 6 commits into
mainfrom
codex/frontend-artifact-delivery-0924

Conversation

@huangruiteng

@huangruiteng huangruiteng commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Parallel frontend PRs currently conflict in generated HTML and asset-retention history even when their source changes are independent. This change makes Git own source and makes the build/release pipeline own a coherent, verified frontend delivery.

  • Remove generated Chat assets from Git; PR CI builds and browser-tests once before uploading a checkout-SHA artifact, including backend and mixed PRs, instead of requiring committed build output.
  • Centralize bundle integrity, source freshness and current/previous asset assembly. Default Chat startup rejects missing or stale bundles; source development and installers have an explicit build/ensure path.
  • Include qualified assets in wheel/sdist and exact desktop source archives. Release builds carry the preceding stable wheel's assets after checksum validation; source installers carry the actual installed snapshot's assets. Already-built archives retain assets without a frontend rebuild.
  • Preserve one previous delivery, retire older history, and prevent failed builds or incremental packaging from producing mixed bundles. Remove copied dependency symlinks from installed snapshots.

Validation: 158 targeted tests passed (4 native Windows tests skipped on macOS and retained in Windows CI); 65 focused bundle/workflow/desktop tests passed; final CI-only consolidation passed 45 workflow and 7 classification/merge-gate tests; production Vite/TypeScript build; nine packaged workspace browser scenarios against the production Chat handler in an isolated installed environment; old-tab deferred-import upgrade/retirement browser smoke; disposable source install/update/rollback smoke; installed wheel and sdist-rebuilt wheel through the real Chat HTTP handler; exact desktop archive extraction/source verification; PWA checks and focused Ruff. The standard premerge canary passed 19 checks. The final CI/documentation-only consolidation changed no runtime files and passed a targeted five-check premerge run. The exact final scope has a valid change-quality receipt.

The page design and Goal/provider semantics are unchanged. Compatibility covers static resources from one preceding delivery, not indefinite backend API compatibility or arbitrary skipped wheel releases. See docs/development/frontend-delivery.md for build, release and rollback commands. Native Windows and signed desktop release execution remain CI/release qualifications.

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
@huangruiteng
huangruiteng marked this pull request as ready for review September 24, 2026 03:16

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)

Reviewed exact head d61b418af02490777db45ca533f9c6e24be42812 against base f3d1e8c4ff1958faf3484bf3dc651a040a41a741.

动机

把生成的 Chat 前端资源移出 Git,同时让源码构建、wheel/sdist、桌面打包和升级时的旧标签页资源使用同一份可校验的交付物,这个目标成立。

改动思路

以源码指纹、清单和文件哈希验证 bundle;构建先暂存再替换,最多保留上一版所需的资源。安装器、打包器、CI 和运行时接到这份产物,而非各自维护一套生成文件。这个边界基本合理。

具体改动

审阅了 npm 构建入口、Python builder/validator、wheel/sdist、Windows/source 安装器、桌面归档、Chat 启动路径及 CI 消费链路。本地运行 uv run --extra test python -m pytest -q tests/presentation/test_chat_bundle.py tests/test_python_ci_workflow.py:59 passed;未在原生 Windows 上执行 npm 命令。

有一个需在此 PR 修复的 P2 问题:apps/presentation/dashboard/package.json:11 把文档推荐的 npm run build:chat 改成直接调用 python3,npm run build 也会走它。在只配置 python.exe、没有 python3 命令别名的受支持 Windows 环境中,构建会在进入跨平台 builder 之前失败;报错给用户的重建建议也指向同一命令。Windows 安装器已经通过解析出的 Python 路径调用 builder,但现有 Windows CI 只下载预构建的 Chat artifact,没有执行这个 npm 入口。请使用可移植的解释器启动方式(保留共享 builder),并在 Windows CI 加一项实际运行 npm run build:chat 的回归,覆盖只有 python.exe 的情况。

对主干的风险

Unix 上的 bundle、清单、上一版资源与打包测试通过;未发现需要拆分的独立框架或第二套状态权威。剩余风险集中在 Windows 源码构建/损坏资源恢复入口。原生 Windows npm 路径、签名桌面发布链路未在这次本地审阅中实跑;不能把 59 个 Python 测试当作其通过证明。

我的整体评价

交付边界和单次升级保留策略可接受,当前先请求修复 Windows 入口并补原生执行证据,再对更新后的 exact head 复核。未来向 refactor 检查:继续复用一份 builder,避免为 Windows 另造 bundle 逻辑;目前不需要扩大重构范围。

English verdict: REQUEST_CHANGES

`npm run build:chat` hardcoded the POSIX `python3` name, so a supported
Windows install that provides `python.exe` alone (or an unusable App
Execution Alias stub for `python3`) failed before reaching the shared
builder, and the rebuild advice pointed at the same broken command.

The npm entry now runs `scripts/chat_bundle_launcher.mjs`, which selects a
Python 3.11+ interpreter the way the rest of LoopX does (LOOPX_PYTHON, the
installer-recorded `.loopx-python`, the repository `.venv`, then
`python3`/`python` and the `py` launcher) and then executes
`scripts/chat_bundle.py`, so build rules stay in one place.

The Windows CI lane now installs frontend dependencies and rebuilds the
bundle through `npm run build:chat` while an unusable `python3.exe` shadows
any real alias, then verifies the source-bound bundle. Focused launcher
tests cover the python.exe-only fallback, the discovery order, the
no-fallback explicit override and the actionable missing-interpreter error.

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…ct-delivery-0924

Generated Chat assets conflicted as delete/modify because this branch
retires them from Git while main still regenerates them, and main added
two new hashed CSS files. Resolution: keep every loopx/web/chat path
deleted, since the bundle is built and verified from source; no other
conflict remained.

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

Reviewed exact head ebbb600a4233ea0a87df6ffc40a0be1437e38e9b against base e67483f3304599db2cb679718764dfe11dda73de.

动机

上一轮评审在 d61b418af 上请求修改:apps/presentation/dashboard/package.json 把 npm run build:chat 改成直接调用 python3,npm run build 也走它。在只提供 python.exe、没有可用 python3 别名(或 python3.exe 只是不可执行的 App Execution Alias 占位)的受支持 Windows 环境里,构建会在进入跨平台 builder 之前失败,而失败信息里的重建建议又指向同一条命令。本 head 针对该点修复,并补上原生 Windows 执行证据。

PR 本身的目标不变:生成的 Chat 资源不再进入 Git,源码构建、wheel/sdist、桌面归档与一次升级窗口都消费同一份带清单与文件哈希的交付物。

改动思路

解释器选择从「命令名假设」变成「一次显式解析」:npm 入口只负责找到可用的 Python 3.11+,构建规则仍由 scripts/chat_bundle.py 单一持有,没有为 Windows 另造第二条构建路径。解析顺序沿用 LoopX 已文档化的约定(LOOPX_PYTHON → 安装器记录的 .loopx-python → 仓库 .venv → python3/python,Windows 追加 py 启动器),每个候选都要通过解释器兼容性探针才会被采用;显式指定的解释器不可用时不回退,直接给出可操作报错。

具体改动

  • 新增 scripts/chat_bundle_launcher.mjs:跨平台启动器,按上述顺序解析解释器后执行 scripts/chat_bundle.py 并透传参数与退出码;找不到可用解释器时报明「Python 3.11+ 缺失、请设置 LOOPX_PYTHON 或安装后重跑 npm run build:chat」。
  • apps/presentation/dashboard/package.json:build:chat 改为 node ../../../scripts/chat_bundle_launcher.mjs build,build 仍复用同一入口;build:chat:vite 与 builder 未改。
  • Windows CI(.github/workflows/python-tests.yml 的 windows-powershell):新增前端依赖安装步骤与「只有 python.exe 可用」的原生回归——在 PATH 前置一个不可执行的 python3.exe 影子文件后执行 npm run build:chat,再跑 python scripts/chat_bundle.py verify --source;同时为该 job 增加 npm 缓存并把预算从 20 分钟提到 30 分钟。旧写法在该环境会直接失败,因此该步骤是有鉴别力的回归。
  • tests/presentation/test_chat_bundle_launcher.py:新增 5 项聚焦测试,覆盖 python.exe 回退(并断言旧式 python3 <builder> 在同一受限 PATH 下非零退出)、LOOPX_PYTHON/.loopx-python/.venv 优先于 PATH、显式解释器不可用不回退、缺失解释器报出可重跑命令,以及 npm 入口确实委托给启动器。
  • tests/test_python_ci_workflow.py:断言 Windows 车道确实安装依赖、在 python3.exe 不可用时通过 npm 重建、并验证产物。
  • 文档与触发条件:docs/development/frontend-delivery.md 说明该 npm 入口的可移植解析顺序与 Windows 前提;frontstage-pages.yml 的路径触发加入启动器文件。

本 head 同时合入最新 main:冲突全部是生成产物(loopx/web/chat/** 的 delete/modify 与 rename/delete,另有 main 新加的两个哈希 CSS)。解决方式是保持这些路径在 Git 中删除,不从两个版本拼接 HTML 或资产保留清单;随后用合并后的源码经 npm run build:chat 重建并通过 verify --source,asset-retention.json 仍在两代以内。

对主干的风险

上一轮的反例(把 python3 写死导致 Windows 构建在进入 builder 前失败)现在有可复现的守门:启动器测试在受限 PATH 下断言旧命令非零、新入口成功,Windows CI 用不可执行的 python3.exe 影子文件做同类回归。python.exe 只有在本机无法原样复现,因此该平台的首个绿色车道仍是它的验收证据,这一点已记入 change-quality receipt 的残留风险。

验证矩阵(本 head):Python 前端交付/工作流/解释器发现/dashboard 命令/Windows 安装 123 用例通过(4 项原生 Windows 用例在 macOS 跳过);npm run build:chat 经启动器在合并源码上成功并接着 verify --source;旧标签页延迟导入升级/退役浏览器 smoke 与 10 个打包 Personal Workspace 场景通过(生产 Chat handler,需显式 LOOPX_PYTHON_BIN);install-local-smoke 单跑 3 分 19 秒通过(canary 的 120 秒单项预算曾把它判为超时);dashboard-pwa-bundle-smoke、docs-governance-smoke、frontstage-pages-workflow-smoke、scripts/ci 单测与 Ruff 全部通过。loopx canary premerge --from-git-diff 19 项中 18 项通过,唯一失败项即上述超时,另有它要求的 exact-scope receipt:cqr_68b67f94416363f8e6f5(decision=pass)。

未覆盖与残留边界

浏览器 smoke 与打包场景仍以 python3 为默认解释器(需要 LOOPX_PYTHON_BIN 覆盖),本次修复的可移植性保证覆盖的是产品重建建议所指向的 npm 构建入口,不是这些开发者证据工具;原生 Windows npm 路径、签名桌面发布与 Windows 生命周期用例仍由 CI/发布资格承担。远端 CI 未等待(沿用本 Goal 的 wait_for_ci=false)。

我的整体评价

APPROVE:上一轮的唯一阻塞项已按「保留共享 builder、只修解释器启动方式」的要求修复,并配有在旧写法下会失败的回归——既在本地受限 PATH 上证明,也在 Windows CI 中作为原生步骤常驻;合并 main 的产物冲突以「保持生成物退出 Git」解决而非拼接。改动仍单主题、可回滚,未引入新的 provider、状态权威或默认行为变更。

English verdict: APPROVE - exact head ebbb600a4233ea0a87df6ffc40a0be1437e38e9b replaces the hardcoded python3 npm entry with a single cross-platform launcher that discovers a Python 3.11+ interpreter (LOOPX_PYTHON, .loopx-python, .venv, python3/python, py), keeps all build rules in the shared builder, and adds a discriminating native Windows regression that rebuilds through npm run build:chat with an unusable python3.exe; the merge of latest main resolved every generated-asset conflict by keeping the deletion and rebuilt the bundle from merged source. 123 Python cases, 5 focused launcher tests, rebuild plus source verification, two browser smokes, PWA/docs/workflow smokes and Ruff passed locally, with receipt cqr_68b67f94416363f8e6f5.

@huangruiteng
huangruiteng merged commit 312934c into main Sep 24, 2026
11 of 12 checks passed
@huangruiteng
huangruiteng deleted the codex/frontend-artifact-delivery-0924 branch September 24, 2026 05:25
@huangruiteng

Copy link
Copy Markdown
Collaborator Author

Self-repair and merged decision record (admin-bypass merge, maintainer-authorized).

  • Requested change addressed: the review on d61b418af required a portable interpreter launch instead of the hardcoded python3 in apps/presentation/dashboard/package.json, plus a Windows CI regression that actually runs npm run build:chat where only python.exe is usable. Both are in this head.
  • Exact head reviewed and merged: ebbb600a4233ea0a87df6ffc40a0be1437e38e9b; merge commit on main: 312934cf34e1e46c8ab3eab99d69a58b29aa773c.
  • Before the merge, loopx pr-review --check-merge-readiness 4977@ebbb600a4... returned ready=true with no blocking reasons, using the author-owned exact-head review published above.
  • git diff ebbb600a4... 312934cf3 is empty: the merged main tree is byte-identical to the head that was validated.

Repair content:

  • scripts/chat_bundle_launcher.mjs (new) resolves a Python 3.11+ interpreter the way the rest of LoopX documents it — LOOPX_PYTHON, the installer-recorded .loopx-python, the repository .venv, then python3/python and the py launcher on Windows — and then runs the shared scripts/chat_bundle.py with forwarded arguments and exit code. An unusable explicit override fails loudly instead of falling back.
  • The npm entry now runs that launcher, so npm run build and the product's own rebuild advice no longer assume a POSIX-only executable name; all build rules stay in the single builder.
  • The windows-powershell lane installs frontend dependencies and rebuilds through npm run build:chat after shadowing python3 with an unusable python3.exe file, then runs python scripts/chat_bundle.py verify --source; npm caching was added and the job budget raised to 30 minutes. The old hardcoded command fails in that environment, so the step is a discriminating regression rather than a repeat of the Linux build.
  • Focused tests: tests/presentation/test_chat_bundle_launcher.py covers the python.exe-only fallback (asserting the legacy python3 <builder> command exits non-zero under the same restricted PATH), discovery precedence, no-fallback on an explicit override, the actionable missing-interpreter error and the npm entry wiring; tests/test_python_ci_workflow.py asserts the Windows rebuild step and its unusable-python3 shadow.
  • Latest main was merged; every conflict was generated output (loopx/web/chat/** delete/modify plus two new hashed CSS files from main). Resolution: keep those paths deleted, never concatenate competing HTML or retention manifests, then rebuild through npm run build:chat from the merged source and re-verify --source. Documentation (docs/development/frontend-delivery.md) and the frontstage workflow path triggers were updated with the portable entry.

Validation at the merged head:

  • Passed: 123 Python cases across frontend delivery, workflow, interpreter discovery, dashboard command and Windows install suites (4 native Windows cases skipped on macOS); npm run build:chat through the launcher on merged source plus scripts/chat_bundle.py verify --source; the old-tab deferred-import upgrade/retirement browser smoke and 10 packaged Personal Workspace browser scenarios against the production Chat handler; install-local-smoke standalone (3m19s); dashboard-pwa-bundle-smoke; docs-governance-smoke; frontstage-pages-workflow-smoke; scripts/ci unit tests; Ruff.
  • loopx canary premerge --from-git-diff: 19 checks selected, 18 passed. The single failure was examples/install-local-smoke.py hitting the canary's 120s per-check budget; it passes standalone in 3m19s.
  • Not awaited: remote CI, per this Goal's wait_for_ci=false and the maintainer's explicit instruction for this run.
  • Change-quality receipt: cqr_68b67f94416363f8e6f5 (decision=pass).
  • Carried limits: the native Windows npm path is proven by the new lane rather than this host, so its first green run is that platform's acceptance evidence; the browser smokes still default to python3 unless LOOPX_PYTHON_BIN is set, which is outside the repaired build entry; native Windows lifecycle tests and signed desktop release execution remain CI/release qualifications.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant