Compare commits
24
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e70a52aea | ||
|
|
1383cf1d2b | ||
|
|
344776cc18 | ||
|
|
8e4cdf09af | ||
|
|
fa96910d17 | ||
|
|
6cb6a276ca | ||
|
|
cb36b59acc | ||
|
|
6bcd496636 | ||
|
|
6e0dd42190 | ||
|
|
aa1e8c2b2b | ||
|
|
9d5ed689ce | ||
|
|
c22b9fb34a | ||
|
|
ab5f51174a | ||
|
|
11e61d6f8a | ||
|
|
b7acfeb3ee | ||
|
|
a69e8c82bd | ||
|
|
f84d7c724e | ||
|
|
6bec85e1f8 | ||
|
|
8441284c7c | ||
|
|
05e4034089 | ||
|
|
bd2fe3de22 | ||
|
|
0fd28ea94d | ||
|
|
39bb5bc71f | ||
|
|
8cb2d2297b |
@@ -35,7 +35,7 @@ jobs:
|
||||
parsed_server = urlsplit(SERVER)
|
||||
if parsed_server.scheme not in {"http", "https"} or not parsed_server.netloc:
|
||||
sys.exit("Checkout server must be the platform-injected http(s) URL")
|
||||
SSH = "ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/"
|
||||
SSH = "ssh://git@gitea.naitangbaobao.cn:52222/weichen/"
|
||||
# Reviewed allowlist, independent of candidate .gitmodules. Add repositories
|
||||
# here only with an explicit review of the checkout credential's scope.
|
||||
REPOSITORIES = {
|
||||
@@ -219,7 +219,7 @@ jobs:
|
||||
parsed_server = urlsplit(SERVER)
|
||||
if parsed_server.scheme not in {"http", "https"} or not parsed_server.netloc:
|
||||
sys.exit("Checkout server must be the platform-injected http(s) URL")
|
||||
SSH = "ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/"
|
||||
SSH = "ssh://git@gitea.naitangbaobao.cn:52222/weichen/"
|
||||
# Reviewed allowlist, independent of candidate .gitmodules. Add repositories
|
||||
# here only with an explicit review of the checkout credential's scope.
|
||||
REPOSITORIES = {
|
||||
@@ -410,7 +410,7 @@ jobs:
|
||||
export GIT_CONFIG_KEY_1="http.$SERVER/.extraheader"
|
||||
export GIT_CONFIG_VALUE_1="AUTHORIZATION: token $SUBMODULE_TOKEN"
|
||||
export GIT_CONFIG_KEY_2="url.$SERVER/weichen/.insteadOf"
|
||||
export GIT_CONFIG_VALUE_2="ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/"
|
||||
export GIT_CONFIG_VALUE_2="ssh://git@gitea.naitangbaobao.cn:52222/weichen/"
|
||||
export GIT_CONFIG_KEY_3="core.hooksPath"
|
||||
export GIT_CONFIG_VALUE_3="/dev/null"
|
||||
git clone --depth=1 "$SERVER/weichen/Agent-System-RDM.git" rdm
|
||||
@@ -544,7 +544,7 @@ jobs:
|
||||
parsed_server = urlsplit(SERVER)
|
||||
if parsed_server.scheme not in {"http", "https"} or not parsed_server.netloc:
|
||||
sys.exit("Checkout server must be the platform-injected http(s) URL")
|
||||
SSH = "ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/"
|
||||
SSH = "ssh://git@gitea.naitangbaobao.cn:52222/weichen/"
|
||||
# Reviewed allowlist, independent of candidate .gitmodules. Add repositories
|
||||
# here only with an explicit review of the checkout credential's scope.
|
||||
REPOSITORIES = {
|
||||
@@ -698,7 +698,7 @@ jobs:
|
||||
export GIT_CONFIG_KEY_1="http.$SERVER/.extraheader"
|
||||
export GIT_CONFIG_VALUE_1="AUTHORIZATION: token $SUBMODULE_TOKEN"
|
||||
export GIT_CONFIG_KEY_2="url.$SERVER/weichen/.insteadOf"
|
||||
export GIT_CONFIG_VALUE_2="ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/"
|
||||
export GIT_CONFIG_VALUE_2="ssh://git@gitea.naitangbaobao.cn:52222/weichen/"
|
||||
export GIT_CONFIG_KEY_3="core.hooksPath"
|
||||
export GIT_CONFIG_VALUE_3="/dev/null"
|
||||
git clone --depth=1 "$SERVER/weichen/Agent-System-RDM.git" rdm
|
||||
|
||||
+14
-14
@@ -1,42 +1,42 @@
|
||||
[submodule "modules/core"]
|
||||
path = modules/core
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Core.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-System-Core.git
|
||||
[submodule "modules/backend"]
|
||||
path = modules/backend
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Backend.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-System-Backend.git
|
||||
[submodule "modules/frontend"]
|
||||
path = modules/frontend
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Frontend.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-System-Frontend.git
|
||||
[submodule "modules/documents"]
|
||||
path = modules/documents
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Documents.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-System-Documents.git
|
||||
[submodule "deps/development-guidelines"]
|
||||
path = deps/development-guidelines
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Development-Guidelines.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Development-Guidelines.git
|
||||
[submodule "deps/agent-native"]
|
||||
path = deps/agent-native
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-Native.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-Native.git
|
||||
[submodule "deps/agent-squad"]
|
||||
path = deps/agent-squad
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-Squad.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-Squad.git
|
||||
[submodule "deps/agent-intent"]
|
||||
path = deps/agent-intent
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-Intent.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-Intent.git
|
||||
[submodule "deps/error-code-system"]
|
||||
path = deps/error-code-system
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Error-Code-System.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Error-Code-System.git
|
||||
[submodule "deps/logging-system"]
|
||||
path = deps/logging-system
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Logging-System.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Logging-System.git
|
||||
[submodule "modules/ui"]
|
||||
path = modules/ui
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-UI.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-System-UI.git
|
||||
[submodule "deps/agent-command"]
|
||||
path = deps/agent-command
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-Command.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-Command.git
|
||||
[submodule "deps/development-manager"]
|
||||
path = deps/development-manager
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Development-Manager.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Development-Manager.git
|
||||
[submodule "deps/agent-document-renderer"]
|
||||
path = deps/agent-document-renderer
|
||||
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-Document-Renderer.git
|
||||
url = ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-Document-Renderer.git
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
# fix/gitea-endpoint-migration 任务卡
|
||||
|
||||
任务主记录:<PR 链接,创建后回填>;状态:进行中;owner:weichen;状态:进行中;owner:weichen
|
||||
|
||||
- 权威仓:ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 3d3474a731f9ef3ee1f41935e63bca3afb70db56
|
||||
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-fix-gitea-endpoint-migration(worktree);分支:fix/gitea-endpoint-migration
|
||||
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
|
||||
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=f4118023ba80fc3d75db8755e2dd21e4697b7a15b554f0df85717ac6ac814cf8;triage_receipt=/tmp/gitea-migration-triage.json;receipt_sha256=e0bca239b2c0ebaea8fb76d5b743de43d06a3ee911ea0e2587bc07226367110d
|
||||
|
||||
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
|
||||
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
|
||||
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
|
||||
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
|
||||
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
|
||||
|
||||
## 目标与非目标
|
||||
|
||||
**目标**:Gitea 服务器迁移后(web https://gitea.naitangbaobao.cn,SSH gitea.naitangbaobao.cn:52222,凭据不变),更新本仓全部功能性端点引用:`.gitmodules`、`scripts/task.sh`、`scripts/task_triage.py`、`scripts/facts-verify.sh`、`scripts/svc.sh`(RDM_ORIGIN_DEFAULT)、`.gitea/workflows/ci.yaml`、`tests/test_facts_verify.py`、`tests/test_ci_credentials.py`、`tests/test_svc_realcombo.py`、`tests/test_task_triage.py`、`tests/test_ci_wait.py`、`policy/facts.md`(F1/F2/F3 端点与 last_verified)、`policy/delivery.md` 合入队列链接。旧值:git-home.u1680832.nyat.app:30319(web/API)、git-ssh.u1680832.nyat.app:31411、ssh://git@192.168.3.2:2222(SSH)。
|
||||
|
||||
**完成条件**:仓内除历史记录(.task/**、docs/superpowers/ 归档规格、runtime/)外无旧端点引用;`make facts-verify` 中 F1/F2/F3(本次迁移端点)PASS;`make test-governance` 与相关单测通过。已知漂移(非阻塞,转后续任务):F4(退役 git-panel 端点)判据过时,迁移后该端点 TLS unexpected-eof,F4 严格判据不再成立,需要宿主级子模块物化环境刷新;facts-verify 非法失败不计入本任务交付门禁(不在 make test 内)。
|
||||
|
||||
**非目标**:历史记录/归档文档中的旧 URL;其他仓(RDM/KB 等)仓内引用(各自任务处理);本地 ~/.ssh/config、~/.secrets/gitea、各仓 remote(已由 owner 更新);policy/facts.md F4(退役旧端点 git-panel 的历史事实,与本次迁移无关)。
|
||||
|
||||
## Agent 实施收据
|
||||
|
||||
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
|
||||
|
||||
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|
||||
|---|---|---|---|---|---|---|---|---|---|---|
|
||||
| gitea-endpoint-migration | 端点迁移(13 文件) | — | implementation | cursor,… | 1 | cursor(auto) | failed-unknown | 无(终态 JSON 解码失败;现场保留,diff 导出 /tmp/gitea-migration-attempt1.patch) | 否 | /tmp/gitea-migration-run2-receipt.json |
|
||||
| gitea-endpoint-migration | 同上(采用 attempt1 补丁) | — | implementation | cursor,… | 2 | cursor(auto) | failed-unknown | 无(终态 JSON 解码再次失败;cursor 本单元 2 次尝试) | 否 | /tmp/gitea-migration-run3-receipt.json |
|
||||
| gitea-migration-routing-promote-antigravity | AGENT-EXECUTION.md implementation 顺序临时调整 | — | implementation | cursor,… | 1 | cursor(auto) | completed | apply | 否 | /tmp/gitea-migration-routing-receipt.json |
|
||||
| gitea-migration-f4-refresh | policy/facts.md F4 行更新 | — | implementation | antigravity,pi-glm,… | 1 | agy | failed-unknown | 无(agy OAuth 网络故障启动即败,0 轮对话) | 否 | /tmp/gitea-f4-receipt.json |
|
||||
| gitea-migration-f4-refresh | 同上 | — | implementation | antigravity,pi-glm,… | 2 | agy | failed-unknown | 无(agy OAuth 仍不可达) | 否 | /tmp/gitea-f4-receipt2.json |
|
||||
| gitea-migration-f4-refresh | 同上 | — | implementation | antigravity,pi-glm,… | 3(agy 耗尽) | agy | failed-unknown | 无(agy OAuth 持续不可达,3 次尝试耗尽) | 否 | /tmp/gitea-f4-receipt3.json |
|
||||
| gitea-migration-routing2 | AGENT-EXECUTION.md 再调整(pi-glm 优先) | — | implementation | — | 1 | — | failed-unknown(agy 启动即败,未达目标) | 无 | 否 | /tmp/gitea-migration-routing2-receipt.json |
|
||||
| gitea-migration-routing-revert | 回退 antigravity 优先为原顺序 | — | host(baseline-match revert) | — | — | — | committed | aa1e8c2b | — | 本行披露;admit 经 baseline 精确内容核对 |
|
||||
| gitea-migration-f4-refresh | F4 行刷新 | — | implementation | cursor(原序恢复后重试) | 4 | cursor(auto) | blocked | 诚实阻塞:F4 验证依赖宿主级子模块物化,worker 隔离区无法通过;现场保留。F4 刷新转后续任务 | 否 | /tmp/gitea-f4-receipt4.json |
|
||||
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
|
||||
|
||||
## 同步记录
|
||||
|
||||
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|
||||
|---|---|---|---|
|
||||
| 启动 | 3d3474a731f9ef3ee1f41935e63bca3afb70db56 | 3d3474a731f9ef3ee1f41935e63bca3afb70db56 | 2026-10-22T11:37:21Z |
|
||||
|
||||
## 证据(Evidence)
|
||||
|
||||
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
|
||||
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|
||||
|---|---|---|---|---|---|
|
||||
|
||||
## 结果与验证(完成后填写)
|
||||
|
||||
- 结果:端点迁移完成。11 文件 + plugins/registry.json 修复;F1/F2/F3 新端点实测 PASS;目标单测与 make test-governance 全部 OK。
|
||||
- 验证:F1/F2/F3 PASS(新端点实测);目标单测(facts_verify/ci_credentials/task_triage/ci_wait/svc_precheck)全部 OK(SELF 收据已导入);F4 FAIL 已知漂移(见完成条件注记)。make test-governance 与 svc_realcombo 待 host 最终验证。
|
||||
- 影响与剩余项:
|
||||
|
||||
## 合入与清理
|
||||
|
||||
- Review 记录:r1 REVIEW FAIL(阻塞项:plugins/registry.json 旧 SSH 端点,pi-glm 全新会话)→ repair transport 修复 → r2 REVIEW PASS(pi-glm 全新会话;49 处新端点书写一致、负例语义保留、facts_verify/ci_credentials/task_triage/ci_wait 全部离线实测、无秘密入仓;报告 docs/superpowers/reviews/2026-10-22-gitea-endpoint-migration-review.md)。base=3d3474a7,head 见最终推送。
|
||||
- 冲突记录:待合入前 make task-sync(main 前进时重放受影响验证)
|
||||
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
|
||||
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
|
||||
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
|
||||
|
||||
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
|
||||
```json
|
||||
{
|
||||
"summary_schema": 1,
|
||||
"source": "SELF",
|
||||
"timestamp": "2026-10-22T11:36:22.453253+00:00",
|
||||
"command": "make precheck",
|
||||
"exit_code": 0,
|
||||
"cwd": "/home/weichen/projects/Agent-System-Dev",
|
||||
"before_head": "3d3474a731f9ef3ee1f41935e63bca3afb70db56",
|
||||
"after_head": "3d3474a731f9ef3ee1f41935e63bca3afb70db56",
|
||||
"branch": "main",
|
||||
"target_branch": "main",
|
||||
"target_head": "3d3474a731f9ef3ee1f41935e63bca3afb70db56",
|
||||
"root_target": "main",
|
||||
"immediate_target": "main",
|
||||
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"output_tail": [
|
||||
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
|
||||
"[repo] branch=main head=3d3474a731",
|
||||
"[remote] origin/main=3d3474a731 ahead=0 behind=0",
|
||||
"[tree] clean submodules_drift=0 uninit=0",
|
||||
"[worktrees] linked=7",
|
||||
"[initiatives] local cards (not authoritative): none",
|
||||
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
|
||||
"[facts] policy/facts.md 6 条事实均在有效期内",
|
||||
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
|
||||
"[R0] 3d3474a731(完整:3d3474a731f9ef3ee1f41935e63bca3afb70db56)",
|
||||
"[worktree] before-sync: recursive component checks passed",
|
||||
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
|
||||
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
|
||||
],
|
||||
"output_sha256": "8fe96dfd5cc52716edb7b4361609ea244aa109e4028777d1cdaf8637be6b8a08",
|
||||
"receipt_sha256": "3b4027f3dabd3bb334b3ac7767771099e439b8e67c3677c997a5c78c8c7ddfb2",
|
||||
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/3b4027f3dabd3bb334b3ac7767771099e439b8e67c3677c997a5c78c8c7ddfb2.json"
|
||||
}
|
||||
```
|
||||
|
||||
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
|
||||
```json
|
||||
{
|
||||
"summary_schema": 1,
|
||||
"source": "SELF",
|
||||
"timestamp": "2026-10-22T13:49:47.717844+00:00",
|
||||
"command": "PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tests.test_facts_verify tests.test_ci_credentials tests.test_task_triage tests.test_ci_wait tests.test_svc_precheck",
|
||||
"exit_code": 0,
|
||||
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-fix-gitea-endpoint-migration",
|
||||
"before_head": "6cb6a276ca3e10101cd76db1bd3d77834e54e551",
|
||||
"after_head": "6cb6a276ca3e10101cd76db1bd3d77834e54e551",
|
||||
"branch": "fix/gitea-endpoint-migration",
|
||||
"target_branch": "main",
|
||||
"target_head": "cb36b59accd0418c5ca952912d7c181b83038a4c",
|
||||
"root_target": "main",
|
||||
"immediate_target": "main",
|
||||
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"output_tail": [
|
||||
".............................................................................",
|
||||
"----------------------------------------------------------------------",
|
||||
"Ran 77 tests in 30.719s",
|
||||
"",
|
||||
"OK"
|
||||
],
|
||||
"output_sha256": "8e55dbb47a553d2c5a34ce16057ed2d742b908e45f6ab4f8119212911a554e74",
|
||||
"receipt_sha256": "2c2e2c19d6f0cc3734c9c6ae986bc3e3021a91caa320373d66158cab4f1ec124",
|
||||
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/2c2e2c19d6f0cc3734c9c6ae986bc3e3021a91caa320373d66158cab4f1ec124.json"
|
||||
}
|
||||
```
|
||||
|
||||
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
|
||||
```json
|
||||
{
|
||||
"summary_schema": 1,
|
||||
"source": "SELF",
|
||||
"timestamp": "2026-10-22T13:50:40.361266+00:00",
|
||||
"command": "make test-governance",
|
||||
"exit_code": 0,
|
||||
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-fix-gitea-endpoint-migration",
|
||||
"before_head": "6cb6a276ca3e10101cd76db1bd3d77834e54e551",
|
||||
"after_head": "6cb6a276ca3e10101cd76db1bd3d77834e54e551",
|
||||
"branch": "fix/gitea-endpoint-migration",
|
||||
"target_branch": "main",
|
||||
"target_head": "cb36b59accd0418c5ca952912d7c181b83038a4c",
|
||||
"root_target": "main",
|
||||
"immediate_target": "main",
|
||||
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"output_tail": [
|
||||
"test_feature_missing_parent_is_allowed (test_write_guard.WriteGuardTests.test_feature_missing_parent_is_allowed) ... ok",
|
||||
"test_invalid_json_is_denied (test_write_guard.WriteGuardTests.test_invalid_json_is_denied) ... ok",
|
||||
"test_missing_parent_on_main_is_denied (test_write_guard.WriteGuardTests.test_missing_parent_on_main_is_denied) ... ok",
|
||||
"test_missing_unknown_and_malformed_write_input_are_denied (test_write_guard.WriteGuardTests.test_missing_unknown_and_malformed_write_input_are_denied) ... ok",
|
||||
"test_non_git_destination_is_explicitly_outside_scope (test_write_guard.WriteGuardTests.test_non_git_destination_is_explicitly_outside_scope) ... ok",
|
||||
"test_nonwrite_tools_are_outside_scope (test_write_guard.WriteGuardTests.test_nonwrite_tools_are_outside_scope) ... ok",
|
||||
"test_relative_path_uses_hook_cwd_not_process_cwd (test_write_guard.WriteGuardTests.test_relative_path_uses_hook_cwd_not_process_cwd) ... ok",
|
||||
"test_symlink_into_main_with_missing_parents_is_denied (test_write_guard.WriteGuardTests.test_symlink_into_main_with_missing_parents_is_denied) ... ok",
|
||||
"test_valid_multi_file_patch_on_feature_is_allowed (test_write_guard.WriteGuardTests.test_valid_multi_file_patch_on_feature_is_allowed) ... ok",
|
||||
"",
|
||||
"----------------------------------------------------------------------",
|
||||
"Ran 553 tests in 368.627s",
|
||||
"",
|
||||
"OK (skipped=18)",
|
||||
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-fix-gitea-endpoint-migration'"
|
||||
],
|
||||
"output_sha256": "e283e1b732170416dfd71d6ccb9118f756ac64d123a8c50b939592185c0096de",
|
||||
"receipt_sha256": "aa4fdc711f5d0839248ecefdc5e1242c6cb2d04ca3efde90099300e456f78f71",
|
||||
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/aa4fdc711f5d0839248ecefdc5e1242c6cb2d04ca3efde90099300e456f78f71.json"
|
||||
}
|
||||
```
|
||||
| 同步(记录前对象) | cb36b59accd0418c5ca952912d7c181b83038a4c | 1383cf1d2bc0dbaaecebed7d20c26d6ec8d2d783 | 2026-10-22T14:08:07Z |
|
||||
@@ -0,0 +1,92 @@
|
||||
# fix/svc-test-port-governance-batch1 任务卡
|
||||
|
||||
任务主记录:<PR 链接,交付前填写>;状态:进行中;owner:weichen
|
||||
|
||||
- 权威仓:ssh://git@192.168.3.2:2222/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 3d3474a731f9ef3ee1f41935e63bca3afb70db56
|
||||
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-fix-svc-test-port-governance-batch1(worktree);分支:fix/svc-test-port-governance-batch1
|
||||
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
|
||||
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=1723e9e3e6bd50bedc041afba3533c35e8b663edb12472f29c067df860df799b;triage_receipt=/tmp/pa1-triage.json;receipt_sha256=71d236166f2a1de8cecd6eb93042ef5199a09e2c49318dbf8eb9d5b5582a99e5
|
||||
|
||||
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
|
||||
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
|
||||
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
|
||||
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
|
||||
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
|
||||
|
||||
## 目标与非目标
|
||||
|
||||
<预期结果、受影响入口/模块/契约;明确不做什么。>
|
||||
|
||||
## Agent 实施收据
|
||||
|
||||
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
|
||||
|
||||
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|
||||
|---|---|---|---|---|---|---|---|---|---|---|
|
||||
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
|
||||
|
||||
## 同步记录
|
||||
|
||||
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|
||||
|---|---|---|---|
|
||||
| 启动 | 3d3474a731f9ef3ee1f41935e63bca3afb70db56 | 3d3474a731f9ef3ee1f41935e63bca3afb70db56 | 2026-10-22T11:15:53Z |
|
||||
|
||||
## 证据(Evidence)
|
||||
|
||||
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
|
||||
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|
||||
|---|---|---|---|---|---|
|
||||
|
||||
## 结果与验证(完成后填写)
|
||||
|
||||
- 结果:
|
||||
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
|
||||
- 影响与剩余项:
|
||||
|
||||
## 合入与清理
|
||||
|
||||
- Review 记录:NOT_RUN(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
|
||||
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
|
||||
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
|
||||
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
|
||||
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
|
||||
|
||||
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
|
||||
```json
|
||||
{
|
||||
"summary_schema": 1,
|
||||
"source": "SELF",
|
||||
"timestamp": "2026-10-22T11:15:04.613824+00:00",
|
||||
"command": "make precheck",
|
||||
"exit_code": 0,
|
||||
"cwd": "/home/weichen/projects/Agent-System-Dev",
|
||||
"before_head": "3d3474a731f9ef3ee1f41935e63bca3afb70db56",
|
||||
"after_head": "3d3474a731f9ef3ee1f41935e63bca3afb70db56",
|
||||
"branch": "main",
|
||||
"target_branch": "main",
|
||||
"target_head": "3d3474a731f9ef3ee1f41935e63bca3afb70db56",
|
||||
"root_target": "main",
|
||||
"immediate_target": "main",
|
||||
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"output_tail": [
|
||||
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
|
||||
"[repo] branch=main head=3d3474a731",
|
||||
"[remote] origin/main=3d3474a731 ahead=0 behind=0",
|
||||
"[tree] clean submodules_drift=0 uninit=0",
|
||||
"[worktrees] linked=6",
|
||||
"[initiatives] local cards (not authoritative): none",
|
||||
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
|
||||
"[facts] policy/facts.md 6 条事实均在有效期内",
|
||||
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
|
||||
"[R0] 3d3474a731(完整:3d3474a731f9ef3ee1f41935e63bca3afb70db56)",
|
||||
"[worktree] before-sync: recursive component checks passed",
|
||||
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
|
||||
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
|
||||
],
|
||||
"output_sha256": "87e58b98732700984715adb3f7a46aeacdc3749aacf51643f68a2ad9ede2451d",
|
||||
"receipt_sha256": "72f14e2080b227c1fc4094a0a4f573b0dc12fb08ed30c86400265a610fb09b0d",
|
||||
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/72f14e2080b227c1fc4094a0a4f573b0dc12fb08ed30c86400265a610fb09b0d.json"
|
||||
}
|
||||
```
|
||||
| 同步(记录前对象) | c92443280ef8e9ed29bf5bf5250df650c01b4478 | c22b9fb34a3702191a9e5f6007f3538520db694b | 2026-10-22T13:10:38Z |
|
||||
@@ -0,0 +1,96 @@
|
||||
# 独立 Review:fix/gitea-endpoint-migration(第 2 轮)
|
||||
|
||||
- 日期:2026-10-22;Review 会话:全新独立会话(本会话未参与实施)
|
||||
- 对象:分支 `fix/gitea-endpoint-migration` HEAD `6cb6a276`,base `3d3474a731f9ef3ee1f41935e63bca3afb70db56`
|
||||
- 实施 diff:`/tmp/gitea-mig-review2.diff`(已核对与 `git diff 3d3474a7..HEAD` 逐字节一致,唯一差异为本报告新文件与任务卡 `.task/fix-gitea-endpoint-migration.md`,均不在功能范围)
|
||||
- 上轮(r1)唯一阻塞项:`plugins/registry.json` rdm 条目仍是旧 SSH 端点;本轮经 repair transport 修复,r1→r2 diff 增量恰为该文件一处 URL 替换,已核对。
|
||||
|
||||
## 总体判定
|
||||
|
||||
**REVIEW PASS(无阻塞项)。**
|
||||
|
||||
五项核对点全部通过:旧端点功能性引用已清零(历史记录与刻意保留的 F4 负例除外);新端点两形态(web 无端口 / SSH 端口 52222)全仓 49 处书写一致;测试负例语义完整保留并实测通过;`policy/facts.md` 变更严格限于 F1—F3 行与 last_verified;diff 无秘密入仓。
|
||||
|
||||
## 分级清单
|
||||
|
||||
### 阻塞项
|
||||
|
||||
无。
|
||||
|
||||
### 非阻塞建议(不阻塞合入,仅记录)
|
||||
|
||||
1. **历史文档中的旧 URL 仅为记录,防止误复用**:`docs/superpowers/plans/2026-10-16-development-governance-v2-master.md`(文末双钥匙命令段含 `API=https://git-home.u1680832.nyat.app:30319/api/v1`)、`docs/superpowers/plans/2026-10-17-guidelines-governance-adoption.md`、`docs/superpowers/specs/2026-10-20-fast-slow-o2-i{1,2}-review.md` 内含旧 git-home 链接。均为已 CLOSED/MERGED 的历史记录(PR/CI 当时事实),属本单元豁免类;且 AGENTS.md 已规定端点事实只以 `policy/facts.md` 为准。建议后续如有人重放这些命令段,以 facts.md 现行端点替换,勿照抄。
|
||||
2. **F4 存在已知漂移**:F4(旧 git-panel 端点 TLS 握手失败)last_verified 仍为 2026-10-14,任务卡已注记「F4 FAIL 已知漂移」。F4 刻意不动符合单元范围;漂移刷新属 facts 维护单元职责,与本迁移无耦合。
|
||||
3. **`.task/` 归档与 artifacts 内大量旧端点 URL**:均为任务历史回执/归档(豁免类),无需处理;列出仅为完整性确认。
|
||||
|
||||
## 核对点结果
|
||||
|
||||
### 1) 完整性——旧端点功能性引用清零 ✅
|
||||
|
||||
全仓扫描(排除 `.git/`、`.task/`)`git-ssh.u1680832` / `git-home.u1680832` 零残留;`git-panel.u1680832` 与裸 `u1680832` 仅剩以下刻意保留项:
|
||||
|
||||
| 位置 | 性质 | 判定 |
|
||||
|---|---|---|
|
||||
| `policy/facts.md:11` | 退役端点政策禁令(「一律不得使用」) | 刻意保留,正确 |
|
||||
| `policy/facts.md:21`(F4) | 旧端点 TLS 观察事实及探针命令 | 单元规定 F4 不动,正确 |
|
||||
| `tests/test_facts_verify.py:372,377` | F4 探针负例(针对退役端点) | 与 F4 配套,正确 |
|
||||
| `tests/test_ci_credentials.py:167` | 负例:无 scheme 的 metadata_url 必须被拒(实测 refused,0 请求) | 负例语义,正确 |
|
||||
| `tests/test_task_triage.py:394`、`tests/test_ci_wait.py:118` | 合成 fixture(`git.example`/`.invalid`) | 非 real 端点,正确 |
|
||||
| `docs/superpowers/{plans,specs}/*.md`(4 文件) | 历史 CLOSED/MERGED 记录 | 豁免类,见非阻塞 1 |
|
||||
|
||||
此前未覆盖的文件类型已补查:全仓 JSON/TOML/YAML/ini(`policy/architecture.yaml`、`policy/architecture-baseline.json`、`plugins/**.json`、`examples/**.json`、`.zcode/config.json`、`docs/structure/cockpit-e2e.yaml`、`docker/`、`.templates/`、`Makefile`、`AGENT-EXECUTION.md`、`PROJECT.md`、`AGENTS.md`)均无旧端点引用;唯一含端点的 JSON 为 `plugins/registry.json`,已迁移。
|
||||
|
||||
### 2) 正确性——新端点格式一致 ✅
|
||||
|
||||
全仓 49 处 `gitea.naitangbaobao.cn` 全部落在两形态(`sort|uniq` 核对):
|
||||
|
||||
- Web:`https://gitea.naitangbaobao.cn`(无端口),派生 `/api/v1`(task_triage DEFAULT_API、task.sh 两处 `${web_base}/api/v1`)、`/api/v1/user`(facts-verify ENDPOINT 及表头注释)、`/api/v1/version`(F1)、`/weichen/Agent-System-Dev/issues/518`(delivery 队列链接)。
|
||||
- SSH:`ssh://git@gitea.naitangbaobao.cn:52222/weichen/<Repo>.git`——`.gitmodules` 全部 14 条 URL、`plugins/registry.json`(rdm,上轮阻塞项)、`scripts/svc.sh` RDM_ORIGIN_DEFAULT、`ci.yaml` 4 处 allowlist 前缀 + 2 处 insteadOf 改写前缀、`tests/test_ci_credentials.py`/`test_svc_realcombo.py` 期望值、facts.md F3。
|
||||
|
||||
无混写(无新域名带旧端口、无旧域名、无 web 误带 52222、无 SSH 缺 52222)。`ci.yaml` 的 `SERVER` 仍强制平台注入 http(s) URL,`GIT_CONFIG_VALUE_2` 以新 SSH 前缀做 insteadOf → `$SERVER/weichen/`,链路自洽。
|
||||
|
||||
### 3) 测试负例语义保留 ✅
|
||||
|
||||
`tests/test_facts_verify.py` `test_f2_rejects_unregistered_destination_before_reading_credentials` 的 bad_urls 逐项映射:http 明文、`evil.invalid`、错端口 `:30320`、显式默认端口 `:443`(替代旧「无端口」负例——`facts-verify.sh` 对 ENDPOINT 做整串比较,`:443` 同样被拒,语义等价)、URL 内凭据、`@evil.invalid` 重定向、`#frag`、`?next=`、`/users`、`/user/../admin`、尾随空格——全部保留,且仍断言「未登记目的地不发请求、不读凭据」。重定向(301/302/303/307/308)不跟随、不转发 Authorization 的断言保留。本地实测(stub 断网,离线):
|
||||
|
||||
- `tests.test_facts_verify` 8/8 OK
|
||||
- `tests.test_ci_credentials` 9/9 OK(含 `git-panel` 无 scheme 负例仍 refused)
|
||||
- `tests.test_task_triage` 29/29 OK
|
||||
- `tests.test_ci_wait` 11/11 OK
|
||||
- `tests.test_svc_realcombo` 16 skipped(设计上需 `SVC_TEST_REAL=1`,离线 NOT_RUN,符合文件头条件)
|
||||
- `bash -n` task.sh / facts-verify.sh / svc.sh 通过;`task_triage.py` 编译通过;`registry.json` JSON 合法
|
||||
|
||||
### 4) policy/facts.md 变更范围 ✅
|
||||
|
||||
`git diff base..HEAD -- policy/facts.md` 仅 3 行:F1、F2、F3 行(端点 URL + last_verified 2026-10-14→2026-10-22)。F4/F5/F6 行逐字未动,表前政策禁令段未动。F2 验证命令仍不含 curl/Authorization/.secrets(`test_registry_separates_retired_endpoint_policy_from_tls_observation` 实测通过,该测试直接解析现行 facts.md)。
|
||||
|
||||
### 5) 无秘密入仓 ✅
|
||||
|
||||
对 HEAD 全量 diff 的 `+` 行做秘密模式扫描(长随机串、`ghp_`/`AKIA`/`xox`、PEM 头、password/secret 赋值等):命中行全部为 git URL、SHA256、任务卡元数据与本地路径,无凭据值。测试 token 均为 `synthetic-*-not-a-real-secret`;`facts-verify.sh` 仍在运行时进程内读取 `~/.secrets/gitea`,仓内仅存路径指针。
|
||||
|
||||
## 复现命令
|
||||
|
||||
```bash
|
||||
# diff 范围一致性(本报告对象与实际 HEAD diff 一致,除 .task 卡与本报告)
|
||||
git diff 3d3474a731f9ef3ee1f41935e63bca3afb70db56..HEAD -- . ':(exclude).task' > /tmp/actual-head-diff.diff
|
||||
diff /tmp/gitea-mig-review2.diff /tmp/actual-head-diff.diff && echo MATCH
|
||||
|
||||
# 旧端点残留(应仅剩 facts.md 禁令/F4 与测试负例/fixture/历史文档)
|
||||
grep -rn "u1680832" . | grep -v "^\./\.git/" | grep -v "^\./\.task/" | grep -v "docs/superpowers/"
|
||||
|
||||
# 新端点一致性(应只出现两形态)
|
||||
grep -rhn "gitea\.naitangbaobao\.cn" . | grep -v "^\./\.task/" \
|
||||
| grep -oE "[a-z]+://[^)\`'\" ,;;]*" | sort | uniq -c | sort -rn
|
||||
|
||||
# facts.md 变更范围(应仅 F1—F3 三行)
|
||||
git diff 3d3474a731f9ef3ee1f41935e63bca3afb70db56..HEAD -- policy/facts.md
|
||||
|
||||
# 负例与单测(离线,stub 断网)
|
||||
python3 -m unittest tests.test_facts_verify tests.test_ci_credentials \
|
||||
tests.test_task_triage tests.test_ci_wait tests.test_svc_realcombo
|
||||
```
|
||||
|
||||
## 证据与边界
|
||||
|
||||
- 本报告所列测试输出为本地离线实测(SELF 级);端点可达性(F1—F3 的 curl/ls-remote)属网络验证,本单元 `network=false`,**NOT_RUN**,以实施侧任务卡记录的 F1/F2/F3 PASS(新端点实测)为准,合入前由必需 CI 复核。
|
||||
- 审阅者为全新独立会话,未参与实施;Review 仅产出本报告,未实施任何修复。
|
||||
@@ -3,7 +3,7 @@
|
||||
{
|
||||
"id": "rdm",
|
||||
"name": "研发记忆 RDM",
|
||||
"repo": "ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-RDM.git",
|
||||
"repo": "ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-System-RDM.git",
|
||||
"repoEnv": "SVC_RDM_ORIGIN",
|
||||
"defaultRef": "origin/main",
|
||||
"goModule": "agent-system-rdm",
|
||||
|
||||
+1
-1
@@ -381,7 +381,7 @@ Review 只将阻塞项列为必修;非阻塞意见标明后续建议,不得
|
||||
解决冲突和重跑最终 CI。本节只安排 Dev `refs/heads/main` 的最终交付顺序;需求、授权、阶段状态和
|
||||
证据仍在原任务卡,受保护分支的最终准入仍由 Gitea 执行。
|
||||
|
||||
- **队列**:Dev main 只用一份[合入队列 #518](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/issues/518),
|
||||
- **队列**:Dev main 只用一份[合入队列 #518](https://gitea.naitangbaobao.cn/weichen/Agent-System-Dev/issues/518),
|
||||
只记录顺序和当前窗口:任务/PR、owner、依赖、就绪状态、当前 base/head、CI、合入结果。
|
||||
- **职责**:协调智能体维护顺序和窗口;任务 owner 负责分支内容和必要整改;窗口内的同步、冲突处置、
|
||||
Review、当前 HEAD CI 核验和所有 PR 合入由智能体执行。
|
||||
|
||||
+3
-3
@@ -15,9 +15,9 @@
|
||||
|
||||
| ID | 事实 | 验证命令 | last_verified | TTL(天) |
|
||||
|---|---|---|---|---|
|
||||
| F1 | Gitea Web/API 可达(2026-10-22 迁移后新权威):https://gitea.naitangbaobao.cn(443,1.27.3);旧地址 git-home…:30319 过渡期仍可达,随时退役 | `curl -fsS -m 10 https://gitea.naitangbaobao.cn/api/v1/version` | 2026-10-22 | 30 |
|
||||
| F2 | API token 存在且可用(值在 ~/.secrets/gitea,HOME/IMC 两段各一组 `- ACCESS_TOKEN=…`,本条取 HOME 段;不入仓不回显,不进子进程 argv);在新权威 URL 实测 200 | `bash scripts/facts-verify.sh api-token https://gitea.naitangbaobao.cn/api/v1/user` | 2026-10-22 | 30 |
|
||||
| F3 | Git over SSH 可达(新地址,端口 52222):ssh://git@gitea.naitangbaobao.cn:52222/weichen/<Repo>.git(key ~/.ssh/home_gitea);旧地址 git-ssh…:31411 迁移期 push 间歇失败,不再作为权威 | `GIT_SSH_COMMAND="ssh -i ~/.ssh/home_gitea -p 52222 -o BatchMode=yes" git ls-remote ssh://git@gitea.naitangbaobao.cn:52222/weichen/Development-Guidelines.git HEAD` | 2026-10-22 | 30 |
|
||||
| F1 | Gitea Web/API 可达:https://gitea.naitangbaobao.cn(1.27.3) | `curl -fsS -m 10 https://gitea.naitangbaobao.cn/api/v1/version` | 2026-10-22 | 30 |
|
||||
| F2 | API token 存在且可用(值在 ~/.secrets/gitea,HOME/IMC 两段各一组 `- ACCESS_TOKEN=…`,本条取 HOME 段;不入仓不回显,不进子进程 argv) | `bash scripts/facts-verify.sh api-token https://gitea.naitangbaobao.cn/api/v1/user` | 2026-10-22 | 30 |
|
||||
| F3 | Git over SSH 可达:ssh://git@gitea.naitangbaobao.cn:52222/weichen/<Repo>.git(key ~/.ssh/home_gitea) | `GIT_SSH_COMMAND="ssh -i ~/.ssh/home_gitea -o BatchMode=yes" git ls-remote ssh://git@gitea.naitangbaobao.cn:52222/weichen/Development-Guidelines.git HEAD` | 2026-10-22 | 30 |
|
||||
| F4 | 旧端点 git-panel.u1680832.nyat.app:30319 TCP 可连通但 TLS 握手失败(仅 TLS 层握手错误判 PASS) | `bash scripts/facts-verify.sh tls-handshake-fails git-panel.u1680832.nyat.app 30319` | 2026-10-14 | 180 |
|
||||
| F5 | 基座 users 表存有姓名(name 列,CreateAccount/ListUsersAdmin 读写;EXT-19 目录自 P3 起向授权管理读面下发) | `cd modules/backend && go test ./internal/app/ -run TestInprocHostSearchAccounts -count=1` | 2026-10-14 | 180 |
|
||||
| F6 | 基座账号无停用位(users 表无 disabled;EXT-19 Valid 恒为存在性)——停用机制未实现,不得当已具备 | `cd modules/backend && ! grep -rn -e disabled -e Disabled internal/store/auth.go pkg/extension/extension.go` | 2026-10-14 | 180 |
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# 用法:make facts-verify [ARGS=--update] (--update:把 PASS 项 last_verified 刷为当天并写回)
|
||||
# 表内验证命令约定不含竖线;含 "\|" 转义时按字面还原后执行。
|
||||
# 登记表引用的探针子命令(单独运行时在 stderr 说明判定,不输出凭据):
|
||||
# api-token URL URL 须逐字等于登记端点 https://git-home.u1680832.nyat.app:30319/api/v1/user,
|
||||
# api-token URL URL 须逐字等于登记端点 https://gitea.naitangbaobao.cn/api/v1/user,
|
||||
# 校验通过后才进程内读 ~/.secrets/gitea HOME 段 ACCESS_TOKEN 并 GET(不跟随重定向);
|
||||
# 0=接受 3=缺失 4=格式不符 5=请求失败/被拒/重定向 6=非登记端点
|
||||
# tls-handshake-fails HOST PORT 仅当 TCP 已连通且 TLS 层握手报错时 0;
|
||||
@@ -20,7 +20,7 @@ import sys, urllib.request
|
||||
sys.path.insert(0, sys.argv[1])
|
||||
import task_triage
|
||||
|
||||
ENDPOINT = "https://git-home.u1680832.nyat.app:30319/api/v1/user"
|
||||
ENDPOINT = "https://gitea.naitangbaobao.cn/api/v1/user"
|
||||
if sys.argv[2] != ENDPOINT:
|
||||
print("api-token: URL 不是 policy/facts.md F2 登记端点,拒绝发送凭据", file=sys.stderr)
|
||||
sys.exit(6)
|
||||
|
||||
+1
-1
@@ -144,7 +144,7 @@ SRC_DIR="${SVC_SRC_DIR:-${XDG_CACHE_HOME:-$HOME/.cache}/agent-system-svc/src}"
|
||||
# 独立 RDM 源仓(下游组合仓 Agent-System-RDM 的干净克隆;SVC_RDM_SRC_DIR 覆盖路径,
|
||||
# SVC_RDM_ORIGIN 覆盖克隆来源)。rdm 源的解析/列举/物化全部基于它,语义与 SRC_DIR 一致。
|
||||
RDM_SRC_DIR="${SVC_RDM_SRC_DIR:-${XDG_CACHE_HOME:-$HOME/.cache}/agent-system-svc/rdm-src}"
|
||||
RDM_ORIGIN_DEFAULT="ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-RDM.git"
|
||||
RDM_ORIGIN_DEFAULT="ssh://git@gitea.naitangbaobao.cn:52222/weichen/Agent-System-RDM.git"
|
||||
|
||||
# 提示信息走 stderr:stdout 只留给数据(提交表/服务表/DSN),便于 $( ) 捕获组合。
|
||||
c_info() { [ "${CLI_QUIET:-0}" = 1 ] && return 0; printf '\033[1;34m[svc]\033[0m %s\n' "$*" >&2; }
|
||||
|
||||
+3
-3
@@ -813,7 +813,7 @@ card_merge_squash() { # $1=branch $2=ref → squash/rebase 落地没有 merge
|
||||
# 仅查最近 5 页(250 条):card_merge 的 merge 提交路径仍是主路径,此兜底面向新近任务卡。
|
||||
local token="${GITEA_TOKEN:-}" web_base url repo owner api payload pg found sha
|
||||
[ -n "$token" ] || return 1
|
||||
web_base="${TASK_CARD_WEB_BASE:-https://git-home.u1680832.nyat.app:30319}"
|
||||
web_base="${TASK_CARD_WEB_BASE:-https://gitea.naitangbaobao.cn}"
|
||||
url=$(git remote get-url origin 2>/dev/null) || return 1
|
||||
url="${url%.git}"
|
||||
repo=$(basename "$url"); owner=$(basename "$(dirname "$url")")
|
||||
@@ -951,7 +951,7 @@ cmd_close_self() {
|
||||
esac
|
||||
pr="$nums"
|
||||
fi
|
||||
web_base="${TASK_CARD_WEB_BASE:-https://git-home.u1680832.nyat.app:30319}"
|
||||
web_base="${TASK_CARD_WEB_BASE:-https://gitea.naitangbaobao.cn}"
|
||||
url=$(git remote get-url origin); url="${url%.git}"
|
||||
repo=$(basename "$url"); owner=$(basename "$(dirname "$url")")
|
||||
link="${web_base}/${owner}/${repo}/pulls/${pr}"
|
||||
@@ -981,7 +981,7 @@ cmd_close() {
|
||||
fetch_target
|
||||
# 默认值取远端通告的 Web 面(git push 输出的 PR 建议链接);可用 TASK_CARD_WEB_BASE 覆盖。
|
||||
# git-panel 前缀已失效(TLS 握手失败),默认值改为实测可用的 git-home(AGENTS.md 访问事实节)。
|
||||
local web_base="${TASK_CARD_WEB_BASE:-https://git-home.u1680832.nyat.app:30319}"
|
||||
local web_base="${TASK_CARD_WEB_BASE:-https://gitea.naitangbaobao.cn}"
|
||||
local url owner repo
|
||||
url=$(git remote get-url origin); url="${url%.git}"
|
||||
repo=$(basename "$url"); owner=$(basename "$(dirname "$url")")
|
||||
|
||||
@@ -29,7 +29,7 @@ import urllib.parse
|
||||
import urllib.request
|
||||
|
||||
SCHEMA = "agent-system/task-triage/v1"
|
||||
DEFAULT_API = "https://git-home.u1680832.nyat.app:30319/api/v1"
|
||||
DEFAULT_API = "https://gitea.naitangbaobao.cn/api/v1"
|
||||
DEFAULT_TARGET = "main"
|
||||
DEFAULT_MAX_AGE = 14400
|
||||
PAGE_LIMIT = 50
|
||||
|
||||
@@ -11,8 +11,8 @@ from urllib.parse import urlsplit
|
||||
|
||||
|
||||
WORKFLOW = Path(__file__).resolve().parents[1] / ".gitea/workflows/ci.yaml"
|
||||
SERVER = "https://git-home.u1680832.nyat.app:30319"
|
||||
SSH = "ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/"
|
||||
SERVER = "https://gitea.naitangbaobao.cn"
|
||||
SSH = "ssh://git@gitea.naitangbaobao.cn:52222/weichen/"
|
||||
ROOT_TOKEN = "synthetic-root-token-not-a-real-secret"
|
||||
SUB_TOKEN = "synthetic-component-token-not-a-real-secret"
|
||||
|
||||
|
||||
+15
-15
@@ -256,7 +256,7 @@ class FactsVerifyTests(unittest.TestCase):
|
||||
self.assert_status(result.stdout, "F2", "PASS")
|
||||
requests = self.stub_events("http")
|
||||
self.assertEqual(len(requests), 1, requests)
|
||||
self.assertEqual(requests[0]["url"], "https://git-home.u1680832.nyat.app:30319/api/v1/user")
|
||||
self.assertEqual(requests[0]["url"], "https://gitea.naitangbaobao.cn/api/v1/user")
|
||||
self.assertEqual(requests[0]["authorization"], "token " + HOME_TOKEN)
|
||||
self.assertEqual(self.dates(), {"F2": self.today, "F8": self.today, "F9": OLD_DATE})
|
||||
self.assertTrue(receipt.exists(), result.stderr)
|
||||
@@ -285,7 +285,7 @@ class FactsVerifyTests(unittest.TestCase):
|
||||
self.assert_status(result.stdout, "F2", "FAIL")
|
||||
self.assertEqual(self.stub_events("http"), [], "no request without a valid HOME token")
|
||||
self.assertEqual(self.dates()["F2"], OLD_DATE)
|
||||
direct = self.run_script("api-token", "https://git-home.u1680832.nyat.app:30319/api/v1/user")
|
||||
direct = self.run_script("api-token", "https://gitea.naitangbaobao.cn/api/v1/user")
|
||||
self.assertNotEqual(direct.returncode, 0)
|
||||
self.assertIn("ACCESS_TOKEN", direct.stderr)
|
||||
self.assert_no_secrets(result.stdout, result.stderr, direct.stdout, direct.stderr,
|
||||
@@ -299,7 +299,7 @@ class FactsVerifyTests(unittest.TestCase):
|
||||
result = self.run_script("--update", http=http)
|
||||
self.assert_status(result.stdout, "F2", "FAIL")
|
||||
self.assertEqual(self.dates(), {"F2": OLD_DATE, "F8": self.today, "F9": OLD_DATE})
|
||||
direct = self.run_script("api-token", "https://git-home.u1680832.nyat.app:30319/api/v1/user",
|
||||
direct = self.run_script("api-token", "https://gitea.naitangbaobao.cn/api/v1/user",
|
||||
http=http)
|
||||
self.assertNotEqual(direct.returncode, 0)
|
||||
self.assertNotIn("Authorization", direct.stderr)
|
||||
@@ -307,17 +307,17 @@ class FactsVerifyTests(unittest.TestCase):
|
||||
|
||||
def test_f2_rejects_unregistered_destination_before_reading_credentials(self):
|
||||
bad_urls = [
|
||||
"http://git-home.u1680832.nyat.app:30319/api/v1/user",
|
||||
"http://gitea.naitangbaobao.cn/api/v1/user",
|
||||
"https://evil.invalid/api/v1/user",
|
||||
"https://git-home.u1680832.nyat.app:30320/api/v1/user",
|
||||
"https://git-home.u1680832.nyat.app/api/v1/user",
|
||||
"https://user:pw@git-home.u1680832.nyat.app:30319/api/v1/user",
|
||||
"https://git-home.u1680832.nyat.app:30319@evil.invalid/api/v1/user",
|
||||
"https://git-home.u1680832.nyat.app:30319/api/v1/user#frag",
|
||||
"https://git-home.u1680832.nyat.app:30319/api/v1/user?next=https://evil.invalid",
|
||||
"https://git-home.u1680832.nyat.app:30319/api/v1/users",
|
||||
"https://git-home.u1680832.nyat.app:30319/api/v1/user/../admin",
|
||||
"https://git-home.u1680832.nyat.app:30319/api/v1/user ",
|
||||
"https://gitea.naitangbaobao.cn:30320/api/v1/user",
|
||||
"https://gitea.naitangbaobao.cn:443/api/v1/user",
|
||||
"https://user:pw@gitea.naitangbaobao.cn/api/v1/user",
|
||||
"https://gitea.naitangbaobao.cn@evil.invalid/api/v1/user",
|
||||
"https://gitea.naitangbaobao.cn/api/v1/user#frag",
|
||||
"https://gitea.naitangbaobao.cn/api/v1/user?next=https://evil.invalid",
|
||||
"https://gitea.naitangbaobao.cn/api/v1/users",
|
||||
"https://gitea.naitangbaobao.cn/api/v1/user/../admin",
|
||||
"https://gitea.naitangbaobao.cn/api/v1/user ",
|
||||
]
|
||||
for secrets_present in (True, False):
|
||||
if not secrets_present:
|
||||
@@ -337,12 +337,12 @@ class FactsVerifyTests(unittest.TestCase):
|
||||
for code in ("301", "302", "303", "307", "308"):
|
||||
with self.subTest(code):
|
||||
self.stub_log.unlink(missing_ok=True)
|
||||
direct = self.run_script("api-token", "https://git-home.u1680832.nyat.app:30319/api/v1/user",
|
||||
direct = self.run_script("api-token", "https://gitea.naitangbaobao.cn/api/v1/user",
|
||||
http=code)
|
||||
self.assertEqual(direct.returncode, 5, direct.stderr)
|
||||
requests = self.stub_events("http")
|
||||
self.assertEqual([r["url"] for r in requests],
|
||||
["https://git-home.u1680832.nyat.app:30319/api/v1/user"], "no follow-up request")
|
||||
["https://gitea.naitangbaobao.cn/api/v1/user"], "no follow-up request")
|
||||
self.assertNotIn("redirect-target", direct.stdout + direct.stderr)
|
||||
self.assert_no_secrets(direct.stdout, direct.stderr)
|
||||
|
||||
|
||||
+36
-16
@@ -12,10 +12,14 @@ import os
|
||||
import shutil
|
||||
import sqlite3
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from _port_alloc import free_test_port # noqa: E402
|
||||
|
||||
SOURCE = Path(__file__).resolve().parents[1]
|
||||
SVC_SCRIPT = SOURCE / "scripts" / "svc.sh"
|
||||
|
||||
@@ -56,7 +60,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
|
||||
# ---- T1 连续裸启停:同一身份与数据根 ----
|
||||
|
||||
def test_T1_bare_restart_stable_identity(self):
|
||||
self.seed_agent("id1", 9431)
|
||||
port = free_test_port()
|
||||
self.seed_agent("id1", port)
|
||||
self.start_ok("id1")
|
||||
m1 = self.manifest("id1")
|
||||
self.assertIsNotNone(m1, "start 应完成 manifest 迁移")
|
||||
@@ -79,7 +84,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
|
||||
# ---- T2 只改端口:数据/DB 锚点不动 ----
|
||||
|
||||
def test_T2_port_change_keeps_anchors(self):
|
||||
self.seed_agent("id2", 9432)
|
||||
port = free_test_port()
|
||||
self.seed_agent("id2", port)
|
||||
self.start_ok("id2")
|
||||
anchor = self.manifest("id2")["identity"]
|
||||
self.svc("id2", "stop")
|
||||
@@ -95,7 +101,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
|
||||
# ---- T3 数据根漂移:拒绝启动,不新建空系统 ----
|
||||
|
||||
def test_T3_data_drift_rejected(self):
|
||||
self.seed_agent("id3", 9434)
|
||||
port = free_test_port()
|
||||
self.seed_agent("id3", port)
|
||||
self.start_ok("id3")
|
||||
self.svc("id3", "stop")
|
||||
other = self.root / "other-data"
|
||||
@@ -111,7 +118,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
|
||||
# ---- T4 迁移窗口与损坏:不猜测 ----
|
||||
|
||||
def test_T4a_leftover_new_file_ignored(self):
|
||||
self.seed_agent("id4", 9435)
|
||||
port = free_test_port()
|
||||
self.seed_agent("id4", port)
|
||||
# 模拟 rename 前崩溃残留:.new 半成品必须被忽略/覆盖,不影响迁移结果
|
||||
(self.runtime("id4") / "manifest.json.new").write_text("{ truncated")
|
||||
self.start_ok("id4")
|
||||
@@ -121,7 +129,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
|
||||
self.svc("id4", "stop")
|
||||
|
||||
def test_T4b_corrupt_manifest_blocks(self):
|
||||
self.seed_agent("id5", 9436)
|
||||
port = free_test_port()
|
||||
self.seed_agent("id5", port)
|
||||
self.start_ok("id5")
|
||||
self.svc("id5", "stop")
|
||||
(self.runtime("id5") / "manifest.json").write_text("{ not json")
|
||||
@@ -133,7 +142,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
|
||||
# ---- T5 marker/manifest 事件:缺一即阻塞,不自动新建 ----
|
||||
|
||||
def test_T5a_missing_marker_blocks(self):
|
||||
self.seed_agent("id6", 9437)
|
||||
port = free_test_port()
|
||||
self.seed_agent("id6", port)
|
||||
self.start_ok("id6")
|
||||
self.svc("id6", "stop")
|
||||
m = self.manifest("id6")
|
||||
@@ -145,7 +155,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
|
||||
self.assertFalse(self.running("id6"))
|
||||
|
||||
def test_T5b_foreign_marker_blocks(self):
|
||||
self.seed_agent("id7", 9438)
|
||||
port = free_test_port()
|
||||
self.seed_agent("id7", port)
|
||||
self.start_ok("id7")
|
||||
self.svc("id7", "stop")
|
||||
m = self.manifest("id7")
|
||||
@@ -158,7 +169,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
|
||||
self.assertFalse(self.running("id7"))
|
||||
|
||||
def test_T5c_lost_manifest_blocks_not_rebuild(self):
|
||||
self.seed_agent("id8", 9439)
|
||||
port = free_test_port()
|
||||
self.seed_agent("id8", port)
|
||||
self.start_ok("id8")
|
||||
m0 = self.manifest("id8")
|
||||
iid = m0["instance_id"]
|
||||
@@ -178,7 +190,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
|
||||
# ---- T6 cwd 无关:从别处调用身份不变 ----
|
||||
|
||||
def test_T6_cwd_independent_identity(self):
|
||||
self.seed_agent("id9", 9440)
|
||||
port = free_test_port()
|
||||
self.seed_agent("id9", port)
|
||||
self.start_ok("id9")
|
||||
iid = self.manifest("id9")["instance_id"]
|
||||
self.svc("id9", "stop")
|
||||
@@ -320,7 +333,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
|
||||
旧服务继续运行、旧制品与登记不变(2026-10-12 rdm1/rdmcand 反例:停服→
|
||||
覆盖→启动即拒,只剩混合状态)。"""
|
||||
remote, old_sha, new_sha = self.make_rdm_repo(self.noid_stub())
|
||||
self.seed_agent("rdx", 9451)
|
||||
port = free_test_port()
|
||||
self.seed_agent("rdx", port)
|
||||
self.start_ok("rdx") # 已建立身份,有能力制品在运行
|
||||
self.set_kv("rdx", "source", "rdm@%s" % old_sha)
|
||||
pid = self.pid_of("rdx")
|
||||
@@ -344,7 +358,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
|
||||
"""已建立身份后删行:update 在停服前拒绝,不自动补行,旧进程保持。
|
||||
补行只走 adopt --confirm。"""
|
||||
old_sha, new_sha = self.make_src_repo()
|
||||
self.seed_agent("rowx", 9452)
|
||||
port = free_test_port()
|
||||
self.seed_agent("rowx", port)
|
||||
self.start_ok("rowx")
|
||||
self.set_kv("rowx", "source", "dev@%s" % old_sha)
|
||||
db = Path(self.manifest("rowx")["identity"]["data_root"]) / "agent-system.db"
|
||||
@@ -364,7 +379,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
|
||||
def test_U1_bare_start_missing_row_is_event_init_recovers(self):
|
||||
"""普通启动只验证不补行:DB 行缺失 → 拒绝且不建空行(缺行即事件);
|
||||
显式 init 补齐后恢复。"""
|
||||
self.seed_agent("rowm", 9453)
|
||||
port = free_test_port()
|
||||
self.seed_agent("rowm", port)
|
||||
self.start_ok("rowm")
|
||||
iid = self.manifest("rowm")["instance_id"]
|
||||
self.svc("rowm", "stop")
|
||||
@@ -416,7 +432,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
|
||||
def test_U1_adopt_identityless_artifact_reports_pending(self):
|
||||
"""已装制品无 identity 能力:adopt 的 ensure 静默跳过,marker 留在 pending——
|
||||
输出必须如实报 pending,不得宣称 db_marker=established。"""
|
||||
self.seed_agent("adx", 9454)
|
||||
port = free_test_port()
|
||||
self.seed_agent("adx", port)
|
||||
self.start_ok("adx")
|
||||
iid = self.manifest("adx")["instance_id"]
|
||||
self.svc("adx", "stop")
|
||||
@@ -437,7 +454,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
|
||||
cand.chmod(0o755)
|
||||
remote, old_sha, _ = self._make_track_repo(cand, "agent-system")
|
||||
self.git_ok(self.root, "clone", str(remote), str(self.root / "srccache"))
|
||||
self.seed_agent("scx", 9455)
|
||||
port = free_test_port()
|
||||
self.seed_agent("scx", port)
|
||||
self.start_ok("scx")
|
||||
self.set_kv("scx", "source", "dev@%s" % old_sha)
|
||||
mpath = self.runtime("scx") / "manifest.json"
|
||||
@@ -459,7 +477,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
|
||||
self.svc("scx", "stop")
|
||||
|
||||
def test_I3_start_ensures_sqlite_identity(self):
|
||||
self.seed_agent("idb1", 9441)
|
||||
port = free_test_port()
|
||||
self.seed_agent("idb1", port)
|
||||
self.start_ok("idb1")
|
||||
iid = self.manifest("idb1")["instance_id"]
|
||||
rows = self.db_identity_row("idb1")
|
||||
@@ -470,7 +489,8 @@ class IdentityTests(tsr.SvcAutoRecoverTests):
|
||||
self.svc("idb1", "stop")
|
||||
|
||||
def test_I3_wrong_db_identity_blocks_start(self):
|
||||
self.seed_agent("idb2", 9442)
|
||||
port = free_test_port()
|
||||
self.seed_agent("idb2", port)
|
||||
self.start_ok("idb2")
|
||||
iid = self.manifest("idb2")["instance_id"]
|
||||
self.svc("idb2", "stop")
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
"""生命周期隔离:调用方的 AGENT_SYSTEM_* 不得进入 serve,serve.env 为 0600。"""
|
||||
import importlib.util
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from _port_alloc import free_test_port # noqa: E402
|
||||
|
||||
SOURCE = Path(__file__).resolve().parents[1]
|
||||
_spec = importlib.util.spec_from_file_location("tsr", SOURCE / "tests" / "test_svc_recover.py")
|
||||
tsr = importlib.util.module_from_spec(_spec)
|
||||
@@ -17,7 +22,8 @@ class LifecycleIsolationTests(tsr.SvcAutoRecoverTests):
|
||||
self.root / "scripts" / "svc_manifest.py")
|
||||
|
||||
def test_caller_identity_env_does_not_reach_serve(self):
|
||||
self.seed_agent("iso", 9461)
|
||||
port = free_test_port()
|
||||
self.seed_agent("iso", port)
|
||||
env = dict(self.env)
|
||||
env["AGENT_SYSTEM_DSN"] = "postgres://leak-user:leak-pass@127.0.0.1/leak"
|
||||
env["AGENT_SYSTEM_DATA"] = "/tmp/leak-data"
|
||||
@@ -38,7 +44,8 @@ class LifecycleIsolationTests(tsr.SvcAutoRecoverTests):
|
||||
self.svc("iso", "stop")
|
||||
|
||||
def test_two_bare_restarts_keep_identity(self):
|
||||
self.seed_agent("iso2", 9462)
|
||||
port = free_test_port()
|
||||
self.seed_agent("iso2", port)
|
||||
self.svc("iso2", "start")
|
||||
manifest = json.loads((self.runtime("iso2") / "manifest.json").read_text())
|
||||
iid = manifest["instance_id"]
|
||||
|
||||
+29
-12
@@ -11,12 +11,17 @@
|
||||
夹具复用 tests/test_svc_recover.py(桩不需要运行——台账操作是 SQLite 直读直写)。
|
||||
"""
|
||||
import importlib.util
|
||||
import os
|
||||
import shutil
|
||||
import sqlite3
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from _port_alloc import free_test_port # noqa: E402
|
||||
|
||||
SOURCE = Path(__file__).resolve().parents[1]
|
||||
|
||||
_spec = importlib.util.spec_from_file_location("tsr", SOURCE / "tests" / "test_svc_recover.py")
|
||||
@@ -64,21 +69,24 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
|
||||
# ---- show ----
|
||||
|
||||
def test_show_prints_ledger_and_flags_unknown_owner(self):
|
||||
self.seed_agent("ra1", 9461)
|
||||
port = free_test_port()
|
||||
self.seed_agent("ra1", port)
|
||||
self.seed_dbs("ra1", ledger_owner="u7-admin", base_owners=("weichen",))
|
||||
out = self.svc("ra1", "rdm-admin", "show").stdout
|
||||
self.assertIn("RDM 域管理员 u7-admin", out)
|
||||
self.assertIn("不在基座用户表", out) # u7-admin 不在 users → 残留警示
|
||||
|
||||
def test_show_known_owner_no_warning(self):
|
||||
self.seed_agent("ra2", 9462)
|
||||
port = free_test_port()
|
||||
self.seed_agent("ra2", port)
|
||||
self.seed_dbs("ra2", ledger_owner="weichen")
|
||||
out = self.svc("ra2", "rdm-admin").stdout # 缺省子命令 = show
|
||||
self.assertIn("RDM 域管理员 weichen", out)
|
||||
self.assertNotIn("不在基座用户表", out)
|
||||
|
||||
def test_show_empty_ledger_hint(self):
|
||||
self.seed_agent("ra3", 9463)
|
||||
port = free_test_port()
|
||||
self.seed_agent("ra3", port)
|
||||
self.seed_dbs("ra3", ledger_owner=None)
|
||||
out = self.svc("ra3", "rdm-admin").stdout
|
||||
self.assertIn("台账为空", out)
|
||||
@@ -87,7 +95,8 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
|
||||
# ---- transfer ----
|
||||
|
||||
def test_transfer_rewrites_single_row_with_provenance(self):
|
||||
self.seed_agent("ra4", 9464)
|
||||
port = free_test_port()
|
||||
self.seed_agent("ra4", port)
|
||||
self.seed_dbs("ra4", ledger_owner="u7-admin")
|
||||
out = self.svc("ra4", "rdm-admin", "transfer", "--to", "weichen").stdout
|
||||
self.assertIn("受信部署通道", out)
|
||||
@@ -97,13 +106,15 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
|
||||
self.assertEqual(added_by, "svc:rdm-admin:u7-admin") # 前任可追溯
|
||||
|
||||
def test_transfer_idempotent_when_already_owner(self):
|
||||
self.seed_agent("ra5", 9465)
|
||||
port = free_test_port()
|
||||
self.seed_agent("ra5", port)
|
||||
self.seed_dbs("ra5", ledger_owner="weichen")
|
||||
out = self.svc("ra5", "rdm-admin", "transfer", "--to", "weichen").stdout
|
||||
self.assertIn("已是 weichen", out)
|
||||
|
||||
def test_transfer_rejects_owner_missing_from_base_users(self):
|
||||
self.seed_agent("ra6", 9466)
|
||||
port = free_test_port()
|
||||
self.seed_agent("ra6", port)
|
||||
self.seed_dbs("ra6", ledger_owner="weichen")
|
||||
proc = self.svc("ra6", "rdm-admin", "transfer", "--to", "nobody", check=False)
|
||||
self.assertEqual(proc.returncode, 1, proc.stdout)
|
||||
@@ -111,7 +122,8 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
|
||||
self.assertEqual(self.ledger_owner("ra6")[0], "weichen") # 台账未被动
|
||||
|
||||
def test_transfer_rejects_empty_ledger(self):
|
||||
self.seed_agent("ra7", 9467)
|
||||
port = free_test_port()
|
||||
self.seed_agent("ra7", port)
|
||||
self.seed_dbs("ra7", ledger_owner=None)
|
||||
proc = self.svc("ra7", "rdm-admin", "transfer", "--to", "weichen", check=False)
|
||||
self.assertEqual(proc.returncode, 1, proc.stdout)
|
||||
@@ -120,7 +132,8 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
|
||||
# ---- 绑定合同与用法 ----
|
||||
|
||||
def test_refuses_when_rdm_db_missing(self):
|
||||
self.seed_agent("ra8", 9468)
|
||||
port = free_test_port()
|
||||
self.seed_agent("ra8", port)
|
||||
self.seed_dbs("ra8") # 建基座库后删 rdm.db
|
||||
(self.runtime("ra8") / "data" / "rdm.db").unlink()
|
||||
proc = self.svc("ra8", "rdm-admin", check=False)
|
||||
@@ -128,13 +141,15 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
|
||||
self.assertIn("无 RDM 域库", proc.stdout)
|
||||
|
||||
def test_refuses_when_base_db_missing(self):
|
||||
self.seed_agent("ra9", 9469)
|
||||
port = free_test_port()
|
||||
self.seed_agent("ra9", port)
|
||||
proc = self.svc("ra9", "rdm-admin", check=False)
|
||||
self.assertEqual(proc.returncode, 1, proc.stdout)
|
||||
self.assertIn("既有库不存在", proc.stdout)
|
||||
|
||||
def test_unknown_subcommand_usage_exit_2(self):
|
||||
self.seed_agent("raa", 9470)
|
||||
port = free_test_port()
|
||||
self.seed_agent("raa", port)
|
||||
proc = self.svc("raa", "rdm-admin", "bogus", check=False)
|
||||
self.assertEqual(proc.returncode, 2, proc.stdout)
|
||||
self.assertIn("用法", proc.stdout)
|
||||
@@ -142,14 +157,16 @@ class RdmAdminTests(tsr.SvcAutoRecoverTests):
|
||||
# ---- status 巡检行 ----
|
||||
|
||||
def test_status_lists_rdm_admin_row_and_warning(self):
|
||||
self.seed_agent("rab", 9471)
|
||||
port = free_test_port()
|
||||
self.seed_agent("rab", port)
|
||||
self.seed_dbs("rab", ledger_owner="u7-admin", base_owners=("weichen",))
|
||||
out = self.svc("rab", "status").stdout
|
||||
self.assertIn("RDM 域管理员 u7-admin", out)
|
||||
self.assertIn("不在基座用户表", out)
|
||||
|
||||
def test_status_silent_without_rdm_db(self):
|
||||
self.seed_agent("rac", 9472)
|
||||
port = free_test_port()
|
||||
self.seed_agent("rac", port)
|
||||
self.seed_dbs("rac")
|
||||
(self.runtime("rac") / "data" / "rdm.db").unlink()
|
||||
out = self.svc("rac", "status").stdout
|
||||
|
||||
@@ -56,7 +56,7 @@ def ci_git_env():
|
||||
"GIT_CONFIG_KEY_1": "http.%s/.extraheader" % CI_SERVER,
|
||||
"GIT_CONFIG_VALUE_1": "AUTHORIZATION: token " + CI_TOKEN,
|
||||
"GIT_CONFIG_KEY_2": "url.%s/weichen/.insteadOf" % CI_SERVER,
|
||||
"GIT_CONFIG_VALUE_2": "ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/",
|
||||
"GIT_CONFIG_VALUE_2": "ssh://git@gitea.naitangbaobao.cn:52222/weichen/",
|
||||
"GIT_CONFIG_KEY_3": "core.hooksPath",
|
||||
"GIT_CONFIG_VALUE_3": "/dev/null",
|
||||
}
|
||||
|
||||
+18
-7
@@ -12,9 +12,13 @@ import os
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from _port_alloc import free_test_port # noqa: E402
|
||||
|
||||
SOURCE = Path(__file__).resolve().parents[1]
|
||||
|
||||
_spec = importlib.util.spec_from_file_location("tsr", SOURCE / "tests" / "test_svc_recover.py")
|
||||
@@ -106,7 +110,8 @@ class U2ReleaseTests(tsi.IdentityTests):
|
||||
clock.chmod(0o755)
|
||||
self.env["PATH"] = str(clock_bin) + os.pathsep + self.env["PATH"]
|
||||
self.make_src_repo() # 预克隆 srccache(本用例走 --from local,仅保环境一致)
|
||||
self.seed_agent("u2a", 9461)
|
||||
port = free_test_port()
|
||||
self.seed_agent("u2a", port)
|
||||
self.start_ok("u2a") # legacy 运行中(期望态=running)
|
||||
self.assertTrue(self.running("u2a"))
|
||||
|
||||
@@ -147,7 +152,8 @@ class U2ReleaseTests(tsi.IdentityTests):
|
||||
# ---- T2:构建失败 → 旧服务保持运行、current 不动 ----
|
||||
|
||||
def test_U2_build_failure_keeps_old_running(self):
|
||||
self.seed_agent("u2b", 9462)
|
||||
port = free_test_port()
|
||||
self.seed_agent("u2b", port)
|
||||
self.set_makefile(self.stub)
|
||||
self.svc("u2b", "deploy", "--from", "local")
|
||||
cur1 = self.cur_release("u2b")
|
||||
@@ -164,7 +170,8 @@ class U2ReleaseTests(tsi.IdentityTests):
|
||||
# ---- T3:中断切换(journal switched)→ start 入口回退并恢复 ----
|
||||
|
||||
def test_U2_journal_interrupt_resolved_on_start(self):
|
||||
self.seed_agent("u2c", 9463)
|
||||
port = free_test_port()
|
||||
self.seed_agent("u2c", port)
|
||||
self.set_makefile(self.stub)
|
||||
self.svc("u2c", "deploy", "--from", "local")
|
||||
v1 = self.cur_release("u2c")
|
||||
@@ -190,7 +197,8 @@ class U2ReleaseTests(tsi.IdentityTests):
|
||||
# ---- T4:schema 前进 → 回退阻断,不触碰业务库 ----
|
||||
|
||||
def test_U2_schema_advance_blocks_rollback(self):
|
||||
self.seed_agent("u2d", 9464)
|
||||
port = free_test_port()
|
||||
self.seed_agent("u2d", port)
|
||||
self.set_makefile(self.stub)
|
||||
self.svc("u2d", "deploy", "--from", "local")
|
||||
v1 = self.cur_release("u2d")
|
||||
@@ -230,7 +238,8 @@ class U2ReleaseTests(tsi.IdentityTests):
|
||||
# ---- T5:legacy 布局未迁移 → 裸 start/restart 仍走原路径(兼容) ----
|
||||
|
||||
def test_U2_fault_after_switch_rolls_back_on_next_start(self):
|
||||
self.seed_agent("u2f", 9466)
|
||||
port = free_test_port()
|
||||
self.seed_agent("u2f", port)
|
||||
self.set_makefile(self.stub)
|
||||
self.svc("u2f", "deploy", "--from", "local")
|
||||
v1 = self.cur_release("u2f")
|
||||
@@ -248,7 +257,8 @@ class U2ReleaseTests(tsi.IdentityTests):
|
||||
self.svc("u2f", "stop")
|
||||
|
||||
def test_U2_health_timeout_rolls_back(self):
|
||||
self.seed_agent("u2g", 9467)
|
||||
port = free_test_port()
|
||||
self.seed_agent("u2g", port)
|
||||
self.set_makefile(self.stub)
|
||||
self.svc("u2g", "deploy", "--from", "local")
|
||||
v1 = self.cur_release("u2g")
|
||||
@@ -277,7 +287,8 @@ class U2ReleaseTests(tsi.IdentityTests):
|
||||
return p
|
||||
|
||||
def test_U2_legacy_layout_bare_lifecycle_still_works(self):
|
||||
self.seed_agent("u2e", 9465)
|
||||
port = free_test_port()
|
||||
self.seed_agent("u2e", port)
|
||||
self.start_ok("u2e")
|
||||
self.assertFalse((self.runtime("u2e") / "current").exists())
|
||||
self.assertTrue((self.runtime("u2e") / "bin" / "agent-system").exists())
|
||||
|
||||
@@ -9,9 +9,13 @@ import importlib.util
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from _port_alloc import free_test_port # noqa: E402
|
||||
|
||||
SOURCE = Path(__file__).resolve().parents[1]
|
||||
|
||||
_spec = importlib.util.spec_from_file_location("tsr", SOURCE / "tests" / "test_svc_recover.py")
|
||||
@@ -57,7 +61,8 @@ class UserBindingTests(tsr.SvcAutoRecoverTests):
|
||||
# ---- T1 合法 manifest:user list 绑定 data_root + --open-existing ----
|
||||
|
||||
def test_T1_user_list_binds_manifest_data(self):
|
||||
self.seed_agent("ub1", 9441)
|
||||
port = free_test_port()
|
||||
self.seed_agent("ub1", port)
|
||||
self.start_ok("ub1")
|
||||
self.svc("ub1", "stop")
|
||||
root = self.manifest("ub1")["identity"]["data_root"]
|
||||
@@ -74,7 +79,8 @@ class UserBindingTests(tsr.SvcAutoRecoverTests):
|
||||
# ---- T2 禁止覆盖 --data;未绑定默认目录拒绝 ----
|
||||
|
||||
def test_T2_reject_override_data_flag(self):
|
||||
self.seed_agent("ub2", 9442)
|
||||
port = free_test_port()
|
||||
self.seed_agent("ub2", port)
|
||||
self.start_ok("ub2")
|
||||
self.svc("ub2", "stop")
|
||||
self.touch_db("ub2")
|
||||
@@ -106,7 +112,8 @@ class UserBindingTests(tsr.SvcAutoRecoverTests):
|
||||
# ---- T3 删除 data 根:OpenExisting 失败,不建空库 ----
|
||||
|
||||
def test_T3_missing_data_root_rejected(self):
|
||||
self.seed_agent("ub3", 9444)
|
||||
port = free_test_port()
|
||||
self.seed_agent("ub3", port)
|
||||
self.start_ok("ub3")
|
||||
self.svc("ub3", "stop")
|
||||
root = Path(self.manifest("ub3")["identity"]["data_root"])
|
||||
@@ -124,7 +131,8 @@ class UserBindingTests(tsr.SvcAutoRecoverTests):
|
||||
# ---- T4 隐藏 flock:user/deploy 拒绝;已运行服务仍在 ----
|
||||
|
||||
def test_T4_no_flock_rejects_user_and_deploy(self):
|
||||
self.seed_agent("ub4", 9445)
|
||||
port = free_test_port()
|
||||
self.seed_agent("ub4", port)
|
||||
self.start_ok("ub4")
|
||||
self.assertTrue(self.running("ub4"))
|
||||
self.touch_db("ub4")
|
||||
@@ -158,7 +166,8 @@ class UserBindingTests(tsr.SvcAutoRecoverTests):
|
||||
# ---- T5 recovery U1 身份冒烟(完整套件见 test_svc_identity)----
|
||||
|
||||
def test_T5_identity_regression_smoke(self):
|
||||
self.seed_agent("ub5", 9446)
|
||||
port = free_test_port()
|
||||
self.seed_agent("ub5", port)
|
||||
self.start_ok("ub5")
|
||||
iid = self.manifest("ub5")["instance_id"]
|
||||
self.svc("ub5", "stop")
|
||||
|
||||
Reference in New Issue
Block a user