fix(GOV-009): 完成仅源码部署最终复审

This commit is contained in:
2026-08-13 21:33:38 +08:00
parent 47d0e0d248
commit c75665446b
13 changed files with 191 additions and 50 deletions
@@ -2,18 +2,18 @@
- 记录时间:2026-08-13 GMT+8
- 分支:`main`
- 实现提交:`95b8611bd9bbc282193591e472e2e19c617e5035`
- 远端:`origin/main` 已核对为同一 SHA
- 仅源码实现提交:`47d0e0d248eb9b21cbd12f1625d3bd0e9c266dc9`
- 远端:`origin/main` 已核对为同一 SHA;最终 Review 证据提交将在验证后同步
```text
Repository: a-share-analysis
Indexed commit: 95b8611
Current commit: 95b8611
Indexed commit: 47d0e0d
Current commit: 47d0e0d
Status: up-to-date
Nodes: 1568
Relationships: 2190
Clusters: 46
Execution flows: 47
Nodes: 1606
Relationships: 2253
Clusters: 48
Execution flows: 50
```
图谱已包含 Web、API、Scheduler、Worker、配置加载、健康检查、OpenAPI、消息信封、Schema、Docker 验证和治理门禁。GitNexus 本地索引未提交仓库。
图谱已包含 Web、API、Scheduler、Worker、配置加载、健康检查、OpenAPI、消息信封、Schema、外部 Redis 预检、源码产物/systemd/Nginx 发布验证和治理门禁。旧 Docker 验证符号已删除,GitNexus 本地索引未提交仓库。
@@ -16,3 +16,16 @@
- Schema 空库、MySQL 5.7.42、契约漂移和 `.vue` 工程边界均有自动门禁。
新增关系数量符合“从占位目录建立应用基线”的预期。后续市场概览功能应在这些边界内增加业务模块,不应把 Web 与 Server 重新耦合。
## 仅源码部署调整对比
| 项目 | 调整设计提交 `cfcd7f1` | 实现与 Review 后 | 变化 |
| --- | ---: | ---: | ---: |
| 符号 | 1589 | 1606 | +17 |
| 关系 | 2211 | 2253 | +42 |
| 执行流程 | 47 | 50 | +3 |
- 删除 Docker 构建、镜像引用和容器生命周期校验符号,新增源码发布校验流程。
- 新增 `checkLocalRedis` 与 `runTestApi`,Playwright 只依赖现有本机 Redis,不拥有基础设施生命周期。
- `verifySourceDeployment` 校验 Web、API、Scheduler、Worker 产物以及 systemd/Nginx;递归阻断任意活动 Dockerfile、`.dockerignore` 和 Compose YAML。
- GitNexus compare 检测风险为 MEDIUM,98 个变更符号、3 个受影响符号,影响集中在部署门禁与 E2E 启动链;未影响业务 API、市场模块、生产数据库或 RocketMQ 消息发送。
@@ -13,3 +13,14 @@ Review 整改前对具体符号分别执行上游影响分析:三进程 bootst
最终代码复审补充发现无引号 Vue 外部 `script src` 可绕过早期正则门禁;影响分析为 LOW,只有 1 个直接调用者和 1 条边界检查流程。`95b8611` 改用 Vue 3.5.41 官方 SFC 解析器,并以单双引号、无引号和属性换序用例验证,未扩大应用运行影响面。
检测范围与开发前影响计划一致,未出现用户体系、生产数据库、外部消息写入或其他项目流程。
## 仅源码部署调整
- 对比基线:`cfcd7f13d9a6a35173d01bd8ca1458911190e70f`
- 实现提交:`47d0e0d248eb9b21cbd12f1625d3bd0e9c266dc9`
- 变更范围:27 个已索引文件、98 个变更符号、3 个受影响符号
- 风险:MEDIUM
开发前对 `assertImmutableImageReferences`、旧 Docker 辅助函数和 `forwardSignal` 的上游影响均为 LOW,0 条业务执行流受影响。最终 compare 的 MEDIUM 来自部署门禁整体替换:旧 Docker 验证删除,源码发布与 Redis 预检新增,并非应用业务依赖扩散。
Review 中 `verifySourceDeployment` 和 `assertDockerArtifactsAbsent` 的影响分析均为 LOW;后者只影响 1 条源码部署校验流程。递归活动资产扫描与 systemd 正式目标名测试完成后,部署 6/6、环境 10/10 和完整 `verify:release` 通过。
@@ -57,7 +57,7 @@
### GREEN
- 源码部署夹具:5/5;覆盖完整发布、Docker 活动文件、Worker 产物缺失、systemd root 用户和 Nginx 错误配置。
- 源码部署夹具:初始 5/5;最终 Review 加入任意新 Dockerfile/Compose 路径回归后为 6/6。
- 环境与部署契约:10/10;活动 Docker 入口不存在,本地外部 Redis和唯一 Ubuntu 源码部署规则通过。
- Redis 预检:2/2;OS 分配的本机 TCP 端口分别验证可达和不可达,不安装或启动外部服务。
- 本机 `redis-cli -h 127.0.0.1 -p 6379 ping` 返回 `PONG`。
@@ -65,3 +65,18 @@
- Playwright 桌面与移动视口共 4/4,通过真实本机 Redis、API 健康接口和 Web 同源代理链路。
前述 `pnpm verify:docker` 及镜像验证内容是调整前的真实历史证据。2026-08-13 用户确认仅源码部署后,这些能力已被取代并从活动仓库删除,不再执行或作为发布依据。
### 最终源码发布验证
`pnpm verify:release`:passed。
- Node.js 22.11.0、pnpm 10.25.0 运行时检查通过。
- 环境 10/10、Schema 28/28、契约 3/3、工程边界 8/8、源码部署 6/6。
- Web 8/8;Server Vitest 30/30,Redis 预检 Node 测试 2/2。
- Web、API、Scheduler、Worker 生产构建通过。
- Playwright 桌面/移动共 4/4,通过现有本机 Redis 和真实 API 健康链路。
- `verify:source` 确认四类产物、三份 systemd 单元与 Nginx 配置一致;未调用 Docker。
应用内浏览器补充验证 1440×900 与 390×844:两种视口页面均非空,页面宽度等于视口宽度,无横向溢出、文字重叠或控制台 warning/error;DOM 中导航与“应用就绪”区域完整。
最终 Review 发现并修复两项 Important:systemd 模板曾以 `.service.example` 目标名安装,任意新路径的 Dockerfile/Compose 文件曾可绕过固定清单。两项均先增加失败测试,再修复至 GREEN。
@@ -22,3 +22,25 @@
Critical、Important、Minor 均无未关闭问题。
最终结论:passed
## 仅源码部署调整复审
- 审查范围:`cfcd7f13d9a6a35173d01bd8ca1458911190e70f..47d0e0d248eb9b21cbd12f1625d3bd0e9c266dc9` 及其后 Review 修复
- 审查重点:发布门禁绕过、子进程与信号、Redis 失败语义、systemd/Nginx 真实命令、历史证据和测试缺口
### 发现与处置
1. **Important:systemd 模板目标名不可执行。** 初版源码手册把 `*.service.example` 原样安装并以该名称重启,真实 systemd 单元名不正确。新增环境契约测试先 RED,随后改为分别安装成 `a-share-api.service`、`a-share-scheduler.service`、`a-share-worker.service`,并统一 verify/restart/status/journalctl 命令;环境 10/10 GREEN。
2. **Important:Docker 禁止清单可被新路径绕过。** 初版只阻断已删除的固定旧路径,`ops/Dockerfile` 或新 Compose YAML 会被放行。新增未列举路径测试先 RED,随后用递归活动资产扫描阻断任意 Dockerfile、`.dockerignore`、`docker-compose*.yml` 和 `compose/` YAML;部署测试 6/6 GREEN。
### 最终证据
- `pnpm verify:release` 完整通过,包含静态检查、类型、全部测试、四类构建、Playwright 4/4 和源码发布校验。
- Redis 不可达时只返回脱敏的固定本机服务提示;无安装、启动、停止或删除基础设施的分支。
- API 子进程只接收公开禁用态测试夹具,SIGINT/SIGTERM 只转发给该子进程。
- 源码门禁要求 Web 与三个 Server 入口、三份最小权限 systemd 单元和 Nginx Web/API 配置完整。
- 当前跟踪文件没有 Dockerfile、Compose、`.dockerignore` 或 Docker 专用脚本;历史文档事实仍可追溯。
Critical、Important、Minor 均无未关闭问题。
最终结论:passed
@@ -19,3 +19,17 @@
Critical、Important、Minor 均无未关闭问题。
最终结论:passed
## 仅源码部署调整复审
- 实施计划、TDD RED/GREEN、GitNexus 前置影响、开发后 compare 和回退说明均已写入 GOV-009 档案。
- 新增关键函数包含外部基础设施所有权和安全边界中文注释,文件按“源码发布门禁”和“E2E 启动器”稳定职责组织,未过度拆分。
- MySQL 仍固定 5.7.42、`utf8mb4`、`utf8mb4_general_ci`、`+08:00`;本次没有连接、探测或读取生产数据库,也没有创建迁移或业务表。
- 本机 Redis 只执行 `PING` 与 TCP 可达性检查;RocketMQ 保持禁用,没有创建 Topic、生产或消费消息。
- 现行架构、开发规范、流程规范和部署手册只宣称 Ubuntu 源码部署;GOV-006 与早期 GOV-009 Docker 记录保留为历史并明确被取代。
- `47d0e0d` 为带 GOV-009 的中文 Conventional Commit,已推送项目专用 Gitea;最终 Review 修复和证据将在验证后以独立中文提交推送。
- manifest 保持 `reviewing/unreleased`,本地与远端均不存在 `v0.0.8`,等待用户完成总体架构确认。
Critical、Important、Minor 均无未关闭问题。
最终结论:passed
@@ -2,7 +2,7 @@
- 功能编号:GOV-009
- 决策日期:2026-08-13
- 状态:设计已确认,待实施
- 状态:已实施并通过 Review,等待总体架构确认
- 取代范围:GOV-006、GOV-009 中仍有效的 Docker 部署约定
## 结论
@@ -54,7 +54,7 @@
- Consumes: repository paths and the existing `deploy/systemd/`, `deploy/nginx/`, `web/dist/`, and `server/dist/` conventions.
- Produces: root scripts `test:deployment` and `verify:source`; failing tests that define the source-only repository contract before implementation.
- [ ] **Step 1: Add failing fixture tests for the source verifier**
- [x] **Step 1: Add failing fixture tests for the source verifier**
Create tests that import the not-yet-existing module and define these exact behaviors:
@@ -96,7 +96,7 @@ test('Nginx 未代理 API 或未指向 Web dist 时会阻断源码发布', async
The local `createSourceReleaseFixture` helper must create only the minimum paths needed by the verifier: four build outputs, three unit files with distinct `EnvironmentFile`, and one Nginx file. It must accept `omit`, `apiUser`, and `invalidNginx` options so each negative test changes one condition.
- [ ] **Step 2: Replace Docker assertions in the environment baseline with source-only assertions**
- [x] **Step 2: Replace Docker assertions in the environment baseline with source-only assertions**
Keep env-template and RocketMQ tests unchanged. Replace Compose/Docker tests with explicit active-path assertions:
@@ -123,7 +123,7 @@ test('活动仓库不再包含 Docker 运行构建或部署入口', async () =>
Add focused checks that current docs describe external local Redis, Ubuntu 22.04/24.04, Node 22.x, pnpm 10.25.0, immutable releases, health checks, and rollback. Do not scan historical feature archives for the word Docker because those files are intentional evidence.
- [ ] **Step 3: Point root deployment scripts at the not-yet-existing source verifier**
- [x] **Step 3: Point root deployment scripts at the not-yet-existing source verifier**
Change root scripts to the following contract:
@@ -135,7 +135,7 @@ Change root scripts to the following contract:
Remove `check:images` and `verify:docker`.
- [ ] **Step 4: Run RED tests and record expected failures**
- [x] **Step 4: Run RED tests and record expected failures**
Run:
@@ -167,11 +167,11 @@ Expected: the deployment test fails because `verify-source-deployment.mjs` does
- Consumes: `verifySourceDeployment(repositoryRoot?: string | URL): Promise<void>` inputs and the existing build/deployment paths.
- Produces: an importable verifier plus the CLI command `pnpm verify:source`, which exits non-zero on incomplete or unsafe source releases.
- [ ] **Step 1: Run GitNexus impact before modifying or deleting deployment symbols**
- [x] **Step 1: Run GitNexus impact before modifying or deleting deployment symbols**
Run upstream impact for `assertImmutableImageReferences`, `docker`, and `verifyLongRunningProcess`, including tests. Report direct callers, affected processes, and risk to the user. If risk is HIGH or CRITICAL, stop before editing and ask for confirmation as required by `AGENTS.md`.
- [ ] **Step 2: Implement the minimal source verifier**
- [x] **Step 2: Implement the minimal source verifier**
Implement these exports in one readable file:
@@ -206,11 +206,11 @@ The implementation must:
- produce errors that identify the missing or invalid file without printing env values;
- print `源码发布产物与 systemd/Nginx 配置验证通过` only in direct CLI mode.
- [ ] **Step 3: Delete the obsolete Docker artifacts**
- [x] **Step 3: Delete the obsolete Docker artifacts**
Delete only the paths listed in this task. Do not delete env templates, systemd units, the production Nginx template, or historical GOV-006/GOV-009 evidence.
- [ ] **Step 4: Run GREEN deployment tests after creating build outputs**
- [x] **Step 4: Run GREEN deployment tests after creating build outputs**
Run:
@@ -223,7 +223,7 @@ pnpm verify:source
Expected: all commands pass; `verify:source` confirms all four build outputs and the deployment templates.
- [ ] **Step 5: Detect scope, commit, and push the executable deployment change**
- [x] **Step 5: Detect scope, commit, and push the executable deployment change**
Run GitNexus `detect_changes(scope: "all")`. Review that only deployment validation and environment-policy flows are affected, then run:
@@ -246,11 +246,11 @@ git push origin "$(git branch --show-current)"
- Consumes: TCP endpoint `127.0.0.1:6379` and the existing public production API fixture.
- Produces: `checkLocalRedis({ host, port, timeoutMs }): Promise<void>` and `runTestApi(): Promise<void>`; direct execution launches only the API process after Redis succeeds.
- [ ] **Step 1: Run GitNexus upstream impact for launcher symbols**
- [x] **Step 1: Run GitNexus upstream impact for launcher symbols**
Run impact for `forwardSignal` and the `run-test-api.mjs` file, including tests. Report the Playwright web-server dependency and any API health flows before editing. Stop for confirmation only if the graph reports HIGH or CRITICAL risk.
- [ ] **Step 2: Write failing launcher tests**
- [x] **Step 2: Write failing launcher tests**
Refactor-safe tests must verify behavior rather than depend on Docker availability:
@@ -275,7 +275,7 @@ test('API 测试启动器不包含 Docker 子进程路径', async () => {
Use an OS-assigned loopback port for deterministic tests. The user-facing failure message may state the fixed required Redis endpoint even when the injected test port differs.
- [ ] **Step 3: Run the launcher RED test**
- [x] **Step 3: Run the launcher RED test**
Run:
@@ -285,7 +285,7 @@ node --test server/tools/run-test-api.test.mjs
Expected: FAIL because `checkLocalRedis` and guarded direct-execution behavior do not yet exist.
- [ ] **Step 4: Refactor the launcher without infrastructure fallback**
- [x] **Step 4: Refactor the launcher without infrastructure fallback**
Remove `execFileSync`, container naming, dynamic Redis port publication, ownership flags, and cleanup. Export and use:
@@ -305,7 +305,7 @@ export async function runTestApi() {
Guard execution with the existing `process.argv[1]` and `fileURLToPath(import.meta.url)` pattern so tests can import the functions without starting API. Keep `REDIS_PORT: '6379'`; never derive or override it from a container.
- [ ] **Step 5: Include the new test in the Server test command**
- [x] **Step 5: Include the new test in the Server test command**
Change the Server test script to run both Vitest and the Node launcher test:
@@ -313,7 +313,7 @@ Change the Server test script to run both Vitest and the Node launcher test:
"test": "vitest run && node --test tools/run-test-api.test.mjs"
```
- [ ] **Step 6: Run GREEN and real local Redis checks**
- [x] **Step 6: Run GREEN and real local Redis checks**
Run:
@@ -326,7 +326,7 @@ pnpm verify:e2e
Expected: unit tests pass, Redis prints `PONG`, and both Playwright viewports pass using the already-running local Redis. If Redis is unavailable, stop with the new explicit error; do not start or install it.
- [ ] **Step 7: Detect scope, commit, and push the launcher change**
- [x] **Step 7: Detect scope, commit, and push the launcher change**
Run GitNexus `detect_changes(scope: "all")`, confirm the impact is limited to Playwright/API startup, then run:
@@ -364,7 +364,7 @@ git push origin "$(git branch --show-current)"
- Consumes: the confirmed `source-only-deployment-design.md` decision and actual Task 2/3 behavior.
- Produces: one unambiguous current deployment policy with intact historical evidence and a traceable GOV-009 record.
- [ ] **Step 1: Update current public docs and architecture**
- [x] **Step 1: Update current public docs and architecture**
Make these statements exact and consistent:
@@ -377,7 +377,7 @@ Make these statements exact and consistent:
Remove the active Docker deployment link from `README.md` and `docs/index.md`.
- [ ] **Step 2: Update mandatory engineering and workflow rules**
- [x] **Step 2: Update mandatory engineering and workflow rules**
In code standards, replace the dual-deployment variable rule with:
@@ -387,7 +387,7 @@ In code standards, replace the dual-deployment variable rule with:
Replace `开发、测试、Docker 和生产环境` with `开发、测试和生产环境`. In workflow rules, require env/systemd/Nginx synchronization and immutable release-directory rollback; remove Compose/image language. State that `verify:release` is the source-release gate and that unavailable external infrastructure is a failed prerequisite, never a container fallback.
- [ ] **Step 3: Update GOV-009 current records without falsifying history**
- [x] **Step 3: Update GOV-009 current records without falsifying history**
Revise PRD scope, R7, design configuration/deployment sections, automated test plan, current release notes, rollback, and architecture review to match actual source-only implementation. Add `source_only_deployment_implementation_plan` to `manifest.yaml`. Keep `status: reviewing`, `release: unreleased`, and the architecture confirmation completion gate.
@@ -395,11 +395,11 @@ In `qa/test-results.md`, preserve dated Docker validation as historical fact and
If GOV-006's manifest presents its Docker approach as current, add only a dated `superseded_by` pointer to the GOV-009 source-only decision; do not rewrite its original PRD/design/test evidence.
- [ ] **Step 4: Add the unreleased changelog decision**
- [x] **Step 4: Add the unreleased changelog decision**
At the top current section, record that the project removed Docker/Compose/image validation and now supports only Ubuntu source deployment with external infrastructure. Leave older entries about when Docker was added unchanged below it.
- [ ] **Step 5: Run active-document policy tests and scan for contradictions**
- [x] **Step 5: Run active-document policy tests and scan for contradictions**
Run:
@@ -410,7 +410,7 @@ rg -n '双部署|同时支持 Docker|Compose 只|Docker Compose 生产|verify:do
Expected: tests pass. Search results may remain only in explicitly dated historical results or supersession explanations; no current instruction may expose a Docker command or claim Docker support.
- [ ] **Step 6: Detect scope, commit, and push documentation alignment**
- [x] **Step 6: Detect scope, commit, and push documentation alignment**
Run GitNexus `detect_changes(scope: "all")`, then:
@@ -437,7 +437,7 @@ git push origin "$(git branch --show-current)"
- Consumes: the completed implementation, root verification scripts, GitNexus graph, and Review standards.
- Produces: final evidence for the deployment-policy adjustment while GOV-009 remains `reviewing/unreleased` pending user architecture confirmation.
- [ ] **Step 1: Run focused tests and full source release verification**
- [x] **Step 1: Run focused tests and full source release verification**
Run without Docker:
@@ -450,11 +450,11 @@ pnpm verify:release
Expected: all pass. `verify:release` must execute the full root verification, desktop/mobile Playwright checks, builds, and `verify:source`; it must not invoke Docker.
- [ ] **Step 2: Perform visual verification at both configured viewports**
- [x] **Step 2: Perform visual verification at both configured viewports**
Use Playwright/browser screenshots at 1440x900 and 390x844. Confirm the page is nonblank, API health data renders, no content overlaps, and browser console/network contains no blocking error. Save screenshots under the existing ignored/output convention and record results, not binary artifacts, in `qa/test-results.md`.
- [ ] **Step 3: Refresh GitNexus and record before/after evidence**
- [x] **Step 3: Refresh GitNexus and record before/after evidence**
Run:
@@ -466,7 +466,7 @@ npm run governance:finish -- GOV-009 application-scaffold-baseline
Then use GitNexus `detect_changes(scope: "compare", base_ref: "cfcd7f13d9a6a35173d01bd8ca1458911190e70f")`. Record node/edge/flow counts, removed Docker verifier symbols, added source verifier symbols, and affected processes in the three GitNexus records. Do not commit `.gitnexus/`.
- [ ] **Step 4: Conduct code Review**
- [x] **Step 4: Conduct code Review**
Review for functional regressions, release-gate bypasses, unsafe process spawning, Redis failure semantics, missing build artifacts, and test gaps. Resolve every blocking finding, rerun affected checks, and finish `review/code-review.md` with the exact line:
@@ -474,7 +474,7 @@ Review for functional regressions, release-gate bypasses, unsafe process spawnin
最终结论:passed
```
- [ ] **Step 5: Conduct development-standards Review**
- [x] **Step 5: Conduct development-standards Review**
Review source-only policy consistency, Chinese comments for non-obvious logic, file responsibility, no secrets, MySQL 5.7 constraints, no production access, historical traceability, Chinese commits, Gitea push state, and the absence of a `v0.0.8` tag. Finish `review/standards-review.md` with the exact line:
@@ -482,7 +482,7 @@ Review source-only policy consistency, Chinese comments for non-obvious logic, f
最终结论:passed
```
- [ ] **Step 6: Re-run final verification after Review edits**
- [x] **Step 6: Re-run final verification after Review edits**
Run:
@@ -494,7 +494,7 @@ git status --short
Expected: formatting and release verification pass. Only intended Review/evidence files remain uncommitted.
- [ ] **Step 7: Detect final scope, commit, and push evidence**
- [x] **Step 7: Detect final scope, commit, and push evidence**
Run GitNexus `detect_changes(scope: "all")`, verify no unexpected application flow changed, then:
@@ -504,7 +504,7 @@ git commit -m "docs(GOV-009): 封存仅源码部署复核证据"
git push origin "$(git branch --show-current)"
```
- [ ] **Step 8: Confirm remote consistency without releasing**
- [x] **Step 8: Confirm remote consistency without releasing**
Run: