Add docker test image with SSH and headless browser for isolated testing #645

Merged
weichen merged 12 commits from feature/docker-test-image into main 2026-10-20 06:09:52 +00:00
Owner

目标与非目标

为本系统准备可重复构建的 Docker 测试环境镜像,供后续用 docker run 启动一次性容器、挂载仓库做隔离测试。镜像只含环境,不含仓库代码与任何密钥;不改变 make test/CI 行为;不引入部署容器化(本仓交付仍非容器化)。

交付内容

  • docker/Dockerfile:ubuntu:24.04(amd64)+ Go 1.27.1(官方 tarball)+ Node 26.10.0(官方 tarball)+ Python 3.14(deadsnakes PPA,python3 默认指向 3.14)+ git/make/openssh-server/sudo + Playwright 1.64.0 chromium(PLAYWRIGHT_BROWSERS_PATH=/opt/ms-playwright,与 modules/frontend 解析的 @playwright/test 1.64.0 对齐)。
  • docker/entrypoint.sh:前台 sshd;host key 首启生成;authorized_keys 运行时只读挂载注入(安装为 dev 属主 0600);支持 exec "$@" 透传调试命令。
  • SSH 边界:PermitRootLogin no、PasswordAuthentication no、专用 dev 用户(UID/GID 1000、NOPASSWD sudo)。
  • docker/verify-env.sh:镜像内环境自检(版本断言、sshd -t、sudo NOPASSWD、chromium --headless --dump-dom 真实启动),任一失败非零退出。
  • 根 Makefile:新增 image-build / image-verify 目标(含 help 与 .PHONY)。
  • docker/README.md:构建、自检、启动容器(端口映射/--shm-size/公钥挂载/仓库挂载 /workspace)、容器内跑 frontend e2e 最小流程、安全边界。

Why

隔离测试需要与本机一致的工具链和可复现环境;镜像不含任何 secret(.env.dev 等未进入镜像或构建上下文),凭据经运行时挂载注入。

Evidence

  • 实施经受控 agent-per-unit 传输进入本分支(transport a443dca04059a65125557a30f32dfa5c/62ee46d8fdc0,commit de3d3aff)。
  • make image-build exit=0;make image-verify exit=0 且 verify-env: PASS(SELF 证据已写入随本 PR 合入的任务卡)。
  • 任务卡(同一文档):.task/feature-docker-test-image.md(需求 R1–R4、单元运行 1–5 收据链、决策点闭合记录)。

Impact

仅新增 docker/ 与 Makefile 两个目标;不触碰 modules/**、CI、治理脚本。已知非阻塞项:FROM --platform=linux/amd64 触发 buildkit 一条 lint 警告(有意钉住 amd64)。

Refs

  • policy/delivery.md(agent-per-unit、分级门禁);AGENT-EXECUTION.md(cursor profile 已由 owner 停用至 2026-11-10 额度重置,见 16776aa)。
### 目标与非目标 为本系统准备可重复构建的 Docker 测试环境镜像,供后续用 `docker run` 启动一次性容器、挂载仓库做隔离测试。镜像只含环境,不含仓库代码与任何密钥;不改变 `make test`/CI 行为;不引入部署容器化(本仓交付仍非容器化)。 ### 交付内容 - `docker/Dockerfile`:ubuntu:24.04(amd64)+ Go 1.27.1(官方 tarball)+ Node 26.10.0(官方 tarball)+ Python 3.14(deadsnakes PPA,`python3` 默认指向 3.14)+ git/make/openssh-server/sudo + Playwright 1.64.0 chromium(`PLAYWRIGHT_BROWSERS_PATH=/opt/ms-playwright`,与 modules/frontend 解析的 @playwright/test 1.64.0 对齐)。 - `docker/entrypoint.sh`:前台 sshd;host key 首启生成;`authorized_keys` 运行时只读挂载注入(安装为 dev 属主 0600);支持 `exec "$@"` 透传调试命令。 - SSH 边界:`PermitRootLogin no`、`PasswordAuthentication no`、专用 `dev` 用户(UID/GID 1000、NOPASSWD sudo)。 - `docker/verify-env.sh`:镜像内环境自检(版本断言、`sshd -t`、sudo NOPASSWD、chromium `--headless --dump-dom` 真实启动),任一失败非零退出。 - 根 `Makefile`:新增 `image-build` / `image-verify` 目标(含 help 与 .PHONY)。 - `docker/README.md`:构建、自检、启动容器(端口映射/--shm-size/公钥挂载/仓库挂载 /workspace)、容器内跑 frontend e2e 最小流程、安全边界。 ### Why 隔离测试需要与本机一致的工具链和可复现环境;镜像不含任何 secret(.env.dev 等未进入镜像或构建上下文),凭据经运行时挂载注入。 ### Evidence - 实施经受控 agent-per-unit 传输进入本分支(transport `a443dca04059a65125557a30f32dfa5c/62ee46d8fdc0`,commit de3d3aff)。 - `make image-build` exit=0;`make image-verify` exit=0 且 `verify-env: PASS`(SELF 证据已写入随本 PR 合入的任务卡)。 - 任务卡(同一文档):`.task/feature-docker-test-image.md`(需求 R1–R4、单元运行 1–5 收据链、决策点闭合记录)。 ### Impact 仅新增 `docker/` 与 Makefile 两个目标;不触碰 modules/**、CI、治理脚本。已知非阻塞项:`FROM --platform=linux/amd64` 触发 buildkit 一条 lint 警告(有意钉住 amd64)。 ### Refs - policy/delivery.md(agent-per-unit、分级门禁);AGENT-EXECUTION.md(cursor profile 已由 owner 停用至 2026-11-10 额度重置,见 16776aa)。
weichen added 9 commits 2026-10-20 04:27:24 +00:00
Why: establish the authorized task workspace and its initial baseline.

Evidence: preserved precheck receipt in .task/feature-docker-test-image.md; R0=162c5a0160955989608f325b4be30458e3717d16.

Impact: task metadata only; the feature workspace starts at 162c5a0160.

Refs: .task/feature-docker-test-image.md
Why: user requested a Docker test image (system env + SSH + headless
browser) for isolated container-based testing; card records the
authorized boundary, requirements R1-R4 and the unit plan before
dispatching the bounded implementation unit.
Evidence: triage NEW receipt /tmp/docker-image-triage.json; startup
precheck READY at R0=162c5a0160 (SELF, in-card).
Impact: .task metadata only; no code behavior change.
Refs: policy/delivery.md; AGENT-EXECUTION.md
Why: first implementation run (cursor) failed-unknown after repeated
Cursor backend connection stalls; policy requires reconciling unknown
side effects before retry. Reconciliation showed no image built, no
containers left, canonical checkout clean; isolated worktree preserved.
Evidence: /tmp/docker-image-unit1-receipt.json (run 1, failed-unknown);
cursor probe exit 0 after recovery.
Impact: .task metadata only.
Refs: AGENT-EXECUTION.md; policy/governance.md
Why: run 2 failed-unknown on Cursor monthly usage cap (deterministic,
resets 2026-11-10); host attempt to disable the cursor profile was
rejected by pre-commit admit (non-exempt path needs transport
provenance), and the routing change itself requires a successful run,
so the dispatch path is dead-locked pending a human decision.
Evidence: /tmp/docker-image-unit2-receipt.json,
/tmp/docker-image-unit3-receipt.json; agy probe ok, pi backend 529.
Impact: .task metadata only.
Refs: AGENT-EXECUTION.md; policy/delivery.md
Why: Cursor Ultra monthly usage cap exhausts on every dispatch
(ActionRequiredError); owner approved disabling via option 1 of the
task decision point, keeping antigravity/pi as active candidates.
Evidence: /tmp/docker-image-unit2-receipt.json (failed-unknown,
usage cap); agy probe ok; agent-exec validate ok.
Impact: execution routing only; re-enable enabled: true after 2026-11-10.
Refs: AGENT-EXECUTION.md; .task/feature-docker-test-image.md
Why: owner approved option 1 - disabled the cursor profile by their
own authority (commit 16776aa) after monthly usage cap exhausted;
dispatch now routes to antigravity (probe ok).
Evidence: AGENT-EXECUTION.md diff in 16776aa; agent-exec validate ok.
Impact: .task metadata only.
Refs: AGENT-EXECUTION.md; policy/delivery.md
Why: run 4 (antigravity) fully implemented and verified the unit, but a
trailing backend API EOF polluted the result envelope, so the controller
fail-closed without a transport. Host independently re-ran
image verify-env.sh (PASS). Redispatch as a pure re-verify run with
docker layer cache; bound set: if transport mechanics fail again,
return to owner decision instead of looping.
Evidence: /tmp/docker-image-unit4-receipt.json; raw log tail EOF;
verify-env PASS re-run by host.
Impact: .task metadata only.
Refs: AGENT-EXECUTION.md; policy/governance.md
task: record run 5 success, apply and authoritative verification
ci / test (pull_request) Successful in 7m52s
ci / svc-realcombo (pull_request) Successful in 3m51s
ci / test-pg (pull_request) Successful in 8m39s
8e062caf9f
Why: run 5 (antigravity re-verify) returned success with a transport;
host applied it (b59e53de..de3d3aff) and re-ran make image-build /
make image-verify on the applied HEAD, both passing (SELF evidence in
card). R1-R4 acceptance conditions met; CI GATE and review pending.
Evidence: /tmp/docker-image-unit5-receipt.json; evidence blocks in card.
Impact: .task metadata only.
Refs: policy/governance.md
weichen added 1 commit 2026-10-20 05:07:13 +00:00
Merge origin/main into feature/docker-test-image
ci / test-pg (pull_request) Successful in 9m56s
ci / svc-realcombo (pull_request) Successful in 2m20s
ci / test (pull_request) Successful in 9m54s
b9c0fc3fa1
Why: delivery policy requires the final candidate to include the
latest authoritative target before review and merge.
Evidence: git merge; conflicts resolved below if any.
Impact: composition update only; component pins unchanged.
Refs: policy/delivery.md
weichen added 2 commits 2026-10-20 05:31:40 +00:00
Why: host review passed (scope, secrets, Makefile increments only);
CI green on merged HEAD b9c0fc3 after two infra-flake reruns;
composition merged with origin/main d2035c7 and components verified.
Evidence: runs 4357/4360 logs; ci-wait CI_SUCCESS; card records.
Impact: .task metadata only.
Refs: policy/delivery.md
Fold-close the task card before merge
ci / test (pull_request) Successful in 8m22s
ci / svc-realcombo (pull_request) Successful in 2m21s
ci / test-pg (pull_request) Successful in 11m57s
ad81857e81
Why: close the task card inside its own PR so landing it needs no post-merge backfill or separate close PR.
Evidence: .task/feature-docker-test-image.md -> .task/archive/feature-docker-test-image.md; status 已完成(合入前闭合); PR #645 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/645.
Impact: task metadata only; the card is archived within PR #645 and lands with its merge commit.
Refs: task.sh close --self
weichen merged commit 65e4aa3959 into main 2026-10-20 06:09:52 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: weichen/Agent-System-Dev#645